진한프로젝트:온, 습도계

학교의 모든 지식. SMwiki
둘러보기로 이동 검색으로 이동

이진한 선생님의 프로젝트 일람. 틀:진한프로젝트

  1. 진한프로젝트:온, 습도계
  2. 진한프로젝트:알루미늄 모듈 선반

개요[편집 | 원본 편집]

아이방에 두고 쓰는 온습도계.

  • 어른이 쾌적해 할 온도와 아이가 쾌적해 할 온도가 다르기에 주변 환경에 대하여 객관적으로 파악할 수 있게 구성하였다.
  • 아이 방에, 거실에 두고 적절한 온습도, 불쾌지수를 확인하기 위해.
  • 사실, 온습도계는 만원이면 살 수 있는데.... 해본다는 것에 의미..!
  • 처음엔 상하좌우버튼으로 온습도, 불쾌지수를 나타내려 했으나, 버튼을 누르는 것 자체가 귀찮아 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;
}