#define BLYNK_TEMPLATE_ID "TMPL6OqbcItot"
#define BLYNK_TEMPLATE_NAME "Project IOT"
#define BLYNK_AUTH_TOKEN "pjWDKo0VoGoyy55OZ27P4tMBaotyeCRD"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <LiquidCrystal_I2C.h>
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
const int PIN_POT = 34, PIN_RELAY = 26, PIN_BUZZER = 27;
float sisaKwh = 12.0;
float daya = 0; // daya terpakai (W)
bool bebanOn = true; // relay beban non-esensial
int level = 0; // 0 = AMAN, 1 = WASPADA, 2 = KRITIS
const char* NAMA[] = {"AMAN", "WASPADA", "KRITIS"};
BlynkTimer timer;
LiquidCrystal_I2C lcd(0x27, 16, 2);
void bip(int kali) {
for (int k = 0; k < kali; k++) {
for (int i = 0; i < 200; i++) {
digitalWrite(PIN_BUZZER, HIGH); delayMicroseconds(500);
digitalWrite(PIN_BUZZER, LOW); delayMicroseconds(500);
}
delay(150);
}
}
void hitung() {
// 1. Baca sensor
daya = analogRead(PIN_POT) * 2500.0 / 4095.0;
if (!bebanOn && daya > 200) daya = 200;
// 2. Kurangi token (1 detik nyata dianggap 10 menit)
sisaKwh -= (daya / 1000.0) * (600.0 / 3600.0);
if (sisaKwh < 0) sisaKwh = 0;
// 3. Tentukan level
int levelBaru = 0;
if (sisaKwh <= 10) levelBaru = 1;
if (sisaKwh <= 3) levelBaru = 2;
// 4. Jika level memburuk: notifikasi + buzzer
if (levelBaru > level) {
if (levelBaru == 1) { Blynk.logEvent("token_menipis", "Token tinggal 10 kWh"); bip(1); }
if (levelBaru == 2) { Blynk.logEvent("token_kritis", "Token kritis, beban diputus"); bip(3); }
}
level = levelBaru;
// 5. Kritis -> putus beban non-esensial
if (level == 2 && bebanOn) {
bebanOn = false;
Blynk.virtualWrite(V4, 0);
}
digitalWrite(PIN_RELAY, bebanOn ? HIGH : LOW);
// 6. Tampilkan di LCD dan Serial Monitor
lcd.setCursor(0, 0); lcd.print("Token: " + String(sisaKwh, 1) + " kWh ");
lcd.setCursor(0, 1); lcd.print("Daya : " + String(daya, 0) + " W ");
Serial.println(String(NAMA[level]) + " | " + String(daya, 0) + " W | " + String(sisaKwh, 2) + " kWh");
}
void kirimData() {
Blynk.virtualWrite(V0, (int)daya);
Blynk.virtualWrite(V1, sisaKwh);
Blynk.virtualWrite(V2, NAMA[level]);
}
BLYNK_WRITE(V3) {
float tambah = param.asFloat();
if (tambah <= 0) return;
sisaKwh += tambah;
if (sisaKwh > 50) sisaKwh = 50;
if (level == 2 && sisaKwh > 3) {
bebanOn = true;
Blynk.virtualWrite(V4, 1);
}
}
// Kontrol dari Blynk: Switch "Beban Non-Esensial"
BLYNK_WRITE(V4) {
bebanOn = (param.asInt() == 1);
if (level == 2) {
bebanOn = false;
Blynk.virtualWrite(V4, 0);
}
}
BLYNK_CONNECTED() {
Blynk.virtualWrite(V4, bebanOn ? 1 : 0);
}
void setup() {
Serial.begin(115200);
pinMode(PIN_RELAY, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
lcd.init();
lcd.backlight();
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
timer.setInterval(1000L, hitung);
timer.setInterval(3000L, kirimData);
}
void loop() {
Blynk.run();
timer.run();
}
Loading
esp32-devkit-c-v4
esp32-devkit-c-v4