Decrease interval logging to 1 per second (increase rate from 5/sec to 1/sec)

@kelster101757

Here’s a similar output from IoTaWatt with 20 samples per second. The data varies by less than .5% over the 3 seconds. Each sample is one AC cycle. It is measured at 60Hz, so at 50Hz the sample count would be more like 16+.

When I say one AC cycle, I mean exactly one AC cycle +/- about 0.1% of the cycle. I think the math for jumping in arbitrarily and sampling for a fixed period of time is flawed for two reasons:

  1. The frequency varies too much to reliably predict when a whole number of cycles has been sampled. UK frequency for the last hour

  2. It matters where you jump in. If you jump in at a peak of the cycle, any short/extra samples due to frequency/sample-rate calibration will result in a much larger error than if the timed sample period begins on or near the zero crossing.

So this data was generated by literally adding one printf statement to the IoTaWatt firmware. Although I output real power and rms voltage, power factor, rms current and of course apparent power are also available to be included in the print statement.

These values are also ms-time-weighted and accumulated, so that the average over any interval, measured in ms, can be easily obtained.

There is a process that already outputs to influxDB - with timestamps.

You may have noticed that I posted this output without explanation. Just to pique your interest. But the moderators insisted on this explanation. Hope it widens the scope of your project.

Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.8, vrms 118.1
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.4, vrms 118.0
Seconds: 11, real power: 123.4, vrms 118.0
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.6, vrms 118.0
Seconds: 11, real power: 123.4, vrms 118.0
Seconds: 11, real power: 123.4, vrms 118.0
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.7, vrms 118.0
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.6, vrms 117.9
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.5, vrms 118.0
Seconds: 11, real power: 123.4, vrms 118.0
Seconds: 11, real power: 123.3, vrms 117.9
Seconds: 11, real power: 123.3, vrms 117.9
Seconds: 12, real power: 123.6, vrms 118.0
Seconds: 12, real power: 123.3, vrms 117.9
Seconds: 12, real power: 123.3, vrms 117.7
Seconds: 12, real power: 123.3, vrms 117.9
Seconds: 12, real power: 123.7, vrms 118.1
Seconds: 12, real power: 123.4, vrms 118.0
Seconds: 12, real power: 123.3, vrms 118.0
Seconds: 12, real power: 123.5, vrms 118.0
Seconds: 12, real power: 123.5, vrms 118.0
Seconds: 12, real power: 123.5, vrms 118.0
Seconds: 12, real power: 123.4, vrms 118.0
Seconds: 12, real power: 123.5, vrms 118.0
Seconds: 12, real power: 123.5, vrms 118.0
Seconds: 12, real power: 123.5, vrms 118.0
Seconds: 12, real power: 122.9, vrms 118.2
Seconds: 12, real power: 123.4, vrms 117.9
Seconds: 12, real power: 123.5, vrms 118.1
Seconds: 12, real power: 123.4, vrms 118.0
Seconds: 12, real power: 123.7, vrms 118.1
Seconds: 12, real power: 123.7, vrms 118.1
Seconds: 13, real power: 123.9, vrms 118.0
Seconds: 13, real power: 123.7, vrms 118.1
Seconds: 13, real power: 123.6, vrms 118.1
Seconds: 13, real power: 123.5, vrms 118.0
Seconds: 13, real power: 123.7, vrms 118.1
Seconds: 13, real power: 123.5, vrms 118.0
Seconds: 13, real power: 123.5, vrms 118.0
Seconds: 13, real power: 123.7, vrms 118.1
Seconds: 13, real power: 123.4, vrms 117.9
Seconds: 13, real power: 123.3, vrms 118.0
Seconds: 13, real power: 123.6, vrms 118.0
Seconds: 13, real power: 123.7, vrms 118.1
Seconds: 13, real power: 123.6, vrms 118.1
Seconds: 13, real power: 123.6, vrms 118.1
Seconds: 13, real power: 123.6, vrms 118.1
Seconds: 13, real power: 123.7, vrms 118.2
Seconds: 13, real power: 123.6, vrms 118.1
Seconds: 13, real power: 123.5, vrms 118.0
Seconds: 13, real power: 123.7, vrms 118.1
Seconds: 13, real power: 123.5, vrms 118.0
Seconds: 14, real power: 123.6, vrms 118.1

I am interested in real power but its not required for this particular application. I’ve used the Arduino Due and with the batch size at 1480 (double Irms = emon1.calcIrms(1480); // Calculate Irms only) and we’re now getting 42 readings per a second which is great :slight_smile: some sample readings below:

Time in mlsec: 4011, Time in sec: 4, 112.73 0.49
Time in mlsec: 4035, Time in sec: 4, 118.12 0.51
Time in mlsec: 4059, Time in sec: 4, 114.29 0.50
Time in mlsec: 4083, Time in sec: 4, 130.31 0.57
Time in mlsec: 4107, Time in sec: 4, 114.04 0.50
Time in mlsec: 4131, Time in sec: 4, 117.60 0.51
Time in mlsec: 4155, Time in sec: 4, 114.90 0.50
Time in mlsec: 4179, Time in sec: 4, 111.32 0.48
Time in mlsec: 4204, Time in sec: 4, 133.66 0.58
Time in mlsec: 4228, Time in sec: 4, 110.25 0.48
Time in mlsec: 4252, Time in sec: 4, 122.75 0.53
Time in mlsec: 4276, Time in sec: 4, 112.39 0.49
Time in mlsec: 4300, Time in sec: 4, 102.19 0.44
Time in mlsec: 4324, Time in sec: 4, 136.63 0.59
Time in mlsec: 4348, Time in sec: 4, 107.33 0.47
Time in mlsec: 4372, Time in sec: 4, 126.12 0.55
Time in mlsec: 4396, Time in sec: 4, 109.94 0.48
Time in mlsec: 4420, Time in sec: 4, 115.94 0.50
Time in mlsec: 4444, Time in sec: 4, 123.19 0.54
Time in mlsec: 4469, Time in sec: 4, 111.07 0.48
Time in mlsec: 4493, Time in sec: 4, 128.67 0.56
Time in mlsec: 4517, Time in sec: 4, 108.16 0.47
Time in mlsec: 4541, Time in sec: 4, 107.79 0.47
Time in mlsec: 4565, Time in sec: 4, 109.58 0.48
Time in mlsec: 4589, Time in sec: 4, 112.17 0.49
Time in mlsec: 4613, Time in sec: 4, 128.13 0.56
Time in mlsec: 4637, Time in sec: 4, 109.30 0.48
Time in mlsec: 4661, Time in sec: 4, 106.59 0.46
Time in mlsec: 4685, Time in sec: 4, 100.08 0.44
Time in mlsec: 4709, Time in sec: 4, 109.85 0.48
Time in mlsec: 4734, Time in sec: 4, 135.57 0.59
Time in mlsec: 4758, Time in sec: 4, 105.58 0.46
Time in mlsec: 4782, Time in sec: 4, 114.73 0.50
Time in mlsec: 4806, Time in sec: 4, 109.88 0.48
Time in mlsec: 4830, Time in sec: 4, 111.58 0.49
Time in mlsec: 4854, Time in sec: 4, 126.52 0.55
Time in mlsec: 4878, Time in sec: 4, 106.58 0.46
Time in mlsec: 4902, Time in sec: 4, 121.61 0.53
Time in mlsec: 4926, Time in sec: 4, 115.90 0.50
Time in mlsec: 4950, Time in sec: 4, 115.02 0.50
Time in mlsec: 4974, Time in sec: 4, 126.46 0.55
Time in mlsec: 4998, Time in sec: 4, 113.47 0.49

The Arduino code I’ve wrote publishes the data directly over the network to the MQTT server. I know the talk in this thread recommended to use the Arduino read and serial the data to the Pi for the publishing but is that required with the Arduino Due since its multi-core and way more powerful? I would appreciate any thoughts on the subject

I’ve coppied the code for your perusal :

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

/*
take electricity readings from A1 pin and post to mqtt

To Do:

  • set to get DHCP address

*/
#include <SPI.h> // SPI required for network
#include <Ethernet.h> // eithernet library for
#include <PubSubClient.h> // pubsubclient library
#include “EmonLib.h” // Include Emon Library
EnergyMonitor emon1; // Create an instance

// Update these with values suitable for your network.
byte mac = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(172, 16, 24, 99); // sets the ip address of this device
IPAddress server(172, 16, 24, 11); // mqtt server on factory vlan

const char * EquipmentID = “equipment1”; //equipment ID of the machine
const char * FullAsset = “equipment1”; //full name of the machine

String temp_str; //Convert the float to the string
char temp[50]; // Temporary variable for charactors

//Processes any returned messages
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}

EthernetClient ethClient; //create a instance of ethernet client
PubSubClient client(ethClient);

unsigned long DueTime; // to store time

void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
// Attempt to connect
if (client.connect(“arduinoClient”)) {
Serial.println(“connected”);
// Once connected, publish an announcement…
client.publish(“outTopic”,“hello world”);
// … and resubscribe
client.subscribe(“inTopic”);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

void setup()
{
//network setup
Serial.begin(115200);
client.setServer(server, 1883); //sets connection for mqtt server
client.setCallback(callback); //sets call back

Ethernet.begin(mac, ip); // Sets mac and ip of the device
delay(1500); // Allow the hardware to sort itself out

//emon setup
emon1.current(1, 111.1); // Current: input pin, calibration.
analogReadResolution(ADC_BITS); // sets resultion to 12bits
}
void loop()
{
double Irms = emon1.calcIrms(1480); // Calculate Irms only
//double Irms = emon1.calcIrms(740); // Calculate Irms only
DueTime = millis(); // Returns the number of milliseconds since the Arduino board began running the current program
Serial.print("Time in mlsec: “);Serial.print(DueTime);Serial.print(”, "); // time in millseconds
Serial.print("Time in sec: “);Serial.print(DueTime/1000);Serial.print(”, “); //time in seconds
Serial.print(Irms*230.0); // Apparent power
Serial.print(” “);
Serial.println(Irms); // Irms
Serial.print(” ");

if (!client.connected()) {
reconnect();
}

//convert irms to string to publish through pubsub
temp_str = String(Irms); //converting ftemp (the float variable above) to a string
temp_str.toCharArray(temp, temp_str.length() + 1); //packaging up the data to publish to mqtt…

client.publish(FullAsset,temp); //logs power
client.loop();

}

There’s no longer anything magic about the number 1480. It used to be the best approximation for 200 ms monitoring with an ATMega328P, but tweaks to speed up emonLib have made it wrong anyway. Until people say differently, we assume you’re using the emonTx/emonPi because most people here do.

All that I’d suggest is you try to make it sample for a whole number of mains cycles - if you can. You’ll minimise the “end effect” of including a part-cycle - and you don’t know where the cycle starts and ends, so the extra/missing part could be at peak amplitude or it could be around zero. That could well account for part of the variation from reading to reading that you’re seeing - just looking at those numbers, it’s about ±12%. I suggest you do as I wrote in another thread only a few minutes ago: 5 second intervals between EmonLib samples? - #4 by Robert.Wall