DIY Real time mains power meter

From DIYWiki
Jump to navigation Jump to search

If you have rather fancied the nifty "in house" real time power use monitors that come with some "smart" meters, but don't fancy the rest of the smart meter, this simple project will get you some of the same functionality.

Rough and ready

A basic clamp meter that can measure the current passing through a wire that is passing through the jaws of the meter. (the probes are not required for AC current measurements using the clamp).

A quick "rough and ready" estimate of your power use can be obtained with a digital "clamp" meter. This will make a "non contact" reading of the current passing through a wire. So if you clamp it round of the "tails" that connect your electricity meter to your Consumer Unit (CU), you will get a reading of the current flowing at that moment. Multiple that number by your mains voltage (typically 240V), and you will have a an indication of the total power in watts being used.

Now this may be all you need, however there are a couple of sources of inaccuracy in this approach. To assess the actual power being used, you need to know the actual voltage as well as the current, so ideally we need to measure this rather than just assume it is 240V since not only will each property likely vary a little from the "normal" voltage anyway, it will fluctuate throughout the day as the load on the supply changes.

The second source of error is that the multiple of volts and amps when dealing with AC rather than DC, does not actually get you Watts, but "Volt Amps" or "VA". The VA reading is the total "apparent power" being used. This may be different from the real power being actually consumed because some part of the electrical load may be "reactive" - i.e. it stores some energy on part of the mains cycle, but then releases it later. This means not all of the current you can measure amounts to energy you need to pay for. See the article on power factor for a fuller explanation of this.

Depending on what you need to know, this may or may not matter. For knowing what size cables are required for a given load or what size UPS is required to keep your computer running during a power cut, the VA is the more useful number, since you need to know how many amps you need to allow for. For working out your energy use or costs, you will need the real power consumption in Watts and not the VA, since domestic electricity meters only charge for the real power consumed.

Design

This project was a simple "proof of concept" to see how well the monitor would work. (It may be followed by a multi channel mains power consumption meter with data logging, but that is for later!). So we need a way to measure the real time mains voltage, and the real time current consumption. This needs to be done in a safe and easy way that does not require wiring into the electrical system.

Using a 9V or 12V AC/AC mains power adaptor (basically a small transformer, in a box with a plug on it, and if we are lucky a thermal fuse), allows gives a low voltage supply that we can measure the voltage of. Power supplies with an AC output are less common than the typical DC ones, but were commonly used with many "dial up" modems, so there is a fair chance there is one stuffed in a drawer somewhere. We need a clip on current transformer to act as our clamp meter, and let us measure the current in the meter tail feeding the CU. Lastly we need a small amount of computing power to collect the voltage and current readings, do some number crunching, and send out the information we need to a local display. For this I used a Aruino "nano" clone, and a 16x2 line LCD display with back light.

Circuit and theory of operation

Circuit diagram for the basic energy monitor

Reading the mains voltage

The AC adaptor will give us a low voltage supply that we can measure. To do this we need to first capture the output from it with an Analogue to Digital Converter (ADC). The ADC channels on the Arduino can measure any analogue voltage between 0V and the supply voltage (typically 5V), and digitize with 10 bits of resolution.

We can't use the output from the adaptor directly, because the peak voltage will exceed the maximum the ADC can read, and there is also a negative component of the waveform which will be below the minimum level for the ADC. So we need to do some conditioning first. There are two parts to this. Compressing the voltage to a smaller range, and adding a constant DC bias to it so that we never see a negative going component to it.

First we need to scale down the voltage range. A 9V AC transformer will give 9V RMS when under some load. Without any load the voltage will tend to rise a bit. So to be on the safe side we shall assume it could be 20% more than the nominal 9V. We also need to allow for the mains voltage to be higher than the nominal 240V. The upper limit is normally taken as 230V + 10%. Lastly the specified voltage is the RMS (i.e. the DC equivalent) voltage, we need to know the full range of values that our ADC will see. This will be the "peak to peak" voltage. So to find the max output due to a high mains input:

Allow for 20% voltage rise on unloaded transformer:

Now convert that to its peak value:

Then just to be on the safe side we should assume that the Arduino may be running at the lower end of its typical supply voltage of 4.8V, restricting the total range of the ADC a bit. So R6 and R7 act as a potential divider that will scale the voltage so that the peak voltage is:

C2 will create an AC path to the Arduino's ground reference. R4 and R5 form a second potential divider, that will add a bias of half the Arduino's supply voltage to the ground referenced side of the transformer's output. So the ADC should see a voltage waveform that can swing between i.e. between approx 1.5 to 3.5V

Reading the mains current

A YHDO SCT 013 Current Transformer. Shown here with a test wire looped through it several times. This multiplies the current seen by the transformer by the number of turns, so it is a handy way to check readings at much higher loads.

The current is sensed by a YHDO SCT 013 current transformer with a 100A maximum reading. These are available in forms that at the full 100A reading will either generate a 50mA current output, or 1V output voltage output. The difference is that the voltage output type includes an internal burden resistor across the output of the transformer's secondary coil, to allow the meter to read a voltage directly. My one was a voltage output type, however to get a bit more resolution from it, I opened it and removed the internal burden resistor, so that I could turn it into the current output version,and then use my own burden resistor to scale the output to better match my ADS range. We also have one of the same problems we had with the voltage input - that the waveform we will see is bipolar with a negative going part of each cycle. So R1 at 33 Ohms will show a potential difference across it of:

Handy current monitor test lead. It allows access to the individual cores to make clamp meter readings (if you try to take a reading on a flex, it will see matched current flowing in both directions (on live and neutral), and decide the net current is zero!

R2 + R3 act as a potential divider and add a bias of half the Arduino supply voltage to side of the transformer coupled to the Arduino earth reference by C1.

For safety, the current transformer and single-insulated mains wires should be fitted into an enclosure with appropriate strain relief glands, etc.

That is all the electronics dealt with.

Building it

Final version built (the software still needs a tweak here - the power should not be larger than the VA reading!)

The first build was quickly put together on a breadboard, and some measurements made of the scaled and biased current and voltage readings to check they were within the required range. I used a 1/2kW fan heater as a dummy load, and then tested higher currents by looping extra turns of the supply wire through the current transformer to make it see a higher current.

(Note on safety, current transformers without an internal burden resistor can generate a high touch voltage on the secondary if they are not terminated into some kind of load. The particular unit chosen however does include circuitry to limit this, so the fact that it presents its output on a 3.5mm jack plug does not pose a risk)

Once happy with the component values selected, I drew up the circuit diagram in KiCad, and then built a neater version on some stripboard. The display selected was a standard 16x2 line LCD with back light, however it also had an I²C interface adaptor on the back that means you only need power plus serial data and clock, rather than a 6 or 10 wire parallel connection. We are not short of spare IO pins here, but less connecting wires to get into the project case would be nice!

Assembled and cased up

Moving to a stripboard, ought to be easy, but in this case I found I was getting very odd looking readings. After spending some considerable time checking it against the circuit diagram, buzzing out connections and checking component values, I could not find anything wrong, there were no errors in the construction, and it matched the circuit diagram faithfully. However it was almost like the current and voltage readings were transposed since the voltage seemed to rise with load, the current was showing a steady 85A almost regardless of load, but the power figure looked about ok.

Then penny dropped... when drawing out the circuit I initially placed both transformers on the right of the circuit diagram, before deciding that it looked a bit cluttered. So I moved the CT to the left. The only problem with that was it then put an unwanted crossover in the ADC lines. Hence I swapped them in the design. Alas not in the software which was built for the breadboard version of the layout. One very simple code change later and it works.

Monitoring the whole house, at a fairly quiet time, so most load will be comprised of electronics including IT kit, and low energy lighting. So a relatively low 0.8pf, with 973VA, and 803W.

I had a small plastic protect case, which was just about big enough to get the LCD in (if I snipped off most of the connection pins on the back of the LCD adaptor board, and soldered the wires direct to the stumps!)

I cut out a rectangle in the face with a small saw blade in a multitool, and fixed things in place with hot glue. The LCD and the circuit board almost meet each other top to bottom when in the case, so I added some insulating tape as a shield between them before doing up the two halves.

Software

The software for this is very simple, since all of the more complicated real time capture of the voltage and current waveforms is handled by the EmonLib library. This takes care of reading the ADCs, adjusting for the slight time delay between reads (that will show up in a slight phase measurement error), filtering out the DC bias from the readings introduced by the electronics etc. (unlike making a reading with a multimeter, the software is not going to be able to read a single stable voltage indicating the instant voltage or current - it will need to sample the waveform at high speed for a number of mains cycles, to be able to capture enough information to work with).

So the setup function initialises the LCD, and tells the emon lib which pins are hooked up to the voltage and current sources. You also need to supply some calibration constants. You may need to tweak these to account for different current transformers or burden resistors. You can either work out the values from first principles or can take the more empirical approach of making measurements with a multimeter, and then tuning the calibration values to make the software readings match the measured ones.

A worthwhile refinement might be to add a rotary encoder, to allow the calibration values to be tuned while running rather than pre-set at compile time.

The Code

/**
 * Basic energy monitor
 * 
 * This is a very simple energy monitor designed to report the instanatneous 
 * main RMS Voltage, Current, Power consumption (real and apparent) and
 * calculate the power factor.
 * 
 * The results are updated periodically on a 16x2 line backlit LCD display connected 
 * via an i2c bus.
 * 
 * Based on code from:
 * 
 * EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3
 * 
 * Version History
 * ===============
 * V 1.0    Nov 2022    J Rumm    First release
 * 
 */



#include <LCD_I2C.h>            // Replacement of LiquidCrystal library with i2c varient
#include "EmonLib.h"            // Include Emon Library

LCD_I2C lcd( 0x27 );
EnergyMonitor emon;      


void setup()
{  
  // Initialise LCD
  lcd.begin();
  lcd.backlight();
  lcd.clear();

  // Set calibration parameters. For detail see:
  
  // https://learn.openenergymonitor.org/electricity-monitoring/ctac/ct-and-ac-power-adaptor-installation-and-calibration-theory
  
  emon.voltage(2, 239.0, 1.7);  // Voltage: input pin, calibration, phase_shift (Adjust to 188.5 for 12V adaptor)
  emon.current(1, 65.0);        // Current: input pin, calibration.
}


void loop()
{
  char topline[20] ;
  char botline[20] ;
  char volts[10];
  char amps[10];
  char watts[10];
  char va[10];
  char pf[10];

  emon.calcVI( 20, 2000 );         // Calculate all. No.of half wavelengths (crossings), time-out

  // Format results into C style strings (Arduino/avr version of sprintf does not handle floating point conversions)
  dtostrf( emon.Vrms, 3, 0, volts );
  dtostrf( emon.Irms, 3, 2, amps );
  dtostrf( emon.realPower, 0, 0, watts );
  dtostrf( emon.powerFactor, 0, 1, pf );
  dtostrf( emon.apparentPower, 0, 0, va );

  sprintf( topline, "%sV %sA %spf", volts, amps, pf );
  sprintf( botline, "%sW %sVA  ", watts, va );
  
  lcd.setCursor(0,0);
  lcd.print( topline );
  lcd.setCursor(0,1);
  lcd.print( botline );

  delay( 1000 );
}