news 2026/2/8 19:22:10

【mcuclub】DHT11温湿度传感器实战:从原理到代码实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【mcuclub】DHT11温湿度传感器实战:从原理到代码实现

1. DHT11温湿度传感器初探

第一次拿到DHT11这个小家伙时,我差点被它朴素的外表给骗了。这个比指甲盖大不了多少的传感器,居然能同时测量温度和湿度!它采用单总线通信协议,只需要一个GPIO引脚就能完成数据交互,特别适合那些IO资源紧张的嵌入式项目。

DHT11内部结构其实挺有意思,拆开外壳能看到两个关键元件:一个是电阻式感湿元件,负责检测环境湿度;另一个是NTC测温元件,用来测量温度。这两个元件的数据由一个8位单片机采集处理,最终输出校准后的数字信号。实测下来,它的温度测量范围是0~50℃,精度±2℃;湿度测量范围20%~90%RH,精度±5%RH。虽然比不上实验室级传感器的精度,但对于大多数智能家居、农业大棚这类应用场景完全够用。

这里有个实际使用中的小技巧:由于DHT11每次测量后都会自动进入低功耗模式,连续读取时需要间隔至少1秒,否则容易读取失败。我曾经在一个智能花盆项目里连续读取数据,就是因为没加延时导致传感器"罢工",排查了半天才发现这个问题。

2. 硬件连接与电路设计

给DHT11设计电路时,最容易被忽略的就是那个上拉电阻。因为它的数据口采用漏极开路输出,如果不接上拉电阻,信号线就只能输出低电平或高阻态,永远没法输出高电平。根据我的经验,当供电电压为5V时,接4.7KΩ的上拉电阻最稳定。如果传输距离超过20米,可以适当减小阻值。

具体接线非常简单,DHT11只有三个有效引脚(有的版本是4个引脚,但第3脚悬空):

  • VCC接3.3V-5V电源
  • GND接地
  • DATA接MCU的GPIO

这里有个硬件设计上的坑要特别注意:如果传感器距离MCU较远,建议在VCC和GND之间加个100nF的去耦电容。有次我在工业现场部署时,因为电源干扰导致数据异常,就是靠这个电容解决的。完整的参考电路如下:

[VCC 3.3V-5V] │ ┌┴┐ │ │ 4.7KΩ └┬┘ │ ├───── DATA │ === 100nF │ [GND]

3. 单总线通信协议详解

DHT11的通信协议看似简单,但时序要求非常严格。整个通信过程可以分为三个阶段:

首先是主机发送开始信号:把数据线拉低至少18ms,然后拉高20-40μs。这个阶段相当于"敲门",告诉DHT11该干活了。这里容易出错的是延时精度,普通延时函数可能不够准确,最好用定时器实现微秒级延时。

接着是传感器响应:DHT11会先拉低80μs,再拉高80μs,然后才开始传输数据。很多初学者容易在这里翻车,看到第一个低电平就急着读取数据,结果读到一堆乱码。我的经验是用中断或轮询方式严格检测这个响应信号。

最后是数据传输阶段:每个bit都以50μs低电平开始,然后高电平的持续时间决定数据是0还是1(26-28μs表示0,70μs表示1)。40bit数据包含:

  • 湿度整数(8bit) + 湿度小数(8bit)
  • 温度整数(8bit) + 温度小数(8bit)
  • 校验和(8bit)

校验和是前四个字节的和,用于验证数据正确性。我曾经遇到过校验失败的情况,后来发现是导线太长导致信号畸变,换成屏蔽线就解决了。

4. STM32驱动代码实现

下面以STM32 HAL库为例,分享一个经过实战检验的驱动代码。首先在CubeMX中配置一个GPIO引脚(如PA0)和定时器(TIM5):

// dht11.h typedef struct { uint8_t humi_int; // 湿度整数 uint8_t humi_dec; // 湿度小数 uint8_t temp_int; // 温度整数 uint8_t temp_dec; // 温度小数 uint8_t checksum; // 校验和 } DHT11_Data; uint8_t DHT11_Read(DHT11_Data *data);
// dht11.c #include "dht11.h" #include "tim.h" #define DHT11_PORT GPIOA #define DHT11_PIN GPIO_PIN_0 // 微秒级延时函数 void delay_us(uint32_t us) { __HAL_TIM_SET_COUNTER(&htim5, 0); HAL_TIM_Base_Start(&htim5); while(__HAL_TIM_GET_COUNTER(&htim5) < us); HAL_TIM_Base_Stop(&htim5); } uint8_t DHT11_Read(DHT11_Data *data) { uint8_t buf[5] = {0}; GPIO_InitTypeDef GPIO_Init = {0}; // 主机拉低18ms HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET); delay_us(18000); HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET); // 切换输入模式 GPIO_Init.Pin = DHT11_PIN; GPIO_Init.Mode = GPIO_MODE_INPUT; GPIO_Init.Pull = GPIO_PULLUP; HAL_GPIO_Init(DHT11_PORT, &GPIO_Init); // 等待传感器响应 while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); while(!HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); // 读取40bit数据 for(int i=0; i<5; i++) { for(int j=0; j<8; j++) { while(!HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); delay_us(40); buf[i] <<= 1; if(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)) { buf[i] |= 1; while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); } } } // 校验数据 if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4]) { >DHT11_Data data; if(DHT11_Read(&data)) { printf("温度: %d℃, 湿度: %d%%\n", data.temp_int, data.humi_int); }

5. 常见问题与优化技巧

在实际项目中,DHT11最常遇到三类问题:

  1. 读取失败:多数是因为时序不准确。建议用逻辑分析仪抓取波形,检查开始信号和响应信号的持续时间是否达标。有个取巧的办法是把延时时间适当加长,比如开始信号用20ms代替18ms。

  2. 数据跳变:环境变化时数据可能突变。我的解决方案是采用滑动窗口滤波:保存最近5次读数,去掉最高最低值后取平均。代码实现如下:

#define SAMPLE_SIZE 5 int filter(int new_val) { static int buf[SAMPLE_SIZE] = {0}; static int index = 0; buf[index++] = new_val; if(index >= SAMPLE_SIZE) index = 0; // 排序找最大值和最小值 int min = buf[0], max = buf[0], sum = 0; for(int i=0; i<SAMPLE_SIZE; i++) { if(buf[i] < min) min = buf[i]; if(buf[i] > max) max = buf[i]; sum += buf[i]; } return (sum - min - max) / (SAMPLE_SIZE - 2); }
  1. 长距离传输不稳定:当传感器与MCU距离超过3米时,建议:
    • 改用屏蔽线
    • 降低上拉电阻阻值(如2.2KΩ)
    • 在MCU端增加施密特触发器整形信号

对于需要更高精度的场景,可以考虑DHT22(AM2302),它的温度精度±0.5℃,湿度精度±2%RH,但价格也更高。还有个选择是SHT30,精度更高但需要I2C接口。

最后分享一个项目经验:在智能农业系统中,我把DHT11放在防水盒里,通过1米长的导线引出,每隔5分钟采集一次数据,配合LoRa模块上传云端,已经稳定运行两年多。关键是要做好防潮处理,传感器周围用硅胶密封,避免凝露影响读数。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/9 3:13:35

Qwen3-VL-4B Pro部署教程:Kubernetes集群中Qwen3-VL-4B Pro服务编排

Qwen3-VL-4B Pro部署教程&#xff1a;Kubernetes集群中Qwen3-VL-4B Pro服务编排 1. 为什么需要在Kubernetes中部署Qwen3-VL-4B Pro 你可能已经试过本地运行Qwen3-VL-4B Pro&#xff0c;点开Streamlit界面、上传一张照片、输入“描述这张图”&#xff0c;几秒后就看到一段流畅…

作者头像 李华
网站建设 2026/2/9 5:41:33

零基础3分钟掌握弹幕盒子:轻松制作专业级自定义弹幕

零基础3分钟掌握弹幕盒子&#xff1a;轻松制作专业级自定义弹幕 【免费下载链接】danmubox.github.io 弹幕盒子 项目地址: https://gitcode.com/gh_mirrors/da/danmubox.github.io 你是否曾想为视频添加弹幕却苦于复杂的软件操作&#xff1f;是否因格式不兼容而放弃创意…

作者头像 李华
网站建设 2026/2/8 18:45:52

小白必看:Hunyuan-MT-7B开箱即用指南,支持5种少数民族语言

小白必看&#xff1a;Hunyuan-MT-7B开箱即用指南&#xff0c;支持5种少数民族语言 你是不是也遇到过这些翻译难题&#xff1f; 收到一份藏文合同&#xff0c;找不到靠谱的翻译工具&#xff1b;需要把蒙古语教学材料转成汉语&#xff0c;但主流翻译器要么不支持&#xff0c;要…

作者头像 李华
网站建设 2026/2/8 15:25:27

PPTXjs技术探险家日志:从浏览器解析到医疗级应用的实战之旅

PPTXjs技术探险家日志&#xff1a;从浏览器解析到医疗级应用的实战之旅 【免费下载链接】PPTXjs jquery plugin for convertation pptx to html 项目地址: https://gitcode.com/gh_mirrors/pp/PPTXjs 技术解构&#xff1a;揭开PPTX在浏览器中重生的奥秘 1.1 格式转换黑…

作者头像 李华