온도/습도 센서는 서미스터(thermistor)를 이용해 온도를 측정하는 센서와 공기 중에 있는 수분을 정전식으로 감지하여 습도를 측정하는 센서가 내장되어 있습니다. 내장된 서미스터와 습도 센서에서 아날로그 신호를 감지하여 아날로그 전압을 디지털 값으로 변환하여 디지털 신호를 출력합니다.
- 서미스터(thermistor)는 열 저항의 일종으로 온도에 따라 물질의 저항이 변화하는 성질을 이용한 장치입니다.
온도가 증가하면 저항이 감소하고 온도가 내려가면 저항이 증가합니다.
- 정전식 습도 센서는 양극(+)과 음극(-) 사이에 습기를 흡수하는 얇은 기판(또는 금속 산화물)을 배치하여 기판(또는 금속 산화물)이 수증기를 흡수하면 양극(+)과 음극(-) 사이에 전도성을 증가시키는 이온을 방출하게 되어 전류가 전달됩니다. 반대로 수증기가 없으면 이온이 방출되지 않아서 전류가 전달되지 않습니다. 이처럼 물질의 저항이 변하는 성질을 이용한 장치입니다.
습도가 높으면 양극(+)과 음극(-) 사이의 저항이 감소하고 습도가 낮으면 양극(+)과 음극(-) 사이의 저항이 증가합니다. 이 저항의 변화는 습도에 비례합니다.
온도는 0℃ ~ 50℃ 범위까지 측정 가능합니다.
습도는 20% ~ 90% 범위까지 측정 가능합니다. (온도에 따라 측정할 수 있는 습도의 범위가 달라집니다.)
온도/습도 센서는 양극(+), 음극(-) 핀으로 전류를 흐르게 하여 저항의 값을 측정하고 out 핀으로 디지털 신호를 출력합니다.
그럼 온도/습도 센서도 digitalRead() 함수를 사용하여 온도/습도 정보를 읽을 수 있을까요?
읽을 수는 있는지만 만들기가 쉽지 않습니다.
온도/습도 센서는 out 핀 하나만으로 정보를 주고받기 위해서는 입력 모드와 출력 모드를 번갈아 사용해야 합니다. 그리고 규칙에 따라 디지털 신호(LOW/HIGH)를 주고받아야 합니다.
이렇게 하나의 핀으로 데이터의 송/수신을 처리하는 방식을 one-wire protocol(단선 프로토콜, 단일 버스)이라고 합니다.
온도/습도 센서는 out 핀을 출력 모드로 전환하여 디지털 신호를 주고 다시 out 핀을 입력 모드로 전환하여 설정된 시간(밀리초)이 지난 후 out 핀으로 부터 특정 길이의 바이트를 읽어 처리해야 합니다. 이처럼 순차적으로 실행해서 처리해야 하기 때문에 입력과 출력의 디지털 신호를 정확하게 해석해야 만들 수 있습니다.
또한 제조사마다 입력과 출력의 디지털 신호 규칙이 다를 수 있고 읽을 바이트 수와 바이트를 처리하는 방식이 다를 수 있습니다. 그래서 제조사가 제공하는 라이브러리나 표준으로 제공하는 라이브러리를 사용하는 것이 좋습니다.
그럼 온도/습도 센서에 대한 라이브러리는 어떻게 처리해야 할까요?
방식은 두 가지가 있습니다.
첫 번째는 제조사가 제공하는 라이브러리나 표준으로 제공하는 라이브러리를 다운로드해서 처리하는 방식 (라이브러리 압축 파일을 다운로드해 아두이노 IDE 라이브러리에 추가해야 함)
두 번째는 아두이노 IDE의 라이브러리 매니저를 이용하여 라이브러리를 다운로드해서 처리하는 방식 (아두이노 IDE에서 다운로드해서 자동으로 라이브러리에 추가됨)
아두이노 IDE의 라이브러리 매니저를 통한 DHT11 라이브러리 받기
1. 메뉴에서 툴 > 라이브러리 관리(또는 스케치 > 라이브러리 포함하기 > 라이브러리 관리)를 클릭합니다. 단축키는 Ctrl + Shift + I를 누릅니다. 그러면 라이브러리 매니저가 실행됩니다.
2. 검색란에 "DHT11"를 입력합니다. 그러면 DHT11 라이브러리들이 필터 되어 나옵니다.
그중에서 DHT sensor library를 선택하고 설치 버튼을 누릅니다.
이 라이브러리는 일반적인 DHT11, DHT22 센서에서 사용할 수 있습니다.
센서 제조사마다 다를 수 있으니 라이브러리 매니저에 없으면 제조사 홈페이지나 Git에서 검색하여 받으시기 바랍니다.
그러면 DHT sensor library에서 사용하는 Adafruit Unified Sensor 라이브러리를 설치하라는 컴펌창이 나타납니다. Install all 버튼을 눌러 설치해 줍니다.
다시 DHT sensor library를 선택하면 설치된 버전이 표시됩니다. (1.4.3 INSTALLED)
그리고 추가로 다른 버전을 선택하여 설치할 수 있게 나옵니다.
닫기 버튼을 누릅니다.
3. 메뉴에서 스케치 > 라이브러리 포함하기를 선택하면 기본으로 제공되는 라이브러리와 PC에 설치되어 사용 가능한 라이브러리들이 나타납니다. 조금 전에 설치한 DHT sensor library라 포함되어 있습니다.
설치된 라이브러리 파일들은 스케치북(스케치 파일을 저장하는 폴더)에서 libraries 폴더 안에 있습니다.
스케치북 위치는 환경설정에서 확인할 수 있습니다.
DHT sensor library에 제공하는 예제 소스
DHT sensor library를 설치하면 아두이노 IDE에서 예제 소스를 확인할 수 있습니다.
메뉴 : 파일 > 예제 > DHT sensor library > DHTtester
예제는 DHT22 센서를 이용하여 시리얼 통신으로 습도와 온도의 섭씨(Celsius)와 화씨(Fahrenheit)를 출력합니다.
#include "DHT.h"
#define DHTPIN 2 // Digital pin connected to the DHT sensor
// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
// Pin 15 can work but DHT must be disconnected during program upload.
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 3 (on the right) of the sensor to GROUND (if your sensor has 3 pins)
// Connect pin 4 (on the right) of the sensor to GROUND and leave the pin 3 EMPTY (if your sensor has 4 pins)
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors. This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
Serial.println(F("DHTxx test!"));
dht.begin();
}
void loop() {
// Wait a few seconds between measurements.
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
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(F("Failed to read from DHT sensor!"));
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(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("°C "));
Serial.print(f);
Serial.print(F("°F Heat index: "));
Serial.print(hic);
Serial.print(F("°C "));
Serial.print(hif);
Serial.println(F("°F"));
}
DHT11 vs DHT22
DHT22는 DHT11과 동일한 핀 구성과 전압 및 전류 소비가 동일합니다. 그러나 DHT22는 온도를 -40℃ ~ 125℃ 범위까지 측정 가능하고 습도는 0% ~100% 범위까지 측정이 가능합니다.
디지털 핀 입력 - 온도/습도 센서(DHT11)
온도/습도 센서는 DHT sensor library에서 제공하는 예제만으로도 충분하기 때문에 예제를 기반으로 하겠습니다.
아두이노 IDE의 메뉴에서 파일 > 예제 > DHT sensor library > DHTtester를 선택합니다. 그러면 새로운 IDE에 예제가 포함되어 오픈됩니다.
예제는 읽기 전용이기 때문에 저장할 수 없습니다. 그래서 복사하시거나 다른 이름으로 저장하여 개발하시기 바랍니다.
예제에 대해 설명하겠습니다.
1. DHT sensor library를 사용하기 위해서 라이브러리를 인클루드 해야 합니다.
#include "DHT.h"
온도/습도 센서가 DHT11 임으로 예제 소스에서 DHT22를 주석 처리하고 DHT11을 주석 처리를 지웁니다.
// Uncomment whatever type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
2. 전역에 DHT형 객체를 선언하면서 센서로 연결된 디지털 핀 번호와 모듈 타입을 설정합니다.
센서와 연결된 디지털 핀은 2번이고 모듈 타입은 DHT11입니다.
전역에 #define으로 선언되어 있습니다.
DHT dht(DHTPIN, DHTTYPE);
3. setup() 함수에서 객체를 사용하기 위해 초기화합니다.
dht.begin();
4. loop() 함수에서 객체 readHumidity() 함수를 사용하여 습도 정보를 받고 readTemperature() 함수를 사용하여 온도(섭씨와 화씨) 정보를 받습니다.
float h = dht.readHumidity(); --> 습도
float t = dht.readTemperature(); --> 온도(섭씨)
float f = dht.readTemperature(true); --> 온도(화씨)
리턴 값이 float인 이유는 습도나 온도의 데이터가 소수점을 가지고 있기 때문입니다.
5. 습도와 온도 정보를 이용하여 열 지수를 계산합니다.
float hif = dht.computeHeatIndex(f, h); --> 열 지수(화씨)
float hic = dht.computeHeatIndex(t, h, false); --> 열 지수(섭씨)
열 지수(heat index - humiture)는 온도와 습도를 결합한 지수로 "체감 온도"입니다.
6. 아두이노 우노 보드와 온도/습도 센서를 연결합니다.
아두이노 우노 보드의 5V 전원 핀에 빨간색 M-F 점퍼 와이어를 꼽고 온도/습도 센서의 양극(+) 핀에 꼽습니다.
아두이노 우노 보드의 GND 핀에 검은색 M-F 점퍼 와이어를 꼽고 온도/습도 센서의 음극(-) 핀에 꼽습니다.
아두이노 우노 보드의 2번 디지털 핀에 갈색 M-F 점퍼 와이어를 꼽고 온도/습도 센서의 out 핀에 꼽습니다.
7. 컴파일하고 업로드한 후 아두이노 IDE에서 시리얼 모니터를 실행시킵니다.
시리얼 모니터를 보면 1초마다 습도, 온도의 섭씨와 화씨가 출력됩니다.
8. 온도/습도 센서를 손으로 잡고 있으면 습도와 온도가 올라가는 것을 확인할 수 있습니다.
온도 센서를 이용하여 선풍기를 제어하거나 습도 센서를 이용하여 가습기나 제습기를 제어할 수 있을 겁니다. 다음에 릴레이 채널을 다룰 때 온도/습도 센서와 선풍기를 연결해 보겠습니다. 실제로는 릴레이 채널로 선풍기와 연결된 멀티탭의 전원을 켜고 끄는 겁니다.
추가로 Serial.print() 함수에서 사용된 F() 함수에 대해 설명드리겠습니다.
F() 함수
아두이노에서는 프로그램에서 사용되는 문자열에 대해 효율적으로 메모리를 관리할 수 있게 F() 함수를 지원하고 있습니다. F() 함수를 사용하면 프로그램에서 사용되는 문자열들이 아두이노 우노 보드의 SRAM에 로드되지 않게 하고 Flash에 있도록 합니다. 그 이유는 SRAM의 저장 공간은 매우 작기 때문입니다. 그래서 연산과 상관없는 데이터를 SRAM으로 로드하지 않음으로써 SRAM의 저장 공간을 효율적으로 사용할 수 있게 됩니다.