#include <PZEM004Tv30.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <EEPROM.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#if !defined(PZEM_RX_PIN) && !defined(PZEM_TX_PIN)
#define PZEM_RX_PIN 16
#define PZEM_TX_PIN 17
#endif
#define PZEM_SERIAL Serial2
#define NUM_PZEMS 3
PZEM004Tv30 pzems[NUM_PZEMS];
float voltage[NUM_PZEMS], current[NUM_PZEMS], power[NUM_PZEMS], energy[NUM_PZEMS], frequency[NUM_PZEMS], pf[NUM_PZEMS];
const unsigned long interval = 5000;
unsigned long previousMillis = 0;
bool flData=false;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_username = "user_e7f8f3cf";//логин от сервера
const char* mqtt_password = "pass_c5f30be1";//пароль от сервера
const char* ClientID = "user_e7f8f3cf_esp_1"; // id устройства esp_1 будет главным хабом)
const char* mqtt_server = "test.mosquitto.org";// адрес сервера
const int mqtt_port = 1883; // порт сервера
//const char* mqtt_server = "home.keenetic.pro";
WiFiClient espClient;
PubSubClient client(espClient);
#define ledPin 2
bool flTEN1on = false, flTEN2on = false, flTEN3on = false;
const int rel1 = 2; //4;
const int rel2 = 4; //4;
bool flStart = true;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
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 callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic PZEM/output, you check if the message is either "on" or "off".
// Changes the output state according to the message
if (String(topic) == "KX09/PZEM/Request") {
Serial.print("Запрос ");
if (messageTemp == "readT") {
Serial.println("readT");
// RBME();
};
if (messageTemp == "readU") {
Serial.println("readU");
//RPZEM();
}
if (messageTemp == "reset") {
Serial.println("RESET!!!");
ESP.restart();
}
}
}
void reconnect() {
// Loop until we're reconnected
static unsigned int nrc = 0;
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// esp_task_wdt_reset();
// Attempt to connect
if (client.connect("ESP32Client")) {
Serial.println("connected");
nrc = 0;
// Subscribe
//client.subscribe("KX09/PZEM/output");
//client.subscribe("KX09/PZEM/output1");
//client.subscribe("KX09/PZEM/output2");
client.subscribe("KX09/PZEM/Request");
if (client.publish("KX09/PZEM/Request", "readU") == true) {
Serial.println("Success sending message");
} else {
Serial.println("Error sending message");
}
if (flStart) {
// client.publish("PZEM/output", "off1");
// client.publish("PZEM/output1", "off2");
// client.publish("PZEM/output2", "off3");
flStart = false;
};
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
for (int j = 0; j < 10; j++) {
delay(500); //esp_task_wdt_reset();};
nrc++;
if (nrc > 120) {
nrc = 0;
};
}
}
}
}
void pzem(void) {
for (int i = 0; i < NUM_PZEMS; i++) {
// Print the Address of the PZEM
Serial.print("PZEM ");
Serial.print(i);
Serial.print(" - Address:");
Serial.println(pzems[i].getAddress(), HEX);
Serial.println("===================");
voltage[i] = pzems[i].voltage();
current[i] = pzems[i].current();
power[i] = pzems[i].power();
energy[i] = pzems[i].energy();
frequency[i] = pzems[i].frequency();
pf[i] = pzems[i].pf();
// Check if the data is valid
if (isnan(voltage[i])) {
Serial.println("Error reading voltage");
} else if (isnan(current[i])) {
Serial.println("Error reading current");
} else if (isnan(power[i])) {
Serial.println("Error reading power");
} else if (isnan(energy[i])) {
Serial.println("Error reading energy");
} else if (isnan(frequency[i])) {
Serial.println("Error reading frequency");
} else if (isnan(pf[i])) {
Serial.println("Error reading power factor");
} else {
// Print the values to the Serial console
flData=true;
Serial.print("Voltage: ");
Serial.print(voltage[i]);
Serial.println("V");
Serial.print("Current: ");
Serial.print(current[i]);
Serial.println("A");
Serial.print("Power: ");
Serial.print(power[i]);
Serial.println("W");
Serial.print("Energy: ");
Serial.print(energy[i], 3);
Serial.println("kWh");
Serial.print("Frequency: ");
Serial.print(frequency[i], 1);
Serial.println("Hz");
Serial.print("PF: ");
Serial.println(pf[i]);
}
}
Serial.println("-------------------");
Serial.println();
if (flData) {
display.clearDisplay();
display.print("U ");display.print(voltage[0]); display.print("/");display.print(voltage[1]); display.print("/");display.println(voltage[2]);
display.print("I ");display.print(current[0]); display.print("/");display.print(current[1]); display.print("/");display.println(current[2]);
display.print("P ");display.print(power[0]); display.print("/");display.print(power[1]); display.print("/");display.println(power[2]);
display.print("E ");display.print(energy[0]); display.print("/");display.print(energy[1]); display.print("/");display.println(energy[2]);
display.display();
flData=false;
}
}
void setup() {
Serial.begin(115200);
// For each PZEM, initialize it
for (int i = 0; i < NUM_PZEMS; i++) {
pzems[i] = PZEM004Tv30(PZEM_SERIAL, PZEM_RX_PIN, PZEM_TX_PIN, 0x10 );
}
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
//for (;;)
;
}
delay(1000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(20, 30);
display.println("Hello, world!");
display.display();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) { reconnect(); };
client.loop();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
pzem();
};
}