Home 1_Measuring Energy

1_Measuring Energy

draft: 2012-01-20, 10:30

Measuring electricity is simple. In fact, everyone already has an energy meter at home that keeps track of the total energy consumption; the one that is installed by the electricity company. Some meters feature a LED that flashes every Wh or a rotating disk with a black stripe whose speed is proportional to the current power consumption. It is possible (and has already been done (see 1 & 2) to measure at those meters and send the data to an Arduino. It is probably the most accurate technique but because not all meters are the same, it would be necessary to build a customized sensor for each meter. There also exists a different approach that measures energy usage with the help of a current transformer. Several energy monitoring manufacturers(see 3 & 4) have chosen for this technique, probably because it can be easily deployed in every home.

The functioning of a current transformer in this context can be explained as follows. It is a device that if it is clipped on a wire can measure the amount of current that flows through it. The wire must be either the live or neutral mains wire. A current transformer consists of a primary winding, a secondary winding and a magnetic core. The primary current Ip creates a magnetic field in the core which in turn induces a current Vs in the secondary winding. Although there is a small fault current, it can be stated that the current in the secondary winding is in proportion to the current that flows through the mains wire. Is = Ip / N

A open source project called OpenEnergyMonitor(5) lead by Trystan Lea and Glyn Hudson came up with a solution where this signal gets converted into something that can be measured with a microcontroller (see fig_). They place a small resistor (burden resistor) in parallel with the CT to produce a voltage proportional to the current in the mains wire. The Arduino analog input pin requires a signal with a positive voltage that lies between 0V and 5V. A voltage divider shifts up the voltage by 2.5V to allow measurement of both the negative and positive component of the waveform. The capacitor is placed to eliminate unwanted high frequency noise. To cut the costs, OpenEnergyMonitor designed a device called emonTx which is based on the Atmega328 8-bit micro-controller and is capable of taking inputs from a CT sensor. The design is fully open-source and build with hacking in mind. In this thesis, a emonTx v2.1 is used to measure the electricity usage.

Actually building it.
Some pictures were taken when building the device and together they form a pictorial build guide which can be found in appendix_ . The result of the soldering is shown in figure_ . There are a lot of open spaces left on this pcb. This is because only the parts needed to monitor one CT channel were soldered on. One of those extra features is to add a AC to AC power adapter to measure the voltage. This is omitted to make the project less complex and reduce the costs. Instead an invariable value for the voltage is chosen to calculate the amount of Watts that are used.

(-include schematic)
Atmega 328 (8-bit microcontroller)
AA battery input (3.3V power)
5V FTDI connection (used to program the device)
mini USB (used to power the device with 5V)
RFM12B (Wireless chip)

The CT that is used is a SCT-013-000 from Beijing YaoHuadechang Electronic Co.,Ltd. It can  measure current up to 100A. The datasheet can be found in appendix_

The firmware was downloaded from https://github.com/openenergymonitor/emonTxFirmware/ on 2012-01-14. At that time, the emonTx was still in development but it already worked great. Only some minor changes to the code had to be made with Arduino 1.0 IDE. Everything was uploaded using a 5V FTDI cable.


|_ _|
___ _ __ ___ ___ _ __ | |_ __
/ _ \ '_ ` _ \ / _ \| '_ \| \ \/ /
| __/ | | | | | (_) | | | | |> <
\___|_| |_| |_|\___/|_| |_\_/_/\_\
// Single CT wireless node example
// Includes watchdog incase it crashes

// Based on JeeLabs RF12 library - now called ports
// 2009-02-13 http://opensource.org/licenses/mit-license.php

// By Glyn Hudson and Trystan Lea
// openenergymonitor.org
// http://openenergymonitor.org/emon/license

// using CT port 2 - middle jackplug


#include //https://github.com/jcw/jeelib
#include //cyclic redundancy check

ISR(WDT_vect) { Sleepy::watchdogEvent(); } // interrupt handler: has to be defined because we're using the watchdog for low-power waiting

// Serial print settings -
#define DEBUG

// RF12 settings
// fixed RF12 settings

#define myNodeID 10 // in the range 1-30
#define network 210 // default network group (can be in the range 1-250). All nodes required to communicate together must be on the same network group
#define freq RF12_433MHZ // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.

// set the sync mode to 2 if the fuses are still the Arduino default
// mode 3 (full powerdown) can only be used with 258 CK startup fuses

#define COLLECT 0x20 // collect mode, i.e. pass incoming without sending acks

// CT energy monitor setup definitions
int CT_INPUT_PIN = 0; // I/O analogue 3 = emonTx CT2 channel. Change to analogue 0 for emonTx CT1 chnnel
int NUMBER_OF_SAMPLES = 1480; // The period (one wavelength) of mains 50Hz is 20ms. Each samples was measured to take 0.188ms. This meas that 106.4 samples/wavelength are possible. 1480 samples takes 280.14ms which is 14 wavelengths.
int RMS_VOLTAGE = 240; // Assumed supply voltage (230V in UK). Tolerance: +10%-6%
int CT_BURDEN_RESISTOR = 15; // value in ohms of burden resistor R3 and R6
int CT_TURNS = 1500; // number of turns in CT sensor. 1500 is the vaue of the efergy CT

double CAL=1.295000139; // *calibration coefficient* IMPORTANT - each monitor must be calibrated for maximum accuracy. See step 4 http://openenergymonitor.org/emon/node/58. Set to 1.295 for Seedstudio 100A current output CT (included in emonTx V2.0 kit)

// LED Indicator
# define LEDpin 9 //hardwired on emonTx PCB

// Data structure for sending emontx data via RF
typedef struct { int power, battery; } PayloadTX;
PayloadTX emontx;

void setup() {
pinMode(LEDpin, OUTPUT);
digitalWrite(LEDpin, HIGH); //turn on LED

Serial.println("emonTx single CT example");


// RFM12B Initialize
rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
rf12_sleep(RF12_SLEEP); // Put the RFM12 to sleep - Note: This RF12 sleep interupt method might not be 100% reliable. Put RF to sleep: RFM12B module can be kept off while not used – saving roughly 15 mA

Serial.print("Node: ");
Serial.print(" Freq: ");
if (freq == RF12_433MHZ) Serial.print("433Mhz");
if (freq == RF12_868MHZ) Serial.print("868Mhz");
if (freq == RF12_915MHZ) Serial.print("915Mhz");
Serial.print(" Network: ");
#ifndef DEBUG
Serial.println("serial disabled");

digitalWrite(LEDpin, LOW); //turn off LED

wdt_enable(WDTO_8S); //enable crash watchdog

void loop()

// 1. Read current supply voltage and get current CT energy monitoring reading
emontx.battery = readVcc(); //read emontx supply voltage
emontx.power = int(emon( CT_INPUT_PIN, CAL, RMS_VOLTAGE, NUMBER_OF_SAMPLES, CT_BURDEN_RESISTOR, CT_TURNS, emontx.battery));

// 2. Send data via RF, see: http://jeelabs.net/projects/cafe/wiki/RF12 for library documentation
rf12_sleep(RF12_WAKEUP); // wake up RF module
int i = 0; while (!rf12_canSend() && i 3300 ) {//if emonTx is powered by 5V usb power supply (going through 3.3V voltage reg) then don't go to sleep
for (int i=0; i } else {
//if battery voltage drops below 2.7V then enter battery conservation mode (sleep for 60s in between readings) (need to fine tune this value)
if ( (emontx.battery) < 2700) Sleepy::loseSomeTime(60000); else Sleepy::loseSomeTime(5000);


// Read current emonTx battery voltage - not main supplyV!
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH< result = 1126400L / result; // Back-calculate AVcc in mV
return result;

together with emon.ino :

int lastSampleI,sampleI; // Sample variables
double lastFilteredI =0 ,filteredI = 0; // Filter variables
double sqI = 0,sumI = 0; // Power calculation variables

for (int n = 0; n < NUMBER_OF_SAMPLES; n++)
lastSampleI = sampleI;
sampleI = analogRead( CT_INPUT_PIN );
lastFilteredI = filteredI;
filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);

// Root-mean-square method current
// 1) square current values
sqI = filteredI * filteredI;
// 2) sum
sumI += sqI;
double I_RATIO = (( CT_TURNS / CT_BURDEN_RESISTOR ) * (SUPPLY_VOLTAGE/1000.0)) / 1024.0; // Rough calibration by component values
I_RATIO = I_RATIO * ICAL; // Fine adjustment calibration for accuracy

double Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES); // Final step in calculation of RMS CURRENT
sumI = 0; // Reset sum ready for next run.

double apparentPower = RMS_VOLTAGE * Irms; // Apparent power calculation
return apparentPower;

1: http://community.pachube.com/node/65
2: http://blog.richard.parker.name/2009/04/25/how-to-build-a-web-connected-gas-meter-with-your-arduino
3: http://www.currentcost.com
4: http://www.efergy.com
5: http://openenergymonitor.org

ref: http://en.wikipedia.org/wiki/Current_transformer

1 comment

emonTx v2.1 (single CT) pictorial build guide | Stijn Coppens Labs Januari 20, 2012 at 2:06 pm

[…] about it can be found on their website. Why I use it in my thesis and how it works can be found here. Components needed to build an emonTx with one […]


Leave a Comment