진한프로젝트:온, 습도계
이진한 선생님의 프로젝트 일람. 틀:진한프로젝트
개요
아이방에 두고 쓰는 온습도계.
- 어른이 쾌적해 할 온도와 아이가 쾌적해 할 온도가 다르기에 주변 환경에 대하여 객관적으로 파악할 수 있게 구성하였다.
- 아이 방에, 거실에 두고 적절한 온습도, 불쾌지수를 확인하기 위해.
- 사실, 온습도계는 만원이면 살 수 있는데.... 해본다는 것에 의미..!
- 처음엔 상하좌우버튼으로 온습도, 불쾌지수를 나타내려 했으나, 버튼을 누르는 것 자체가 귀찮아 1초에 한 번 다른 정보를 띄워주는 방식으로 진행하기로 함.
참고
항목 | 참고 | 비고 |
---|---|---|
하드웨어 | 아두이노 우노 인클로저(나사는 M2*10 쓰면 맞음.), 여기에 호환되는 버튼
LCD는 DFRobot에서 만든 것을 사용함. 온습도계는 DHT22. |
|
코드 | 아두이노:온습도센서, 아두이노:LCD 사용 | |
기초지식
불쾌지수
- 불쾌지수 68 이하: 쾌적함
- 대부분의 사람들이 쾌적함을 느끼며, 불쾌감을 거의 느끼지 않습니다.
- 불쾌지수 68 ~ 72: 조금 불쾌함
- 일부 사람들이 약간의 불쾌감을 느끼기 시작합니다.
- 불쾌지수 73 ~ 77: 상당히 불쾌함
- 많은 사람들이 불쾌감을 느끼며, 실내 환경에서는 에어컨 등의 냉방 장치를 사용하는 것이 좋습니다.
- 불쾌지수 78 ~ 82: 매우 불쾌함
- 대부분의 사람들이 상당한 불쾌감을 느끼며, 냉방 장치가 필수적입니다.
- 불쾌지수 83 이상: 극도로 불쾌함
- 거의 모든 사람들이 견디기 어려운 불쾌감을 느끼며, 건강에 영향을 미칠 수 있습니다.
코드
// 온습도계 관련 정의.
#include "DHT.h"
#define DHTPIN1 2 // 첫 번째 DHT 센서 핀 설정.
#define DHTPIN2 3 // 두 번째 DHT 센서 핀 설정.
#define DHTTYPE DHT22 // DHT22 센서를 사용
DHT dht1(DHTPIN1, DHTTYPE); // DHT 객체 생성
DHT dht2(DHTPIN2, DHTTYPE);
float humidity1; // 각 센서의 습도값 저장할 변수.
float humidity2;
float temperature1; // 온도값.
float temperature2;
// 지난시간 관련.
unsigned long startTime; // 분유 먹인 시간 저장.
// WIFI.
#include <WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <time.h>
const char* ssid = "kwsh";
const char* password = "khsh9700#";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
// LCD 관련 정의.
#include <LiquidCrystal.h> // 관련 라이브러리.
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // LCD panel에서 사용되는 핀 선택.
int lcd_key = 0; // 들어온 키 값을 해석한 값을 담을 변수.
int lcd_key_in = 0; // LCD에서 들어오는 키 값을 담을 변수.
// 밝기조절 관련.
const int lcd_backlightPin = 10; // 제품별로 핀 달라짐.
int brightness = 128; // 초기 밝기.
void setup() {
Serial.begin(9600); // 시리얼 통신을 사용하기 위해 보드레이트를 9600으로 설정합니다.
lcd.begin(16, 2); // LCD 초기화.
pinMode(lcd_backlightPin, OUTPUT);
dht1.begin();
dht2.begin();
WiFi.begin(ssid, password);
// WiFi 연결 시도
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi network");
// 시간관련모듈.
timeClient.begin();
timeClient.setTimeOffset(32400); // 서울 시간(UTC+9)으로 변환하기 위한 오프셋 설정
}
void loop() {
lcd_key = read_LCD_buttons(); // 들어온 버튼을 해석한다.
lcd.setCursor(0, 0); // LCD 시작점 지정.
switch (lcd_key) {
case 1: { // 상
brightness = min(brightness + 10, 255); // 255로 제한.
analogWrite(lcd_backlightPin, brightness); // 조정된 밝기 값을 적용합니다.
delay(500); // 버튼이 한번만 눌리게끔.
break;
}
case 2: { // 하
brightness = min(brightness - 10, 255); // 255로 제한.
analogWrite(lcd_backlightPin, brightness); // 조정된 밝기 값을 적용합니다.
delay(500); // 버튼이 한번만 눌리게끔.
break;
}
case 3: { // 좌
lcd.print("좌");
break;
}
case 4: { // 우
break;
}
case 5: { // 선택
startTime = millis(); // 새로 시작.
break;
}
case 0: { // 버튼 눌림 없음.
unsigned long elapsedSeconds = (millis() % 60000) / 1000;
elapsedSeconds = elapsedSeconds /3; // n초마다 변경을 설정하기 위해.
int functionIndex = elapsedSeconds % 3; // 3가지 함수를 보여줄 거라서.
switch (functionIndex) {
case 0:
show_humid_temp();
break;
case 1:
show_Discomfort();
break;
case 2:
show_elapsedTime();
break;
}
break;
}
}
// lcd.clear(); 를 쓰면 문자가 점멸해서;; 불편; 차라리 덮어씌우는 전략으로...!
}
void show_humid_temp(){
humidity1 = dht1.readHumidity();
temperature1 = dht1.readTemperature();
lcd.print("H1:");
lcd.print(humidity1,1);
lcd.print(",T1:");
lcd.print(temperature1,1);
humidity2 = dht2.readHumidity();
temperature2 = dht2.readTemperature();
lcd.setCursor(0, 1); // 두 번째 줄로 이동.
lcd.print("H2:");
lcd.print(humidity2, 1);
lcd.print(",T2:");
lcd.print(temperature2, 1);
Serial.print("온습도센서점검");
Serial.print(humidity1);
Serial.println(humidity2);
}
void show_elapsedTime() { // 특정 시간으로부터 지난 시간 알려주기.
// 현재시간 띄우기.
timeClient.update();
String fromattedTime = timeClient.getFormattedTime();
lcd.print("Now: ");
lcd.print(fromattedTime.substring(0,2));
lcd.print(":");
lcd.print(fromattedTime.substring(3,5));
lcd.print(" ");
unsigned long currentTime = millis(); // 현재시간
// 경과 시간 계산 (밀리초 단위)
unsigned long elapsedTime = currentTime - startTime;
// 경과 시간을 시, 분, 초 단위로 변환
unsigned long elapsedHours = elapsedTime / 3600000;
unsigned long elapsedMinutes = (elapsedTime % 3600000) / 60000;
// 표시
lcd.setCursor(0, 1); // 두 번째 줄로 이동.
lcd.print("after ");
lcd.print(elapsedHours);
lcd.print(":");
if (elapsedMinutes < 10) {
lcd.print("0"); // 분이 한 자리일 때 앞에 0 추가
}
lcd.print(elapsedMinutes);
lcd.print(" ");
}
int read_LCD_buttons() { // 입력신호를 해석할 함수.
lcd_key_in = analogRead(0); // 센서에서 들어온 값을 읽는다.
// 상하좌우, 선택 순으로 인덱스를 지정한다.
if (lcd_key_in > 1000) return 0; // 입력이 없는 경우.
if (lcd_key_in > 700) return 5; // 선택버튼.
if (lcd_key_in > 450) return 3; // 좌
if (lcd_key_in > 300) return 2; // 하
if (lcd_key_in > 100) return 1; // 상
return 4; // 우
}
void show_Discomfort(){
lcd.print("Discomfort:");
lcd.print(calculateDiscomfortIndex(temperature1, humidity1));
lcd.setCursor(0, 1);
lcd.print("Discomfor2:");
lcd.print(calculateDiscomfortIndex(temperature2, humidity2));
}
float calculateDiscomfortIndex(float temperature, float humidity) {
// 불쾌지수 계산 공식
return 0.81 * temperature + 0.01 * humidity * (0.99 * temperature - 14.3) + 46.3;
}