【电子DIY作品】+环境监测+鸿蒙hi3861开发板

[复制链接]
查看219 | 回复6 | 2024-8-14 18:25:49 | 显示全部楼层 |阅读模式

本帖最后由 单字一个轩 于 2024-8-14 18:39 编辑

本帖最后由 单字一个轩 于 2024-8-14 18:36 编辑

本帖最后由 单字一个轩 于 2024-8-14 18:34 编辑

项目名称

基于OpenHarmony环境监测控制系统。可以通过连接华为云实现远程计算机对环境进行监控。依托开发板上的环境监测传感器采集环境信息并显示,并进行异常报警。通过上云,实现监测系统的远端控制和查询。

实验内容及实验成果

1)通过按键可以控制系统的LED灯,表示系统状态;

2) 通过屏幕显示传感器的采集数据;

3) 控制蜂鸣器进行监测异常报警;

4) 借助ADC转换器采集电压值并显示;

5) 借助光强传感器、人体红外传感器、温湿度传感器采集环境数据,并显示;

6)控制风扇转动,调节温湿度;

7)通过云端控制系统,并实现系统状态的查询。

实验方法

2.1 核心板通过读取IO状态直接获取外设状态(按键),通过IIC协议与IO拓展芯片通信控制LED灯,表示系统状态。

(1)认识IO扩展芯片(PCF8574)

在PCF8574的引脚中,VCC和GND为电源和地引脚,A0\~A2为从器件地址,通过引脚的输入电平,可以配置地址为0\~7,因此一个IIC总线上最多可以挂载8片PCF8574芯片,每个IO口可以单独的分配为输入或者输出。

图2.1.1

(2)分析原理图(如图2.1.1)

图2.1.1

由原理图可知:LED灯连接在PCF8574芯片的P2引脚上LED灯的引脚输出低电平,点亮LED灯LED灯的引脚输出高电平,熄灭LED灯

(3)使用IIC协议控制PCF8574改变引脚输出电平。

关键字:union

联合体的大小:

联合体的所有成员都使用同一段内存空间,联合体大小即为联合体中最大的那个成员大小

格式:

union 联合体名{

``` 数据类型 成员名;

数据类型 成员名; ```

};

uint32\_t PCF8574\_Write(uint8\_t data);

功能:向PCF8574芯片写1个字节的数据,只能读1个字节的数据。

参数:

``` data:数据中的每一位代表引脚 高位->低位,P7->P0 ```

返回值:

``` 成功返回0,非0为失败 ```

定义了包含所有引脚的联合体PCF8574.io.all和PCF8574.io.bit.P0-P1。改变PCF8574.io.all中引脚的值,并通过写函数写入PCF8574,便可以实现点亮LED的行为

(4)认识按键,分析原理图。(如图2.1.4)

图2.1.4

按键检测方式有两种,分为轮询检测和中断检测。

轮询检测(如图2.1.5)是一直进行在检测中,发现按键的电平变化后,执行设置操作。但有弊端是机械按键都会存在抖动可能会有多次的误判断,这时候就需要按键消抖,消抖时需要延时,便会产生CPU的占用,所以按键轮询检测会十分的占用CPU资源。

为了改进该实验操作,所以我们采用了按键的中断检测,即只有检测到按键的低电平时才会进行中断检测。“中断(如图2.1.6):CPU在运行的时候,突然发生紧急的事件,暂停当前的程序转而去执行提前设置好的程序,处理完成后然后在回到之前的程序继续执行,这个过程叫做中断。中断只需要使能一次,就可以执行中断事件。”

图2.1.6

中断检测判断需要对IO口进行相关设置,且中断内不宜执行过长耗时操作,不然会影响系统的正常使用。对按键的配置和回调函数的设置如图2.1.7。

图2.1.7

CPU在检测到按键被按下时便会执行回调函数中的相关内容。并在回到主程序后,继续执行原本操作,如果有回调函数中相关数据的改变时,主程序中也发生改变。

(5)使用按键控制LED运行指示灯的状态(见图2.1.8和图2.1.9)

图2.1.8 图2.1.9

2.2 通过屏幕显示传感器的采集数据

(1) 认识OLED屏

OLED屏采用SSD1306芯片进行驱动0.96寸OLED显示屏本显示屏使用黄+蓝屏幕进行显示,点阵数量为128\*64.

OLED,即有机发光二极管(Organic Light-Emitting Diode)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性。

与LCD相比,LCD需要背光,同样的显示,OLED 效果要来得好一些,OLED分辨率可以做到很高。OLED 由于同时具备自发光,不需背光源、厚度薄、视角广、反应速度快、可用于挠曲性面板等等。与LCD相比,LCD需要背光,同样的显示,OLED效果要来得好一些,OLED分辨率可以做到很高。

(2) 扫描方式

虽然在屏幕中我们是按照像素点(bit:比特位)来进行打印图片的,但实际上在向屏幕输出数据时,是按照字节为大小进行输出的,也就会是屏幕从128\*64变为128的输出方式,也延伸出另外的两种扫描方式,列行式和行列式。屏幕从上到下共8页,屏幕从左到右共128列。如图2.2.1

图2.2.1

由原理图可知OLED显示屏通过IIC总线连接与HI3861。

分析API的接口函数,利用SHT20读取环境的温度与湿度,并在OLED屏上显示,如图2.2.3。

图2.2.3

(4)显示图片与字符串

如果显示图片,利用取模软件,取得图片数据,调用显示图片的函数,实现图片在OLED上显示的功能。

如图2.2.4。

图2.2.4

在屏幕上显示任意字符:

因为如果我们想让打印的字符串所打印出来的为ASCII字符,所以在设计字库的时候设计人员便可以使用ASCII排序对每个字符进行绘制取模。如图2.2.5。

图2.2.5

2.3 控制蜂鸣器进行监测异常报警

(1)蜂鸣器控制原理与led,风扇控制原理基本一致,再此不多赘述。

(2)封装控制蜂鸣器的函数

define BAURATE 100000 //定义IIC速率

define DEV\_ADDR 0x42 //定义IIC器件地址

define OFF 0

define ON 1

tn\_pcf8574\_io\_t ioname = {0};

//pcf8574初始化的函数

void pcf8574\_init()

{

``` //设置IO9为IIC的时钟线 ```

hi\_io\_set\_func(HI\_IO\_NAME\_GPIO\_9,HI\_IO\_FUNC\_GPIO\_9\_I2C0\_SCL);

``` //设置IO10为IIC的数据线

hi\_io\_set\_func(HI\_IO\_NAME\_GPIO\_10,HI\_IO\_FUNC\_GPIO\_10\_I2C0\_SDA);

//设置IO9和IO10的上拉电阻

hi\_io\_set\_pull(HI\_IO\_NAME\_GPIO\_9,HI\_IO\_PULL\_UP);

hi\_io\_set\_pull(HI\_IO\_NAME\_GPIO\_10,HI\_IO\_PULL\_UP);

//IIC初始化

hi\_i2c\_init(HI\_I2C\_IDX\_0,BAURATE);

//设置硬件设备为关闭状态

ioname.bit.p2 = 1;//led\_off

ioname.bit.p1 = 1;//beep\_off

ioname.bit.p0 = 0;//fan\_off

//写入到pcf8574芯片

pcf8574\_write(ioname.all); ```

}

//向pcf8574写入数据的函数

void pcf8574\_write(uint8\_t wdata)

{

``` uint8\_t wbuf[] = {wdata};

hi\_i2c\_data data = {0};

data.send\_buf = wbuf;

data.send\_len = sizeof(wbuf);

//iic写入数据

hi\_i2c\_write(HI\_I2C\_IDX\_0,DEV\_ADDR,&data); ```

}

void beep\_ctl(uint32\_t states)

{

``` if(states == OFF)

{

ioname.bit.p1 = 1;

pcf8574\\\_write(ioname.all);

}else if(states == ON)

{

ioname.bit.p1 = 0;

pcf8574\\\_write(ioname.all);

} ```

}

}

void mytest(void){

pcf8574\_init();

``` beep\_ctl(off); //关闭蜂鸣器 ```

while(1)

{ }

}

2.4 借助ADC转换器采集电压值并显示

(1) ADC(Analog-to-Digital Converter),即模拟-数字转换器,可以将连续变化的模拟信号转换为离散的数字信号,进而使用数字电路进行处理,称之为数字信号处理。

(2)GPIO引脚复为ADC用

其中ADC通道有7个,其中GPIO可复用成ADC的通道如下:

[td] | **Pin** | **管脚名称** | **复用信号** | | ------------ | --------------- | --------------- | | 6 | GPIO\_04 | ADC1 | | 17 | GPIO\_05 | ADC2 | | 19 | GPIO\_07 | ADC3 | | 27 | GPIO\_09 | ADC4 | | 29 | GPIO\_11 | ADC5 | | 30 | GPIO\_12 | ADC0 | | 31 | GPIO\_13 | ADC6 |

(3)API接口函数的使用

static float GetVoltage(void)

{

``` unsigned int ret;

unsigned short data;

// 该函数通过使用AdcRead()函数来读取 ADC\_CHANNEL\_5 的数值存储在data中,

// WIFI\_IOT\_ADC\_EQU\_MODEL\_8 表示8次平均算法模式,

// WIFI\_IOT\_ADC\_CUR\_BAIS\_DEFAULT 表示默认的自动识别模式,

// 最后通过 data \* 1.8 \* 4 / 4096.0 计算出实际的电压值。

ret=Adc\_Read(WIFI\_IOT\_ADC\_CHANNEL\_5,&data,WIFI\_IOT\_ADC\_EQU\_MODEL\_8, WIFI\_IOT\_ADC\_CUR\_BAIS\_DEFAULT, 0xff);

if (ret != WIFI\_IOT\_SUCCESS)

{

printf("ADC Read Fail\\\\n");

}

return (float)data \* 1.8 \* 4 / 4096.0; ```

}

//ADC采集的主函数

static void ADCTask(void)

{

``` float voltage;

while (1)

{

//获取电压值

voltage = GetVoltage();

printf("vlt:%.3fV\\\\n", voltage);



//延时1s

usleep(1000000);

} ```

}

(4)运行效果

因为电池电压一般要大于额定电压,所以计算方法应该稍微修改成在电池满电的时候输出是电池满电电压的值。

2.5 借助光强传感器、人体红外传感器、温湿度传感器采集环境数据,并显示

(1) 实验的主要结果是通过I2C总线控制光强度传感器AP3216C对环境光强度及物体接近情况进行测量并获取环境光强度及是否有物体靠近,然后通过OLED显示屏将读取到的光强度、接近程度、红外信息显示在Hi3861的屏幕上。

(2)分析调用API接口函数

uint32\_t AP3216C\_Init(void);

功能:AP3216C 初始化

参数:

``` 无 ```

返回值:

``` 成功返回0,非0为失败 ```

uint32\_t AP3216C\_ReadData(uint16\_t \*irData, uint16\_t \*alsData, uint16\_t \*psData);

功能:读 接近传感器、光照强度传感器、人体红外传感器的数值

参数:

``` irData:人体红外传感器

alsData 光强传感器 ```

psData 接近传感器

``` 初始化,读数据便完成了对三合一传感器的使用 ```

(3)将三合一传感器的结果用OLED显示

//定义存放数据的结构体:

typedef struct message\_sensorData

{

uint8\_t led; // LED灯当前的状态

uint8\_t fan; // 风扇当前的状态

uint8\_t buzzer; // 蜂鸣器当前的状态

uint16\_t light; // 光照强度

uint16\_t proximity; // 接近传感器的数值

uint16\_t infrared; // 人体红外传感器的数值

float temperature; // 当前的温度值

float humidity; // 当前的湿度值

} msg\_sensorData\_t;

msg\_sensorData\_t sensorData = {0}; // 传感器的数据

//初始化OLED和三合一传感器

``` SHT20\_Init(); // SHT20初始化 ```

AP3216C\_Init(); // 三合一传感器初始化

``` SSD1306\_CLS(); // 清屏 ```

//读三合一传感器的数据

AP3216C\_ReadData(&sensorData.infrared, &sensorData.light,sensorData.proximity);

memset(displayBuffer, 0, sizeof(displayBuffer));

``` sprintf((char \*)displayBuffer, "T:%.1fC H:%.1f%%",sensorData.temperature,sensorData.humidity);

SSD1306\_ShowStr(0, 1, displayBuffer,8); ```

//将数据放入数组,并且oled显示数组

2.6 控制风扇转动,调节温湿度

(1)分析风扇的原理图

与风扇相连的元件有三极管,控制风扇的三极管为NPN类型,当基极为高电平时,集电极和发射极会导通。基极电平由P0口控制。

2.7 通过云端控制系统,并实现系统状态的查询

(1) 通过云端控制系统,并实现系统状态的查询。

注册华为IoTDA物联网平台

创建产品

根据设备信息,生成用户名和密码

创建产品模型

数据上云

(2) MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅式消息传输协议,非常适合于低带宽、高延迟或不可靠的网络条件下设备间的通信。

(3)建立JSON数据流

JSON数据流要与云平台的名称保持一致:

[attach]27428[/attach]

视频链接

【hi3861环境监测】(https://www.bilibili.com/video/BV1iUenehENR?vd_source=4f560f98370e70269a89ec949b90960a)

(我真服啦,MD里面不能加图片,富文本里加了转到md发现不能加图片后再转到富文本,发现全都没了!!!!!!!!!!!!)

回复

使用道具 举报

单字一个轩 | 2024-8-14 18:40:11 | 显示全部楼层
:):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)
回复 支持 反对

使用道具 举报

iiv | 2024-8-14 20:39:10 | 显示全部楼层
哈哈哈哈哈哈嗝
回复 支持 反对

使用道具 举报

爱笑 | 2024-8-15 09:54:54 | 显示全部楼层

md里面直接复制图片就行
用心做好保姆工作
回复 支持 反对

使用道具 举报

WT_0213 | 2024-8-15 10:36:58 | 显示全部楼层
视频开头看着头好晕
回复 支持 反对

使用道具 举报

大猫的鱼 | 2024-8-15 13:42:33 | 显示全部楼层
不错不错
回复

使用道具 举报

putin | 2024-8-15 21:53:17 | 显示全部楼层
鸿蒙开发版!❓高级
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则