DHT11溫溼度傳感器模塊使用方法和驅動代碼實現

DHT11模塊簡介

DHT11是一款價格便宜,易於使用的溫度溼度測量二合一傳感器。它具備超小體積、極低功耗的特色。它使用單根總線與單片機進行雙向的串行數據傳輸,信號傳輸距離可達20米以上。很是適用於對精度和實時性要求不高的溫溼度測量場合。php

本文將以DFRobot開源硬件平臺的DHT11模塊和DFRduino開發板來演示,講解DHT11的驅動和使用。html

DHT11電氣參數git

電源電壓:3~5.5V(典型值:5V);數組

溫度量程:0~50℃,偏差 ±2℃;函數

溼度量程:20~90%RH,偏差 ±5%RH;oop

採樣週期:大於等於1秒/次。學習

 

DHT11硬件原理圖

數據總線DATA使用上拉電阻拉高,所以總線空閒時爲高電平。上拉電阻阻值推薦範圍:4.7K~5.1K。測試

必要時在VDD和GND之間並一個100nF的去耦電容。ui

 

 

DHT11的工做原理

DHT11使用單一總線通訊,即DATA引腳和單片機鏈接的線。總線老是處於空閒狀態通訊狀態這個2個狀態之間。spa

當單片機沒有與DHT11交互時,總線處於空閒狀態,在上拉電阻的做用下,處於高電平狀態。

當單片機和DHT11正在通訊時,總線處於通訊狀態,一次完整的通訊過程以下:

①單片機將驅動總線的IO配置爲輸出模式。準備向DHT11發送數據。

②單片機將總線拉低至少18ms,以此來發送起始信號。再將總線拉高並延時20~40us,以此來表明起始信號結束。

③單片機將驅動總線的IO配置爲輸入模式,準備接收DHT11回傳的數據。

④當DHT11檢測倒單片機發送的起始信號後,就開始應答,回傳採集到的傳感器數據。DHT11先將總線拉低80us做爲對單片機的應答(ACK),而後接着將總線拉高80us,準備回傳採集到的溫溼度數據。溫溼度數據以固定的幀格式發送,具體格式以下圖:

能夠發現一幀爲40個bit,而每個bit的傳輸時序邏輯爲:每個bit都以50us的低電平(DHT11將總線拉低)爲先導,而後緊接着DHT11拉高總線,若是這個高電平持續時間爲26~28us,則表明邏輯0,若是持續70us則表明邏輯1。

⑤當一幀數據傳輸完成後,DHT11釋放總線,總線在上拉電阻的做用下再次恢復到高電平狀態。 

 

注意事項

一、DHT11上電後,要等待 1秒 以越過不穩定狀態,在此期間不能發送任何指令。

二、DHT11屬於低速傳感器,兩次通訊請求之間的間隔時間不能過短,通常來講要不能低於1秒。 

三、當前DHT11通訊幀的小數部分默認都是0,廠商預留給之後實現。因此通常只讀取整數值部分便可。校驗和定義爲:前4個Byte的總和的低8位。

Ardunio驅動代碼

在DFRobot官網能夠找到DHT11模塊驅動庫,但出於學習和講解的目的,下面給出了我本身的驅動實現源代碼。使用C語言編寫,並在Arduino上測試。

//file:dht11.h
//author:lulipro
//date:2019-5-5


#ifndef DHT11_H__
#define DHT11_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif


#define DHT11_OK         (0)     //讀取成功
#define DHT11_TIMEOUT    (-1)    //DHT11響應超時
#define DHT11_CHECKERROR (-2)    //數據幀校驗錯誤

void DHT11_init(uint8_t pin);
int  DHT11_read(uint8_t* temperature,uint8_t* humidity );


#ifdef __cplusplus
}
#endif

#endif

 

 

//file:dht11.c
//author:lulipro
//date:2019-5-5



#include "dht11.h"


#include <Arduino.h>                  //for pinMode(),delay() 等
#include <string.h>                   //for memset()

static uint8_t DHT11_dataPin_;       //驅動DHT11的數據線引腳
static uint8_t DHT11_recvData_[5];   //存放 從DHT11讀取的數據的緩衝數組,40個bit

/**********************
*做用:初始化
*參數:pin,Arduino驅動DHT11的總線使用的IO引腳
*返回:無
**********************/ void DHT11_init(uint8_t pin) { DHT11_dataPin_ = pin; //delay(1000); }
/*********************
*做用:讀取一次DHT11的傳感器數據
*參數:temperature,指向存放溫度數據的指針;humidity,指向存放溼度數據的指針
*返回:函數的執行狀態:DHT11_OK,DHT11_TIMEOUT,DHT11_CHECKEROR
*********************/
int DHT11_read(uint8_t* temperature,uint8_t* humidity ) { uint8_t time_cnt; uint8_t i; uint8_t bit_position; memset(DHT11_recvData_,0,5); //緩衝數組內容清0 /*--------------主機發送起始信號----------------*/ pinMode(DHT11_dataPin_,OUTPUT); digitalWrite(DHT11_dataPin_, LOW); // 主機將總線拉低(時間>=18ms),使得DHT11可以接收到起始信號。 delay(20); //至少 18 ms digitalWrite(DHT11_dataPin_, HIGH); // 主機將總線拉高,表明起始信號結束。 delayMicroseconds(40); //延時20~40us /*--------------引腳配置爲輸入模式,準備接收傳感器回傳的數據-------------------*/ pinMode(DHT11_dataPin_,INPUT); //配置爲輸入模式 //DHT11將總線拉低至少80us,做爲DHT11的響應信號(ACK)。 time_cnt=0; while(LOW == digitalRead(DHT11_dataPin_)) { delayMicroseconds(5); ++time_cnt; if(time_cnt > 16) return DHT11_TIMEOUT; } //DHT11將總線拉高至少80us,爲發送傳感器數據作準備。 time_cnt=0; while(HIGH == digitalRead(DHT11_dataPin_)) { delayMicroseconds(5); ++time_cnt; if(time_cnt > 16) return DHT11_TIMEOUT; } /*-------------------DHT11數據幀的接收和解析------------------*/ for( i=0 ; i < 40 ; ++i ) { time_cnt = 0; while( LOW == digitalRead(DHT11_dataPin_) ) //拉低50us做爲bit信號的起始標誌 { time_cnt++; delayMicroseconds(5); if(time_cnt>10) return DHT11_TIMEOUT; } time_cnt = 0; while( HIGH == digitalRead(DHT11_dataPin_) ) //拉高。持續26~28us表示bit0,持續70us表示bit1 { time_cnt++; delayMicroseconds(5); if(time_cnt>14) return DHT11_TIMEOUT; } if(time_cnt>6){ //說明是bit1 bit_position = 7 - i%8; DHT11_recvData_[i/8] |= (uint8_t)(1<<bit_position); } } //------------檢驗和的比對------------- i = (uint8_t)(DHT11_recvData_[0] + DHT11_recvData_[1] + DHT11_recvData_[2] + DHT11_recvData_[3]) ; if(i != DHT11_recvData_[4] ) return DHT11_CHECKERROR; *humidity = DHT11_recvData_[0]; //回傳溼度數據 *temperature = DHT11_recvData_[2]; //回傳溫度數據 return DHT11_OK; }

 

實驗例子

硬件鏈接 

Arduino 5V     --- DHT11 VDD

Arduino pin5  --- DHT11 DATA

Arduino GND --- DHT11 GND

  

主程序 

#include "dht11.h"
#include <stdint.h>


uint8_t temperature ,humidity ;  //保存溫度和溼度的全局變量

void setup (void)
{
  Serial.begin (115200);  //波特率115200
  DHT11_init(5);           //使用Arduino的pin 5驅動DHT11
  delay(1000);
}

void loop(void)
{
   
   switch (DHT11_read(&temperature,&humidity))
   {
    case DHT11_OK: 
        Serial.print("Temperature:");
        Serial.print(temperature,DEC);
        Serial.print("°C");
        Serial.print("  Humidity:");
        Serial.print(humidity,DEC);
        Serial.println("%RH");
        break;
    case DHT11_TIMEOUT: 
        Serial.println("time out");  break;
    case DHT11_CHECKERROR: 
         Serial.println("check error"); break;
    default: 
        Serial.println("unknown error");  break;
  }

  delay(2000);
  
}

 

 

 

Arduino社區貢獻的DHT11庫

DFRobot DHT11使用教程頁面的【樣例代碼】一節找到【下載樣例程序和庫文件】,點擊便可下載Arduino社區開發的DHT11驅動庫。

下載後完成後,解壓出來。在Arduino安裝目錄下的【librraies】目錄下新建文件夾【dht11】,並將解壓出來的dht11.cpp和dht11.h複製到新建的【dht11】文件夾下,便可完成庫的安裝。

安裝到Arduino的【librraies】目錄下的庫使用#include <xxx>的方式來包含其頭文件。例以下面的測試代碼:

// 
//   FILE:  dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
//
#include <dht11.h>     //包含驅動庫的頭文件
dht11 DHT;             //創建一個dht11模塊對象
#define DHT11_PIN 4

void setup(){
  Serial.begin(9600);   
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop(){
  int chk;
  Serial.print("DHT11, \t");
  chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
    default: 
                Serial.print("Unknown error,\t"); 
                break;
  }
 // DISPLAT DATA
  Serial.print(DHT.humidity,1);
  Serial.print(",\t");
  Serial.println(DHT.temperature,1);

  delay(2000);
}

 

本文參考資料

DHT11官方手冊

DFRobot DHT11模塊

DFRobot DHT11使用教程

相關文章
相關標籤/搜索