// Include libraries
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// Blynk credentials (GANTI DENGAN MILIKMU)
char auth[] = "YOUR_BLYNK_AUTH_TOKEN"; // Dapatkan dari Blynk app
char ssid[] = "Wokwi-GUEST"; // WiFi SSID untuk Wokwi (atau WiFi rumahmu)
char pass[] = ""; // WiFi password (kosong untuk Wokwi)
// Pin definitions
#define LED_PIN 13
#define LDR_PIN 34 // Analog pin untuk LDR sensor (ganti dari POT_PIN)
#define BUZZER_PIN 15
#define LCD_ADDR 0x27 // Alamat I2C LCD (default 0x27 atau 0x3F)
// Threshold untuk LDR (sesuaikan: >2000 = gelap = trigger toggle)
#define LDR_THRESHOLD 2000 // Nilai analog tinggi = gelap (test dengan Serial Monitor)
// Objects
RTC_DS3231 rtc;
LiquidCrystal_I2C lcd(LCD_ADDR, 16, 2);
// Variables
bool lampuState = false; // Status lampu (false = mati)
bool lastTriggerState = false; // Flag untuk deteksi perubahan (debounce, untuk LDR)
unsigned long lastToggle = 0; // Untuk debounce (minimal 1 detik)
int alarmHour = 0; // Jam alarm (dari Blynk V1)
int alarmMinute = 0; // Menit alarm (dari Blynk V2)
bool alarmActive = false; // Flag untuk alarm berbunyi
unsigned long lastUpdate = 0; // Untuk update LCD (setiap 1 detik)
void setup() {
// Initialize pins
pinMode(LED_PIN, OUTPUT);
pinMode(LDR_PIN, INPUT); // Analog untuk LDR (aktif default)
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
// Initialize Serial for debug (lihat nilai LDR di sini)
Serial.begin(115200);
// Initialize I2C
Wire.begin(21, 22); // SDA=21, SCL=22 untuk ESP32
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Starting...");
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
lcd.clear();
lcd.print("RTC Error!");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Set waktu compile sebagai default
}
// Connect to Blynk
Blynk.begin(auth, ssid, pass);
// Initial LCD
updateLCD();
}
void loop() {
Blynk.run(); // Handle Blynk
// Update LCD setiap 1 detik
if (millis() - lastUpdate > 1000) {
updateLCD();
checkAlarm(); // Cek alarm
lastUpdate = millis();
}
// === LOGIC UNTUK LDR SENSOR (AKTIF DEFAULT) ===
int ldrValue = analogRead(LDR_PIN);
Serial.print("LDR Value: "); Serial.println(ldrValue); // Debug (pantau di Serial Monitor)
bool isTrigger = (ldrValue > LDR_THRESHOLD); // Tinggi = gelap = trigger (simulasi kondisi gelap)
if (isTrigger && !lastTriggerState && (millis() - lastToggle > 1000)) { // Edge + debounce
lampuState = !lampuState; // Toggle
digitalWrite(LED_PIN, lampuState);
Serial.println(lampuState ? "Lampu NYALA (LDR gelap)" : "Lampu MATI (LDR terang)");
Blynk.virtualWrite(V0, lampuState); // Sync ke Blynk
lastToggle = millis();
}
lastTriggerState = isTrigger;
// Alarm buzzer (jika active, beep setiap detik)
if (alarmActive) {
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(800);
// Jika lampu nyala saat alarm, matikan otomatis
if (lampuState) {
lampuState = false;
digitalWrite(LED_PIN, LOW);
Serial.println("Lampu MATI (alarm)");
Blynk.virtualWrite(V0, false);
}
}
}
// Blynk functions (sama seperti sebelumnya)
BLYNK_WRITE(V0) { // Virtual Pin V0: Switch untuk kontrol lampu
lampuState = param.asInt();
digitalWrite(LED_PIN, lampuState);
Serial.println(lampuState ? "Lampu NYALA (Blynk)" : "Lampu MATI (Blynk)");
}
BLYNK_WRITE(V1) { // Virtual Pin V1: Slider jam alarm (0-23)
alarmHour = param.asInt();
Serial.print("Alarm Jam: "); Serial.println(alarmHour);
rtc.setAlarm(ALM1_MATCH_HOURS, 0, alarmHour, 0); // Menit=0, detik=0
}
BLYNK_WRITE(V2) { // Virtual Pin V2: Slider menit alarm (0-59)
alarmMinute = param.asInt();
Serial.print("Alarm Menit: "); Serial.println(alarmMinute);
rtc.setAlarm(ALM1_MATCH_MINUTES, 0, alarmMinute, alarmHour); // Detik=0
}
// Function to update LCD (sama)
void updateLCD() {
DateTime now = rtc.now();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
if (now.hour() < 10) lcd.print("0");
lcd.print(now.hour());
lcd.print(":");
if (now.minute() < 10) lcd.print("0");
lcd.print(now.minute());
lcd.print(":");
if (now.second() < 10) lcd.print("0");
lcd.print(now.second());
lcd.setCursor(0, 1);
lcd.print("Alarm: ");
if (alarmHour < 10) lcd.print("0");
lcd.print(alarmHour);
lcd.print(":");
if (alarmMinute < 10) lcd.print("0");
lcd.print(alarmMinute);
lcd.print(" Lampu:");
lcd.print(lampuState ? "ON" : "OFF");
}
// Function to check alarm (sama)
void checkAlarm() {
DateTime now = rtc.now();
if (now.hour() == alarmHour && now.minute() == alarmMinute && now.second() == 0) {
alarmActive = true;
Serial.println("ALARM BERBUNYI!");
} else {
alarmActive = false;
}
}Loading
esp32-devkit-c-v4
esp32-devkit-c-v4