#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
//#include <Wire.h>
#include <RTClib.h>
#include <pitches.h>
#include <ezButton.h>
#include <DHT.h>
//#include <WiFi.h>
//#include <NTPClient.h>
//#include <WiFiUdp.h>
#include "Variable_Hydro.h"
void setup() {
Serial.begin(115200);
//button press
ButtonMode.setDebounceTime(50); // set debounce time to 100 milliseconds
ButtonUp.setDebounceTime(50);
ButtonDown.setDebounceTime(50);
ButtonLeft.setDebounceTime(50);
ButtonRight.setDebounceTime(50);
ButtonDone.setDebounceTime(50);
pinMode(IRPin, INPUT);
pinMode(BuzzerPin, OUTPUT);
pinMode(WaterLevelPin, INPUT);
pinMode(PHPin, INPUT);
pinMode(WaterQPin, INPUT);
//Relay pin
pinMode(RelayFanPin, OUTPUT);
pinMode(RelaySpkPin, OUTPUT);
pinMode(RelaySolPin, OUTPUT);
pinMode(RelayPMIPin, OUTPUT);
pinMode(RelayPMOPin, OUTPUT);
pinMode(ServoPin, OUTPUT);
dht.begin();
lcd.init();
rtc.begin();
servo.attach(ServoPin, 500, 2400);
lcd.backlight();
CheckSensor();
DisplayDateTime();
curround = 5;
//lcd.setCursor(0, 0);
//lcd.print("DD167");
interval = curtime * 60000;
DisplayFunda();
//CheckFoodFeed();
CurrentCol = MinCol;
CurrentRow = MinRow;
lcd.setCursor(CurrentCol, CurrentRow);
//String CurrentChar = UpandDown(CurrentCol, CurrentRow, 'f');
//lcd.print(CurrentChar);
MOrder = FanStrUp;
PosiCol = 0; //position cursor for setup
PosiRow = 2;
// สร้างอักขระพิเศษในตำแหน่ง 0
lcd.createChar(0, arrowUp);
// Control relays based on switch states
/*digitalWrite(RelayFanPin, FanSwtState ? LOW : HIGH);
digitalWrite(RelaySpkPin, SpkSwtState ? LOW : HIGH);
digitalWrite(RelaySolPin, SolSwtState ? LOW : HIGH);
digitalWrite(RelayPMIPin, PMISwtState ? LOW : HIGH);
digitalWrite(RelayPMOPin, PMOSwtState ? LOW : HIGH);*/
FanSwtState = LOW;
SpkSwtState = LOW;
SolSwtState = LOW;
PMISwtState = LOW;
PMOSwtState = LOW;
// เชื่อมต่อกับ Wi-Fi
/*
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to WiFi");
timeClient.begin();
timeClient.update();
// ตั้งเวลา RTC ให้ตรงกับเวลาที่ได้รับจาก NTP
DateTime now = DateTime(timeClient.getEpochTime() * 1000L); // แปลงเวลา NTP เป็นมิลลิวินาที
rtc.adjust(now);
Serial.println("RTC initialized and synced");
*/
}// end setu
void loop() {
ButtonMode.loop(); // MUST call the loop() function first
ButtonUp.loop();
ButtonDown.loop();
ButtonLeft.loop();
ButtonRight.loop();
ButtonDone.loop();
issetupatime(); // Setup mode, working auto, working manual
if (setupatime == false) {
if ((mode == false) and (setupatime == false)) {
lcd.setCursor(0, 0);
lcd.print("MAN ");
lcd.setCursor(10, 1);
lcd.print(FanStrLo + SpkStrLo + SolStrLo);
lcd.setCursor(10, 2);
lcd.print(FDDStrLo + PMIStrLo + PMOStrLo);
swdone = digitalRead(ButtonDonePin);
if ( swdone == 0 ) {
numround = 1;
}
else {
swdone = HIGH;
numround = 0;
}
ButtonManual();
}
if (mode == true and setupatime == false) {//auto
lcd.setCursor(0, 0);
lcd.print("Auto");
lcd.setCursor(10, 1);
lcd.print(FanStrLo + SpkStrLo + SolStrLo);
ButtonAuto();
automode();
numround = 0;
}
}
else if (setupatime == true) {
lcd.setCursor(0, 0);
lcd.print("SET ");
DisplaySetup();
ButtonSetup();
}
DisplayDateTime();
} //end loop
void issetupatime() {
if (ButtonMode.isPressed()) {
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
if (ButtonMode.isReleased()) {
isPressing = false;
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if ( pressDuration < SHORT_PRESS_TIME )
Serial.println("A short press is detected");
mode = ! mode;
if (mode == true) {
previousMillis = millis();
}
Serial.print("Setup Mode ");
Serial.println(mode);
}
if (isPressing == true && isLongDetected == false) {
long pressDuration = millis() - pressedTime;
if ( pressDuration > LONG_PRESS_TIME ) {
Serial.println("A long press is detected");
isLongDetected = true;
setupatime = ! setupatime;
lcd.clear(); //เพื่อเข้าสู่โหมดการทำงาน
}
}
}//end issetupatime
void packmansound() {
int size = sizeof(durations) / sizeof(int);
for (int note = 0; note < size; note++) {
//to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int duration = 1000 / durations[note];
tone(BuzzerPin, melody[note], duration);
//to distinguish the notes, set a minimum time between them.
//the note's duration + 30% seems to work well:
int pauseBetweenNotes = duration * 1.30;
delay(pauseBetweenNotes);
//stop the tone playing:
noTone(BuzzerPin);
}
}
void CheckSensor() { //Check Sensor
//DHT
// อ่านค่าความชื้นและอุณหภูมิ
float h = dht.readHumidity(); // อ่านความชื้น
float t = dht.readTemperature(); // อ่านอุณหภูมิในองศาเซลเซียส
// ตรวจสอบว่ามีการอ่านค่าที่ถูกต้องหรือไม่
if (isnan(h) || isnan(t)) {
Serial.println("ไม่สามารถอ่านค่าจากเซ็นเซอร์ DHT ได้!");
lcd.setCursor(10, 3);
lcd.print(DHTType);
lcd.println("NotOK");
delay(2000);
} else {
DHT_Ok = true;
}
//Ir
int val = analogRead(IRPin); //อ่านค่าสัญญาณ ซ็นเซอร์ตรวจจับวัตถุ IR Infrared
Serial.print("val = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "val = "
Serial.println(val); // พิมพ์ค่าของตัวแปร val
if (isnan(val)) { // อ่านค่าไม่ได้
Serial.println("ไม่สามารถอ่านค่าจากเซ็นเซอร์ IR ได้!");
lcd.setCursor(10, 3);
lcd.print(" IR ");
lcd.println("NotOK");
delay(2000);
//return;
} else {
IR_Ok = true;
}
//Servo
CheckServoOk();
//RTC
// ตรวจสอบการเชื่อมต่อกับ RTC
if (!rtc.begin()) {
Serial.println("RTC not found!");
lcd.setCursor(10, 3);
lcd.print(" RTC ");
lcd.println("NotOK");
delay(2000);
} else {
RTC_Ok = true;
}
/*/ ตรวจสอบว่า RTC ได้ตั้งค่าเวลาหรือไม่
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting the time!");
// หาก RTC สูญเสียพลังงาน ให้ตั้งเวลา (กำหนดเป็นเวลาปัจจุบัน)
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
} */
//Buzzer
//WaterLevel
int Wvalue = analogRead(WaterLevelPin); // Water Level
if (isnan(Wvalue)) {
lcd.setCursor(10, 3);
lcd.print("WLeve");
lcd.println("NotOK");
delay(2000);
} else {
WaterL_Ok = true;
}
//PH
CheckPhOk();
} //End Check sensor
float offset() {
return 0; // ปรับเปลี่ยนค่า offset ตามค่าที่ได้จากการสอบเทียบ
}
void CheckPhOk() {
float voltage; // ตัวแปรสำหรับเก็บค่าความดันไฟฟ้า
float pHValue; // ตัวแปรสำหรับเก็บค่าพีเอช
voltage = analogRead(PHPin) * (5.0 / 1023.0); // แปลงค่า analog เป็นแรงดันไฟฟ้า
pHValue = 3.5 * voltage + offset(); // แปลงแรงดันไฟฟ้าเป็นค่าพีเอช
Serial.print("pH Value: ");
Serial.println(pHValue); // แสดงค่าพีเอชใน Serial Monitor
// ตรวจสอบค่าพีเอช
if (pHValue < 0 || pHValue > 14) {
Serial.println("ไม่สามารถอ่านค่าจากเซ็นเซอร์ PH ได้!");
lcd.setCursor(10, 3);
lcd.print(" PH ");
lcd.println("NotOK");
delay(2000);
} else {
Serial.println("pH sensor is working correctly.");
PH_Ok = true;
}
delay(2000); // รอ 2 วินาทีก่อนอ่านค่าใหม่
}
void CheckServoOk() {
// ตรวจสอบการตอบสนองของเซอร์โว
servo.write(0);
//delay(1000); // รอให้เซอร์โวหมุน
int sensorValue = digitalRead(ServoPin);
if (sensorValue == HIGH) {
Servo_Ok = true;
} else {
Serial.println("ไม่สามารถอ่านค่าจากเซ็นเซอร์ Servo ได้!");
lcd.setCursor(10, 3);
lcd.print("Servo");
lcd.println("NotOK");
delay(2000);
}
}
void DisplayDHT() {
if (DHT_Ok) {
int h = dht.readHumidity(); // อ่านความชื้น
int t = dht.readTemperature(); // อ่านอุณหภูมิในองศาเซลเซียส
lcd.setCursor(1, 1);
lcd.print("T");
if (t < 10) {
lcd.print(" ");
lcd.print(t);
} else lcd.print(t);
lcd.setCursor(5, 1);
lcd.print("H");
if (h < 10) {
lcd.print(" ");
lcd.print(h);
} else lcd.print(h);
} else {
lcd.setCursor(1, 1);
lcd.print("T");
lcd.print("--");
lcd.setCursor(5, 1);
lcd.print("H");
lcd.print("--");
} //end DHT Ok
}//end Display DHT
void DisplayFeed() {
if (Servo_Ok) {
lcd.setCursor(5, 2);
lcd.print("F ");
lcd.print(FeedPerDay);
//lcd.print("/D");
if (mode == true) { //Auto
lcd.setCursor(10, 3);
switch (FeedPerDay) { //auto
case 2:
lcd.print(FeedingTime2);
lcd.print(" ");
break;
case 4:
lcd.print(FeedingTime4);
lcd.print(" ");
break;
case 6:
lcd.print(FeedingTime6);
break;
}
}
} else {
lcd.setCursor(5, 2);
lcd.print("F ");
lcd.print("-");
//lcd.print("/D");
} //end Feed Ok
} //End Display Feed
void DisplayWaterL() {
if (WaterL_Ok) {
int Wvalue = analogRead(WaterLevelPin); // Water Level
lcd.setCursor(1, 2);
lcd.print("W");
lcd.print(Wvalue);
} else {
lcd.setCursor(1, 2);
lcd.print("W ");
lcd.print("--");
} //end Water level
} //End Display Water level
void DisplayPH() {
if (PH_Ok) {
float voltage; // ตัวแปรสำหรับเก็บค่าความดันไฟฟ้า
int pHValue; // ตัวแปรสำหรับเก็บค่าพีเอช
voltage = analogRead(PHPin) * (5.0 / 1023.0); // แปลงค่า analog เป็นแรงดันไฟฟ้า
pHValue = 3.5 * voltage + offset(); // แปลงแรงดันไฟฟ้าเป็นค่าพีเอช
//Serial.print("PH ");
//Serial.println(pHValue);
lcd.setCursor(4, 3);
lcd.print("PH");
lcd.print(pHValue);
} else {
lcd.setCursor(4, 3);
lcd.print("PH");
lcd.print("--");
}
} //End Display PH
void DisplayWaterQ() {
if (WaterQ_Ok) {
int WaterQ = analogRead(WaterQPin); // Water Level
//Serial.print("Water Quality ");
//Serial.println(WaterQ);
lcd.setCursor(1, 3);
lcd.print("Q");
lcd.print(WaterQ);
} else {
lcd.setCursor(1, 3);
lcd.print("Q");
lcd.print("--");
}
} //End Display Water Quality
void DisplayFunda() {
DisplayDHT();
DisplayDateTime();
DisplayWaterL();
DisplayFeed(); //Check Servo and IR
DisplayPH();
DisplayWaterQ();
}//End Fundamental
String UpandDown(int col, int row, char inputchar) {
/*Serial.print("Col ");
Serial.print(col);
Serial.print("Row ");
Serial.print(row); */
switch (col) {
case 10 :
if (row == 1) {
MOrder = FanStrUp;
if (isUpperCase(inputchar)) {
return FanStrLo;
} else {
return FanStrUp;
}
} else if (row == 2) {
MOrder = FDDStrUp;
if (isUpperCase(inputchar)) {
return FDDStrLo;
} else {
return FDDStrUp;
}
}
case 13 :
if (row == 1) {
MOrder = SpkStrUp;
if (isUpperCase(inputchar)) {
return SpkStrLo;
} else {
return SpkStrUp;
}
} else if (row == 2) {
MOrder = PMIStrUp;
if (isUpperCase(inputchar)) {
return PMIStrLo;
} else {
return PMIStrUp;
}
}
case 16 :
if (row == 1) {
MOrder = SolStrUp;
if (isUpperCase(inputchar)) {
return SolStrLo;
} else {
return SolStrUp;
}
} else if (row == 2) {
MOrder = PMOStrUp;
if (isUpperCase(inputchar)) {
return PMOStrLo;
} else {
return PMOStrUp;
}
}
}
//Serial.print("MOrder");
//Serial.print(MOrder);
}
void ButtonManual() {
//swup
swup = digitalRead(ButtonUpPin);
if ((swup == 0 ) and (setupatime == false) and (CurrentRow > MinRow)) {
CurrentRow--;
lcd.setCursor(CurrentCol, CurrentRow);
String Output = UpandDown(CurrentCol, CurrentRow, 'f');
lcd.print(Output);
}
//swdown
swdown = digitalRead(ButtonDownPin);
if ((swdown == 0) and (CurrentRow < MaxRow) and (setupatime == false)) {
CurrentRow++;
lcd.setCursor(CurrentCol, CurrentRow);
String Output = UpandDown(CurrentCol, CurrentRow, 'f');
lcd.print(Output);
}
//swleft
swleft = digitalRead(ButtonLeftPin);
if ((swleft == 0) and (CurrentCol > MinCol) and (setupatime == false)) {
CurrentCol = CurrentCol - 3;
lcd.setCursor(CurrentCol, CurrentRow);
String Output = UpandDown(CurrentCol, CurrentRow, 'f');
lcd.print(Output);
}
//swright
swright = digitalRead(ButtonRightPin);
if ((swright == 0) and (CurrentCol < MaxCol) and (setupatime == false)) {
CurrentCol = CurrentCol + 3;
lcd.setCursor(CurrentCol, CurrentRow);
String Output = UpandDown(CurrentCol, CurrentRow, 'f');
lcd.print(Output);
}
//swdone
swdone = digitalRead(ButtonDonePin);
if ((swdone == 0) and (setupatime == false)) {
if (MOrder == "FAN") {
int orderF = digitalRead(RelayFanPin);
if (orderF == HIGH) {
digitalWrite(RelayFanPin, LOW);
} else {
digitalWrite(RelayFanPin, HIGH);
}
}
else if (MOrder == "SPK") { //debug
int orderS = digitalRead(RelaySpkPin);
if (orderS == HIGH) {
digitalWrite(RelaySpkPin, LOW);
} else {
digitalWrite(RelaySpkPin, HIGH);
}
}
else if (MOrder == "SOL") { //debug
int orderSo = digitalRead(RelaySolPin);
if (orderSo == HIGH) {
digitalWrite(RelaySolPin, LOW);
} else {
digitalWrite(RelaySolPin, HIGH);
}
}
else if (MOrder == "FDD") {
numround = numround + 1;
servomove();
lcd.setCursor(10, 3);
lcd.print(" ");
}
else if (MOrder == "PMI") { //debug
int orderPi = digitalRead(RelayPMIPin);
if (orderPi == HIGH) {
digitalWrite(RelayPMIPin, LOW);
} else {
digitalWrite(RelayPMIPin, HIGH);
}
}
else if (MOrder == "PMO") {
int orderPo = digitalRead(RelayPMOPin);
if (orderPo == HIGH) {
digitalWrite(RelayPMOPin, LOW);
} else {
digitalWrite(RelayPMOPin, HIGH);
}
}
}
lcd.setCursor(CurrentCol, CurrentRow);
String Output = UpandDown(CurrentCol, CurrentRow, 'f');
lcd.print(Output);
} // end button control manual
void ButtonAuto() {
DisplayFunda();
} // end button auto
void DisplaySetup() {
lcd.setCursor(PosiCol, PosiRow + 1);
lcd.write(byte(0)); // แสดงอักขระพิเศษ Arrow up
if (SetupArr <= 14) {
lcd.setCursor(0, PosiRow);
if (SetupArr + 1 >= 10) {
lcd.print(SetupArr + 1);
} else {
lcd.print(SetupArr + 1);
lcd.print(" ");
}
}
if ((SetupArr >= 0) and (SetupArr <= 6 )) {
lcd.setCursor(2, 2);
lcd.print(SensorArr[SetupArr]);
lcd.setCursor(7, 2);
lcd.print(">");
lcd.print(MinSensorValue[SetupArr]);
lcd.print(FormatFour(MinSensorValue[SetupArr]));
lcd.setCursor(13, 2);
lcd.print("<");
lcd.print(MaxSensorValue[SetupArr]);
lcd.print(FormatFour(MaxSensorValue[SetupArr]));
} else if ((SetupArr >= 7) and (SetupArr <= 14)) {
lcd.setCursor(2, 2);
lcd.print(SensorArr[SetupArr]);
lcd.setCursor(7, 2);
lcd.print(" ");
lcd.setCursor(14, 2);
lcd.print(MaxSensorValue[SetupArr]);
lcd.print(FormatFour(MaxSensorValue[SetupArr]));
/*
Serial.print("Min ");
Serial.print(MinSensorValue[SetupArr]);
Serial.print("Max ");
Serial.print(MaxSensorValue[SetupArr]);
*/
}
lcd.setCursor(PosiCol, PosiRow + 1);
lcd.print(" "); //อักขระพิเศษกระพริบ
}
void ButtonSetup() {
if (setupatime == true) {
if ((SetupArr >= 0) and (SetupArr <= 6 )) {
//swup
swup = digitalRead(ButtonUpPin);
if ((swup == 0 ) and (SetupArr < 14 )) {
switch (PosiCol) {
case 0:
SetupArr++;
break;
case 8:
MinSensorValue[SetupArr]++;
break;
case 14:
MaxSensorValue[SetupArr]++;
break;
}
}
//swdown
swdown = digitalRead(ButtonDownPin);
if ((swdown == 0) and (SetupArr >= 0)) {
switch (PosiCol) {
case 0:
if (SetupArr > 0) SetupArr--;
break;
case 8:
if (MinSensorValue[SetupArr] > 0) MinSensorValue[SetupArr]--;
break;
case 14:
if (MaxSensorValue[SetupArr] > 0) MaxSensorValue[SetupArr]--;
break;
}
}
Serial.print("swdown");
Serial.print("SetupArr ");
Serial.println(SetupArr);
//swleft
swleft = digitalRead(ButtonLeftPin);
if ((swleft == 0) and (PosiCol > SetupPosi[0] )) {
ArrIndex--;
PosiCol = SetupPosi[ArrIndex];
lcd.setCursor(PosiCol, PosiRow);
Serial.print("PosiCol ");
Serial.print(PosiCol);
Serial.print("Row ");
Serial.print(PosiRow);
}
//swright
swright = digitalRead(ButtonRightPin);
if ((swright == 0) and (PosiCol < SetupPosi[2])) {
ArrIndex++;
PosiCol = SetupPosi[ArrIndex];
lcd.setCursor(PosiCol, PosiRow);
Serial.print("SetupArr ");
Serial.print(SetupArr);
Serial.print("PosiCol ");
Serial.print(PosiCol);
Serial.print("Row ");
Serial.println(PosiRow);
}
} else if ((SetupArr >= 7 ) and (SetupArr <= 14)) {
/////
swup = digitalRead(ButtonUpPin);
if ((swup == 0 ) and (SetupArr <= 14)) {
switch (PosiCol) {
case 0:
if (SetupArr < 14) SetupArr++;
break;
case 14:
MaxSensorValue[SetupArr]++;
break;
}
Serial.print("swup ");
Serial.print("SetupArr ");
Serial.println(SetupArr);
}
//swdown
swdown = digitalRead(ButtonDownPin);
if ((swdown == 0) and (SetupArr > 0) ) {
switch (PosiCol) {
case 0:
SetupArr--;
break;
case 14:
if (MaxSensorValue[SetupArr] > 0) MaxSensorValue[SetupArr]--;
break;
}
Serial.print("swdown ");
Serial.print("SetupArr ");
Serial.println(SetupArr);
}
//swleft
swleft = digitalRead(ButtonLeftPin);
if ((swleft == 0) and (PosiCol > SetupPosi[0] )) {
ArrIndex = ArrIndex - 2;
PosiCol = SetupPosi[ArrIndex];
lcd.setCursor(PosiCol, PosiRow);
// Serial.print("PosiCol ");
////Serial.print(PosiCol);
//Serial.print("Row ");
//Serial.print(PosiRow);
}
//swright
swright = digitalRead(ButtonRightPin);
if ((swright == 0) and (PosiCol < SetupPosi[2])) {
ArrIndex = ArrIndex + 2;
PosiCol = SetupPosi[ArrIndex];
lcd.setCursor(PosiCol, PosiRow);
//Serial.print("PosiCol ");
//Serial.print(PosiCol);
//Serial.print("Row ");
//Serial.print(PosiRow);
}
////
}
}
} // End button setup
void CheckFoodFeed() { //Check feed food
int val = analogRead(IRPin); //อ่านค่าสัญญาณ ซ็นเซอร์ตรวจจับวัตถุ IR Infrared
Serial.print("val = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "val = "
Serial.println(val); // พิมพ์ค่าของตัวแปร val
if (val > 100 ) { // ไม่มีสิ่งกีดขวาง
lcd.setCursor(10, 3);
lcd.print("FFOODEMPTY");
//tone(buzzerpin, NOTE_B4, 80);
digitalWrite(BuzzerPin, HIGH);
delay(20);
digitalWrite(BuzzerPin, LOW);
//digitalWrite(ledir, HIGH);
}
else {
lcd.setCursor(10, 3);
lcd.print(" ");
//digitalWrite(ledir, LOW);
}
}
void DisplayDateTime() {
DateTime now = rtc.now();
//Date
lcd.setCursor(6, 0);
if (now.day() > 9) {
lcd.print(now.day(), DEC);
} else {
lcd.print("0");
lcd.print(now.day(), DEC);
}
lcd.print("/");
if (now.month() > 9) {
lcd.print(now.month(), DEC);
} else {
lcd.print("0");
lcd.print(now.month(), DEC);
}
lcd.print("/");
int dyear = now.year() - 2000;
if (dyear > 9) {
lcd.print(dyear, DEC);
} else {
lcd.print("0");
lcd.print(dyear, DEC);
}
//Time
lcd.setCursor(15, 0);
if (now.hour() > 9) {
lcd.print(now.hour(), DEC);
} else {
lcd.print("0");
lcd.print(now.hour(), DEC);
}
lcd.print(":");
if (now.minute() > 9) {
lcd.print(now.minute(), DEC);
} else {
lcd.print("0");
lcd.print(now.minute(), DEC);
}
}//end displayDate
void DisplayTime() {
DateTime now = rtc.now();
lcd.setCursor(15, 0);
if (now.hour() > 9) {
lcd.print(now.hour(), DEC);
} else {
lcd.print("0");
lcd.print(now.hour(), DEC);
}
lcd.print(":");
if (now.minute() > 9) {
lcd.print(now.minute(), DEC);
} else {
lcd.print("0");
lcd.print(now.minute(), DEC);
}
}//end displaytime
void servomove() {
CheckFoodFeed();
//digitalWrite(ledservo, HIGH);
for (int nmove = curround ; nmove >= 1; nmove--) { //number for move
lcd.setCursor(10, 3);
lcd.print("ServoMove");
lcd.print(nmove);
//lcd.print(" ");
Serial.print("nmove ");
Serial.println(nmove);
for (pos = 0; pos <= 180; pos += 1) {
servo.write(pos);
delay(15);
}
for (pos = 180; pos >= 0; pos -= 1) {
servo.write(pos);
delay(15);
}
}
//digitalWrite(ledservo, LOW);
}
void OnOffSol(unsigned long PreMillis, int index) {
int IntervalSol = MaxSensorValue[11] * 1000;
if (millis() - PreMillis >= IntervalSol) {
// เก็บเวลาเริ่มต้นของการเปลี่ยนสถานะ Relay
PrevMillisArr[index] = millis();
// สลับสถานะ Relay
SolSwtState = !SolSwtState;
digitalWrite(RelaySolPin, SolSwtState ? HIGH : LOW);
Serial.print("Sol ");
Serial.print(" IntervalSol ");
Serial.println(IntervalSol);
}
//
}
void OnOffFan(unsigned long cMillis, int index) {
int IntervalFan = MaxSensorValue[8] * 1000;
if (cMillis - PrevMillisArr[index] >= IntervalFan) {
// เก็บเวลาเริ่มต้นของการเปลี่ยนสถานะ Relay
PrevMillisArr[index] = cMillis;
// สลับสถานะ Relay
FanSwtState = !FanSwtState;
digitalWrite(RelayFanPin, FanSwtState ? HIGH : LOW);
Serial.print("Fan ");
Serial.print(" IntervalFan ");
Serial.println(IntervalFan);
}
}
void OnOffSpk(unsigned long cMillis, int index) {
int IntervalSpk = MaxSensorValue[9] * 1000;
if (cMillis - PrevMillisArr[index] >= IntervalSpk) {
// เก็บเวลาเริ่มต้นของการเปลี่ยนสถานะ Relay
PrevMillisArr[index] = cMillis;
// สลับสถานะ Relay
SpkSwtState = !SpkSwtState;
digitalWrite(RelaySpkPin, SpkSwtState ? HIGH : LOW);
Serial.print("Spk ");
Serial.print(" IntervalSpk ");
Serial.println(IntervalSpk);
}
}
void OnOffPMI(unsigned long cMillis, int index) {
int IntervalPMI = MaxSensorValue[12] * 1000;
if (cMillis - PrevMillisArr[index] >= IntervalPMI) {
// เก็บเวลาเริ่มต้นของการเปลี่ยนสถานะ Relay
PrevMillisArr[index] = cMillis;
// สลับสถานะ Relay
PMISwtState = !PMISwtState;
digitalWrite(RelayPMIPin, PMISwtState ? HIGH : LOW);
Serial.print("PMI ");
Serial.print(" IntervalPMI ");
Serial.println(IntervalPMI);
}
}
void OnOffPMO(unsigned long cMillis, int index) {
int IntervalPMO = MaxSensorValue[13] * 1000;
if (cMillis - PrevMillisArr[index] >= IntervalPMO) {
// เก็บเวลาเริ่มต้นของการเปลี่ยนสถานะ Relay
PrevMillisArr[index] = cMillis;
// สลับสถานะ Relay
PMOSwtState = !PMOSwtState;
digitalWrite(RelayPMOPin, PMOSwtState ? HIGH : LOW);
Serial.print("PMO ");
Serial.print(" IntervalPMO ");
Serial.println(IntervalPMO);
}
}
void automode() {//every 5 minute
unsigned long currentMillis = millis();
if ( currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
for (int i = 0; i <= 6; i++) {
PrevMillisArr[i] = currentMillis;
}
if (mode == true) {//auto
lcd.setCursor(10, 3);
lcd.print(" ");
DateTime now = rtc.now();
for (int i = 0; i <= 6; i++) {
switch (i) {
case 0:
if (DHT_Ok) {
if (now.hour() >= 6 && now.hour() < 18) {//It's daytime.;
int t = dht.readTemperature();
if (t < MinSensorValue[i]) {//เปิดไฟ
//
OnOffSol(PrevMillisArr[i],i);
OnOffFan(currentMillis, i);
//Springkler
OnOffSpk(currentMillis, i);
//
}
}
}
break;
case 1:
if (DHT_Ok) {
if (now.hour() >= 18 && now.hour() < 6) {//It's nighttime.;
int t = dht.readTemperature();
if (t < MinSensorValue[i]) {
// Solar
OnOffSol(currentMillis, i);
}
if (t > MaxSensorValue[i]) {//เปิด พัดลม, springkler
//Fan
OnOffFan(currentMillis, i);
//Springkler
OnOffSpk(currentMillis, i);
}
}
}
break;
case 2:
if (DHT_Ok) {
int h = dht.readHumidity();
if (h < MinSensorValue[i]) {//เปิด Spk
//Springkler
OnOffSpk(currentMillis, i);
}
if (h > MaxSensorValue[i]) {//เปิด พัดลม, เปิดไฟ
OnOffFan(currentMillis, i);
OnOffSol(currentMillis, i);
}
}
break;
case 7: //check ต้องตรวจสอบเวลาการให้อาหารตามเวลา
servomove();
numround = 0;
break;
case 4:
if (WaterL_Ok) {
int Wvalue = analogRead(WaterLevelPin); // Water Level
if (Wvalue < MinSensorValue[i]) {//เปิด PMI และตรวจสอบระดับน้ำให้อยู่ในช่วงที่ตั้งไว้
OnOffPMI(currentMillis, i);
}
if (Wvalue > MaxSensorValue[i]) {//เปิด PMO
OnOffPMO(currentMillis, i);
}
}
break;
case 5: //ph
if (PH_Ok) {
float voltage; // ตัวแปรสำหรับเก็บค่าความดันไฟฟ้า
int pHValue; // ตัวแปรสำหรับเก็บค่าพีเอช
voltage = analogRead(PHPin) * (5.0 / 1023.0); // แปลงค่า analog เป็นแรงดันไฟฟ้า
pHValue = 3.5 * voltage + offset(); // แปลงแรงดันไฟฟ้าเป็นค่าพีเอช
if (pHValue < MinSensorValue[i]) {//เปิด PMI และตรวจสอบระดับน้ำให้อยู่ในช่วงที่ตั้งไว้
lcd.setCursor(10, 3);
lcd.print("pH < ");
lcd.print(pHValue);
OnOffPMI(currentMillis, i); //Waiting Test
}
if (pHValue > MaxSensorValue[i]) {//เปิด PMO
lcd.setCursor(10, 3);
lcd.print("pH > ");
lcd.print(pHValue);
OnOffPMO(currentMillis, i); //Watiing Test
}
}
break;
case 3: //Light intensity
//servomove();
//numround = 0;
break;
case 6: //water quality
if (WaterQ_Ok) {
int WaterQ = analogRead(WaterQPin); // Water Level
if (WaterQ < MinSensorValue[i]) {//เปิด PMI และตรวจสอบระดับน้ำให้อยู่ในช่วงที่ตั้งไว้
lcd.setCursor(10, 3);
lcd.print("WQ < ");
lcd.print(WaterQ);
OnOffPMI(currentMillis, i); //Waiting Test
}
if (WaterQ > MaxSensorValue[i]) {//เปิด PMO
lcd.setCursor(10, 3);
lcd.print("WQ > ");
lcd.print(WaterQ);
OnOffPMO(currentMillis, i); //Watiing Test
}
}
break;
}
}
}
}//end if
//
//
} //end automode