While working on the experiments I’ve done in the past months with the Arduino Duemilanove, RBBB, XBee Series 1 and 2 modules the thought of a wireless, battery powered, ‘intelligent’ sensor kept me busy.
Finally the time had come to do some experiments in that direction. I’ve found several very well written articles, all by Jean-Claude Wippler regarding Low-power techniques. This was a very good starting point; one of the things that i concluded is that running on 3.3V is the best choice: it seems it’s much easier to interface with sensors at 3.3V then 5V. So i really gotta have me some JeeNodes soon now! 🙂
But it wouldn’t hurt to already start searching the net for code that would support bringing the ATMega to a state in which it would consume much less power. I had already found a way to bring an XBee module to deep sleep by setting Sleep Mode (SM) to 1 and grounding pin 9, so now it was time to start sketching and produce something that could put both the RBBB and the attached XBee to sleep for a fixed period, wake them up, take samples of whatever sensor is attached, send the data to the Zigbee Coordinator and go back to sleep again. I didn’t want to use any external trigger, so the solution had to be found inside the MCU itself.
Putting XBee to sleep
First i wrote a sketch that periodically woke up the XBee, send some data and put the XBee back to sleep. That shouldn’t be that hard. How wrong could i be….
The job to do comes down to the following sequence:
- wake up the XBee (use a Digital Output from the RBBB to set XBee pin 9 low);
- wait for the XBee to be ready (CTS pin to go low);
- send some dummy data;
- wait a little more and put the XBee back to sleep (set XBee pin 9 back to high);
- delay the loop for a number of seconds.
At first run all worked fine. However, after increasing the interval at which the job listed above were to be executed, i started losing packets. Because i enclosed a counter value into the sent data, i could see a very strange behavior: depending on the interval i saw packets coming only once every 2 or 3 times a packet was sent… What’s that?? By playing around with the interval i could determine that something strange was happening when the interval was set above 5 seconds. Why ? It took me some time to figure this out.
I remembered the 5 seconds to be the default value for the “Time Before Sleep” (ST) Command. But this Command and the value set, are only applicable for Cyclic Sleep End Devices. And indeed, changing the Time Before Sleep didn’t make things better. OK, so now it was time to start reading the manual really well 🙂
And there it was: the “Child Poll Timeout” must be what is bugging me. This is what the manual has to say about Child Poll Timeout:
“Router and coordinator devices maintain a timestamp for each end device child indicating when the end device sent its last poll request to check for buffered data packets. If an end device does not send a poll request to its parent for a certain period of time, the parent will assume the end device has moved out of range and will remove the end device from its child table. This allows routers and coordinators to be responsive to changing network conditions.”
So, if an End Device doesn’t let it’s parent (= Router, Coordinator) know that it’s still there from time to time, the End Device will be thrown out of the PAN, and has to start joining all over again; which takes a relatively long time, which it doesn’t really have being powered down all the time..
Increasing the value for the Child Poll Timeout on the Coordinator (to a higher value then the minimum of 5 seconds) resolved everything.
On to the next ‘easy’ job; using the ATMega328 Watchdog Timer to put the RBBB to sleep 🙂