728x90

1. DHT11이란?

DHT11은 온도와 습도를 모두 측정할수 있는 센서이다. DHT11의 측정 범위는 다음과 같다.

 

온도 0 ~ 50 ℃ ± 2℃
습도 20 ~ 90 % ± 5%

 

2. DHT11 연결

위 처럼 4개의 Pin 중 1번 Pin은 VCC, 2번 Pin은 Data, 3번 Pin은 비워두고, 4번 Pin은 GND에 연결하면 된다. DHT11은 3~5.5V의 전원을 줄 수 있다.

3. DHT11 통신 방식

Single-bus data format으로 Single-Wire Two-Way 방식이다. 한번 측정 과정은 약 4ms가 소요된다.

 

data는 40bit로 구성되어 있고, 습도 정수 8bit, 습도 소수 8bit, 온도 정수 8bit, 온도 소수 8bit, checksum 8bit로 이루어져 있다. 데이터가 똑바로 수신 되었다면 checksum 8bit는 나머지 32비트를 더한 값이어야 한다.

 

1. 전반적인 통신 방식

전반적인 통신 방식은 다음과 같다. 여기서 검은색 라인은 MCU가 센서에게 값을 보내는 것을 의미하고 금색 라인은 센서가 MCU에게 값을 보내는 것을 의미한다.

 

먼저 MCU측에서 Start Signal을 LOW 시그널로 보내준다. 그 후 pull up 후 센서 반응을 기다린다.

그 후 DHT측에서 LOW 신호를 보내준 후 pull up 후 수집한 데이터 값을 보낼 준비를 한다.

데이터를 보내고 40bit를 전송 완료했다면 다음 전송을 위해 50us간 대기한다.

2. 세부적인 통신 방식

1. MCU가 DHT에 Start Signal 송신, DHT가 MCU에 응답

먼저 MCU측에서 start signal을 보낸다. pull down을 하여 최소 18ms간 LOW신호를 DHT에 보내준다. 그 후 pull up 후 HIGH 신호를 20~40us 동안 보내준다.

MCU가 Start Signal을 보내준 후엔 DHT가 LOW신호를 80us동안 보낸다. 그 후 80us동안 HIGH신호를 보낸 다음 데이터 전송을 시작한다.

2. DHT가 MCU에게 Data 전송

DHT가 데이터를 보내는 방식은 먼저 50us동안 1bit data를 LOW신호로 보낸다. 그 후 HIGH 신호를 보내주게 되는데 이 신호가 26~28us 동안 보냈다면 '0'을 의미하고, 70us 동안 보냈다면 '1'을 보낸다.

4. 소스(C)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <wiringPi.h>
#define DHT11 1
using namespace std;

class dht11{
    uint8_t data[5];
public:
    dht11();
    void Send();
    void Response();
    void Process();
    int GetData();
};
dht11::dht11()
{
    for(int i = 0 ; i < 5 ; i++)
    {
        data[i] = 0;
    }
}
void dht11::Send()
{
    pinMode(DHT11, OUTPUT);        // MCU send out start siganl
    digitalWrite(DHT11, LOW);    // and pulls down voltage
    delay(20);            // for at least 18ms to let DHT11 detect the signal
    digitalWrite(DHT11, HIGH);    // MCU pulls up voltage
    delayMicroseconds(30);        // and waits for DHT respons(20~40)us
} // 5.2 MCU Sends out Start Signal to DHT
void dht11::Response()
{
    pinMode(DHT11, INPUT);

    while(digitalRead(DHT11)!=LOW);  // DHT send out a low-voltage-level response signal
    while(digitalRead(DHT11)!=HIGH); // DHT pulls up voltage and keeps it for 80us and prepares for data transmisson
    while(digitalRead(DHT11)!=LOW);  // Start to transmit next bit data
} 
int dht11::GetData()
{
    int count = 0;
    int j;
    for(j = 0 ; j < 40 ; j++)
    {
        count = 0;
        while(digitalRead(DHT11) == LOW)
        {
            delayMicroseconds(1);
            count++;
            if(count >= 255) return -1;     // start to transmit 1-bit data(50us)
        } // When DHT is sending data to MCU, every bit of data begins with the 50us low-voltage-level
        count = 0;
        while(digitalRead(DHT11) == HIGH)
        {
            delayMicroseconds(1);
            count++;
            if(count >= 255) return -1;
        }
        data[j/8] <<= 1;
        if(count > 30)
        {
            data[j/8] |= 1;
        } // the length of the following high-voltage-level signal determines whether data bit is "0" or "1"
          // 26-28us voltage-length means data "0"
          // 70us voltage-length means data "1"
    }

    if((j>=40)&&(data[4] == data[0] + data[1] + data[2] + data[3]))
    {
        printf("hum = %d, temp = %d\n", data[0], data[2]);
        return -1;
    }
    else
    {
        // cout << "error";
        return -1;
    } // parity bit(data[4])
} // 5.3 DHT Response to MCU
void dht11::Process()
{
    Send();
    Response();
    int result = GetData();
}
int main()
{
    if(wiringPiSetup() == -1)
        exit(1);
    dht11 mdht11;
    while(1)
    {
        mdht11.Process();
        delay(1000);        // wait 1s
    }
}
 

5. 실행 화면

 

728x90

+ Recent posts