#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include "DHT.h"
//LDC 20x4
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
//DHT22
float h;
float t;
float f;
#define DHTPIN 13
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
//Keypad 4x4
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 33, 25, 26, 27 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 18, 5, 4, 2 }; // Pins connected to R1, R2, R3, R4
char key;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//Relay + LED
#define TempLED 15
#define HumiLED 19
//Check state for each valve
/*
0 = close
1 = open
*/
int valveWaterState = 0;
int valveNState = 0;
//Count time (s)
unsigned long previousTime = 0;
byte seconds;
byte real_seconds;
void setup() {
Serial.begin(9600);
//Display LCD 20x4
lcd.init();
lcd.backlight(); // turn on backlight
//DHT22
dht.begin();
//Relay LED
pinMode(TempLED, OUTPUT);
pinMode(HumiLED, OUTPUT);
MainMenu();
}
//เก็บข้อความ
String inputString;
//เก็บค่า Temp (อุณหภูมิ)
int default_TempLow = 0; //เก็บค่าตัวแปรอุณหภูมิต่ำสุดเริ่มต้น
int default_TempHigh = 0; //เก็บค่าตัวแปรอุณหภูมิสูงสุดเริ่มต้น
int configTemp = 0;
int inputTempLow = 0; //เก็บค่าตัวแปรอุณหภูมิต่ำสุดใหม่
int setTempLow = 0;
int inputTempHigh = 0; //เก็บค่าตัวแปรอุณหภูมิสูงสุดใหม่
int setTempHigh = 0;
//เก็บค่า Humi (ความชื้น)
int default_HumiLow = 0; //เก็บค่าตัวแปรความชื้นต่ำสุดเริ่มต้น
int default_HumiHigh = 0; //เก็บค่าตัวแปรความชื้นสูงสุดเริ่มต้น
int configHumi = 0;
int inputHumiLow = 0; //เก็บค่าตัวแปรความชื้นต่ำสุดใหม่
int setHumiLow = 0;
int inputHumiHigh = 0; //เก็บค่าตัวแปรความชื้นสูงสุดใหม่
int setHumiHigh = 0;
//เก็บค่าเช็คการกดยืนยัน
int CheckSummit = 1; //1 = กดยืนยันครั้งที่หนึ่ง, 2 = กดยืนยันครั้งที่สอง
//เก็บค่าตำแหน่งการแสดงตัวอักษร
int currentF = 10; //ตำแหน่งเริ่มต้นตัวอักษรบนจอ LCD ของค่าต่ำสุด (ด้านหน้า)
int currentB = 15; //ตำแหน่งเริ่มต้นตัวอักษรบนจอ LCD ของค่าสูงสุด (ด้านหลัง)
void loop() {
key = keypad.getKey(); //รับค่าจาก Keypad
if (key) {
switch (key) { //เลือกทำ
case 'A': //แสดงค่าจากเซนเซอร์
lcd.clear();
while (1) {
key = keypad.getKey();
if (key == '*') { //กดกลับ Main Menu
lcd.clear();
MainMenu();
break;
} else {
//เช็ค Error ของ DHT22
h = dht.readHumidity();
t = dht.readTemperature();
f = dht.readTemperature(true);
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
//แสดงอุณหภูมิ จากเซนเซอร์ DHT22
lcd.setCursor(0, 0);
lcd.print("Temp :");
lcd.setCursor(7, 0);
lcd.print(t, 2);
lcd.setCursor(13, 0);
lcd.print("C");
//แสดงความชื้นสัมพันธ์ จากเซนเซอร์ DHT22
lcd.setCursor(0, 1);
lcd.print("Humi :");
lcd.setCursor(7, 1);
lcd.print(h, 2);
lcd.setCursor(13, 1);
lcd.print("%RH");
//แสดงข้อความ
//lcd.setCursor(0, 2);
//lcd.print("System running . . .");
lcd.setCursor(0, 3);
lcd.print("Press * back to Menu");
//เงื่อนไขการทำงานของ Relay + LED ของอุณหภูมิ (Temp)
if (configTemp == 0) {
if ((t >= default_TempLow) && (t <= default_TempHigh)) {
digitalWrite(TempLED, LOW);
valveWaterState = 0;
} else {
digitalWrite(TempLED, HIGH);
valveWaterState = 1;
}
} else if (configTemp == 1) {
if ((t >= inputTempLow) && (t <= inputTempHigh)) {
digitalWrite(TempLED, LOW);
valveWaterState = 0;
} else {
digitalWrite(TempLED, HIGH);
valveWaterState = 1;
}
}
//เงื่อนไขการทำงานของ Relay + LED ของอุณหภูมิ (Humi)
if (configHumi == 0) {
if ((h >= default_HumiLow) && (h <= default_HumiHigh)) {
digitalWrite(HumiLED, LOW);
valveNState = 0;
} else {
digitalWrite(HumiLED, HIGH);
valveNState = 1;
}
} else if (configHumi == 1) {
if ((h >= inputHumiLow) && (h <= inputHumiHigh)) {
digitalWrite(HumiLED, LOW);
valveNState = 0;
} else {
digitalWrite(HumiLED, HIGH);
valveNState = 1;
}
}
/*
//หน่วงเวลา
delay(1000);
//ล้างจอ LCD
lcd.clear();
*/
}
}
break;
case 'B': //ควบคุมวาล์ว
lcd.clear();
ControlValveMenu();
while (1) {
key = keypad.getKey();
if (key == '*') { //กดกลับ Main Menu
lcd.clear();
MainMenu();
break;
} else {
if (valveWaterState == 1) {
lcd.setCursor(0, 0);
lcd.print("1.Water Valve: ON ");
}
if (valveNState == 1) {
lcd.setCursor(0, 1);
lcd.print("2.N Valve: ON ");
}
if (key == '1') {
if (valveWaterState == 0) {
digitalWrite(TempLED, HIGH);
valveWaterState = 1;
lcd.setCursor(0, 0);
lcd.print("1.Water Valve: ON ");
} else if (valveWaterState == 1) {
digitalWrite(TempLED, LOW);
valveWaterState = 0;
lcd.setCursor(0, 0);
lcd.print("1.Water Valve: OFF");
}
} else if (key == '2') {
if (valveNState == 0) {
digitalWrite(HumiLED, HIGH);
valveNState = 1;
lcd.setCursor(0, 1);
lcd.print("2.N Valve: ON ");
} else if (valveNState == 1) {
digitalWrite(HumiLED, LOW);
valveNState = 0;
lcd.setCursor(0, 1);
lcd.print("2.N Valve: OFF");
}
}
}
}
break;
case 'C': //ตั้งค่าเงื่อนไข, ตั้งค่าการทำงานอัติโนมัติ
lcd.clear();
SettingMenu();
while (1) {
key = keypad.getKey();
if (key == '*') { //กดกลับ Main Menu
lcd.clear();
MainMenu();
break;
} else if (key == '1') {
SettingTemp(); //กดตั้งค่าอุณหภูมิ
break;
} else if (key == '2') {
SettingHumi(); //กดตั้งค่าความชื้นสัมพัทธ์
break;
} else if (key == '3') {
ViewSetting(); //กดดูการตั้งค่า
break;
}
}
break;
default: //แจ้งเตือนหากกดนอกเหลือจากที่กำหนด
lcd.clear();
while (1) {
key = keypad.getKey();
if (key == '*') { //กดกลับ Main Menu
lcd.clear();
MainMenu();
break;
} else { //แสดงข้อความแจ้งเตือน
ErrMenu();
}
};
}
}
}
void MainMenu() {
lcd.setCursor(0, 0);
lcd.print("Press A-C to Select");
lcd.setCursor(0, 1);
lcd.print("Press A - Sensor");
lcd.setCursor(0, 2);
lcd.print("Press B - Valve");
lcd.setCursor(0, 3);
lcd.print("Press C - Setting");
}
void ErrMenu() {
lcd.setCursor(0, 0);
lcd.print(" Please Press A - C ");
lcd.setCursor(0, 1);
lcd.print(" to Select Menu ");
lcd.setCursor(0, 3);
lcd.print("Press * back to Menu");
}
void ControlValveMenu() {
lcd.setCursor(0, 0);
lcd.print("1.Water Valve: OFF");
lcd.setCursor(0, 1);
lcd.print("2.N Valve: OFF");
}
void SettingMenu() {
lcd.setCursor(0, 0);
lcd.print("Press 1 - Set Temp");
lcd.setCursor(0, 1);
lcd.print("Press 2 - Set Humi");
lcd.setCursor(0, 2);
lcd.print("Press 3 - View Set");
lcd.setCursor(0, 3);
lcd.print("Press * back to Menu");
}
void SettingTemp() {
lcd.clear();
//แสดงข้อความการกำหนดค่าอุณหภูมิ
lcd.setCursor(0, 0);
lcd.print("Set-Temp: ");
lcd.setCursor(13, 0);
lcd.print("-");
lcd.setCursor(19, 0);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Press C to Cancel");
lcd.setCursor(0, 3);
lcd.print("Press * back to Menu");
lcd.setCursor(10, 0); //--------
lcd.blink(); //--------
while (1) {
key = keypad.waitForKey();
if (key) {
if (key >= '0' && key <= '9') { //เช็ครับเฉพาะตัวเลข 0 - 9
if (CheckSummit == 1) { //แสดงการป้อนค่าช่วงต่ำสุด (ด้านหน้า)
lcd.setCursor(currentF, 0); //ตำแหน่งการเริ่มแสดงค่าที่ป้อน
lcd.blink(); //--------
lcd.print(key);
currentF++; //เลื่อนไปต่ำแหน่งต่อไป
} else if (CheckSummit == 2) { //แสดงการป้อนค่าช่วงสูงสุด (ด้านหลัง)
lcd.setCursor(currentB, 0); //ตำแหน่งการเริ่มแสดงค่าที่ป้อน
lcd.blink(); //--------
lcd.print(key);
currentB++; //เลื่อนไปต่ำแหน่งต่อไป
}
inputString += key; //เพิ่ม Char จากปุ่มกดตัวใหม่ไปต่อใน String
} else if (key == '#' && CheckSummit == 1) { //รับค่าสำหรับกำหนด Low Temp
if (inputString.length() > 0) {
setTempLow = inputString.toInt(); //แปลงจาก Char เป็น Int
inputString = ""; //ล้าง Input
CheckSummit++; //สั่งเพิ่มค่า +1 สำหรับเช็คการกดยืนยัน
lcd.noBlink(); //--------
lcd.setCursor(10, 0);
lcd.print(setTempLow); //แสดงค่าต่ำสุดของอุณหภูมิ (Temp) ที่ป้อน
currentF = 10; //ย้อนกลับต่ำแหน่งเริ่มต้นตัวอักษรของค่าต่ำสุด (ด้านหน้า)
lcd.setCursor(15, 0); //--------
lcd.blink();
}
} else if (key == '#' && CheckSummit == 2) { //รับค่าสำหรับกำหนด High Temp
setTempHigh = inputString.toInt(); //แปลงจาก Char เป็น Int
inputString = ""; //ล้าง Input
CheckSummit++; //สั่งเพิ่มค่า +1 สำหรับเช็คการกดยืนยัน
lcd.noBlink(); //--------
lcd.setCursor(15, 0);
lcd.print(setTempHigh); //แสดงค่าสูงสุดของอุณหภูมิ (Temp) ที่ป้อน
currentB = 15; //ย้อนกลับต่ำแหน่งเริ่มต้นตัวอักษรของค่าสูงสุด (ด้านหลัง)
//แสดงข้อความการตั้งค่าสำเร็จ
lcd.setCursor(0, 1);
lcd.print("Setting Successfully");
} else if (key == '*' && CheckSummit == 3) { //กดกลับ Main Menu
CheckSummit = 1;
configTemp = 1;
inputTempLow = setTempLow;
inputTempHigh = setTempHigh;
lcd.noBlink(); //--------
lcd.clear();
MainMenu();
return;
} else if ((key == '*' && CheckSummit == 1) || (key == '*' && CheckSummit == 2)) {
inputString = "";
CheckSummit = 1;
currentF = 10;
currentB = 15;
lcd.noBlink(); //--------
lcd.clear();
MainMenu();
return;
} else if (key == 'C') { //ยกเลิกการกระทำหรือการกำหนดค่า
inputString = "";
setTempLow = 0;
setTempHigh = 0;
CheckSummit = 1;
currentF = 10;
currentB = 15;
lcd.noBlink(); //--------
//แสดงข้อความการยกเลิกการตั้งค่า
lcd.setCursor(0, 0);
lcd.print("Set-Temp: - C");
lcd.setCursor(0, 1);
lcd.print(" Setting Canceled ");
}
}
}
}
void SettingHumi() {
lcd.clear();
//แสดงข้อความการกำหนดค่าอุณหภูมิ
lcd.setCursor(0, 0);
lcd.print("Set-Humi: ");
lcd.setCursor(13, 0);
lcd.print("-");
lcd.setCursor(19, 0);
lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("Press C to Cancel");
lcd.setCursor(0, 3);
lcd.print("Press * back to Menu");
lcd.setCursor(10, 0); //--------
lcd.blink(); //--------
while (1) {
key = keypad.waitForKey();
if (key) {
if (key >= '0' && key <= '9') { //เช็ครับเฉพาะตัวเลข 0 - 9
if (CheckSummit == 1) { //แสดงการป้อนค่าช่วงต่ำสุด (ด้านหน้า)
lcd.setCursor(currentF, 0); //ตำแหน่งการเริ่มแสดงค่าที่ป้อน
lcd.blink(); //--------
lcd.print(key);
currentF++; //เลื่อนไปต่ำแหน่งต่อไป
} else if (CheckSummit == 2) { //แสดงการป้อนค่าช่วงสูงสุด (ด้านหลัง)
lcd.setCursor(currentB, 0); //ตำแหน่งการเริ่มแสดงค่าที่ป้อน
lcd.blink(); //--------
lcd.print(key);
currentB++; //เลื่อนไปต่ำแหน่งต่อไป
}
inputString += key; //เพิ่ม Char จากปุ่มกดตัวใหม่ไปต่อใน String
} else if (key == '#' && CheckSummit == 1) { //รับค่าสำหรับกำหนด Low Humi
if (inputString.length() > 0) {
setHumiLow = inputString.toInt(); //แปลงจาก Char เป็น Int
inputString = ""; //ล้าง Input
CheckSummit++; //สั่งเพิ่มค่า +1 สำหรับเช็คการกดยืนยัน
lcd.noBlink(); //--------
lcd.setCursor(10, 0);
lcd.print(setHumiLow); //แสดงค่าต่ำสุดของความชื้น (Humi) ที่ป้อน
currentF = 10; //ย้อนกลับต่ำแหน่งเริ่มต้นตัวอักษรของค่าต่ำสุด (ด้านหน้า)
lcd.setCursor(15, 0); //--------
lcd.blink();
}
} else if (key == '#' && CheckSummit == 2) { //รับค่าสำหรับกำหนด High Humi
setHumiHigh = inputString.toInt(); //แปลงจาก Char เป็น Int
inputString = ""; //ล้าง Input
CheckSummit++; //สั่งลดค่า -1 สำหรับเช็คการกดยืนยัน
lcd.noBlink(); //--------
lcd.setCursor(15, 0);
lcd.print(setHumiHigh); //แสดงค่าสูงสุดของความชื้น (Humi) ที่ป้อน
currentB = 15; //ย้อนกลับต่ำแหน่งเริ่มต้นตัวอักษรของค่าสูงสุด (ด้านหลัง)
//แสดงข้อความการตั้งค่าสำเร็จ
lcd.setCursor(0, 1);
lcd.print("Setting Successfully");
} else if (key == '*' && CheckSummit == 3) { //กดกลับ Main Menu
CheckSummit = 1;
configHumi = 1;
inputHumiLow = setHumiLow;
inputHumiHigh = setHumiHigh;
lcd.noBlink(); //--------
lcd.clear();
MainMenu();
return;
} else if ((key == '*' && CheckSummit == 1) || (key == '*' && CheckSummit == 2)) {
inputString = "";
CheckSummit = 1;
currentF = 10;
currentB = 15;
lcd.noBlink(); //--------
lcd.clear();
MainMenu();
return;
} else if (key == 'C') { //ยกเลิกการกระทำหรือการกำหนดค่า
inputString = "";
setHumiLow = 0;
setHumiHigh = 0;
CheckSummit = 1;
currentF = 10;
currentB = 15;
lcd.noBlink(); //--------
//แสดงข้อความการยกเลิกการตั้งค่า
lcd.setCursor(0, 0);
lcd.print("Set-Humi: - %");
lcd.setCursor(0, 1);
lcd.print(" Setting Canceled ");
}
}
}
}
void ViewSetting() {
lcd.clear();
while (1) {
key = keypad.getKey();
if (key == '*') {
lcd.clear();
MainMenu();
return;
} else {
//แสดงค่าการตั้งค่าอุณหภูมิ
lcd.setCursor(0, 0);
lcd.print("Set-Temp: ");
lcd.setCursor(10, 0);
lcd.print(inputTempLow);
lcd.setCursor(12, 0);
lcd.print(" - ");
lcd.setCursor(15, 0);
lcd.print(inputTempHigh);
lcd.setCursor(19, 0);
lcd.print("C");
//แสดงค่าการตั้งค่าความชื้นสัมพัทธ์
lcd.setCursor(0, 1);
lcd.print("Set-Humi: ");
lcd.setCursor(10, 1);
lcd.print(inputHumiLow);
lcd.setCursor(12, 1);
lcd.print(" - ");
lcd.setCursor(15, 1);
lcd.print(inputHumiHigh);
lcd.setCursor(19, 1);
lcd.print("%");
//แสดงข้อความปุ่มย้อนกลับ
lcd.setCursor(0, 3);
lcd.print("Press * back to Menu");
}
}
}