资讯详情

Arduino三合一DHT库:DHT11/DHT21/DHT22驱动安装与避坑要点

📅 2026/10/21 21:53:22 | 华诺云谱 👁 阅读
Arduino三合一DHT库:DHT11/DHT21/DHT22驱动安装与避坑要点
简介面向Arduino开发者的DHT11、DHT21、DHT22温湿度传感器库文件压缩包专为需要在物联网及DIY电子项目中快速接入环境监测功能的用户准备。包内包含核心库文件与示例程序可直接在Arduino IDE中调用免去手动解析单总线通信协议的繁琐过程。资源共10个文件以C源码.cpp/.h为主辅以Arduino示例.ino、说明文档.md、属性配置.properties及关键字文件.txt整体仅15KB轻量且便于移植。DHT22支持-40℃至80℃测量范围相对DHT11具有更高精度可满足不同场景的精度需求。该资源已吸引1369人学习下载适合正在学习传感器应用或准备快速完成环境监测项目的初中级开发者拿到手即可参考示例完成初始化与数据读取。1. 一份 DHT11-DHT21-DHT22 库文件三款传感器的 Arduino 读取被一个小 zip 收编了我在某温湿度采集 Demo 里第一次把 DHT11 换成 DHT22 时沿用旧的单型号驱动串口全返回 -999一度怀疑买到坏件。后来才明白DHT11、DHT21、DHT22 虽然长相和引脚接近底层单总线时序、校验和逻辑并不共用光在代码里改型号名没用。这份 DHT11-DHT21-DHT22 库文件.zip解决的就是“同一套 Arduino 代码按宏定义切换三款传感器型号”的问题构造 DHT 对象时指一下型号温湿度统一用 readHumidity() 和 readTemperature()不用自己对着数据手册抠时序。新手直接跑 examples 里的示例就行熟手可以拿来做多传感器轮询与低功耗改造的底子。这篇文章就把选型、安装、接线、避坑、进阶验证一次说清楚。2. DHT11、DHT21、DHT22 的差异与库安装参数表决定你该选谁2.1 三款传感器关键参数对比先看参数再写代码不然你不理解为什么同一个库可以传三种型号却不通用。下面是三款传感器的常用参数对比采购和调参都会用到。参数项DHT11DHT21AM2301DHT22AM2302湿度精度±5%RH±3%RH±2%RH温度精度±2°C±0.5°C±0.5°C湿度量程20%-80%RH0%-100%RH0%-100%RH温度量程0-50°C-40°C-80°C-40°C-80°CBus 类型单总线单总线单总线最小采样间隔1 秒2 秒2 秒温度分辨率1°C0.1°C0.1°C湿度分辨率1%RH0.1%RH0.1%RHDHT11 适合对环境数据只做大趋势判断的场景比如教室温湿度展示、简易空气站刷 LED 屏。DHT22 适合需要判断 0.5°C 变化的场景比如机房温度告警、药品柜存储监测。DHT21 相对冷门但它对长线和工业环境的抗干扰能力通常比 DHT22 好一些我做过一个配电柜环境监测方案走的 DHT21 4.7kΩ 上拉数据就很稳。这三款都是单总线通信协议里都包含起始信号、响应信号和 40 bit 数据帧但每一位高低电平时序的长度不一样。DHT21 与 DHT22 的时序比较接近DHT11 则明显不同所以库里必须用枚举类型区分这也解释了为什么一份库打包三款传感器值得下载自己按 datasheet 写协议识别 40 bit 数据至少要多花两天调试。2.2 解压 zip 后应该放在哪个目录Arduino IDE 的库目录有固定位置。Windows 一般是%USERPROFILE%/Documents/Arduino/librariesmacOS 是~/Documents/Arduino/librariesLinux 是~/Arduino/libraries。Arduino IDE 1.x 和 2.x 共用这几个目录装一次两边都能识别。很多人装完库编译报DHT.h: No such file or directory原因就是 zip 解压后直接把 DHT.cpp 和 DHT.h 丢进了 .ino 所在目录。IDE 编译时只搜索工程目录、库目录和内置核心目录不会递归搜索工程下面的所有子文件夹所以必须规范放到 libraries 下。另外解压工具如果不小心解出两层同名目录比如DHT-master/DHT-master/DHT.h也会导致 IDE 找不到正确路径。规范路径是libraries/DHT/DHT.h中间不多包一层。# macOS / Linux 命令行安装示例 mkdir -p ~/Documents/Arduino/libraries cp -r ~/Downloads/DHT-master ~/Documents/Arduino/libraries/DHT这段命令做了两件事先确保 libraries 目录存在再把解压出来的整体复制成 DHT 目录。复制完成后可以检查一下目录结构ls ~/Documents/Arduino/libraries/DHT # 预期能看到 DHT.h 和 DHT.cppWindows 用户直接用资源管理器把整个文件夹移动到文档/Arduino/libraries下并改名 DHT 即可。文件夹名不要带空格、中文或-master后缀新版 IDE 的库管理索引对目录名有约束带特殊字符有时能编译过但库管理器里显示会异常。装好后务必重启一次 Arduino IDE。IDE 启动时才扫描 libraries 目录不重启直接编译偶尔会遇到头文件索引没刷新的玄学问题。2.3 如何确认库真的被装入 IDE重启 IDE 后新建一个空工程写入#include DHT.h并编译。编译通过说明头文件路径正确。菜单栏“项目→加载库”列表里如果能看到 DHT 相关条目说明 library.properties 被正确解析如果列表看不到但编译通过多半是这份库缺少规范的 library.properties 元数据不影响实际使用。注意一种特殊情况某些库压缩包内部带src子目录真正的源码有两套路径根目录一份、src 里一份。Arduino 库规范会把src当作根目录所以编译不会报错。如果出现multiple definition这类重定义错误通常是根目录和 src 下都放了同名 .cpp手动保留一份即可。这份 zip 的实际内容我没有逐字节核对但按 DHT 库常见打包方式至少包含 DHT.h、DHT.cpp、examples 目录和 keywords.txt。examples 里通常有一个 DHTtester 示例程序这是验证安装是否成功最快的方式。建议优先打开 examples 里的 .ino 编译因为示例里的引脚和型号宏是作者验证过的组合。3. 接线与第一个读取程序用 DHT_TYPE 宏一次兼容三种传感器3.1 传感器引脚定义与上拉电阻三款传感器都是四针封装直插式通常从左到右是 VCC、DATA、NC、GND但不同厂家的丝印排序可能有差异接线前一定要看丝印不要只认颜色。模块式一般引出 VCC、DATA、GND 三线板载电容和上拉电阻已经集成接起来更省心。裸传感器则需要自己补一个 4.7kΩ 到 10kΩ 的上拉电阻接在 DATA 和 VCC 之间。原因很简单DHT 数据线是开漏输出没有上拉电阻时高电平会漂移单片机会把 1 判断成 0出现偶发乱码或者读值偶尔 NaN。我在项目里见过直接把数据线悬空接杜邦线的跑了半天全是固定 0加上拉后立刻正常。传感器引脚接线去向说明VCCArduino 5V 或 3.3V推荐 5V低压下个别批次不稳定DATAArduino D2数据脚外接 4.7k-10k 上拉GNDArduino GND共地NC悬空不要接任何网络上拉电阻的选择也有讲究。DHT11 用 10kΩ 没问题DHT21 在长线下建议用 4.7kΩ因为 DHT21 的内部上拉能力偏弱电阻太大高电平建立时间不够时序就容易超时。如果传感器距离单片机超过 20cm把线换成双绞屏蔽线Data 与 GND 同轴走线能减少环境干扰。3.2 主程序初始化、读取、串口打印拿到库后最快的跑通方式是打开 examples 下的 DHTtester修改 DHT_PIN 和 DHT_TYPE 两个宏即可。核心代码的结构大致如下#include DHT.h #define DHT_PIN 2 #define DHT_TYPE DHT22 // 切型号就改这一行DHT11 / DHT21 / DHT22 DHT dht(DHT_PIN, DHT_TYPE); void setup() { Serial.begin(115200); dht.begin(); Serial.println(DHT program started); } void loop() { float humidity dht.readHumidity(); float temperature dht.readTemperature(); if (isnan(humidity) || isnan(temperature)) { Serial.println(Read failed, check wire or pull-up); delay(2000); return; } Serial.print(Humidity: ); Serial.print(humidity); Serial.print( %\t); Serial.print(Temperature: ); Serial.print(temperature); Serial.println( *C); delay(3000); }逻辑说明第一行引入库头文件第三行定义数据引脚第四行定义传感器型号这是整份库的核心抽象。第七行构造 DHT 对象构造顺序是引脚在前、型号在后写反了在编译期不会报错但运行时读到的是乱码。setup 里的 begin() 负责完成内部状态初始化包括引脚模式设置。loop 里 readHumidity 返回湿度百分比readTemperature 默认返回摄氏温度底层把 20 bit 温湿度原始值除以 10。参数上需要记住三个细节。第一DHT_TYPE 只能填 DHT11、DHT21、DHT22 三种大小写敏感填错不报错但读不出来。第二readTemperature() 可以传 true 返回华氏温度比如dht.readTemperature(true)不传参数默认是摄氏度。第三读取失败时两个函数会返回 NaN所以代码里必须用 isnan 拦截否则后续用这个值算热指数会输出一串无效数。部分库版本还带 readHeatIndex() 热指数计算但热指数公式只在高温高湿区间有意义低温环境算出来反而离谱不要无脑用。3.3 首次运行串口输出长什么样与异常值识别上传程序后打开串口监视器波特率必须设成 115200。如果设成 9600串口打印出来全是乱码——这不是传感器问题是波特率不匹配。正常情况下的输出类似DHT program started Humidity: 51.20 % Temperature: 26.30 *C Humidity: 51.30 % Temperature: 26.30 *C Humidity: 51.50 % Temperature: 26.60 *C如果读完一次后按复位键传感器第二次上电通常输出会更快稳定因为模块内部电容已经完成初充电。第一次上电出现一次 NaN 是比较常见的现象原因是 DHT 起始信号发出后等待响应超时代码里已经做了 NaN 拦截和重试问题不大。我把首次运行常见的串口现象整理成一个表排查时对号入座串口现象可能原因下一步操作完全没有输出串口选错或波特率不对核对端口和 115200一直 NaN线松、型号宏错检查上拉和 DHT_TYPE固定 0.00 / -999型号宏选错DHT11 写成 DHT22 典型的症状数值定住不动采样间隔没到确认 delay 大于等于 2 秒隔一段跳一个大值干扰、热源缩短线长或软件滤波这里尤其要提醒 DHT21某些批次的模块上电后内部晶振起振很慢setup 里 begin() 完立刻读会稳定返回 NaN。我在模拟项目X 里处理 DHT21 时会在 begin() 后面加一个delay(3000)让传感器先完成自检和内部状态机复位再进入 loop 循环一次成功率明显提升。如果你读到的温湿度一直是“整数”也可能不是代码问题而是 DHT11 的分辨率只有 1°C 和 1%RH25.3°C 显示成 25°C 属于物理特性不是精度缺陷。4. 避坑与排查装完库第一次读数翻车逐条解决这一章整理五条实际调试中很常见的坑每条按“现象→原因→解决”展开。这些坑单看都简单但组合出现时真会耗掉一整个下午。4.1 现象编译报错 DHT.h: No such file or directory这是安装库最常见的问题。原因几乎都是库文件没有真正放进 libraries 目录或者放进了但目录层级不对。Arduino IDE 搜索头文件时只认固定位置不会帮你自动遍历 zip 解压出来的多级目录。解决方法是先确认路径层级正确结构必须是libraries/DHT/DHT.h。如果你的 libraries 目录下同时存在 DHT 和 DHT-master 两个文件夹IDE 会优先加载其中一个也可能两个都加载然后产生重复符号建议只保留一份最干净的 DHT 目录。我一般装完库会顺手执行一次目录树检查确认头文件在正确路径后再关闭 IDE 重启很少再出现找不到库的情况。4.2 现象DHT11 读出固定 0.00 或 -999.00这大概率不是传感器坏了而是 DHT_TYPE 宏填成了 DHT22。DHT11 和 DHT22 的时序参数不同库内部靠宏决定延时长度和位判断逻辑用错了型号解析出来的 40 bit 数据全是无效值。代码层面没有报错机制因为读回的数据校验和可能恰好通过但数值永远是假的。解决方式简单直接#define DHT_TYPE DHT11改完宏删除旧固件重新上传。还有一个小坑市面上部分模块丝印写 DHT11但内部芯片实际是 DHT21 或 DHT22 的兼容替代这类模块用 DHT11 模式读可能读到的是无效值。遇到这种“怪模块”把 DHT_TYPE 挨个换一遍哪个读出的数据合理就用哪个这是最朴素的排除法。4.3 现象DHT21 一直读 NaNDHT11 在同一引脚正常硬件没坏但换成 DHT21 就读不出来常见原因有三个上电稳定时间不够、上拉电阻偏大、数据线过长。DHT21 对下降沿采样时序更敏感10kΩ 上拉在长线场景下恢复时间太长导致库读到无效位。解决步骤第一begin() 后 delay 3000ms 再进主循环第二把上拉电阻换成 4.7kΩ第三杜邦线尽量缩短在 10cm 内。如果这三个条件都满足还是 NaN换一颗传感器试一下个别批次模块内部焊点不良也会造成长期读失败。4.4 现象数值每隔几秒跳一个异常大值数据大部分时间正常偶尔冒出一个 70%RH 或者 40°C之后又恢复正常。这个现象的本质是单总线上的毛刺被当成了一位有效数据常见诱因是传感器离开关电源或者继电器太近数据线与电源线长距离并行走线。解决思路分两步硬件上让数据线远离电源线和继电器输出线软件上做滤波。最简单的做法是中位数滤波而非平均滤波连续采三次取中间值。平均滤波会把尖峰摊到结果里中位数则能直接丢弃单点异常。float stableHumidity() { float readings[3]; for (int i 0; i 3; i) { readings[i] dht.readHumidity(); delay(100); } if ((readings[0] readings[1] readings[0] readings[2]) || (readings[0] readings[1] readings[0] readings[2])) return readings[0]; if ((readings[1] readings[0] readings[1] readings[2]) || (readings[1] readings[0] readings[1] readings[2])) return readings[1]; return readings[2]; }逻辑说明三次读取之间 delay 100ms避免连续读时拿到缓存值。中间值判断逻辑兼容了相等情况返回的一定是三次读数的中位数而不是平均值。这样处理之后单次毛刺不会被纳入最终结果。4.5 现象Arduino IDE 库管理器搜不到这份库但示例能编译通过搜不到通常会让人心里打鼓但不用慌。库管理器列表依赖 library.properties 文件里的版本字段如果这份 zip 内的元数据不完整IDE 的库管理器就不会显示它。可只要头文件和源码在 libraries 目录下编译器依然能正常找到。解决不依赖库管理器列表直接用 examples 里的 .ino 编译验证。注意不要在库管理器界面里手动修改文件夹名那样会造成索引混乱重启后列表反而消失。物理上直接复制文件夹到 libraries 目录是最可靠的安装方式IDE 的扫描机制对这种手动安装的兼容性是最好的。5. 多传感器轮询与低功耗采样把库用进真实环境监控5.1 单板多传感器轮询一个 Arduino Nano 挂四路 DHT22 做空间温湿度网格测量是室内环境监测里很常见的用法。四路传感器共用 VCC 和 GND数据线分别接 D2、D3、D4、D5。代码层面就是实例化多个 DHT 对象DHT dht1(2, DHT22); DHT dht2(3, DHT22); DHT dht3(4, DHT22); DHT dht4(5, DHT22); void setup() { Serial.begin(115200); dht1.begin(); dht2.begin(); dht3.begin(); dht4.begin(); } void loop() { Serial.print(t1); Serial.print(dht1.readTemperature()); Serial.print( t2); Serial.print(dht2.readTemperature()); Serial.println(); delay(2000); }逻辑说明每个对象绑定独立引脚begin 全部调用一次loop 里逐个读取。这里最容易翻车的是把四路数据线并到同一个引脚上因为 DHT 单总线没有片选机制四颗传感器同时驱动一根线电平互相钳制结果就是全部 NaN。数据线必须一引脚一传感器。如果需要动态管理传感器数量可以用数组配合模板但在 Arduino 这种资源受限的环境里直接声明对象更直观占用的 RAM 也更容易估算。每个 DHT 对象只维护引脚、型号、私有缓冲区整体内存开销很小不用担心资源耗尽。注意轮询的读数顺序多路传感器中如果有一颗响应特别慢它会拖慢整轮循环因为库的 read 函数是阻塞式等待。对实时性要求高的场景可以把不同传感器安排在不同时隙读取防止某颗异常传感器卡住整个系统。5.2 低功耗场景睡眠唤醒与采样周期电池供电的温湿度记录仪不能一直用 delay 阻塞循环。常规做法是用 Arduino 低功耗库或者直接操作 AVR 寄存器让芯片睡眠定时唤醒后读一次传感器再睡。核心约束是传感器的采样周期DHT11 至少 1 秒DHT21 和 DHT22 至少 2 秒唤醒后立刻读会拿到缓存值或触发超时。我一般建议的时序是唤醒 → delay 300ms 让传感器内部状态稳定 → 读数据 → 处理数据 → 睡眠。睡多久取决于业务需求半小时采样一次对多数环境监测已经足够。器件状态典型电流说明Arduino Nano 睡眠约 0.2mA关闭 ADC、掉电模式DHT22 空闲约 0.2mA数据线保持高电平DHT22 读取瞬间约 1mA持续几十毫秒整体每小时采样一次平均约 0.2mA取决于唤醒次数低功耗最容易踩的坑是传感器一直供电没问题读取前没有给足稳定时间。深度睡眠唤醒后主控立刻执行 dht.readHumidity()读进一个 NaN然后马上又睡了这组数据就成了缺测值。修正方式是在读之前固定加 200ms 延时虽然浪费一点唤醒时间但换来的是高一次成功率。这里还要补一个边界知识如果要求真正的微安级功耗不能只靠传感器待机电流LDO 的静态电流往往比传感器本身还大。需要把传感器 VCC 用 MOSFET 或 IO 口控制只在采样前给传感器供电几十毫秒。但库本身不关心供电什么时候来只要保证读时序期间 VCC 稳定就可以。5.3 移植到 ESP32 及其他开发板的边界这份库面向 Arduino IDE但本质是普通 C 类ESP32、ESP8266、STM32 的 Arduino 核心都能编译。我实测过在 ESP32 上跑 DHT22只需要把 DHT_PIN 改成支持的 GPIO 编号即可。ESP32 的引脚编号不一定等于板面丝印编号比如某些开发板丝印 D4 实际是 GPIO4直接用 GPIO 号就没错。需要注意的是 ESP32 的 GPIO 输入模式默认带内部上拉但内部上拉阻值约 30kΩ-50kΩ对 DHT21 这种对上升沿敏感的传感器偏弱。我仍然会外接一个 4.7kΩ 上拉电阻不依赖内部上拉。电源用 3.3V 即可但数据线不要从 5V 模块上取电电平不匹配会造成读值漂移。STM32 通过 Arduino IDE 使用时引脚编号要参考具体板型映射不要直接套 UNO 的 D2 概念。只要硬件上拉满足条件库源码不需要改动因为单总线协议只依赖引脚高低电平翻转与底层芯片架构关系不大。如果你是做产品原型先用 Arduino 板验证传感器和算法再整体迁移到低功耗 MCU这套库代码可以原样带走。6. 十分钟验货用串口绘图仪确认库和硬件都正常拿到这份 DHT11-DHT21-DHT22 库文件.zip 后我的第一个动作不是改代码而是原样跑 examples 里的 DHTtester 示例。修改三处DHT_PIN 设置成实际接线引脚DHT_TYPE 设置成传感器型号波特率保持 115200。编译上传打开串口绘图仪Arduino IDE 的菜单路径是“工具→串口绘图仪”。串口绘图仪会同时画出两条曲线一条是湿度一条是温度。因为温湿度数值范围不同正常时曲线能看出明显区分对着传感器哈气湿度曲线从 50%RH 左右快速抬升到 70%RH 以上然后自然回落温度曲线也会跳高 0.5°C 左右再慢慢降回来。如果曲线是一条完全水平的线先用手握住传感器体加热温度曲线出现小台阶说明传感器活着若温度纹丝不动大概率是型号宏写错或接线问题。串口绘图仪还有一个容易被忽略的好处它打印的数据就是库输出的原始 float。湿度正常范围在 0-100%RH温度在传感器量程内如果你看到湿度 200%RH 这种超量程数值说明库内部解析出来的 8 bit 湿度整数位出了问题先把 DHT_TYPE 换一个排列组合试通常能解决。我习惯在验货完后把 loop 里的 delay(3000) 改成 500ms并对着传感器吹气观察波形变化这样能在十分钟内确认三件事库安装正确、硬件接线正确、传感器型号匹配。DHT 系列的“玄学”问题大多是安装和时序问题很少是芯片本身损坏。从那以后我每次拿到新的 DHT 传感器型号都强制自己先走一遍“改宏、跑示例、对着传感器哈气”的流程再也没有被莫名其妙的 NaN 骗过。这套办法如果你照着做应该也能少走几天弯路希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑