commit 13024658b4627da31d59947dbe4756c9c8dbe211 Author: Wahyue Date: Tue Jul 9 12:35:25 2024 +0700 first commit diff --git a/pzem004t.ino b/pzem004t.ino new file mode 100644 index 0000000..2a87845 --- /dev/null +++ b/pzem004t.ino @@ -0,0 +1,232 @@ +#include // Library Thinger.io untuk ESP8266 +#include // Library untuk sensor PZEM004Tv30 +#include // Library WiFiManager untuk manajemen koneksi Wi-Fi +#include // Library NTPClient untuk sinkronisasi waktu +#include // Library WiFiUDP untuk komunikasi UDP +#include // Library EEPROM untuk penyimpanan data + +#define USERNAME "wahyuee" // Username Thinger.io +#define DEVICE_ID "NodeMCU_PZEM" // ID perangkat Thinger.io +#define DEVICE_CREDENTIAL "abogoboga" // Kredensial perangkat Thinger.io + +ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL); // Objek ThingerESP8266 untuk menghubungkan ke Thinger.io + +// Pin yang terhubung ke relay 4 channel +const int relay1 = D0; +const int relay2 = D1; +const int relay3 = D3; +const int relay4 = D4; +const int buzzerPin = D2; // Pin buzzer + +PZEM004Tv30 pzem(14, 12); // GPIO14(D5) ke Tx PZEM004; GPIO12(D6) ke Rx PZEM004 + +// Variabel untuk menyimpan data sensor +float Voltage, Current, Power, Energy, Frequency, PF, VA, VAR, totalCost; +bool relay1State = LOW; // Relay1 awalnya dalam keadaan hidup +unsigned long relayOffTime = 0; // Waktu saat relay1 dimatikan +const float tariffPerKWh = 1352.0; // Tarif per kWh +unsigned long startTime = 0; // Waktu awal + +WiFiUDP ntpUDP; // Objek WiFiUDP untuk komunikasi NTP +NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 60000); // Klien NTP untuk sinkronisasi waktu, update setiap menit + +const int EEPROM_SIZE = 10; // Ukuran EEPROM +const int EEPROM_ADDR = 0; // Alamat EEPROM untuk penyimpanan data + +void setup() { + WiFi.mode(WIFI_STA); // Mengatur mode WiFi menjadi station + Serial.begin(115200); // Memulai komunikasi serial dengan baud rate 115200 + WiFiManager wm; // Objek WiFiManager untuk manajemen koneksi Wi-Fi + wm.resetSettings(); // Mereset pengaturan WiFiManager + startTime = millis(); // Mendapatkan waktu awal dalam milidetik + + // Mengatur pin relay dan buzzer sebagai output + pinMode(relay1, OUTPUT); + pinMode(relay2, OUTPUT); + pinMode(relay3, OUTPUT); + pinMode(relay4, OUTPUT); + pinMode(buzzerPin, OUTPUT); + + bool res; + // Menghubungkan ke Wi-Fi dengan WiFiManager + res = wm.autoConnect("AutoConnectAP", "password"); + if (!res) { + Serial.println("Failed to connect"); + } else { + Serial.println("connected... :)"); + } + + thing.add_wifi(WiFi.SSID().c_str(), WiFi.psk().c_str()); // Menambahkan koneksi Wi-Fi ke Thinger.io + + // Mendefinisikan endpoint untuk data sensor pada Thinger.io + thing["PZEM"] >> [] (pson & out) { + out["voltage"] = String(Voltage, 2); + out["current"] = String(Current, 2); + out["power"] = String(Power, 2); + out["energy"] = String(Energy, 3); + out["frequency"] = String(Frequency, 2); + out["faktor daya"] = String(PF, 2); + out["Apparent Power"] = String(VA, 2); + out["Reactive Power"] = String(VAR, 2); + out["Total Biaya"] = String(totalCost, 2); + }; + + // Mendefinisikan endpoint untuk setiap relay pada Thinger.io + thing["Perangkat 1"] << digitalPin(relay1); + thing["Perangkat 2"] << digitalPin(relay2); + thing["Perangkat 3"] << digitalPin(relay3); + thing["Perangkat 4"] << digitalPin(relay4); + + timeClient.begin(); // Memulai klien NTP + + EEPROM.begin(EEPROM_SIZE); // Memulai EEPROM dengan ukuran yang telah ditentukan + unsigned long lastResetTime = 0; // Waktu reset terakhir + EEPROM.get(EEPROM_ADDR, lastResetTime); // Mendapatkan waktu reset terakhir dari EEPROM + + if (lastResetTime == 0) { // Jika waktu reset terakhir adalah 0 + lastResetTime = timeClient.getEpochTime(); // Mengatur waktu reset terakhir dengan waktu saat ini + EEPROM.put(EEPROM_ADDR, lastResetTime); // Menyimpan waktu reset terakhir ke EEPROM + EEPROM.commit(); // Mengkomit perubahan ke EEPROM + } +} + +void loop() { + thing.handle(); // Menghandle koneksi dan komunikasi dengan Thinger.io + timeClient.update(); // Mengupdate waktu dari NTP + + // Membaca data dari sensor PZEM-004T + Voltage = pzem.voltage(); + Current = pzem.current(); + Power = pzem.power(); + Energy = pzem.energy(); + Frequency = pzem.frequency(); + PF = pzem.pf(); + + // Menghitung Apparent Power (VA) + if (PF == 0) { + VA = 0; + } else { + VA = Power / PF; + } + + // Menghitung Reactive Power (VAR) + if (PF == 0) { + VAR = 0; + } else { + VAR = Power / PF * sqrt(1 - sq(PF)); + } + + totalCost = Energy * tariffPerKWh; // Menghitung total biaya berdasarkan energi dan tarif + + // Memeriksa validitas data dan menampilkan nilai-nilai pada Serial console + if (isnan(Voltage)) { + Serial.println("Error membaca tegangan"); + } else { + Serial.print("Voltage : "); + Serial.print(Voltage); + Serial.println("V"); + } + + if (isnan(Current)) { + Serial.println("Error membaca arus"); + } else { + Serial.print("Current : "); + Serial.print(Current); + Serial.println("A"); + } + + if (isnan(Power)) { + Serial.println("Error membaca daya"); + } else { + Serial.print("Power : "); + Serial.print(Power); + Serial.println("W"); + } + + if (isnan(Frequency)) { + Serial.println("Error membaca frekuensi"); + } else { + Serial.print("Frequency : "); + Serial.print(Frequency); + Serial.println("Hz"); + } + + if (isnan(PF)) { + Serial.println("Error membaca faktor daya"); + } else { + Serial.print("Faktor Daya : "); + Serial.print(PF); + Serial.println("PF"); + } + + if (isnan(VA)) { + Serial.println("Error membaca apparent power"); + } else { + Serial.print("Apparent Power : "); + Serial.print(VA); + Serial.println("VA"); + } + + if (isnan(VAR)) { + Serial.println("Error membaca reactive power"); + } else { + Serial.print("Reactive Power : "); + Serial.print(VAR); + Serial.println("VAR"); + } + + if (isnan(Energy)) { + Serial.println("Error membaca energi"); + } else { + Serial.print("Energy : "); + Serial.print(Energy, 3); + Serial.println("kWh"); + } + + if (isnan(totalCost)) { + Serial.println("Error menghitung biaya"); + } else { + Serial.print("Total Biaya: "); + Serial.println(totalCost); + } + + // Mengaktifkan buzzer jika Apparent Power dalam rentang 90-100 VA + if (VA >= 90 && VA <= 100) { + digitalWrite(buzzerPin, HIGH); + delay(1000); + digitalWrite(buzzerPin, LOW); + delay(1000); + thing.call_endpoint("monitor_listrik"); // Memanggil endpoint yang telah dibuat + } else { + digitalWrite(buzzerPin, LOW); + } + + // Jika Apparent Power lebih dari 100 VA, matikan relay1 + if (VA > 100) { + if (relay1State == LOW) { + digitalWrite(relay1, HIGH); + relay1State = HIGH; + relayOffTime = millis(); // Mengatur waktu saat relay1 dimatikan + thing.call_endpoint("monitor_listrik1"); // Memanggil endpoint yang telah dibuat + } + } else { + if (relay1State == HIGH && millis() - relayOffTime >= 120000) { // Periksa apakah sudah 2 menit berlalu + digitalWrite(relay1, LOW); + relay1State = LOW; + } + } + + // Mengecek apakah sudah 30 hari berlalu dan mereset energi jika ya + unsigned long currentTime = timeClient.getEpochTime(); + unsigned long lastResetTime; + EEPROM.get(EEPROM_ADDR, lastResetTime); + + if (currentTime - lastResetTime >= 2592000) { // 30 hari = 2592000 detik + pzem.resetEnergy(); // Mereset energi pada sensor PZEM + EEPROM.put(EEPROM_ADDR, currentTime); // Menyimpan waktu reset terakhir ke EEPROM + EEPROM.commit(); // Mengkomit perubahan ke EEPROM + } + + Serial.println(); + delay(1000); +} diff --git a/pzem004t.ino8974169033029273303.tmp b/pzem004t.ino8974169033029273303.tmp new file mode 100644 index 0000000..d6a7a65 --- /dev/null +++ b/pzem004t.ino8974169033029273303.tmp @@ -0,0 +1,196 @@ +#include // Library Thinger.io untuk ESP8266 +#include // Library untuk sensor PZEM004Tv30 +#include // Library ESP8266WiFi untuk manajemen koneksi Wi-Fi + +#define USERNAME "wahyuee" // Username Thinger.io +#define DEVICE_ID "NodeMCU_PZEM" // ID perangkat Thinger.io +#define DEVICE_CREDENTIAL "abogoboga" // Kredensial perangkat Thinger.io + +ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL); // Objek ThingerESP8266 + +const char* ssid = "Wahyu"; +const char* password = "wahyu123"; + +// Pin yang terhubung ke relay 4 channel +const int relay1 = D0; +const int relay2 = D1; +const int relay3 = D3; +const int relay4 = D4; +const int buzzerPin = D2; // Pin buzzer + +PZEM004Tv30 pzem(14, 12); // GPIO14(D5) to Tx PZEM004; GPIO12(D6) to Rx PZEM004 + +float totalPower =0.0; // Total daya dalam watt-menit +float Voltage, Current, Power, Energy, Frequency, PF, VA, VAR, totalCost; // Variabel untuk menyimpan data sensor +unsigned long startTime = 0; // Waktu awal setiap menit +bool relay1State = HIGH; // Relay1 awalnya dalam keadaan hidup + +void setup() { + Serial.begin(115200); + + startTime = millis(); // Mengatur waktu awal pengukuran + + pinMode(relay1, OUTPUT); + pinMode(relay2, OUTPUT); + pinMode(relay3, OUTPUT); + pinMode(relay4, OUTPUT); + pinMode(buzzerPin, OUTPUT); + + + WiFi.begin(ssid, password); + while(WiFi.status() != WL_CONNECTED) + { + delay(1000); + Serial.println("Menghubungkan ke WiFi..."); + } + Serial.println("WiFi terhubung!"); + Serial.print("Alamat IP: "); + Serial.println(WiFi.localIP()); + delay(1000); + + thing.add_wifi(ssid, password); // Menambahkan koneksi Wi-Fi ke Thinger.io + + // Mendefinisikan endpoint untuk data sensor pada Thinger.io + thing["PZEM"] >> [] (pson & out) { + out["voltage"] = String(Voltage,2); + out["current"] = String(Current,2); + out["power"] = String(Power,2); + out["energy"] = String(Energy,2); + out["frequency"] = String(Frequency,2); + out["faktor daya"] = String(PF,2); + out["Apparent Power"] = String(VA,2); + out["Reactive Power"] = String(VAR,2); + out["Total Biaya"] = String(totalCost,2); + }; + // Mendefinisikan endpoint untuk setiap relay pada Thinger.io + thing["Perangkat 1"] << digitalPin(relay1); + thing["Perangkat 2"] << digitalPin(relay2); + thing["Perangkat 3"] << digitalPin(relay3); + thing["Perangkat 4"] << digitalPin(relay4); +} + +void loop() { + thing.handle(); // Menghandle koneksi dan komunikasi dengan Thinger.io + +// Membaca data dari sensor PZEM-004T + Voltage = pzem.voltage(); + Current = pzem.current(); + Power = pzem.power(); + Energy = pzem.energy(); + Frequency = pzem.frequency(); + PF = pzem.pf(); + // Menghitung Apparent Power (VA) + if (PF == 0) { + VA = 0; + } else { + VA = Power / PF; + } + // Menghitung Reactive Power (VAR) + if (PF == 0) { + VAR = 0; + } else { + VAR = Power / PF * sqrt(1-sq(PF)); + } + // Memeriksa validitas data + if (isnan(Voltage)) { + Serial.println("Error membaca tegangan"); + } else { + // Menampilkan nilai-nilai pada Serial console + Serial.print("Voltage : "); + Serial.print(Voltage); + Serial.println("V"); + } + if (isnan(Current)) { + Serial.println("Error membaca arus"); + } else { + Serial.print("Current : "); + Serial.print(Current); + Serial.println("A"); + } + if (isnan(Power)) { + Serial.println("Error membaca daya"); + } else { + Serial.print("Power : "); + Serial.print(Power); + Serial.println("W"); + } + + if (isnan(Frequency)) { + Serial.println("Error membaca frekuensi"); + } else { + Serial.print("Frequency : "); + Serial.print(Frequency); + Serial.println("Hz"); + } + if (isnan(PF)) { + Serial.println("Error membaca faktor daya"); + } else { + Serial.print("Faktor Daya : "); + Serial.print(PF); + Serial.println("PF"); + } + if (isnan(VA)) { + Serial.println("Error membaca apparent power"); + } else { + Serial.print("Apparent Power : "); + Serial.print(VA); + Serial.println("VA"); + } + if (isnan(VAR)) { + Serial.println("Error membaca reactive power"); + } else { + Serial.print("Reactive Power : "); + Serial.print(VAR); + Serial.println("VAR"); + } + if (isnan(Energy)) { + Serial.println("Error membaca energi"); + } else { + // Menghitung total daya dalam watt-menit + totalPower += Power * ((millis() - startTime) / 1000.0) / 60.0; // Mengubah watt-detik menjadi watt-menit + // Memeriksa apakah satu detik telah berlalu + if (millis() - startTime >= 1000) { // 1000 milidetik = 1 detik + Energy = totalPower / 1000.0; // Mengubah watt-menit menjadi kilowatt-jam + totalCost = Energy * 1352.0; // Mengalikan dengan biaya per kilowatt-jam + Serial.print("Energy : "); + Serial.print(Energy); + Serial.println("kWh"); + } + } + if (isnan(totalCost)){ + Serial.println("Error menghitung biaya"); + } else { + Serial.print("Total Biaya: "); + Serial.println(totalCost); + startTime = millis(); // Mengatur ulang waktu awal untuk detik berikutnya + } + + // Mengaktifkan buzzer jika Apparent Power dalam rentang 90-100 VA + if (VA >= 90 && VA <= 100) { + digitalWrite(buzzerPin, HIGH); + delay(1000); + digitalWrite(buzzerPin, LOW); + delay(1000); + thing.call_endpoint("monitor_listrik"); // memanggil endpoint yang telah dibuat + } else { + digitalWrite(buzzerPin, LOW); + } + + // Jika Apparent Power lebih dari 100 VA, matikan relay1 + if (VA > 100) { + if (relay1State == HIGH) { + digitalWrite(relay1, LOW); + relay1State = LOW; + thing.call_endpoint("monitor_listrik1"); // memanggil endpoint yang telah dibuat + } + } else { + digitalWrite(relay1, HIGH); + relay1State = HIGH; + thing.call_endpoint("monitor_listrik2"); + delay(60000) + } + } + + Serial.println(); + delay(1000); +}