@Karolis-Kirna Just a bit late but here it is.
The code:
/*
* Send Watt and Kwh to gateway
* using PZEM-004t
* 26/8/2020 cambiato linea 45, 21-23
*/
/*++++++++++++++ Global Settings +++++++++++++++++*/
#define SN "PZEM Monitor"
#define SV "0.4"
// Enable and select radio type attached
#define MY_RADIO_NRF24
#define MY_NODE_ID 9
#define MY_PARENT_NODE_ID 11 // from domoticz log
#define MY_PARENT_NODE_IS_STATIC
/*+++++++++++++ Local Settings ++++++++++++++++++++*/
#define SEND_ONLY_IF_CHANGED
//#define MY_DEBUG
//#define DEBUG
//#define TEST // Aggiunge codice di test da levare
#if F_CPU == 8000000L
#define MY_BAUD_RATE 9600
#endif
#include <debugpaolo.h>
#include <SPI.h>
#include <MySensors.h>
//#include <SoftwareSerial.h> // Arduino IDE <1.6.6
#include <PZEM004T.h>
#define RX_PIN 4
#define TX_PIN 5
PZEM004T pzem(RX_PIN,TX_PIN); // RX pin,TX pin
IPAddress ip(192,168,1,1);
#define CHILD_WATT_ID 0
#define VOLTAGE_ID 1
unsigned long lastSend=0;
unsigned long SEND_FREQUENCY = 40000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
MyMessage wattMsg(CHILD_WATT_ID,V_WATT);
MyMessage kWhMsg(CHILD_WATT_ID,V_KWH);
//MyMessage kwhSaveMsg(CHILD_WATT_ID,V_VAR1);
//MyMessage varMsg(CHILD_WATT_ID,V_VAR); // chi lo sa non va in domoticz
double oldKwh=0.0;
double oldwh=0.0;
float oldwatt=0.0;
#ifdef TEST
double whtest=0.0;
#endif
#ifdef SEND_ONLY_IF_CHANGED
int kwh_counter;
#define KWH_COUNTER_MAX 33 //dopo 23 volte(15 min) invia comunque
#endif
MyMessage msgVoltage(VOLTAGE_ID, V_VOLTAGE);
float lastv=0;
#define V_COUNTER_MAX 70
int v_counter=0;
int BATTERY_SENSE_PIN = A3; // select the input pin for the battery sense point
int oldBatteryPcnt = 0;
#define MAX_BATTERY_CHECK 56 // 56*40 sec = 56 min circa
int battery_check;
#define VREF 1.106
#define RBATT 5.73305 // ((1578+333.4)/333.4)?
#define VFACTOR RBATT*VREF/1023 //
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++ SETUP +++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void setup() {
// begin(incomingMessage);
analogReference(INTERNAL);
pzem.setAddress(ip);
battery_check = MAX_BATTERY_CHECK;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++ Presentation ++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo(SN, SV);
present(CHILD_WATT_ID, S_POWER);
present(VOLTAGE_ID, S_MULTIMETER);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++ Loop +++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void loop() {
/* +++++++++++++++++++++++++++++++++++++++++++
++++ PZEM section +++++++++
+++++++++++++++++++++++++++++++++++++++++++*/
float v = pzem.voltage(ip);
if (v < 0.5) {
delay(500);
// check v twice
v = pzem.voltage(ip);
if (v < 0.5 ) v = 0.0;
}
DEBUG_PRINT(v);DEBUG_PRINT("V; ");
#ifdef DEBUG
float i = pzem.current(ip);
if(i >= 0.0){ DEBUG_PRINT(i);DEBUG_PRINT("A; "); }
float VA=v*i;
if(VA >= 0.0){ DEBUG_PRINT(VA);DEBUG_PRINTLN("VA; "); }
#endif
/* ---------------------------
*------- Sezione potenza ----
----------------------------*/
float watt = pzem.power(ip);
#ifdef TEST
watt=kwh_counter*2;
#endif
DEBUG_PRINT(watt);DEBUG_PRINT("W ");DEBUG_PRINT(VA);DEBUG_PRINTLN("VA ");
if (watt <=0 ) {
DEBUG_PRINT(watt);DEBUG_PRINTLN("W. Sensore NC o assenza rete! ");
if ( oldwatt>0) {
watt =0;
send(wattMsg.set(watt,1)); // Send watt value to gw
oldwatt=0.0;
}
}
else {
if ( oldwatt==0.0) {
send(wattMsg.set(watt,1)); // Send watt value to gw
DEBUG_PRINT(watt);DEBUG_PRINTLN("Rete ritornata! ");
oldwatt = watt;
}
else {
DEBUG_PRINT(watt);DEBUG_PRINTLN("W; ");
float diffwatt=abs(watt-oldwatt);
if ( diffwatt >= 49.9 ) { // watt in aumento di 50watt
DEBUG_PRINT("Differenza ");DEBUG_PRINT(diffwatt);DEBUG_PRINTLN("W; ");
oldwatt = watt;
send(wattMsg.set(watt,1)); // Send watt value to gw
}
else {
float perc = 100.0*diffwatt/oldwatt; // oldwatt o watt?
DEBUG_PRINT("Perc ");DEBUG_PRINT(perc);DEBUG_PRINTLN("% ");
if ( perc >= 49.9 ) { // variazione del 50%
DEBUG_PRINT("Percentuale Diff ");DEBUG_PRINT(perc);DEBUG_PRINTLN("%; ");
oldwatt = watt;
send(wattMsg.set(watt,1)); // Send watt value to gw
// send(varMsg.set(watt,1)); // non va in domoticz
}
else {
if ( (perc >= 15.0) && (diffwatt>=8) ) {
DEBUG_PRINT("Diff ");DEBUG_PRINT(diffwatt);
DEBUG_PRINT("Perc ");DEBUG_PRINT(perc);DEBUG_PRINTLN("%; ");
oldwatt = watt;
send(wattMsg.set(watt,1)); // Send watt value to gw
}
}
}
}
}
//send(wattMsg.set(watt,1)); // Send watt value to gw
/* ---------------------------
*------- Sezione energia ----
---------------------------*/
float wh = pzem.energy(ip);
#ifdef TEST
whtest+=10.0;
wh=whtest;
#endif
if(wh >= 0.0){ DEBUG_PRINT(wh);DEBUG_PRINT("Wh; "); }
else wh = 0.0;
DEBUG_PRINTLN();
#ifdef SEND_ONLY_IF_CHANGED
if ( (kwh_counter==0) ||(abs(wh-oldwh) > 187) ) { // 100 wh
#else
if ( wh > 0.0 ) {
#endif
double kwh = (double)wh/(double)1000.0;
send(kWhMsg.set(kwh, 3)); // Send kwh value to gw
oldwh=wh;
#ifdef SEND_ONLY_IF_CHANGED
kwh_counter=0;
#endif
}
#ifdef SEND_ONLY_IF_CHANGED
DEBUG_PRINT("kwh_counter=");
kwh_counter++;
DEBUG_PRINT(kwh_counter);DEBUG_PRINT(" ");
if (kwh_counter == KWH_COUNTER_MAX ) kwh_counter = 0;
DEBUG_PRINTLN();
#endif
/* +++++++++++++++++++++++++++++++++++++++++++
++++ Battery check section +++++++++
+++++++++++++++++++++++++++++++++++++++++++*/
if ( battery_check == MAX_BATTERY_CHECK) {
analogRead(BATTERY_SENSE_PIN); // needed for accuracy
int sensorValue = analogRead(BATTERY_SENSE_PIN);
DEBUG_PRINT("A0 Value = ");DEBUG_PRINTLN(sensorValue);
float batteryV = sensorValue * VFACTOR;
// 100% 4.0v 0% 3.3v
int batteryPcnt = ( batteryV - 3.3) / (4.0 - 3.3) * 100;
batteryPcnt = (batteryPcnt > 100) ? 100 : batteryPcnt;
batteryPcnt = (batteryPcnt < 0) ? 0 : batteryPcnt;
DEBUG_PRINT("Battery Voltage: ");DEBUG_PRINT(batteryV);DEBUG_PRINTLN(" V");
DEBUG_PRINT("Battery Percent: ");DEBUG_PRINT(batteryPcnt);DEBUG_PRINTLN(" %");
//if (oldBatteryPcnt != batteryPcnt) {
sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
//}
battery_check=0;
} else {
battery_check++;
DEBUG_PRINT("Check = ");
DEBUG_PRINTLN(battery_check);
}
/* +++++++++++++++++++++++++++++++++++++++++++
++++ 230 Voltage section +++++++++
+++++++++++++++++++++++++++++++++++++++++++*/
#ifdef SEND_ONLY_IF_CHANGED
float diffv= abs(v-lastv);
if ( ((v_counter == 0) || ( diffv > 3.50)) ) {
DEBUG_PRINT("v diff: ");DEBUG_PRINT(diffv);DEBUG_PRINTLN("V ");
if ( diffv > 3.50 ) v_counter = 0;
else v_counter++;
DEBUG_PRINT("v_counter : ");DEBUG_PRINTLN(v_counter);
#endif
send(msgVoltage.set(v, 1));
lastv = v;
#ifdef SEND_ONLY_IF_CHANGED
} else {
v_counter++;
if (v_counter >= V_COUNTER_MAX ) v_counter = 0;
DEBUG_PRINT("v_counter : ");DEBUG_PRINTLN(v_counter);
}
#endif
sleep(SEND_FREQUENCY);
delay(500); // ???
}