The power of Arduino and Zigbee

Today i had some spare time to combine a few of the things i’ve been working on lately:

  • My Zigbee API;
  • Arduino;
  • Pan & Tilt mechanism

I wanted to create a small executable that would enable me to control the position of the 2 servo’s.

XBee module

I started with programming the XBee: Zigbee End Device AT firmware, the right PAN, Node Identifier ED5 (as in End Device 5), Sleep Mode=1 (Pin Hibernate). I put the module on a breadboard by use of a Breakout Board. Grounded pin 9 and used the 3.3V output of the Arduino to power the module.


I strapped the Arduino Duemilanove to the same breadboard and wired the 2 servo’s. Pins 9 and 10 of the Arduino are used as PWM output for the 2 servo’s. Arduino pins 2 & 3 were connected to the DIN and DOUT pins of the XBee module.


Now it was time to write a sketch that would receive commands from the XBee and move the servo’s accordingly. The sketch is a real quick and dirty one, low on error handling and validation. I made up a small ‘protocol’: commands have to end with the exclamation mark (“!”) and can be either 1 or 2 characters long.

P+! would Pan right 3 degrees, P-! would Pan left 3 degrees, T+! would Tilt up 3 degrees and so on. H! is the command to go back to the Home position. Of course you can extend this as much as you like, e.g. add absolute positioning, presets, you name it.

This is the sketch:

#include <NewSoftSerial.h>
#include <ServoTimer1.h>
#include <PString.h>

ServoTimer1 PanServo;
ServoTimer1 TiltServo;

int PanAngle = 90;
int TiltAngle = 90;
byte DeltaPan = 3;         // move 3 degrees
byte DeltaTilt = 3;        // move 3 degrees
char cbuffer[40] = "";     // receive buffer
NewSoftSerial XBSerial = NewSoftSerial(2, 3);
PString buffer(cbuffer, sizeof(cbuffer));

void setup() {

  XBSerial.begin(9600);         // set up XBee at 9600 bps
  delay(10000);                 // wait 10 sec. for possible joining



void waitforcommand()
  while (true)
    if (XBSerial.available())
      int c =;
      if (c == 0x21)     // command terminator = "!"
        // add to buffer

void loop() {


  // what's the first character?
  switch (buffer[0])
    case 0x50:             // P for Pan
        // what's the next character?
        switch (buffer[1])
          case 0x2B:       // +
            PanAngle += DeltaPan;

          case 0x2D:       // -
            PanAngle -= DeltaPan;
    case 0x54:            // T for Tilt
        // what's the next character?
        switch (buffer[1])
          case 0x2B:       // +
            TiltAngle += DeltaTilt;

          case 0x2D:       // -
            TiltAngle -= DeltaTilt;
    case 0x48:            // H for Home


  // check boundaries for Pan
  PanAngle=(PanAngle < 0)?0:PanAngle;
  PanAngle=(PanAngle > 180)?180:PanAngle;

  // check boundaries for Tilt
  TiltAngle=(TiltAngle < 90)?90:TiltAngle;
  TiltAngle=(TiltAngle > 180)?180:TiltAngle;

  // Set dervo's accordingly


PC software

Next item was a small program that would use the API to address the XBee module.

XBee servo control

XBee servo control

4  buttons for Left, Rigth, Up and Down, a Home button and a button to connect to the Zigbee network. Not very spectacular, I’d say.

There are 2 important API functions that are used to communicate with the Zigbee module:

  • Node Discovery
  • XBee Transmit Request.

The code that is executed when the “Connect” button is pressed, sends out a Node Discovery command. This will trigger all joined Zigbee modules to respond with information about themselves, like 16- and 64-bit address, node identifier and some more interesting stuff. The code goes something like this:


The Node Identifier is used to see if the Zigbee module that is connected to the Arduino, is “in the air”. Cause it doesn’t have to be, it could be disconnected from power or whatever…

When the Zigbee module with Node Identifier “”ED5” has responded, the 5 buttons are enabled and clicking them will move the servo’s. This is done with the XBee Transmit Request function; a string is being sent to the XBee and the XBee will take care of transferring it out on the UART.  Below the code for the “Home” button:

if i >=0
then begin
Module := TXBeeModule(gXBeeModules.Objects[i]);
Addr16:= Module.Addr16 ;
Addr64:= Module.Addr64 ;

Et voila, the servo’s start moving!

To see how (good or bad) it works, i’ve made a small video.
The power of Arduino and Zigbee!!!

ATMega328 and its Watchdog Timer

Now that i managed to put an XBee ZB module to sleep, all i had left to do was being able to put the RBBB to sleep for a certain amount of time (and have it wake up again!).  It would be very nice if i could use 2 triggers for waking up the controller: based on a predefined interval and by some external source (for example an attached motion detector that detects motion).

Zigbee module

Low-power Zigbee & Arduino

Both are actually equally important, so i tossed a coin with the outcome that i started with trying to accomplish to wake up the RBBB on a predefined interval. I found an article that pretty much did what i wanted. The maximum time that the Watchdog Timer can power down the microcontroller is 8 seconds, after which it will wake up again and carry on with it’s job. I modified some things so that the power down routine is called multiple times, which results in a power down mode in multples of 8 seconds. Currently the wake up interval is set at 32 (4*8) seconds and it has run flawlessly for 16 hours now. I still have to dig in deeper to the Watchdog code see if my ‘modifications’ can be made more efficient, but for now this will be OK.

Now i wonder what the power consumption of this combination of RBBB and Zigbee module is… should i let it run on a battery and wait till it stops? How long will that be…. no; i think it’s better to find a way to estimate battery life by actually measuring the power consumption. That will probably mean i will need extra hardware and tools.

Sleepy Arduino and Zigbee

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.

RBBB controlling a XBee ZB module

RBBB controlling a XBee ZB module

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.

Sleeping XBee

Sleeping XBee

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 🙂

Testing Zigbee, Arduino and Domotica interface

This weekend i’ve been working on a setup to be able to test various things with the exciting Digi XBee modules that i’ve purchased some time ago.

XBee ZB modules and a RBBB

XBee ZB modules and a RBBB

As you can see there are 2 different types of XBee modules placed on the breadboard; there are 3 (a bit smaller) XBee Series 2 modules and 3 (larger) XBee-PRO modules. I also included an RBBB, a very small Arduino compatible device, that is located on the lower half of the board and is connected to the 6th XBee module. On the lower right side of the board there’s a 3.3V regulator to power the XBee modules.

First thing that had to be done was programming the upper row of 5 Digi XBee modules with the right firmware to let them all act as a End Device in AT/Transparent mode, and do some wiring. The XBee breakout board had already been soldered some time ago. I also added some LEDs for visualizing the status of the modules. After that, it was time do do some testing of my Domotica software to interface with these modules. Commands like “IS” for sampling the Digital/Analog IO ports on the modules. Here the first problem came up; the command did execute correctly cause i got a response back, but the payload of the frame was empty.. of course, after some time i realized i forgot to enable any of the I/O on the modules… 🙁

Next command on the list was the ZigBee Transmit Request Command. This command is used for sending data to a module where it will be sent to the UART. This way it will arrive at the device that is attached to the XBee, in my case the RBBB. This allows me to communicate with the Arduino wirelessly. All worked well, i got the right responses back and i saw data arriving on the RBBB.

Now it was time to start sending data from the RBBB to my Domotica system. Here the default sleep mode of the Zigbee took some time to resolve. The first sketch for the RBBB sent some text to the XBee every 15 seconds. But this only arrived on my PC once every 2 minutes or so… and i didn’t know why. Changing the sketch and now sending the same text every second, made the problem go away… Suddenly i realized is was the default sleep mode that was bugging me! The default sleep mode for an XBee with this firmware is “Cyclic Sleep”, which means the module is only awake periodically. Ofcourse, sending data to the UART of a sleeping XBee doesn’t work… I tried to change Sleep mode to 0 (“always awake”) but that’s not even supported! Hmm, fortunately there’s a workaround for this: set sleep mode to 1 (“Pin Hibernate”), ground Pin 9 (the yellow wire in the picture does that) and you’re done. While trying to change the sleep mode on a specific module the use of the LED really payed off, cause suddenly the LED for the wrong module went off.. it seemed i had addressed the wrong module with the Sleep mode set to Pin Hibernate command. Typically a case of where you can keep on searching for hours and hours why it’s not working as expected, and all you did wrong was addressing the wrong module…

Now i have a sketch running on the RBBB that transmits a small text every 10 seconds and it will echo anything that is received. This way i can start testing how reliable the combination of XBee and Arduino really is.

Working on Zigbee API mode interface

Since 4 weeks i have a Digi XStick. This is a USB module that provides connectivity to a XBee network:



This XStick ZB is configured to behave as a coordinator within a mesh topology. The XStick can be plugged directly into the USB port of a PC and doesn’t require batteries or power adapter since it’s USB powered. Last 2 weeks i’ve been working on a Zigbee interface for my domotica system, using ths XStick.

First some things you need to know..

An Xbee module has three communication modes:

  • Transparent mode,
  • Command mode
  • API mode.

At startup, an Xbee module is in transparent mode. In this mode, the module acts as a serial line replacement. All data received from the DIN pin is transmitted, and when RF data is being received, it is sent out on the DOUT pin. A pair of XBee modules can act as invisible cables in this mode.

Command mode is where you can change a large amount of settings of the XBee module. To enter Command mode you must send the characters “+++” and wait a second. Once the XBee enters command mode, it will answer with OK. Most of us will remember this behavior from modems. While in command mode you can change baud rate, destination address, etc etc. Leaving command mode can be accomplished by executing the ATCN command.

Sending messages to constantly changing targets (=other XBee modules), API mode is the best mode to choose. It is the most powerfull but also the most complicated mode to use. API (Application Programming Interface) mode is a frame-based method for sending and receiving data to and from an XBee.

API mode has some special abilities:

  • Changing parameters without entering command mode;
  • RSSI and source address information;
  • Receive packet delivery confirmation on every transmitted packet

Since API mode seems to be the most flexible, i decided to create an API-mode interface. With more then 140 pages of  information of how to interface with XBee/XBee-PRO ZB RF modules i knew this was a job that could take a while, but today i managed to get a sequence of API mode commands working.

The first command i started with  was the Node Discovery command, which will let every device on the network respond with basic information about that device. These reponses are received by the XStick, the address information of the responding XBee devices is stored and the next step is to send a request to all of the responding devices to request information about their hardware version. Today i succeeded in doing this first excercise, as you can see here:

Execute Node Discovery
Sending frame:7E 00 04 08 01 4E 44 64
RxBuffer:7E 00 1D 88 01 4E 44 00 86 23 00 13 A2 00 40 31 B9 04 45 44 41 54 32 00 00 00 02 00 C1 05 10 1E 12

*** Processing frame ***
ApiID = 88
Checksum Ok=True

ATCommandResponse, 29 bytes:
MY 8623
SH,SL 5526146518202628 (0013A2004031B904)
PARENT 00 00

Request Hardware Version for Node 8623
Sending frame:7E 00 0F 17 01 00 13 A2 00 40 31 B9 04 86 23 00 48 56 BD
RxBuffer:7E 00 11 97 01 00 13 A2 00 40 31 B9 04 86 23 48 56 00 19 44 E0

*** Processing frame ***
ApiID = 97
Checksum Ok=True

RemoteATCommandResponse, 17 bytes:
Response=19 44

So the XBee module that responded has a Hardware Version of 1944 🙂