0% found this document useful (0 votes)
30 views6 pages

Power Flow

This document contains the code for an ESP32-based power meter that connects to WiFi, publishes data to an MQTT broker, and displays readings and charts on a dashboard. It includes code to read sensor data using Modbus, convert values to JSON, connect to WiFi and MQTT, and update the dashboard displays with the sensor readings for voltage, current, power, and flow rates.

Uploaded by

maxchaotic7
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
Download as txt, pdf, or txt
0% found this document useful (0 votes)
30 views6 pages

Power Flow

This document contains the code for an ESP32-based power meter that connects to WiFi, publishes data to an MQTT broker, and displays readings and charts on a dashboard. It includes code to read sensor data using Modbus, convert values to JSON, connect to WiFi and MQTT, and update the dashboard displays with the sensor readings for voltage, current, power, and flow rates.

Uploaded by

maxchaotic7
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1/ 6

#include <WiFi.

h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "REG_PM5300.h"
#include <ModbusMaster.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#include <WebSerial.h>
#include <ESPDash.h>
#define baud 9600
#define timeout 100
#define polling 100
#define retry_count 10
ModbusMaster node;
#define flow_sensor 14
#define flow_sensor1 27

bool bdetectOn = false;


bool bReset = false;

volatile uint32_t unpulseCount = 0; // volatile : RAM Write (Interrupt Fast


Variable)
uint32_t undisplayCount = 0;

#define MAX485_DE 26
#define MAX485_RE_NEG 25

const char* ssid = "Sakthi-Deco";


const char* password = "33333sak88888";
uint8_t bssid[] = {0x58, 0x6D, 0x8F, 0x3C, 0x72, 0xDB};
const char* mqtt_server = "ec2-54-255-83-30.ap-southeast-1.compute.amazonaws.com";

WiFiClient espClient;
PubSubClient client(espClient);
const char* topicName = "/machine/powermeter2";
char data[138];
long lastMsg = 0;
char msg[256];
int value = 0;
int DELAY = 3000;

void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}

void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info){


Serial.println("Connected to AP successfully!");
}

void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info){


Serial.println("WiFi connected");
}

void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info){


Serial.println("Disconnected from WiFi access point");
Serial.println("Trying to Reconnect");
delay(1000);
WiFi.begin(ssid, password);
delay(1000);
}

//01 04 00 00 00 02 71 3F // Test 30001


//------------------------------------------------
// Convent 32bit to float
//------------------------------------------------
float HexTofloat(uint32_t x)
{
return (*(float*)&x);
}

uint32_t FloatTohex(float x)
{
return (*(uint32_t*)&x);
}
//------------------------------------------------

float Read_Meter_float(char addr , uint16_t REG)


{
float i = 0;
uint8_t result,j;

uint16_t data[17];
uint32_t value = 0;
node.begin(ID_meter,Serial2);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);

result = node.readInputRegisters(REG,2); ///< Modbus function 0x04 Read Input


Registers
delay(500);
if (result == node.ku8MBSuccess)
{
for (j = 0; j < 2; j++)
{
data[j] = (node.getResponseBuffer(j));
}

// Serial.print(data[1],HEX);
// Serial.println(data[0],HEX);

// value = data[1];
// value = value << 16;
// value = value + data[0];
value = data[0];
value = value << 16;
value = value + data[1];
i = HexTofloat(value);
return i;
}
else
{
Serial.print("Connect modbus fail. REG >>> "); Serial.println(REG); // Debug
delay(1000);
return 0;
}
}
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();

}
AsyncWebServer server(80);
ESPDash dashboard(&server);
Card card1(&dashboard, GENERIC_CARD, "Volt A");
Card card2(&dashboard, GENERIC_CARD, "Volt B");
Card card3(&dashboard, GENERIC_CARD, "Volt C");
Card card4(&dashboard, GENERIC_CARD, "Ampere A");
Card card5(&dashboard, GENERIC_CARD, "Ampere B");
Card card6(&dashboard, GENERIC_CARD, "Ampere C");
Card card7(&dashboard, GENERIC_CARD, "KW");
Card card8(&dashboard, GENERIC_CARD, "KWH");
Card card9(&dashboard, GENERIC_CARD, "Power Factor");
Card card10(&dashboard, PROGRESS_CARD, "Reset Progress", "", 0, 201680);
Chart chart1(&dashboard, BAR_CHART, "Voltage");
Chart chart2(&dashboard, BAR_CHART, "Current");
Card card11(&dashboard, HUMIDITY_CARD, "Solar Heater Flow", "L/min");
Card card12(&dashboard, HUMIDITY_CARD, "Rainwater Flow", "L/min");
//
***********************************************************************************
***************************
void setup()
{
Serial.begin(baud);
Serial2.begin(baud,SERIAL_8E1, 16, 17);

// Serial.println(F("Test"));
pinMode(flow_sensor, INPUT);
pinMode(flow_sensor1, INPUT);
attachInterrupt(digitalPinToInterrupt(flow_sensor1), detectInterruptSignal,
FALLING); // RISING(LOW-&gt;HIGH), FALLING(HIGH-&gt;LOW),CHANGE
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);

WiFi.disconnect(true);

delay(1000);

WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_STA_CONNECTED);
WiFi.onEvent(WiFiGotIP, SYSTEM_EVENT_STA_GOT_IP);
WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_STA_DISCONNECTED);

WiFi.begin(ssid, password);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);

Serial.println();
Serial.println();
Serial.println("Wait for WiFi... ");

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {


request->send(200, "text/plain", "Hi! I am EAGLE-POWERMETER.");
});
AsyncElegantOTA.begin(&server); // Start ElegantOTA
WebSerial.begin(&server);
server.begin();
WebSerial.println("HTTP server started");

void reconnect() {
while (!client.connected()) {
WebSerial.print("Attempting MQTT connection...");
if (client.connect("")) {
WebSerial.println("connected");
client.subscribe("/machine/powermeter2");
} else {
WebSerial.print("failed, rc=");
WebSerial.print(client.state());
WebSerial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void loop()
{
AsyncElegantOTA.loop();
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > DELAY) {
lastMsg = now;

StaticJsonDocument<256> doc;
uint32_t pulse = pulseIn(flow_sensor,HIGH);
//uint32_t pulse1 = pulseIn(flow_sensor1,HIGH);
undisplayCount = unpulseCount;
// data["Active_Energy"] = Read_Meter_float(ID_meter, Reg_ActEnergyLoadIN);
// data["A"] = Read_Meter_float(ID_meter, Reg_CurrentA);
// data["B"] = Read_Meter_float(ID_meter, Reg_CurrentB);
// data["C"] = Read_Meter_float(ID_meter, Reg_CurrentC);
// data["N"] = Read_Meter_float(ID_meter, Reg_CurrentN);
// data["Voltage_AB"] = Read_Meter_float(ID_meter, Reg_VoltAB);
// data["Voltage_BC"] = Read_Meter_float(ID_meter, Reg_VoltBC);
// data["Voltage_CA"] = Read_Meter_float(ID_meter, Reg_VoltCA);
// data["Voltage_LL"] = Read_Meter_float(ID_meter, Reg_VoltLLAvg);
// data["Voltage_LL_Worst"] = Read_Meter_float(ID_meter, Reg_VoltULLWorst);
// data["Voltage_LN_Worst"] = Read_Meter_float(ID_meter, Reg_VoltULNWorst);
// data["Active_A"] = Read_Meter_float(ID_meter, Reg_AcPwrA);
// data["Active_B"] = Read_Meter_float(ID_meter, Reg_AcPwrB);
// data["Active_C"] = Read_Meter_float(ID_meter, Reg_AcPwrC);
// data["Total_Active"] = Read_Meter_float(ID_meter, Reg_AcPwrTot);
// data["Power_Factor"] = Read_Meter_float(ID_meter, Reg_PwrFTot);
// doc["date"] = timeClient.getFormattedTime();
float voltA = Read_Meter_float(ID_meter, Reg_VoltAB);
float voltB = Read_Meter_float(ID_meter, Reg_VoltBC);
float voltC = Read_Meter_float(ID_meter, Reg_VoltCA);
float ampA = Read_Meter_float(ID_meter, Reg_CurrentA);
float ampB = Read_Meter_float(ID_meter, Reg_CurrentB);
float ampC = Read_Meter_float(ID_meter, Reg_CurrentC);
float kw = Read_Meter_float(ID_meter, Reg_AcPwrTot);
float kwh = Read_Meter_float(ID_meter, Reg_ActEnergyLoadIN);
float p_factor = Read_Meter_float(ID_meter, Reg_PwrFTot);
float percentage = (kwh/201680)*100;
float Hz = 0.00046*pulse;
float flow = Hz;
//float Hz1 = 0.00046*pulse1;
//float flow1 = Hz1;
float flow1 = undisplayCount * 4.6E-4;
if (isinf(flow)) {
flow = 0;
}
//if (isinf(flow1)) {
// flow1 = 0;
//}
doc["volt_a"] = voltA;
doc["volt_b"] = voltB;
doc["volt_c"] = voltC;
doc["amp_a"] = ampA;
doc["amp_b"] = ampB;
doc["amp_c"] = ampC;
doc["kw"] = kw;
doc["kwh"] = kwh;
doc["p_factor"] = p_factor;
doc["temp_hot_tank"] = p_factor;
doc["temp_tank"] = p_factor;
doc["temp_solar_heater"] = p_factor;
doc["flow_solar_heater"] = flow;
doc["flow_rain_water"] = flow1;
doc["flow_main"] = p_factor;

char buffer[256];
serializeJson(doc, buffer);
client.publish(topicName, buffer);
WebSerial.println(buffer);
String XAxis[] = {"A", "B", "C"};
int YAxis1[3];
int YAxis2[3];
YAxis1[0] = voltA;
YAxis1[1] = voltB;
YAxis1[2] = voltC;
YAxis2[0] = ampA;
YAxis2[1] = ampB;
YAxis2[2] = ampC;
card1.update(voltA);
card2.update(voltB);
card3.update(voltC);
card4.update(ampA);
card5.update(ampB);
card6.update(ampC);
card7.update(kw);
card8.update(kwh);
card9.update(p_factor);
card10.update(percentage, "%");
card11.update(flow);
card12.update(flow1);
chart1.updateX(XAxis, 3);
chart2.updateX(XAxis, 3);
chart1.updateY(YAxis1, 3);
chart2.updateY(YAxis2, 3);
dashboard.sendUpdates();
}

void detectInterruptSignal()
{
unpulseCount++;
bdetectOn = true;
}

You might also like