Electric Imp and Non-invasive AC current sensor

@osherl
me too! i hope we can get this thing a little bit further.
i will now try to get more accuracy.

Applications such as this are exactly what the sampler is for. Without accurate timing of the samples, you have no idea whether you’re measuring one cycle, lots of cycles but with whopping aliasing problems, or just a tiny part of one cycle. (Though you could find out using hardware.micros().)

Peter

What is the minimum current you can measure? Please keep us posted…

0.20-0.22 is the actual minimum. i have no clue what the emontx or the arduino guys over at opemEM measure. but with the actual accuracy i will not see ~50W.

@peter
Thanks for the sampler suggestion. I’ll give it a try.
I did use hardware.micros() to determine the sampling rate. It’s about 75 samples per cycle at 60Hz (16.66 ms per cycle).

You could speed this up a lot by doing something like:
sensor <- hardware.pin5; outside of the loop, and inside the loop use: sample = sensor.read(); but ultimately, the sampler will give you a much higher rate.

thx, i will try that!
looking for a nice way to use the function for 3 sensors to measure 3 phases.

Here is the code with the sampler. Peter, thanks again for the suggestion. It appears to be more accurate (and I learned about the sampler and blobs). Please comment on my implementation (not sure about the sample loop). @Chrischi, my minimum current now is way under 0.20.
`
const ICAL = 100.0; // 100 A / 50 mA / 20 Ω = (100 / 0.050) / 20 = 100.0
sampleI <- 31800; // calibrate for first run
lastSampleI <- 0.0;
filteredI <- 0.0;
lastFilteredI <- 0.0;
sqI <- 0.0;
sumI <- 0.0;

function DataReady(buffer, length)
{
local i;
if (length > 0)
{
for (i=0;i<length;i+=2) {
//server.log(buffer[i]+buffer[i+1]*256); // little-endian
lastSampleI = sampleI;
sampleI = buffer[i]+buffer[i+1]256; // the samples…
lastFilteredI = filteredI;
filteredI = 0.996
(lastFilteredI+sampleI-lastSampleI); // phase correction algorithm
sqI = filteredI * filteredI; // root-mean-square method current (RMS)
sumI += sqI;
}
local I_RATIO = ICAL * ((hardware.voltage()) / 65536.0);
local Irms = I_RATIO * math.sqrt(sumI / 3000);
sumI = 0;
server.log(Irms +" "+ Irms * 120.0); // Irms and apparent power
}
}
function StopSampler()
{
hardware.sampler.stop();
sample();
}
function sample()
{
hardware.sampler.start();
imp.wakeup(1, StopSampler);
}
buffer1 <- blob(3000);
buffer2 <- blob(3000);
imp.configure(“Energy Monitor”, [], []);
// 6000 bytes of data are produced every second at 3KHz, 50 samples/cycle at 60Hz)
hardware.sampler.configure(hardware.pin2, 3000, [buffer1,buffer2], DataReady);
sample();
`

@osherl
awesome, this is much better! :)>- the improvement in accuracy is very good.

will try to do that for my 3 phases measurement.

I believe you can only have one sampler (ie, sample one analog input). Admittedly, I haven’t spent a lot of time on it, but when I tried setting up multiple samplers, only the last-configured channel received any data.

There has been so much discussion, I sort of lost track of what has happened. Is there a way where one pin could be used to detect the ac zero-crossing and look at the maximum value between crossings? A circuit with a pulse at each zero crossing?

There’s still something I don’t quite get: how does the calibration work?

How can I get real power in kWatts?

Ok, I figured out that to get the real power I need instantaneous current x instant. voltage. How do I get the current?

alkopop79: there is a edit button next to the post-time. :wink:

current is what you get after using some of the code posted before.

Just noticed that only buffer1 is being processed (half of the samples). When I changed imp.wakeup(1.0, StopSampler); to imp.wakeup(1.01, StopSampler);, both buffers are filled and processed. It needs that extra 1/100 of a second to fill the second buffer. It works fine, but is there a better way of doing this?

@sjm multi-channel sampling is on the roadmap, no date as yet.

@all

can you please list your sensor and the minimum Irms you can read?

SCT-013-000, 22Ohm burden, minimum (Irms) = ~0,21-0,22 (~45W / 230V)

SCT-013-000, 20 Ohm burden, minimum (Irms) = ~0.18 (~22W / 120V)

@osherl you are using 120V, right?