//
// PowerMeter
// GRA
// Créé le : 22.05.2019
// V1.0 Lecture d'une phase et envoi par MQTT sur node-red
// Param pour ESP MQTT HW 2.0 : Generic ESP8266 module, 115200, 80MHz, 26MHz, DOUT(compatible), 512K (no SPIFFS), 40MHz, ck, Disabled, Rien, V2 lower memory, Flash, Disabled, 2, Only Sketch
#include <PZEM004Tv30.h>
#include <PubSubClient.h>
#include "ESP8266WiFi.h"
#define Tx 5
#define Rx 4
#define AD0_PIN 12
#define AD1_PIN 13
#define LED_PIN 14
#define waitTime 60 // en seconde
// Ponthaux
const char* ssid = "yourSSID";
const char* password = "YourPassword";
const char* server = "yourMQTTserverIP";
char* topicPowerMeter = "power/powerMeter"; // Topic Power meter
String swVersion = "V1.0";
String hwVersion = "V1.0";
String payload = "";
String clientName;
String msg = "";
char message_buff[1]; // initialise storage buffer (i haven't tested to this capacity.)
int sleepTimeS = 30; //300 = 5mn, 600 = 10mn, 1800 = 30mn, 3600 = 1h
int i = 0;
unsigned long lastReconnectAttempt = 0;
void callback(char* topicPowerMeter, byte* payload, unsigned int length);
WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);
//PZEM004T pzem(D1,D2); // (RX,TX) connect to TX,RX of PZEM
PZEM004Tv30 pzem(Rx, Tx); // (RX,TX) connect to TX,RX of PZEM
IPAddress ip(192,168,1,1);
///////////////////////////////////////////////////////////////
// Convert Mac adress to string
///////////////////////////////////////////////////////////////
String macToStr(const uint8_t* mac)
{
String result;
for (i = 0; i < 6; ++i) {
result += String(mac[i], 16);
if (i < 5)
result += ':';
}
return result;
}
///////////////////////////////////////////////////////////////
// Connect to wifi
///////////////////////////////////////////////////////////////
void connectwifi()
{
int cnt = 0;
Serial.print("Connecting to ");
Serial.print(ssid);
WiFi.mode(WIFI_STA); // 26.05.2018 Mettre en station et non AP pour ne pas être piratable
WiFi.begin(ssid, password);
//WiFi.config(ip, gateway, subnet);
while (WiFi.status() != WL_CONNECTED)
{
digitalWrite(LED_PIN, LOW);
delay(50);
Serial.print(".");
cnt += 1;
digitalWrite(LED_PIN, HIGH);
if(cnt>=500) //V1.7 240->500
{
digitalWrite(LED_PIN, LOW);
delay(1000);
//connectwifi(); //V1.7 supprimé ESP.deepSleep(1000); pour retenter la connexion
cnt = 0; // Ajouté pour remettre à 0
ESP.restart();
}
}
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Generate client name based on MAC address
clientName += "PowerRemote-";
uint8_t mac[6];
WiFi.macAddress(mac);
clientName += macToStr(mac);
Serial.print("Connecting to ");
Serial.print(server);
Serial.print(" as ");
Serial.println(clientName);
if (client.connect((char*) clientName.c_str()))
{
Serial.println("Connected to MQTT broker");
Serial.print("Topic is: ");
Serial.println(topicPowerMeter);
char* topicTest = "test/test-connexion";
if (client.publish(topicTest, "Starting..."))
{
Serial.println("Publish successfully sent");
//client.subscribe(topicPowerMeter);
}
else
{
digitalWrite(LED_PIN, LOW);
Serial.println("Publish failed");
}
}
else
{
digitalWrite(LED_PIN, LOW);
Serial.println("MQTT connect failed");
Serial.println("Sleeping and try again...");
//ESP.deepSleep(5000000);
}
digitalWrite(LED_PIN, HIGH);
}
///////////////////////////////////////////////////////////////
// Callback
///////////////////////////////////////////////////////////////
void callback(char* topicCallback, byte* payload, unsigned int length)
{
/*// Here is what i have been using to handle subscriptions. I took it as a snippet from elsewhere but i cannot credit author as i dont have reference!
int i = 0;
Serial.print("Comparaison de topics : ");
Serial.print(topicPowerMeter);
Serial.print(" et ");
Serial.println(topicCallback);
if (String(topicPowerMeter) == String(topicCallback ))
{
Serial.println("Message arrived: topic: " + String(topicCallback));
Serial.println("Length: " + String(length,DEC));
// create character buffer with ending null terminator (string)
for(i=0; i<length; i++)
{
message_buff[i] = payload[i];
delay(20);
}
message_buff[i] = '\0';
String msgString = String(message_buff);
Serial.println("Payload: " + msgString);
if (String(topicPowerMeter) == String(topicCallback)) // Si bon topic, récupérer les données tension courant
{
digitalWrite(LED_PIN, LOW); // set output low
Serial.print("Voltage : ");
Serial.println(voltage);
}
else if
else
{
return;
}
}
else
{
Serial.println("Another topic, not for me");
}*/
}
///////////////////////////////////////////////////////////////
// Reconnect to MQTT client
///////////////////////////////////////////////////////////////
boolean reconnect()
{
Serial.println("Connection loosen, try to reconnect");
if (client.connect("ESPClient"))
{
// Once connected, publish an announcement...
client.publish("topicTest","hello world");
// ... and resubscribe
//client.subscribe(topicPowerMeter);
}
return client.connected();
}
///////////////////////////////////////////////////////////////
// Setup
///////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(115200);
delay(100);
Serial.println();
Serial.println("Power Meter ");
Serial.print(swVersion);
Serial.print(", HW:");
Serial.println(hwVersion);
pinMode(AD0_PIN, OUTPUT);
pinMode(AD1_PIN, OUTPUT);
delay(200);
digitalWrite(AD0_PIN,LOW);
digitalWrite(AD1_PIN,LOW);
//pzem.setAddress(ip);
connectwifi(); // Connect wifi
if (client.connected()) // Connect to broker
{
if (client.publish(topicPowerMeter, (char*) payload.c_str(),true))
{
Serial.println("Publish ok");
//client.subscribe(topicPowerMeter);
digitalWrite(LED_PIN, HIGH);
}
else
{
digitalWrite(LED_PIN, LOW);
Serial.println("Publish failed");
}
}
else
{
digitalWrite(LED_PIN, LOW);
Serial.println("Try to reconnect...");
ESP.deepSleep(1000);
}
for (int i=0;i<=4;i++)
{
digitalWrite(LED_PIN, LOW);
delay(200);
digitalWrite(LED_PIN, HIGH);
delay(200);
}
}
///////////////////////////////////////////////////////////////
// Loop
///////////////////////////////////////////////////////////////
void loop()
{
if (!client.connected())
{
long now = millis();
if (now - lastReconnectAttempt > 50000)
{
lastReconnectAttempt = now;
Serial.print("Last Reconnect Attempt : ");
Serial.println(lastReconnectAttempt);
// Attempt to reconnect
if (reconnect())
{
Serial.println("Reconnected");
lastReconnectAttempt = 0;
}
}
Serial.println("");
}
client.loop();
if (WiFi.status() != WL_CONNECTED) // Si le Wifi n'est plus connecté, reconnecter
{
delay(200);
connectwifi();
Serial.println("");
}
int i = 0;
// Envoi sur les 3 UART différents la demande d'énergée puis envoyer par wifi sur le serveur MQTT
for(i = 0 ; i<=2 ; i++)
{
Serial.print("Capteur sélectionné : ");
Serial.println(i);
//Serial.println(i & 0b00000001);
//Serial.println(i & 0b00000010);
if(i == 0)
{
digitalWrite(AD0_PIN,LOW);
digitalWrite(AD1_PIN,LOW);
}
else if(i == 1)
{
digitalWrite(AD0_PIN,HIGH);
digitalWrite(AD1_PIN,LOW);
}
else if(i == 2)
{
digitalWrite(AD0_PIN,LOW);
digitalWrite(AD1_PIN,HIGH);
}
else if(i == 3)
{
digitalWrite(AD0_PIN,HIGH);
digitalWrite(AD1_PIN,HIGH);
}
delay(1000);
float voltage = pzem.voltage();
Serial.println(voltage);
if(not isnan(voltage))
{
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}
float current = pzem.current();
Serial.println(current);
if(not isnan(current))
{
Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
Serial.println("Error reading current");
}
float power = pzem.power();
Serial.println(power);
if(not isnan(power))
{
Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.println("Error reading power");
}
float energy = pzem.energy();
Serial.println(energy);
if(not isnan(energy))
{
Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");
} else {
Serial.println("Error reading energy");
}
float frequency = pzem.frequency();
Serial.println(frequency);
if(not isnan(frequency))
{
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
Serial.println("Error reading frequency");
}
float pf = pzem.pf();
Serial.println(pf);
if(not isnan(pf))
{
Serial.print("PF: "); Serial.println(pf);
} else
{
Serial.println("Error reading power factor");
//break;
}
if(isnan(voltage) || isnan(current) || isnan(power) || isnan(energy))
{
Serial.println("At least one 'NAN' status");
//break;
}
else
{
i++;
msg = "v" + String(i) + ":" + String(voltage) +"V;i" + String(i) + ":" + String(current) + "A;p" + String(i) + ":" + String(power) + "W;e" + String(i) + ":" + String(energy) +"kWh";
Serial.print("Msg : ");
Serial.println(msg);
Serial.println("Publishing PZEM data...");
client.publish(topicPowerMeter, msg.c_str(),true);
i--;
}
delay(250);
}
digitalWrite(AD0_PIN,LOW); // Remise à 0 de l'adresse
digitalWrite(AD1_PIN,LOW);
Serial.println("Waiting...");
delay(waitTime*1000);
ESP.restart(); // On restart pour se reconnecter!
}
Comments