# Building a power monitor

#### jgauthier

Mar 22, 2013
63
Greetings,

I own a TED (The Energy Detective) 1000 model. It's quite a few years old, and does whole house monitoring. It communicates using PLC.

I decided I wanted to build my own, and use a current transformer on each circuit. This would allow me to really see where my power is going, and I think it sounds fun.

So, I grabbed a \$10 CT from sparkfun, along with an MCP3002.

I attached this all to a Raspberry Pi, and so far so good(ish).
Let me step back a quick moment. First, to test the MCP3002, I used a simple 100k pot, and attached that to the input pin.
Since the MCP3002 is a 10-bit ADC, I was able to get ranges from 0-1023 without a problem.

I attached the CT using a 110Ohm burden resistor so the ADC will get ~0-3.3v for the input, since it's using 3.3v as the analog reference.

Using a multimeter, and math, I am able to calculate the output, and it's correct, when I get to about 1200 watts (hair dryer).

My readings on the raspberry pi are all over the board. I definitely can tell there is some accuracy here, but it spikes up and down continuously. I am wondering if this is because the analog input to the ADC is RMS, and therefore goes negative, and depending on when the input is read through to the pi, it could be anywhere on the AC sign wave.

If that could be confirmed, great. And if that is the issue, I am looking for some suggestions to overcome it. I considered a full wave bridge rectifier, but with the very low voltages it won't work, and i'll lose the precision I am looking for,

Thanks!

#### Harald Kapp

##### Moderator
Moderator
Nov 17, 2011
13,447
Show us a schematic of your connections. As far as I understand you have the burden in parallel to the CT's output and you measure the voltage across the burden using the ADC, right?
There are certain limitations on the allowable input voltages to the ADC. Most importantly they shall not go below Vss-100mV. Your AC signal will, however, go below that limit unless you add some signal conditioning. Ideally you'd use an ompamp to decouple the signal from the ct, adding an offset, adjusting gain and filtering the signal. A very simple setup, however, can look like this:

The measured current is translated to a voltage across the burden resistor.
The filter resistors and capacitors remove high frequency noise. Set the corner frequency to a value that lets pass enough of the useful signal including as many harmonics as you need to measure.
The voltage divider should be made from comparatively low value resistors (e.g. 1kOhm)) and sets one end of the ct to a fixed reference potential (1/2*Vref = 1,65V, make sure Vref is stable and well filtered).
The output to the ADC now swings around 1.65V:
• A voltage of 1.65V at the output is equivalent to 0V (0A) at the ct.
• A voltage of 3.3V at the output is equivalent to +1.65V at the ct.
• A voltage of 0V at the output is equivalent to -1.65V at the ct.
You will have to do the scaling of the ADC values to appropriate currents in software, remembering that a numerical value of 512 (0x200) is equivvalent to 0V (or 0A if translated to the primary of the ct).
You will also have to adpat the burden resistor. If it currently produces +-3.3V voltage drop at max. current, use half the currrent resistance to produce +-1.65V. Otherwise you will overload the ADC's input.

If this simple circuit is not satisfactorily, you may add an opamp stage between ct and ADC for additional gain control, filtering, offset adjustement etc.

#### Attachments

• CT_input.gif
5 KB · Views: 2,061

#### duke37

Jan 9, 2011
5,364
I would consider rectifying the signal it you do not want true RMS values. In any case, you are not taking power factor into account.

Put the secondary of the current transformer through a bridge rectifier which then feeds the burden resistor, paralleled with a capacitor. The current transformer will provide the voltage necessary to overcome the diode drop but Schottky diodes would help. The output would be a measure of mean current.

#### jgauthier

Mar 22, 2013
63
Thanks. A lot to think on which direction to take. I did confirm my reading fluctuations were definitely because of the AC signal. I grabbed 4000 samples into an output file and graphed them in Excel:

This looks good, other than the readings are too high. 600 would be 40 amps, and I was only at 10. But that's probably just a math issue in my code.

My circuit looks very similar to the above, with fewer caps and no filter resistors. Something like this:

It's not great, sorry. I just used a quick schematic editor online. VSS goes to ground, VDD/VREF are 3.3V.
My actual ADC doesn't have a VDD, FYI. Just an VREF.

#### jgauthier

Mar 22, 2013
63
So, I believe I have a suitable software solution. Let me know if I'm crazy.
I'm taking 1000 samples, which executes in 41ms. Of the 1000 samples, I implement a max() function to store the maximum value. That value should be the peak current. I then simply multiply by .707 and get the RMS current. This seems to be extremely accurate in respect to the ammeter I have inline.

I think I am going to stick with this method, unless someone can tell me why this is a glaringly bad idea!
I do have some readings (a 2 on the ADC) without any load. I think I can clean that up with a filter capacitor on the ADC input. Not sure, but I will try.

#### Harald Kapp

##### Moderator
Moderator
Nov 17, 2011
13,447
Your solution is a very simplified one, assuming comparatively pure sine waveforms. Once you have peaks and troughs on your signal due to e.g. noise from a motor (washing machine, dryer...), you will see peaks higher than expected, which will result in a "pseudo" RMS computed completely wrong.

Let's start from the other end:

1) Get your signal clean. Your ADC reads show that the signal is clipped on the negative peaks of the sine. You need to get the signal into the range of the AC to avoid clipping. Since you have some headroom to the top (10bit --> max. reading = 1023), increase R2 to set the 0-reference higher. Currently it seems to be somewhere around a reading of 200 (check by short circuiting the input to the ct and take the same measurement again - where's the flat line now?). Adjust the amplítude, if necessary, by changing the value of the burden resistor.

2) Calculate "real" RMS from the samples directly. RMS is sqrt(1/T*ntegral(I²(t)dt)). Since your system is discrete in time (sampled) and amplitude (quantized), you can simplify this integral to a sum: RMS = sqrt(1/n*sum (k=1 to n)(I²(k))) where n = number of samples taken and the time for n samples should be an integer multiple of teh mains period (16.66ms at 60 Hz).
To avoid aliasing, the sampling frequency must be higher than the max. frequency component of your signal. Measuring 60 Hz and assuming (only!) 10 harmonics will give a signal spectrum from 0 Hz to 600 Hz. Your sampling frequency should therefore be at least 1.2kHz to satisfy the Nyquist-Shannon theorem (short: sampling frequency >= 2*max. signal frequency). This gives you 20 samples per cycle of a 60 Hz sine and is good for calculating an RMS.
This procedure has the advantage that it takes into account deformations of the current due to non-ideal loads. It will even display useful values for a current that is definitely non-sinusoidal, as e.g. when a traic dimmer is used (the accuracy of the method depends on the sampling rate because a dimmer will create harmonics higher than the 10th).

#### jgauthier

Mar 22, 2013
63
Harald,

That's a lot to take in. I'm going to digest this, and work on #1. I really appreciate your input, as there is a lot of stuff I have not taken into consideration. I definitely consider myself a novice in this area. My goal is to have fun and learn, so here we go...

#### jgauthier

Mar 22, 2013
63
I spent awhile and changed everything around, including some tests. Something is not right, and I'm not sure what.

First. I moved the burden resistor from 110, to 55 Ohms. This had my ADC input range from 0-3.3v. Now with 55 Ohm, it's 0-1.65V. This will allow me to offset the CT output, getting the full wave, and not overload the ADC.

I was using 47K resistors in the divider. I moved them to 1K (actually 1.1k is all I could find). I Then played around with increasing R2 (the resistor that goes to ground in the voltage divider) to 4.7K. While I was able to offset, the offsetting isn't quite right.

at a low 80w, my output looks like this:

At 400W, it's almost ideal:

But at 1200W I am clipping again:

I'm going to do some more reading about offsetting the AC signal.

#### Harald Kapp

##### Moderator
Moderator
Nov 17, 2011
13,447
Your offset now seems to be around 40 (as I said, measure offset with the input of the ct short circuited). It should be at ~512 (your range with 10 bits is 0...1023). That is why you still see clipping. But this may be a result of scaling, see nelow.
Also, at 1200 W your max. signal is 160. You obvously have some scaling in place, other wise this would mean the ADC is heavily underused. Try to get the analog pathway in order by working with unscaled output (0...1023). Once you've fixed that, you can scale teh digital words to a meaningful representation (e.g. amps(primary)).

#### duke37

Jan 9, 2011
5,364
If you are going to do complex calculations, then you could consider multiplying the current by the voltage so that power factor is taken into account and true power is obtained.

The voltage could be obtained by a low voltage transformer for isolation.

#### jgauthier

Mar 22, 2013
63
Harald> Ah, I understand.
Duke> I considered that. I read several places that use something like a 9v AC/AC converter to obtain power factor, rms voltage, etc. One thing that wasn't immediately clear is if this circuit needed to be replicated for every single circuit breaker. Is so, that is just too much circuitry, too much expense, too much wiring.

If that's something that can be obtained with just one device, then I would implement it. Buy I'm just not sure,

#### duke37

Jan 9, 2011
5,364
The voltage input will be similar for all outputs, it is the current which differs.
Thus one voltage reference would be adequate but a current transformer would be necessary for each output.

#### Harald Kapp

##### Moderator
Moderator
Nov 17, 2011
13,447
The voltage input will be similar for all outputs, it is the current which differs.
Right. If you have a fixed installation, you can use a single voltage transformer, one current transformer per load or per outlet.
If you want to make the gadget portable, you will need a voltage ransformer plus a current transformer for each device.

Thus one voltage reference would be adequate but a current transformer would be necessary for each output.

... or for each phase if you have a multiphase (3-phase) system - which is unlikely for a home installation.

#### jgauthier

Mar 22, 2013
63
Alright. First, thanks! I was out of town, and had a busy week. So I haven't had a chance to do much with this until the middle of the week. I've had some great success.
First, I resolved my DC offset issue. While I had my schematic correct, I actually did not have the physical circuit applied correctly. So, now my offset is a nice perfect 512.

I'm still messing with the true RMS calculation. I'm not sure it's quite right. With a pretty simple sin-wave I would expect this to be closer to the calculated RMS (pk * .707). I still have some more tests to do.

#### Harald Kapp

##### Moderator
Moderator
Nov 17, 2011
13,447
Have a close look at the instantnaeous values. By sampling the input chances are that you miss the absolute peak value and your samples are a bit before and after the peak. How much depends on the sampling rate vs. signal frequency.

#### jgauthier

Mar 22, 2013
63
I got this working pretty great last night. Solid output, and the wattage (RMS) calculations are pretty close to on par with my physical meter.
I am taking 80-100 samples, and the output looks like below.

I can certainly do more samples for the true RMS calculation.

#### (*steve*)

##### ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
How many samples per second are you capturing and how does that compare with the mains frequency? It looks to me like you're capturing insufficient samples.

#### jgauthier

Mar 22, 2013
63
100 samples over a period of ~200-225ms. My mains frequency is 60hz, since I'm in the US.
My thought process is that a single wave form takes 1/60th of a second (16.66ms), and I want to take samples over ~10 wave forms.

#### Harald Kapp

##### Moderator
Moderator
Nov 17, 2011
13,447
Nay
You need to sample more often. Read my post #6. Your sampling frequency should be 1.2kHz (or more). Actually you have only approx. 500Hz.
My thought process is that a single wave form takes 1/60th of a second (16.66ms), and I want to take samples over ~10 wave forms.
This thougt process is not well founded. You calculate the number of samples for a good reproduction of the input signal with respect to the fundamental frequency of the signal (60Hz), not with respect to an interval that you want to average the RMS value over. You should have at least 20 samples per 16.66ms cycle which translates to 200 samples for averaging RMS over 10 cycles of your mains frequency.

The insufficient number of samples is the reason for the crooked waveform you see.

Another point: mains frequency isn't constant. The utilities try to average the frequency such that in the long term (1 month) the average is good enough to e.g. keep mains synchronized clocks going relatively accurate. In the short term, however, mains frequency can vary considerably. Therefore it pays to measure the frequency (look for zero crossings of the input signal and measure the time in between) of the input signal and track the sampling rate such that you have a fixed number of samples per cycle, even when the cycle period changes. Otherwise you may end having 20 samples in one cycle, 21 in the next and only 19 in the one after. This will disturb your measurements.

Here is a website that offers lots of information and some tools to play with to get familiar with these concepts.

#### jgauthier

Mar 22, 2013
63
I must say, that was a complete misinterpretation on my part. That site is great, and I definitely intend to spend some time with those tools. In the meanwhile, I implemented more precise timing in my code, and I collect data for ~167ms (~10 wave forms). This is ~6000 samples, and the machine I am using (raspberry pi) is able to process this pretty quickly.

My graph looks smoother now. reviewing the data, I do see I record a '0', so I could certainly grab some time stamps and calculate the frequency from that as well, but there is some overhead when doing time calls, so I would have to be careful.

Replies
2
Views
776
Replies
1
Views
681
Replies
6
Views
2K
Replies
2
Views
1K
Replies
10
Views
2K