Projects‎ > ‎

Energy monitor


Wanting a way to monitor and graph our home electricity consumption was a good excuse to build an AVR based energy usage logger. For simplicity, I chose to count indicator pulses from the existing supply meter using a phototransistor, and send results wirelessly to an existing web server over an XBee link every 5 minutes.

I gave myself a design brief of achieving at least one year run time on 3xAA cells, so had to pay close attention to the power drawn by the circuit. For a  project of this nature, the hardware would spend 99.99% percent of it's time in sleep mode, so I was looking primarily for the lowest quiescent current I could manage. This seemed to rule out all the switching regulators I looked at, so I opted for an LDO linear regulator to power the AVR and the XBee (I couldn't run directly off the batteries, as this would be over the maximum input voltage for the XBee module). I decided on a regulator output of 3v to give a little more headroom with battery life.

For the AVR, I chose the ATMEGA88PA, as the 48/88/268/328 is a chip family I've used it in the majority of my microcontroller projects. In keeping with the low power considerations, I chose to use the internal oscillator as the clock source, but also to use a 32.768kHz crystal to calibrate the oscillator before each wireless transmission, and to provide a timer source when the AVR is in power save mode.

Initial prototype

The initial schematic design was done with paper and pencil, and the prototype was built up on stripboard.

The prototype used a Maxim MAX604 linear regulator, as I had a couple of free samples lying about in DIP footprint. These can supply 500mA, and claim a typical quiescent current of around 15uA.

The logger initially used an XBee Pro module with integrated chip antenna, but due to range issues this later replaced by a module with a U.FL connector, and a small 2.2dBi external omnidirectional antenna (not shown).

The photodiode was mounted through a piece of scrap plastic, and positioned in front of the LED on the meter. A short length of heat shrink tubing helps ensure it's only reading the LED and not any ambient light when the meter cupboard is opened.

At the time of writing (late 2011), this prototype has been running for just over 2 years. Curious as to how the original batteries were holding up, I imported the data into a spreadsheet. This showed the voltage had only dropped about 0.3v over the this time (see graph below). It was interesting to note the increased drops in voltage over the winter months. Am unsure whether this is because of the increased wakeup rate (higher energy usage resulting in a higher number of pulses from the meter), or the colder temperatures?

SMD redesign

Earlier this year we had a ground source heat pump installed, with a separate meter to get a better idea of the running costs. Needing another energy monitor to report on this additional meter, it seemed like a good time to try my hand at an SMD board.

This design used an ATMEGA168PA in a 0.8mm pitch TQFP footprint. (As for some reason, the 168 was cheaper to buy than the 88).

I chose to use a Microchip MCP1700 LDO regulator in a SOT-89 footprint. These claim a typical quiescent current of 1.6uA, but are only rated for 250mA continuous output current.

Note: I had wondered whether heat dissipation in the smaller linear regulator could be an issue at higher current draws, but the only component that draws a significant amount of power is the XBee module. The standard module draws 45mA, and the Pro draws 215mA when transmitting. This design only transmits for a couple of milliseconds at a time and the LDO doesn't feel warm to the touch at all.

Battery state is monitored through a voltage divider, fed into an AVR ADC input. This circuit uses 470K/680K resistors in order to reduce the current drain, which are a higher impedance than would normally be suitable for the ADC input (nominally 10K). To support this configuration, a small 10nF capacitor provides the necessary current for the ADC input during sampling. An alternative approach would be enable a lower value resistor divider with a high side switch while sampling, but the existing circuit reduces the current leakage to a few uA.

Note: The main supply meter briefly pulses the indicator LED, but the reconditioned meter we used for the heat pump has a 50% duty cycle on the indicator. Because of this, current will flow through the phototransitor 50% of the time, but because of the high value of the load resistor, this will only be a couple of uA.

The overall quiescent current of the populated board (with no current flowing through the phototransitor) has been measured at 7uA.

Schematic capture and board layout

Schematic capture and board layout was done with KiCad. Since the initial prototype was made, I've used KiCad for other projects, but this would be my first SMD board.

Looking at the default libraries, I wasn't 100% happy with the SMD component footprints, so I took the plunge and created my own component and footprint libraries. For the footprint dimensions, I checked out various other online sources looking for consensus. Populating the board, the chosen footprints worked well for hand soldering.

TODO: Push the KiCad libraries to github & provide a link

Board manufacture

I had 10 boards made using the Seeed Studio Fusion service, and am happy with the results. The boards were sized to match the 3xAA cell battery holders, which unfortunately took them just over the cheapest 5x5cm option. They're a reasonably good match to the battery holders, but are a few mm out on the top edge - so that's on the list to fix in a future revision (if there is one).

I actually got 12 boards back - have no idea how I'll use them all! (Anticipating the spare boards, I'd added some additional headers on unused pins, which may make them more useful for future prototyping).


This was my first SMD soldering experience (other than a little bit of rework), but it seemed to go incredibly smoothly. Thanks no doubt to the various online tutorials, and lashings of flux ;) In fact, the biggest issue I had was lining up the individual pin headers I'd added for test points. After I was finished, I realised this would be an ideal use for some of the spare boards, as they would make a great jig for holding the headers in place.

The battery holder terminals were soldered through the board, and a dab of hot glue added to avoid any strain on the joints.

Just like the prototype meter, the photodiode was mounted through a piece of scrap plastic, and positioned in front of the LED with a length of heat shrink tubing to help block out any ambient light. I did find that the LED on this (refurbished) meter was dimmer than others I'd seen, so the load resistor was changed from 680K to 1M to ensure a logic low level at the INT0 pin.

BOM Costs

I made a rough attempt at working out the costs. Some figures are accurate from invoices, and some are just estimates (I split the difference between XBee Standard and XBee Pro pricing).

I like using the XBee's, but they really bump up the price (in fact everything about XBee's is expensive, even the 2mm pin headers!).

Part Qty Unit cost Total £

Xbee module 1 £20.00 £20.00
Enclosure 1 £4.50 £4.50
Xbee headers 2 £1.38 £2.76
PCB 1 £2.00 £2.00
ATMEGA168PA 1 £1.80 £1.80
Crystal 1 £0.71 £0.71
Battery holder 1 £0.64 £0.64
Misc connectors 1 £0.50 £0.50
Photo-transistor 1 £0.40 £0.40
Regulator 1 £0.28 £0.28
LEDs 2 £0.07 £0.14
Schottky 1 £0.09 £0.09
Capacitors 9 £0.01 £0.09
Inductor 1 £0.08 £0.08
Resistors 6 £0.01 £0.06

TOTAL £34.05


An external interrupt (INT0) is used to wake the AVR and increment a pulse count when the phototransitor output is pulled low.

An 8-bit timer (TIMER2) is clocked asynchronously from a 32.768kHz watch crystal, and is used to wake the AVR every 5 seconds.

Every 5 mins (300 timer ticks) a summary of the collected data is transmitted over the serial port (and over the XBee link to the central web server). Because the internal oscillator is generally not accurate enough for serial comms over a wide temperature range, it is calibrated against the watch crystal before every transmission.

To save power, the AVR is put into PWR_SAVE mode while waiting for the ISRs to fire. Also all unused pins are set as inputs with pullup resistors enabled to avoid floating pins. The XBee module is normally switched into hibernate mode, and only woken for the duration of the transmit routines.

Note: It's worth documenting that the datasheet says this AVR cannot be woken from power save mode by an edge triggered external interrupt. (The correct method would be to use a pin change interrupt, and check the level in the ISR). However, I'd implemented this code on several prototypes before I noticed the datasheet said it wasn't possible ;) Testing shows that it does not work on non-picopower devices from this series, but every picopower device I've tried has worked fine for me, ymmv.


All source code, schematics, and pcb design files can be found in the git repository

The source code is released under an MIT license, schematic and pcb files are released under a Creative Commons Attribution ShareAlike license.