基於arduino的dht11溫濕度傳感器的使用


DHT11庫文件下載

 

Arduino不調用庫實現DHT11數據讀取

 

  DHT11是一款有已校准數字信號輸出的溫濕度傳感器。 其精度濕度+-5%RH, 溫度+-2℃,量程濕度20-90%RH, 溫度0~50℃。

  DHT11數字溫濕度傳感器是一款含有已校准數字信號輸出的溫濕度復合傳感器,它應用專用的數字模塊采集技術和溫濕度傳感技術,確保產品具有極高的可靠性和卓越的長期穩定性。傳感器包括一個電阻式感濕元件和一個NTC測溫元件,並與一個高性能8位單片機相連接。因此該產品具有品質卓越、超快響應、抗干擾能力強、性價比極高等優點。每個DHT11傳感器都在極為精確的濕度校驗室中進行校准。校准系數以程序的形式存在OTP內存中,傳感器內部在檢測信號的處理過程中要調用這些校准系數。單線制串行接口,使系統集成變得簡易快捷。超小的體積、極低的功耗,信號傳輸距離可達 20 米以上,使其成為該類應用中,在苛刻應用場合的最佳選擇。產品為4針單排引腳封裝,連接方便。DHT11溫濕度傳感器常應用於暖通空調、汽車 、 消費品 、 濕度調節器 、 除濕器、醫療、自動控制等領域。

 

  DHT11溫濕度傳感器電氣特性

基於arduino的dht11溫濕度傳感器的使用

  溫濕度傳感器DHT11封裝形式及接口說明

  建議連接線長度短於20米時用5K上拉電阻,大於20米時根據實際情況使用合適的上拉電阻(若購買的是已集成的模塊,模塊上已加上拉電阻,以下請忽略),當然,如果你想要精簡電路的話, STC增強型單片機自帶的推挽輸出功能不失為一個選擇,其相當於外接了一個2k的上拉電阻,但在設計電路時需注意:整個單片機的電流推薦不超過55mA,即從MCU-VCC流入的電流不超過55mA,從MCU-GND流出的電流不超過55mA,整體流入、流出電流均不超過55mA,封裝尺寸及典型應用電路圖如下圖所示。

基於arduino的dht11溫濕度傳感器的使用

  DHT11溫濕度傳感器典型應用電路

基於arduino的dht11溫濕度傳感器的使用

  DHT11溫濕度傳感器時序圖

基於arduino的dht11溫濕度傳感器的使用

  DHT11溫濕度傳感器連接圖

 

 將DHT11的正極與5V電源接口相連,負極與GND相連,中間的數據接口與2號引腳相連。

  代碼

 

#include <dht11.h>

dht11 DHT11;
#define DHT11PIN 3

void setup(){
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM");
  Serial.print("LIBRARY VERSION:");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
}

void loop(){
Serial.println("\n");
int chk=DHT11.read(DHT11PIN);
Serial.println("Read sensor: ");
      
switch(chk){
  case DHTLIB_OK:
       Serial.println("OK");
       break;
  case DHTLIB_ERROR_CHECKSUM:
       Serial.println("Checksum error");
       break;
  case DHTLIB_ERROR_TIMEOUT:
       Serial.println("Time out error");
       break;
  default:
       Serial.println("Unknown error");
       break;
  }

Serial.print("Humidity (%): ");
Serial.println((float)DHT11.humidity, 2);
Serial.print("Temperature (oC): ");
Serial.println((float)DHT11.temperature, 2);
  
delay(2000);
}

  

  注意事項

  1、代碼中引用了#include <dht11.h>,這個是操作DHT11的庫文件,有了它,就可以輕松操作我們這個溫濕度傳感器了。但是引用這個庫文件的操作步驟是:

  (1)在網上找到並下載該庫文件,包括一個頭文件和一個.cpp文件。

  (2)在arduino IDE中點擊菜單:程序–導入庫–add library,然后選擇你存放庫文件的那個文件夾。

  (3)在代碼中引用#include <dht11.h>,這樣就可以使用了。

  2、#define DHT11PIN 3,表示定義引腳3的名字為DHT11PIN ,注意這個定義語句后面沒有分號。

  原理分析

  在硬件編程過程中,當你拿到一個器件,首先要了解他的引腳定義,這會告訴你這個東西應該怎么連接,在一個就是要看他的時序圖,看了時序圖你就知道主從設備之間進行數據采集過程中的代碼應該怎么寫,比如怎么啟動,如何握手,怎么采集真正的數據等等。

  在我們這個試驗中,DHT11的時序圖是這樣的:

基於arduino的dht11溫濕度傳感器的使用

 

  DHT11溫濕度傳感器使用注意事項

  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不會主動進行溫濕度采集。采集數據后轉換到低速模式。

  通訊過程

基於arduino的dht11溫濕度傳感器的使用

  總線空閑狀態為高電平,主機把總線拉低等待DHT11響應,主機把總線拉低必須大於18毫秒,保證DHT11能檢測到起始信號。DHT11接收到主機的開始信號后,等待主機開始信號結束,然后發送80us低電平響應信號。主機發送開始信號結束后,延時等待20-40us后,讀取DHT11的響應信號,主機發送開始信號后,可以切換到輸入模式,或者輸出高電平均可,總線由上拉電阻拉高。

基於arduino的dht11溫濕度傳感器的使用

  總線為低電平,說明DHT11發送響應信號,DHT11發送響應信號后,再把總線拉高80us,准備發送數據,每一bit數據都以50us低電平時隙開始,高電平的長短定了數據位是0還是1.格式見下面圖示。如果讀取響應信號為高電平,則DHT11沒有響應,請檢查線路是否連接正常。當最后一bit數據傳送完畢后,DHT11拉低總線50us,隨后總線由上拉電阻拉高進入空閑狀態。

  數字0信號表示方法

基於arduino的dht11溫濕度傳感器的使用

  數字1信號表示方法

基於arduino的dht11溫濕度傳感器的使用

 

通訊步驟

根據時序定義來完成通訊過程

  1. 總線空閑狀態為高電平HIGH,主機把總線拉低LOW等待DHT11響應,主機把總線拉低必須大於18ms,保證DHT11能檢測到起始信號;
  2. 主機把總線拉高HIGH, 延遲等待20-40ms讓DHT11 把總線拉低到LOW ;
  3. 主機檢測到總線為LOW后延遲等待80us;
  4. 主機檢測到總線為HIGH后繼續延遲等待80us即可開始進行數據讀取;
  5. 主機等待50us,當檢測到總線為HIGH時,延時30us再次檢測總線狀態,根據時序圖定義,高電平持續時間大於30us時候為1小於為0即可獲取到數據,不斷重復8次即可獲取到1字節的數據;
  6. 重復執行步驟5,5次即可獲取到全部的數據

 

  程序:

//Test the DHT11
int dhPin = 3;  // 溫濕度信號接腳連入 Arduino 的 Pin 3
byte dat[5];   // 存放濕度2byte, 溫度 2 byte, checksum 1 byte
byte readData() {  // 每次讀取 8 bits  ( one byte)
  byte data = 0 ; // 初始化數據,不然可能出錯
  for (int i = 0; i < 8; i++) {
    if (digitalRead(dhPin) == LOW) {  // 一開始要 LOW 才表示要傳過來
      while (digitalRead(dhPin) == LOW); //等待 50us;
      // 現在已經變成 HIGH 了
      delayMicroseconds(30); //判斷高電平持續時間,以判定資料是‘0’還是‘1’;
      if (digitalRead(dhPin) == HIGH) // 持續了 30 us 以上就是 1
        data |= (1 << (7 - i)); //高位在前,低位元在后;
      //如果這時已經是 LOW, 表示這 bit 是 0, 不必塞入 data
      //..而且以下的 while 也會立即結束(因為 LOW), 准備接收下一個 bit
      while (digitalRead(dhPin) == HIGH); // 等待下一bit的接收;
      //這時一定已經變成 LOW 了
    }
  }
  return data;   // 收完 8 bit = one byte = one char
}
void start_test(  ) {  // 每次要與 DHT11 溝通
  digitalWrite(dhPin, LOW); //拉低到 LOW,發送表示要開始溝通的信號;
  delay(30); //延時要大於 18ms,以便 DHT11 能檢測到開始信號;我們用30ms
  digitalWrite(dhPin, HIGH);  // 拉高HIGH, 讓 DHT11 拉低到 LOW 告訴我們要傳送
  delayMicroseconds(40);  // 給40us等待 DHT11 響應;
  pinMode(dhPin, INPUT); // 改為輸入 mode 准備 digitalRead( )
  while (digitalRead(dhPin) == HIGH);  // 必須等到 LOW
  delayMicroseconds(80); //DHT11 發出響應,會拉低 80us;所以至少等80us
  while (digitalRead(dhPin) == LOW); // 繼續等到變 HIGH
  delayMicroseconds(80); //DHT11 會拉高到HIGH 80us 后開始發送數據;
  /// 以下連續讀入 5 bytes (40 bits), 最后的 byte 是 checksum 校驗值
  for (int i = 0; i < 5; i++) dat[i] = readData(); //接收溫濕度資料,校驗位元;
  pinMode(dhPin, OUTPUT); // 改為 Output mode, 准備拉高HIGH
  digitalWrite(dhPin, HIGH); //發送完一次資料后釋放bus,等待下一次開始信號;
}
void setup(  ) {
  Serial.begin(9600);
  Serial.println("begin!");
  pinMode(dhPin, OUTPUT);
}
void loop(  ) {
  start_test( );  // 讀取濕度溫度和檢核位到 dat[ ]; 其中dat[4]是checkSum
  // 根據datasheet規定, dat[4] 要 == (dat[0]+dat[1]+dat[2]+dat[3]) %256
  // 否則表示溝通有錯誤 !!
  Serial.print("Current humdity = ");
  Serial.print(dat[0], DEC); //顯示濕度的整數部分;
  Serial.print('.');
  Serial.print(dat[1], DEC); //顯示濕度的小數位;(其實是 0)
  Serial.println(" %");  // 注意有空格要用 " %"  不可用 ' %'
  Serial.print("Current temperature = ");
  Serial.print(dat[2], DEC); //顯示溫度的整數部分;
  Serial.print('.');
  Serial.print(dat[3], DEC); //顯示溫度的小數位;(其實是 0)
  Serial.println(" C");
  delay(1985);
}

DHT11通信波形;測試平台Arduino Due

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM