数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 3410|回复: 3

[Arduino] Arduino读取DHT11,DHT22,SHTC3温湿度数据

[复制链接]
发表于 2020-5-9 14:15:10 | 显示全部楼层 |阅读模式
本帖最后由 Meise 于 2020-5-9 15:53 编辑

本文章讲解使用NodeMcu开发板读取DHT11、DHT22、SHTC3这三个温湿度传感器的数据并发送至串口。各传感器我都写了使用第三方库和不用第三方库的例程。
ESP8266开发环境搭建教程:https://blog.zeruns.tech/archives/526.html
文中所用到传感器购买地址在文章最下面。

DHT11
DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH, 温度0~50℃。精度不高,但价格低廉。DHT11使用单总线通信。供电电压3.3~5V。


使用DHT库
使用DHT sensor library库(需自己安装,安装教程在上面的ESP8266开发环境搭建教程中)来直接读取DHT11的数据。
  1. #include <DHT.h>        //调用DHT库

  2. DHT dht(D1,DHT11);      //设置Data引脚所接IO口和传感器类型

  3. void setup(){ //初始化函数,只在程序开始时运行一次
  4.   Serial.begin(115200);   //设置串口波特率
  5.   dht.begin();            
  6. }
  7. //https://blog.zeruns.tech
  8. void loop() {
  9.   delay(1000);                  //延时1000毫秒
  10.   float RH = dht.readHumidity();   //读取湿度数据
  11.   float T = dht.readTemperature();//读取温度数据
  12.   Serial.print("Humidity:");  //向串口打印 Humidity:
  13.   Serial.print(RH);           //向串口打印湿度数据
  14.   Serial.print("%");
  15.   Serial.print("  Temperature:");
  16.   Serial.print(T);            //向串口打印温度数据
  17.   Serial.println("C");
  18.   Serial.println("https://blog.zeruns.tech");
  19. }
复制代码

不使用库
通过阅读DHT11的数据手册自己编写程序读取数据。
DHT11数据手册:http://go.zeruns.tech/G
  1. #define data D1   //DHT11的Data引脚(2Pin)接到NodeMcu开发板的D1引脚

  2. unsigned char i;  //无符号8位整型变量
  3. float RH,T;       //单精度浮点数(32位长度)
  4. byte RH_H,RH_L,T_H,T_L,sum,check;  //字节变量,二进制数

  5. void setup() {    //初始化函数,只在程序开始时运行一次
  6.   Serial.begin(115200);   //设置串口波特率
  7. }

  8. void loop() {     //循环函数,运行完初始化函数后不断循环运行这个函数
  9.   delay(1000);    //延时1000毫秒
  10.   DHT11();        //获取温湿度数据
  11.   Serial.print("Humidity:");  //向串口打印 Humidity:
  12.   Serial.print(RH);           //向串口打印湿度数据
  13.   Serial.print("%");
  14.   Serial.print("  Temperature:");
  15.   Serial.print(T);            //向串口打印温度数据
  16.   Serial.println("C");
  17.   Serial.println("https://blog.zeruns.tech");
  18. }

  19. void DHT11()
  20. {
  21.   RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
  22.   pinMode(data,OUTPUT);   //设置IO口为输出模式
  23.   digitalWrite(data,1);   //设置IO口输出高电平
  24.   delay(10);              //延时10毫秒
  25.   digitalWrite(data,0);   //设置IO口输出低电平
  26.   delay(25);              //延时25毫秒
  27.   digitalWrite(data,1);   //设置IO口输出高电平
  28.   pinMode(data,INPUT);    //设置IO口为输入模式
  29.   delayMicroseconds(30);  //延时30微秒
  30.   if(!digitalRead(data))  //判断IO口输入电平是否低电平
  31.   {//https://blog.zeruns.tech
  32.     while(!digitalRead(data));  //一直循环至输入为高电平
  33.     while(digitalRead(data));   //一直循环至输入为低电平
  34.     for(i=0;i<8;i++)            //循环执行8次
  35.     {   
  36.       while(!digitalRead(data));//一直循环至输入为高电平   
  37.       delayMicroseconds(28);    //延时28微秒
  38.       if(digitalRead(data)){    //判断IO口输入电平是否高电平
  39.         bitWrite(RH_H, 7-i, 1); //在二进制变量RH_H的第7-i位(从右数起)写入1     
  40.         while(digitalRead(data));
  41.       }
  42.     }
  43.     for(i=0;i<8;i++)
  44.     {
  45.       while(!digitalRead(data));
  46.       delayMicroseconds(28);
  47.       if(digitalRead(data)){
  48.         bitWrite(RH_L, 7-i, 1);
  49.         while(digitalRead(data));
  50.       }
  51.     }
  52.     for(i=0;i<8;i++)
  53.     {
  54.       while(!digitalRead(data));
  55.       delayMicroseconds(28);
  56.       if(digitalRead(data)){      
  57.         bitWrite(T_H, 7-i, 1);
  58.         while(digitalRead(data));
  59.       }
  60.     }
  61.     for(i=0;i<8;i++)
  62.     {
  63.       while(!digitalRead(data));
  64.       delayMicroseconds(28);
  65.       if(digitalRead(data)){      
  66.         bitWrite(T_L, 7-i, 1);
  67.         while(digitalRead(data));
  68.       }
  69.     }
  70.     for(i=0;i<8;i++)
  71.     {
  72.       while(!digitalRead(data));
  73.       delayMicroseconds(28);
  74.       if(digitalRead(data)){      
  75.         bitWrite(check, 7-i, 1);
  76.         while(digitalRead(data));
  77.       }
  78.     }
  79.    }
  80.   sum=RH_H + RH_L + T_H + T_L;
  81.   byte sum_temp=0;
  82.   //读取sum的末8位写入sum_temp
  83.   for(i=0;i<8;i++){
  84.     bitWrite(sum_temp,i,bitRead(sum,i));
  85.   }//https://blog.zeruns.tech
  86.   if(check==sum_temp){  //校验数据
  87.     RH=RH_H+float(RH_L)/10;
  88.     T=T_H+float(T_L)/10;
  89.   }
  90. }
复制代码

效果图


DHT22(AM2302)
DHT22(AM2302)是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±2%RH, 温度±0.5℃,量程湿度0-100%RH, 温度-40~80℃,分辨率都为0.1。精度较高,且价格不贵。DHT22使用单总线通信。供电电压3.3~5V。


使用DHT库
使用DHT sensor library库来直接读取DHT22的数据。
  1. #include <DHT.h>        //调用DHT库

  2. DHT dht(D1,DHT22);      //设置Data引脚所接IO口和传感器类型

  3. void setup(){ //初始化函数,只在程序开始时运行一次
  4.   Serial.begin(115200);   //设置串口波特率
  5.   dht.begin();            
  6. }
  7. //https://blog.zeruns.tech
  8. void loop() {
  9.   delay(1000);                  //延时1000毫秒
  10.   float RH = dht.readHumidity();   //读取湿度数据
  11.   float T = dht.readTemperature();//读取温度数据
  12.   Serial.print("Humidity:");  //向串口打印 Humidity:
  13.   Serial.print(RH);           //向串口打印湿度数据
  14.   Serial.print("%");
  15.   Serial.print("  Temperature:");
  16.   Serial.print(T);            //向串口打印温度数据
  17.   Serial.println("C");
  18.   Serial.println("https://blog.zeruns.tech");
  19. }
复制代码

不使用库
通过阅读DHT22的数据手册自己编写程序读取数据。
DHT22数据手册:http://go.zeruns.tech/H
  1. #define data D1   //DHT22的Data引脚(2Pin)接到NodeMcu开发板的D1引脚

  2. unsigned char i;  //无符号8位整型变量
  3. float RH,T;       //单精度浮点数(32位长度)
  4. byte RH_H,RH_L,T_H,T_L,sum,check;  //字节变量,二进制数

  5. void setup() {    //初始化函数,只在程序开始时运行一次
  6.   Serial.begin(115200);   //设置串口波特率
  7. }

  8. void loop() {     //循环函数,运行完初始化函数后不断循环运行这个函数
  9.   delay(1000);    //延时1000毫秒
  10.   DHT11();        //获取温湿度数据
  11.   Serial.print("Humidity:");  //向串口打印 Humidity:
  12.   Serial.print(RH);           //向串口打印湿度数据
  13.   Serial.print("%");
  14.   Serial.print("  Temperature:");
  15.   Serial.print(T);            //向串口打印温度数据
  16.   Serial.println("C");
  17.   Serial.println("https://blog.zeruns.tech");
  18. }

  19. void DHT11()
  20. {
  21.   RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
  22.   pinMode(data,OUTPUT);   //设置IO口为输出模式
  23.   digitalWrite(data,1);   //设置IO口输出高电平
  24.   delay(10);              //延时10毫秒
  25.   digitalWrite(data,0);   //设置IO口输出低电平
  26.   delay(25);              //延时25毫秒
  27.   digitalWrite(data,1);   //设置IO口输出高电平
  28.   pinMode(data,INPUT);    //设置IO口为输入模式
  29.   delayMicroseconds(30);  //延时30微秒
  30.   if(!digitalRead(data))  //判断IO口输入电平是否低电平
  31.   {//https://blog.zeruns.tech
  32.     while(!digitalRead(data));  //一直循环至输入为高电平
  33.     while(digitalRead(data));   //一直循环至输入为低电平
  34.     for(i=0;i<8;i++)            //循环执行8次
  35.     {   
  36.       while(!digitalRead(data));//一直循环至输入为高电平   
  37.       delayMicroseconds(28);    //延时28微秒
  38.       if(digitalRead(data)){    //判断IO口输入电平是否高电平
  39.         bitWrite(RH_H, 7-i, 1); //在二进制变量RH_H的第7-i位(从右数起)写入1     
  40.         while(digitalRead(data));
  41.       }
  42.     }
  43.     for(i=0;i<8;i++)
  44.     {
  45.       while(!digitalRead(data));
  46.       delayMicroseconds(28);
  47.       if(digitalRead(data)){
  48.         bitWrite(RH_L, 7-i, 1);
  49.         while(digitalRead(data));
  50.       }
  51.     }
  52.     for(i=0;i<8;i++)
  53.     {
  54.       while(!digitalRead(data));
  55.       delayMicroseconds(28);
  56.       if(digitalRead(data)){      
  57.         bitWrite(T_H, 7-i, 1);
  58.         while(digitalRead(data));
  59.       }
  60.     }
  61.     for(i=0;i<8;i++)
  62.     {
  63.       while(!digitalRead(data));
  64.       delayMicroseconds(28);
  65.       if(digitalRead(data)){      
  66.         bitWrite(T_L, 7-i, 1);
  67.         while(digitalRead(data));
  68.       }
  69.     }
  70.     for(i=0;i<8;i++)
  71.     {
  72.       while(!digitalRead(data));
  73.       delayMicroseconds(28);
  74.       if(digitalRead(data)){      
  75.         bitWrite(check, 7-i, 1);
  76.         while(digitalRead(data));
  77.       }
  78.     }
  79.    }
  80.   sum=RH_H + RH_L + T_H + T_L;
  81.   byte sum_temp=0;
  82.   //读取sum的末8位写入sum_temp
  83.   for(i=0;i<8;i++){
  84.     bitWrite(sum_temp,i,bitRead(sum,i));
  85.   }//https://blog.zeruns.tech
  86.   if(check==sum_temp){
  87.     if(bitRead(RH_H,7)==1){ //判断温度是否零下
  88.       T=-(float(T_H<<8)+float(T_L))/10;
  89.     }else{
  90.       T=(float(T_H<<8)+float(T_L))/10;
  91.     }
  92.     RH=(float(RH_H<<8)+float(RH_L))/10;
  93.   }  
  94. }
复制代码

效果图


SHTC3
SHTC3是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±2%RH, 温度±0.2℃,量程湿度0-100%RH, 温度-40~125℃,分辨率都为0.01。精度高,且价格也较便宜,但资料太少了。SHTC3使用I2C(IIC)通信。供电电压1.62~3.6V。
SHTC3数据手册:http://go.zeruns.tech/I


使用Wire(I2C)库
使用Wire库来与SHTC3通信读取数据。
  1. /* https://blog.zeruns.tech
  2. * 连接方式
  3. * SHTC3    开发板
  4. * SCL      SCL(NodeMcu开发板是D1)
  5. * SDA      SDA(NodeMcu开发板是D2)
  6. */
  7. #include <Wire.h>

  8. #define SHTC3_ADDRESS 0x70  //定义SHTC3的I2C器件地址为0x70
  9. float T,RH;

  10. void setup() {    //初始化函数,只在程序开始时运行一次
  11.   Serial.begin(115200);   //设置串口波特率
  12.   Wire.begin();   //初始化为I2C主机
  13. }

  14. void loop() {     //循环函数,运行完初始化函数后不断循环运行这个函数
  15.   delay(1000);    //延时1000毫秒
  16.   SHTC3();        //获取温湿度数据
  17.   Serial.print("Humidity:");  //向串口打印 Humidity:
  18.   Serial.print(RH);           //向串口打印湿度数据
  19.   Serial.print("%");
  20.   Serial.print("  Temperature:");
  21.   Serial.print(T);            //向串口打印温度数据
  22.   Serial.println("C");
  23.   Serial.println("https://blog.zeruns.tech");
  24. }

  25. void SHTC3(){   //获取温湿度数据
  26.   Wire.beginTransmission(SHTC3_ADDRESS); //根据地址0x70,开始向I2C的从机进行传输。
  27.   Wire.write(byte(0xE0));       //发送写入指令
  28.   Wire.endTransmission();       //停止向从机传输
  29.   Wire.beginTransmission(SHTC3_ADDRESS);
  30.   Wire.write(byte(0x35));       //发送唤醒指令的高位部分
  31.   Wire.write(byte(0x17));       //发送唤醒指令的低位部分
  32.   Wire.endTransmission();
  33.   delayMicroseconds(300);       //延时300微秒
  34.   Wire.beginTransmission(SHTC3_ADDRESS);
  35.   Wire.write(byte(0xE0));
  36.   Wire.endTransmission();
  37.   Wire.beginTransmission(SHTC3_ADDRESS);
  38.   Wire.write(byte(0x7C));       //发送采集指令的高位部分
  39.   Wire.write(byte(0xA2));       //发送采集指令的低位部分
  40.   Wire.endTransmission();
  41.   Wire.beginTransmission(SHTC3_ADDRESS);
  42.   Wire.write(byte(0xE1));       //发送读取指令
  43.   Wire.endTransmission();
  44.   Wire.requestFrom(SHTC3_ADDRESS,6);     //向从机请求数据
  45.   uint16_t T_temp,RH_temp,T_CRC,RH_CRC;
  46.   if (2 <= Wire.available()) {
  47.     T_temp = Wire.read();     //接收温度高位数据
  48.     T_temp = T_temp << 8;     //左移8位
  49.     T_temp |= Wire.read();    //左移8位后的温度高位数据与接收到的温度低位数据进行按位或运算
  50.     T_CRC = Wire.read();      //接收CRC校验码
  51.     if(SHTC3_CRC_CHECK(T_temp,T_CRC)){  //校验数据
  52.       T =float(T_temp) * 175 / 65536 - 45;  //计算出温度
  53.     }
  54.   }//https://blog.zeruns.tech
  55.   if (2 <= Wire.available()) {
  56.     RH_temp = Wire.read();     //接收湿度高位数据
  57.     RH_temp = RH_temp << 8;     //左移8位
  58.     RH_temp |= Wire.read();    //左移8位后的湿度高位数据与接收到的湿度低位数据进行按位或运算
  59.     RH_CRC = Wire.read();
  60.     if(SHTC3_CRC_CHECK(RH_temp,RH_CRC)){
  61.       RH =float(RH_temp) * 100 / 65536;
  62.     }
  63.   }
  64. }
  65. //https://blog.zeruns.tech
  66. uint8_t SHTC3_CRC_CHECK(uint16_t DAT,uint8_t CRC_DAT) //SHTC3的CRC校验
  67. {
  68.     uint8_t i,t,temp;
  69.     uint8_t CRC_BYTE;  
  70.     CRC_BYTE = 0xFF;  
  71.     temp = (DAT>>8) & 0xFF;        
  72.     for(t = 0;t < 2;t ++)
  73.     {
  74.         CRC_BYTE ^= temp;
  75.         for(i = 0;i < 8;i ++)
  76.         {
  77.             if(CRC_BYTE & 0x80)
  78.             {
  79.                 CRC_BYTE <<= 1;               
  80.                 CRC_BYTE ^= 0x31;   
  81.             }else{
  82.                 CRC_BYTE <<= 1;   
  83.             }
  84.         }        
  85.         if(t == 0)
  86.         {
  87.             temp = DAT & 0xFF;
  88.         }
  89.     }//https://blog.zeruns.tech   
  90.     if(CRC_BYTE == CRC_DAT)
  91.     {
  92.         temp = 1;   
  93.     }else{
  94.         temp = 0;   
  95.     }   
  96.     return temp;
  97. }
复制代码
使用SHTC3库
先安装SparkFun SHTC3库。
  1. /* https://blog.zeruns.tech
  2. * 连接方式
  3. * SHTC3    开发板
  4. * SCL      SCL(NodeMcu开发板是D1)
  5. * SDA      SDA(NodeMcu开发板是D2)
  6. */

  7. #include <SparkFun_SHTC3.h>

  8. SHTC3 mySHTC3;

  9. void setup(){ //初始化函数,只在程序开始时运行一次
  10.   Serial.begin(115200);   //设置串口波特率
  11.   while(Serial == false){};   //等待串行连接启动
  12.   Wire.begin();           //初始化Wire(IIC)库
  13.   unsigned char i=0;
  14.   errorDecoder(mySHTC3.begin());// To start the sensor you must call "begin()", the default settings use Wire (default Arduino I2C port)
  15. }
  16. //https://blog.zeruns.tech
  17. void loop() {
  18.   float RH,T;
  19.   delay(1000);                  //延时1000毫秒
  20.   SHTC3_Status_TypeDef result = mySHTC3.update();
  21.   if(mySHTC3.lastStatus == SHTC3_Status_Nominal)   //判断SHTC3状态是否正常
  22.   {
  23.     RH = mySHTC3.toPercent();   //读取湿度数据                       
  24.     T = mySHTC3.toDegC();       //读取温度数据                    
  25.   }else{
  26.     Serial.print("Update failed, error: ");
  27.     errorDecoder(mySHTC3.lastStatus); //输出错误原因
  28.     Serial.println();
  29.   }
  30.   Serial.print("Humidity:");  //向串口打印 Humidity:
  31.   Serial.print(RH);           //向串口打印湿度数据
  32.   Serial.print("%");
  33.   Serial.print("  Temperature:");
  34.   Serial.print(T);            //向串口打印温度数据
  35.   Serial.println("C");
  36.   Serial.println("https://blog.zeruns.tech");
  37. }

  38. void errorDecoder(SHTC3_Status_TypeDef message) // The errorDecoder function prints "SHTC3_Status_TypeDef" resultsin a human-friendly way
  39. {
  40.   switch(message)
  41.   {
  42.     case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
  43.     case SHTC3_Status_Error : Serial.print("Error"); break;
  44.     case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
  45.     default : Serial.print("Unknown return code"); break;
  46.   }
  47. }
复制代码

效果图


传感器购买
DHT11:复制$Lk3h1Mx8UTO$打开手机淘宝立即下单
DHT22:复制$kr2T1MxkUKY$打开手机淘宝立即下单
SHTC3:复制$UD4D1Mx6N3R$打开手机淘宝立即下单

推荐阅读:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 1家元 +40 收起 理由
家睦 + 40

查看全部打赏

发表于 2021-10-12 18:56:37 | 显示全部楼层
你的代码有问题不使用第3方库运行会报错
回复 支持 反对

使用道具 举报

发表于 2021-10-12 21:38:51 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-10-12 22:57 编辑

以前用stm32玩过, 用了3种方法, 软件判断,定时器输入捕获,定时器PWM模式, 都能工作, 后面2种可靠性更好




回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-19 05:00 , Processed in 0.109200 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表