OverviewWanting 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 prototypeThe 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
|
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 |
Firmware
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.
Links
All source code, schematics, and pcb design files can be found in the git repository https://github.com/dresco/PowerMeter
The source code is released under an MIT license, schematic and pcb files are released under a Creative Commons Attribution ShareAlike license.