Energy Meter - not sending at expected
-
a few thing that can be my error.
- I had one beginner mistake, no cap on NRF thats why it was getting Failed a few times, this happened after 0-10 minutes and during my first setup it was 5 minutes to send.
New NRF and Cap seems to solve one issue. Sorry - I noticed if the Watt is sent it will update Domoticz. If VAR is sent it will not update Domoticz. If kwh is sent it will update Domoticz.
- skectch is checking if kwh was same as old, the check is only handling 2 decimals(what is can see in SerialPrint) so I needed a lot of watts to change second decimal. 1845110734 is my VAR but the IF code is only seeing 184511.07
summary
Bad NRF, it was working a few minutes. Biggest error
My watt was same, heating system and right now it doesn't heat = dont send
My kwh was increasing slowly = don't sendI think I will remove the check if value is old and send it every 5 minutes even if watt, kwh, pulsecount is same as old
- I had one beginner mistake, no cap on NRF thats why it was getting Failed a few times, this happened after 0-10 minutes and during my first setup it was 5 minutes to send.
-
@flopp pulseCount/V_VAR1 and Domoticz is something else... I have not got my finger around it but what I know is that some values in the energi meter is calculacted from V_VAR1 / day. When i tested my rain sensor (tip_bucket) i pretty much have to do 1 test each day to be sure. Also there is the possibility to edit the database but as i said, im not sure.
If you had a pulsecount of 1000 and set it to 0 it would show -1000 in watts i think or something... but only calculated the pulse from that day.
Sorry, not bringing anything good to the table, just remember it was a bit hard to get my head around.@sundberg84
i also had a lot of problem with my Rain data in Domoticz.
read more here https://www.domoticz.com/forum/viewtopic.php?f=28&t=11088if your Sensor timeout is 2 hours you need to send rain VAR within 2 hours otherwise your graph will look strange.
Yes, if you change the VAR during the day to a lower value you will get minus value. Took me a few days to understand how Domoticz DB file was working.
Keep up the good work :punch:
-
But I found something weird about the division

Why doesn't it send the exact value?
My pulseCount is 1845124894 and it is sent to Controller correct, then it will use below function
My PULSE_FACTOR is 10000double kwh = ((double)pulseCount/((double)PULSE_FACTOR));and send the divided value to Controller, but it doesn't send correct value, it is missing the two last numbers "94" it is absolutely not a big problem but why send 4 decimals when the two last it always 0(zero)
Look at last row, 1845125113 = 184512.5200?
Is this because double values is rounding up? But 5113 should be 5100.
-
But I found something weird about the division

Why doesn't it send the exact value?
My pulseCount is 1845124894 and it is sent to Controller correct, then it will use below function
My PULSE_FACTOR is 10000double kwh = ((double)pulseCount/((double)PULSE_FACTOR));and send the divided value to Controller, but it doesn't send correct value, it is missing the two last numbers "94" it is absolutely not a big problem but why send 4 decimals when the two last it always 0(zero)
Look at last row, 1845125113 = 184512.5200?
Is this because double values is rounding up? But 5113 should be 5100.
-
@flopp could be because 'double' is actually float on Arduino, and therefore precision is limited. Have to do so maths though to know for sure.
-
still working with UNO.
this is the sketch i am running
#include <SPI.h> #include <MySensor.h> #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your light sensor. (Only 2 and 3 generates interrupt!) #define PULSE_FACTOR 10000 // Nummber of blinks per KWH of your meeter #define SLEEP_MODE false // Watt-value can only be reported when sleep mode is false. #define MAX_WATT 15000 // Max watt value to report. This filetrs outliers. #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) #define CHILD_ID 1 // Id of the sensor child unsigned long SEND_FREQUENCY = 5*60000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. MySensor gw; double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour boolean pcReceived = false; volatile unsigned long pulseCount = 0; volatile unsigned long lastBlink = 0; volatile unsigned long watt = 0; unsigned long oldPulseCount = 0; unsigned long oldWatt = 0; double oldKwh; unsigned long lastSend; MyMessage wattMsg(CHILD_ID,V_WATT); MyMessage kwhMsg(CHILD_ID,V_KWH); MyMessage pcMsg(CHILD_ID,V_VAR1); void setup() { gw.begin(incomingMessage); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("Energy Meter", "1.1"); //1.1 no check for old value, always send // Register this device as power sensor gw.present(CHILD_ID, S_POWER); // Fetch last known pulse count value from gw gw.request(CHILD_ID, V_VAR1); attachInterrupt(INTERRUPT, onPulse, RISING); lastSend=millis(); } void loop() { gw.process(); unsigned long now = millis(); // Only send values at a maximum frequency or woken up from sleep bool sendTime = now - lastSend > SEND_FREQUENCY; if (pcReceived && (SLEEP_MODE || sendTime)) { // New watt value has been calculated // Check that we dont get unresonable large watt value. // could hapen when long wraps or false interrupt triggered if (watt<((unsigned long)MAX_WATT)) { gw.send(wattMsg.set(watt)); // Send watt value to gw } Serial.print("Watt:"); Serial.println(watt); oldWatt = watt; // Pulse cout has changed if (pulseCount != oldPulseCount) { gw.send(pcMsg.set(pulseCount)); // Send pulse count value to gw double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); oldPulseCount = pulseCount; gw.send(kwhMsg.set(kwh, 4)); // Send kwh value to gw oldKwh = kwh; } lastSend = now; } else if (sendTime && !pcReceived) { // No count received. Try requesting it again gw.request(CHILD_ID, V_VAR1); lastSend=now; } if (SLEEP_MODE) { gw.sleep(SEND_FREQUENCY); } } void incomingMessage(const MyMessage &message) { if (message.type==V_VAR1) { pulseCount = oldPulseCount = message.getLong(); Serial.print("Received last pulse count from gw:"); Serial.println(pulseCount); pcReceived = true; } } void onPulse() { if (!SLEEP_MODE) { unsigned long newBlink = micros(); unsigned long interval = newBlink-lastBlink; if (interval<10000L) { // Sometimes we get interrupt on RISING return; } watt = (3600000000.0 /interval) / ppwh; lastBlink = newBlink; } pulseCount++; } -
There must be something wrong with my code. Since 1 February my Arduino is 3 kWh before the real energy value for my house.
My second Arduino is measuring kWh on my heating system and that one is running correct.
For my house I use Nano(clone) for heating system I use UNO(original)
Can the hardware be the bad guy here?
It should be same code in both Arduino but tomorrow I will use an UNO(org) for my house and wait 1 week. -
There must be something wrong with my code. Since 1 February my Arduino is 3 kWh before the real energy value for my house.
My second Arduino is measuring kWh on my heating system and that one is running correct.
For my house I use Nano(clone) for heating system I use UNO(original)
Can the hardware be the bad guy here?
It should be same code in both Arduino but tomorrow I will use an UNO(org) for my house and wait 1 week. -
I changed to a UNO now my Watt is showing the same value!!
EDIT: this was because the WATT was above 15000 and then it didn't send any data to Controller. I had values up to 110000.
It must be something with the Watt calculation. Anyone seen this before?

-
I think I found it.
if (interval<10000L) { // Sometimes we get interrupt on RISING return; }It seems to be that my interrupt is to quick. above code is default if I change to
if (interval<35000L) { // Sometimes we get interrupt on RISING return; }it will calculate Watt as I think it should be.
I will let it run for a week and see if kWh is OK now.