@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); // ??? }