Arduino로 DHT11, DHT22, SHTC3 온도 및 습도 데이터 읽기

이 문서에서는 NodeMcu 보드를 사용하여 DHT11, DHT22, SHTC3 세 가지 온습도 센서의 데이터를 읽어 시리얼로 전송하는 방법을 설명합니다. 각 센서에 대해 타사 라이브러리를 사용하는 경우와 사용하지 않는 경우의 예제를 모두 제공했습니다.

ESP8266 개발 환경 설정 튜토리얼: https://blog.zeruns.com/archives/526.html

본 문서에서 사용된 센서 구매 링크는 문서 하단에 있습니다.

DHT11

DHT11은 교정된 디지털 신호 출력을 갖춘 온습도 센서입니다. 습도 정확도는 ±5%RH, 온도 정확도는 ±2℃이며, 측정 범위는 습도 20~90%RH, 온도 0~50℃입니다. 정확도는 낮지만 가격이 저렴합니다. DHT11은 싱글 바스 버스 통신을 사용하며, 작동 전압은 3.3~5V입니다.

DHT 라이브러리 사용

DHT sensor library 라이브러리(자체 설치 필요. 설치 방법은 위의 ESP8266 개발 환경 설정 튜토리얼 참조)를 사용하여 DHT11 데이터를 직접 읽습니다.

#include ```<DHT.h>        // 호출 DHT 라이브러리

DHT dht(D1, DHT11);      // 데이터 핀에 연결된 IO 핀과 센서 유형 설정

void setup(){ // 초기화 함수, 프로그램 시작 시 한 번만 실행
  Serial.begin(115200);   // 시리얼 보드레이트 설정
  dht.begin();       
}
//https://blog.zeruns.com
void loop() {
  delay(1000);                  // 1000밀리초 지연
  float RH = dht.readHumidity();   // 습도 데이터 읽기
  float T = dht.readTemperature(); // 온도 데이터 읽기
  Serial.print("Humidity:");  // 시리얼에 Humidity: 출력
  Serial.print(RH);           // 시리얼에 습도 데이터 출력
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 시리얼에 온도 데이터 출력
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

라이브러리 사용하지 않기

DHT11 데이터시트를 읽고 직접 프로그램을 작성하여 데이터를 읽습니다.

DHT11 데이터시트: http://go.zeruns.com/G

#define data D1   // DHT11의 Data 핀(2핀)을 NodeMcu 보드의 D1 핀에 연결

unsigned char i;  // 부호 없는 8비트 정수 변수
float RH,T;       // 단정도 부동소수점(32비트 길이)
byte RH_H,RH_L,T_H,T_L,sum,check;  // 바이트 변수, 이진수

void setup() {    // 초기화 함수, 프로그램 시작 시 한 번만 실행
  Serial.begin(115200);   // 시리얼 보드레이트 설정
}

void loop() {     // 루프 함수, 초기화 함수 실행 후 계속 반복 실행
  delay(1000);    // 1000밀리초 지연
  DHT11();        // 온습도 데이터 가져오기
  Serial.print("Humidity:");  // 시리얼에 Humidity: 출력
  Serial.print(RH);           // 시리얼에 습도 데이터 출력
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 시리얼에 온도 데이터 출력
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void DHT11()
{
  RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
  pinMode(data,OUTPUT);   // IO 핀을 출력 모드로 설정
  digitalWrite(data,1);   // IO 핀에 고전압 출력
  delay(10);              // 10밀리초 지연
  digitalWrite(data,0);   // IO 핀에 저전압 출력
  delay(25);              // 25밀리초 지연
  digitalWrite(data,1);   // IO 핀에 고전압 출력
  pinMode(data,INPUT);    // IO 핀을 입력 모드로 설정
  delayMicroseconds(30);  // 30마이크로초 지연
  if(!digitalRead(data))  // IO 핀 입력 전압이 저전압인지 확인
  {//https://blog.zeruns.com
    while(!digitalRead(data));  // 입력이 고전압이 될 때까지 반복
    while(digitalRead(data));   // 입력이 저전압이 될 때까지 반복
    for(i=0;i<8;i++)            // 8회 반복 실행
    {   
      while(!digitalRead(data));// 입력이 고전압이 될 때까지 반복   
      delayMicroseconds(28);    // 28마이크로초 지연
      if(digitalRead(data)){    // IO 핀 입력 전압이 고전압인지 확인
        bitWrite(RH_H, 7-i, 1); // 이진 변수 RH_H의 7-i번째 비트(오른쪽에서 시작)에 1을 작성
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){
        bitWrite(RH_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_H, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(check, 7-i, 1);
        while(digitalRead(data));
      }
    }
   }
  sum=RH_H + RH_L + T_H + T_L;
  byte sum_temp=0;
  // sum의 하위 8비트를 sum_temp에 저장
  for(i=0;i<8;i++){
    bitWrite(sum_temp,i,bitRead(sum,i)); 
  }//https://blog.zeruns.com
  if(check==sum_temp){  // 데이터 검증
    RH=RH_H+float(RH_L)/10;
    T=T_H+float(T_L)/10;
  }
}

결과 이미지

DHT22 (AM2302)

DHT22(AM2302)는 교정된 디지털 신호 출력을 가진 온습도 센서입니다. 습도 정확도는 ±2%RH, 온도 정확도는 ±0.5℃, 측정 범위는 습도 0-100%RH, 온도 -40~80℃이며, 해상도는 모두 0.1입니다. 정확도가 높고 가격도 저렴합니다. DHT22는 단일 버스 통신을 사용하며, 공급 전압은 3.3~5V입니다.

DHT 라이브러리 사용

DHT sensor library 라이브러리를 사용하여 DHT22 데이터를 직접 읽습니다.

#include <DHT.h>        // DHT 라이브러리 호출

DHT dht(D1, DHT22);      // 데이터 핀에 연결된 IO 핀과 센서 유형 설정

void setup(){ // 초기화 함수, 프로그램 시작 시 한 번만 실행
  Serial.begin(115200);   // 시리얼 보드레이트 설정
  dht.begin();       
}
//https://blog.zeruns.com
void loop() {
  delay(1000);                  // 1000밀리초 지연
  float RH = dht.readHumidity();   // 습도 데이터 읽기
  float T = dht.readTemperature(); // 온도 데이터 읽기
  Serial.print("Humidity:");  // 시리얼에 Humidity: 출력
  Serial.print(RH);           // 시리얼에 습도 데이터 출력
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 시리얼에 온도 데이터 출력
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

라이브러리 사용하지 않기

DHT22 데이터시트를 읽고 직접 프로그램을 작성하여 데이터를 읽습니다.

DHT22 데이터시트: http://go.zeruns.com/H

#define data D1   // DHT22의 Data 핀(2핀)을 NodeMcu 보드의 D1 핀에 연결

unsigned char i;  // 부호 없는 8비트 정수 변수
float RH,T;       // 단정도 부동소수점(32비트 길이)
byte RH_H,RH_L,T_H,T_L,sum,check;  // 바이트 변수, 이진수

void setup() {    // 초기화 함수, 프로그램 시작 시 한 번만 실행
  Serial.begin(115200);   // 시리얼 보드레이트 설정
}

void loop() {     // 루프 함수, 초기화 함수 실행 후 계속 반복 실행
  delay(1000);    // 1000밀리초 지연
  DHT11();        // 온습도 데이터 가져오기
  Serial.print("Humidity:");  // 시리얼에 Humidity: 출력
  Serial.print(RH);           // 시리얼에 습도 데이터 출력
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 시리얼에 온도 데이터 출력
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void DHT11()
{
  RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
  pinMode(data,OUTPUT);   // IO 핀을 출력 모드로 설정
  digitalWrite(data,1);   // IO 핀에 고전압 출력
  delay(10);              // 10밀리초 지연
  digitalWrite(data,0);   // IO 핀에 저전압 출력
  delay(25);              // 25밀리초 지연
  digitalWrite(data,1);   // IO 핀에 고전압 출력
  pinMode(data,INPUT);    // IO 핀을 입력 모드로 설정
  delayMicroseconds(30);  // 30마이크로초 지연
  if(!digitalRead(data))  // IO 핀 입력 전압이 저전압인지 확인
  {//https://blog.zeruns.com
    while(!digitalRead(data));  // 입력이 고전압이 될 때까지 반복
    while(digitalRead(data));   // 입력이 저전압이 될 때까지 반복
    for(i=0;i<8;i++)            // 8회 반복 실행
    {   
      while(!digitalRead(data));// 입력이 고전압이 될 때까지 반복   
      delayMicroseconds(28);    // 28마이크로초 지연
      if(digitalRead(data)){    // IO 핀 입력 전압이 고전압인지 확인
        bitWrite(RH_H, 7-i, 1); // 이진 변수 RH_H의 7-i번째 비트(오른쪽에서 시작)에 1을 작성
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){
        bitWrite(RH_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_H, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(check, 7-i, 1);
        while(digitalRead(data));
      }
    }
   }
  sum=RH_H + RH_L + T_H + T_L;
  byte sum_temp=0;
  // sum의 하위 8비트를 sum_temp에 저장
  for(i=0;i<8;i++){
    bitWrite(sum_temp,i,bitRead(sum,i)); 
  }//https://blog.zeruns.com
  if(check==sum_temp){
    if(bitRead(RH_H,7)==1){ // 온도가 음수인지 확인
      T=-(float(T_H<<8)+float(T_L))/10;
    }else{
      T=(float(T_H<<8)+float(T_L))/10;
    }
    RH=(float(RH_H<<8)+float(RH_L))/10;
  }  
}

결과 이미지

SHTC3

SHTC3는 교정된 디지털 신호 출력을 가진 온습도 센서입니다. 습도 정확도는 ±2%RH, 온도 정확도는 ±0.2℃, 측정 범위는 습도 0-100%RH, 온도 -40~125℃이며, 해상도는 모두 0.01입니다. 정확도가 높고 가격도 저렴하지만 자료가 매우 적습니다. SHTC3는 I2C(IIC) 통신을 사용하며, 공급 전압은 1.62~3.6V입니다.

SHTC3 데이터시트: http://go.zeruns.com/I

Wire(I2C) 라이브러리 사용

Wire 라이브러리를 사용하여 SHTC3와 통신하여 데이터를 읽습니다.

/* https://blog.zeruns.com
 * 연결 방법
 * SHTC3    개발 보드
 * SCL      SCL (NodeMcu 개발 보드는 D1)
 * SDA      SDA (NodeMcu 개발 보드는 D2)
 */
#include <Wire.h>

#define SHTC3_ADDRESS 0x70  // SHTC3의 I2C 장치 주소를 0x70으로 정의
float T, RH;

void setup() {    // 초기화 함수, 프로그램 시작 시 한 번만 실행
  Serial.begin(115200);   // 시리얼 보드레이트 설정
  Wire.begin();   // I2C 마스터로 초기화
}

void loop() {     // 루프 함수, 초기화 함수 실행 후 계속 반복 실행
  delay(1000);    // 1000밀리초 지연
  SHTC3();        // 온습도 데이터 가져오기
  Serial.print("Humidity:");  // 시리얼에 Humidity: 출력
  Serial.print(RH);           // 시리얼에 습도 데이터 출력
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 시리얼에 온도 데이터 출력
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void SHTC3(){   // 온습도 데이터 가져오기
  Wire.beginTransmission(SHTC3_ADDRESS); // 주소 0x70을 사용하여 I2C 슬레이브로 데이터 전송 시작
  Wire.write(byte(0xE0));       // 쓰기 명령 전송
  Wire.endTransmission();       // 슬레이브로의 전송 종료
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0x35));       // 웨이크업 명령의 상위 비트 전송
  Wire.write(byte(0x17));       // 웨이크업 명령의 하위 비트 전송
  Wire.endTransmission();
  delayMicroseconds(300);       // 300마이크로초 지연
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0xE0));
  Wire.endTransmission();
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0x7C));       // 측정 명령의 상위 비트 전송
  Wire.write(byte(0xA2));       // 측정 명령의 하위 비트 전송
  Wire.endTransmission();
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0xE1));       // 읽기 명령 전송
  Wire.endTransmission();
  Wire.requestFrom(SHTC3_ADDRESS,6);     // 슬레이브로부터 데이터 요청
  uint16_t T_temp, RH_temp, T_CRC, RH_CRC;
  if (2 <= Wire.available()) {
    T_temp = Wire.read();     // 온도 상위 비트 데이터 수신
    T_temp = T_temp << 8;     // 8비트 왼쪽 시프트
    T_temp |= Wire.read();    // 8비트 시프트된 온도 상위 비트와 수신된 온도 하위 비트를 비트 OR 연산
    T_CRC = Wire.read();      // CRC 검사 코드 수신
    if(SHTC3_CRC_CHECK(T_temp,T_CRC)){  // 데이터 검증
      T = float(T_temp) * 175 / 65536 - 45;  // 온도 계산
    }
  }//https://blog.zeruns.com
  if (2 <= Wire.available()) {
    RH_temp = Wire.read();     // 습도 상위 비트 데이터 수신
    RH_temp = RH_temp << 8;     // 8비트 왼쪽 시프트
    RH_temp |= Wire.read();    // 8비트 시프트된 습도 상위 비트와 수신된 습도 하위 비트를 비트 OR 연산
    RH_CRC = Wire.read();
    if(SHTC3_CRC_CHECK(RH_temp,RH_CRC)){
      RH = float(RH_temp) * 100 / 65536;
    }
  }
}
//https://blog.zeruns.com
uint8_t SHTC3_CRC_CHECK(uint16_t DAT, uint8_t CRC_DAT) // SHTC3의 CRC 검사
{
    uint8_t i, t, temp;
    uint8_t CRC_BYTE;  
    CRC_BYTE = 0xFF;  
    temp = (DAT >> 8) & 0xFF;  
    for(t = 0; t < 2; t ++)
    {
        CRC_BYTE ^= temp;
        for(i = 0; i < 8; i ++)
        {
            if(CRC_BYTE & 0x80)
            {
                CRC_BYTE <<= 1;         
                CRC_BYTE ^= 0x31;  
            }else{
                CRC_BYTE <<= 1;  
            }
        }  
        if(t == 0)
        {
            temp = DAT & 0xFF; 
        }
    }//https://blog.zeruns.com  
    if(CRC_BYTE == CRC_DAT)
    {
        temp = 1;  
    }else{
        temp = 0;  
    }   
    return temp;
}

### SHTC3 라이브러리 사용

먼저 `SparkFun SHTC3` 라이브러리를 설치하세요.

```c
/* https://blog.zeruns.com
 * 연결 방법
 * SHTC3    개발 보드
 * SCL      SCL (NodeMcu 개발 보드는 D1)
 * SDA      SDA (NodeMcu 개발 보드는 D2)
 */

#include <SparkFun_SHTC3.h>

SHTC3 mySHTC3;

void setup(){ // 초기화 함수, 프로그램 시작 시 한 번만 실행
  Serial.begin(115200);   // 시리얼 보드레이트 설정
  while(Serial == false){};   // 시리얼 연결이 시작될 때까지 대기
  Wire.begin();           // Wire(I2C) 라이브러리 초기화
  unsigned char i=0;
  errorDecoder(mySHTC3.begin());// 센서를 시작하려면 "begin()"을 호출해야 하며, 기본 설정은 Wire(기본 Arduino I2C 포트)를 사용합니다.
}
//https://blog.zeruns.com
void loop() {
  float RH, T;
  delay(1000);                  // 1000밀리초 지연
  SHTC3_Status_TypeDef result = mySHTC3.update();
  if(mySHTC3.lastStatus == SHTC3_Status_Nominal)   // SHTC3 상태가 정상인지 확인
  {
    RH = mySHTC3.toPercent();   // 습도 데이터 읽기                
    T = mySHTC3.toDegC();       // 온도 데이터 읽기             
  }else{
    Serial.print("Update failed, error: ");
    errorDecoder(mySHTC3.lastStatus); // 오류 원인 출력
    Serial.println();
  }
  Serial.print("Humidity:");  // 시리얼에 Humidity: 출력
  Serial.print(RH);           // 시리얼에 습도 데이터 출력
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 시리얼에 온도 데이터 출력
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void errorDecoder(SHTC3_Status_TypeDef message) // errorDecoder 함수는 "SHTC3_Status_TypeDef" 결과를 인간이 읽기 쉬운 방식으로 출력합니다
{
  switch(message)
  {
    case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
    case SHTC3_Status_Error : Serial.print("Error"); break;
    case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
    default : Serial.print("Unknown return code"); break;
  }
}

결과 이미지

센서 구매

DHT11: $Lk3h1Mx8UTO$ 복사하여 모바일 타오바오에서 즉시 주문

DHT22: $kr2T1MxkUKY$ 복사하여 모바일 타오바오에서 즉시 주문

SHTC3: $UD4D1Mx6N3R$ 복사하여 모바일 타오바오에서 즉시 주문

추천 읽기:

  • 가성비 높고 저렴한 VPS/클라우드 서버 추천: https://blog.zeruns.com/archives/383.html
  • 내부 네트워크 터널 서버 구축, 웹 패널 포함: https://blog.zeruns.com/archives/397.html
  • Cloudreve를 사용한 개인 클라우드 스토리지 구축: https://blog.zeruns.com/archives/515.html
  • 개인 블로그 구축 방법: https://blog.zeruns.com/archives/218.html
  • 학생 할인 혜택 전체: https://blog.zeruns.com/archives/321.html
  • 돈을 벌 수 있는 작은 게임 공유: https://blog.zeruns.com/archives/472.html
1개의 좋아요