Arduino & XBee

XBee Module Xbee modules provide a very simple way to add a wireless capability to communications on Arduino. Essentially they let you work in exactly the same way as a direct serial connection between two boards – albeit wirelessly.

The easiest way to connect an Xbee to your Arduino, is to use the Arduino Wireless Shield.

XBee Sheild

It’s possible to connect Xbee’s without a shield – but given the fact that they don’t have the (standard) breadboard 0.1″ pin-pitch, this requires a special breakout board, or some custom hardware. If you’re using an Arduino, I think the shields are definitely the best way to go (and they’re pretty inexpensive).

There are a number of different types of XBee – the most notable distinction is between the original, “series 1” devices (directly using the 802.15.4 wireless protocol) and the “series 2”, ZNet 2.5 (or ZB) modules: which add an additional communications layer over the base-standard. Series 1 and series 2 devices are incompatible with each other (and cannot communicate with each other) – but they are pin compatible with each other: so for point-to-point applications, it’s possible to swap out S1 devices with S2 devices (providing you exchange both ends of the communication).

Because S1 devices are simple point-to-point radios, they have a slightly simpler configuration process. Out of the box, two S1 XBee’s should “just work” with each other: but there are a number of configuration parameters that you’ll want to set (most particularly the network ID). S2 devices are very different beasts however. ZNet 2.5 is a meshed radio protocol, where one device is a “master” (called a coordinator) node, and any number of other devices are “end devices” (which send or receive data from the network), or “routers” (which pass communications from end-devices, or other routers, back to the coordinator). As such, in order of facilitate communications between a pair of S2 devices, it’s first necessary to configure one of them as a coordinator.

To do this, you’ll need the X-CTU software from Digi (it’s Window’s only: though with care it can be made to run under WINE on Linux), and some way to connect your XBee to the computer’s USB port. The easiest way is to use a dedicated converter board such as the Sparkfun XBee Explorer: but if you don’t have one, it’s also possible to use an Arduino board & your XBee shied – though to do that you’ll need to (carefully) remove the ATMega chip from your Arduino board (it should also work, if you tie the micro-controller into an empty loop, i.e. upload void setup() {} void loop() {}, but I’ve not not found this method very reliable). If you are using an XBee shield, don’t forget to configure it to allow USB communications with the Xbee (on the Arduino Wireless Proto Shield, this is done via a small switch on the top-left of the shield – check the details that came with your shield, if you’re using a different one).

Using X-CTU, you’ll need to change role of one of the XBees to be the coordinator, using the “modem configuration” tab, and changing the function set to “ZNET 2.5 COORDINATOR AT”. You’ll need to make sure that the PAN ID of both devices is the same, and for simple two-board communications, you’ll also need to change the destination address of the coordinator (stored as two words, destination address high & low – DH and DL) to match the SL & SH words of the end-point.
X-CTU Coordinator
X-CTU Router - End Device
Although you’ll need X-CTU to change the firmware, it’s possible to make the other configuration changes using any serial terminal connected to the XBee, using AT modem commands. Possible: but not really recommended – despite what at least some books on the subject suggest. It really is much simpler to use the GUI provided in X-CTU: and since you’ll need that to upload the correct firmware to the devices anyway, you may as well just use it…

Now let’s look at the code to enable serial communications between two Arduino’s. It’s pretty much the same as the code you’d use to communicate between your computer and your Ardunio – using the Serial library. As with all serial comms, you’ll need to initialize in setup(), and then handle the communications within the main loop.

For a simple example (following the Arduino tutorial) we can have one board sequentially send a byte corresponding to a desired HIGH state, and a byte corresponding to a desired LOW state: and the other board receiving those bytes, and (for example) turning on or off the status LED.

We’ll start with the transmitter.

The setup() simply sets up pin 13 (connected to the on-board LED) for output, and initializes serial communications at 9600 baud (which is the default speed for the the XBee modules).

Next we define a simply function (blinky()) to blink the status LED every time a byte is sent over the wireless link. There’s no need to do this – but it provides a nice visual indication that something is happening.

Finally we send either an ‘H’ (ASCII 72) or an ‘L’ (ASCII 76) over the serial link.

void setup()
{
    Serial.begin(9600);
    pinMode(13, OUTPUT);
}

void blinky()
{
    for (int i=0;i<2;i++)
    {
        digitalWrite(13, HIGH);
        delay(200);
        digitalWrite(13, LOW);
        delay(100);
    }
}

void loop()
{
    Serial.print('H');
    blinky();
    delay(1000);
    Serial.print('L');
    blinky();
    delay(1000);
}

Now we have the receiver. Again, the setup() function, does nothing more than setup pin 13 & initialize the serial comms.

The main loop circles around, until there’s some serial data to receive, then reads this and either switches the LED on or off (or does nothing) depending on the value of that data.

void setup()
{
    Serial.begin(9600);
    pinMode(13, OUTPUT);
}

void loop()
{
    int incomingByte;
    if (Serial.available() > 0)
    {
        incomingByte = Serial.read();
        if (incomingByte == 'H')
        {
            digitalWrite(13, HIGH);
        }
        if (incomingByte == 'L')
        {
            digitalWrite(13, LOW);
        }
    }
}

To test this is all working, we can first check the serial monitor to see if the transmitting board is sending a sequence of high’s and low’s (in this case H’s and L’s), and that the receiving board turns the status LED on and off, when it receives an H or an L from the console. If it’s all working, you can then use a pair of wires connect the two boards using the serial TX & RX pins (pins 0 & 1) – connecting the TX of one board to the RX of the other, and vice versa. Note however, that there’s a trap for the unwary, if you’re using one of the new Arduino Leonardo boards. Because of the way these are constructed, the standard Serial commands only send data to the USB. In order to send or receive data on the serial pins 0 & 1 (which is how the XBee’s work) you need to substitute Serial.begin(), Serial.Print(), etc – with Serial1 (e.g. Serial1.begin() and Serial1.Print()). If you don’t do this, you’ll have a very frustrating time trying to figure out why it only works when you’re looking at it on the USB serial monitor!

Once you’ve got your two Arduino boards talking to each other via a wired serial connection, all you need to do is remove the connecting wires, and add the Wireless Shields and the XBees: et voilà, wireless communications.

Leave a Reply

Your email address will not be published. Required fields are marked *