#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <Keypad.h>

// กำหนดค่าขาและไลบรารีที่ใช้
#define DHTPIN 2    
#define DHTTYPE DHT22   
#define RELAY_PIN 3

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);

// การตั้งค่าคีย์แพด
const byte ROWS = 4; 
const byte COLS = 4; 
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 10, 11, 12}; 
byte colPins[COLS] = {1, 4, 5, 7}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

float temp_set = 23.0;  // ค่าตั้งต้นของอุณหภูมิที่ผู้ใช้ระบุ
float humi_set = 30.0;  // ค่าตั้งต้นของความชื้นสัมพัทธ์ที่ผู้ใช้ระบุ
String inputString = "";  // สำหรับเก็บค่าที่รับจาก Keypad
enum State {NORMAL, SET_TEMP, SET_HUMI}; // สถานะการทำงาน
State currentState = NORMAL; // สถานะเริ่มต้น

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);

  lcd.init();                      
  lcd.backlight();
  dht.begin();
  
  Serial.begin(9600);

  displaySettings();
}

void loop() {
  char key = keypad.getKey();

  if (key) {
    Serial.print("Key pressed: ");
    Serial.println(key);
    
    if (key == 'A') { // เข้าสู่โหมดการตั้งค่าอุณหภูมิ
      currentState = SET_TEMP;
      inputString = "";
      lcd.clear();
      lcd.print("Set Temp (C): ");
    } else if (key == 'B') { // เข้าสู่โหมดการตั้งค่าความชื้น
      currentState = SET_HUMI;
      inputString = "";
      lcd.clear();
      lcd.print("Set Humidity (%): ");
    } else if (key == '#') { // ยืนยันค่าที่ตั้งไว้
      if (currentState == SET_TEMP && inputString != "") {
        temp_set = inputString.toFloat();
        currentState = NORMAL;
        inputString = "";
        displaySettings();
      } else if (currentState == SET_HUMI && inputString != "") {
        humi_set = inputString.toFloat();
        currentState = NORMAL;
        inputString = "";
        displaySettings();
      }
    } else if (key == '*') { // ยกเลิกค่าที่กำลังกรอก
      inputString = "";
      lcd.clear();
      lcd.print(currentState == SET_TEMP ? "Set Temp (C): " : "Set Humidity (%): ");
    } else if (key >= '0' && key <= '9') { // รับค่าตัวเลข
      inputString += key;
      lcd.setCursor(0, 1);
      lcd.print(inputString);
    }
  }

  if (currentState == NORMAL) {
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();

    if (isnan(humidity) || isnan(temperature)) {
      Serial.println("Failed to read from DHT sensor!");
      lcd.clear();
      lcd.print("Sensor Error!");
      delay(2000);
      displaySettings();
      return;
    }

    // แสดงผลข้อมูลที่วัดได้บนจอ LCD
    lcd.setCursor(0, 0);
    lcd.print("Temp: ");
    lcd.print(temperature);
    lcd.print("C   ");
    
    lcd.setCursor(0, 1);
    lcd.print("Humidity: ");
    lcd.print(humidity);
    lcd.print("%  ");

    // การควบคุมรีเลย์
    if (temperature > temp_set || humidity > humi_set) { 
      digitalWrite(RELAY_PIN, HIGH);  // เปิดรีเลย์ถ้าอุณหภูมิหรือความชื้นเกินค่าที่ตั้งไว้
      Serial.println("Relay ON");
    } else  {
      digitalWrite(RELAY_PIN, LOW);   // ปิดรีเลย์ถ้าอุณหภูมิและความชื้นอยู่ในค่าที่ตั้งไว้
      Serial.println("Relay OFF");
    }

    delay(2000);
  }
}

void displaySettings() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Set Temp: ");
  lcd.print(temp_set);
  lcd.print("C");

  lcd.setCursor(0, 1);
  lcd.print("Set Humi: ");
  lcd.print(humi_set);
  lcd.print("%");
}
NOCOMNCVCCGNDINLED1PWRRelay Module