Arduino Due Calibrating Voltage sense +/- 0.1 at first, now +/- 0.3 what does it mean?

I am up and running, but I need to figure out why some things are not reading correctly. My input 6 is always reading negative realpower and powerfactor. My input 7 normally reads positive but when it gets a really resistive load it flips from being positive to being negative.I have another input 10, which is one leg of a 220 circuit for the dryer, its showing 6watts, but I already confirmed that its 0 with my clamp meter. (The dryer is not running, it is off)

So I have some things to figure out. The value column of the inputs is clipped so that I cannot see it all. Does anyone know which file to edit to make that column wider?

Does the dryer have any “electronics” in it?

its like a 10 year old kenmore, just a couple nobs and a start button, no display of any kind (dummy type, not a smart/wifi dryer.) I plan to compare what emoncms is showing with what my meter or scope is saying. (I have already calibrated this extensively so I am a bit surprised, but thing happen.) I think I might have the column fully showing now.

I fixed the truncated values column, its probably not the cleanest way to do it, but the result looks great.

Now that I can fully see the value column I can begin to compare those values with my clamp meter and see how many of them are off.

fix width column for the value output:

sudo nano /var/www/emoncms/Modules/input/Views/input_view.js

change:

    var columnsWidth = 0
    for (k in keys) {
        let key = keys[k]
        columnsWidth += col_max[key];
        hidden[key] = columnsWidth > rowWidth;
    }

to:

    var columnsWidth = 0
    for (k in keys) {
        let key = keys[k]
        if (key == "D") {
                col_max[key] = 60;
        }
        columnsWidth += col_max[key];
        hidden[key] = columnsWidth > rowWidth;
    }

I am not sure what to make of this one, it seems when the powerfactor is large enough (pure resistive load, it is probably the heater kicking on) the powerfactor switches to a negative value:

The results are in, a lot of stuff is completely wrong. When I calibrated, I did so at my desk in my house. This arduino is installed at the SubPanel in the Utility room, which is a completely separate building.

The only thing I can think to do is calibrate it again with it in place where it is currently installed.

Everything was spot on when I calibrated it, but now its wildly off.

input 1: 0 Amps on Clamp meter, emon shows powerfactor of .99 but it should be 0
input 2: appears to be correct.
input 3: 0 Amps on Clamp meter, emon shows powerfactor of 0.82 but it should be 0
input 4: 0 Amps on clamp meter, emon shows powerfactor of .95 but should be 0
input 5: 10.5Amps on clamp meter, emon shows 1144 realpower at 0.95 power factor, correct or close.
input 6: 6.1Amps on clamp meter, emon shows -1640 realpower at -0.84 power factor, wrong.
input 7: 14.9Amps on clamp meter, emon shows 3.4 realpower at 0.31 power factor, wrong.
input 8: 0 Amps on clamp meter, emon shows 2.09 realpower at 0.23 power factor, should be 0
input 9: 0 Amps on clamp meter, emon shows 0.95 realpower at 0.1 power factor, should be 0
input 10: 0 Amps on clamp meter, emon shows 7.32 realpower at 0.58 power factor, should be 0
input 11: 0 Amps on clamp meter, emon shows 0 realpower at 0 power factor, PERFECT!

A few points:

I think at least part of your problem is the amount of phase correction you seem to need. Quite honestly, values in the range 2.2 to 4.0 are ridiculous - the algorithm was never designed to cope with numbers in that range. Those values mean that either the time taken to read the analogue value is extremely long, or one of your sensors has an excessive phase shift, or both.

Remind me how you are measuring current and voltage. Do you know, or can you find out, the individual phase errors of each?

Do you know - can you time - how long it takes between consecutive readings by your Due, and how may pairs of readings (including all the necessary processing) you get per second?

As a guide, and on a 50 Hz system, our UK a.c. adapter shows a phase error of a little over 6° at our nominal 240 V, the standard 100 A c.t. around 4° leading over the normal range of currents, and emonLib reads about 52 pairs (current and voltage) per cycle at 50 Hz, the time between the two readings being about 113 ”s. At 50 Hz, 1° relates to a delay of 55.55 ”s.

If current is zero, you have no power factor - it does not exist. You need to decide how to indicate that - 0, 1.0 could both be sensible values.

1 Like

Here is a picture from when I first started calibrating, The difference is that originally I was using the ZMPT101B module, however I am now using an AC-AC Adapter instead. In addition to the P3 kill a watt. I also used a Fluke multimeter and poke the probes into the power strip, it’s voltage agreed with the voltage on the P3, but I had both on my desk at the same time. I agree with the phase shift value being too large and I would love to reduce it.

here were my calibrations:

  emon[0].voltage(0, 161.74, 3.11);//Voltage: pin, calibration, phase_shift
  emon[0].current(1, 20.01);       //Current: pin, calibration
  emon[1].voltage(0, 161.74, 3.06);
  emon[1].current(2, 20.08);
  emon[2].voltage(0, 161.74, 2.49);
  emon[2].current(3, 19.89);
  emon[3].voltage(0, 161.74, 3.06);
  emon[3].current(4, 20.11);
  emon[4].voltage(0, 161.74, 2.17);
  emon[4].current(5, 29.83);
  emon[5].voltage(0, 161.74, 3.98);
  emon[5].current(6, 30.55);
  emon[6].voltage(0, 161.74, 2.43);
  emon[6].current(7, 29.87);
  emon[7].voltage(0, 161.74, 2.27);
  emon[7].current(8, 29.83);
  emon[8].voltage(0, 161.74, 2.36);
  emon[8].current(9, 29.85);
  emon[9].voltage(0, 161.74, 2.22);
  emon[9].current(10, 29.83);
  emon[10].voltage(0, 161.74, 2.46);

As you can see they Vary between 2.17 and 3.98, to me this suggests that the AC Adapter could be off quite a bit because none of the CT clamps had a phase shift calibration of less than 2.17, which I would think is unusual.

Each full loop takes 1850ms for all inputs to be read and then posted to emoncms.

So my full method for calibrating voltage, was to watch both the P3 Kill a watt set to voltage as wel as the Fluke multimeter, and then adjust the voltage, I came to a setting of 161.74, at which point the serial console agreed with the fluke and P3 kill a watt.

emon[0].voltage(0, 161.74, 3.11);

That took care of the AC-AC adapter.
Next I calibrated each CT. I would start by adjusting the current until the serial output matched the P3 kill a watt current:

emon[0].current(1, 20.01);

Once I had the current dialed in I adjusted the Phase shift for that individual CT, I did it so that realpower would = apparaent power for example 3.11 for this one:

emon[0].voltage(0, 161.74, 3.11);

I did that for all 11 CT inputs. I have errands to run, but when I get home in a couple hours I plan to calibrate it again with it in place in the utility room, hopefully it will shed some light on why its so far off from when I calibrated in the house.

EDIT: When I calibrated in the house the serial console would always show a power factor of 1 when the water heater was plugged in, and a power factor close to 0 when i unplugged the water heater.

OK, I think you didn’t understand what I was getting at.

You’re using emonLib, correct?

That works like this. It reads current and voltage (maybe the order is reversed), but there’s a time lag between the two reading. It then processes the numbers and repeats the process in a loop. The phase error compensation is the time (expressed as a proportion of the time to go round the loop) between the difference between the phase errors (as a time) plus the time between voltage and current readings.

What I am trying to calculate is whether, by modifying the way the readings are taken (possibly by recording and delaying one by a few samples) we can bring the phase correction down. Ideal values are 0 and 1, anything close to those or between them is where distortion and errors are at a minimum.

1 Like

Yes I am, downloaded directly from github.

AH! your referring to the time it takes to run this for a single ct input, correct?

emon[i].calcVI(20,2000);

If so I will time that as soon as I get home, Thank you very much for the help.

The Arduino Due runs a SAM3X8E ARM (32 bit) processor at 84MHz, it is much, much faster than the EmonTX or EmonPi front ends with their ATmega328P (8 bit) processors at 16MHz.

I’m not sure how much faster the ADC’s are though?

No comparison. One Arduino forum user states:

With the code below, I can reach 999 938 Hz in Free Running Mode with Prescal (1) and 1 908 976 Hz with Prescal (0), not bad for ADC conversions followed by DAC conversions of 128 Half words buffers:

Excerpted from how to get the 1Msps in Due - Arduino Due - Arduino Forum

That’s something of a special circumstance. i.e one channel, no muxing.
But others in the same thread say 500 KSPS is very reachable.

I took some timings, and here is the sketch I used:

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3
#include "EmonLib.h"             // Include Emon Library

#define NSENSORS 11
EnergyMonitor emon[NSENSORS]; // Instance of EmonTX sensors
unsigned long ctspeed = 0;
unsigned long loopspeed = 0;

void setup()
{
  Serial.begin(9600);
  analogReadResolution(ADC_BITS);
  emon[0].voltage(0, 161.74, 3.11);//Voltage: pin, calibration, phase_shift
  emon[0].current(1, 20.01);       //Current: pin, calibration
  emon[1].voltage(0, 161.74, 3.06);
  emon[1].current(2, 20.08);
  emon[2].voltage(0, 161.74, 2.49);
  emon[2].current(3, 19.89);
  emon[3].voltage(0, 161.74, 3.06);
  emon[3].current(4, 20.11);
  emon[4].voltage(0, 161.74, 2.17);
  emon[4].current(5, 29.83);
  emon[5].voltage(0, 161.74, 3.98);
  emon[5].current(6, 30.55);
  emon[6].voltage(0, 161.74, 2.43);
  emon[6].current(7, 29.87);
  emon[7].voltage(0, 161.74, 2.27);
  emon[7].current(8, 29.83);
  emon[8].voltage(0, 161.74, 2.36);
  emon[8].current(9, 29.85);
  emon[9].voltage(0, 161.74, 2.22);
  emon[9].current(10, 29.83);
  emon[10].voltage(0, 161.74, 2.46);
  emon[10].current(11, 29.89);
}

void loop()
{
  loopspeed = millis();
  for (int i=0; i<NSENSORS; i++)
  {
    ctspeed = millis();
    emon[i].calcVI(20,2000);    // Calculate all. No.of half wavelengths (crossings), time-out 20 (20 = 1849ms loopSpeed)
    Serial.println("ct speed ms:" + String(millis() - ctspeed)); // loopSpeed checker
  }
  Serial.println("loop speed ms:" + String(millis() - loopspeed)); // loopSpeed checker
  delay(100);
}

It takes about 166-174ms per reading (how does 166ms compare to other emon units? I would assume the Due is faster but it is using 12 bit precision for the analog inputs so not necessarily), and 1850ms for the entire loop, here is the output:

ct speed ms:168
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:166
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
loop speed ms:1851
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:174
loop speed ms:1849
ct speed ms:167
ct speed ms:167
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:166
ct speed ms:174
loop speed ms:1850
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:166
ct speed ms:167
ct speed ms:174
ct speed ms:167
loop speed ms:1849
ct speed ms:166
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
loop speed ms:1850
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:166
ct speed ms:167
loop speed ms:1849
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:166
ct speed ms:166
ct speed ms:174
loop speed ms:1849
ct speed ms:166
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:167
ct speed ms:174
ct speed ms:167
ct speed ms:167
loop speed ms:1850

(you may notice I have delay(100); at the end of the loop for all ct’s 100ms is roughly the amount of time it takes per loop for the network code in my full sketch that posts to emoncms)

Also this is with using .calcVI(20,2000) it would take less time if I use less than 20 half wavelengths, resulting in even faster processing but less samples in the average. I chose 20 because it is what was used in the examples, so I figured it was a good number to use.

I just noticed you asked how long it takes between consecutive readings, for that I am thinking you want the time between these two?

	sampleI = analogRead(inPinI);   //Read in raw current signal
	sampleV = analogRead(inPinV);   //Read in raw voltage signal

If thats the case let me know and I can try and whip something up to take some timings there instead.

I am not sure if thats a half crossing or full wave. however my loop is reading 20 half crossings per
CT in its current configuration, thats 11 ct inputs and the AC-AC adapter. 20 crossings * 11 CT inputs, thats a total of 220 crossings per loop which takes roughly 1750ms on the Due.

What I am not certain about is the “per cycle”, what is that referring to?

I need to figure out the delay between my readings as you pointed out, but I should also try and figure out the phase shift of the AC-AC adapter that I am using.

@emrys - one for you?

ok so after reading over what you posted a few times and letting it sink in, I have modified the emon lib to print those values, I’ve included the code I wrote, incase the way I wrote it introduces a problem that skews the time, i don’t think it should but this is my first arduino:

For anyone that finds this, I would only use these changes for debugging, dont use it in a production system once your up and running.

nano EmonLib.h

change:

    int sampleV;              //sample_ holds the raw analog read value
    int sampleI;

to:

    int sampleV;              //sample_ holds the raw analog read value
    int sampleI;
    unsigned long usI; //debug time

nano EmonLib.cpp

change:

		sampleI = analogRead(inPinI);  //Read in raw current signal
		sampleV = analogRead(inPinV);  //Read in raw voltage signal

to:

		sampleI = analogRead(inPinI);  //Read in raw current signal
		usI = micros();
		sampleV = analogRead(inPinV);  //Read in raw voltage signal
		Serial.println("us:" + String(micros() - usI));

The delay between reading the voltage & current is 12”s on the due while using 12bit resolution
So my 12”s (12/55) should be equivalent to 0.218 degree shift? except im on 60Hz not 50Hz

So the due has almost no phase shift at all from timings between the two, I suspect my AC-AC adapter must have quite a bit of phase error
 However maybe I should just store the values like the 3phase sketch does and offset appropriately per CT input, but ideally I would prefer to have components with less phase error.

Edit: even if the AC-AC adapter is responsible for a lot of phase error, there was also a lot of varriance of phase error between the various CT clamps. One Idea I had was to swap a couple CT clamps, such as one showing phase shift of 4 with one shing 2, and see if the phase error follows the ct clamp, if it does then its the clamp, otherwise its a component on the shield for that ct input.

us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12
us:12

thanks @xekon re: value column width adjustment in inputs list

the issue was that the column width was based on the time value not the data value. I’ve now changed this in this pull request and it should be fixed when this is pulled into the master branch.

2 Likes