《机智云Gokit3开发篇》7 DHT11温湿度远程监测
注:文章结尾附本文章源码、原理图 资料链接
概述:本文介绍了Gokit3板载的DHT11温湿度传感器工作原理,以及驱动移植调用,读取温湿度,最后实现上传机智云平台实现远程监测
前期准备工作:
硬件准备:
Gokit3 开发板
软件准备:
机智云 GAgent 固件包(以下会提供如何在机智云官网下载固件包)。
如何移植机智云SDK 实现上云可看上一期详细介绍;
本期采用上一期的代码工程作为基础;
一、DHT11温湿度传感器工作原理介绍
Gokit3板载的温湿度传感器DHT11如图
蓝色的小方块,内置温度和湿度感应,性价比高。
1.1 DHT11工作原理
DHT11 是一款含有已校准数字信号输出的温湿度复合传感器。
外观:
通常有 3 个或 4 个引脚。
里面内置一颗8位单片机,它内部包含一个电阻式感湿元件和一个NTC测温元件,并与这颗单片机相连。
这意味着: 它是数字传感器,不是模拟传感器。你读出来的直接就是二进制数据,不需要 STM32 再去算 ADC 电压值了。
性能参数:
参数测量范围测量精度分辨率
温度0℃ ~ 50℃±2℃ 1℃
湿度20% ~ 90% RH ±5% RH1% RH
工作电压 3.3V ~ 5.5V
采样周期 ≥ 1秒
1.2 通信协议(重点):
单总线通信 (One-Wire)。
解释:不像串口有 TX/RX 两根线,DHT11 只有一根数据线(DATA)
1.3交互流程(握手):
主机请求: STM32 先把数据线拉低(至少 18ms)。
解释:通知DHT11,准备给我温湿度数据
从机响应: DHT11 收到信号后,会把线拉低一小会儿,
解释:收到,准备发送
数据传输: DHT11 开始按序发送 40 位 (bit) 的数据(0和1)。
结束: 传输完毕,总线被拉高,进入空闲状态。
注意:
因为单总线对时间精度要求极高(微秒级)。例如,DHT11 发送“0”是低电平50us+高电平26us,发送“1”是低电平50us+高电平70us。
如果你的 STM32 延时函数 (delay_us) 不准,或者读取时被中断打断,就会导致数据错乱或校验失败。
1.4 数据解析:
DHT11 一次传输 40 位数据(5个字节),高位先出。顺序如下:
8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
关于校验: 这是防止数据出错的保险机制。
算法: 前4个字节相加的结果,取最后8位,应该等于 校验和。
例子: 如果你读到湿度 45%,温度 28℃,数据可能是这样的:
00101101 (45) + 00000000 (0) + 00011100 (28) + 00000000 (0) = 01001001 (73)
如果最后收到的校验和也是 73,说明数据是对的
1.5 Gokit3 板载DHT11温湿度传感器原理图部分及对应STM32 IO口
通过原理图可以找到,DHT11的数据引脚接到了STM32的PB3引脚上
注意:Gokit3 的 DHT11 接在 PB3 引脚上,而在 STM32F103 中,PB3 默认是 JTAG 调试口。如果不关闭 JTAG 功能,PB3 是无法作为普通 GPIO 控制 DHT11 的。
二、机智云添加数据点以及移植代码包
2.1 创建新的数据点
登录机智云开发者中心 -> 找到你的产品 -> 数据点 (Data Points)。
这里以上期工程为模版,新增温度和湿度两个数据点
新建数据点:
温度 (Temperature): 标识名 temp,类型“数值”,范围 -20~80,单位 ℃,只读。
湿度 (Humidity): 标识名 hum,类型“数值”,范围 0~100,单位 %,只读。
生成代码后,开始移植到自己的工程
把以下两个文件以及对应的头文件添加进自己的工程,如果已经添加,这里就选择覆盖
2.2 移植官方DHT11 驱动程序
复制黏贴进自己的工程
打开keil,添加进工程目录
注意:DHT11需要用到delay演示,所以还需添加delay文件
2.3读取DHT11 温湿度数据
引入头文件
在 main.c 顶部的 Includes 区域,加入我们刚移植好的驱动头文件:
/* USER CODE BEGIN Includes */
#include "Hal_temp_hum.h" // 引入DHT11头文件
/* USER CODE END Includes */
定义变量
在 main 函数内部,while(1) 之前,定义用来存温湿度的变量和计时变量:
/* USER CODE BEGIN 1 */
uint8_t temp_value = 0; // 存温度
uint8_t humi_value = 0; // 存湿度
uint32_t dht11_timer = 0; // 这里的计时器变量用于非阻塞延时
/* USER CODE END 1 */
初始化传感器在 main 函数的初始化部分,调用初始化函数:
/* USER CODE BEGIN 2 */
userInit(); // 机智云自带的初始化
dht11Init(); // <--- 在这里初始化 DHT11
/* USER CODE END 2 */
在主循环中读取 (核心步骤)
在 while (1) 循环中,我们需要写一个非阻塞的读取逻辑。
解释:
很多新手在读取传感器时习惯使用 HAL_Delay(2000) 来延时。但在物联网开发中,这样会阻塞整个程序的运行
阻塞的后果: 机智云的协议需要每隔一段时间发送“心跳包”来维持设备在线。如果你使用了 HAL_Delay 死等 2 秒,CPU 就会停止处理网络任务,导致设备与云端断开连接,App 上就会显示“设备离线”。
解决办法: 我们利用 STM32 的系统滴答定时器 (HAL_GetTick) 获取当前时间。通过计算 当前时间 - 上次读取时间 是否大于 2000ms,来实现**“非阻塞”**的定时任务。这样既保证了 DHT11 有足够的采样间隔,又不会耽误机智云的网络通信。
代码添加:
请找到 userHandle() 函数调用的地方,并修改如下:
// 获取当前系统运行时间(毫秒)
// 如果当前时间 - 上次读取时间 > 2000ms (2秒),则读取一次
if(HAL_GetTick() - dht11_timer > 2000)
{
// 更新计时器
dht11_timer = HAL_GetTick();
// 调用读取函数,参数是取地址符 &
// 返回值 0 表示成功,1 表示失败
if(dht11Read(&temp_value, &humi_value) == 0)
{
// --- 读取成功,开始赋值给机智云 ---
//以下调用userHandle();函数
}
else
{
}
}
// 机智云的处理函数,必须不断运行,不能被阻塞
userHandle();
gizwitsHandle((dataPoint_t *)¤tDataPoint);
2.4 把温湿度数据上传机智云云平台
在 STM32 读取到温湿度数据后,我们需要把数据“搬运”到机智云自动生成的结构体中。
找到 userHandle 函数(或者在主循环读取成功后的位置),将变量赋值给 currentDataPoint 结构体。
在中解除注释,把温湿度数据的变量赋值:
void userHandle(void)
{
currentDataPoint.valuetemp = temp_value;//Add Sensor Data Collection
currentDataPoint.valuehum = humi_value;//Add Sensor Data Collection
}
2.5 编译烧录,打开机智云APP
这里开始配网连接上机智云,这里烧录和配网以及如何安装机智云APP可以看我往期的帖子
2.6 可以看到,温湿度的数据已经读取并上传云平台,通过机智云APP显示
三、常见问题排查
如果你烧录后发现 App 上数据全是 0,或者显示离线,请检查以下几点:
数据一直是是 0?
检查杜邦线连接是否松动。
检查 delay_us 微秒延时函数是否精准(DHT11 对时序要求极高
检查 PB3 的 JTAG 模式是否禁用(见上文 1.5 节)。
App 显示设备离线?
检查代码中是否使用了长时间的 HAL_Delay 阻塞了主循环。
检查 Wi-Fi 模组是否正常供电。
**温度显示 255 或乱温度显示 255 或乱码?
通常是校验和错误导致的。请检查 DHT11 的供电电压(推荐 3.3V 或 5V),并尝试重新复位开发板。
本文到此结束,谢谢大家!
源码、原理图资料链接
原理图:
链接: https://pan.baidu.com/s/1orRkTIyottPv_pUBzvWubw?pwd=WPC1 提取码: WPC1
源码:
链接: https://pan.baidu.com/s/1womRu2KPWfOuJaT5x1T58g?pwd=WPC1 提取码: WPC1
页:
[1]