The result was a device which lasts almost a month when it reports temperature once an hour over XBee and is powered by 1000mAh LiPo battery.
The most interesting parts of the code are probably the power saving functions
procedure Put_XBee_To_Sleep is begin AVR.MCU.PortC_Bits (0) := True; end Put_XBee_To_Sleep; ... loop -- Read temperature ... Put_XBee_To_Sleep; Sleeper.Init; Sleeper.Sleep (Seconds => Unsigned_16 (Wait_Time)); Sleeper.Wake_Up; Wake_Up_XBee; end loop;
The suspend/sleep pin of XBee is connected to A0 pin of Arduino (Port C0 on atmega328p). Turning the port high puts XBee into sleep mode so it consumes less power. And as expected, setting the port low wakes up the XBee.
The processor is put to sleep using the Sleeper package from my previous power article.
The communication is handled by a pair of XBee devices. On the temperature sensor, I have XBee Series 2 device configured as a router and, on the other end the XBee is configured as a central device.
The central device is connected to Olinuxino-imx233-maxi via XBee USB explorer. On Olinuxino, I run Debian armel and have a simple Python script which listens USB serial console for temperature data.
import serial import time import sys port = "/dev/ttyUSB0" if len(sys.argv) > 1: port = sys.argv f = open('temperatures.txt','a') ser = serial.Serial(port, 9600) while True: line = ser.readline() t = time.asctime(time.localtime()) s = "%s: %s" % (t,line[:-1]) f.write(s) f.write('\n') f.flush() print s time.sleep(1)
The Olinuxino-imx233-maxi inside a Sparkfun case:
With some holes:
It was nice to see that you can create an AVR device which runs about 4 weeks on a single battery. Of course, in my setup, I reported the temperature only once per hour. Doing it more often would drain the battery more.
The source code is available at bitbucket.org/tkoskine/arduino-blog as usual.