목차

DHT11 온습도 센서 소스 코드

Adafruit DHT11 라이브러리

#include <DHT.h>
 
 
 
#define DHT11PIN 2
#define DHTTYPE DHT11
 
DHT dht(DHT11PIN, DHTTYPE);
 
void setup()
{
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM ");
 
  dht.begin();
}
 
void loop()
{
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);
 
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    delay(10000);
    return;
  }
 
  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);
 
  Serial.print("\nHumidity (%): ");
  Serial.println((float)h, 2);
 
  Serial.print("Temperature (oC): ");
  Serial.println((float)hic, 2);
 
  Serial.print("Temperature (oF): ");
  Serial.println((float)hif, 2);
 
 
  delay(5000);
}

라이브러리 사용 안하는 버전

출처 : https://tkkrlab.nl/wiki/Arduino_KY-015_Temperature_and_humidity_sensor_module

//KY015 DHT11 Temperature and humidity sensor 
//https://tkkrlab.nl/wiki/Arduino_KY-015_Temperature_and_humidity_sensor_module
 
int DHpin = 2;
byte dat [5];
byte read_data () {
  byte data;
  for (int i = 0; i < 8; i ++) {
    if (digitalRead (DHpin) == LOW) {
      while (digitalRead (DHpin) == LOW); // wait for 50us
      delayMicroseconds (30); // determine the duration of the high level to determine the data is '0 'or '1'
      if (digitalRead (DHpin) == HIGH)
        data |= (1 << (7-i)); // high front and low in the post
      while (digitalRead (DHpin) == HIGH); // data '1 ', wait for the next one receiver
     }
  }
return data;
}
 
void start_test () {
  digitalWrite (DHpin, LOW); // bus down, send start signal
  delay (30); // delay greater than 18ms, so DHT11 start signal can be detected
 
  digitalWrite (DHpin, HIGH);
  delayMicroseconds (40); // Wait for DHT11 response
 
  pinMode (DHpin, INPUT);
  while (digitalRead (DHpin) == HIGH);
  delayMicroseconds (80); // DHT11 response, pulled the bus 80us
  if (digitalRead (DHpin) == LOW);
  delayMicroseconds (80); // DHT11 80us after the bus pulled to start sending data
 
  for (int i = 0; i < 4; i ++) // receive temperature and humidity data, the parity bit is not considered
    dat[i] = read_data ();
 
  pinMode (DHpin, OUTPUT);
  digitalWrite (DHpin, HIGH); // send data once after releasing the bus, wait for the host to open the next Start signal
}
 
void setup () {
  Serial.begin (9600);
  pinMode (DHpin, OUTPUT);
}
 
void loop () {
  start_test ();
  Serial.print ("Current humdity =");
  Serial.print (dat [0], DEC); // display the humidity-bit integer;
  Serial.print ('.');
  Serial.print (dat [1], DEC); // display the humidity decimal places;
  Serial.println ('%');
  Serial.print ("Current temperature =");
  Serial.print (dat [2], DEC); // display the temperature of integer bits;
  Serial.print ('.');
  Serial.print (dat [3], DEC); // display the temperature of decimal places;
  Serial.println ('C');
  delay (700);
}

라이브러리 사용 안하는 버전 (2)

출처 : 아두이노-DHT11 소자에서 온도/습도 읽어오기

메인 소스 코드

// 2015.09.30 Jihan Kim
 
#include "myDHT11.h"
int SIGNAL_PIN_NUMBER = 2;
 
 
 
CmyDHT11 myDHT11(SIGNAL_PIN_NUMBER);
 
void setup()
{
    Serial.begin(9600);
}
 
void loop()
{
    float temp = 0.f;
    float humid = 0.f;
 
    if (myDHT11.read(&temp, &humid) == 0)
    {
          Serial.print("Temperature: ");
          Serial.print(temp);
          Serial.print(" Humidity: ");
          Serial.println(humid);
 
    }
 
    delay(1000);
}

DHT11 구동 클래스 (CmyDHT11)

헤더파일

// myDHT11.h
// 2015.09.30 Jihan Kim
 
#ifndef _MYDHT11_h
#define _MYDHT11_h
 
#if defined(ARDUINO) && ARDUINO >= 100
    #include "arduino.h"
#else
    #include "WProgram.h"
#endif
 
const int PACKET_LENGTH = 40;    // [bits]
const int DECISION_THRESHOLD = 30;    // [us]
 
class CmyDHT11
{
public:
    CmyDHT11(uint8_t targetPortNum);
    ~CmyDHT11();
 
 
    int read(float* pTemperature, float* pHumidity);
private:
 
    unsigned long waitFor(uint8_t pinNumber, uint8_t targetStatus, unsigned long maxTime);
    uint8_t checkBit(unsigned long time);
    uint8_t m_TargetPort;
};
 
 
#endif

구현부 파일

// 
// 2015.09.30 Jihan Kim
// 
 
#include "myDHT11.h"
 
 
CmyDHT11::CmyDHT11(uint8_t targetPort)
{
    m_TargetPort = targetPort;
 
    // maintain its HIGH status
    pinMode(m_TargetPort, OUTPUT);
    digitalWrite(m_TargetPort, HIGH);
}
 
CmyDHT11::~CmyDHT11()
{
    ;
}
 
 
uint8_t CmyDHT11::checkBit(unsigned long time)
{
    if (time < DECISION_THRESHOLD)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
 
 
 
unsigned long CmyDHT11::waitFor(uint8_t pinNumber, uint8_t targetStatus, unsigned long maxTime)
{
    unsigned long startCount = micros();
    unsigned long endCount = startCount + maxTime;
 
    while (digitalRead(pinNumber) != targetStatus)
    {
        if (micros() > endCount)
        {
            return -1;
        }
    }
 
    return micros() - startCount;
}
 
 
 
int CmyDHT11::read(float* pTemperature, float* pHumidity)
{
    pinMode(m_TargetPort, OUTPUT);
    digitalWrite(m_TargetPort, LOW);
    delay(18); // Low로 18[ms] 유지해준다.
    digitalWrite(m_TargetPort, HIGH); // HIGH로 복귀
 
    pinMode(m_TargetPort, INPUT);
 
    int t0 = waitFor(m_TargetPort, LOW, 40);    // DHT11이 준비를 기대린다. LOW 까지 최대 40 [us] 기다린다
    if (t0 < 0)
    {
        Serial.println("Error");
        return -1;
    }
 
    int t1 = waitFor(m_TargetPort, HIGH, 90);  // Tx 준비를 체크한다. HIGH까지 최대 90 [us] 까지 기다린다
    if (t1 < 0)
    {
        Serial.println("Error");
        return -1;
    }
 
    int t2 = waitFor(m_TargetPort, LOW, 90);   // Tx 준비를 체크한다. LOW까지 최대 90 [us] 까지 기다린다
    if (t2 < 0)
    {
        Serial.println("Error");
        return -1;
    }
 
 
    // 데이터 전송 시작. 40 bit 읽는다.
    // 습도 정수부 [8bit] + 습도 소수부 [8bit] + 온도 정수부 [8bit] + 온도 소수부 [8bit] + 체크섬 [8bit]
    // HIGH가 유지되는 시간이 짧으면 0, 길면 1이다.
    // 30 [us]를 기준으로 한다.
    int pTimeArray[PACKET_LENGTH];
    for (int idx = 0; idx < PACKET_LENGTH; ++idx)
    {
        if (waitFor(m_TargetPort, HIGH, 50) < 0)    // 데이터 송신 기다린다. HIGH까지 최대 50 [us] 기다린다.
        {
            return -1;
        }
 
        int dataDuration = waitFor(m_TargetPort, LOW, 80);    // 데이터 송신 받는다. 최대 80 [us] 기다린다.
        if (dataDuration < 0)
        {
            return -1;
        }
 
        pTimeArray[idx] = dataDuration;
    }
 
    int RH_Int = 0;
    int RH_Dec = 0;
    int Temp_Int = 0;
    int Temp_Dec = 0;
    int checkSum = 0;
    int bitValue = 0;
    for (int idx = 0; idx < 8; ++idx)
    {
        // 습도 정수부
        RH_Int += (checkBit(pTimeArray[idx]) << (7 - idx));
 
        // 습도 소수부
        RH_Dec += (checkBit(pTimeArray[idx + 8]) << (7 - idx));
 
 
 
        // 온도 정수부
        Temp_Int += (checkBit(pTimeArray[idx + 16]) << (7 - idx));
 
        // 온도 소수부
        Temp_Dec += (checkBit(pTimeArray[idx + 24]) << (7 - idx));
 
 
        // 체크섬
        checkSum += (checkBit(pTimeArray[idx + 32]) << (7 - idx));
    }
 
 
 
 
    if (RH_Int + RH_Dec + Temp_Int + Temp_Dec == checkSum)
    {
        *pTemperature = Temp_Int + Temp_Dec*0.01f;
        *pHumidity = RH_Int + RH_Dec*0.01f;
        return 0;
    }
    else
    {
        return -1;
    }
}

Arduino Playground 소스

메인 소스코드

// 
//   FILE:  dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
//
 
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
	return 1.8 * celsius + 32;
}
 
// fast integer version with rounding
//int Celcius2Fahrenheit(int celcius)
//{
//  return (celsius * 18 + 5)/10 + 32;
//}
 
 
//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
	return celsius + 273.15;
}
 
// dewPoint function NOAA
// reference (1) : http://wahiduddin.net/calc/density_algorithms.htm
// reference (2) : http://www.color ado.edu/geography/weather_station/Geog_site/about.htm
//
double dewPoint(double celsius, double humidity)
{
	// (1) Saturation Vapor Pressure = ESGG(T)
	double RATIO = 373.15 / (273.15 + celsius);
	double RHS = -7.90298 * (RATIO - 1);
	RHS += 5.02808 * log10(RATIO);
	RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
	RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
	RHS += log10(1013.246);
 
        // factor -3 is to adjust units - Vapor Pressure SVP * humidity
	double VP = pow(10, RHS - 3) * humidity;
 
        // (2) DEWPOINT = F(Vapor Pressure)
	double T = log(VP/0.61078);   // temp var
	return (241.88 * T) / (17.558 - T);
}
 
// delta max = 0.6544 wrt dewPoint()
// 6.9 x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
	double a = 17.271;
	double b = 237.7;
	double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);
	double Td = (b * temp) / (a - temp);
	return Td;
}
 
 
#include <dht11.h>
 
dht11 DHT11;
 
#define DHT11PIN 2
 
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.print("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 (°C): ");
  Serial.println((float)DHT11.temperature, 2);
 
  Serial.print("Temperature (°F): ");
  Serial.println(Fahrenheit(DHT11.temperature), 2);
 
  Serial.print("Temperature (°K): ");
  Serial.println(Kelvin(DHT11.temperature), 2);
 
  Serial.print("Dew Point (°C): ");
  Serial.println(dewPoint(DHT11.temperature, DHT11.humidity));
 
  Serial.print("Dew PointFast (°C): ");
  Serial.println(dewPointFast(DHT11.temperature, DHT11.humidity));
 
  delay(2000);
}
//
// END OF FILE
//

드라이버 클래스

dht11.h (헤더파일)

// 
//    FILE: dht11.h
// VERSION: 0.4.1
// PURPOSE: DHT11 Temperature & Humidity Sensor library for Arduino
// LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html)
//
// DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf
//
//     URL: http://playground.arduino.cc/Main/DHT11Lib
//
// HISTORY:
// George Hadjikyriacou - Original version
// see dht.cpp file
// 
 
#ifndef dht11_h
#define dht11_h
 
#if defined(ARDUINO) && (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
 
#define DHT11LIB_VERSION "0.4.1"
 
#define DHTLIB_OK				0
#define DHTLIB_ERROR_CHECKSUM	-1
#define DHTLIB_ERROR_TIMEOUT	-2
 
class dht11
{
public:
    int read(int pin);
	int humidity;
	int temperature;
};
#endif
//
// END OF FILE
//

dht11.h (소스파일)

//
//    FILE: dht11.cpp
// VERSION: 0.4.1
// PURPOSE: DHT11 Temperature & Humidity Sensor library for Arduino
// LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html)
//
// DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf
//
// HISTORY:
// George Hadjikyriacou - Original version (??)
// Mod by SimKard - Version 0.2 (24/11/2010)
// Mod by Rob Tillaart - Version 0.3 (28/03/2011)
// + added comments
// + removed all non DHT11 specific code
// + added references
// Mod by Rob Tillaart - Version 0.4 (17/03/2012)
// + added 1.0 support
// Mod by Rob Tillaart - Version 0.4.1 (19/05/2012)
// + added error codes
//
 
#include "dht11.h"
 
// Return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_TIMEOUT
int dht11::read(int pin)
{
	// BUFFER TO RECEIVE
	uint8_t bits[5];
	uint8_t cnt = 7;
	uint8_t idx = 0;
 
	// EMPTY BUFFER
	for (int i=0; i< 5; i++) bits[i] = 0;
 
	// REQUEST SAMPLE
	pinMode(pin, OUTPUT);
	digitalWrite(pin, LOW);
	delay(18);
	digitalWrite(pin, HIGH);
	delayMicroseconds(40);
	pinMode(pin, INPUT);
 
	// ACKNOWLEDGE or TIMEOUT
	unsigned int loopCnt = 10000;
	while(digitalRead(pin) == LOW)
		if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
 
	loopCnt = 10000;
	while(digitalRead(pin) == HIGH)
		if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
 
	// READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
	for (int i=0; i<40; i++)
	{
		loopCnt = 10000;
		while(digitalRead(pin) == LOW)
			if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
 
		unsigned long t = micros();
 
		loopCnt = 10000;
		while(digitalRead(pin) == HIGH)
			if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
 
		if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
		if (cnt == 0)   // next byte?
		{
			cnt = 7;    // restart at MSB
			idx++;      // next byte!
		}
		else cnt--;
	}
 
	// WRITE TO RIGHT VARS
        // as bits[1] and bits[3] are allways zero they are omitted in formulas.
	humidity    = bits[0]; 
	temperature = bits[2]; 
 
	uint8_t sum = bits[0] + bits[2];  
 
	if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
	return DHTLIB_OK;
}
//
// END OF FILE
//