#define BLYNK_TEMPLATE_ID "TMPL6oANP5se5" #define BLYNK_TEMPLATE_NAME "Hamster" #define BLYNK_AUTH_TOKEN "Os8S_bWQluJnzva0eW_Rmtvv2KDJbvGA" #include #include #include #include #include #include "RTClib.h" Servo servo; RTC_DS3231 rtc; LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address, columns, rows const int servoPin = 25; const int trigPin = 5; const int echoPin = 34; const int ledPin = 2; const int buttonPin = 23; char ssid[] = "Barudak RIAU"; char pass[] = "tanyadulu"; int jamInput = -1; int menitInput = -1; BlynkTimer timer; // Fungsi pemberian pakan void aktifkanServo() { Serial.println("šŸ”§ Servo aktif: Memberi pakan"); servo.write(90); delay(500); servo.write(0); delay(500); } // Blynk: Tombol V0 untuk aktifkan servo BLYNK_WRITE(V0) { int value = param.asInt(); if (value == 1) { aktifkanServo(); } } // Blynk: Input waktu dari V1 BLYNK_WRITE(V1) { String waktu = param.asStr(); int delimiter = waktu.indexOf(':'); if (delimiter != -1) { jamInput = waktu.substring(0, delimiter).toInt(); menitInput = waktu.substring(delimiter + 1).toInt(); Serial.print("šŸ•’ Input manual dari Blynk: "); Serial.print(jamInput); Serial.print(":"); Serial.println(menitInput); } } // Fungsi utama pengecekan void cekPakanDanWaktu() { DateTime now = rtc.now(); int hour = now.hour(); int minute = now.minute(); int second = now.second(); // LCD: Tampilkan jam lcd.setCursor(0, 0); lcd.print("Jam: "); if (hour < 10) lcd.print("0"); lcd.print(hour); lcd.print(":"); if (minute < 10) lcd.print("0"); lcd.print(minute); lcd.print(":"); if (second < 10) lcd.print("0"); lcd.print(second); // Serial: Tampilkan jam Serial.print("šŸ•’ Waktu: "); Serial.print(hour); Serial.print(":"); Serial.print(minute); Serial.print(":"); Serial.println(second); // Kirim waktu ke Blynk (opsional) Blynk.virtualWrite(V1, String(hour) + ":" + String(minute)); // Cek waktu pemberian pakan otomatis if (((hour == 8 || hour == 12 || hour == 18) && minute == 0 && second == 0) || (hour == jamInput && minute == menitInput && second == 0)) { aktifkanServo(); delay(1000); } // Sensor ultrasonik: baca jarak digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH); float jarak = duration * 0.034 / 2; lcd.setCursor(0, 1); if (jarak <= 9.0) { digitalWrite(ledPin, LOW); lcd.print("Pakan Ada "); Blynk.virtualWrite(V3, "Pakan Ada"); Blynk.virtualWrite(V2, 255); // LED ON di app Serial.println("āœ… Status: Pakan ADA"); } else { digitalWrite(ledPin, HIGH); lcd.print("Pakan Habis "); Blynk.virtualWrite(V3, "Pakan Habis"); Blynk.virtualWrite(V2, 0); // LED OFF di app Serial.println("āš ļø Status: Pakan HABIS"); } // Cek tombol fisik if (digitalRead(buttonPin) == LOW) { Serial.println("šŸ”˜ Tombol ditekan: Servo aktif"); aktifkanServo(); delay(500); } } void setup() { Serial.begin(115200); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); servo.attach(servoPin); lcd.init(); // untuk inisialisasi lcd.backlight(); // RTC if (!rtc.begin()) { Serial.println("ā›” RTC tidak ditemukan!"); while (1); } // WiFi manual untuk kontrol error Serial.print("šŸ“¶ Menghubungkan ke WiFi: "); Serial.println(ssid); WiFi.begin(ssid, pass); int retries = 0; while (WiFi.status() != WL_CONNECTED && retries < 20) { delay(500); Serial.print("."); retries++; } if (WiFi.status() == WL_CONNECTED) { Serial.println("\nāœ… WiFi Terhubung"); Serial.print("šŸ“” IP ESP32: "); Serial.println(WiFi.localIP()); Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass); } else { Serial.println("\nā›” Gagal tersambung ke WiFi. Blynk tidak dijalankan."); } timer.setInterval(1000L, cekPakanDanWaktu); } void loop() { if (WiFi.status() == WL_CONNECTED) { Blynk.run(); } timer.run(); }