first commit
This commit is contained in:
commit
13024658b4
|
@ -0,0 +1,232 @@
|
||||||
|
#include <ThingerESP8266.h> // Library Thinger.io untuk ESP8266
|
||||||
|
#include <PZEM004Tv30.h> // Library untuk sensor PZEM004Tv30
|
||||||
|
#include <WiFiManager.h> // Library WiFiManager untuk manajemen koneksi Wi-Fi
|
||||||
|
#include <NTPClient.h> // Library NTPClient untuk sinkronisasi waktu
|
||||||
|
#include <WiFiUdp.h> // Library WiFiUDP untuk komunikasi UDP
|
||||||
|
#include <EEPROM.h> // 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);
|
||||||
|
}
|
|
@ -0,0 +1,196 @@
|
||||||
|
#include <ThingerESP8266.h> // Library Thinger.io untuk ESP8266
|
||||||
|
#include <PZEM004Tv30.h> // Library untuk sensor PZEM004Tv30
|
||||||
|
#include <ESP8266WiFi.h> // 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);
|
||||||
|
}
|
Loading…
Reference in New Issue