While rummaging for bargains in the Radio Shack store closing sale I
came across a couple of small boxes labeled ‘X-Bee Shield’—I think the
price was $6.00, XBee
not included. At
the time I did not
know what an XBee was,
but for $6.00 and some unknown but presumed-small additional cost I
might find out. A few weeks later I purchased a pair of 2.4 GHz XBees
for $12 each.
The USB adapter that was needed for setting them up was an
additional $10. All considered, to learn a little about XBees
was not an expensive proposition.
On-line tutorials and examples typically
feature one XBee connected to the computer via USB and another
connected to an Arduino. The program XCTU (free download from DIGI) can be used to configure
XBees, and to setup a pair of them to communicate with one another. In
addition to its configuration options, XCTU
includes a console that supports bi-directional wireless communication
between a computer-connected XBee and another one at a distance away.
All this is documented in multiple places. However, as a learning exercise I wanted to make a
different kind of demo, one in which both XBees would be Arduino-based,
neither connected to the computer or the XCTU utility software.
The idea that sprang to mind and the one
I will describe here was a simple number guessing game in which one
Arduino would pick a number and the other would guess it, transmitting
each guess wirelessly. On hitting upon the right guess, the turns would
change. As imagined, the demo program or ‘sketch’
would have no intelligence, but would simulate an autonomous
conversation between XBees—actually
are only the radio part.
Before writing the demo sketch I first
created a simple test program that would transmit a single
byte, or receive a byte and return a one byte reply. In theory, for
this test Arduino’s
on-board LED (pin 13) would fire whenever a byte was received. However,
the test did not work—how
could such a simple program fail? Or, more basically, given that it had
failed, how could the program be debugged? In order to see what was
happening during execution I wrote a simple subroutine that would flash
an attached LED
n-times. By observing the number of flashes, it would be possible to
deduce where failure occurred. Alas, there was no obvious failure.
Every part of the sketch—there
being reached, and executing,
yet nothing happened. This caused me to wonder if I had inadvertently
fried one or both of the XBees. But that was not the explanation. On
testing each XBee again, using XCTU, they both checked good.
Something was different between the XCTU
test and the Arduino-connected XBees test. As I thought about this I
realized that I had not configured the XBee shield jumpers, having
assumed that they
were connected to the appropriate pins for Serial communication,
This was not the case. The default Arduino Uno UART pins are D0 and D1,
while the XBee shield (out
of the box) had jumpers
on D2 and D3. Of course, I should have checked this at the beginning,
or at least have read the Serial documentation, but what can
say... Obviously serial communication does not work unless something is
connected. After transferring the XBee transmit and receive jumpers to
Arduino’s default serial
com pins, the test sketch behaved in the expected way.
The rest was anti-climax. The
number-guessing game sketch also worked more or less as had been conceived. With the program loaded the XBees began an animated
conversation in their rather limited blinking LED
language. The demo sketch provides an
easy-to-understand starting point for Arduino XBee serial
communication. The same program runs in both XBees, except that near
the top the constant GOFIRST should be changed to false for one of the
Arduinos. A small amount of additional code might eliminate this
variants, different numbers of LEDs or different
Arduino pins, etc. should require only minor
XBee demo: XBee/friends.mp4
far apart can XBees be?
The particular ones I tested cannot be very far from one another. When
placed across the room or in nearby rooms they
continue conversing. However, at greater distances they lose
contact, and stop talking. On looking into this I found that the units
I bought are the lowest power type at 1 mW. More powerful versions
are readily available, as
are other similar Arduino-compatible transceiver chips that operate in
the 915 MHz band, where distances of up to a few miles are possible.
Although the number guessing game was
just a demo, I wanted to address the case where the XBees go quiet
after losing contact. The sketch should be able to detect when they are
stuck so that they can unstick themselves. To this end I made a small
auto-recovery patch. It works like this: First there’s an ‘idle
timeout’ number. It is either zero (meaning the auto-recovery feature
is not implemented) or it is a small random amount more than twice the
time between games. Second, there is an active timer that
resets whenever a byte is received from the other XBee, in other words
whenever the normal thing happens. Finally, if the
timer reaches a value at least as great as the timeout, meaning no data
have been received for too long, then it goes into auto-recovery.
The first thing auto-recovery does is
switch turns, in case the two Arduinos are on the same turn, as seems
to happen on signal loss more often that I would have
guessed. If this particular try doesn’t work it will switch
turns again in a short time, sooner or later getting on the right
(complementary) turn even if both are concurrently trying to
recover. Next auto-recovery transmits a byte that can be
interpreted either as a bad guess, in case the other one is waiting for
a guess, or as ‘your guess was correct—OK
to start another game’, in
case the other one is waiting for feedback.
Finally, it flashes the blue LED (three flashes) so that a person can
tell that a recovery attempt is executing. Recovery also
resets the timer, in order to allow time for the other XBee to respond
before starting another recovery attempt.
expectation was that when the XBees were stuck it would be necessary to
move them closer together, so that they would resume play after recovering.
What actually happens is they resume play right there and then, without
being moved again. When a signal is good enough for play most of the
time, but not sufficient to prevent occasional drops, they are able to
resume or continue play, generally for a few games, before getting
stuck again and repeating the cycle. To observe long-term
stoppage it would be necessary to position them far enough apart that
they have no signal most of the time. Note: For running
the demo sketch (either of them), the Arduino that has the ‘GOFIRST
= false’ edit should be started first.
Project descriptions on this page are intended for entertainment only.
The author makes no claim as to the accuracy or completeness of the
information presented. In no event will the author be liable for any
damages, lost effort, inability to carry out a similar project, or to
reproduce a claimed result, or anything else relating to a decision to
use the information on this page.