322 lines
9.7 KiB
C++
322 lines
9.7 KiB
C++
#include <PZEM004Tv30.h>
|
|
#include <HardwareSerial.h>
|
|
#include <WiFi.h>
|
|
#include <PubSubClient.h>
|
|
#include <Wire.h>
|
|
#include <RTClib.h>
|
|
|
|
// Inisialisasi dua objek serial hardware untuk masing-masing sensor
|
|
HardwareSerial pzemSerial1(1); // Gunakan UART 1 pada ESP32 (pin 16 sebagai Rx, pin 17 sebagai Tx)
|
|
HardwareSerial pzemSerial2(2); // Gunakan UART 2 pada ESP32 (pin 19 sebagai Rx, pin 23 sebagai Tx)
|
|
|
|
// Inisialisasi dua objek PZEM untuk masing-masing sensor
|
|
PZEM004Tv30 pzem1(&pzemSerial1, 16, 17); // kamar1
|
|
PZEM004Tv30 pzem2(&pzemSerial2, 19, 23); // kamar2
|
|
|
|
// Definisikan pin GPIO untuk mengendalikan relay
|
|
const int relayPin1 = 32; //kamar1
|
|
const int relayPin2 = 33; //kamar2
|
|
const int relay1 = 1;
|
|
const int relay2 = 1;
|
|
// Biaya per kilowatt-hour (kWh)
|
|
const float electricityCost = 1352; // biaya Rp. 1.352,- per kWh
|
|
|
|
// WiFi settings
|
|
const char* ssid = "KOST HIJAU 77";
|
|
const char* password = "ardiyanti260804";
|
|
|
|
// MQTT settings
|
|
const char* mqtt_server = "broker.mqtt.cool";
|
|
const int mqtt_port = 1883;
|
|
const char* mqtt_user = "your_mqtt_user";
|
|
const char* mqtt_password = "your_mqtt_password";
|
|
const char* mqtt_topic_subscribe1 = "kamar1/relay";
|
|
const char* mqtt_topic_subscribe2 = "kamar2/relay";
|
|
const char* mqtt_topic_publish_TOPIC1 = "kamar1/tegangan";
|
|
const char* mqtt_topic_publish_TOPIC2 = "kamar1/arus";
|
|
const char* mqtt_topic_publish_TOPIC3 = "kamar1/daya";
|
|
const char* mqtt_topic_publish_TOPIC4 = "kamar1/totaldaya";
|
|
const char* mqtt_topic_publish_TOPIC5 = "kamar1/biaya";
|
|
const char* mqtt_topic_publish_TOPIC6 = "kamar2/tegangan";
|
|
const char* mqtt_topic_publish_TOPIC7 = "kamar2/arus";
|
|
const char* mqtt_topic_publish_TOPIC8 = "kamar2/daya";
|
|
const char* mqtt_topic_publish_TOPIC9 = "kamar2/totaldaya";
|
|
const char* mqtt_topic_publish_TOPIC10 = "kamar2/biaya";
|
|
|
|
WiFiClient espClient;
|
|
PubSubClient client(espClient);
|
|
RTC_DS3231 rtc;
|
|
bool hasResetToday = false;
|
|
|
|
void setup() {
|
|
Serial.begin(9600);
|
|
|
|
// mulai komunikasi sensor PZEM
|
|
pzemSerial1.begin(9600, SERIAL_8N1, 16, 17);
|
|
pzemSerial2.begin(9600, SERIAL_8N1, 19, 23);
|
|
|
|
// Setting relay pin output
|
|
pinMode(relayPin1, OUTPUT);
|
|
pinMode(relayPin2, OUTPUT);
|
|
|
|
// relay menyala awal
|
|
digitalWrite(relayPin1, LOW);
|
|
digitalWrite(relayPin2, LOW);
|
|
|
|
// Initialize WiFi
|
|
setup_wifi();
|
|
|
|
// Initialize MQTT
|
|
client.setServer(mqtt_server, mqtt_port);
|
|
client.setCallback(callback);
|
|
|
|
// mengubungkan MQTT broker
|
|
while (!client.connected()) {
|
|
Serial.print("Attempting MQTT connection...");
|
|
if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
|
|
Serial.println("connected");
|
|
client.subscribe(mqtt_topic_subscribe1);
|
|
client.subscribe(mqtt_topic_subscribe2);
|
|
} else {
|
|
Serial.print("failed, rc=");
|
|
Serial.print(client.state());
|
|
Serial.println(" try again in 5 seconds");
|
|
delay(5000);
|
|
}
|
|
}
|
|
|
|
// initialize rtc
|
|
if (!rtc.begin()) {
|
|
Serial.println("RTC tidak terdeteksi");
|
|
while (1);
|
|
}
|
|
if (rtc.lostPower()) {
|
|
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Set waktu RTC ke waktu kompilasi
|
|
}
|
|
}
|
|
|
|
void callback(char* topic, byte* payload, unsigned int length) {
|
|
Serial.print("Message arrived in topic: ");
|
|
Serial.print("kamar1/relay");
|
|
Serial.print("Message: ");
|
|
String message;
|
|
for (unsigned int i = 0; i < length; i++) {
|
|
message += (char)payload[i];
|
|
}
|
|
Serial.println(message);
|
|
if (String(topic) == mqtt_topic_subscribe1) {
|
|
if (message == "1") {
|
|
digitalWrite(relayPin1, LOW);
|
|
Serial.println("Relay 1 on");
|
|
} else if (message == "0") {
|
|
digitalWrite(relayPin1, HIGH);
|
|
Serial.println("Relay 1 off");
|
|
}
|
|
}
|
|
if (String(topic) == mqtt_topic_subscribe2) {
|
|
if (message == "1") {
|
|
digitalWrite(relayPin2, LOW);
|
|
Serial.println("Relay 2 on");
|
|
} else if (message == "0") {
|
|
digitalWrite(relayPin2, HIGH);
|
|
Serial.println("Relay 2 off");
|
|
}
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
if (!client.connected()) {
|
|
reconnect();
|
|
}
|
|
client.loop();
|
|
|
|
// cek tanggal dan jam saat ini
|
|
DateTime now = rtc.now();
|
|
Serial.println(now.day());
|
|
|
|
// Cek apakah saatnya reset
|
|
if (now.day() == 1 && !hasResetToday) {
|
|
pzem1.resetEnergy();
|
|
pzem2.resetEnergy();
|
|
Serial.println("Energi PZEM1 dan PZEM2 direset.");
|
|
hasResetToday = true; // Set flag bahwa reset telah dilakukan hari ini
|
|
} else if (now.day() != 1) {
|
|
hasResetToday = false; // Reset flag jika hari bukan tanggal 1
|
|
}
|
|
|
|
// Baca dan cetak data dari sensor 1
|
|
Serial.println("Sensor 1:");
|
|
float energy1 = readAndPrintData(pzem1, mqtt_topic_publish_TOPIC1, mqtt_topic_publish_TOPIC2, mqtt_topic_publish_TOPIC3, mqtt_topic_publish_TOPIC4, mqtt_topic_publish_TOPIC5);
|
|
|
|
// Baca dan cetak data dari sensor 2
|
|
Serial.println("Sensor 2:");
|
|
float energy2 = readAndPrintData(pzem2, mqtt_topic_publish_TOPIC6, mqtt_topic_publish_TOPIC7, mqtt_topic_publish_TOPIC8, mqtt_topic_publish_TOPIC9, mqtt_topic_publish_TOPIC10);
|
|
|
|
// Hitung biaya listrik untuk setiap sensor.
|
|
float cost1 = energy1 * electricityCost;
|
|
float cost2 = energy2 * electricityCost;
|
|
|
|
Serial.println("Biaya penggunaan listrik Sensor 1: Rp. " + String(cost1));
|
|
Serial.println("Biaya penggunaan listrik Sensor 2: Rp. " + String(cost2));
|
|
|
|
char cost1Str[10];
|
|
char cost2Str[10];
|
|
dtostrf(cost1, 6, 2, cost1Str); // Mengonversi float menjadi string dengan 2 tempat desimal.
|
|
dtostrf(cost2, 6, 2, cost2Str); // Mengonversi float menjadi string dengan 2 tempat desimal.
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC5, cost1Str);
|
|
client.publish(mqtt_topic_publish_TOPIC10, cost2Str);
|
|
|
|
// Kontrol relay berdasarkan kondisi tertentu
|
|
controlRelayBasedOnCondition();
|
|
|
|
delay(2000);
|
|
}
|
|
|
|
float readAndPrintData(PZEM004Tv30& pzem, const char* topic1, const char* topic2, const char* topic3, const char* topic4, const char* topic5) {
|
|
float energy = 0.0;
|
|
|
|
float voltage = pzem.voltage();
|
|
float voltage1 = pzem1.voltage();
|
|
float voltage2= pzem2.voltage();
|
|
if (!isnan(voltage)) {
|
|
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
|
|
|
|
char voltageStr1[10];
|
|
dtostrf(voltage1, 6, 2, voltageStr1); // Mengonversi float menjadi string dengan 2 tempat desimal.
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC1, voltageStr1);
|
|
|
|
char voltageStr2[10];
|
|
dtostrf(voltage2, 6, 2, voltageStr2);
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC6, voltageStr2);
|
|
} else {
|
|
Serial.println("Error reading voltage");
|
|
}
|
|
float current = pzem.current();
|
|
float current1 = pzem1.current();
|
|
float current2 = pzem2.current();
|
|
if (!isnan(current)) {
|
|
Serial.print("Current: "); Serial.print(current); Serial.println("A");
|
|
|
|
char currentStr1[10];
|
|
dtostrf(current1, 6, 2, currentStr1); // Mengonversi float menjadi string dengan 2 tempat desimal.
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC2, currentStr1);
|
|
|
|
char currentStr2[10];
|
|
dtostrf(current2, 6, 2, currentStr2);
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC7, currentStr2);
|
|
} else {
|
|
Serial.println("Error reading current");
|
|
}
|
|
|
|
float power = pzem.power();
|
|
float power1 = pzem1.power();
|
|
float power2 = pzem2.power();
|
|
if (!isnan(power)) {
|
|
Serial.print("Power: "); Serial.print(power); Serial.println("W");
|
|
|
|
char powerStr1[10];
|
|
dtostrf(power1, 6, 2, powerStr1); // Mengonversi float menjadi string dengan 2 tempat desimal.
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC3, powerStr1);
|
|
|
|
char powerStr2[10];
|
|
dtostrf(power2, 6, 2, powerStr2);
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC8, powerStr2);
|
|
} else {
|
|
Serial.println("Error reading power");
|
|
}
|
|
|
|
energy = pzem.energy();
|
|
float energy1 = pzem1.energy();
|
|
float energy2 = pzem2.energy();
|
|
if (!isnan(energy)) {
|
|
Serial.print("Energy: "); Serial.print(energy, 3); Serial.println("kWh");
|
|
|
|
char energyStr1[10];
|
|
dtostrf(energy1, 6, 2, energyStr1); // Mengonversi float menjadi string dengan 2 tempat desimal.
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC4, energyStr1);
|
|
|
|
char energyStr2[10];
|
|
dtostrf(energy2, 6, 2, energyStr2);
|
|
|
|
client.publish(mqtt_topic_publish_TOPIC9, energyStr2);
|
|
} else {
|
|
Serial.println("Error reading energy");
|
|
}
|
|
|
|
float frequency = pzem.frequency();
|
|
if (!isnan(frequency)) {
|
|
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
|
|
} else {
|
|
Serial.println("Error reading frequency");
|
|
}
|
|
|
|
float pf = pzem.pf();
|
|
if (!isnan(pf)) {
|
|
Serial.print("PF: "); Serial.println(pf);
|
|
} else {
|
|
Serial.println("Error reading power factor");
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
return energy;
|
|
}
|
|
|
|
//ini untuk memberikan informasi pada serial monitor ketika relay menyala atau tidak
|
|
void controlRelayBasedOnCondition() {
|
|
if (relay1) {
|
|
Serial.println("Relay 1 on");
|
|
} else {
|
|
Serial.println("Relay 1 off");
|
|
}
|
|
|
|
if (relay2) {
|
|
Serial.println("Relay 2 on");
|
|
} else {
|
|
Serial.println("Relay 2 off");
|
|
}
|
|
}
|
|
|
|
void setup_wifi() {
|
|
delay(10);
|
|
Serial.println();
|
|
Serial.print("Connecting to ");
|
|
Serial.println(ssid);
|
|
|
|
WiFi.begin(ssid, password);
|
|
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
Serial.print(".");
|
|
}
|
|
|
|
Serial.println("");
|
|
Serial.println("WiFi connected");
|
|
Serial.println("IP address: ");
|
|
Serial.println(WiFi.localIP());
|
|
}
|
|
|
|
void reconnect() {
|
|
while (!client.connected()) {
|
|
Serial.print("Attempting MQTT connection...");
|
|
if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
|
|
Serial.println("connected");
|
|
client.subscribe(mqtt_topic_subscribe1);
|
|
client.subscribe(mqtt_topic_subscribe2); // Subscribe topic
|
|
} else {
|
|
Serial.print("failed, rc=");
|
|
Serial.print(client.state());
|
|
Serial.println(" try again in 5 seconds");
|
|
delay(5000);
|
|
}
|
|
}
|
|
}
|