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

학교의 모든 지식. SMwiki
Sam (토론 | 기여)님의 2024년 6월 13일 (목) 17:44 판 (→‎코드)
둘러보기로 이동 검색으로 이동

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

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

개요

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

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

참고

항목 참고 비고
하드웨어 아두이노 우노 인클로저, 여기에 호환되는 버튼

LCD는 DFRobot에서 만든 것을 사용함. 온습도계는 DHT11.

코드 아두이노:온습도센서, 아두이노:LCD 사용

기초지식

불쾌지수

  • 불쾌지수 68 이하: 쾌적함
    • 대부분의 사람들이 쾌적함을 느끼며, 불쾌감을 거의 느끼지 않습니다.
  • 불쾌지수 68 ~ 72: 조금 불쾌함
    • 일부 사람들이 약간의 불쾌감을 느끼기 시작합니다.
  • 불쾌지수 73 ~ 77: 상당히 불쾌함
    • 많은 사람들이 불쾌감을 느끼며, 실내 환경에서는 에어컨 등의 냉방 장치를 사용하는 것이 좋습니다.
  • 불쾌지수 78 ~ 82: 매우 불쾌함
    • 대부분의 사람들이 상당한 불쾌감을 느끼며, 냉방 장치가 필수적입니다.
  • 불쾌지수 83 이상: 극도로 불쾌함
    • 거의 모든 사람들이 견디기 어려운 불쾌감을 느끼며, 건강에 영향을 미칠 수 있습니다.

코드

// 온습도계 관련 정의.
#include <dht11.h>  // dht11.h 라이브러리를 불러옵니다.
dht11 DHT11_1;  // 첫 번째 DHT11 객체 생성.
dht11 DHT11_2;  // 두 번째 DHT11 객체 생성.
#define DHT11PIN 2  // 첫 번째 DHT11 센서 핀 설정.
#define DHT11PIN2 3  // 두 번째 DHT11 센서 핀 설정.
float humidity1;  // 각 센서의 습도값 저장할 변수.
float humidity2;
float temperature1;  // 온도값.
float temperature2;
// 지난시간 관련.
unsigned long startTime;  // 분유 먹인 시간 저장.


// 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);
}

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(){
    int chk1 = DHT11_1.read(DHT11PIN);  // 첫 번째 DHT11 센서에서 값을 읽음.
    humidity1 = DHT11_1.humidity;
    temperature1 = DHT11_1.temperature;
    lcd.print("H1:");
    lcd.print(humidity1,1);
    lcd.print(",T1:");
    lcd.print(temperature1);

    int chk2 = DHT11_2.read(DHT11PIN2);  // 두 번째 DHT11 센서에서 값을 읽음.
    humidity2 = DHT11_2.humidity;
    temperature2 = DHT11_2.temperature;
    lcd.setCursor(0, 1);  // 두 번째 줄로 이동.
    lcd.print("H2:");
    lcd.print(humidity2,1);
    lcd.print(",T2:");
    lcd.print(temperature2);
}

void show_elapsedTime() {  // 특정 시간으로부터 지난 시간 알려주기.
  unsigned long currentTime = millis();  // 현재시간
  // 경과 시간 계산 (밀리초 단위)
  unsigned long elapsedTime = currentTime - startTime;
  // 경과 시간을 시, 분, 초 단위로 변환
  unsigned long elapsedHours = elapsedTime / 3600000;
  unsigned long elapsedMinutes = (elapsedTime % 3600000) / 60000;
  // 표시
  lcd.print("after ");
  lcd.print(elapsedHours);
  lcd.print(":");
  if (elapsedMinutes < 10) {
    lcd.print("0");  // 분이 한 자리일 때 앞에 0 추가
  }
  lcd.print(elapsedMinutes);
  lcd.print("             ");
  lcd.setCursor(0, 1);  // 두 번째 줄로 이동.
  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;
}