178 lines
5.6 KiB
Plaintext
178 lines
5.6 KiB
Plaintext
#include <Wire.h>
|
|
#include <LiquidCrystal_I2C.h>
|
|
#include <PZEM004Tv30.h>
|
|
#include <SoftwareSerial.h>
|
|
|
|
// Konfigurasi pin untuk sensor tegangan DC
|
|
const int analogPinBattery = A0; // Pin sensor tegangan baterai
|
|
const int analogPinSolar = A1; // Pin sensor tegangan panel surya
|
|
|
|
// Rasio tegangan yang diberikan oleh modul sensor
|
|
const float voltageDividerRatio = 5.0; // Biasanya modul ini memiliki rasio 5:1
|
|
|
|
// Konfigurasi PZEM-004T
|
|
SoftwareSerial pzemSerial(10, 11); // RX, TX
|
|
PZEM004Tv30 pzem(pzemSerial);
|
|
|
|
// Konfigurasi LCD I2C
|
|
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C 0x27 untuk LCD 16x2
|
|
|
|
// Konfigurasi SoftwareSerial untuk komunikasi dengan ESP32
|
|
SoftwareSerial espSerial(2, 3); // RX, TX
|
|
|
|
// Konfigurasi push button dan buzzer
|
|
const int buttonPin = 4;
|
|
const int buzzerPin = 5; // Pin untuk buzzer
|
|
|
|
int buttonState;
|
|
int lastButtonState = LOW;
|
|
unsigned long lastDebounceTime = 0;
|
|
unsigned long debounceDelay = 50;
|
|
|
|
int displayMode = 0; // mode tampilan awal
|
|
|
|
unsigned long previousMillis = 0; // waktu sebelumnya
|
|
const long interval = 2000; // interval pengiriman data (ms)
|
|
|
|
void setup() {
|
|
pinMode(buttonPin, INPUT_PULLUP);
|
|
pinMode(buzzerPin, OUTPUT); // Set pin buzzer sebagai output
|
|
Serial.begin(9600);
|
|
espSerial.begin(9600); // Inisialisasi SoftwareSerial untuk ESP32
|
|
lcd.init(); // Inisialisasi LCD
|
|
lcd.backlight(); // Aktifkan backlight LCD
|
|
}
|
|
|
|
void loop() {
|
|
int reading = digitalRead(buttonPin);
|
|
if (reading != lastButtonState) {
|
|
lastDebounceTime = millis();
|
|
}
|
|
|
|
if ((millis() - lastDebounceTime) > debounceDelay) {
|
|
if (reading != buttonState) {
|
|
buttonState = reading;
|
|
if (buttonState == LOW) {
|
|
displayMode++;
|
|
if (displayMode > 3) {
|
|
displayMode = 0;
|
|
}
|
|
// Aktifkan buzzer untuk waktu singkat
|
|
digitalWrite(buzzerPin, HIGH);
|
|
delay(100);
|
|
digitalWrite(buzzerPin, LOW);
|
|
}
|
|
}
|
|
}
|
|
lastButtonState = reading;
|
|
|
|
unsigned long currentMillis = millis();
|
|
if (currentMillis - previousMillis >= interval) {
|
|
previousMillis = currentMillis;
|
|
|
|
// Membaca nilai analog dari pin A0 (tegangan baterai aki)
|
|
int analogValueBattery = analogRead(analogPinBattery);
|
|
float voltageBattery = analogValueBattery * (5.0 / 1023.0);
|
|
float actualVoltageBattery = voltageBattery * voltageDividerRatio;
|
|
|
|
// Membaca nilai analog dari pin A1 (tegangan panel surya)
|
|
int analogValueSolar = analogRead(analogPinSolar);
|
|
float voltageSolar = analogValueSolar * (5.0 / 1023.0);
|
|
float actualVoltageSolar = voltageSolar * voltageDividerRatio;
|
|
|
|
// Membaca tegangan AC dari PZEM-004T
|
|
float voltage = pzem.voltage();
|
|
float current = pzem.current();
|
|
float power = pzem.power();
|
|
float energy = pzem.energy();
|
|
float frequency = pzem.frequency();
|
|
float pf = pzem.pf();
|
|
|
|
// Memastikan data valid
|
|
if (isnan(voltage) || voltage < 0 || voltage > 300) voltage = 0;
|
|
|
|
// Jika tegangan AC adalah nol, set nilai lainnya menjadi nol kecuali energy
|
|
if (voltage == 0) {
|
|
current = 0;
|
|
power = 0;
|
|
frequency = 0;
|
|
pf = 0;
|
|
}
|
|
|
|
// Menampilkan nilai tegangan ke Serial Monitor
|
|
Serial.print("Battery Voltage: ");
|
|
Serial.print(actualVoltageBattery);
|
|
Serial.println(" V");
|
|
Serial.print("Solar Panel Voltage: ");
|
|
Serial.print(actualVoltageSolar);
|
|
Serial.println(" V");
|
|
|
|
// Menampilkan nilai parameter PZEM ke Serial Monitor
|
|
Serial.print("AC Voltage: ");
|
|
Serial.println(voltage);
|
|
Serial.print("AC Current: ");
|
|
Serial.println(current);
|
|
Serial.print("AC Power: ");
|
|
Serial.println(power);
|
|
Serial.print("AC Energy: ");
|
|
Serial.println(energy, 3);
|
|
Serial.print("AC Frequency: ");
|
|
Serial.println(frequency, 1);
|
|
Serial.print("AC Power Factor: ");
|
|
Serial.println(pf);
|
|
|
|
// Mengirim nilai ke ESP32 melalui Serial dalam format tag:value
|
|
espSerial.print("battery:"); espSerial.print(actualVoltageBattery); espSerial.print(",");
|
|
espSerial.print("solar:"); espSerial.print(actualVoltageSolar); espSerial.print(",");
|
|
espSerial.print("ac_voltage:"); espSerial.print(voltage); espSerial.print(",");
|
|
espSerial.print("ac_current:"); espSerial.print(current); espSerial.print(",");
|
|
espSerial.print("ac_power:"); espSerial.print(power); espSerial.print(",");
|
|
espSerial.print("ac_energy:"); espSerial.print(energy); espSerial.print(",");
|
|
espSerial.print("ac_frequency:"); espSerial.print(frequency); espSerial.print(",");
|
|
espSerial.print("ac_power_factor:"); espSerial.println(pf); // Mengakhiri dengan newline
|
|
|
|
// Menampilkan nilai ke LCD berdasarkan mode tampilan
|
|
lcd.clear();
|
|
switch (displayMode) {
|
|
case 0:
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Battery: ");
|
|
lcd.print(actualVoltageBattery);
|
|
lcd.print(" V");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Solar: ");
|
|
lcd.print(actualVoltageSolar);
|
|
lcd.print(" V");
|
|
break;
|
|
case 1:
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Voltage: ");
|
|
lcd.print(voltage);
|
|
lcd.print(" V");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Current: ");
|
|
lcd.print(current);
|
|
lcd.print(" A");
|
|
break;
|
|
case 2:
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Power: ");
|
|
lcd.print(power);
|
|
lcd.print(" W");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Energy: ");
|
|
lcd.print(energy);
|
|
lcd.print(" kWh");
|
|
break;
|
|
case 3:
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Freq: ");
|
|
lcd.print(frequency);
|
|
lcd.print(" Hz");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("PF: ");
|
|
lcd.print(pf);
|
|
break;
|
|
}
|
|
}
|
|
} |