DHT11 温湿度传感器使用 - arduino - avr

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。包括一个电阻式感湿元件和一个NTC测温元件,采用单线制串行接口,超小的体积、极低功耗,信号传输距离可达20米以上。产品为 4 针单排引脚封装。测量分辨率分别为 8bit(温度)、8bit(湿度)。


DHT11 温湿度传感器使用 - arduino - avr_第1张图片


典型应用电路
DHT11 温湿度传感器使用 - arduino - avr_第2张图片


使用注意
DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。


微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.
操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据+8bit校验和
数据传送正确时校验和数据 等于 8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据 所得结果的末8位。

用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.
从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
通讯过程
DHT11 温湿度传感器使用 - arduino - avr_第3张图片
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
DHT11 温湿度传感器使用 - arduino - avr_第4张图片

总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。

数字0信号表示方法
DHT11 温湿度传感器使用 - arduino - avr_第5张图片
数字1信号表示方法
DHT11 温湿度传感器使用 - arduino - avr_第6张图片

封装
DHT11 温湿度传感器使用 - arduino - avr_第7张图片
DHT11 温湿度传感器使用 - arduino - avr_第8张图片


程序

// DHT11 temperature
// [email protected]
// arduino nano
// arduino lite
#include "arduino_lit.h"
#define DHT11Pin 2
//Test the DHT11 -- [email protected]
byte dat[5];   // 存放湿度2byte, 温度 2 byte, checksum 1 byte
byte readData() { // 每次读取 8 bits  ( one byte)
  byte data;
  for(int i=0; i<8; i++) {
    if(digitalRead(DHT11Pin) == LOW)
    {
      // 一开始要 LOW 才表示要传过来
      while(digitalRead(DHT11Pin) == LOW); //等待 50us;
      // 现在已经变成 HIGH 了
      _delay_us(30); //判断高电平持续时间,以判定资料是‘0’还是‘1’;
      if(digitalRead(DHT11Pin) == HIGH)  // 根据时序持续了 30 us 以上就是 1
      data |= (1<<(7-i)); //高位在前,低位元在后;
      //如果这时已经是 LOW, 表示这 bit 是 0, 不必塞入 data
      //..而且以下的 while 也会立即结束(因为 LOW), 准备接收下一个 bit
      while(digitalRead(DHT11Pin) == HIGH); // 等待下一bit的接收;
      //这时一定已经变成 LOW 了
    }
  }
  return data;   // 收完 8 bit = one byte = one char
}
void start_dht11(){  // 每次要与 DHT11 沟通
  DIGITAL_WRITE(DHT11Pin,LOW); //拉低到 LOW,发表示要开始沟通的信号;
  _delay_ms(30); //延时要大于 18ms,以便 DHT11 能检测到开始信号;这里用30ms

  DIGITAL_WRITE(DHT11Pin,HIGH);   // 拉高HIGH, 让 DHT11 拉低到 LOW 告诉我们要传送
  _delay_us(40);  // 给40us等待 DHT11 响应;
  PIN_MODE(DHT11Pin,INPUT);  // 改为输入 mode 准备 digitalRead( )

  while(DIGITAL_READ(DHT11Pin) == HIGH);   // 必须等到 LOW
  _delay_us(80); //DHT11 发出响应,会拉低 80us;所以至少等80us
  while(DIGITAL_READ(DHT11Pin) == LOW);  // 继续等到变 HIGH
  _delay_us(80); //DHT11 会拉高到HIGH 80us 后开始发送资料;
  /// 以下连续读入 5 bytes (40 bits), 最后的 byte 是 checksum 校验值
  for(int i=0;i < 5;i++)
    dat[i] = readData( ); //接收温湿度资料,校验;
  PIN_MODE(DHT11Pin,OUTPUT);  // 改为 Output mode, 准备拉高HIGH
  DIGITAL_WRITE(DHT11Pin,HIGH); //发送完一次资料后释放bus,等待下一次开始信号;
}
void setup() {
  SERIAL_BEGIN();
  PIN_MODE(DHT11Pin, OUTPUT);
}
void loop() {
  start_dht11();  // 读取湿度温度和检核位到 dat[ ]; 其中dat[4]是checkSum
  // 根据datasheet规定, dat[4] 要 == (dat[0]+dat[1]+dat[2]+dat[3]) %256
  // 否则表示沟通有错误 !!
  PRINT("current humidity = ");
  println(dat[0] & 0xff,10,serial_puts);

  PRINT("current temperature = ");
  println(dat[2] & 0xff, 10,serial_puts); //显示温度的整数部分;
  _delay_ms(2000);
} 
int main()
{
  setup();
  while(1)
    loop();
}

你可能感兴趣的:(AVR,&,Arduino)