The Hands On XBEE Lab Manual

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 304

DownloadThe Hands-on XBEE Lab Manual
Open PDF In BrowserView PDF
Experiment | 1

Introduction to the
X-CTU Software
REQUIREMENTS
1 XBee module
1 USB-to-XBee adapter (see text)
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this short experiment you will learn how to use the Digi International
X-CTU software to program and control XBee modules. These modules
use a simple serial communication protocol that connects them to external
devices, such as a PC and microcontroller integrated circuits, through a built-in
Universal Asynchronous Receiver Transmitter (UART). The UART in the
XBee modules operates by default at 9600 bits/second, which makes it compatible with UARTs in other equipment, thus simplifying communications.
Many XBee commands use standard alphanumeric characters in the
American Standard Code for Information Interchange (ASCII), which means
you can simply type on a PC keyboard to perform XBee-module operations
without having to write programs for a computer. Thus early experiments in
this book will not require a microcontroller (MCU), although readers familiar
with MCUs will quickly understand how to apply them, if they choose. For a
table of ASCII characters and values, see Appendix G.
The X-CTU software “connects” with an XBee module via a USB connection that acts like a “virtual” serial port. The software handles the USB drivers
needed to make possible these serial communications from a Windows PC.
At the XBee end of the USB cable you need an XBee-to-USB adapter such
as the XBee USB Adapter Board (part no. 32400) from Parallax or the XBee
Explorer USB (part no. WRL-08687) from SparkFun Electronics. Both adapters provide several small LEDs that indicate operating conditions. Refer to
1
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

2

Introduction to the X-CTU Software

the respective adapter data sheets for more information. You must have one of
these adapters to perform the experiments in this book.
Step 1. Digi International provides free X-CTU software that you can
download from the Digi Web site at: www.digi.com. Search for XCTU (no
hyphen) and find the entry, “Knowledge Base Article – X-CTU (XCTU) software” and click on it. On this page, click on the link at the bottom of the page,
“Click here to go to the X-CTU download page.” Then download the latest
version of the X-CTU software and install it. Do not start the X-CTU software.
Step 2. Attach the XBee-to-USB adapter to the USB cable and then attach
the USB cable to your PC. If possible, use a USB port on your PC. Extension
USB ports on monitors or USB hubs sometimes cause problems. Do not insert
an XBee module in the adapter now. You will do so shortly. Follow the adapter
manufacturer’s instructions (if any) that describe how to load drivers that configure the USB port to act like a serial port. If you plug in the XBee-to-USB adapter
after you start the X-CTU software, the software might not detect the adapter.
Step 3. Start the X-CTU software as you would start any other program.
The opening display should appear as shown in Figure 1.1. If not already

FIGURE 1.1 The X-CTU software opens a window that offers four tabs along the top. To
start, click on the PC Settings tab to make a connection between your PC and the XBeeto-USB adapter.

Introduction

3

selected, click on the PC Settings tab. In the Serial Com Port window, you
should see text similar to:
Communications Port (COM1)
USB Serial Port (COMxx)
where the xx represents a 1- or 2-digit number. Use your mouse to select this
line of text, which should highlight it to tell X-CTU to use the COMxx port to
connect to the XBee-to-USB adapter. Windows assigns COM-port numbers in
sequence and on my lab PC the adapter appeared as COM19. Many late-model
PCs lack a serial port, so you might not see the first line shown above for COM1.
The X-CTU software uses the following settings to communicate with an
XBee module:
Baud
 9600 (Equivalent to 9600 bits/second)
Flow Control  NONE
Data Bits
8
Parity
 NONE
Stop Bits
1
The X-CTU software should start up with these settings, but if not, use
your mouse to change them to the settings shown above.
Step 4. Disconnect the USB-XBee adapter board from the end of the
USB cable and insert an XBee module into the socket strips on the adapter
board. Ensure you have matched the placement of the XBee module with that
specified by legends on the adapter, or diagrams in the adapter instructions.
Figure 1.2 illustrates possible hardware problems.
After you have properly inserted the XBee module into the USB-to-XBee
adapter, reconnect the adapter to your USB cable. Depending on the adapter
you use, you might see LEDs turn on or flash. (On the Parallax adapter, a
yellow and a green LED turned on and a red LED flashed.)
Step 5. In the X-CTU window again look at the PC Settings section. Click
on the PC Settings tab at the top of the X-CTU window if you have clicked on
other tabs.
In the PC Settings area, find the button on the right side marked Test/
Query. Click on it to test the electrical communication connection to the XBee
module. A “Com test/Query Modem” window will open and it should appear
as shown in Figure 1.3.
If you see the error message, “Unable to communicate with modem,”
shown in Figure 1.4, the X-CTU program cannot “find” the XBee module.
Click on Retry to try communications again, or click on OK to go back to the
PC Settings window. You also can close the X-CTU program and restart it after
you confirm you have the XBee-to-USB adapter properly connected to your
PC. The X-CTU program usually does not recognize an adapter board plugged
in after you start the software. Also recheck the settings given in Step 3.
Step 6. The information shown earlier in Figure 1.3 indicates this experiment used an XB24 XBee module with firmware version 10E6. Depending on
the module you have, model and firmware information might vary from that
shown here. The version information uses hexadecimal, or base-16, values.

4

Introduction to the X-CTU Software

(a)

(b)

(c)

(d)

FIGURE 1.2 These photos illustrate problems that can occur when you improperly insert
an XBee module in an adapter: (a) Incorrect module orientation, (b) a bent pin, (c) incomplete insertion in an adapter or other socket, and (d) a module in an off-by-one-pin position.

FIGURE 1.3 When the X-CTU software successfully communicates with an XBee module,
you will see a display that includes the information shown here.

Step 7. After you have seen the Modem type and Modem firmware version
information in the Com test/Query Modem window, click on OK and then
select the Terminal tab to open the X-CTU terminal window (Figure 1.5). This
window lets you type a message to control the attached XBee module and to
see responses from the module. The cursor should already flash in the white
message area.

Introduction

5

FIGURE 1.4 If you see this screen when you test the connection between the X-CTU
software and your XBee module, recheck the settings shown in Steps 3 and 5, ensure you
have firm connections at each end of the USB cable, and that you have plugged in the XBee
module firmly.

FIGURE 1.5 The top of the X-CTU Terminal provides several settings and buttons. Leave
the settings as shown. You will use the Assemble Packet, Clear Screen, and Show Hex
button in later experiments.

The XBee modules rely on a set of “AT” commands to set operating conditions and request actions. Years ago engineers created dial-up modems that
used similar AT commands to set up modem conditions, initiate communications, dial phone numbers, and so on. Digi International lists the set of XBee
AT commands for the XBee24 modules in the document “XBee/XBee-PRO
RF Modules” available on the company’s web site: http://ftp1.digi.com/
support/documentation/90000982_D.pdf as revision D, dated 25 July 2011.
Digi might have posted a newer version, though.
An AT command begins with three plus signs, , sent from your PC.
Type  in the terminal window. DO NOT press Enter or any other key
after you type .
You should see the  printed in blue and after a few seconds, the letters
OK should appear in red at the end of the plus signs (Figure 1.6). The “OK”
message lets you know the XBee module can accept AT commands. An XB24
module remains in this “AT-command” mode for about a minute. If you don’t

6

Introduction to the X-CTU Software

FIGURE 1.6 An OK response from an XBee module that received the characters .

type in a command within that time, you must type  again and wait for
the XB24 module to again display “OK” in the terminal window.
Step 8. In this step you will put the XBee module into the AT-command
mode and then send it a command. Review the command sequence below
before you do anything more:

ATVR [Enter]
Now, type the three plus signs and wait for the “OK” response:  OK
Then, type ATVR and press Enter. Note what you see in the terminal
window. In my lab, I saw:
 OK
ATVR
10E6
The ATVR command sends the AT prefix that lets an XBee module know a
command will follow. In this case, the VR – Firmware Version command asked
the module to reply with the version number for its firmware.
Do not put an XBee module in AT-command mode and type random letters
just to see what happens. Doing so could alter internal settings that affect an
XBee module’s operations.
If you type an invalid AT command or a valid AT command the XBee module cannot perform, it responds with ERROR in red letters below the latest AT
command.
Step 9. If you plan to go on to Experiment 2 now, leave your XBee module connected to the USB-XBee adapter, leave the USB cable connected to the
adapter and your PC, and do not close the X-CTU window.
Note: For more information about the origin and use of the AT modem
commands, visit: en.wikipedia.org/wiki/Hayes_command_set.

Experiment | 2

How to Change XBee
Module Configurations
REQUIREMENTS
1 XBee module
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use the X-CTU software to program
an XBee module for specific actions. You will make changes in experiments
that will follow, so please do not go on to the next experiment until you understand how to change settings and confirm them.
Step 1. You must have an XBee module plugged into a USB-XBee adapter
and the adapter must connect to a Windows PC USB port. You also must run
the X-CTU software. If you do not have this equipment set up and the X-CTU
software running, please complete Experiment 1 before you proceed.
Step 2. Check the connection between your PC and the XBee module:
Within the X-CTU window, click on the PC Settings tab and ensure you have
the communications set for Baud: 9600, Flow Control: NONE, Data Bits: 8,
Parity: NONE, and Stop Bits: 1. Click on the Test/Query button and the Com
test/Query Modem window should open and display “Communication with
modem..OK” and other information. (If you do not see this message, go back
and repeat Experiment 1 and see the Troubleshooting section in Appendix H.)
Click on OK in the message window.
Step 3. Click on the Modem Configuration tab. This window lets you
observe and change all of the operating information internal to an XBee
module. At this point the configuration window could be blank (white) or
it might contain information as shown in Figure 2.1. It does not matter.
7
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

8

How to Change XBee Module Configurations

FIGURE 2.1 The Modem Configuration window displays settings from an XB24 XBee
module with firmware version 10E6.

FIGURE 2.2 Leave the “Always update firmware” box unchecked, or uncheck it. You do
not need to update firmware and trying to do so could cause problems.

FIGURE 2.3 If not already set as shown here, change the MODEM: XBee and Function
Set text boxes to the configurations shown here.

(Digi International often uses “modem” to describe its XBee modules. To me,
modem sounds archaic, so I will avoid using it as much as possible.)
Step 4. Before you proceed, uncheck the small box “Always update
firmware” on the left side of the Modem Configuration window as shown in
Figure 2.2. If you check this box, or leave it checked, the X-CTU software
will attempt to update the firmware in an attached XBee module. If that update
fails, you could end up with a non-functional module. Do not update firmware.
Step 5. Before you use the X-CTU software to change configuration information, you must ensure the software knows the type of module and the function set you plan to use. When you work with a module, the Modem: XBee
should show XB24 and the Function Set should show XBee 802.15.4, as
shown in Figure 2.3.

Introduction

9

FIGURE 2.4 Modifying an XBee configuration setting changes its color so you can
quickly spot modified values or selections.

FIGURE 2.5 The text window provides information about a selected module-configuration setting.

The XBee 802.15.4 setting operates the modules according to a standard
established for the Institute of Electrical and Electronic Engineers (IEEE) to
ensure proper communications between all modules via a fixed protocol.
Step 6. In the Modem Parameters and Firmware box in the upper left
section of the X-CTU window, click on Read. This action reads the settings
already programmed in your XBee module. The window should now display
the parameters in a directory-like format typical of Windows and other operating systems, as shown earlier in the lower part of Figure 2.1.
You should see a folder labeled Networking & Security at the top
of the window and below that, settings for CH–Channel, ID–PAN ID,
DH–Destination Address High, and so on. Under the Networking & Security
heading, move the mouse cursor to DL–Destination Address Low and click
on this label. A text box will open to the right of the DL–Destination Address
Low label. Disregard any value in this box.
Clear any information in the box and type 4567. The 4567, a hexadecimal value, also appears in the parentheses to the left of the DL–Destination
Address Low label, and the label turns olive green (Figure 2.4). That color,
which indicates you changed the information, makes it easy to find modified
parameters. Unchanged parameters remain bright green, parameters you cannot change appear in black, and errors turn a parameter label red.
A click on a parameter also displays information about the parameter and
its allowed settings in the text area at the bottom of the Modem Configuration
window (Figure 2.5).
Step 7. Move the cursor to MY–16-Bit Source Address, click on it and
in the text box that opens to the right of the label, type 1234. Again, note the
X-CTU program placed 1234 in the parentheses at the left of the MY–16-Bit
Source Address label.
Step 8. For now, any changes made in the Modem Configuration window
exist only within the X-CTU software. An attached XBee module has not yet
received them. In the Modem Parameters and Firmware box, click on the Write

10

How to Change XBee Module Configurations

FIGURE 2.6 This message shows the X-CTU program successfully transferred the configuration information to an XBee module.

button. Below the list of settings the X-CTU software displays the message,
“Getting modem type” and then a bar graph labeled, “Setting AT parameters.”
When the bar graph disappears, you should see the messages shown in Figure 2.6.
Step 9. These messages indicate the X-CTU program has successfully
saved the two parameters you changed in an attached XBee module. You can
confirm this action in two ways:
l
Click the Read button to obtain the settings from the XBee module you just
programmed. To the left of the labels Destination Address Low and 16-Bit
Source Address you should see the values typed in earlier.
l
In the Modem Configuration window, each label has a 2-letter prefix, such
as DL for Destination Address Low and MY for 16-Bit Source Address.
These letters represent the AT command used to read or write a parameter
value or choice. Click on the Terminal tab to get to the terminal view. In
this window, click the Clear Screen button.
To determine the Destination Address Low value, type:

ATDL[Enter]
You should see:
OK
ATDL
4567
To determine the 16-Bit Source Address, type:

ATMY[Enter]
You should see:
OK
ATMY
1234
Step 10. You also can use the AT commands to set parameters. Just follow
the AT command with a new parameter. To change the MY–16-Bit Source
Address to 0040, type:

ATMY0040[Enter] (No space between command and a parameter value!)
To query the XBee module, type:

ATMY[Enter]
You should see:
OK

Introduction

11

ATMY
40
The X-CTU software does not display nor does it need leading zeros in
the Modem Configuration window, so the command ATMY0040 and ATMY40
have the same effect. In some cases, described later, commands must include
leading zeros, and instructions will explain those situations.
Step 11. To return an XBee module to its factory-default condition,
click on the Modem Configuration tab and then in the Modem Parameters
and Firmware box, click on Restore. This action resets all parameters to the
factory-default settings and automatically writes them into the XBee module’s
flash memory. You do not have to click the Write button.
To confirm the default settings, click on Read and you will see the labels
for all the settings you can modify have returned to green and thus the factoryset values. Before you go to the next experiment, I recommend you restore the
default values for the attached XBee module.
Step 12. So far, the XBee module does not transfer information wirelessly.
The next experiment takes that step.
Note: Unless specified otherwise, all modem parameters use hexadecimal
values. You will find a hexadecimal-binary-decimal converter at: http://www.
mathsisfun.com/binary-decimal-hexadecimal-converter.html.

Experiment | 3

One-Way Digital-Input
Communications
REQUIREMENTS
2 XBee modules
2 XBee adapters (see text)
1 USB-to-XBee adapter (see text)
1 USB cable—type-A to mini-B
1 3.3-volt DC power supply (see text)
Solderless breadboard
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
This experiment shows you how to configure one XBee module as a wireless
transmitter and one as a receiver. You will set the transmitter to continually
send information to the receiver, which will display information in the X-CTU
Terminal window. The diagram in Figure 3.1 shows this basic arrangement for
one-way communication of digital information from the XMTR to the RCVR
module. The RCVR sends the received information to the X-CTU Terminal,
which converts each byte into a corresponding ASCII character and a hexadecimal value.
Now you will set up a solderless breadboard to hold two XBee modules
and supply power to them. The 20-pin XBee modules use male pins spaced
2 mm apart, but typical solderless breadboards space receptacles on 0.1-inch
(2.5 mm) centers, so you need adapters that make connections between the pins
on an XBee module and the receptacles.
Manufacturers have produced several types of XBee socket adapters.
I have used the 22-pin 32403 XBee Adapter Board from Parallax and the 20-pin
BOB-08276 Breakout Board for XBee Module from SparkFun Electronics. No
matter which adapter you use—or make—keep a diagram handy that shows the
pin numbers for the adapter and the XBee-module pins the breadboard receptacles connect to. They do not correspond one-to-one on all types of adapters.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

13

14

One-Way Digital-Input Communications
Wireless Link

PC
AD0-DIO0 Input

“XMTR”
XBee

“RCYR”
XBee
USB Connection
USB-to-XBee Adapter

FIGURE 3.1 This experiment configures one XBee module as a transmitter with one
active digital input. That module will take two samples, one second apart, and transmit the
results to another XBee module labeled RCVR.

FIGURE 3.2 Breadboards come in a variety of shapes and sizes. Some include marked
power buses and terminals.

The experiments in this book always refer to the pin numbers and signal names
on an XBee module.
Step 1. In this step, plug two XBee adapters into a solderless breadboard and
keep the adapters separated by about 3 inches (7.6 cm). If the breadboard has
other components attached to it, please remove them now. Do not put an XBee
module in either adapter. In later experiments you will use the second adapter,
but it’s easier to insert it now when you have nothing else in the breadboard.
Figure 3.2 shows three solderless breadboards. When I make breadboard
power connections, I use the outside buses for the positive voltage and the inside
buses for ground. I have used this arrangement for many years because regardless of breadboard orientation, I know where to connect to power and ground.
The photo in Figure 3.2 also shows a breadboard, but with color-coded and

Introduction

15

Top View
+3.3 V
UART Data Out
UART Data IN – /CONFIG
DO8 *
/RESET
PWM0 – RSSI
PWM1
(Reserved)
/DTR – SLEEP_RQ – DI8
GND

1
2
3
4
5 XBee XB24
6
7
8
9
10

20
19
18
17
16
15
14
13
12
11

AD0 – DIO0
AD1 – DIO1
AD2 – DIO2
AD3 – DIO3
AD6 – DIO6 – /RTS
AD5 – DIO5 – Associate
VREF
ON – /SLEEP
DIO7 – /CTS
AD4 – DIO4

* DO8 not supported at this time

FIGURE 3.3 Pin-and-signal designations for an XB24 XBee module.

labeled power and ground buses. Use any arrangement you like, but I strongly
recommend you label or color the ground and the positive-voltage buses unless
already labeled. Incorrect power connections can quickly destroy circuits.
I also recommend you label one XBee module XMTR for transmitter and
one RCVR for receiver. I used a marker to color the XBee logo green on my
transmitter and red on my receiver. In other experiments the XMTR won’t
always transmit and the RCVR won’t always receive, but labels and colors
make them easier to keep track of. If you have additional XBee modules, label
them, too. (I had two other modules labeled END and PRO.)
Step 2. The diagram in Figure 3.3 shows the pin numbers and signal labels
for XBee and XBeePRO modules based on a top-down view. Some pins share
functions. The ADx–DIOx pins, for example, can operate as digital inputs or
outputs, or as analog inputs for an internal analog-to-digital converter (ADC).
Step 3. As I prepared the experiments for this book I used an Extech
Instruments Model 382203 Analog Triple Output DC Power Supply because
I had one in my lab. You do not need this type of high-quality power supply for
experiments. Although experiments will call for 3.3 volts, two D-size 1.5-volt
dry cells in series will suffice to power XBee modules. And batteries work well
if you want to locate XBee modules and circuits away from your lab bench.
Jameco Electronics sells a 2-cell battery holder (part no. 216390) and DigiKey
stocks a similar battery holder (part no. BH2DL-ND).
Connect 3.3-volt power to pin 1 (VCC) on each adapter and connect
ground to pin 10 (GND) on each module, as shown in Figure 3.4. Pin numbers
always refer to XBee pin numbers and not to adapter pin numbers due to variation in adapter pin configurations. All pin information refers to a top view of
a device.
Step 4. Now you will program the transmitter (XMTR) XBee module.
I recommend you always disconnect the USB-to-XBee adapter from its USB
cable before you insert or remove an XBee module. This means you have an
unpowered USB-to-XBee adapter when you insert or extract a module.

16

One-Way Digital-Input Communications
Top View
+3.3 volts

Ground

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 3.4 In this experiment, the XMTR XBee module needs only a power and a
ground connection. In a later step you will make another connection.

Disconnect the USB-to-XBee adapter from its cable. Insert your XMTR
module in the USB-to-XBee adapter socket and reconnect the adapter to the
USB cable.
Step 5. If not already running, start the X-CTU software and confirm it
can communicate with the XBee module. Use the PC Settings window or the
Terminal to test communications. After you have communications between the
module and the X-CTU software, go to the X-CTU Modem Configuration tab
and click the Restore button to return configurations to their default condition.
Then click Read to obtain those settings.
Step 6. You must change the XBee configurations for the transmitter module to those shown below. If you have problems and cannot get the
XBee modules to work properly, download the EX3_XMTR.pro file that provides a ready-to-use configuration for the transmitter. Then in the Modem
Configuration window, find the Profile area and click on Load. Locate the
appropriate profile and it will load into the Modem Configuration window.
Click on Write to save it in an XBee module. Remember, all XBee configurations use either a menu choice or hexadecimal digits.
If you do not use the configuration file, under the Networking & Security
heading, change:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
Each XBee module has a 64-bit (8-byte) serial number as well as a 64-bit
destination address divided into a DH and a DL section, each 32 bits, or 4
bytes, long. The DL value sets the 16-bit address of the destination XBee module you want to communicate with. The DH address remains set at 0x0000,
where the zero and lowercase x denote a hex value. So, the XMTR module has
a destination address of 0x0000 0x1234. The MY value sets the 16-bit source
address for the XMTR module. In other words, the MY information gives a
module with its own unique 16-bit address.

Introduction

17

Step 7. Scroll down in the Modem Configuration window to the I/O
Settings heading. In this section clicking on some parameters opens a small
text window that lets you select one of several choices. Other parameters
require a typed hexadecimal value.
Under the I/O Settings heading, change:
D0 – DIO0 Configuration	  3-DI (Sets data-input for pin 20, AD0/DIO0)
IR – Sample Rate	  3E8 (Hexadecimal for 1000)
IT – Samples before TX	  2
Now pin 20 (AD0-DIO0) at the XMTR module will operate as a digital
input (DI) pin. The sample rate uses increments of one millisecond, so a value of
0x03E8 (100010) provides a delay of 1000 milliseconds, or one second, between
samples. Once a second the transmitter will sample any XBee input/output pins
that you enabled—in this case only AD0-DIO0—and save that information.
The IT parameter set the transmitter to acquire two samples before it transmits data to the receiver. Thus, the receiver should see information from the
transmitter once every two seconds.
Step 8. After you have entered the parameters above, recheck them and
click on the Write button to save them in the XBee XMTR module attached to
the USB-to-XBee adapter.
After you successfully program the XMTR module, you can click the
Read button and review the settings to ensure you programmed them properly.
If necessary, make changes to the parameters and again click the Write button
and then the Read button to confirm the latest changes.
Disconnect the USB-to-XBee adapter from the USB cable and remove
the XBee XMTR module. Insert it into the one of the XBee adapters in your
breadboard.
Step 9. Now you will program the XBee receiver module, RVCR. Place the
XBee module marked as the receiver in the USB-to-XBee adapter and connect the
adapter to the USB cable. The X-CTU software should still be running, so confirm
communication between the X-CTU program and the RCVR XBee module.
After you have communications between the module and the X-CTU software, go to the X-CTU Modem Configuration tab and click the Restore button
to return configurations to their default condition. Then click Read to obtain
those settings.
Step 10. You now set parameters in the RCVR module so it can receive information from the XMTR module you just programmed. Click on Read to read
the RCVR module’s configuration information. As described in Step 6, if you
have problems and cannot get the XBee modules to work properly, download the
EX3_RCVR.pro file that has the ready-to-use configuration for the receiver.
Step 11. Change the RCVR XBee-module configurations to those shown
below.
If you do not use the configuration file, under the Networking & Security
heading, set:
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234

18

One-Way Digital-Input Communications
“XMTR” Module

“RCVR” Module

DL = 1234

DL = 5678

MY = 5678

MY = 1234

FIGURE 3.5 By setting the MY and DL values as shown here, two XBee modules can
communicate with each other.

These two settings relate to those you set for the XMTR module in Step 6.
Now you have the RCVR module set with the MY address you used as the
destination address in the XMTR module, and the destination address in the
RCVR module corresponds to the MY address in the XMTR module. These
corresponding addresses, shown in Figure 3.5, will let the modules communicate with each other.
Step 12. Under the I/O Settings heading, look for the IU – I/O Output
Enable parameter. Click on it and confirm the RCVR module has it set to
1-ENABLED. If this setting does not equal 1, click on the label and choose
the setting 1-ENABLED. This parameter lets a module send data it received
from another XBee module to an external device, perhaps an MCU, via the
UART. In this experiment, the X-CTU software will receive that information
and display it in the Terminal window.
Step 13. After you have changed the DL, MY, and IU parameters shown
above, recheck them and click on the Write button to save them in the RCVR
XBee module attached to the USB-to-XBee adapter. After you successfully
program the RCVR module, click the Read button and review the parameters
to ensure you programmed them properly.
Do not remove the RCVR module from the USB-to-XBee adapter.
It will receive wireless information from the XMTR module and send it to the
X-CTU software through the USB connection.
Step 14. Click on the Terminal tab in X-CTU and click on Clear Screen.
Then apply power to the XMTR module. You should see a display of somewhat
random characters start to appear in the Terminal window as shown in Figure 3.6.
The X-CTU Terminal does not display messages in text you can read.
Instead it sends information in packets of bytes. To display the data as hexadecimal values, click the Show Hex button on the upper right side of the
Terminal display. The display now shows the characters on the left side of the
screen and the hexadecimal data on the right, as shown in Figure 3.7.
A close look at the hex information shows a repeating pattern:
7E 00 0C 83 56 78 3F 00 02 00 01 00 01 00 01 6A
7E 00 0C 83 56 78 3F 00 02 00 01 00 01 00 01 6A
7E 00 0C 83 56 78 3F 00 02 00 01 00 01 00 01 6A
7E 00 0C 83 56 78 30 00 02 00 01 00 01 00 01 7B

Introduction

19

FIGURE 3.6 A raw-data message from an XBee transmitter looks like this.

FIGURE 3.7 By splitting the Terminal window into a character column (left) and a hexvalues column (right) you can obtain bytes of information that indicate the state of I/O pins
at the XMTR module.

Parsing this information according to specifications for XBee communications lets you see what it means. Although the values do not include a 0x prefix
they appear next as hexadecimal numbers:
7E	  start of transmission, a preset value (1 byte)
00 0C	  a count of the following bytes in transmission (2 bytes)
83	  code for 16-bit module addressing, preset value (1 byte)
5678	  16-bit address (2 bytes)
3F	  signal strength of wireless signal at receiver (1 byte)
00	  status byte (1 byte)
02	  number of samples (1 byte)
00 01	  Active-Signal Bytes identify active I/O pins (2 bytes)
00 01	  first of two samples for digital I/O pins (2 bytes)
00 01	  second of two samples for digital I/O pins (2 bytes)
6A	  calculated checksum (1 byte), not included in byte count

20

One-Way Digital-Input Communications

Here’s how you break down this transmission in more detail:
00 0C	  1210 bytes in the transmission, not counting the checksum, the
start-of-transmission byte or these two byte-count values
5678	  the Destination Address Low you programmed into the RCVR
module
3F	  the signal strength at the RCVR, now a value of 6310
00	  a status byte
02	  the number of samples you programmed as the Samples-before-TX
value in the XMTR module
00 01	  Active-Signal Bytes that identify active analog or digital pins at
the transmitter module
00 01	  digital information for active digital inputs (1st sample)
00 01	  digital information for active digital inputs (2nd sample)
Step 15. In the Bit Position row in the following tables, B7 represents the
most-significant bit and B0 represents the least-significant bit. Appendix I provides blank tables you can copy for your own use. The information in the two
Active Signal Bytes (0x00 and 0x01) goes into Table 3.1 to identify any active
I/O pins at the XMTR module. Each I/O pins has a corresponding bit position
in these two bytes. The letter X in a Bit-Function position indicates the bit has
no use in I/O operations.
The left-most Active-Signal Byte, 0x00, equals 000000002, which indicates inactive analog channels A5 through A0 and an inactive digital input at
D8. The right-most Active-Signal Byte, 0x01, equals 000000012, which indicates inactive digital pins for D7 through D1 (AD7-DIO7 through AD1-DIO1),
but an active digital pin at D0 (AD0-DIO0). Remember: You set DIO0 as
“3 – INPUT” for the transmitter.
Important: The Active-Signal Bytes indicate which inputs will have information for the receiving XBee module. They do not indicate the state of any
active I/O pins. The bytes that follow provide that information.

Table 3.1 Bit Locations in Active-Channel Bytes
First Active-Signal Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

A5

A4

A3

A2

A1

A0

D8

Data

0

0

0

0

0

0

0

0

Second Active-Signal Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

0

0

0

0

0

0

0

1

Introduction

21

Next you have two values, 0x0001 and 0x0001, that represent the two samples from the XMTR module, taken one second apart. The sampled-data bytes
have the arrangement shown in Table 3.2, which includes data from the first
pair of bytes, 0x00 and 0x01. Again, an X in a Bit-Function position indicates
the bit has no use in I/O operations.
Because the Active-Signal Bytes indicate only the DIO0 pin will have an
active signal on it, you can look only at the D0 position in the Second Data
Byte. So ignore the D8 through D1 bits in Table 3.2. To re-emphasize; the
Active-Signal Byte indicates any active I/O pins and the Data Bytes tell us
what signal exists at the corresponding input.
Table 3.2 Byte Arrangements for Digital Inputs
First Digital-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

X

D8

Data

0

0

0

0

0

0

0

0

Second Digital-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

0

0

0

0

0

0

0

1

Step 16. The data received from the XMTR module includes a checksum
byte, 0x7A. The transmitter calculated this value based on the values of the bytes
in the message. A receiving XBee module also will calculate a checksum based
on the received-message values and will compare it to the received checksum.
If the checksum values do not match, a transmission or reception error occurred
and the RCVR will “silently” discard the received information. A receiver that
detects a checksum error will not send an error message to an attached MCU or
other device, so you will usually not know when a checksum error occurs. The
receiving module will send an acknowledgement to a transmitting module, however. If the transmitter does not receive an acknowledgement, perhaps due to a
checksum error, it will try for as many as three times to complete the communication with the receiver. (The RR command will increase the number of retries,
but the experiments in this book use the default value for three.)
The checksum involves only the underlined message bytes shown here:
7E 00 0C 83 56 78 2F 00 02 00 01 00 01 00 01 7A

It ignores the 0x7E start-of-transmission value and the 2-byte byte-count
value, 0x000C. To calculate the checksum, add the underlined hexadecimal

22

One-Way Digital-Input Communications
Top View
+3.3 volts

Ground

1
2
3
4
5
6
7
8
9
10

“XMTR”

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0

To Ground

FIGURE 3.8 By connecting the AD0-DIO0 input at pin 20 at the XMTR module, you
force this input to a logic-0 state.

values. Here the sum comes to 0x185. Keep only the two right-most (leastsignificant) hex digits, 0x85, and subtract them from 0xFF. The answer comes
to 0x7A.
(For an online hex calculator, visit: http://www.squarebox.co.uk/hcalc.
html?0. Appendix E also explains how to download and use an Excel packetcreator spreadsheet that can calculate a checksum value and simplify creating
messages used in later experiments.)
Step 17. Although you have only power and ground connected to the
XMTR, it transmits a logic 1 to the RCVR as if the D0 input had a logic 1, or
about 3 volts connected to it. In an XBee module, internal resistors between
the I/O pin and 3.3 volts “pull up” an unconnected input to a logic-1 state.
An XBee module has a default condition that turns on these pull-up resistors. In a later experiment you will learn how to use the PR command to turn
selected pull-up resistors on or off.
In this step, you will force the D0 input to the logic-0 state to see what
happens to the data displayed in the X-CTU Terminal window. Turn off power
to your XMTR module. Connect a short wire between the D0 line at pin 20
(AD0-DIO0) and ground (Figure 3.8). This connection pulls the D0 input
down to ground, or zero volts, which represents a logic 0. Remember, a logic 0
does not mean “nothing” or an unconnected pin.
Turn on the XMTR module and use the Show Hex view in the Terminal
window to observe information received. I observed the following data:
7E 00 0C 83 56 78 2D 00 02 00 01 00 00 00 00 7E

The Active-Signal Bytes do not change because the AD0-DIO0 pin
remains active. But the data at position D0 in the Second Data Byte indicates
a logic 0, or ground, at the AD0-DIO0 pin at the XMTR. Use the information
for the two data bytes shown in Table 3.2 above to confirm a logic 0 for the D0
line at the XMTR.

Introduction

23

You can remove the ground connection at pin 20 on the XMTR module to
see if the AD0-DIO0 input goes back to a logic 1.
Step 18. Optional. Go back to Step 7 and use the X-CTU software to
configure the AD3-DIO3 pin at the XMTR module as a second digital input
pin. You must disconnect the RCVR module and place the XMTR module in
the XBee-to-USB adapter. Then return the XMTR and RCVR modules to the
breadboard adapter and the XBee-to-USB adapter, respectively. When you
power the XMTR module and change the AD3-DIO3 pin (pin 17) from logic
1 (3.3 volts) to ground (0 volts), you should see a change in the data bytes
for the DIO3 pin in the Terminal window. Use the blank tables in appendix I to
help parse the new data from the XMTR module.
In the next experiment you will learn how to use the RCVR module to
control an external device. You may leave your XMTR and RCVR modules as
new set up and use them in Experiment 4.

Experiment | 4

Use an XBee Module
for Remote Control
REQUIREMENTS
2 XBee modules
2 XBee adapters
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
1 3.3-volt DC power supply
1 LED
1 220-ohm, 1/4-watt resistor, 10% (red-brown-red)
1 Solderless breadboard
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In Experiment 3 you learned how a transmitter module (XMTR) could send
information about the state of a digital input to a receiver module (RCVR).
The received information shown in the X-CTU Terminal let you determine the
logic state of the input pin at the XMTR module. In this experiment you will
connect an LED to the RCVR module and control it from the XMTR module. I
recommend you perform Experiment 3 before you start this experiment.
Step 1. You will use the same experimental setup used in Experiment 3 for
the XMTR module, as shown in Figure 4.1. This figure shows the placement of
a jumper wire at the AD0-DIO0 input so you can place a logic-0 or a logic-1
signal on the AD0-DIO0 pin.
Step 2. In this experiment you will configure the RCVR module so its
AD0-DIO0 digital output (pin 20) controls an LED. Recall an ADx-DIOx pin
can operate as a digital input or output, or as an analog input, depending how
you configure it. To set the AD0-DIO0 pin on the RCVR as an output, you must
modify the settings in the RCVR module. If you just completed Experiment 3
you should have the RCVR module plugged into the USB-to-XBee adapter and
the adapter should connect to a USB port on your PC.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

25

26

Use an XBee Module for Remote Control
+3.3 volts

Top View
+3.3 volts

Ground

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0

Jumper
Ground

Figure 4.1 Connections for the XMTR XBee adapter in a solderless breadboard for a
remote-control experiment.

If you just completed Experiment 3 and have not made any changes to the
RCVR Modem Configuration information, please go to Step 3.
l
If you have changed any of the RCVR Modem Configuration information
or don’t know its configuration, you should reset your RCVR module to its
default Modem Configuration. To do so, click on the Restore button and wait
for the message: “Restore Defaults..complete” in the bottom X-CTU window. Next, click on Read so you can see the default Modem Configuration
settings retrieved from your RCVR module.
If you have problems and cannot get the XBee modules to work properly,
download the EX4_RCVR.pro file that provides a ready-to-use configuration
for the receiver.
Step 3. Use the X-CTU program to make following four changes to the
Modem Configuration settings for the RCVR module:
Networking & Security:
DL – Destination Address Low
 5678
MY – 16-Bit Source Address
 1234
I/O Settings:
D0 – DIO0 Configuration
 5 – D0 High
I/O Line Passing:
IA – I/O Input Address
 FFFF
You must click on the plus sign () to the right of the I/O Line Passing
folder to open it and see the IA – I/O Input Address configuration. When you
move the cursor to, and then click on, the IA – I/O Input Address line, to the
right you will see a button labeled Set. Click on it. The Set button opens a text
window that shows the I/O Input Address information. Click the Clear button,
type in FFFF, and click OK. You should now see the I/O Input Address set to
FFFF. This setting lets the receiver accept all I/O-data packets from a transmitter.
The D0 – DIO0 Configuration of “5 – D0 High” places the AD0-DIO0 pin
(pin 20) at the receiver module in a “high,” or logic-1 state unless a command
from a remote module changes its state to a logic 0.
l

Introduction

27

Step 4. Click the Write button to load the new configuration into your
RCVR module.
Step 5. If you have not changed or reset the configuration of your XMTR
module, please proceed to Step 6. If you have changed, reset, or don’t know
the settings for your XMTR module, go through the following sequence:
Disconnect the USB-to-XBee adapter from the cable, remove the RCVR
module from the adapter, and set it aside. Place the XMTR module in the
USB-to-XBee adapter and reconnect it to the USB cable. Open the X-CTU
Modem Configuration window and click the Restore button. After you see the
message “Restore Defaults..complete” click the Read button. Now change the
following configurations shown below for the XMTR module:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
D0 – DIO0 Configuration	  3-DI
IT – Samples before TX	  02
IR – Sample Rate	  3E8
After you recheck these settings, click on Write to load them into your
XMTR module. Disconnect the USB-to-XBee adapter from the cable and
remove the XMTR module from the adapter. Return the XMTR module to its
adapter socket in your breadboard. Replace the RCVR module in the USB-toXBee adapter and reconnect it to the USB cable.
If you have problems and cannot get the XBee modules to work properly,
download the EX4_XMTR.pro file that provides a ready-to-use configuration
for the transmitter.
Step 6. The XMTR module requires a wire on the breadboard between pin
20 (AD0-DIO0) and 3.3 volts, as shown earlier in Figure 4.1. This wire provides a logic-1 or a logic-0 input for the DIO0 input pin. If your XMTR module does not have this connection, add it now.
Click on the Terminal tab in the X-CTU window, clear it, and then apply
power to your XMTR module. You should see a string of bytes, such as that
shown below, represented as hexadecimal values:
7E 00 0C 83 56 78 30 00 02 00 01 00 01 00 01 79

As you learned in Experiment 3, these bytes represent:
7E
 start of transmission, a preset value (1 byte)
00 0C
 a count of the following bytes in transmission (2 bytes)
83
 code for 16-bit module addressing, preset value (1 byte)
5678
 16-bit address (2 bytes)
30
 signal strength of wireless signal at receiver (1 byte)
00
 status byte
02
 number of samples (1 byte)
00 01
 Active-Signal Bytes identify active I/O pins (2 bytes)
00 01
 first of two samples for digital I/O pins (2 bytes)
00 01
 second of two samples for digital I/O pins (2 bytes)
79
 calculated checksum (1 byte), not included in byte count

28

Use an XBee Module for Remote Control
+3.3 volts

LED Anode (+)

LED
LED Cathode (–)
Top View
+3.3 volts

Ground

20
1
19
2
18
3
17
4
5 XBee XB24 16
15
6
14
7
13
8
12
9
11
10

220 ohms
AD0-DIO0

Figure 4.2 This diagram shows power and ground as well as an LED and resistor connected to an XBee adapter socket.

The two samples indicate a logic-1 signal at the DIO0 input on the XMTR
module. Your signal strength and checksum values will likely differ from those
shown here.
Step 7. Turn off power to the XMTR module. If you have not plugged a
second XBee adapter into the solderless breadboard, choose an open section about 3 inches (7.5 cm) away from the XMTR module. Place the second
XBee adapter so it orients the XBee socket in the same direction as the adapter
already in use for the XMTR module. That means both adapters should have
XBee pins 1 through 10 face the same side of your solderless breadboard. This
orientation helps avoid confusion over pin numbers and locations. Insert the
second, empty XBee adapter in your breadboard.
The second XBee adapter requires 3.3 volts connected to pin 1 (VCC)
and ground connected to pin 10 as shown on the left side of the XBee module
in Figure 4.2. Make these connections now.
Step 8. On your solderless breadboard, connect one end of a 220-ohm
resistor (red-red-brown) to pin 20, AD0-DIO0, on the unoccupied XBee
adapter. Connect the other end to an unused column of contacts on your breadboard. This column should have nothing else connected to it.
Connect a light-emitting diode (LED) between the free end of the 220-ohm
resistor and power. An LED provides two ways to identify its proper connection. The anode () has the longer of the two leads. Most individual LEDs
also have a flat side on their retaining ring, as shown in Figure 4.3. The flat
side indicates the cathode () lead.
Next you will connect the LED’s anode () lead to the 3.3-volt bus on
your breadboard and then connect the cathode () lead to the free end of the
220-ohm resistor in the otherwise-unconnected column of contacts. When the

Introduction

29

Flat Side
Cathode (–)
LED Body
Anode (+)
Retaining Ring

Figure 4.3 Electrical-lead identification for a discrete LED.

DIO0 output of an XBee module in this adapter becomes a logic 0, or ground,
current will flow through the LED and resistor and into the DIO0 pin and the
LED will turn on. When the DIO0 pin becomes a logic 1, it produces a voltage
close to 3.3 volts, so no current can flow and the LED will turn off.
Step 9. Disconnect the USB-to-XBee adapter from the USB cable and
remove the RCVR module from the adapter. Ensure you have turned off the
3.3-volt supply to your breadboard. Check the RCVR module for proper orientation with the XBee outline on the unoccupied adapter board and plug in the
receiver module.
Step 10. Apply power to your breadboard to turn on the XMTR and RCVR
modules. Note the state of the LED. Is the LED on or off?
If you have connected pin 20 (AD0-DIO0) on the XMTR to 3.3 volts,
the LED should not light. Move the connection on pin 20 (AD0-DIO0) on the
XMTR from 3.3 volts to ground. What happens now? The LED should turn
on, but perhaps not immediately.
Remember, the XMTR transmits new information only every two seconds.
It has a delay of one second between samples and it takes two samples, so it
can take as long as two seconds for the LED to change state after you change
the jumper at the XMTR from 3.3 volts to ground, or vice versa. If you think
a digital input will change faster than every two seconds, you might need to
increase the sample rate at the transmitter accordingly so an XBee receiver
module gets the digital information in a timely fashion.
You now have wireless control of the LED at the RCVR module based on
the logic input at the DIO0 pin at the XMTR module. You could use a switch,
pushbutton, or other mechanical device instead of the jumper at the XMTR
module to cause an action at the RCVR module. The XBee modules operate from a 3.3-volt power supply, so you also could connect digital inputs to
3.3-volt-compatible logic devices such as a microcontroller or individual logic
circuits. Also, you could use several digital inputs and outputs in parallel.
In the next experiment, you will learn how the XBee modules can transfer
analog signals--voltages between ground (0 volts) and 3.3 volts.
Step 11. Optional. If you would like the LED to respond faster, what
could you do?

30

Use an XBee Module for Remote Control

You could reduce the time between transmissions on the XMTR module
and also go from two samples to only one sample per transmission.
Program the XMTR for a sample rate of 1/4 second and only one sample.
Remember 1/4 second equals 250 milliseconds, for a setting:
IR – Sample Rate	  FA
IT – Samples before TX	  1
Or you could use the IC – DIO Change Detect command to configure the
XMTR module to transmit new digital-input information as soon as the DIO0
input changes state from a logic 0 to a logic 1 or vice versa. You will learn how
to do that in another experiment.

Experiment | 5

XBee Modules Transfer
and Control Analog
Signals
REQUIREMENTS
2 XBee modules
2 XBee adapters
1 3.3V DC power supply
1 LED
1 220-ohm, 1/4-watt resistor, 10% (red-red-brown)
1 10-kohm (10,000-ohm) variable resistor (trimmer)
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Solderless breadboard
Digi X-CTU software running on a Windows PC, with an open USB port
Small screwdriver, flat blade

INTRODUCTION
In Experiment 4 you learned how an XBee transmitter (XMTR) can send digital (on/off) information to an XBee receiver module (RCVR). XBee modules
also can communicate voltage information. When you change the voltage on
a pin at a transmitter module an output on a receiver will change its output
accordingly. Each XBee XB24 module provides two voltage outputs and six
voltage inputs. A digital signal exists in only one of two discrete states; logic
0 or logic 1. An analog voltage can exist at any voltage, say 1.236 volts or
1.249 volts, without any defined voltage increments or steps.
Step 1. You will use an experimental setup that includes two XBee adapters in a solderless breadboard. As shown in Figure 5.1, each adapter should
have only power (3.3 volts at pin 1) and ground (0 volts at pin 10) connected
to it. If you have other connections, please remove them now. Turn off power
to the breadboard.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

31

32

XBee Modules Transfer and Control Analog Signals
Top View
+3.3 volts

Ground

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 5.1 For this experiment you need two XBee adapters inserted in your solderless breadboard and each adapter must connect to power and ground. Pin numbers refer to
XBee-module pins.

Ensure you have the X-CTU program running on your Windows PC. If you
have the transmitter (XMTR) or receiver (RCVR) module in an adapter on the
breadboard, remove the modules and set them aside. Leave the adapters in the
breadboard. For this experiment, both modules require programming with new
parameters.
Step 2. Six of the general-purpose I/O pins, AD0-DIO0 through AD5DIO5, will accept an analog voltage. An internal analog-to-digital converter
(ADC) will convert the voltage to a 10-bit binary value. That value will range
from 0x000 to 0x3FF. The connection of the reference-voltage input (pin 14,
VREF) on a module to a stable voltage establishes the upper limit of the voltage signal the ADC can convert to a digital value. The ADC always has a lower
limit of 0 volts. In practice you would use a stable voltage-reference integrated
circuit to provide a reference for ADC measurements. Experiments will use the
3.3-volt power, which will provide acceptable results. The VREF input must
not exceed the 3.3-volt supply voltage and it cannot go below 2.08 volts.
If you supply a VREF equal to 3.3 volts, the maximum ADC output,
0x3FF, corresponds to a 3.3-volt signal into the ADC. If you supply a VREF
equal to 2.5 volts—a common reference voltage—then the maximum ADC
output, 0x3FF, corresponds to a 2.5-volt signal into the ADC.
Step 3. In this step, you will use a variable resistor, also called a potentiometer, or “pot,” to change the voltage applied to a pin on a transmitter XBee
module. We often call these small variable resistors “trimmers,” or “trim pots”
because electronic designs include them to slightly adjust, or trim, a voltage. Figure 5.2 shows several types of trimmers suitable for use in a solderless breadboard. In most cases, the middle terminal connects to an internal
wiper that moves across a fixed resistor that connects to the two end terminals.
The resistance between the end terminals does not vary.

Introduction

33

FIGURE 5.2 Trimmer potentiometers, or simply “trimmers,” come in many package types
suitable for use in a breadboard.

Trimmer manufacturers use a numeric code to indicate the resistance between
the two end terminals. You will find some 10-kohm trimmers marked “10K” and
others marked “103.” The 103 means a 10 followed by 3 zeros, thus: 10,000 ohms.
Likewise, a 502 trimmer would have a resistance of 5000 ohms, or 5 kohms;
50 followed by two zeros. Some trimmers have one turn—actually about
270-degrees—and other types offer 10 turns in a larger housing. The 10-turn trimmers offer greater accuracy. These experiments use an inexpensive 1-turn trimmer.
To determine the proper connections on a 1-turn trimmer either: (a)
Download a data sheet from the supplier, or (b) Hold the trimmer and turn the
pointer fully clockwise. The arrow points to one of the end terminals. Now
turn the pointer fully counterclockwise and the arrow points to the other end
terminal. The middle terminal connects to a wiper—shown as the arrow in a
schematic circuit diagram—that provides the varying resistance.
Place a 10-kohm trimmer resistor on the breadboard and ensure each pin
goes in its own column of contacts on the breadboard. Then wire it as shown in
Figure 5.3. Connect one of the trimmer’s end terminals to ground and connect
the other end terminal to 3.3 volts. Connect the trimmer’s wiper terminal to
the adapter pin that goes to pin 20 (AD0-DIO0) for the XMTR XBee module.
Also, connect XBee module pin 14 (VREF) to the 3.3-volt power bus.
Turning the trimmer from one extreme to the other varies the voltage at the
wiper terminal—and thus at the AD0-DIO0 input—between 0 and 3.3 volts.
The XMTR module will convert this voltage to a 10-bit value and transmit it to
the RCVR module.
Step 4. Place the XMTR module in the USB-to-XBee adapter.
Click the Restore button in the X-CTU window. After you see the message “Restore Defaults..complete” click the Read button. Now set the configurations as follows. If you wish, you can load this configuration from the file
EX5_XMTR.pro:
Networking and Security:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678

34

XBee Modules Transfer and Control Analog Signals
10 kohm Trimmer
+3.3 volts

Ground

Top View
+3.3 volts

Ground

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0

VREF

+3.3 volts

FIGURE 5.3 Wiring diagram for the XMTR XBee adapter in a solderless breadboard. Pin
numbers refer to XBee-module pins.

I/O Settings:
D0 – DIO0 Configuration
choose: 2-ADC
IT – Samples before TX
 02
IR – Sample Rate		
 03E8
Instead of setting the AD0-DIO0 line (pin 20) as a digital input, you have
now set it to provide an analog input for the ADC in the XMTR module.
Click on Write to save this configuration information in the XMTR module. Insert the XMTR module into the adapter with the 10-kohm trimmer connected to it.
Step 5. Place the RCVR module in the USB-to-XBee adapter.
Click the Restore button. After you see the message “Restore Defaults..
complete” click the Read button. Now set the configurations as follow. If you
wish, you can load this configuration from the file EX5_RCVR.pro:
Networking & Security:
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234
Under the “I/O Line Passing” heading, go to the line labeled “P0-PWM0
Configuration” and click on it. Change this setting to:
P0 – PWM0 Configuration
2-PWM OUTPUT
and change:
IA – I/O Input Address		
 FFFF
The 2-PWM OUTPUT setting configures pin 6 (PWM0-RSSI) as the output at the RCVR XBee module that corresponds to the AD0-DIO0 voltage
input on the XMTR module.
Step 6. Click on Write to save this configuration in the RCVR, but leave
the RCVR module in the USB-to-XBee socket. You will use the X-CTU
program to monitor the information sent by the XMTR module.

Introduction

35

Step 7. Switch the X-CTU display to the Terminal screen, clear it, and
change to the Show Hex setting if the Terminal window is not already in this
mode.
Apply power to the XMTR module and use a small screwdriver to slowly
adjust the potentiometer. Remember, the XMTR module takes two readings
one second apart and then transmits them to the RCVR module, so data will
appear and show changes only every two seconds.
In the Terminal window you should see data that looks somewhat like:
7E

00 0C 83 56 78 2E 00 02 02 00 02 41 02 41 F6

.....
7E 00 0C 83 56 78 2E 00 02 02 00 00 00 00 00 26

To stop receiving data just turn off the XMTR module. You can turn it
on again later. The following breakdown shows the structure of the received
information. The upper portion duplicates information seen previously in
Experiment 3. The lower portion also might look somewhat familiar.
7E	  start of transmission
00 0C	  number of bytes in transmission
83	  code for 16-bit module addressing
5678	  16-bit address
2E	  signal strength
00	  status byte
02	  number of samples
02 00	  Active-Signal Bytes
02 41	  first of two samples
02 41	  second of two samples
F6	  checksum
The information in Table 5.1 includes data from the first ActiveSignal Byte, 0x02 (000000102), and the second Active-Signal Byte, 0x00
(000000002), to indicate an active AD0-DIO0 pin as an analog input and no
active digital I/O lines.
Because you have no active digital I/O pins on the XMTR module, it will
not transmit any digital information to the RCVR module. The XMTR module
will send data only for active inputs. So in this experiment you will see two
10-bit samples in each transmission from the XMTR because you set it to take
two samples from one ADC input and transmit them.
The two ADC values appeared in the transmission as 0x0241 and 0x0241
on my PC. In this example they show equal values because I didn’t adjust the
trimmer while the XMTR performed the analog-to-digital conversions. (You
may go ahead and adjust the trimmer to see how it affects your ADC values.)
The information in Table 5.2 shows how to interpret the two bytes that hold
a 10-bit value from the transmitter’s ADC. The two most-significant bits in the

36

XBee Modules Transfer and Control Analog Signals

Table 5.1 The Active-Signal Bytes Sent by a Remote XBee Module let you
Determine which Analog Inputs and Digital I/O Pins are Active
First Active-Signal Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

A5

A4

A3

A2

A1

A0

D8

Data

0

0

0

0

0

0

1

0

Second Active-Signal Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

0

0

0

0

0

0

0

0

Table 5.2 Arrangement of Bits Received from a 10-Bit Analog-To-Digital Conversion
at a Remote XBee Module
First Analog-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

A9

A8

Data

0

0

0

0

0

0

1

0

Second Analog-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

A7

A6

A5

A4

A3

A2

A1

A0

Data

0

1

0

0

0

0

0

1

10-bit value arrive in the First Analog-Data Byte, 0x02 (000000102), and correspond to bits AD9 and AD8. The remaining eight bits from the ADC arrive in
the Second Analog-Data Byte, 0x41 (010000012), and correspond to bits AD7
through AD0. Keep in mind these labels refer to bits in the 10-bit ADC output,
not to I/O pins AD0, AD1, and so on. The XBee-module pins have complete
labels, such as AD2-DIO2, and so on.
Step 8. What voltage does the 0x0241 value represent? You can combine
the 10 bits to 10010000012, or keep it as 0x241. When you convert 0x0241 to
decimal you get 577. The maximum value for a 10-bit converter equals 0x3FF,

Introduction

37

or 1023, but the results include 1024 possible values. The ratio of 577 to 1024
multiplied by the VREF voltage (3.3 volts) gives you the voltage applied via
the trimmer to the AD0-DIO0 input at the XMTR module.
You transferred this value via a wireless link, and:
(577 / 1024) * 3.3 volts  1.86 volts
So, the 1.86-volt “signal” now appears as the hex value 0x0241 at the
receiving XBee module. So at the time of my first measurements, the trimmer supplied 1.86 volts to pin 20 on my XMTR. How would you interpret the
10-bit ADC value 0x16F for a 2.5-volt reference? (Here’s where a hexadecimal
calculator can help convert values.)
0x16F  367
(367 / 1024) * 2.5 volts  0.90 volts
Remember, you can only perform a conversion when you set an input pin
for an ADC input, and only AD0-DIO0 through AD5-DIO5 have this ADC
capability.
Although we know the voltage at my trimmer as a number, it would help if
the receiver module could actually produce an analog voltage. It can, as you’ll
learn in the next steps.
Step 9. Turn off power to your breadboard. Remove the RCVR module
from the USB-to-XBee adapter and insert it into the second (unused) XBee
adapter on your breadboard.
Connect one lead of a 220-ohm resistor (red-red-brown) to the XBee
RCVR module PWM0-RSSI signal at pin 6 as shown in Figure 5.4. Insert
the other resistor lead into an unused column of contacts on your breadboard.
Connect an LED between the resistor lead in the unused column of contacts and 3.3 volts. Connect the LED’s long lead (anode, ) to 3.3 volts.
Connect the LED’s shorter lead (cathode, ) to the resistor lead in the unused
column of contacts.

Top View
+3.3 volts
Anode
LED
Cathode
PWM0–RSSI
220 ohms

Ground

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 5.4 This diagram shows the connection of power and ground to the RCVR
XBee module as well as an added LED and resistor connected between 3.3 volts and the
PWM0-RSSI signal at pin 6.

38

XBee Modules Transfer and Control Analog Signals

Step 10. Set the trimmer at the XMTR module about halfway between its
end positions. Turn on power to your breadboard. The LED connected to the
RCVR module should turn on within a second or two.
Adjust the trimmer in small increments. Remember, it can take as long as
two seconds for the XMTR module to send updated voltage information to the
RCVR module. Do you remember why? You set the XMTR module to take
two samples one second apart and then transmit the values from the ADC, so
you might not see an immediate change in LED brightness when you vary the
trimmer setting. As you slowly adjust the trimmer between its end points you
should see the LED go from off to full brightness.
Step 11. Optional: If you would like a faster response, reprogram the
XMTR module with a shorter delay between samples:
IR – Sample Rate  0x03E8 (1-second delay)
For a 1/4-second sample rate, use 250 milliseconds (0xFA) or for a 1/10thsecond sample rate, use 100 milliseconds (0x64).
Remember to first Read the parameters from the XMTR module, then
modify the IR – Sample Rate parameter and save it in the XMTR module.
Place the module back in its socket adapter and turn on power. Does the LED
respond faster to trimmer changes? It should.
Step 12. In this step you will learn how the voltage output works on the
RCVR module.
It appears the RCVR module produces a voltage between 0 and 3.3 volts
to match the voltage measured at the XMTR module. The changing voltage
would account for the changes in the LED’s brightness. But the RCVR does not
operate this way. Instead, the PWM0 output at pin 6 produces a pulse-widthmodulated (PWM) output that comprises a series of electrical pulses at a constant frequency. The received voltage value determines the width of these pulses.
The plot in Figure 5.5 shows voltage (y axis, 1 volt/division) vs. time
(x axis, 50 μsec/devision). Most of the time the PWM0 output remains at
0 volts, so current flows from 3.3 volts through the LED, which turns on.
Although our eyes cannot see the LED turn on or off, it does so, and the long
LED-on periods mean the LED appears bright. In Figures 5.5, 5.6, and 5.7, the
horizontal line labeled T represents the trigger-voltage level of 750 mV.
Figure 5.6 shows another plot of voltage vs. time for the PWM0 output
but with the trimmer at the XMTR module positioned about halfway between
its end points. Now the PWM0 output at the RCVR module is on or off for
about half the time. The LED appears at about half brightness because it is on
(logic 0) for a shorter time than that shown in Figure 5.5.
The pulses shown in Figure 5.7 cause the LED to turn on only during the
short logic-0 periods, so it appears dim, or perhaps off. The frequency of the
pulses—about 16 kilohertz, or 16 kHz—remained the same in each of the three
plots. Only the pulse widths changed.
Step 13. In some cases you need a real voltage output, not a series of
pulses. You can build an electrical low-pass filter that smoothes the pulses into
a voltage output. The circuit diagram in Figure 5.8 shows a simple filter that

Introduction

39

FIGURE 5.5 This pulse-width-modulated output shows an output in a logic-0 state, or
ground, most of the time. You would see this type of output when you have set the trimmer
on the XMTR module close to 0 volts.

FIGURE 5.6 A PWM output in which the on and off times are approximately equal for
each pulse period. The trimmer on the XMTR module is set about halfway between 0
and 3.3 volts.

averages the high and low parts of the PWM signal to create a steady voltage.
This filter circuit replaces the LED circuit shown earlier in Figure 5.4.
Depending on whether you changed the sample period for the XMTR module, it still might take a second or two for the voltage output to reflect a change

40

XBee Modules Transfer and Control Analog Signals

FIGURE 5.7 The pulses in this plot of voltage vs. time remain at 3.3 volts most of the
time. Thus, the trimmer at the XMTR module is set close to its 3.3-volt end.

PWM0–RSSI In

1000

1000
+

Ground

10 uF

Voltage Out
+

10 uF
Ground

FIGURE 5.8 This simple low-pass filter produces an average voltage output from the
pulses created at the PWM0 output at the RCVR XBee module.

at the XMTR trimmer because the XMTR still samples its ADC twice before it
transmits the values to the RCVR module.
An XBee module has two independent PWM outputs; pin 6 (PWM0RSSI) and pin 7 (PWM1). Digi International has associated each PWM output
with a specific ADC input. The AD0-DIO0 analog input controls the output
at a receiver’s PWM0-RSSI pin (pin 6) and the AD1-DIO1 input controls the
receiver’s PWM1 pin (pin 7).
If you must create an output on PWM0, configure the PWM0 output on
the receiver for PWM, and configure the AD0-DIO0 input as an ADC input
on the transmitter.
Step 14. The RCVR module does not “know” the reference voltage
(VREF) used by the ADCs on the XMTR module. It simply passes along the
ADC values, which range from 0x000 to 0x3FF. As explained earlier in Step 2,
if you supply a VREF equal to 3.3 volts, the maximum ADC output, 0x3FF,
corresponds to a 3.3-volt signal into the ADC. If you supply a VREF equal
to 2.5 volts, then the maximum ADC output, 0x3FF, corresponds to a 2.5-volt
signal into the ADC.

Introduction

41

So, if you have a 2.5-volt reference voltage at the XTMR module, the ADC
provides the value 0x3FF for a measured voltage of 2.5 volts and 0x000 for a
measured voltage of 0 volts, or ground.
But at the RCVR module, the PWM output continues to produce signals that
vary from 0 to 3.3 volts as their widths change. If you use a filter circuit, such as
that shown in Figure 5.8, on the PWM output you see the filter’s Voltage Output
signal vary from 0 volts to 3.3 volts rather than from 0 to 2.5 volts measured at
the transmitter. You have two ways to handle this mismatch:
1. Use precision resistors to create a voltage divider that scales the filtered
PWM output to the same range provided by the ADC at the transmitting
XBee module. Then use an operational-amplifier (op amp) follower circuit
as a high-impedance-input, low-impedance-output buffer. The simple circuit shown in Figure 5.9 uses two resistors to produce a 0-to-2.5-volt output
from a 0-to-3.3-volt input, assuming a 2.5-volt VREF input at the XMTR
module. The Microchip Technology MCP6004 op amp serves as the buffer.
I wanted a maximum of 2.5 volts at the  input to the op amp and chose the
4750-ohm resistor as a starting value. Next I used Ohm’s law to calculate the
current through the 4750-ohm resistor for a 2.5-volt signal:
IE/R
So, 2.5 volts across this resistance yields:
2.5 V / 4750 ohms  0.526  103 amperes
That small current—about half a milliamp—will not exceed the specification for the PWM0 output on the RCVR module. The current through the other
two resistors from the 3.3-volt input also must equal 0.532  103 amperes
and the voltage across those resistors equals: 3.3 volts  2.5 volts, or 0.8 volts.
Using Ohm’s law again:
I  E / R or R  E / I
0.8 volts / 0.526  103 amperes  1521 ohms

0 to 3.3 V In
1470 ohms
+3.3 V
49.9 ohms
3
4750 ohms

2

+
–

4 MCP6004 (14 pin)
1
0 to 2.5 V Out
11

FIGURE 5.9 This circuit uses a voltage divider to scale a 0-to-3.3-volt signal to a 0-to2.5-volt output. An op-amp buffer provides the output signal.

42

XBee Modules Transfer and Control Analog Signals

You cannot find a 1521-ohm resistor, but a 1470-ohm resistor in series with
a 49.9-ohm resistor will give you 1519.9 ohms, which comes close enough.
These resistors all have a 1-percent tolerance. Although the XBee ADC provides a resolution of one part in 1024, or about 0.1 percent, in practice, you
will get about 1-percent accuracy, which matches well with the 1-percent
resistor tolerance.
Op-amp circuits go beyond the scope of this series of experiments, though.
Find useful information in the following references:
l
Baker, Bonnie, “Using Single Supply Operational Amplifiers in Embedded
Systems,” AN682, Microchip Technology, http://ww1.microchip.com/
downloads/en/AppNotes/00682D.pdf.
l
“Op Amps for Everyone,” Texas Instruments document number:
SLOD006B. http://focus.ti.com/lit/an/slod006b/slod006b.pdf.
l
“A Single-Supply Op-Amp Circuit Collection,” Texas Instruments document number: SLOA058. http://www.ti.com/lit/an/sloa058/sloa058.pdf
2. Process the data from an ADC at a remote module with software that runs
on a small MCU. As you saw in the first part of this experiment, the RCVR
module provides the ADC data in the hex values it sends out its serial
port. Later experiments explain how you can connect an XBee receiver to
an MCU, parse packets, and then calculate voltages based on the known
reference voltage at a transmitter.

Notes
If you wish, you can set the PWM0 or PWM1 output as a received signalstrength indicator (RSSI). You would select RSSI for the PWM0 Configuration
or for the PWM1 Configuration in the X-CTU software via the Modem
Configuration window. Then connect an LED as shown in Figure 5.4 to indicate the signal strength.
If you set the PWM0-RSSI output (pin 6) for RSSI on the RCVR module and place your hand over the XMTR or RCVR module you can affect the
signal strength measured at the receiver. You should see RSSI output vary as
indicated by the brightness of the attached LED. It’s unlikely you will need an
RSSI indication except for testing and debugging an electronic system based
on XBee modules.
The article, “PWM RSSI signal – ATRP command for analog RSSI indication” on the Digi International Web site provides a circuit for a 3-level signalstrength indicator. See: http://www.digi.com/support/kbase/kbaseresultdetl.
jsp?id2031.

Experiment | 6

Remote Control of
Digital and Analog
Devices
REQUIREMENTS
2 XBee modules
2 XBee adapters
1 3.3V DC power supply
2 LEDs
2 220-ohm, 1/4-watt resistors, 10% (red-red-brown)
1 4700-ohm, 1/4-watt resistor, 10% (yellow-violet-red)
1 10-kohm, 1/4-watt resistor, 10% (brown-black-orange)
1 10-kohm (10,000-ohm) variable resistor
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port
Small screwdriver, flat blade
Optional
1 39-kohm, 1/4-watt resistor, 10% (orange-white-orange)
1 Photoresistor, PDV-P9003-1 (see Bill of Materials in Appendix F)
1 5V DC power supply

INTRODUCTION
In Experiments 4 and 5 you learned how an XBee transmitter can remotely
control a digital or an analog output at a receiver. In this experiment, you
will configure a transmitter to send both analog and digital information. The
receiver will drive two LEDs, one with a digital (on/off) output and one with
43
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

44

Remote Control of Digital and Analog Devices

an analog output that varies LED brightness. You also will learn how to parse
the digital and analog information received from a transmitter that has active
digital and analog inputs and takes several samples.
Step 1. If you have a powered breadboarded circuit, please turn off the
power. Remove the XMTR module from its socket adapter, place it in the
USB-to-XBee adapter and connect the adapter to the PC’s USB cable. Run
the X-CTU program and test communications with the XMTR module.
If you don’t know the state of configuration settings, click on Restore and
then click Read to obtain the default settings.
Now set the configurations as follows:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
D0 – DIO0 Configuration	  2-ADC
D3 – DIO3 Configuration	  3-DI
IT – Samples before TX	  02
IR – Sample Rate	  3E8
You can find this configuration profile in EX6_XMTR_A.pro.
Recheck these settings and save them in the XMTR module. The parameter
settings above duplicate those from Experiment 5 but now include a setting to
configure pin 17 (AD3-DIO3) as a digital input.
Step 2. Place the XMTR module in its adapter socket on the breadboard.
Ensure you have the power (pin 1) and ground (pin 10) connections to the
XMTR module. Add a jumper wire between 3.3 volts and pin 17 on the
XMTR XBee module. This wire lets you change the logic state of the DIO3
input on the XMTR module as shown in Figure 6.1. If not already connected,
add the 10-kohm trimmer and the reference-voltage (VREF) connections.

10–kohm Trimmer
+3.3 volts

Ground

Top View
+3.3 volts

Ground

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0
+3.3 volts
AD3–DIO3

VREF

Jumper
Ground

+3.3 volts

FIGURE 6.1 This XMTR module has a digital input at its AD3-DIO3 pin and an analog
input at its AD0-DIO0 input.

Introduction

45

Step 3. Insert the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable. If you don’t know the state of configuration
settings, click on Restore and then click Read to obtain the default settings.
Now set the configurations as follow:
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234
D3 – DIO3 Configuration	  5 D0-HIGH
I/O Line Passing:
P0 – PWM0 Configuration	  2-PWM Output
IA – I/O Input Address	  FFFF
You can find this configuration profile in EX6_RCVR_A.pro.
Recheck these settings and save them in the RCVR module. Leave the
RCVR module in the USB-to-XBee adapter connected to the PC. The parameter settings above duplicate those from Experiment 5 but add a setting to configure pin 17 (AD3-DIO3) on the RCVR module to output a digital signal.
Step 4. Set the trimmer connected to the XMTR module at about halfway
between its end points. Change the X-CTU program to the Terminal window
and set it to display hex values. Clear the Terminal window. Turn on power to
the breadboard and watch as the X-CTU program displays hex values. When I
ran this experiment, I found these results; your results will vary:
7E 00 10 83 56 78 2F 00 02 02 08 00 08 02 02 00 08 02 02 5B
7E 00 10 83 56 78 2F 00 02 02 08 00 08 02 02 00 08 02 02 5B
.....

In this experiment you should see more bytes of information than you saw
in Experiments 4 and 5, in which you had either a digital or an analog input at
the XMTR module. Now you have a digital input and an analog input.
You can break down the hexadecimal message shown above into two sections:
7E	  start of transmission
0010	  number of bytes in transmission
83	  code for 16-bit module addressing
5678	  16-bit address
2F	  signal strength
00	  status byte
02	  number of samples
0208	  Active-Signal Bytes
0008	  first digital-input sample
0202	  first analog-input sample
0008	  second digital-input sample
0202	  second analog-input sample
5B	  checksum
Take the two Active-Signal Bytes 0x02 and 0x08 and fill in the spaces in
Table 6.1 with the equivalent binary bits. Can you tell which inputs are active
at the transmitter?

46

Remote Control of Digital and Analog Devices

Table 6.1 This Table lets you Determine which Analog or Digital
Pins the Transmitting Module has in use
First Active-Signal Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

A5

A4

A3

A2

A1

A0

D8

Data

0

Second Active-Signal Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

The first Active-Signal Byte—0x02 or 000000102—indicates you have
an active A0 analog-input channel and the second Active-Signal Byte—0x08
or 000010002—indicates you have an active D3 digital-input channel, which
corresponds to the AD3-DIO3 input (pin 17). Those settings should match the
configuration you programmed in the XMTR module.
When an XBee module transmits both digital and analog information in two
samples, the received digital and analog information for sample one appears
first, followed by digital and analog information for sample two, and so on.
Given the first pair of Digital-Data Bytes, 0x00 and 0x08, fill in the spaces in
Table 6.2 to determine the state of the any active digital inputs identified in
Table 6.1. Remember to look only at the digital information for the active inputs.
Now look at the value in the first sample received from the ADC at the
AD0-DIO0 input. The first pair of bytes from the ADC equals 0x02 0x02, or
000000102 000000102. Table 6.3 shows the arrangement of bits for an ADC.
Fill in the bits in Table 6.3 to determine the value from the transmitter’s ADC.
As explained in Experiment 5, you can convert the ADC data, 0x0202 in my
results, to a decimal value and compute the voltage applied at the AD0-DIO0
pin (pin 20) at the XMTR. I calculated a voltage of 1.7 volts for my values.
Your experimental setup will probably have different analog values, depending
on how you set the trimmer in your XMTR-module circuit. Calculate the voltage for your 10-bit ADC value displayed in the X-CTU terminal window. For a
hexadecimal calculator, visit: http://www.squarebox.co.uk/hcalc.html?0.
Step 5. In this step, clear the Terminal window, and turn on the XMTR module. Watch the digital and analog data change in the Terminal window as you
move the wire connected to pin 17, the AD3-DIO3 digital input, to ground, then
to 3.3 volts, then back to ground. You should see the first Digital-Data Byte
value remain 0x00. The second byte will change from 0x00 for a logic-0 (ground)
input to 0x08 for a logic-1 (3.3 volts) input at the AD3-DIO3 digital input.

Introduction

47

Table 6.2 This Table lets you Determine the State of all Active
Digital Inputs Identified by the Active-Signal Bytes in a Transmission
from a Remote XBee Module
First Digital-Data Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

X

D8

Data

0

0

0

0

0

0

0

Second Digital-Data Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

Table 6.3 Fill in this Table to show the Bits in the two Bytes
Received from an Active ADC input in a Transmission from a
Remote XBee Module
First Analog-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

A9

A8

Data

0

0

0

0

0

0

Second Analog-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

A7

A6

A5

A4

A3

A2

A1

A0

Data

Also change the trimmer settings to confirm you can see the 10-bit ADC
value change. You can turn off the XMTR’s power to stop transmissions so
you can read the digital and analog information. Remember, the XMTR still
acquires two samples from the digital and ADC inputs before it transmits, so
you should see a new transmission of two sets of data every two seconds.
Step 6. Turn off power to your breadboard. In this step, you will configure another analog input at the XMTR to see how it affects the received data.

48

Remote Control of Digital and Analog Devices

Remove the RCVR module from the USB-to-XBee adapter and set it aside.
Remove the XMTR module from its adapter on the breadboard and insert it
into the USB-to-XBee adapter. Change to the Modem Configuration window
and read the configuration data from the XMTR module.
Leave all Modem Configuration information as it is for the XMTR module,
but set:
D1 – DIO1 Configuration  2-ADC
You can find the complete configuration profile in EX6_XMTR_B.pro. The
RCVR module needs no configuration changes.
Recheck your configuration settings and save them in the XMTR module.
Remove the XMTR module from the USB-to-XBee adapter and insert it in its
breadboard adapter socket. Connect the AD1-DIO1 pin (pin 19) on the XMTR
module to the two resistors as shown in Figure 6.2 to create a constant voltage
for this analog-input pin.
Place the RCVR module back in the USB-to-XBee adapter. Clear the
X-CTU Terminal window and turn on power to the breadboard. Here’s the data
I observed with the input-data bytes underlined:
7E 00 14 83 56 78 3F 00 02 06 08 00 00 02 3E 01 4E 00 00 02 3E
01 4D 42

Again, turn off power to the XMTR module to stop transmissions so you
can read the information in the Terminal window. Use Tables 6.1, 6.2, and 6.3
to decode the information above. Then decode the information shown in your
Terminal window. Find blank tables you can copy in Appendix I. I put the
answers for my series of data bytes at the end of this experiment.

10–kohm Trimmer
+3.3 volts

+3.3 volts
10k

Top View
+3.3 volts

1

20

2

19

3

18

4

17

5

Ground

XBee XB24

AD0–DIO0
AD1–DIO1
AD3–DIO3

4700
Jumper

16

6

15

7

14

8

13

9

12

10

11

VREF

+3.3 volts

FIGURE 6.2 The circuit for this part of Experiment 6 requires these connections to
create two analog inputs (pins 19 and 20) and a digital input (pin 17).

Introduction

49

Step 7. In this step, you will connect two LEDs to the RCVR module and
control one as a digital (on/off) device and the other as a variable (analog) device.
You’ll increase the sample rate so you can see changes at the LEDs occur faster.
Turn off power to your breadboard. Remove the XMTR module from the
breadboard and set it aside. Remove the RCVR XBee module from the USBto-XBee adapter and set it aside, too. Remove the wire at the XMTR adapter
between pin 19 and the 10-kohm and 4700-ohm resistors. Figure 6.1 shows the
proper wiring for the XMTR module. Place the XMTR module in the USB-toXBee adapter.
Set the XMTR-module configurations to:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
D0 – DIO0 Configuration	  2 – ADC
D1 – DIO1 Configuration	  0 – DISABLED
D3 – DIO3 Configuration	  3 – DI
IT – Samples before TX	  01
IR – Sample Rate	  64
You can find the complete configuration profile in EX6_XMTR_C.pro.
Recheck the XMTR configuration information and save it in the XMTR module. Place the XMTR module in its adapter on the breadboard.
You should have a second XBee adapter in your breadboard. If you do
not, insert it now. Next add the components described in the next section and
shown in Figure 6.3 to the RCVR module.
l
Connect a 220-ohm (red-red-brown) resistor between 3.3 volts and an
open column on your breadboard. Connect an LED between the open end
of the 220-ohm resistor and the RCVR pin 6 (PWM0-RSSI). Ensure you

+3.3 V

220
LED

Anode
PWM0–RSSI

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD3–DIO3

220

Anode
LED
Cathode

Ground

FIGURE 6.3 The RCVR module should have two LEDs connected to it, one to the PWM0
output and another to the DI03 output.

50

Remote Control of Digital and Analog Devices

connect the longer LED lead to the 220-ohm resistor and the shorter lead to
the PWM0-RSSI pin.
l
Connect a 220-ohm (red-red-brown) resistor between RCVR pin 17
(AD3-DIO3) and an open breadboard column. Then connect an LED
between the free end of the 220-ohm resistor and ground. Ensure you
connect the shorter LED lead to ground and the longer lead to the 220-ohm
resistor.
Set the RCVR-module parameters to:
DL – Destination Address Low	  0x5678
MY – 16-Bit Source Address	  0x1234
D3 – DIO3 Configuration	  5 D0-HIGH
I/O Line Passing:
P0 – PWM0 Configuration	  2-PWM OUTPUT
IA – I/O Input Address	  0xFFFF
You can find this configuration profile in EX6_RCVR_C.pro.
Place the RCVR module in its adapter on the breadboard.
Step 8. Apply power to your breadboard. The brightness of the LED connected to RCVR pin 6 (PWM0-RSSI) should vary from off to full-on as you
change the trimmer setting at the XMTR module. As you move the wire that
connects to XMTR pin 17 (AD3-DIO3) between ground and 3.3 volts, and
back to ground, the LED connected to pin 17 (AD3-DIO3) at the RCVR module should turn on or off.
You have successfully controlled an analog and a digital device at the
RCVR module based on an analog voltage and a digital signal at the XMTR
module. The XMTR and RCVR modules could be placed 100 feet or more
from each other and still perform this type of control.
Important: The digital I/O pins on XBee modules have a one-to-one relationship. If, for example, you set AD4-DIO4 as a digital input on a transmitter and set AD4-DIO4 as an output on a receiver with the corresponding DL
and MY addresses, you have direct control of the output at the receiver by
changing the state of the input pin on the transmitter. The circuit does not need
additional components. Because an XBee module has as many as seven ADx –
DIOx pins, you can independently control as many as seven remote devices.
You also could employ seven remote modules and control one digital output on
each one from one transmitter.

OPTIONAL STEPS
The next steps substitute a cadmium-sulfide (CdS) photoresistor and a fixedvalue resistor for the trimmer potentiometer. This circuit will let you control
the brightness of the LED on the PWM0 output at the RCVR module based on
the light intensity at the photoresistor.
Step 9. Turn off power to your breadboard and remove the 10K-ohm trimmer connected to the XMTR module. Now insert the photoresistor between
the ground wire that went to the trimmer and the wire that connects to pin 20

Optional Steps

51

+5 volts
39k

Top View
+3.3 volts

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0

Photoresistor

VREF

+3.3 volts

FIGURE 6.4 In this circuit, a photoresistor and a fixed-value resistor form a voltage
divider that produces about a 3-volt output in complete darkness to about a 0.1-volt output
in bright light.

(AD0-DIO0) at the XMTR module. The photoresistor does not have a polarity,
so you do not have to think about a cathode or an anode. Insert the 39-kohm
resistor between the 3.3-volt wire that went to the trimmer and pin 20.
Figure 6.4 shows a circuit diagram for the photoresistor and its connection to
the XMTR module.
Step 10. Turn on power to the breadboard and shine a light on the
photoresistor. You should see the LED connected to pin 6 (PWM0-RSSI)
on the RCVR module decrease in brightness. As you block the light to the
photoresistor, the LED should decrease in brightness. This part of the experiment uses a 5-volt power supply for the photoresistor circuit so the circuit provides a wide range of voltages to the XMTR module’s ADC input.
The PDV-P9003 photoresistor has a log-log response which means you do
not see a simple one-to-one ratio between illumination on the photoresistor and
light output from the LED. Download the Advanced Photonix data sheet for a
graph of photoresistor resistance versus illuminance in units of lux. This photoresistor will respond to light between violet and red in the visible spectrum
and it has the maximum sensitivity at 520 nanometers (nm), which corresponds to green light.
Step 11. Turn off power to your breadboard and remove the RCVR module from its adapter. Insert the RCVR module in the USB-to-XBee adapter.
Change the X-CTU window to the Terminal view and clear the Terminal
window. Illuminate the photoresistor as brightly as you can and turn on power
to the breadboard. Look in the Terminal window for the hex values that correspond to the ADC data from the XMTR module. What do you see? (You can
turn off power to the XMTR module after you see several packets of information from the XMTR so you can better read the ADC values.)

52

Remote Control of Digital and Analog Devices

With a 60-watt lamp placed a few inches above the photoresistor, I read the
hex value 0x000F in the Terminal window; the value received from the ADC
on the XMTR module.
Now repeat the measurement with the photoresistor darkened. Do you see
a change?
I saw ADC values between 0x3EE and 0x3F5, which is almost a full-scale
reading (0x3FF) from the ADC.
You could use other resistive sensors in place of the photoresistor and fixed
resistor. Use Ohm’s Law and choose resistance values so the sensor output has
a range between 0 volts and the VREF voltage applied to the XBee module
VREF input at pin 14. The VREF input must not exceed 3.3 volts.

ANSWERS TO QUESTIONS IN STEP 6
For the string of hex values I obtained:
7E 00 14 83 56 78 3F 00 02 06 08 00 00 02 3E 01 4E 00 00 02 3E
01 4D 42

I “decoded” the following:
02
 number of samples
0608  indicates active analog and digital channels:
AD0-DIO0 active as an analog input
AD1-DIO1 active as an analog input
AD3-DIO3 active as a digital input
First sample:
0000	  AD3-DIO3 input at a logic 0
023E	  AD0-DIO0 analog input (57410)
014E	  AD1-DIO1 analog input (33410)
Second sample:
0000	  AD3-DIO3 input at a logic 0
023E	  AD0-DIO0 analog input (57410)
014E	  AD1-DIO1 analog input (33410)
Your measurements for the DIO3 and ADC0 inputs will vary from mine,
depending on how you set the trimmer and whether you have the AD3-DIO3
input connected to 3.3 volts or ground. The 0x014E reading from ADC1 represents 1.07 volts, which corresponds to the 1.05-volt value calculated for the
10-kohm and 4700-ohm resistor voltage-divider circuit.

Experiment | 7

How to Transmit Data
on a Logic-Level
Change
REQUIREMENTS
2 XBee modules
2 XBee adapters
1 3.3-volt DC power supply
1 10-kohm (10,000-ohm) variable resistor
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
X-CTU software running on a Windows PC, with an open USB port
Small screwdriver, flat blade
Copies of the tables from Appendix I

INTRODUCTION
In Experiment 6, an XBee module transmitted data continuously based on the
Sample-Rate and the Samples-before-TX parameters set with the X-CTU program. If an equipment designer selected a long sample rate—a long period
between samples—the equipment could miss detecting a change at one of the
XBee module’s digital inputs when it occurs. Suppose you have connected sensors to the digital inputs on an XBee transmitter to detect when certain doors or
windows open while homeowners work outdoors. You want an XBee receiver to
let them know immediately about a window that opens, not, say, 10 minutes later
when the XBee transmitter takes its periodic sample of window and door sensors. In this experiment you will learn how to configure a transmitter so a change
on one or more of its digital inputs forces it to transmit digital-input information.
53
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

54

How to Transmit Data on a Logic-Level Change
10 kohm Variable Resistor
+3.3 volts

Ground

Top View
+3.3 volts

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0

+3.3 volts

AD1–DIO1
AD3–DIO3

VREF

+3.3 volts

Ground

FIGURE 7.1 The connections in this circuit let you change digital inputs from logic-0 to
logic-1 states, or vice versa, and immediately transmit digital data.

Step 1. In this experiment the XMTR XBee module will have two digital
inputs and one analog input. Before you change any connections, turn off
power to the breadboard circuits. The circuit diagram in Figure 7.1 shows the
needed connections.
These connections to the variable resistor provides an analog signal for the
AD0-DIO0 input (pin 20). The jumpers provide digital signals at the AD1-DIO1
(pin 19) and the AD3-DIO3 (pin 17) inputs. The connection between VREF
(pin 14) and 3.3 volts supplies a reference voltage for the analog-to-digital
converter (ADC) in the XMTR module.
Remove the XMTR module from its adapter, place it in the USB-to-XBee
adapter, and connect the adapter to the PC’s USB cable. Run the X-CTU
program and test communications with the XMTR module.
In the Modem Configuration window, click on Read to obtain the configuration from the XMTR module. If you don’t know the state of configuration
settings, click on Restore and then click Read to obtain the default settings. In
the X-CTU Modem Configuration window, set the XMTR-module configurations as shown below. Do not save these settings in the XMTR module until
instructions tell you to.
DL – Destination Address Low  1234
MY – 16-Bit Source Address  5678
D0 – DIO0 Configuration
 2-ADC
D1 – DIO1 Configuration
 3-DI
D3 – DIO3 Configuration
 3-DI
IT – Samples before TX
 0A; 1010 samples
IR – Sample Rate
 3E8; 1-second sample interval

55

Introduction

Step 2. Next you will create a value for the IC-DIO Change-Detect parameter, located under the I/O Settings heading. This hexadecimal value lets you
select one or more digital inputs, DIO7 through DIO0, that can cause an immediate transmission of digital-input information. When a selected input changes
its state—from a logic 1 to a logic 0, or vice versa—it forces the XMTR module to transmit the logic state of each active digital input. The IC-DIO ChangeDetect parameter comprises one byte, as shown in Table 7.1.

Table 7.1 IC-Change-Detect Settings for Inputs DIO7 Through DIO0
IC- DIO Change Detect
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

DIO7

DIO6

DIO5

DIO4

DIO3

DIO2

DIO1

DIO0

Data

0

0

0

0

1

0

0

0

For this experiment, assume a change in the logic state at the AD3-DIO3
(pin 17) input will force the XMTR module to transmit data. You need a 1 at
position DIO3 in the IC-Change-Detect byte to correspond with an input at
AD3-DIO3. Place a 0 in the other seven bit positions so you have 000010002,
which translates to 0x08.
Within the Modem Parameters window, set:
IC – DIO Change Detect	  08
for the XMTR module. Find this configuration profile in EX7_XMTR_A.pro.
Review the settings and save them in the XMTR module. The XMTR will
now gather 10 measurements (IT  0x0A) one second apart (IR  0x3E8)
before it transmits all samples to the RCVR module. Thus new information
will appear in the X-CTU Terminal window every 10 seconds and the messages will hold 10 samples of digital- and analog-input data.
I chose the setting of ten samples for two reasons: First, so you can see
how to break down a transmission to locate all ten samples. And second, so
you will have sufficient time between the transmissions scheduled for every 10
seconds to force a transmission of digital data.
Step 3. You must understand how an XBee transmitter works when you use
the IC-Change Detect settings:
l
If an XBee module has gone part-way through a sampling sequence, it will
transmit any samples it has already acquired followed by the digital-input
information transmitted in response to a digital-input change.
l
A forced transmission of digital-input information will not include information from active ADC inputs. You will get only the digital-input information.
l
You can force a transmission of digital-input states only when the XBee
module detects a logic-level change at a digital input selected with a corresponding 1 in the IC-Change Detect command byte.

56

How to Transmit Data on a Logic-Level Change

A logic-1-to-logic-0 or a logic-0-to-logic-1 transition will trigger a transmission for a change on an input selected with the IC-Change Detect
parameter for the transmitter.
Step 4. Place the XMTR module in its adapter on the breadboard. Check
the connections to the XMTR module and the breadboard.
Step 5. Place the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable. If you don’t know the state of configuration
settings, click on Restore and then click Read to obtain the default settings.
Set the RCVR-module parameters to:
DL – Destination Address Low  5678
MY – 16-Bit Source Address
 1234
D3 – DIO3 Configuration
 5 D0-HIGH
P0 – PWM0 Configuration
 2-PWM Output
IA – I/O Input Address
 FFFF
Confirm these settings and save them in the RCVR module. Find this configuration profile in EX7_RCVR_A.pro. Leave the RCVR module in the USBto-XBee adapter connected to the PC. You will use the X-CTU program to
monitor data from the XMTR module.
Step 6. Set the variable resistor connected to the XMTR module at about
halfway between its end stops. Switch the X-CTU program to the Terminal
window and set it to display hex values. Turn on power to the breadboard and
watch as the X-CTU program displays data in hex characters. It should take 10
seconds for the first transmission to start. After you receive one or two transmissions of 10 samples, turn off power to the breadboard. You need only one
set of information to analyze.
When I ran this experiment, I found the following hex values in the
Terminal window. Reformatted values makes it easier to understand them. Your
data will look a bit different:
l

7E 00 30 83 56 78 2B 00 0A 02 0A
00 0A 01 D7
00 0A 01 D7
00 0A 01 D7
00 0A 01 D7
00 0A 01 D7
00 0A 01 D8
00 0A 01 D8
00 0A 01 D8
00 0A 01 D8
00 0A 01 D7
F6

Introduction

57

Here’s how this hex information breaks down:
7E
 start of transmission
0030  number of bytes in transmission
83
 code for 16-bit module addressing
5678  16-bit address
2B
 signal strength
00
 status byte
0A
 number of samples
020A  Active-Signal Bytes
Use copies of the tables in Appendix I to decode the Active-Signal Bytes
0x020A value and determine which analog or digital inputs are active at the
XMTR module.
You should find the AD0-DIO0 (pin 20) pin configured as an active analog
input and the AD3-DIO3 (pin 17) and AD1-DIO1 (pin 19) pins set for use as
digital I/O signals.
Again use the tables from the Appendix to decode one of the 10 samples of
analog- and digital-input information in the four columns of hex values above.
The first two bytes, 0x00 and 0x0A, provide digital data from AD3-DIO3 and
AD1-DIO1. The last two bytes, 0x01 and 0xD7, provide a value from the
XMTR module’s ADC.
What do these bytes tell you? First, the two digital inputs at the XMTR
module are in the logic-1 state. Second, the ADC value, 0x01D7, translates to
47110 or 3.3 * (471/1024) volts, which comes to about 1.52 volts.
Step 7. Now you will force the XMTR module to transmit information.
Remember you set the IC-DIO Change-Detect parameter to 0x08, which corresponds to the AD3-DIO3 input on the XMTR module. Changing the logic state
of the AD3-DIO3 input should force the XMTR to transmit the digital-input
logic states.
Please read the following lettered steps below before you perform them
because they involve making an electrical change at a specific time.
l
Clear the X-CTU Terminal window.
l
Turn on power to the breadboard.
l
After 10 seconds you should see a string of hex values appear in the
Terminal window. As soon as this happens, count off four or five seconds.
l
Then remove the XMTR connection between pin 17 (AD3-DIO3)
and 3.3-volt power at the power bus and connect this end securely
to ground. This change places a logic 0 on the AD3-DIO3 input at the
XMTR module and should force a transmission of the logic states on the
active logic inputs. This type of forced transmission will NOT include any
analog-input information. Turn off power to the breadboard.
When ready, please perform the four steps above. You can repeat them several times. Just ensure you start with a logic 1 (3.3 volts) applied at the
AD3-DIO3 input (pin 17) and when you move this connection from 3.3
volts to ground ensure you have a good ground connection. Moving the
jumper between 3.3 volts and ground provides a crude way to change logic

58

How to Transmit Data on a Logic-Level Change

states: logic 1 to logic 0. (The last section of this experiment, Make Clean
Logic Transitions, explains a better way to create clean control signals.)
Block 1
7E 00
0A 01
0A 01
0A 01
0A 01

30
D8
D7
D7
D7

83
00
00
00
90

56
0A
0A
0A

78
01
01
0A

32
D7
D7
D7

00
00
00
00

0A
0A
0A
0A

02
01
01
01

0A
D7
D7
D8

00
00
00
00

Block 2
7E 00 18 83 56 78 32 00
04 02 0A 00 0A 01 D7 00 0A 01 D8 00
0A 01 D8 00 0A 01 D7 E2
Block 3
7E 00 0A 83
56 78 33 00 01 00 0A 00 02 6E
Block 4
30
D8
D8
D8
D8

83
00
00
00
E0

56
02
02
02

78
01
01
01

2D
D8
D8
D8

00
00
00
00

0A
02
02
02

02
01
01
01

0A
D7
D7
D7

00
00
00
00

7E
02
02
02
02

00
01
01
01
01

FIGURE 7.2 This data appeared in the Terminal window when I performed the sequence
listed in Step 5. Dividing the data into blocks makes it easier to interpret.

The information in Figure 7.2 shows information from the X-CTU
Terminal window after I performed the steps above. I separated this information into four blocks for clarity and underlined the analog and digital data sent
from the XMTR module.
Each block starts with the standard start-of-transmission value (7E), number of bytes, module address, signal-strength byte, and option byte.
Block 1 shows the first transmission with 10 samples of digital and analog
information (underlined).
Block 2 shows an abbreviated set of four (0x04) samples (underlined)
taken prior to the change at the AD3-DIO3 input.
Block 3 shows only one sample, which identified only the active digital
lines and indicated the logic level on the active digital lines (underlined). The
communication ended with a checksum. Note that the Block-3 data indicates
only one sample of digital inputs in the transmission.
Block 4 shows the next transmission of 10 samples of analog and digital
information (underlined), gathered based on the configuration information
saved in the XMTR module.
What happened at the XMTR module? After the first series of 10 samples
appeared (Block 1), I waited from four to five seconds and then grounded the
input to the AD3-DIO3 pin (pin 17). That transition from a logic 1 (3.3 volts)
to a logic 0 (ground) caused the XMTR module to first transmit the samples

Introduction

59

it had acquired up until that logic transition. So we see the abbreviated set of
four samples shown in Block 2.
Next, the XMTR module transmitted the forced sample taken in response to
the logic transition at the AD3-DIO3 pin. Thus the information in Block 3 only
identifies the active digital inputs and their state. Because I grounded the AD3DIO3 input, it shows a logic 0 and the AD1-DIO1 input shows a logic 1. After
the XMTR module sends the forced sample, it goes back to its programmed
mode, accumulates 10 samples over 10 seconds, and transmits them.
Step 8. After you complete the steps above and analyze your data, you
should have the AD3-DIO3 jumper connected to ground. If not, move it
to ground now to place a logic 0 on the AD3_DIO3 input. Now perform the
sequence described below. In this step, though, you will change the AD3-DIO3
input from a logic 0 to a logic 1.
l
Clear the X-CTU Terminal window.
l
Turn on power to the breadboard.
l
After 10 seconds you should see a string of hex values appear in the
Terminal window. As soon as this happens, count off four or five seconds.
l
Then at the ground bus, remove the connection between ground and pin 17
(AD3-DIO3). This action changes the AD3-DIO3 input at the XMTR module to a logic 1. Because an unconnected XBee pin floats to a logic 1, you
don’t have to connect the jumper to 3.3 volts to produce a logic 1 at the
AD3-DIO3 pin. Turn off power to the breadboard.
You should see an arrangement of information similar to that observed in
Figure 7.2. This response indicates either a logic-1-to-logic-0 or a logic-0-tologic-1 transition will force a transmission of data from active digital inputs at
a transmitter.
Step 9. You could set up a transmitter to send, say, a single sample
(IT – Samples before TX  0x01) every 60,000 milliseconds (60 seconds) by
setting IR-Sample Rate  0xEA60. By using one digital input as a trigger and
setting IC-DIO Change-Detect to let that input force a transmission, a switch
or sensor could force a transmission at any time. Use this type of operation
when you must receive digital-input information from a transmitter as soon as
some event occurs.
If you plan to use this mode keep the following points in mind:
l
You must have at least one digital input enabled with its Dx-DIOx
Configuration set to 3-DI.
l
You must set the corresponding DIOx bit to a logic 1 in the IC-ChangeDetect byte programmed in the transmitting XBee module.
l
The received information might include a “short” set of data that represents
only samples already taken at the transmitter and ready for transmission.
If you used a microcontroller to receive this data, its software must handle
this type of abbreviated transmission.
l
A forced transmission updates the receiver about the state of any active
digital inputs. That means enabled digital-output pins at the receiver
receive an update and the data from the receiver’s UART also reflects the

60

How to Transmit Data on a Logic-Level Change

current state of digital-input pins at the transmitter. In this experiment, the
UART sends serial data to the X-CTU Terminal window, but you could
send it to a microcontroller instead.
Step 10. Optional. The circuit shown in Figure 7.1 includes a jumper for
the AD1-DIO1 input. Determine how to change the forced transmission from
a logic transition on the AD3-DIO3 input to a change on the AD1-DIO1 input.
Test your change. Did it work? Hint—you only need to change the IC – DIO
Change Detect configuration.
Could you change the IC – DIO Change Detect configuration so a change
on the AD1-DIO1 or the AD3-DIO3 input forces a transmission? How would
you do it?

MAKE CLEAN LOGIC TRANSITIONS
You can change electronic logic states from a logic 1 (3.3 volts) to a
logic 0 (ground) by moving a wire between these two voltages. But this crude
technique can cause problems when you need a single transition. Mechanical
switches and wires to power or ground contacts tend to “bounce,” or open and
close rapidly, which causes several transitions between logic-1 and logic-0
conditions. The timing diagram in Figure 7.3 shows the transitions between a
logic 1 and logic 0 caused by a mechanical switch within the circuit shown in
Figure 7.4. You can identify many transitions from one switch closure.
When you need one clean transition per switch actuation, “debounce”
a mechanical switch’s contacts. You can use a cross-coupled NAND-gate
integrated circuit such as an SN74AHC00 and wire it as shown in Figure 7.5.
You will need two pull-up resistors and a single-pole double-throw (SPDT)
switch or pushbutton.
An SN74AHC00 IC includes four separate NAND gates so you can
debounce two switches with one IC. This IC can operate with a power-supply

FIGURE 7.3 This oscilloscope display shows logic-1 to logic-0 transitions caused by
contact bounce in a mechanical switch. The pulses have a 0-to-5-volt range over 1.6 msec.

Make Clean Logic Transitions

61

+5 volts

1000
To oscilloscope input
Switch
To oscilloscope ground
Ground

FIGURE 7.4 This simple circuit lets a storage oscilloscope capture a mechanical-switchbounce signal.

+V
1000
1

14

2

74AHC00
3

Q

6

*Q

7

SPDT Switch

Ground

4
5

1000
+V

FIGURE 7.5 This debounce circuit can operate with a supply voltage between 2.0 and
5.0 volts, so you can use it with 5-volt or 3.3-volt logic circuits.

voltage between 2.0 and 5.5 volts, so by changing its supply voltage
you can operate debounce circuits for either 3.3-volt or 5-volt logic circuits.
With the switch in the position shown, the Q output remains at a logic 1 and
the *Q output remains at a logic 0. When you actuate the switch, the Q output
becomes logic 0 and the *Q output becomes a logic 1, without any extra transitions created by switch bounce. For more information about switch debouncing
techniques, read, “A Guide to Debouncing,” by Jack Ganssle at: http://www.
ganssle.com/debouncing.htm.

Experiment | 8

How to Handle Data
from Several Analog
Inputs
REQUIREMENTS
2 XBee modules
2 XBee adapters
1 3.3-volt DC power supply
1 10-kohm (10,000-ohm) variable resistor
1 10-kohm resistor, 1/4-watt, 10% (brown-black-orange)
1 4700-ohm resistor, 1/4-watt, 10% (yellow-violet-red)
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port
Small screwdriver, flat blade
Copies of the tables from Appendix I

INTRODUCTION
In previous experiments you learned how an XBee receiver formats its data.
With that knowledge, you can separate, or parse, the received information into
groups to determine the logic state of any active digital inputs and extract data
for any active ADC inputs. So far, though, experiments have used only one
analog input. In this short experiment, you will use two analog inputs and learn
how a receiver formats their data. The same format applies to communications
from a transmitter that has more than two active analog inputs.
Step 1. Before you change any wiring on the breadboard, turn off power to
the breadboard circuits. The diagram in Figure 8.1 shows the needed connections. If you have any other components attached to the XMTR adapter, please
remove them. Then make the connections shown in Figure 8.1.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

63

64

How to Handle Data from Several Analog Inputs
10 kohm Variable Resistor
+3.3 V
+3.3 V

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0–DIO0
AD1–DIO1
AD2–DIO2
AD3–DIO3

10 k
+3.3 V
+3.3 V
4.7 k

VREF

+3.3 V

Ground

FIGURE 8.1 These connections provide two digital signals and two analog signals for the
XMTR XBee module. Schematic diagrams now use a small triangle symbol to represent a
common ground connection.

The two fixed resistors (10 kohms and 4700 ohms) create a voltage divider
and supply a constant analog voltage of about 1.0 volts to the AD2-DIO2 (pin
18) input. Depending on the types of resistors you have, resistances can vary
by about 5 to 10 percent, so the voltage on your XMTR module at pin 18
will likely come close to, but not equal to, 1.0 volts.
Place the XMTR module in the USB-to-XBee adapter and connect the
adapter to the PC’s USB cable. Run the X-CTU program and test communications with the XMTR module. In the Modem Configuration window, click on
Read to obtain the configuration from the XMTR module. If you don’t know
the state of configuration settings, click on Restore and then click Read to
obtain the default settings. In the X-CTU Modem Configuration window, set
the XMTR-module configurations to:
DL – Destination Address Low  1234
MY – 16-Bit Source Address
 5678
D0 – DIO0 Configuration
 2-ADC
D1 – DIO1 Configuration
 3-DI
D2 – DIO2 Configuration
 2-ADC
D3 – DIO3 Configuration
 3-DI
IT – Samples before TX
 03
IR – Sample Rate
 3E8
The Sample-before-TX value 0x03 will cause the XMTR to acquire three
samples before it transmits them. New information will appear in the X-CTU
Terminal window every three seconds.
Confirm these settings and save them in the XMTR module. You can find
this configuration profile in EX8_XMTR_A.pro.

Introduction

65

Step 2. Place the XMTR module in its adapter on the breadboard. Recheck
the connections between the XMTR module and the breadboard.
Step 3. Insert the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable. If you don’t know the state of configuration
settings, click on Restore and then click Read to obtain the default settings. Set
the RCVR-module parameters to:
DL – Destination Address Low  5678
MY – 16-Bit Source Address
 1234
D3 – DIO3 Configuration
 5 D0-HIGH
P0 – PWM0 Configuration
 2-PWM Output
IA – I/O Input Address
 FFFF
Confirm these settings and save them in the RCVR module. You can find
this configuration profile in EX8_RCVR_A.pro. Leave the RCVR module in
the USB-to-XBee adapter connected to the PC. You will use the X-CTU program to monitor data from the XMTR module.
Step 4. Set the variable resistor connected to the XMTR module to about
mid range. Switch the X-CTU program to the Terminal window, clear the window, and set it to display hex values. Turn on power to the breadboard and
watch as the X-CTU program displays data in hex characters. It should take
three seconds for the first transmission to start. After you receive two or three
transmissions, turn off power to the breadboard. You need only one or two sets
of received information to analyze.
When I ran this experiment, I found the following hex values in the
Terminal window. I reformatted the hex values to make them easier to understand. Your data will look different:
7E 00 1A 83 56 78 2C 00 03 0A 0A
00 0A 01 D8 01 48
00 0A 01 D8 01 48
00 0A 01 D8 01 48
E7

Here’s how this hex information breaks down:
7E	  start of transmission
001A	  number of bytes in transmission
83	  code for 16-bit module addressing
5678	  16-bit address
2C	  signal strength
00	  status byte
03	  number of samples
0A0A	  Active-Signal Bytes
Step 5. Use copies of the tables in Appendix I to decode the 0x0A0A value
and determine which analog or digital inputs are active at the XMTR module.

66

How to Handle Data from Several Analog Inputs

You should find the AD0-DIO0 (pin 20) and AD2-DIO2 (pin 18) pins configured as active analog inputs and the AD3-DIO3 (pin 17) and AD1-DIO1
(pin 19) pins set as digital inputs. Because you have set up two ADC inputs
at the XMTR module, the data displayed in the Terminal window will include
a 2-byte sample for each ADC input. The digital and analog data conforms to
the following format: digital-input data followed by ADCx data, ADCx1 data,
and so on. The x subscript indicates the ADC data arrives first from the lowestnumbered ADC input, followed in order by data from the higher-numbered active
ADC inputs. In this case you should see the ADC data for the AD0-DIO0 input
arrive first, followed by the data from the AD2-DIO2 ADC. If a transmitter has
inactive analog input pins (disabled, or used for digital I/O), results will not
include any analog information for those pins.
Step 6. Again use the tables from Appendix I to decode one of the three
samples of analog- and digital-input information in the six columns of hex
values above or use the data you collected in the Terminal window. The first
two bytes of my data, 0x00 and 0x0A, provide digital data, the next two bytes
come from the first enabled ADC, and the final two bytes come from the second enabled ADC.
The AD3-DIO3 and the AD1-DIO1 inputs both connect to 3.3 volts, so,
as expected, they both appear as a logic 1 in the digital-data information.
The four bytes of analog data, 0x01D8 and 0x0148, represent binary information from the XMTR module’s internal 10-bit ADC. In this experiment, the
1.5 volts from the 10 kohm variable resistor connects to the AD0-DIO0 (pin
20) input. The fixed-resistor circuit provides about 1.0 volts to the AD2-DIO2
(pin 18) input. What voltages do the ADC bytes represent, based on a VREF
input of 3.3 volts? Here are the results for my ADC values.
0x01D8 = 47210 and (472/1024) * 3.3 volts = 1.52 volts at AD0-DIO0
input
0x0148 = 32810 and (328/1024) * 3.3 volts = 1.06 volts at AD2-DIO2
input

These calculations confirm the XMTR transmitter sends the lowest-numbered ADC value first, followed by data from ADCs in numerical order. If
in doubt, adjust the trimmer and observe the received values from the AD0DIO0 input. Convert these values into voltages. Did you get the voltages you
expected? The number of pairs of analog bytes transmitted always equals the
number of ADC inputs you have enabled.
Step 7. In addition to changing the trimmer settings you also can swap the
placement of the fixed 10-kohm and 4700-ohm resistors to change the voltage
on the AD2-DIO2 (pin18) input and see how it affects the data.
Step 8. Here are some questions to answer: Which of the two analog inputs
could control a PWM signal at a receiver? Which digital or analog inputs could
force an immediate transmission? Could such a transmission include analog

Answers to Questions in Step 8

67

data? Why does the XMTR module need a 3.3-volt connection to the VREF
input?
Find answers at the end of this experiment.

A REMINDER ABOUT SAMPLE RATES
The manual for the Digi International XBee/XBee-PRO RF modules notes the
following:
The maximum sample rate you can achieve while using one ADC input
is one sample every millisecond or 1000 samples/sec. Note that the
XBee transmitter cannot keep up with transmission when you set IR
and IT equal to 1. Configuring an XBee to sample at rates faster than
once every 20 milliseconds is not recommended.
In other words, suppose you need three active ADC inputs. In theory
a transmitter needs at least three milliseconds to perform the conversions,
because the analog inputs share the ADC. An XBee module will perform a
conversion, store the result, and connect the ADC to the next active ADC input
pin, and so on. The more ADC inputs you activate, the more time you must
allow for sampling. I don’t recommend you try a sample period shorter than
the 20-millisecond period Digi International recommends. The sampling time
does not increase as you enable more digital input or output pins.

ANSWERS TO QUESTIONS IN STEP 8
l

l

l

l

Which of the two analog inputs could control a PWM signal at a receiver?
Only the AD0-DIO0 and AD1-DIO1 analog inputs can control the PWM0
and PWM1 outputs, respectively.
Which digital input or inputs could force an immediate transmission? A
transition of a logic signal at any digital input can trigger an immediate
transmission. You must configure the I/O pin needed for the trigger input as
a digital input and you must place a 1 in the IC-Change-Detect configuration value for that digital input.
Could such a transmission include analog data? A transmission forced by a
transition at a digital input contains only information about digital inputs.
It contains no information from analog inputs.
Why does the XMTR module need a 3.3-volt connection to the VREF
input? All analog-to-digital converters need a reference voltage that determines the range of the ADC. Without a stable reference, the ADC would
produce meaningless results. The reference should offer better accuracy
than the ADC it connects to.

Experiment | 9

Investigate Sleep
Modes and Sleep-Mode
Timing
REQUIREMENTS
2 XBee modules
2 XBee adapters
1 3.3-volt DC power supply
1 10-kohm (10,000-ohm) variable resistor
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port
Small screwdriver, flat blade

INTRODUCTION
In this experiment you will learn how to place an XBee module in a “sleep”
state that saves power. This type of operation comes in handy when you plan
to operate a remote wireless device from battery power or from an energyharvesting power source. The XBee modules include two sleep modes that
reduce a module’s power consumption, and you select the mode within the
Modem Configuration window under the Sleep Modes [NonBeacon] heading:
SM – Sleep Mode
 1-PIN HIBERNATE
SM – Sleep Mode
 2-PIN DOZE
When in the DOZE mode used in this experiment, an XBee module will
draw less than 50 microamperes (50 μA) and the module will wake up to a
completely operational condition in two milliseconds (2 msec). When in the
HIBERNATE mode, an XBee module will draw even less power—below 10
microamperes (10 μA), but it will take the module longer to awaken—13.2
milliseconds (13.2 msec). In this mode you decrease power another five fold,
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

69

70

Investigate Sleep Modes and Sleep-Mode Timing
First 5 Samples

Second 5 Samples

/DTR–SLEEP_RQ–DI8

a

b

c

d

e

0

1

2

3

4
5
6
Time (seconds)

7

8

9

10

FIGURE 9.1 Timing relationships between a sleep-request signal at the /DTR-SLEEP_
RQ-DI8 input and the information sampled by an XBee module. This diagram assumes a
programmed sequence of five samples at one-second intervals.

but at the cost of a longer wake-up time. This experiment does not test the
hibernate mode, but you can experiment with it on your own.
When in either of these two modes, a logic 1 on the /DTR-SLEEP_RQ-DI8
input keeps a module in a sleep condition. When the /DTR-SLEEP_RQ-DI8
input changes to a logic 0, the module wakes up and starts to sample information as previously configured with Sample Rate and Samples-before-TX
values. A data transmission occurs as soon as the XBee module takes the last
sample. The timing diagram in Figure 9.1 shows the relationship between five
different logic-0 pulse widths at the /DTR-SLEEP_RQ-DI8 input and how
they affect the operation of an XBee in a doze or hibernate mode. The descriptions that follow explain the effect of each pulse type.
When you look at the timing information in Figure 9.1 you see five logic-0
signals at the /DTR-SLEEP_RQ-DI8 input. Here’s how they affect an XBee
module in doze or hibernate mode based on my observations:
Pulse a. When the length of the logic-0 signal is shorter than the interval
between samples, an XBee module does not sample any inputs and does not
transmit information. This example uses a sample period of one second, so a
pulse width of less than one second does not awaken a “sleeping” XBee module.

Introduction

71

Pulse b. When the length of the logic-0 signal exceeds the interval between
samples, an XBee module proceeds with the five samples and transmits the
expected data.
Pulse c. When the length of the logic-0 signal exceeds the interval between
samples, but does not extend to the final sample, an XBee module proceeds
with the five samples and transmits the expected data.
Pulse d. When the length of the logic-0 signal exceeds the interval between
samples, but does not extend to the time of the first sample in the successive
set of samples, the XBee module transmits data for the first five samples. But
it does not proceed with the second set of five samples and returns to its sleep
state.
Pulse e. When the length of the logic-0 signal extends beyond the time
of the first sample in the successive series of samples, the XBee module will
complete the second set of samples and transmit their data.
In all five examples above, when an XBee module detects a logic 0 at
its/DTR-SLEEP_RQ-DI8 input it comes out of the sleep mode and starts
to draw a higher current. It will continue to draw this current until it transmits the last set of samples data and then goes back into a sleep mode. So,
power consumption occurs as follows for the five types of pulses shown in
Figure 9.1:
Pulse a. Full power used during the logic-0 period. No data transmitted.
Pulses b and c. Full power used during the five-sample period. Five
samples transmitted.
Pulse d. Five samples transmitted and full power used during the entire
logic-0 period.
Pulse e. Full power during the two five-sample periods. First five samples
transmitted at the five-second mark, second five samples transmitted at the
10-second mark.
This timing and power-consumption information shows if you need a set
of only five samples, keep the width of the logic-0 pulse applied to an XBee
transmitter longer than the sample period and less than the sample period
multiplied by the number of samples. So in this case: 1 sec /DTR-SLEEP_
RQ-DI8  5 sec. If you use a longer logic-0 pulse, you will get more data than
you need and will increase power use by the transmitting XBee module.
Step 1. In this experiment you will set up the XMTR module so it has two
digital inputs and one analog input. Before you change any connections, turn
off power to the breadboard.
Make connections shown in Figure 9.2. If you have other components or
wires that connect to the XMTR adapter, please remove them. To start, connect
the /DTR-SLEEP_RQ-DI8 (pin 9) input to 3.3 volts to supply a logic 1 at
pin 9. Later you will move this jumper wire to ground (logic 0).
Step 2. Place the XMTR module in the USB-to-XBee adapter and connect
the adapter to the PC’s USB cable. Run the X-CTU program and test communications with the XMTR module.

72

Investigate Sleep Modes and Sleep-Mode Timing
10–kohm Trimmer
+3.3 V
+3.3 V

+3.3 V
/DTR–SLEEP_RQ–DI8

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

AD0–DIO0
20
AD1–DIO1
+3.3 V
19
18
AD3–DIO3
17
+3.3 V
16
15
VREF
14
+3.3 V
13
12
11

FIGURE 9.2 This XBee-module circuit includes a jumper that will control the powersaving sleep state.

In the Modem Configuration window, click on Read to obtain the configuration from the XMTR module. If you don’t know the state of configuration
settings, click on Restore and then click Read to obtain the default settings. In the
X-CTU Modem Configuration window, set the XMTR-module configurations to:
DL – Destination Address Low
 1234
MY – 16-Bit Source Address
 5678
SM – Sleep Mode
 2-PIN DOZE
D0 – DIO0 Configuration
 2-ADC
D1 – DIO1 Configuration
 3-DI
D2 – DIO2 Configuration
 0-DISABLED
D3 – DIO3 Configuration
 3-DI
IT – Samples before TX
 0A
IR – Sample Rate
 3E8
Confirm these settings and save them in the XMTR module. You can find
this configuration profile in EX9_XMTR_A.pro.
The Sample-before-TX value 0x0A will cause the XMTR to acquire 1010
samples before it transmits them. Thus new information will appear in the
X-CTU Terminal window every 10 seconds.
Step 3. Place the XMTR module in its adapter on the breadboard and
recheck the connections.
Step 4. Place the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable. If you don’t know the state of configuration
settings, click on Restore and then click Read to obtain the default settings. Set
the RCVR-module parameters to:
DL – Destination Address Low
 5678
MY – 16-Bit Source Address
 1234
IA – I/O Input Address
 FFFF
Confirm these settings and save them in the RCVR module. You can find
this configuration profile in EX9_RCVR_A.pro. Leave the RCVR module in

Introduction

73

the USB-to-XBee adapter connected to the PC. You will use the X-CTU program to monitor data from the XMTR module.
Step 5. Set the variable resistor connected to the XMTR module between
1/4 and 3/4 of the way between its end stops. Select the Terminal window,
clear it, and set it to display hex values. Turn on power to the breadboard and
wait. You should not see any received data in the Terminal window because the
connection of the /DTR-SLEEP_RQ-DI8 (pin 9) input to logic 1 (3.3 volts)
keeps the XMTR module in the doze mode.
Step 6. Move the wire connected to the /DTR-SLEEP_RQ-DI8 (pin 9) input
from logic 1 (3.3 volts) to logic 0 (ground). The logic 0 on pin 9 will cause
the XMTR module to exit the doze mode and transmit data after it collects all
10 samples. So, ten seconds after you change the /DTR-SLEEP_RQ-DI8 input
to a logic 0, you should see data appear in the Terminal window.
As long as you keep the /DTR-SLEEP_RQ-DI8 input connected to a logic
0, the XMTR will continue to send 10 samples every 10 seconds. You could use
a switch or a signal from another electronic device such as an MCU to change
the logic state at the /DTR-SLEEP_RQ-DI8 input and awaken an XBee module.
Adjust the variable resistor and observe the data in the Terminal window.
You should see the value of the bytes from the XMTR ADC change.
To stop the transmission of data, move the wire connected to the /DTRSLEEP_RQ-DI8 input at pin 9 to logic 1. You might see one final burst of data
in the Terminal window after you reconnect the /DTR-SLEEP_RQ-DI8 input
to logic 1. You’ll learn why in the next step.
Step 7. In this step you will see what happens when you try to switch the
XMTR module into a sleep mode during the time it samples the two digital
inputs and one analog input.
Suppose the XMTR module has sent data for 10 samples and it already has
taken six samples to prepare for the next transmission. At this time you change
the /DTR-SLEEP_RQ-DI8 input to logic 1 to force the XMTR module into
its sleep mode. What happens to those six samples? Does the XMTR module
save them for the next transmission? Does it continue sampling until it has all
10 samples, transmit them, and only then go into the sleep mode? Or does it
discard them?
Use the variable resistor to change the voltage measured by the XMTR
ADC so you can watch the effect of taking the XMTR out of its sleep mode
and putting it back into sleep mode. Turn off power to your breadboard and
clear the Terminal window. Change the /DTR-SLEEP_RQ-DI8 (pin 9) input to
a logic 1 (3.3 volts). This connection puts the XMTR in the sleep mode.
Do not perform the following lettered steps below yet. First read them
so you understand what to do and the timing involved. Use two hands in this
experiment.
l
Turn on power to the breadboard. No information should appear in the
Terminal window.
l
Use a small screwdriver to slowly adjust the variable resistor back and
forth between its end points. Continue to adjust the variable resistor back

74

Investigate Sleep Modes and Sleep-Mode Timing

and forth until instructed to stop. (You don’t have to go all the way to the
end points, though.)
l
As you change the variable resistor setting, move the /DTR-SLEEP_
RQ-DI8 input at pin 9 to a logic 0. In 10 seconds, the first burst of information should appear in the Terminal window.
l
As soon as you see the data appear in the Terminal window, count off four
or five seconds and then change the /DTR-SLEEP_RQ-DI8 input back to a
logic 1. This step signals the XMTR module to go back into its sleep mode
after it has already taken four or five samples. (You don’t need precise
timing here; you just want to change the logic level at the /DTR-SLEEP_
RQ-DI8 input as the XBee module takes the second group of 10 samples.)
l
You should see a second burst of data appear in your Terminal window.
Now stop adjusting the variable resistor. Turn off power to the breadboard.
After you understand these steps, do them. Don’t hesitate to try them several
times. Clear the Terminal screen each time so you can easily see the newest
data.
At the end of these steps, the Terminal window should show two sets of
data—the data taken when the XMTR module awakened in step (c) above,
and the data taken as you put the XMTR module back into its sleep mode in
step (d).
My Terminal displayed the data shown next, which I reformatted for clarity. The two left-most columns represent digital information from the two digital inputs, DIO1 and DIO3. The value of these bytes (0x000A) did not change
because I did not change the logic level on the corresponding pins. The two
right-most columns represent the analog voltage (underlined), measured as
I changed the variable-resistor setting.
First burst of data after wake-up:
7E 00 30 83 56 78 3D 00 0A 02 0A
00 0A 02 31
00 0A 00 00
00 0A 00 FB
00 0A 02 70
00 0A 03 FF
00 0A 03 08
00 0A 01 12
00 0A 00 00
00 0A 02 4D
00 0A 03 FF
E6

Introduction

75

Second burst of data taken as I put the XMTR back into sleep mode but
continued to vary the trimmer setting:
7E 00 30 83 56 78 2E 00 0A 02 0A
00 0A 03 04
00 0A 01 75
00 0A 00 00
00 0A 01 6D
00 0A 03 40
00 0A 03 A7
00 0A 01 CD
00 0A 00 0E
00 0A 00 2A
00 0A 02 06
20



Before you analyze this data, review the steps performed earlier: The
XMTR module acquired the first 10 samples after you woke it up. Then, about
four or five seconds into the next set of 10 samples, you signaled the XMTR
module to go back into a sleep mode. In the second set of data, the analog voltage continued to vary even after you changed the /DTR-SLEEP_RQ-DI8 input
to logic 1.
You expect to see the first set of data, but you might not have expected
the XMTR module to send the second set of data. After all, you might think
it would go into its sleep mode as soon as you changed the /DTR-SLEEP_
RQ-DI8 input to a logic 1. But because the /DTR-SLEEP_RQ-DI8 input
remained at a logic 0 beyond the minimum time needed to awaken—or keep
awake—the XMTR module, it continued its task. So, you obtained a complete
set of 10 samples. Refer back to Figure 9.1 for the timing relationships.
Step 8. In this step you will awaken the XMTR module and keep it
awake only long enough to acquire one set of data. Turn off power to the
breadboard.
Do not perform the following lettered steps yet. Read them first to understand what you will do and the timing involved. You need both hands in this
experiment. The following steps do not simply duplicate those you performed
earlier. Pay careful attention to the timing.
l
Connect the /DTR-SLEEP_RQ-DI8 input at pin 9 to logic 1 (3.3 volts).
If the Terminal window contains information, click on Clear Screen to
get a clear area. Turn on power to the breadboard. You should not see any
information appear in the Terminal window.

76

Investigate Sleep Modes and Sleep-Mode Timing

Use a small screwdriver to slowly adjust the variable resistor back and
forth between its end points. Continue to adjust the variable resistor back
and forth until instructed to stop. (You don’t have to go all the way to the
end points, though.)
l
As you change the variable resistor setting, change the /DTR-SLEEP_
RQ-DI8 input at pin 9 to a logic 0 to take the XMTR module out of the
sleep mode. After about four or five seconds, change the /DTR-SLEEP_
RQ-DI8 input back to a logic 1. This signals the XMTR module to go back
into its sleep mode after it has sampled the two digital inputs and one analog input four or five times. (You don’t need precise timing here, but you
must put the XMTR module back in the sleep mode before the end of the
10-second sample period.)
l
As soon as a burst of data appears in the Terminal window, stop adjusting
the variable resistor.
Now you should see only one set of 10 samples.
To put an XBee module back in its sleep mode, you must return the /DTRSLEEP_RQ-DI8 (pin 9) input to a logic 1 before the module completes its
sequence of taking the number of samples you programmed as the Samplesbefore-TX parameter for the XMTR module. If you must cause a module to
perform a short operation, using a switch to change logic levels on the /DTRSLEEP_RQ-DI8 input might not work because you couldn’t switch back to a
logic-1 input quickly enough. You would have to use a short logic-0 pulse from
a microcontroller or other device.
Step 9. Optional. You can experiment with an XBee module in the hibernate state by changing the SM-Sleep Mode setting to 1-PIN HIBERNATE, but
you will not see any differences unless you can measure the XMTR module’s
current use and the module’s start-up time when it comes out of a sleep mode.
Note: Rather than change the variable-resistor setting by hand, I also ran
this experiment and used a triangle-wave generator (Global Specialties Model
2001) to provide a slowly changing voltage between 0 and 3 volts for the
ADC. The results duplicated those shown earlier.
l

Experiment | 10

How to Use API
Packets to Control a
Local XBee Module
REQUIREMENTS
1 XBee module
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use application programming interface (API) packets that include AT commands to control an XBee module
and transfer information to and from it. These commands, which use the standard AT-command letters, give you greater control over modules than you can
obtain with the Modem Configuration settings alone. And they let you break
away from using the X-CTU software.
Although you connected an XBee module to a PC via a USB port, the
X-CTU software handled communications through a virtual serial port. These
communications use a device called a Universal Asynchronous Receiver/
Transmitter (UART) that forms the core of a serial port. A UART can transmit and receive bytes of information at specific bit rates adopted by convention, and it always formats data with a logic-0 start bit followed by n bits of
data, where n usually equals eight, followed by a logic-1 stop bit, as shown in
Figure 10.1. Although a UART can send a parity bit for error detection, most
communications do not include it. Visit the Wikipedia Web site for an article
that provides more details about UART operations: http://en.wikipedia.org/
wiki/Universal_asynchronous_receiver/transmitter.
In a UART-type communication, each bit requires the same period. Thus,
if you have a 9600 bits/second transmission, each bit takes 1/9600 seconds,
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

77

78

How to Use API Packets to Control a Local XBee Module
Start Bit

Stop Bit

Data Bits
D0
LSB

D1

D2

D3

D4

D5

D6

D7
MSB

Time

FIGURE 10.1 A UART receives and transmits 8-bit data in this standard format, with a
logic-0 start bit and a logic-1 stop bit. Although some UART communications include a parity bit, most do not.

or about 104 microseconds. The receiver and transmitter must operate their
UARTs with the same bit rate.
An integrated circuit in the USB-to-XBee adapter converts the USB signals
into signals for the UART within the XBee chip. According to Digi International:
The API commands act much like the Modem Configuration settings,
but your PC—or another device, such as a microcontroller (MCU)—
can transmit API commands on the fly to both local and remote XBee
modules. In the case of a microcontroller, communications would
eliminate the USB connection and hardware would provide a direct
UART-to-UART connection. Your microcontroller’s code would create the
API commands and send them to the XBee module, and the MCU would
received responses triggered by API commands and interpret them.
Almost every microcontroller (MCU) includes at least one UART, loosely
called a serial port. The UART simplifies communications between an MCU
and devices such as XBee modules. Later experiments will involve MCUUART-to-XBee-module communications and control software.
After you finish this experiment, go on to the next one in the same session
because it builds on the experience you gain here.
Step 1. In this step you will configure the RCVR module to operate with
API packets sent from the X-CTU Terminal. Each packet includes information
you have already learned about along with a 2-letter AT-modem-control command such as MY, SL, and IT. In some cases, the AT command includes data
for the attached XBee module.
Place the RCVR module in the USB-to-XBee adapter and reconnect this
adapter to the USB cable. Click on Restore and then click Read to obtain the
default settings.
In the Modem Configuration window, look under the Networking & Security
heading and note the hexadecimal serial numbers for your RCVR module:
SH – Serial Number High  ____________________
SL – Serial Number Low  ____________________
Digi has pre-programmed a unique serial number in each module and it
will never change. Set the RCVR-module parameters to those shown next.
Find these settings in the file: EX10_RCVR.pro:

Introduction

79

DL – Destination Address Low  5678
MY – 16-Bit Source Address
 1234
IA – I/O Input Address
 FFFF
Find the Serial Interfacing heading and locate the API-Enable setting.
Change its setting to:
AP – API Enable
 1-API ENABLED
Confirm these settings and save them in the RCVR module. Leave the
RCVR module in the USB-to-XBee adapter connected to the PC.
Step 2. Now you can send an AT command in an API packet to the RCVR
module from the X-CTU program. First, though, you must understand how to
create such a packet, which requires several bytes. (The Digi XBee/XBee-PRO
RF Modules manual provides more information about the API packets that
contain the AT commands and responses to AT commands.)
When you need to send an AT command to an XBee module connected
directly to your computer, use a simple packet as shown below. All commands
sent to a local XBee module use the same packet format. In this context, the
word “local” refers to XBee modems connected directly to the packet sender,
perhaps an MCU, or in this case, the X-CTU software:
0x7E
 start-of-transmission byte
0x____
 message-length bytes
AT-command structure goes here
0x__
 checksum
The basic AT-command structure of an API packet for a local XBee module includes:
l
The identifier 0x08, which indicates a command for a local XBee module
l
A frame-identifier value of your choice (all experiments use 0x52)
l
The AT command
l
Any information or data the AT command requires
Suppose you wanted to read the Serial Number Low from the attached RCVR
XBee module. First create the AT command in the structure just introduced:
0x08 0x52 S L
The S and L characters come from the 2-letter settings listed in the X-CTU
Modem Configuration window and also listed in Appendix C. Because you want
to read the serial number, this command does not require any additional information. But you cannot just type letters such as S and L in an AT command. You
must convert letters to their corresponding hex values: S  0x53 and L  0x4C.
Each character has a standard 8-bit binary value defined in the American
Standard Code for Information Interchange, or ASCII. Tables available in
Appendix G and on many Web sites let you find a character and its equivalent
hexadecimal value in an ASCII table.
The final AT command looks like this: 0x08 0x52 0x53 0x4C. And you
insert it into the API packet, which also assumes hex values:
7E ?? ?? 08 52 53 4C ??

80

How to Use API Packets to Control a Local XBee Module

The message-length value counts only the bytes in the message (underlined) and you only sum these bytes to calculate the checksum.
So, the command now looks like:
7E 00 04 08 52 53 4C ??
Next, calculate the hexadecimal checksum from: 0x08  0x52  0x53 
0x4C  0xF9. Then subtract this sum from 0xFF: 0xFF  0xF9  0x06.
If you have a larger sum, such as 0xAFC7, just subtract the two leastsignificant digits, 0xC7, from 0xFF. An inexpensive calculator, such as the
Casio FX-260 Solar or the Texas Instruments TI 36X Solar, can handle hex
math. Appendix E includes information about how to use an Excel “Packet
Creator” spreadsheet that lets you insert decimal and hexadecimal values and
ASCII characters to create a hex packet complete with checksum. For more
information about checksums and their limits, see Appendix B.
Now the complete API packet with the SL command looks like this, again
in hex values:
7E 00 04 08 52 53 4C 06
Step 3. With the RCVR module connected to your PC, open the Terminal
window in the X-CTU software. Click on Clear Screen. If you don’t see a twocolumn window, click on Show Hex to see information as hexadecimal values.
Click on Assemble Packet. If you see information in the Send Packet window, click Clear. In the bottom-right corner of the Send Packet window, click
HEX. Then, type in your API packet, but without spaces, which the Send
Packet window includes automatically:
7E 00 04 08 52 53 4C 06
Check your data and then click on Send Data. You should see your API
packet appear in the Terminal window in blue characters (7E...06) and the
RCVR module’s response in red characters (7E...F5). My computer displayed
the information shown in Figure 10.2.

FIGURE 10.2 This screen image shows the packet sent to the RCVR module and the
reply. The upper information appeared in the Terminal window.

If you did not see a response from your RCVR module, go back to Step 1
and check your settings. You must have the API mode enabled in the RCVR
module. Use the X-CTU Modem Configuration section to read the current settings from the RCVR module so you can review them. Make any changes and
then click Write to transfer the settings to the RCVR module.

Introduction

81

Step 4. How do you interpret the reply from the RCVR module? It replied
with information in a standard format. (Your data will vary from that shown
next, but it will follow the same format.)
7E 00 09 88 52 53 4C 00 40 49 E0 28 F5
Here’s how the hex information breaks down:
7E
 start of transmission
0009
 number of bytes in transmission
88
 packet type (AT Command Response)
52
 frame-identifier byte (always 52 in experiments)
53
 hex code for letter S
4C
 hex code for letter L
00
 status byte
4049E028  SL information from my RCVR module
F5
 checksum for this message
In this example, the 0x88 identifies the message as a standard AT
Command Response and the 0x52 duplicates the frame-identifier value sent
to the RCVR module. This value—which you assign—should always match
the frame-identifier byte sent in the original command packet. Although packets require this byte and it appears in responses, you do not have to do anything with it. The Status Byte identifies one of several conditions shown in
Table 10.1. The response from the RCVR module indicates the OK condition.

Table 10.1 Status Bytes in XBee Communications
Status Byte

Status

0x00

OK

0x01

Error

0x02

Invalid Command

0x03

Invalid Parameter

0x04

No Response

Step 5. Again, click on Send Data to retransmit the API packet you created
in Step 4 to ensure you get a response from the RCVR module.
Next, go to the packet in the Send Packet window and change the checksum value to: 0x00. This checksum is not valid for this packet but it lets
you see how the RCVR module responds. The new packet should look like:
7E 00 04 08 52 53 4C 00
Click on Send Data. What did you observe? You should see no reply from
the RCVR module. When a packet includes an incorrect checksum, the module that received the packet takes no action because the checksum it calculates differs from the checksum in your packet. Unfortunately, you can’t tell

82

How to Use API Packets to Control a Local XBee Module

what causes the lack of response. Always confirm the accuracy of a checksum
before you transmit a packet. (If you plan to use an MCU to provide an API
packet to an XBee module, your software can calculate the checksum, as later
experiments demonstrate.)
Step 6. In this step you will send the RCVR module a packet with an
invalid AT command, QQ, which does nothing. The letter Q corresponds to the
hex value 0x51.
7E
 start byte
0004  4 bytes in message
08
 AT command-identifier byte
52
 frame-identifier byte
51
 hex code for Q
51
 hex code for Q
??
 checksum on four message bytes
Calculate the checksum you must use to replace the two question marks for
the four bytes in the message.
7E 00 04 08 52 51 51 03
Clear the Send Packet window, type in the hex values shown directly above,
and click Send Data. You should see the same data as shown below received
from the XBee module:
7E 00 05 88 52 51 51 02 81
The information in Table 10.1 lets you interpret the Status Byte (0x02),
which now indicates an Invalid Command.
Step 7. In this step, you will use the MY command to change the 16-bit
Source Address in the RCVR module with the following API packet:
7E
 start byte
0006  message length
08
 AT command-identifier byte
52
 frame-identifier byte
4D
 hex code for M
59
 hex code for Y
12AF  hex values for Source Address
3E
 checksum
Clear the Send Packet window and type in the packet:
7E 00 06 08 52 4D 59 12 AF 3E
and click Send Data. You should see the reply below:
7E 00 05 88 52 4D 59 00 7F
You can parse this information as follows:
7E
 start byte
0005  message length
88
 AT command response
52
 frame-identifier byte

Answers to Questions in Step 8

83

4D
 hex code for M
59
 hex code for Y
00
 status byte
7F
 checksum
The Status Byte indicates no errors (see Table 10.1).
Switch to the X-CTU Modem Configuration window and click Read to
obtain the configuration information from the RCVR. Under the Networking &
Security heading, find the address given to MY – 16-Bit Source Address. You
should see:
(12AF) MY – 16-Bit Source Address
An API packet that contains an AT command can change information within
the RCVR module. You can use any of the AT commands in this way to modify or read the settings within an XBee module configured with the AP - API
Enable set to 1-API ENABLED.
Be sure to change the 16-Bit Source Address (MY) back to 0x1234.
Instead of using the Modem Configuration window, create an API packet to
send the RCVR module via the Send Packet window.
Step 8. Optional. What would happen when you try to set the 16-bit
Source Address but you use the hex codes for the lowercase letters m and y?
Try this on your own.
0x6D  Hex code for m
0x79  Hex code for y
See my results at the end of this experiment.
Note: In a real-world design, most likely a microcontroller would issue AT
commands within an API packet to make changes or read values. This type
of MCU-to-XBee communication uses the same UART input and output pins
used by the USB-to-XBee adapter. The adapter board includes an integrated
circuit that handles the UART-to-USB communications.
In the next experiment you will learn how to use the API to change settings
in a remote XBee module.

ANSWERS TO QUESTIONS IN STEP 8
The following API packet uses the lowercase “m” and “y” to change the MY
address in an XBee module to 0x0000:
7E 00 06 08 52 6D 79 00 00 BF
When I transmitted this API packet, the RCVR module responded just as it
would for the upper-case letters. A look at the binary code for the letters shows
the relationship between the codes for upper- and lower-case letters:
M

= 0100 1101

0x4D

m

= 0110 1101

0x6D

Y

= 0101 1001

0x59

y

= 0111 1001

0x79

84

How to Use API Packets to Control a Local XBee Module

The only difference between the upper- and lower-case binary codes exists
at bit position D5 underlined above (remember, start numbering bits with D0
for the right-most bit).
So, either an XBee module or the X-CTU software knows the codes for
upper- and lower-case letters, or it simply ignores the D4 bit in ONLY the
AT commands. The D4 bit is still valid in all other values in an API packet.
I recommend you always use the ASCII values for uppercase letters in AT
commands.

Experiment | 11

How to Use API
Packets to Control
Remote XBee Modules
REQUIREMENTS
2 XBee modules
1 XBee adapter
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use application programming interface (API) packets to transfer information to and from local and remote XBee
modules. The API lets you send AT commands to modules to control them via
a wireless connection. If you have not performed Experiment 10, I recommend
you do so before you proceed with this experiment. This experiment will take
time to do properly, so don’t rush and double-check your actions.
In previous experiments, you used the X-CTU software to configure an
RCVR and an XMTR module so inputs at the XMTR could control outputs on
the RCVR module connected through a USB cable to a PC. Now you will use
application programming interface (API) packets to transmit AT commands
from the RCVR module to the XMTR module. Although you labeled one module as a transmitter (XMTR) and one as a receiver (RCVR), both can act as
transceivers and transmit and receive information, but not simultaneously. You
will continue to use the XMTR and RCVR labels for clarity and consistency,
even though the XMTR module might operate as a receiver and the RCVR
module might act as a transmitter.
85
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

86

How to Use API Packets to Control Remote XBee Modules

Step 1. In this step you will configure the XMTR module to operate
with the AT commands via the API. Ensure you have turned off power to the
breadboard. Then place the XMTR module in the USB-to-XBee adapter and
reconnect this adapter to the USB cable and your PC.
Within the X-CTU window, click on Modem Configuration and then
click on Restore. After a few seconds you should see the message “Restore
Defaults..complete” appear at the bottom of the X-CTU window. Click on
Read to obtain the restored default values from the XMTR module.
Step 2. Check to ensure the DL – Destination Address Low and MY –
16-Bit Source Address each have a value of 0. This condition indicates the
X-CTU software has reset all the XMTR module settings to their default state.
If DL and MY are not equal to 0, perform Step 1 again.
Step 3. In the Modem Configuration window, look under the Networking &
Security heading and note the serial number for your XMTR module. Digi has
pre-programmed a unique serial number in each module and it will never change:
SH – Serial Number High
 ____________________
SL – Serial Number Low
 ____________________
Also note the value for SC – Scan Channels  ____________________
Step 4. Find the XMTR configuration in EX11_XMTR.pro. In the Modem
Configuration window and under the Networking and Security heading, set the
following hex values for the XMTR module:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
And under the Serial Interfacing heading locate the AP – API Enable setting. Change this setting to:
AP – API Enable	  1-API ENABLED.
Under I/O Settings heading look for the I/O Line Passing file icon and
click on the  to view the settings. Click on the IA – I/O Input Address name
and then click on the Set button that appears to its right. You should see a Set
Hex String window open. In this window, click on Clear, type FFFF in the text
area, and click on OK. In the Modem Configuration window you should see:
[FFFF] IA – I/O Input Address
Step 5. Recheck the four settings you changed in the Modem Configuration
window. After you confirm the proper values, click on Write to save these settings
in the XMTR module. After you see the message “Write Parameters...Complete”
appear at the bottom of the X-CTU window, continue to the next step.
Step 6. Remove the USB-to-XBee adapter from the USB cable and remove
the XMTR module from the adapter socket. Place the XMTR module in its
XBee adapter on the breadboard.
Step 7. Place the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable. Within the X-CTU window, click on
Modem Configuration and then click on the Restore button. After a few seconds you should see the message “Restore Defaults..complete” appear at the
bottom of the X-CTU window. Click on Read to obtain the restored default
values from the RCVR module.

Introduction

87

Step 8. Check to ensure the DL – Destination Address Low and MY – 16-Bit
Source Address each have a value of 0. This condition indicates the X-CTU
software has reset all the RCVR module settings to their default state. If DL
and MY are not equal to 0, perform Step 7 again.
Step 9. Find the RCVR configuration in EX11_RCVR.pro. In the Modem
Configuration window and under the Networking & Security heading, set the
following values for the RCVR module:
DL – Destination Address Low	  5678
MY– 16-Bit Source Address	  1234
And under the Serial Interfacing heading locate the AP – API Enable setting. Change this setting to:
AP – API Enable	  1-API ENABLED
Under I/O Settings heading look for the I/O Line Passing file icon and
click on the  to view the settings. Click on the IA – I/O Input Address name
and then click on the Set button that appears to its right. You should see a Set
Hex String window open. In this window, click on Clear, type FFFF in the text
area, and click on OK. In the Modem Configuration window you should see:
[FFFF] IA – I/O Input Address
Step 10. Recheck the four settings you changed in the Modem
Configuration window. After you confirm the proper values, click on Write
to save these settings in the RCVR module. Leave the RCVR module in the
USB-to-XBee adapter socket connected to the PC.
Step 11. The schematic diagram in Figure 11.1 shows the only two
connections—3.3-volt power and ground—needed for the XMTR module in
your breadboard. If you have other connections for the XMTR module, please
disconnect them now.

+3.3 V

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

GND

FIGURE 11.1 In this experiment, the XMTR module in the solderless breadboard needs
only power and ground connections.

88

How to Use API Packets to Control Remote XBee Modules

Step 12. Now you will learn how to send an AT command to the remote
XMTR module. (The Digi International document, XBee/XBee-PRO RF
Modules, provides more information about the AT commands, command packets, and the use of the API.)
When you need to send an AT command to a remote XBee module via a
wireless link, you use the API-packet framework shown below. This format
duplicates the one used in Experiment 10. The AT command structure forms
the “payload” of the API packet.
0x7E	  start byte
0x____	  message length
Insert AT-command-specific structure here
0x__	  checksum
Depending on the AT command, the structure can vary. Information in a
remote AT command includes:
l
An identifier of 0x17, which indicates a remote AT-command request
l
A frame-identifier value of your choice (all experiments use 0x52)
l
The 64-bit destination address; that is, the remote module’s serial number
l
The destination module’s 16-bit network address (MY), or 0xFFFE
l
A Command Options byte
l
The AT command
l
Any parameter the AT command requires
Important: In the section immediately above, the remote AT Command
request uses an identifier byte of 0x17. In Experiment 10, the AT Command for
a local, directly connected module used an identifier byte of 0x08.
My XMTR module has the serial number: 13A200 4049E0EC. So I used
this address to identify it as the recipient for an AT command. Likely your
Serial Number High value for the transmitter module also will appear as a
3-byte value because the X-CTU program does not display leading zeros. In
that case, just append 0s to the left side of the Serial Number High value to
create a 4-byte value. My Serial Number High appeared as (13A200) in the
Modem Configuration window, so I changed it to: 0013A200.
Next, I created a remote-AT-command request to have my XMTR module in the breadboard send its Serial Number Low data back to the RCVR.
Of course I already know the Serial Number Low information on my XMTR
module, as would you. So this section of the experiment simply demonstrates
how to create and use an API packet for a remote XBee module. The SL command returns already-known information, which makes it easy to confirm the
remote command worked.
Here’s how the remote-AT command (underlined information) would
appear when placed in an API packet:
7E	  start byte
000F	  number of bytes in transmission
17	  Remote AT Command Request byte
52	  frame identifier value (all experiments use this
value)

Introduction

89

0013A2004049E0EC	  XMTR serial number (SH and SL)
FFFE	  FFFE for 64-bit addressing with SH and SL bytes
02	  immediate action (explained later)
53	  hex code for letter S
4C	  hex code for letter L
EE	  checksum
In the Terminal window, I cleared the Send Packet window and typed in
the packet below.
7E 00 0F 17 52 00 13 A2 00 40 49 E0 EC FF FE 02 53 4C EE

After I turned on power to my XMTR module, I clicked on Send Data and
saw the response shown in Figure 11.2.

FIGURE 11.2 This figure shows the API packet sent to the XMTR module as well as the
information received from the XMTR module in response to the AT command SL.

Step 13. XBee modules reply with information in a standard format.
(Soon when you run this experiment for yourself, your data will vary from that
shown because your XMTR module has a different serial number.)
Message received:
7E 00 13 97 52 00 13 A2 00 40 49 E0 EC 56 78 53 4C 00 40 49 E0
EC 4A

Here’s how the hex information breaks down:
7E	  start byte
0013	  number of bytes in message
97	  packet type (remote Command Response)
52	  frame-identifier byte (all experiments use this value)
0013A200	  SH for responding module
4049E0EC	  SL for responding module
5678	  16-bit address of responding module
53	  hex code for letter S
4C	  hex code for letter L
00	  status byte
4049E0EC	  SL value response to command
4A	  checksum
In this example, the reply included information in a standard format similar
to that you have seen before. After the status byte, the next four bytes provide

90

How to Use API Packets to Control Remote XBee Modules

the Serial Number Low (SL) value for my RCVR module 0x4049E0EC, which
corresponds to the Serial Number Low information in the X-CTU Modem
Configuration window when I read the configuration information from my
XMTR module and the SL information used in the API packet. So, the command worked at the remote XMTR module.
A quick review: I created a remote AT Command request sent to the RCVR
module from the X-CTU program. The XMTR module picked up the wireless message from the RCVR and because its 64-bit serial number matched the
serial number in the command, it executed the command and replied with its
SL information.
Step 14. Now use the RCVR module and the X-CTU software to send the
SL command to your XMTR module. Substitute your 8-byte XMTR module
serial number (SH and SL) in the AT command framework below and calculate
a new checksum marked “??” for the underlined values:
7E 00 0F 17 52 [SH] [SL] FF FE 02 53 4C ??

Remember to take the two least-significant hex digits from the sum and subtract only them from FF to yield the checksum. If your hex sum comes to 0xCA6,
for example, subtract only 0xA6 from 0xFF, as in: 0xFF  0xA6  0x59.
Note: Do not include spaces—or the hex value for a space (0x20)—in
transmissions you send to a module. Spaces help us visualize bytes, but a
transmission simply sends one byte after another without any spaces.
Step 15. In the X-CTU window, click on Terminal and click Clear Screen.
Ensure you have this window set for the 2-column display of hex values. Click
on Assemble Packet to open the Send Packet text window. Click on Clear in
the bottom-right corner of the Send Packet to ensure you have a clean text
area. Also click on HEX in the same area to ensure the text you type appears as
hex characters.
Move the cursor into the Send Packet text window and type your line of
hex characters shown above but with your substituted XMTR module’s serial
number and the checksum you calculated. Recheck your typed values and correct any errors.
Step 16. Turn on power to your XMTR module, wait a few seconds, and
in the Send Packet window, click on Send Data. You should see your transmitted packet in blue type and the response from your XMTR module in red type.
If you do not get a response, or if you get something other than the response
you expected, check the following troubleshooting tips:
l
Did you use the correct serial-number information for your XMTR module? Remember you must have eight bytes of serial-number information.
If your Serial Number High appears shorter than four bytes (eight hex digits), just place 0s in the most-significant positions—on the left end of the
Serial Number High—to create a four-byte (8 hex-digit) value. If for example your Serial Number High (SH) appears as [095AC3] in the Modem
Configuration window, place zeros on the left end to create eight hex digits
in all: 00095AC3.

Introduction

91

Recheck your typing.
Does the number of bytes in your message match the byte-count at the start
of the message—the two-byte value that follows the 0x7E Start Byte.
l
Did you calculate the proper checksum? Remember, don’t include the Start
Byte or the number-of-bytes hex values in your sum.
l
Have you set the proper configuration for the XMTR and RCVR modules?
l
Have you applied power to the XMTR module?
l
Is the RCVR module attached to the USB-to-XBee adapter board and is
that board connected to your PC?
Did you see the Serial Number Low (SL) in the information received by your
RCVR module and displayed in the X-CTU Terminal window? Use the information in Step 12 to parse the response into sections you can interpret.
Step 17. In this step you will learn what happens when an XBee module
transmits a command and the addressed module does not respond. Turn off
power to the breadboard so the XMTR module cannot operate. Wait for a few
seconds to let the power-supply voltage drop to 0. Go to the X-CTU Terminal
window and clear it. If you don’t see the Send Packet window, click on the
Assemble Packet button.
Click on the Send Data button to transmit the message you created in
Step 13 to the RCVR module. What do you see? I saw the information presented in Figure 11.3.
l
l

FIGURE 11.3 Sending the packet shown above to an unpowered XBee module results in
a short message that indicates an error condition; the 0x04 byte just before the checksum.

In this case—for the unpowered XMTR module—the message returned
came from the RCVR module with the status byte set to 0x04, which indicates No Response (see Step 12 or Table 10.1). The RCVR module transmitted
the packet containing the SL command to my unpowered XMTR module, but
it could not respond. When you connect an MCU to an XBee module, your
software can examine the value of the Status Byte and take an action, such as
sending you an alert message or trying another transmission.
Step 18. Now you will create a remote-AT-command request that addresses
your XMTR module to have it return its SC – Scan Channels value, which
you wrote down earlier in Step 3. But instead of using a long 64-bit address
(SH and SL), you will use the 16-bit source address (MY) you established in

92

How to Use API Packets to Control Remote XBee Modules

the Modem Configuration window under the Networking & Security heading.
Here’s how you do it:
In the following packet, I replaced the serial number for the XMTR
module with eight all-zero bytes, 0x00. Instead of placing 0xFFFE in the position left for the MY address information, I inserted the actual MY bytes for the
XMTR module: MY  0x5678. Then I used that address to create a remoteAT-command request as shown below:
7E	  start byte
000F	  number of bytes in transmission
17	  Remote-AT-command-request byte
52	  frame identifier value (all experiments use this value)
0000000000000000	  No serial number used, insert eight 0x00 bytes
instead
5678	  5678  source address for XMTR module
02	  immediate actions (explained later)
53	  hex code for letter S
43	  hex code for letter C
30	  checksum
When you choose to identify a remote module with its 16-bit MY address,
always insert eight 0x00 bytes for the serial number and insert the 2-byte MY
address below it. The source address takes the place of the 0xFFFE information that occupied these two bytes when you used the remote module’s 64-bit
(8-byte) address in the command sequence shown in Step 12.
You can use 64-bit addressing at any time by simply placing the 64-bit
(8-byte) address in the packet and following it with 0xFFFE in place of the MY
address. The 0xFFFE value indicates to XBee modules that 64-bit addressing is
in effect.
In this example, the AT command SC should return the Scan Channels
value from the XMTR module.
Your and my XMTR modules have the same source address, 0x5678, so
we can send the same packet to our XMTR module. Even though Digi has
assigned each module a unique serial number, you can create your own unique
16-bit identifier and use it instead to address an XBee module. The complete
API packet follows:
7E 00 0F 17 52 00 00 00 00 00 00 00 00 56 78 02 53 43 30

Clear the Terminal window and ensure you have power applied to the
remote XMTR module. Set the Terminal window to display hex values and
click on the Assemble Packet button. Clear the Send Packet window and type
the hex values shown above. After you have checked your values and corrected
any errors, click Send Data.
On my computer, I saw the information shown in Figure 11.4.
You will see standard information in response to the API packet followed by:
5678	  16-bit MY address of XMTR module
53	  hex code for letter S

Immediate Command Actions

93

FIGURE 11.4 This screen image shows the API packet with the SC AT command embedded in it and the response from the XMTR module.

43	  hex code for letter C
00	  status byte (status  OK)
1FFE	  requested Scan-Channel data from responding XMTR module
Step 19. Could you create an API packet to obtain the SC information by
using the complete address—SH and SL information—for your XMTR module instead of the 16-bit address? Remember to set the 16-bit MY address in
the packet to 0xFFFE. Try it.
Step 20. If you plan to go on to Experiment 12, you can leave your
XMTR module connected to the solderless breadboard and the RCVR module
attached to the USB-to-XBee adapter that connects to your PC. That experiment shows how to use AT commands in API packets to control outputs at a
remote XBee module.

IMMEDIATE COMMAND ACTIONS
In this experiment, each AT command sent to a remote module included:
0x02	  immediate actions
This Command Options value forces a remote module to immediately perform the action requested by the accompanying AT command. If you substitute
0x00 for this value, the receiving module postpones action until it receives an
Apply Changes (AC) command in a separate API packet. I recommend you
include the 0x02 Command Options value to cause changes to take effect immediately. Then you don’t have to remember to send a separate AC command later.

Experiment | 12

How to Use API
Packets to Control
Remote I/O Lines
REQUIREMENTS
2 XBee modules
1 XBee adapter
1 Solderless breadboard
2 LEDs
2 220-ohms resistors, 1/4 watt, 10% (red-red-brown)
1 USB-to-XBee adapter
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use AT commands in application programming interface (API) packets to control the output lines on a remote XBee
module. If you have not performed Experiments 10 and 11 I recommend you
do so before you proceed with this experiment.
In Experiments 10 and 11 you used the API packets and AT commands to
read values from and write values to both a local and a remote XBee module.
The local module (RCVR) connected to a nearby PC, but the remote module
(XMTR) used the wireless link to receive commands and transfer information. Now you will learn how to use AT commands to control output pins on a
remote module.
By using the AT commands a microcontroller (MCU) can directly control remote devices based on instructions in a program or results from math or
logic operations in software. If, for example, a remote XBee module provides
temperature information, another XBee module could receive the temperature information and an attached MCU could decide whether to turn on a fan
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

95

96

How to Use API Packets to Control Remote I/O Lines

or a heater, or generate an alarm signal. Then the MCU could transmit an AT
command to another remote XBee module to control the fan or heater, or possibly shut off both. The use of a wireless command to control remote devices
gives equipment designers great flexibility when they face a remote-control
problem.
If you just completed Experiment 11 and have your modules still in place,
please go to Step 3.
Step 1. In this step you will configure the XMTR module to operate with
the AT commands via the API. Ensure you have turned off power to the breadboard. Then place the XMTR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable and your PC. Find the XMTR configuration
in EX12_XMTR.pro.
Within the X-CTU window click on Modem Configuration and then
click on Restore. After a few seconds you should see the message “Restore
Defaults..complete” appear in the message area at the bottom of the X-CTU
window. Click on Read to obtain the restored default values from the XMTR
module.
Check to ensure the DL – Destination Address Low and MY – 16-Bit Source
Address each have a value of 0. This condition indicates the X-CTU software reset all the XMTR module settings to their default state. If DL and MY
are not equal to 0, perform Step 1 again.
In the Modem Configuration window, set the following values for the
XMTR module:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
Save these configuration settings in the XMTR module. After you see the
message “Write Parameters..Complete” in the bottom text window, remove
the USB-to-XBee adapter from the USB cable and remove the XMTR module from the adapter socket. Replace the XMTR module in its XBee adapter
socket on the breadboard.
Step 2. Place the RCVR module in the USB-to-XBee adapter and
reconnect this adapter to the USB cable. Find the RCVR configuration in
EX12_RCVR.pro.
Within the X-CTU window, click on Modem Configuration and then
click on Restore. After a few seconds you should see the message “Restore
Defaults..complete” appear in the message area at the bottom of the X-CTU
window. Click on Read to obtain the restored default values from the RCVR
module.
Check to ensure the DL – Destination Address Low and MY – 16-Bit
Source Address each have a value of 0. This condition indicates the X-CTU
software reset all the RCVR module settings to their default state. If DL and
MY are not equal to 0, perform Step 2 again.

Introduction

97

In the Modem Configuration window, set the following values for the
RCVR module:
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
Save these configuration settings in the RCVR module. Leave the RCVR
module in the USB-to-XBee adapter socket connected to the PC.
Step 3. The schematic diagram in Figure 12.1 shows the connections
needed for the XMTR module in your breadboard. If you have connections
other than 3.3-volt power (pin 1) and ground (pin 10) on the XMTR module,
disconnect them now. Connect the LEDs and resistors to the AD2-DIO2 pin
(pin 18) and the AD3-DIO3 pin (pin 17).
+3.3 V

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD2–DIO2
AD3–DIO3
LED2
220

LED1
220

FIGURE 12.1 In this experiment you must connect an LED and a resistor in series for two
I/O pins.

Step 4. Now you will learn how to send a command packet to the remote
XMTR module to turn the LEDs on or off. To briefly review, an API packet
uses the basic framework shown below.
0x7E	  start byte
0x__	  message length
Insert AT-command-specific structure here
0x__	  checksum
Depending upon the AT command you choose to send, the AT-commandspecific structure varies slightly. Use a local AT command to control an XBee
module attached to your PC or an MCU. Use a remote AT command to send
the command to a remote module you specifically address. Information in a
remote AT command includes:
l
An identifier of 0x17, which indicates a remote AT-command request
l
A frame-identifier value of your choice (all experiments use 0x52)

98

How to Use API Packets to Control Remote I/O Lines

The 64-bit destination address; that is, the remote module’s serial number
The destination module’s 16-bit network address (MY)
l
A Command Options byte
l
The AT command
l
Any parameter the AT command requires
In Experiment 11 you learned how to use a remote module’s 16-bit MY
address to select it, rather than use its longer 64-bit serial number. This experiment continues the MY type of addressing. Your and my XMTR module have
the same MY address of 0x5678, which we set in the Modem Configuration
window and programmed into our XMTR module.
To control the AD2-DIO2 (pin 18) line for LED1, you use the the D2DIO2 Configuration command and follow it with the condition you want to set
for that pin. You can have one of five settings for I/O pins AD0-DIO0 through
AD5-DIO5, as shown in Table 12.1. The AD6-DIO6 and AD7-DIO7 pins have
digital I/O functions, too, but they lack the ADC capability and have other
functions instead.
l
l

Table 12.1 I/O Pin Configurations for Remote AT Commands
I/O Parameter

Configuration

0x00

Disabled

0x01

Do Not Use

0x02

ADC - Analog Input

0x03

DI - Digital Input

0x04

DO - Digital Output (Low)

0x05

DO - Digital Output (High)

A digital-output-low condition forces the corresponding pin to ground,
or logic 0. A digital-output-high condition forces the corresponding pin to
approximately 3 volts, or logic 1. To set the D2 pin as a digital output in a
logic-1 state (LED on), you use the D2 command and follow it with the value
5 as shown in the API packet that follows.
Important: To transmit a D2 command, for example, you use the ASCII
hex value for the letter D (0x44) and the ASCII hex value for the numeral 2
(0x32). Do not enter the letter D or the numeral 2. They will make no sense to
an XBee module in API mode.
7E	  start byte
0010	  number of bytes in transmission
17	  Remote AT Command Request byte
52	  frame identifier value
0000000000000000	  XMTR serial number (set to 0s)
5678	  5678  source address for XMTR module

Introduction

99

02	  Command Options byte (immediate)
44	  hex code for letter D
32	  hex code for numeral 2
05	  hex code for I/O pin action (see Table 12.1)
4B	  checksum
Step 5. Turn on power to your XMTR module and the LED circuits. In
the Terminal window, clear the Send Packet window and type in the command
packet below:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 32 05 4B
Transmit it to your powered XMTR module. What did you observe? LED1
should turn on and you should see a response in the Terminal window similar
to that shown in Figure 12.2.

FIGURE 12.2 An API packet to turn on an LED at the AD2-DIO2 output pin caused the
XMTR to transmit the response shown here.

Here’s how the hex information breaks down for the latter part of the reply
message:
7E 00 0F 97 52 00 13 A2 00 40 49 E0 EC 56 78 44 32 00 C8
...
5678	  16-bit address of XMTR module
44	  hex code for letter D
32	  hex code for numeral 2
00	  status byte (OK)
C8	  checksum
To review: The response includes the D2 command you sent followed by
the status byte, which in this case indicated OK.
Step 6. Can you create an API packet that includes an AT command to turn
off LED1 at the AD2-DIO2 pin?
Here is a basic packet framework for you:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 ___ ___ ___ ___
See the answer at the end of this experiment. In the framework above,
insert the hex bytes for the command and for the I/O action you want to occur.
Then calculate the checksum for the 16 AT-command bytes. Remember to take
the two least-significant hex digits from the sum and subtract only them from
FF to yield the checksum. (You can turn off LED1 in more than one way, as
explained later.)

100

How to Use API Packets to Control Remote I/O Lines

Step 7. Send your packet to the XMTR module. You should see your transmitted packet in blue type and the response from your XMTR module in red
type in the X-CTU Terminal window. Your LED1 should turn off.
If you do not get a response, or if you get something other than the
response you expected, check the following troubleshooting tips:
l
Recheck your typing.
l
Does the number of bytes in your message match the byte-count at the start
of the message—the two-byte value that follows the 0x7E start byte.
l
Did you calculate the proper checksum? Remember, don’t include the start
byte or the number-of-bytes values in your sum. On some hexadecimal calculators, it’s easy to confuse a lower-case b with the numeral 6.
l
Have you set the proper configuration for the XMTR and RCVR modules?
l
Have you applied power to the XMTR module? Have you properly connected the LEDs and resistors?
l
Is the RCVR module attached to the USB-to-XBee adapter board and is
that board connected to your PC?
Step 8. To turn off LED1, I used the D2 04 command and the following
packet:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 32 04 4C
This packet forces the AD2/DIO2 (pin 18) output to a logic 0, so no current
will flow from the XBee module pin: Both sides of the LED see only a ground
connection.
You also could use the following commands to turn off the LED.
D2 03, which changes the AD2/DIO2 pin to become a digital input
D2 02, which changes the AD2/DIO2 pin to connect as an input to the
ADC
D2 00, which disables the AD2/DIO2 pin
Step 9. Create a packet that will turn on LED2 at the AD3-DIO3 pin, and
another packet to turn it off:
LED On:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 ___ ___ ___ ___
LED Off:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 ___ ___ ___ ___
See the answers at the end of this experiment.
Unfortunately, the XBee modules do not have a command that lets you
change the logic condition at several bits simultaneously. You must do so one
at a time. Keep in mind, though, the API packets and AT commands used in
this experiment all started with the same information:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 ___ ___ ___ ___
followed by a two-byte command, a parameter, and a checksum. You’ll
find similar patterns when you use API packets to transmit other AT commands. When a microcontroller sends an API packet, it simply sends one byte
after another with no ASCII space values between them and usually no delay
between them.

Experiment Answers

101

EXPERIMENT ANSWERS
Important: In this experiment you did not configure the two ADx-DIOx
pins on the XMTR module as digital outputs. The API command performed
this operation by causing the XMTR module to put these pins in a logic-1
or a logic-0 state. You could have used a command to cause a remote XBee
module use an I/O pin as an analog input. The AT commands within an API
packet give you many control options. You also could control PWM outputs at
a remote XBee module, for example.
Step 6. Can you create a packet with a command to turn off LED1 at the
AD2/DIO2 pin?
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 32 04 4C
Step 9. Create a packet that will turn on LED2 and another packet to turn
it off:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 05 4A
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 04 4B

Experiment | 13

Remote Control
of PWM Outputs
REQUIREMENTS
2 XBee modules
1 XBee adapter
3 LEDs
3 220-ohm resistors, 1/4 watt, 10% (red-red-brown)
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use an application programming
interface (API) command to control a PWM output on a remote XBee module
without applying a voltage to the AD0-DIO0 or AD1-DIO1 input at a transmitting module. The PWM outputs have some particular traits you must pay
careful attention to if you need to use PWM signals in a design. You will learn
about those traits in this experiment.
Step 1. In this step you will configure the module labeled XMTR to operate with AT commands via the API. Ensure you have turned off power to the
breadboard. Then place the XMTR module in the USB-to-XBee adapter and
reconnect this adapter to the USB cable and your PC. You can find the configuration information that follows in the file EX13_XMTR.pro.
Within the X-CTU window, click on Modem Configuration and click on
Restore. After a few seconds you should see the message “Restore Defaults..
complete” appear at the bottom of the X-CTU window. Click Read to obtain
the default values from the XMTR module. Ensure the DL – Destination
Address Low and MY – 16-Bit Source Address each have a value of 0. If they
do not, perform Step 1 again.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

103

104

Remote Control of PWM Outputs

In the Modem Configuration window, set the following hex values for the
XMTR module:
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
P0 – PWM0 Configuration	  2-PWM OUTPUT
PT – PWM Output Timeout	  FF
Save these configuration settings in the XMTR module and move it to its
XBee adapter socket on the breadboard. Do not turn on power to the breadboard.
Step 2. If you just completed Experiment 12 and have not changed any of
the Modem Configuration settings in the module labeled RCVR, please go to
Step 3. Otherwise, place the RCVR module in the USB-to-XBee adapter and
reconnect this adapter to the USB cable. You can find the configuration information that follows in file EX13_RCVR.pro.
Within the X-CTU window, click on Modem Configuration and click on
Restore. After the message “Restore Defaults..complete” appears, click Read.
If the DL – Destination Address Low and MY – 16-Bit Source Address are not
equal to 0, perform Step 2 again.
In the Modem Configuration window, set the following values for the
RCVR module:
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
Save these configuration settings in the RCVR module and leave the
RCVR module in the USB-to-XBee adapter socket connected to the PC.
Step 3. The circuit diagram in Figure 13.1 shows connections needed for
the XMTR module in your breadboard. If you have connections other than
3.3-volts power (pin 1) and ground (pin 10) at the XMTR module, disconnect them now. One LED circuit connects to pin 6, the PWM0-RSSI output,
and will indicate activity at this pin. The other two LEDs connect to the AD0DIO0 and AD3-DIO3 pins to indicate their logic state. A logic 0 at a pin turns
on the corresponding LED. I recommend you keep the PWM0 LED separate
from the other two because you will monitor its operation most often.
Step 4. An XBee module has two PWM outputs, PWM0 and PWM1,
with corresponding output-control commands M0 and M1. You also can set a
PWM-output configuration via a P0 or P1 API command, but in this experiment you set the P0 configuration via the X-CTU Modem Configuration
window in Step 1. A P0 or P1 command sent in an API packet would require
the same settings available in the X-CTU Modem Configuration window:
0 – DISABLE, 1 – RSSI, or 2 – PWM OUTPUT.
Because you already set the PWM0 pin on the XMTR module to act as
an output, you only need to send a PWM value, between 0X000 and 0x3FF,
to control the pulse width. The output ranges from 0 to 100 percent, and it

Introduction

105

+3.3 V
LED

220

PWM0–RSSI

Top View
1
2
3
4
5 XBee XB24
6
7
8
9
10

20
19
18
17
16
15
14
13
12
11

LED

LED

220

220

DIO0

DIO3

FIGURE 13.1 An LED connected to the PWM0-RSSI output lets you monitor activity
of the PWM portion of an XBee module. Two other LEDs let you observe changes at the
DIO0 and DIO3 pins.

provides 1024 values, from 0 through 102310. In the M0 API packet, the value
0x0380 will set the PWM0 output to about a 1-to-8 ratio of logic 0 to logic 1
periods, which will make the LED turn on about 12 percent of the time and
appear dim. The higher the PWM value, the longer each pulse provides a
logic-1 signal.
Now you will prepare to send an AT command to the remote XMTR module to control the PWM output. This experiment continues to use the 16-bit
Source Address for the XMTR module instead of its 64-bit serial number. Thus
your and my XMTR module have the same Source Address, 0x5678, which
we set in the Modem Configuration window, so we can use the same API
packet to control the PWM-output LED at the XMTR module. In the partial
packet below, the 2-byte value that controls the PWM0 output follows the M0
command.
...
4D	  hex code for letter M
30	  hex code for numeral 0
03	  most-significant byte of PWM value
80	  least-significant byte of PWM value
...
Important: When you transmit an M0 or an M1 command use the hex
code for the letter M (0x4D) and the hex code for numeral 0 (0x30) or numeral
1 (0x31). Do not enter a 0 or 1. (The same requirements hold true for a P0 or

106

Remote Control of PWM Outputs

P1 command.) The M0 and M1 commands sent without the two data bytes let
you read the value currently in use.
Step 5. If your breadboard is powered, remove power, wait about five seconds, and turn power on. If power is off to start, turn on power to your XMTR
module now. The LED connected to the PWM0 output should turn on to full
brightness because when reset a PWM output provides a logic-0 signal. Type
the following packet into the Send Packet window but do not transmit it to the
powered XMTR module.
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

This experiment involves sending many command packets to the XMTR
module, but most of the hex values remain the same. You need to change only
the byte count value and the last few bytes in the command packets that follow. In the previous packet I underlined the bytes that change from packet to
packet.
Please read this paragraph before you perform the steps it describes. Watch
the LED and send the packet. The PWM0 LED should dim when the XMTR
receives the M0 command packet. Continue to watch the LED for about 30
seconds. What did you observe? After the 30-second period, turn off power to
the XMTR module and go back to the start of this paragraph, and time the
period between the dimming of the LED and the next change in brightness.
The LED at my XMTR module dimmed and then about 22 seconds later it
turned on to full brightness. Perhaps you thought the LED would remain dim
due to a continuing PWM output of pulses.
Step 6. The Digi International manual for the XBee/XBee-PRO modules
provides the following cryptic description of the PT – PWM Output Timeout,
which you configured with the value 0xFF in Step 1:
PWM Output Timeout. Set/Read output timeout value for both PWM
outputs. When PWM is set to a non-zero value: Due to I/O line passing,
a time is started which when expired will set the PWM output to zero.
The timer is reset when a valid I/O packet is received. Parameter
Range: 0 – 0xFF [100 msec]. (Ref. 1)
I assumed this description meant the PWM output would turn on with
the pulse width set with the 0x380 value. Then, after the programmed period,
which for 0xFF equals 25.5 seconds, the PWM output would become a logic 0.
That matched the observation in Step 5, although I measured 22 seconds with
a stopwatch.
The Digi description seems to imply the next I/O command would reset
the timer and thus turn on the PWM output again. So I transmitted a command
packet to change the DIO3 pin to a logic 0:
44   hex code for letter D
33   hex code for numeral 3
04   04 (DO-LOW)

Introduction

107

Here’s the complete packet for the AD3-DIO3 DO-LOW command:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 04 4B

Although this command turned on the LED connected to the DIO3 pin, it
did not reactivate the PWM output. I also tried the command packet to set the
AD0-DIO0 pin to a logic 0:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 30 04 4E

Likewise, this command failed to reactivate the PWM output, although it
turned on the DIO0 LED. Try these command packets with your remote XBee
module to confirm this behavior. Only the underlined values change.
Step 7. So how can you obtain a continuous output at the PWM0 pin?
You might wonder if a second transmission of the M0 command packet would
restart the PWM output. Turn off power to your XMTR module, wait a few
seconds and turn power on again. This action resets the XMTR module. Then
send the command packet for M0 with a value 0x0380:
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

The PWM0 LED should dim and become brighter after 22 seconds when
the PWM0 output changes to a logic 0. Resend the M0 command packet and
observe the LED again. Does it brighten again after 22 seconds? In my lab, the
second transmission of the packet caused the LED to dim and it remained that
way. An oscilloscope confirmed the continuing presence of the PWM0 pulses.
As long as the XMTR module remained powered, it produced the proper
PWM signal. So it seems the first M0 command packet started the timer, but
subsequent M0 command packets produce a continuing PWM output without
the timed period. Do not turn off power to your breadboard or to the XMTR
module.
Step 8. The Digi manual referred to earlier noted, “The timer is reset when
a valid I/O packet is received.” That statement seems to imply an I/O command
will reset the timer and thus the PWM output. The next steps determine if this
timer reset will occur and how I/O-port commands affect PWM operation.
Step 9. At this point, the LED on the PWM0 pin should remain dim
because the PWM output continues to produce short logic-0 pulses. If the LED
connected to the PWM0 pin on your XMTR module remains dim, skip ahead
to Step 10. If the LED appears bright, or if in doubt, continue with this step.
Remove power from the XMTR module and breadboard, wait five-or-so
seconds, and turn on power. Then send the packet that follows:
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

Wait until the LED becomes bright again and send the packet a second
time. The LED now should remain dim beyond the 22-second timeout period.
That condition indicates the PWM0 output continues to produce short logic-0
pulses.

108

Remote Control of PWM Outputs

Step 10. Type the following command to set the DIO0 pin to a logic 0 and
observe what—if anything—happens to the PWM LED brightness:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 30 04 4E

The LED gets brighter as soon as you send the command. Thus, the I/O
command stopped the PWM output, which became a logic 0 again. Do not turn
off power to your XMTR module. Resend the PWM M0 command packet you
used earlier:
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

Did the PWM output change the brightness of the LED? The LED should
have dimmed, which means the PWM0 output again has a pulse output. The
LED connected to the DIO0 pin should turn on. Now, resend the packet to
again set the AD4-DIO4 pin to a logic 0:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 30 04 4E

Did the brightness of the PWM0 LED change? It should not change.
Although you sent the AD0-DIO0 command twice, the first command changed
the state of the pin from a logic 1 to a logic 0. The second command had
no effect because the DIO0 output was already a logic 0. Thus, no change
occurred at the DIO0 pin. You can conclude that only a change in the state of
an I/O pin will stop the PWM outputs and force them to a logic-0 state.
When you consider this PWM-reset action and the reset caused by the PWM
Output Timeout, maintaining a continuous PWM output becomes a chore. You
can use a work-around, though, to get close to a continuous PWM output.
Step 11. Unfortunately, neither the Digi International Web site nor other
sites provide examples of how to properly use the PWM Output Timeout or
how to maintain a continuous PWM output, so I ran a few more experiments
that you will duplicate in the following steps.
Turn off power to your breadboard, remove the XMTR module from its
adapter socket, and place it in the USB-to-XBee adapter. Read its Modem
Configuration information and find the PT – PWM Output Timeout setting
under the I/O Line Passing heading. Set the PT value to zero: PT – PWM
Output Timeout  0.
Save this new configuration in the XMTR module and return it to the
adapter in the breadboard, but do not turn on power. With a PWM timer value
of 0, what might you expect?
In the X-CTU Send Packet window, re-enter the M0 PWM command
packet:
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

Turn on power to your breadboard and send the packet. The LED connected to the PWM0 output should dim and remain dim. No timeout occurs
and the PWM0 output continues to produce the expected signal. After an hour

Introduction

109

or so, my XMTR module continued to produce the same PWM signal, as seen
with an oscilloscope. During that time I had not sent the XMTR module any
other commands. It seems as though a PT – PWM Output Timeout setting of 0
disables the timeout period for the PWM output, which now continues to produce pulses for as long at the XMTR module remains powered.
Step 12. Send the XMTR module the command packet used in Step 6 to
cause the XMTR module to place a logic-0 signal on the DIO3 pin:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 04 4B

What happens to the PWM0 LED when you send this packet? That LED
brightened, signaling the PWM0 output had reset to a logic 0. The LED
connected to the DIO3 pin also turned on. Although setting the PT – PWM
Output Timeout value to 0 eliminated the timeout period for the PMW0 signal,
changing an I/O pin still stops the PWM signal and forces the PWM0 output to
logic 0.
I found an imperfect solution to the problem, and, absent additional information from Digi or from someone with additional XBee-module PWM
experience, it must suffice for a stand-alone XBee module. Because an I/O
command might disable a PWM output I recommend you set PWM Output
Timeout to 0 and follow any I/O command with a PWM M0 or M1 command
to “refresh” the corresponding PWM value. Given the other useful operations
of the XBee modules, Digi’s approach to control of PWM outputs seems odd.
Step 13. Turn off power to your XMTR module and then turn on power.
Send the XMTR module the command that follows to start the pulsed output
on the PWM0 pin. You should see the PWM0 LED go dim.
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

Then in the Send Packet window, type the following packet that includes
two commands, placed in sequence:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 04 4B 7E
00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 4D 30 03 80 C6

Do not press the Enter key, just keep typing so the Send Packet window has
a continuous series of hex values. The first packet (underlined) forces the DIO3
pin to a logic 0 and the packet that immediately follows sends the same PWM
command packet that created the PWM pulses at the start of this step. Watch
the PWM0 LED and click Send Data. What did you observe on the LED?
The PWM0 LED produced a brief flash and then went back to its dim
mode. To start, the PWM output produced the expected pulses that dimmed the
LED. The command that turned on the DIO3 LED turned off the PWM pulses
so the PWM0 pin dropped briefly to logic 0, which causes the LED to become
bright. The second command in the packet turned the PWM back on with the
original value, 0x380, so the LED went back to its dim condition. The bright
flash appeared for about 17 msec. Figure 13.2 provides a timing diagram that
shows the relationship of the PWM0 output to the DIO3 output change.

110

Remote Control of PWM Outputs
0.90 msec

1
0

PWM Output

PWM Output

1
0

DIO3 Output

17 msec

Time

FIGURE 13.2 This timing diagram shows the relationship between the change at an output pin caused by a command packet and the end of a series of PWM pulses. A second
command packet reloads the PWM0 value and the PWM output restarts.

Step 14. Resend the long packet that contains the DIO3 and the PWM
command to the XMTR module, what do you think happened? Nothing happens, because the DIO3 command does not change any of the I/O pin settings.
Only a change turns off the PWM output.

A BETTER APPROACH
Given the difficulty sorting out the use of the PWM capabilities in an XBee
module, if you need a continuous PWM output without the glitches introduced
by I/O changes I recommend using a small microcontroller. Many MCUs provide a PWM output that operates without interruption. An XBee module could
send PWM values to an attached MCU via its serial port. Likewise, the MCU
could provide many types of I/O ports not available on an XBee module. In
this situation, let the XBee module provide wireless communications and have
the MCU control analog, digital, and PWM signals.

REFERENCE
“XBee/XBee-PRO RF Modules,” Product Manual V1.xEx – 802.15.4 Protocol, Digi
International. 2009.

Experiment | 14

How to Parse Data from
Digital and Analog Pins
and Control Individual
Digital Outputs
REQUIREMENTS
2 XBee modules
1 XBee adapter board
1 220-ohm resistor, 1/4 watt, 10% resistor (red-red-brown)
1 4700-kohm, 1/4W, 10% resistor (yellow-violet-red)
1 10-kohm, 1/4W, 10% resistor (brown-black-orange)
1 10-kohm potentiometer
1 LED
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use an application programming
interface (API) command to ask a remote XBee module to reply with information
about the state of its digital I/O pins and the values from all active analog-todigital converter (ADC) inputs.
Step 1. In this step you will configure the remote XMTR module to operate
with the AT commands via API packets. Ensure you have turned off power to
the breadboard. Then place the XMTR module in the USB-to-XBee adapter
and reconnect this adapter to the USB cable and your PC.
Within the X-CTU window, click on Modem Configuration and then
click on Restore. After a few seconds you should see the message “Restore
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

111

112

How to Parse Data from Digital and Analog Pins

Defaults..complete” appear. Click on Read to obtain the restored default values
from the XMTR module.
Check to ensure the DL – Destination Address Low and MY – 16-Bit Source
Address each have a value of 0. This condition indicates the X-CTU software
has reset all the XMTR module settings to their default state. If DL and MY
are not equal to 0, please retry the procedure in this step.
In the Modem Configuration window, set the following hex values for
the XMTR module. You can find this configuration information in the file:
EX14_XMTR.pro.
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
D7 – DIO7 Configuration	  3-DI
D6 – DIO6 Configuration	  3-DI
D5 – DIO5 Configuration	  2-ADC
D4 – DIO4 Configuration	  2-ADC
D3 – DIO3 Configuration	  DO LOW
D2 – DIO2 Configuration	  DO LOW
D1 – DIO1 Configuration	  DO HIGH
D0 – DIO0 Configuration	  DO HIGH
These settings establish two digital-input pins (D7 and D6), two ADCinput pins (D5 and D4), two digital outputs set at logic 0 (D3 and D2), and
two digital outputs set at logic 1 (D1 and D0). Double check the configurations
above and save them in the XMTR module.
Remove the USB-to-XBee adapter from the USB cable and remove the
XMTR module from the adapter socket. Place the XMTR module in its XBee
adapter socket on the breadboard.
Step 2. Place the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable.
Within the X-CTU window, click on Modem Configuration and then click
Restore. After a few seconds you should see the message “Restore Defaults..
complete” appear. Click on Read to obtain the restored default values from the
RCVR module.
Check to ensure the DL – Destination Address Low and MY – 16-Bit Source
Address each have a value of 0. This condition indicates the X-CTU software
has reset all the RCVR module settings to their default state. If DL and MY
are not equal to 0, please perform this step again.
In the Modem Configuration window, set the values shown next for the RCVR
module. You can find this configuration information in the file: EX14_RCVR.pro.
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
Save these configuration settings in the RCVR module. Leave the RCVR
module in the USB-to-XBee adapter socket connected to the PC.

Introduction
+3.3 V

113

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
AD6–DIO6
16
15
14
13
DIO7
12
11

FIGURE 14.1 Connections needed to create a logic-0 signal for two XBee inputs.

Step 3. The schematic diagram in Figure 14.1 shows the connections
needed for the XMTR module in your breadboard. If you have other connections at the XMTR module, please disconnect them now and make only the
connections shown in Figure 14.1.
Step 4. This experiment continues to use a remote module’s 16-bit address,
so your and my XMTR module have a Source Address of 0x5678, which we
set in the Modem Configuration window and saved in our XMTR modules.
The 2-character AT command IS – Force Sample causes the addressed
module to reply with information about all its I/O ports and active ADC inputs.
This command has no parameters associated with it. The characters I and S
have equivalent ASCII hex values: I  0x49 and S  0x53.
The partial packet below includes the IS command:
...
5678	  16-bit source address (network address)
02	  Value that causes immediate actions
49	  Hex code for letter I
53	  Hex code for letter S
??	  Checksum
Step 5. Turn on power to your XMTR module in the breadboard and
switch to the X-CTU Terminal window. Clear the Terminal window and ensure
you have it set for Show Hex. Click on Assemble Packet and in the Send
Packet window, type the following hex values:
7E 00 0F 17 52 00 00 00 00 00 00 00 00 56 78 02 49 53 2A
Click Send Data. You should see hex values as shown in Figure 14.2, but
not all these values will match yours. The information that follows shows the
portion of the reply that follows the IS command and the status byte:
...
01
 one sample of I/O lines and ADC inputs
60	  first active-signal byte
CF	  second active-signal byte
00	  first digital-data byte

114

How to Parse Data from Digital and Analog Pins

03	  second digital-data byte
03FF	  analog sample from AD4-DIO4
03FF	  analog sample from AD5-DIO5

FIGURE 14.2 The X-CTU terminal shows the results from sending the IS command.

You set the XMTR module for D5 and D4 as ADC inputs, so the 0x60 byte
identifies these active inputs as shown in Table 14.1. You did not configure the
D8 pin as an input, so it remains 0; inactive. The second active-signal byte,
0xCF, also shown in Table 14.1, indicates all pins set for digital inputs except
for the AD5-DIO5 and AD4-DIO4, which now serve as analog inputs.
Table 14.1 The Active-Signal Bytes in the Reply to an IS Command
First Active-Signal Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

A5

A4

A3

A2

A1

A0

D8

Binary Data

0

1

1

0

0

0

0

0

Hex Data

6

0

Second Active-Signal Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Binary Data

1

1

0

0

1

1

1

1

Hex Data

C

F

The next two bytes, 0x00 and 0x03, shown in Table 14.2, give you the state
of the digital pins. You can ignore the first digital-data byte because the D8
input was not set for any digital input.
For the second digital-data byte 0x03, also shown in Table 14.2, you see
a logic 1 for D1 and D0 because you configured them as digital-output-high
(DO-HIGH) pins. Pins D3 and D2 show logic 0 because you configured
them as digital-output-low (DO-LOW) pins. You grounded input pins D7 and

Introduction

115

D6 on the breadboard for the XMTR module, so they appear as logic 0. You
can ignore the D5 and D4 bits (grey background) because they correspond to
analog inputs.

Table 14.2 The Digital-Data Bytes in the Reply to an IS Command
First Digital-Data Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

X

D8

Binary Data

0

0

0

0

0

0

0

0

Hex Data

0

0

Second Digital-Data Byte
First Hex Character
Second Hex Character
Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

0

0

0

0

0

0

1

1

Hex Data

0

3

The next two hex values, 0x03FF and 0x03FF, represent the voltages present at the ADC inputs you selected, D4 and D5. Because you did not connect
these inputs to an external signal, they “float” to a 3.3-volt level and give a
full-scale 10-bit value of 0x3FF.
Important: The IS - Force Sample command returns information not only
for active inputs, but also for the state of any active outputs. This command
gives you a way to quickly determine what data—input or output—exists on
the digital I/O pins and it forces an immediate analog-to-digital conversion of
the voltages present on any active ADC inputs. Later when you work with an
XBee module and an MCU you will learn how to use the IS command in software to poll all active XBee modules to gather information from them. The IS
command can play an important part in the repertoire of commands used in a
network of modules that collect information from remote devices.
As you can guess, creating an API command packet for each module
can become tedious and could lead to errors in inserting proper addresses.
Thankfully, MCU software can handle these tasks. Creating packets by hand
only makes sense for testing and experiments such as those in this book.
Step 6. In this step you will change the inputs at four pins and add an LED
as an output indicator, as described next and shown in Figure 14.3.
l
Turn off power to your XMTR module
l
At DIO7 (pin 12) and DIO6 (pin16) change the logic-0 (ground) inputs to
logic-1 (3.3 volts) inputs.

116
l

l

l
l

How to Parse Data from Digital and Analog Pins

Connect the a 10-kohm potentiometer between 3.3 volts and ground and
connect the potentiometer’s center contact to the AD5-DIO5 pin (pin 15).
Adjust the potentiometer to about halfway between its end points.
Connect a 10-kohm fixed resistor (brown-black-orange) and a 4.7-kohm
resistor (yellow-violet-red) as shown in Figure 14.3 and connect the junction of the resistors to the AD4-DIO4 pin (pin 11).
Connect the XBee module ADC reference line, VREF (pin 14) to 3.3 volts.
Connect the LED to the AD2-DIO2 pin as shown.
+3.3 V
+3.3 V

LED

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

10 kohms

20
19
18
17
16
15
14
13
12
11

220

AD2–DIO2
AD6–DIO6
+3.3 V
AD5–DIO5
VREF
+3.3 V
DIO7
AD4–DIO4

+3.3 V

+3.3 V
10 kohm

4.7 kohm

FIGURE 14.3 Connections for analog and digital inputs at the remote XMTR module to
provide voltages to the ADC inputs and logic levels for digital inputs.

Step 7. Turn on power to the breadboard and XMTR module and the LED
should turn on because the AD2-DIO2 pin at the XMTR module still has the
DO LOW setting established in Step 1. Thus current flows through the LED
and into the XBee module.
Open the X-CTU Terminal window and clear it. In the Send Packet window you should still see the packet entered in Step 5. If not, go to Step 5 and
re-enter the packet. Click on Send Data. What do you see in the Terminal window? I saw the information shown in Figure 14.4. Our XMTR-module serialnumber bytes will not match.
Refer to Tables 14.1 and 14.2 or use blank tables in Appendix I to help
you interpret the I/O-pin data obtained from your XMTR module. The data I
received follows and your data should look similar.
01
 1 sample of I/O lines and ADC inputs
60	  D5 and D4 set as analog inputs
CF	  D7, D6, and D3--D0 set as digital pins
00	  First digital-data byte (D8)

Introduction

117

C3	  Second digital data byte, D7, D6, D1 D0  logic 1 and D2 and
D3  logic 0
02B8	  10-bit analog value from AD4 (will vary from my data)
0211	  10-bit analog value from AD5 (will vary from my data)

FIGURE 14.4 This information shows the effect of adding digital and analog signals at
the XMTR module and sending the IS command.

Step 8. Change the potentiometer setting, resend the IS-command packet,
and confirm the analog value from input-pin DIO5 changes. You can change
the logic level at the digital inputs DIO7 (pin 12) and DIO6 (pin 16) and confirm they change, too.
Now you know how you can force a module to transmit the state of its
digital inputs and outputs as well as perform an analog-to-digital conversion
at active ADC inputs, on command. Note, though, you cannot force this pinsampling action when you have a module in either the DOZE or HIBERNATE
sleep mode.
Step 9. Could you create a command packet to turn the LED off? What
state do you need at the AD2-DIO2 pin to turn off the LED?
Use the following “framework” to create a command packet that turns the
LED off:
7E 00 __ 17 52 00 00 00 00 00 00 00 00 56 78 02 __ __ __ __ __ __ __ __
The underlined spaces leave room for the command, parameter, bytecount, and checksum values you think appropriate. Hint: Look in the X-CTU
Modem Configuration window for the setting that configures the D2 pin. Find
an answer at the end of this experiment.
After you turn the LED off, re-enter the command packet used earlier to
force a sample of the I/O pins at the XMTR module:
7E 00 11 17 52 00 00 00 00 00 00 00 00 56 78 02 49 53 2A
Can you determine from the reply to this command that the AD2-DIO2 pin
has a logic-1 (5 – DO HIGH) setting?
AT commands can manipulate individual bits at a remote XBee module,
an important capability when you need to control individual devices without
disturbing others. You could control sprinkler valves, door locks, automobile ignition, appliances, motors, and so on. The reply to an IS command lets
you confirm settings so you can determine the state of inputs and outputs at a
remote module as well as sample analog signals.

118

How to Parse Data from Digital and Analog Pins

EXPERIMENT ANSWERS
Step 8. You can use the AT command D2 to control the AD2-DIO2 pin. To
force that pin to a logic-1 state, use the command D2 05, which configures the
pin for a data-output-high (DO – HIGH) state. The packet shown next will turn
the LED off:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 32 05 4B
To turn the LED back on, use D2 04 to configure the pin for a data-outputlow (DO – LOW) state.
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 32 04 4C
In each packet, you changed only the byte that set a configuration for the
selected I/O pin and the checksum. In many cases, you need not create a completely new packet when you work with I/O pins.

Experiment | 15

How to Control Several
XBee Modules with
Broadcast Commands
REQUIREMENTS
3 XBee modules
2 XBee adapter boards
4 LEDs
4 220-ohm, 1/4 watt, 10% resistors (red-red-brown)
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to communicate with more than one
remote XBee module via wireless communications. You will use the application programming interface (API) to send AT commands to two remote modules to turn LEDs on or off. In previous experiments you used two modules,
one marked XMTR and one marked RCVR. This experiment adds a third
XBee module, which I labeled END. If you have only two XBee modules, you
can skip this experiment, but I recommend you read at least through it.
You also will learn how to use a broadcast command that affects all remote
modules and how to change XBee parameters semi-permanently so they
remain set when power ceases to an XBee module.
Step 1. In this step you configure the XMTR module to operate with the AT
commands via the API. Ensure you have turned off power to the breadboard.
Then place the XMTR module in the USB-to-XBee adapter and reconnect this
adapter to the USB cable and your PC.
119
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

120

How to Control Several XBee Modules with Broadcast Commands

Within the X-CTU window, click on Modem Configuration and then click
Restore. After a few seconds you should see the message “Restore Defaults..
complete” appear. Click on Read to obtain the restored default values from the
XMTR module.
Check to ensure the DL – Destination Address Low and MY – 16-Bit Source
Address each have a value of 0. This condition indicates the X-CTU software
has reset all the XMTR module settings to their default state. If DL and MY
are not equal to 0, retry the procedure in this step.
In the Modem Configuration window, set the following hex values for the
XMTR module. Find this configuration information in the file: EX15_XMTR.pro.
DL – Destination Address Low	  1234
MY – 16-Bit Source Address	  5678
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
D3 – DIO3 Configuration	  4 – DO LOW
D1 – DIO1 Configuration	  5 – DO HIGH
These settings establish two digital-output pins on the XMTR module, one
set to a logic 0 and the other set to a logic 1. Double check the configurations
above and save them in the XMTR module.
Remove the USB-to-XBee adapter from the USB cable and remove the
XMTR module from the adapter socket. Insert the XMTR module in its XBee
adapter socket on the breadboard.
Step 2. For a second XBee module you also will use as a remote device,
follow the procedure in Step 1, but in the Modem Configuration window, set
the following hex values for this module, which in my lab I labeled END. Find
this configuration information in the file: EX15_END.pro.
DL – Destination Address Low	  0
MY – 16-Bit Source Address	  89FA
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
D3 – DIO3 Configuration	  4 – DO LOW
D1 – DIO1 Configuration	  5 – DO HIGH
These settings establish two digital-output pins on the END module, one
set to a logic 0 and the other set to a logic 1. Note: The END module has a
16-bit Source Address of 89FA. Double check the configurations above and
save them in the END module.
Remove the USB-to-XBee adapter from the USB cable and remove the
END module from the adapter socket. Insert a second XBee adapter in your solderless breadboard about 3 inches (7.5 cm) from the adapter used for the XMTR
module. Insert the END module into this second adapter. You should now have
two XBee modules, XMTR and END, in XBee adapters on your breadboard.
Step 3. Place the RCVR module in the USB-to-XBee adapter and reconnect this adapter to the USB cable.
Within the X-CTU window, click on Modem Configuration and then
click Restore. After a few seconds you should see the message “Restore

Introduction

121

Defaults..complete” appear. Click on Read to obtain the restored default values
from the RCVR module.
Check to ensure the DL – Destination Address Low and MY – 16-Bit
Source Address each have a value of 0. This condition indicates the X-CTU
software has reset all the RCVR module settings to their default state. If DL
and MY are not equal to 0, perform Step 3 again.
In the Modem Configuration window, set the following values for the RCVR
module. Find this configuration information in the file: EX15_RCVR.pro.
DL – Destination Address Low	  5678
MY – 16-Bit Source Address	  1234
AP – API Enable	  1-API ENABLED
IA – I/O Input Address	  FFFF
Check your configuration settings. Save these configuration settings in the
RCVR module. Leave the RCVR module in the USB-to-XBee adapter socket
connected to the PC.
Step 4. The schematic diagram in Figure 15.1 shows the connections
needed for both the XMTR and the END module in your breadboard. If you
have other wires or components attached to the XMTR or the END module,
please disconnect them now. Then add the components shown in Figure 15.1.
The photo in Figure 15.2 shows the arrangement of the XBee modules and
LEDs on my breadboard. I suggest you use a similar arrangement—or otherwise
label the LEDs—so you know which one corresponds to each output on a module.
Step 5. Turn on power to your breadboard and the two XBee modules,
XMTR and END. LED1 connected to the AD1-DIO1 pin on each module
should remain off and LED3 connected to the AD3-DIO3 pin should turn on.
Do you know why? (See the Answers section at the end of this experiment.)
+3.3 V
220

+3.3 V

LED1

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

220
LED3

AD1–DIO1
AD3–DIO3

FIGURE 15.1 This schematic diagram applies to the XMTR and the END XBee module
used in this experiment. (There is no LED2.)

122

How to Control Several XBee Modules with Broadcast Commands

FIGURE 15.2 Keep the LEDs near their respective XBee module and make sure you
know which LED corresponds to the AD1-DIO1 or AD3-DIO3 pin.

Step 6. Now you will write commands to change the state of the LEDs.
The following API command packets assume 16-bit addressing; 5678 for
the XMTR, and 89FA for the END modules. I have completed the first command and leave it to you to create the other three. You need change only the
underlined bytes to address a different module and change the state of either
the AD1-DIO1 or AD3-DIO3 pin. Remember, to turn an LED off, you need a
logic 1 at the corresponding output. A logic 0 will turn on the associated LED.
If you get stuck, see Answers at the end of this experiment.
l
Turn off LED3 at XMTR module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 05 4A
l
Turn on LED1 at XMTR module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 ___ ___ 02 ___ ___ ___ ___
l
Turn off LED3 at END module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 ___ ___ 02 ___ ___ ___ ___
l
Turn on LED1 at END module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 ___ ___ 02 ___ ___ ___ ___
Step 7. Note the state of the LEDs after you have sent the commands
above and the LEDs have changed on/off conditions.
XMTR: LED1 ______ LED3 ______ END: LED1 ______ LED3 ______
Now turn off the power to the XMTR and END modules, wait a few seconds,
and turn the power on again. What happens to the state of the LEDs? Do you
know why? For an explanation, go to the Answers section at the end of this
experiment.
Step 8. You can use the WR-Write command to change a remote module’s
configuration and make those changes remain constant even when you turn off
power to a module. In this step you will use the WR command to change the
power-up reset condition for the AD1-DIO1 configuration at the XMTR module.
If not already powered, turn on power to your breadboard. Each XBee
module should have its LED3 lit. The LED1 LEDs should remain off. Use the
command you created earlier to turn on LED1 at the XMTR module (0x5678).

Introduction

123

If you do not have a command packet written down, see the answer for Step 6
at the end of this experiment.
Now both LED1 and LED3 at the XMTR module should be lit. To make
this configuration remain as now set during power-up reset of the XMTR module, you must send a WR command. This command requires no parameters
and it has one byte fewer than the command packets sent to remote modules to
control LEDs:
7E 00 0F 17 52 00 00 00 00 00 00 00 00 56 78 02 57 52 1D
The packet above includes the byte 0x02 for immediate action, followed by
the ASCII values for the letters W (0x57) and R (0x52). Go to the Send Packet
window, type this packet, and send it. (Did you remember to change the third
byte that indicates packet length?)
What did you observe? You should see only a reply in the X-CTU Terminal
window with a status byte that indicates “OK.” The WR-Write command did
not affect the LEDs.
Turn off power to your breadboard, wait a few seconds, and reapply power.
What do you observe now? The LED1 and LED3 at the XMTR module turn
on because you have modified the I/O-pin configuration and saved it in the
XMTR module.
Now you must change the configuration for the XMTR module to its original state for this experiment. You could send the module two packets to do this,
but I recommend repeating Step 1, which uses the X-CTU program. When you
do, first read the configuration from the module and look at the I/O Settings
list. You should see both the D3-DIO3 and D1-DIO1 configurations set for
4 - DO-LOW. Now please proceed with Step 1 and then go on to Step 9.
Step 9. This experiment with three XBee modules created a peer-to-peer
(equal-to-equal) network because all three XBee modules could communicate with each other. In this case, the RCVR module communicated with the
XMTR and END modules, but the XMTR and END modules also could communicate with each other by using their respective 16-bit network addresses
and setting their high and low addresses to zero in commands. This experimental setup, though, doesn’t provide an easy way to initiate a transmission by the
XMTR or END modules.
If you have only a few modules, this type of peer-to-peer network might work
well, but if you have five or more transceivers, without careful planning, you
could end up with communication chaos. Imagine an unruly meeting in which
several groups have separate conversations going on. A later experiment will have
you set up a network of end-device modules and one coordinator, which simplifies control.
Step 10. The XBee modules let you transmit a broadcast message or command that all modules within range receive simultaneously. The remote modules also acknowledge a broadcast message. So you can determine which
modules received the broadcast and which did not. A broadcast message could
help you synchronize all modules, send a timing signal to all modules, turn off
all devices immediately, and so on.

124

How to Control Several XBee Modules with Broadcast Commands

The following information explains how to set up and send a broadcast packet, which follows the same general format used with other packets.
A complete broadcast packet that causes all modules to place their AD1-DIO1
pin in a logic-0 state looks like this:
7E	  start byte
0010	  number of bytes in transmission
17	  remote AT-command-request byte
52	  frame identifier value (all experiments use this value)
000000000000FFFF	  64-bit broadcast identifier
FFFE	  value needed to force 64-bit addressing above
02	  value that causes immediate actions
44	  hex code for D
31	  hex code for numeral 1
04	  hex code for DO – LOW
20	  checksum
The 0xFFFE value used as the 16-bit network address directs modules
to use the transmitted 64-bit address instead. For XBee modules, the address
0x000000000000FFFF indicates they all must respond to this message regardless of their factory-programmed serial number. The broadcast message will
turn on LED1 on the XMTR and END modules simultaneously.
Turn off power to the breadboard and XMTR and END modules. Turn
power on again. You should see LED3 lit at each module. Type the command
above into the Send Packet and click on Send Data. (Remember, this packet
has a byte count of 0x10.) You should see LED1 turn on at each module.
Now complete the following packet to broadcast a command to the XMTR
and END modules to turn off LED3:
7E 00 10 17 52 00 00 00 00 00 00 FF FF FF FE 02 ___ ___ ___ ___
Find a complete packet in the Answers section at the end of this experiment.
Step 11. Each module—END and XMTR—responded to the broadcast
message with its own acknowledgement, as shown in the information that
follows. (Your XBee-module serial number or numbers will not match mine,
which I underlined.)
7E 00 0F 97 52 00 13 A2 00 40 49 E1 E6 89 FA 44 33 00 17
7E 00 0F 97 52 00 13 A2 00 40 49 E0 EC 56 78 44 33 00 C7
Both responses include standard information: each module’s serial number,
network address, the D3 command, a status byte, and a checksum. If you had
additional modules, they also would send an acknowledgement message.
Although you can send a broadcast packet, use it with care. Unless you
need simultaneous actions, you might get better control by sending a message
to individual modules and then monitoring for an acknowledgement from each
before transmitting to another module.

EXPERIMENT ANSWERS
Step 5. When you apply power to a module, it starts in the configuration programmed with the X-CTU software. If you use a command to change the logic

Experiment Answers

125

level at an output pin, for example, it remains “volatile.” That means when you
turn off power and re-power a module, it reverts to the configurations set with
the X-CTU software. In this experiment you will learn how to save new configuration settings in remote modules.
Step 6.
l
Turn off LED3 at XMTR module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 33 05 4A
Use a D3 command for LED3 with the value 04 for a logic 1 at the
AD3-DIO3 pin at the XMTR module (0x5678).
l
Turn on LED1 at XMTR module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 56 78 02 44 31 04 4D
Use a D1 command for LED1 with the value 05 for a logic 0 at the
AD1-DIO1 pin at the XMTR module (0x5678).
l
Turn off LED3 at END module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 89 FA 02 44 33 05 95
Use a D3 command for LED3 with the value 04 for a logic 1 at the
AD3-DIO3 pin at the END module (0x89FA).
l
Turn on LED1 at END module:
7E 00 10 17 52 00 00 00 00 00 00 00 00 89 FA 02 44 31 04 98
Use a D1 command for LED1 with the value 05 for a logic 0 at the
AD1-DIO1 pin at the END module (0x89FA).
Step 7. The LEDs at the XMTR and END modules return to the original conditions set with the X-CTU software. The LED connected to the
AD3-DIO3 pin at each module turns on, and the other LED turns off. This situation reflects the configuration you set in each module in Steps 1 and 2. Even
though you changed the state of the AD1-DIO1 and AD3-DIO3 pins at each
module, those changes exist only as long as you maintain power to a module.
When a module goes through a power-up reset, it reverts to the original settings, so you know any attached equipment starts in a known state.
Step 10. Now complete the following packet to broadcast a command to
the XMTR and END modules to turn off LED3:
7E 00 10 17 52 00 00 00 00 00 00 FF FF FF FE 02 44 33 05 1D

Experiment | 16

How to Communicate
Between an MCU and
an XBee Module
REQUIREMENTS
2 XBee modules
1 XBee adapter board
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
1 Microcontroller with a serial port (Arduino Uno or ARM mbed)
1 5-V-to-3.3-V logic-conversion circuit or module (for Arduino Uno)
Terminal-emulation software such as HyperTerminal for Windows
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to transfer information from a microcontroller to a PC by using one XBee module as a transmitter and another as a
receiver. You can send as many bytes as you need, and they can include typed
information, data from measurements, error and status messages, and so on.
The type of information depends solely on your requirements. As such, the
XBee transmitter and receiver modules acts as “transparent” devices as though
they have a direct, wired connection. The wireless communications neither
include nor require any commands for XBee modules.
This experiment uses your XMTR module with a microcontroller (MCU)
to create information the XMTR will transmit to the RCVR module. The
RCVR module connects to your PC, which will display results in a terminalemulator window. The diagram in Figure 16.1 shows the equipment setup.
127
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

128

How to Communicate Between an MCU and an XBee Module
Wireless Link

PC
Your MCU Module
UART

Serial
Bits

XBee

XBee
USB Connection
USB–to–XBee Adapter

FIGURE 16.1 A block diagram of microcontroller-to-computer communications with
XBee modules.

This experiment works directly with either an ARM mbed module or an
Arduino Uno module, although I encourage experiments with other MCUs and
boards on your own.
Several vendors offer these MCU modules, peripheral-device boards, and
add-on devices at low cost and they provide easy ways to run experiments
without getting deeply into hardware or software details. See Appendix D for
information about where to obtain these products.
Step 1. In this step you will configure the XMTR module to operate with
its default factory settings. Ensure you have turned off power to the breadboard. Then remove the XMTR module from the XBee socket in your breadboard and place it in the USB-to-XBee adapter and reconnect this adapter to
the USB cable and your PC.
If not already running, start the X-CTU software. Within the X-CTU window, click on Modem Configuration and then Restore. After a few seconds you
should see the message “Restore Defaults..complete” appear. Click on Read
to obtain the restored default values from the XMTR module. Check to ensure
the DL – Destination Address Low and MY – 16-Bit Source Address each
have a value of 0. This condition indicates the X-CTU software has reset all
XMTR module settings to their default state. If DL and MY are not equal to 0,
retry the procedure in this step. After you confirm the default condition, place
the XMTR module back in its adapter on the solderless breadboard.
Step 2. Place the RCVR module in the USB-to-XBee adapter and reconnect
this adapter to the USB cable. Perform the configuration described in the second
paragraph of Step 1. After you have restored the default settings for the RCVR
XBee module, leave it in the USB-to-XBee adapter connected to your PC.
Step 3. The schematic diagram in Figure 16.2 shows the connections
needed for the XMTR module in your breadboard. You need only power,
ground, and a connection to your MCU. You may connect the wire to pin 3 on
the XMTR module now, but do not connect it to your MCU. If you have other
components or wires connected to the XMTR module, please disconnect them
now. You also need a ground connection between your MCU and the XBee
breadboard.

Using a UART
+3.3 V

/CONFIG–DIN
To MCU UART Output

To MCU–module ground

129

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 16.2 Connections at the XBee XMTR module for Experiment 16.

In the next steps, you will connect a serial-output pin on an MCU to the
XMTR module. The Arduino Uno provides 5-volt logic signals, and the ARM
mbed module provides 3.3-volt logic signals. The XBee modules work with
3.3-volt signals, so you cannot connect an XBee module directly to an Arduino
Uno.
See Appendix A for instructions that describe how to build a simple, inexpensive logic-level converter, a schematic diagram and bill of materials. You
need this circuit only if you plan to use a 5-volt MCU such as the Arduino
Uno. The ARM mbed does not require logic-level conversions, nor do other
3.3-volt MCUs.
Important: This experiment assumes you already know how to program
and use an Arduino Uno or ARM mbed MCU module, or that you’re learning
how to use one of them. The following steps include software examples for
each MCU, but they do not provide step-by-step information about how to use
the corresponding software tools that work with the ARM mbed or Arduino
Uno modules. If you need tutorial information, visit the Arduino and mbed
Web sites. Each module has its own group of supporters so you can find useful
“how to” information, code, and examples on the Internet.
Experiments that use an MCU board will provide complete listings and
code, so you will not need to write programs. Download all the code from:
http://www.elsevierdirect.com/companion.jsp?ISBN=9780123914040.

USING A UART
Experiment 10 provided a short introduction to serial communications; the
information that follows offers more details. If you have experience with
serial devices, feel free to skip this section. Almost every MCU provides at
least one Universal Asynchronous Transmitter/Receiver (UART) interface that
will send and receive streams of logic bits via a separate transmit output and
receive input. A UART takes a byte you supply, inserts a logic-0 start bit at the

130

How to Communicate Between an MCU and an XBee Module

beginning of its “packet” and ends with one or two logic-1 stop bits, as shown
in Figure 16.3. When you configure a UART via software, you specify its bit
rate, the number of data bits in a transmission (almost always 8), the number of
stop bits (usually only one), and parity (usually none). The parity bit can help
detect errors in communications, but for the most part, we don’t use it. Most
MCUs offer standard data rates such as 1200, 2400, 9600, and 115,200 bits/
second.
UART receiver detects start–bit transition

Logic Level

UART samples incoming bits

104 microseconds

1
0
0

0

1

0

1

0

LSB

0

1

0

1

MSB

Start
Bit

Stop
Bit
Data Bits
Time

FIGURE 16.3 The stream of bits for a 9600 bits/sec. transmission of 0x4A.

The word “asynchronous” indicates UARTs in separate circuits do not
share a synchronizing, or clocking, signal to time the data transfers. Instead, a
UART receiver monitors its input and recognizes a logic-1-to-logic-0 transition
as the beginning of a start bit (always logic 0). Then it acquires the following
eight data bits and a parity bit (if any). The transmission ends when the UART
receives a valid stop bit (always a logic 1). Bits always have equal duration
and the UART samples them at the middle of their time slot as shown by the
small arrows in Figure 16.3. Each bit in a 9600 bits/second transmission, for
example, has a period of 104 microseconds. To operate properly, the receiving
and transmitting UARTs must have the same data rate and the same configuration for the number of data bits, number of stop bits, and parity.
You might wonder why a UART doesn’t see every logic-1-to-logic-0 transition as the beginning of a start bit. The “quiet” time between transmissions
lets it determine when to “look” for the transition at the edge of a start bit.
Note that a standard UART follows the start bit with the least-significant bit
(LSB) in the byte transmitted. So, the transmission of the ASCII value for the
character “J” (0x4A or 010010102) looks like the bits shown in Figure 16.3.
Software for the Arduino Uno and ARM mbed modules make it easy to
set up a UART and serial communications. In its factory-default condition, an
XBee communicates through its internal UART at 9600 bits/second with eight
data bits, no parity, and one stop bit. The experiments in this book use these
settings, but UARTs on MCUs and XBee modules can communicate at higher
rates.
Important: When you run into a communication problem that involves
UARTs, always check the serial-port configurations first. Many problems

Using an Arduino Uno

131

involve mismatched settings you assume are properly set, but aren’t. In particular, in terminal-emulator software ensure you have no flow control.

TERMINAL-EMULATION SOFTWARE
I used the Windows HyperTerminal program in the following steps. You can
find other terminal-emulation programs for PCs on the Internet. Before you
use a terminal-emulator program, quit X-CTU to avoid contention for use of
the same PC COM port that connects to an XBee module at your PC.
Set your terminal emulator for a data rate of 9600 bits/second, or 9600
baud. Set the number of stop bits to 1, parity to none, and number of data
bits to 8. If you can select a flow-control mode, choose none. Ensure you
have the terminal emulator set for the COM port that connects to the XBee
RCVR module. If you cannot determine the correct COM port assignments,
go to Windows Settings→Control Panel→System→Hardware→Device
Manager→Ports (COM & LPT) to identify available COM devices. Then try
the available COM ports in your terminal-emulator software.
A terminal-emulator program that receives characters from an external
device will continue to print them on one line in its window unless instructed
otherwise. Your programs must send the terminal emulator a “line feed” command, also called “new line,” to move the cursor down a line in the terminal
window, followed by a “carriage return” command to move the cursor to the
left side of the window. You might see carriage-return and line-feed abbreviated as CR and LF or together as CRLF.
Use the hex value 0x0A to cause a line feed and 0x0D for a carriage return.
You can send these bytes directly or in a C-language program use the “\n” and
“\r” symbols in print commands. Depending on your terminal-emulator settings, you might need to try 0x0A and 0x0D together or separately.
Important: If you plan to go to Experiment 17 now, you can leave your
hardware set up when you finish this experiment.

USING AN ARDUINO UNO
Uno Step 1. The Arduino Uno module uses code written in the C language to
communicate with an external device via a UART. A group of Serial commands such as Serial.print and Serial.begin simplify serial-communication code. The Arduino Uno module always assumes an 8-bit transmission
with no parity and one stop-bit, abbreviated as 8N1. A software command sets
the bit rate independently.
The Arduino Uno module defines pin 1, labeled TX--  1 on the board, as
its UART transmitter output, so this experiment uses that pin. Pin numbering
on a Uno module starts with pin 0. Do not count pins, use the pin labels and
numbers printed on the Uno board.
The C program EX16_Uno_Hello will send out—via the UART—the
ASCII characters H, e, l, l, o, along with three periods and two spaces. Do not
enter this program yet.

132

How to Communicate Between an MCU and an XBee Module

Uno Program EX16_Uno_Hello
void

setup()

{
Serial.begin(9600);

//Set up serial port

}
void loop()
{
Serial.print("Hello... ");
delay(100);
}

// wait for 0.1 second

The Serial.begin command set the data rate at 9600 bits/sec. The rest
of the program simply goes through an infinite loop that continues to display “Hello...” again and again in the terminal-emulator window. The delay
command provides a 100-millisecond (0.1-second) delay so you can see the
message arrive on the screen.
Uno Step 2. The diagram in Figure 16.4 shows the Arduino Uno connections
to your XBee XMTR module. Note the use of the 5-to-3 logic-level-conversion
circuit (LLC).
The logic-level conversion circuit described in Appendix A requires additional connections not shown in the Figure 16.4 diagram. Please make the
following additional connections if they do not yet exist at your logic-levelconversion circuit. On the 5-to-3-volt logic-level conversion circuit,
l
Connect a 1000-ohm resistor (brown-black-red) between pins 1 and 2.
l
Connect pins 11, 12, 13, and 22 to ground.
l
Connect pin 1 to 5 volts.
l
Connect pins 23 and 24 to 3.3 volts.
+3.3 V
Top View
LLC 5–to–3
To Arduino Uno
Pin TX– –> 1

3

DIN

21

To Arduino Uno
POWER GND

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

GND

FIGURE 16.4 Schematic diagram for data transmission from an Arduino Uno module to
an XBee transmitter.

Using an Arduino Uno

133

Important: Make these extra connections only at the 5-to-3-volt logic-levelconversion circuit. Do not make any of these connections to the XBee module
or you will damage it.
People often run into problems because their circuits lack a common ground.
You must ensure you have a ground connection that links all power-supply and
circuit grounds used in an experiment. In this case, you need a common ground
between the Arduino Uno module, the logic-level-conversion circuit, the XBee
breadboard, and your power supplies. You do not need a common ground
between your breadboarded circuits and your PC because they have no common
electrical connection. All communications occur over the wireless link.
Turn on power to your Arduino Uno module and temporarily remove the
end of the wire at the TX--1 pin on the arduino module. Breaking this connection prevents problems due to the Arduino Uno module sharing its serial
port with the USB connection used to download programs from your PC.
Load into the arduino uno the EX16_Uno_Hello program shown earlier.
Turn on power to your logic-level-conversion circuit and to the XBee module
in the breadboard. Reconnect the wire from your logic-level-conversion circuit
to the Arduino Uno module TX receptacle. Whenever you load programs into
an Arduino Uno module, you must disconnect the TX and RX connections,
and reconnect them after the program has loaded.
In your terminal emulator you should see the repeating pattern: Hello...
Hello... Hello... This display indicates the Uno module created the serial bytes
that represent each character in the message. The XMTR module connected
to the Uno module transmitted this information via its wireless output and the
RCVR module received it. The RCVR module sent the information to the PC’s
terminal emulator via its USB connection.
Keep in mind the terminal emulator must communicate with the virtual
serial port that connects to the XBee RCVR module and not to the virtual
serial port that connects from your PC to the Arduino Uno board.
If you did not see the repeated “Hello...” message, you likely had incorrect UART settings for the Arduino Uno MCU or in your terminal emulator.
Recheck your settings so they match 9600 bits/second, or 9600 baud. You also
need eight data bits, no parity, and one stop bit. Set the terminal-emulator software for no flow control.
Uno Step 3. In this step you will change the program slightly so the MCU
creates its own bytes and the terminal emulator will display many different
characters. As you program the Uno module, you can leave power applied to
your circuits. Remove the TX connection at the Arduino Uno receptacle strip.
Load the new program, EX16_Uno_Alpha, into your Uno module and run it.
Reconnect the wire to the TX receptacle.
At times when using an Arduino Uno module I had difficulty getting the
Arduino software to recognize the board and I also saw error messages such
as “Serial port ‘COMxx’ already in use.” If you see error messages, close all
other programs such as X-CTU or the terminal emulator that might try to

134

How to Communicate Between an MCU and an XBee Module

connect with the virtual serial port used to connect the Arduino compiler to the
Uno board. It might take several attempts, as I described in the Introduction, to
get an Arduino Uno module to respond properly.

Uno Program EX16_Uno_Alpha
char

alphachar;

// initialize serial port
void setup()
{
Serial.begin(9600);
}
void loop()
{
alphachar = 0x20;
while (alphachar < 0x7F)
{
Serial.print(alphachar,BYTE);
delay(100);
alphachar = alphachar + 1;
}
}

What do you see in the terminal-emulator window?
This program sets up a loop to increment a value that starts at 0x20.
The while loop tests alphachar to determine if it is less than 0x7F. When
alphachar exceeds 0x7E, the program exits the while loop and the main loop
starts again and initializes alphachar back to 0x20.
The values correspond to the characters “space” through “~” in the ASCII
character set, and after “printing” one set, the code goes through the same
sequence again and again in an endless, or infinite, loop that runs until you
turn off power.
Uno Step 4. Can you write a short C program to print only the numbers from 9 to 0 and then start over at 9 and go down to 0 again and again?
Each sequence, 9876543210, should appear on a separate line in a terminalemulator window. You can use “\r\n” in a Serial.print command to force
a new line in your terminal emulator. The downloaded code file for this
experiment includes a program that prints numbers in this format.
If you plan to go right to Experiment 17, you may leave your circuits set
up. You will use them as set up for this experiment.

USING AN ARM MBED MODULE
mbed Step 1. The ARM mbed (yes, all lowercase letters) module uses code
written in the C language to communicate with an external device via its
UART. You can give the serial port a name, select the pins used to transmit and
receive information, establish the UART operating conditions, and then write
code with C commands such as print and printf. The ARM mbed module’s

Using an ARM mbed Module

135

serial ports default to the format that uses eight data bits, no parity, and one
stop bit. Refer to the ARM mbed online “Handbook” for information about all
serial-port commands: www.mbed.org.
The C program EX16_mbed_Hello will send via the ARM mbed UART
the ASCII characters H, e, l, l, o, along with three periods and two spaces. The
ARM mbed module offers three serial ports and the program below uses pin 9
to transmit data. You won’t use the receiver input, pin 10, in this experiment.
The pin numbers refer to the module and not to the on-board MCU. Don’t
enter this program yet.

mbed Program EX16_mbed_Hello
#include "mbed.h"
Serial XBeePort(p9, p10);

// set transmit & receive pins

int main()
{
XBeePort.baud(9600);

//Set bit rate

while(1)
{
XBeePort.printf("Hello... ");
wait_ms(100);
}
}

The line # include “mbed.h” causes the ARM mbed compiler to use a file
that defines many operations so you do not have to set or clear bits in control
registers to set up a UART or serial port.
The Serial XBeePort(p9, p10); command names the serial port as
XBeePort to make it easy to identify and refer to in code. You could name the
serial port almost anything, such as framostan, SerialX, MySerialPort, and so on.
After naming the serial port you use its name in the main routine to set its bit rate.
The XBeePort.printf(“Hello...”); command sends the word Hello, followed by three periods and two spaces to your terminal-emulator window. The
wait_ms(100); command causes a 100 millisecond (0.1 second) delay.
mbed Step 2. The diagram in Figure 16.5 shows the ARM mbed module
connections to your XBee XMTR module. Because an ARM mbed module
provides 3.3-volt logic levels, you do not need to convert voltage levels and
can make direct connections between an ARM mbed and an XBee module.
The ARM mbed module obtains power from your PC via its USB connection.
Connect your ARM mbed module to your PC and load the program EX16_
mbed_Hello into it. Note: An ARM mbed module acts like an external USB
drive, so you simply “save” your code to the ARM mbed module and then
press the ARM mbed pushbutton to start your program. On my PC, the ARM
mbed module appeared as the F: drive. Refer to the mbed.org web site for tutorial and reference information.

136

How to Communicate Between an MCU and an XBee Module
+3.3 V
Top View

To mbed Module
Pin 9 (Tx)

To mbed Module
Pin 1 (GND)

DIN

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 16.5 The ARM mbed schematic diagram for Experiment 16.

After you turn on power to your XBee module in the breadboard, press the
Reset button on the ARM mbed to start the program you just downloaded. In
your terminal emulator you should see the repeating pattern: Hello... Hello...
Hello... and so on. This display indicates the ARM mbed module created the
serial bytes that represent each character in the message. The XMTR module
connected to the ARM mbed module transmitted this information via its wireless output and the RCVR module received it. The RCVR module sent the
information to the PC’s terminal emulator.
Important: People often run into problems because their circuits lack a
common ground. You must ensure you have a ground connection between the
ARM mbed module and the XBee breadboard.

mbed Troubleshooting
If you did not see the repeated “Hello...” message, you likely had incorrect
UART settings in the ARM mbed MCU or in your terminal emulator. Recheck
your settings so they match 9600 bits/second, or 9600 baud. You also need
eight data bits, no parity, one stop bit, and no flow control in your terminalemulator program.
Because the ARM mbed uses a USB port to communicate with its Webbased development software, ensure you have selected the “USB Serial Port”
for the USB-to-XBee adapter board when you set up your terminal emulator. Do not use the COM port for the ARM mbed module. That COM port
serves as the programming and debugging port for the ARM mbed compiler.
If you cannot determine the correct COM port assignments, go to Windows
Settings→ Control Panel→ System→ Hardware→ Device Manager→
Ports (COM & LPT) to identify available COM devices.
mbed Step 3. In this step you will change the program slightly so the
MCU creates its own bytes within the program. The terminal emulator will
display many different characters.
As you program the ARM mbed module, you can leave power applied to
your circuits. You will not change any settings in your XMTR or RCVR just

Using an ARM mbed Module

137

because you have power on. Load program EX16_mbed_Alpha into your
ARM mbed module and run it.

mbed Program EX16_mbed_Alpha
#include "mbed.h"
Serial XBeePort(p9, p10);

// select UART pins

int alphachar;
int main()
{
XBeePort.baud(9600);
while(1)
{
XBeePort.printf("\n\r");
alphachar = 0x20;
while(alphachar <0x7F)
{
XBeePort.putc(alphachar);
alphachar = alphachar + 1;
wait_ms(100);
}
}
}

What do you see in the terminal-emulator window?
This program sets up a loop that will increment the variable alphachar that
starts with a value of 0x20 and ends with with a value of 0x7E. The while loop
tests alphachar to determine if it is less than 0x7F. When alphachar exceeds
0x7E, the program exits the while(alphachar... loop and the while(1) loop
starts again and initializes alphachar back to 0x20.
The values correspond to the characters “space” through “~” and after
printing one set of characters, the ARM mbed code goes through the same
sequence again and again in an endless, or infinite, loop that runs until you
turn off power. Note a difference between the “Hello” program and the program directly above. The EX16_mbed_Alpha program uses the XBeePort.
putc command to send a single hex byte—the alphachar value—to the UART.
This program used an XBeePort.printf command to send the terminal emulator commands for a carriage return and a line feed.
mbed Step 4. Can you write a short C program to print only the numbers from 9 to 0 and then start over at 9 and go to 0 again and again? Each
sequence, 9876543210, and so on should appear on a separate line in the
terminal-emulator window. The downloaded code file for this experiment
includes a program that prints numbers in this format.
If you plan to go right to Experiment 17, leave your circuits set up. You
will use them as set up for this experiment.

Experiment | 17

Two-Way
Communications with
XBee Modules
REQUIREMENTS
2 XBee modules
1 XBee adapter board
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable (type depends on MCU board chosen)
1 Microcontroller board with a serial port (see Experiment 16)
1 5-V-to-3.3-V logic-conversion circuit or module (see text)
1 3.3-V-to-5-V logic-conversion circuit or module (see text)
1 1000-ohm, 1/4-watt, 10% resistor (brown-black-red) (see text)
Terminal-emulation software such as HyperTerminal for Windows
Digi X-CTU software running on a Windows PC, with two open USB ports

INTRODUCTION
In Experiment 16 you learned how a simple computer program could use a
remote XBee module to transmit information to a receiving XBee module.
In this experiment you will use two-way communications to send a wireless
message from your PC to a remote microcontroller (MCU), after which the
MCU will send back a reply. XBee modules operate most of the time as receivers, but they can quickly change to the transmit mode and then back to the
receive mode under control of an MCU.
The diagram in Figure 17.1 shows the module configuration for this experiment. Note the two-way communications between the XMTR and RCVR
XBee modules and between the XMTR XBee module and the MCU. This diagram represents a typical configuration for XBee modules, as well as for other
types of transceivers.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

139

140

Two-Way Communications with XBee Modules
Two–Way Wireless Link

PC
Your MCU Module

Serial

UART
Bits

XBee

XBee
USB Connection
USB–to–XBee Adapter

FIGURE 17.1 A block diagram of computer-to-computer communications.

This experiment lets you work with either of two MCU modules: An
Arduino Uno MCU module or an ARM mbed MCU module. These modules
and boards are available at low cost and provide easy ways to run experiments
without getting deeply into hardware or software details.
If you have just completed Experiment 16, please jump ahead to Step 3
below. If you have not yet run Experiment 16, I recommend you do so before
you run this experiment.
Step 1. In this step you will configure the XMTR module to operate with
its default factory settings. Ensure you have turned off power to the breadboard.
Then remove the XMTR module from the XBee socket in your breadboard and
place it in the USB-to-XBee adapter and reconnect this adapter to the USB
cable and your PC.
If not already running, start the X-CTU software. Within the X-CTU window, click on Modem Configuration and then Restore. After a few seconds you
should see the message “Restore Defaults..complete” appear. Click on Read
to obtain the restored default values from the XMTR module. Check to ensure
the DL – Destination Address Low and MY – 16-Bit Source Address each
have a value of 0. This condition indicates the X-CTU software has reset all
XMTR module settings to their default state. If DL and MY are not equal to 0,
retry the procedure in this step. After you confirm the default condition, place
the XMTR module back in its adapter on the solderless breadboard.
Step 2. Place the RCVR module in the USB-to-XBee adapter and reconnect
this adapter to the USB cable. Perform the configuration described in the second
paragraph of Step 1. After you have restored the default settings for the RCVR
XBee module, leave it in the USB-to-XBee adapter connected to your PC.
Step 3. The schematic diagram in Figure 17.2 shows the connections needed
between an XBee module and an MCU for serial communications. Later you
will make specific connections for the MCU you chose to work with. For now, if
you have other connections to the XMTR module, please disconnect them.

SOFTWARE
This experiment uses two programs with the Arduino Uno or ARM mbed MCU
modules. The first program sets up the MCU and the XBee module (XMTR)
to accept five bytes sent from the XBee module (RCVR) attached to your PC.

Software
+3.3 V

To MCU UART Input

141

Top View

DOUT
CONFIG–DIN

To MCU UART Output

1

20

2

19

3

18
17

4
5

Ground to other Devices

XBee XB24

16

6

15

7

14

8

13

9

12

10

11

FIGURE 17.2 Connections at an XBee XMTR module for 2-way MCU serial communications.

Set up variables;
charrcvd array and
counter

Start

Get character from XBee
at MCU UART input

Received all
5 characters?

No

Yes
Transmit a character from MCU
to XBee module

Sent all 5
characters?

No

Yes
Send new-line value

FIGURE 17.3 Flow chart for the first program used to receive and retransmit five bytes
of information.

As soon as the MCU module has received all five bytes, it transmits them back
to your PC. You will use a terminal-emulator program or the Terminal window
in the X-CTU software to enter characters, each of which exists as a byte of
information. The flow chart in Figure 17.3 shows how the program operates.

142

Two-Way Communications with XBee Modules
Set up variables;
charrcvd array,
counter, and alphachar

Start

Set alphachar = 0
Get XBee character at MCU
UART input

Character =
T or t?

Yes

Set alphachar = 1

No

No

Received all 5
characters?

Yes
Transmit a character from MCU
to XBee module

Set all 5
characters?

No

Yes

alphachar = 1

Yes

Send:
“T Received.”

No
Send new-line value

FIGURE 17.4 Flow chart for the extended program that will detect a “T” or “t” character
received by the XMTR XBee module.

In the first program, the MCU simply receives five characters and transmits them back to the terminal emulator. The second program, shown as a
flow chart in Figure 17.4, makes a decision based on the bytes received by the
XMTR XBee module. The MCU will still accept the bytes for five typed characters and retransmit them. But if you type a “T” or a “t,” in the group of five
characters, the reply will include the message “T Received.”

Using an Arduino Uno Module

143

This type program demonstrates how an MCU can take an action based
on the information it receives. If an MCU receives a “T,” it might make a
temperature measurement, convert it to degrees Celsius, and transmit that
value back to the requesting XBee module. Likewise, receipt of a “P” might
trigger a response with atmospheric pressure from a remote XBee-and-MCU
location.
Experiments that use an MCU board will provide complete listings, so
you will not need to write programs. Download all the code from: http://www
.elsevierdirect.com/companion.jsp?ISBN=9780123914040.

TERMINAL-EMULATION SOFTWARE
I used the Windows HyperTerminal program in the following steps. You can
find other terminal-emulation programs for PCs on the Internet. Before you
use a terminal-emulator program, quit X-CTU to avoid contention for use of
the same PC COM port that connects to an XBee module at your PC.
Set your terminal emulator for a data rate of 9600 bits/second, or 9600
baud. Set the number of stop bits to 1, parity to none, and number of data bits
to 8. If you can select a flow-control mode, choose none. Ensure you have the
terminal emulator set for the COM port that connects to the XBee RCVR module. If you cannot determine the correct COM port assignments, go to Windows
Settings→ Control Panel→ System→ Hardware→ Device Manager→ Ports
(COM & LPT) to identify available COM devices. Then try the available COM
ports in your terminal-emulator software.
Depending on your terminal-emulator setting, you might not see typed
characters in its window. To set HyperTerminal to “echo” what you type, open
it and follow these menu choices: File→Properties→Settings→ASCII Setup,
and click on “Echo typed characters locally.” Other emulators might have a
similar capability.

USING AN ARDUINO UNO MODULE
Arduino Uno Step 1. The Arduino Uno module uses code written in the C
language to communicate with an external device via a UART, and commands
such as Serial.print and Serial.begin simplify serial-communication software. The Arduino Uno module always assumes an 8-bit transmission with no
parity and one stop-bit, abbreviated as 8N1.
The C-language program EX17_Uno_Five will monitor the Arduino Uno
UART input for a new byte received from the XMTR XBee module. When the
MCU UART receives a byte, it will save it in an array that can hold five values.
After the MCU has received five bytes, it will send them back to the XMTR
module that will transmit them wirelessly to the RCVR module. The RCVR
module will send the bytes to your PC, which will display them in its terminalemulator window. Do not enter program EX17_Uno_Five at this time.

144

Two-Way Communications with XBee Modules

Arduino Uno Program EX17_Uno_Five
/*
Experiment 17 Arduino Uno
EX17_Uno_Five.pde
Jon Titus, 07-06-2011
*/
char charrcvd[5];
int counter;

// Set up array for rcvd bytes
// Set counter variable

void setup()

// Set serial port for 9600
// bits/sec

{
Serial.begin(9600);
}
void loop()
// main loop starts here
{
counter = 0;
// set counter to zero to start
while(counter < 5)
// while count is less than 5
{
// go through this loop
if (Serial.available() > 0)
// check UART for any new data
{
charrcvd[counter] = Serial.read(); // detected new UART
// data, so get
// the UART byte
counter = counter + 1;
// increment counter by one
}
}
// received five characters,
// so exit while loop
counter = 0;
// set counter to zero to start
while(counter < 5)
// while counter is less than 5
{
// go through this loop
Serial.print(charrcvd[counter],BYTE);
// print character
// as a byte code
delay(100);
// wait 100 msec between
// characters
counter = counter + 1;
// increment counter by one
}
Serial.print("\n\r");
// "print" new line
}
// printed five characters,
// so exit while loop
//end of code, but execution returns to loop()

The Serial.begin command sets the Arduino Uno UART data rate at
9600 bits/second. The first while(counter < 5) loop will save five bytes
received from the UART and this loop includes the statement:
if (Serial.available() > 0)

The program needs this statement to determine whether or not the UART
has a new byte available. The Serial.available() function returns the value
0 if the UART receiver is empty and it returns a non-zero value when the

Using an Arduino Uno Module
LLC 3–to–5
To Arduino Uno Pin 0 (Rx)

3

2

21

LLC 5–to–3
To Arduino Uno Pin 1 (Tx)

3

21
1 kohm

To Arduino POWER GROUND

+3.3V

145

Top View
1
20
2
19
3
18
4
17
5 XBee XB24 16
6
15
7
14
8
13
9
12
10
11

GND
Logic–Level–Converter (LLC) Connections:
Ground at pins 11, 12, 13, 22.
+5 volts at pin 1; +3.3 volts at pins 23, 24.
On LLC 5–to–3: 1 kohm resistor between pins 1 and 2.
On LLC 3–to–5: ground pin 2.

FIGURE 17.5 Arduino Uno schematic diagram with logic-level-converters.

UART has a new byte available. Without this statement, the software would
continuously read the UART receiver, regardless of whether or not it contained
new data, and cause the program to display whatever byte the UART receiver
holds. An Arduino Uno program MUST check the UART for available data
before it tries to read data from it. Other MCUs behave in a similar fashion;
that is, they provide a “flag” that software can test to determine if a UART or
other device is ready or not ready, full or empty, on or off, and so on.
The program EX17_Uno_Five will save five bytes in the charrcvd array
and then transmit them back to the XMTR module so they appear via wireless link in your terminal-emulator window. The delay command provides a
100-millisecond (0.1-second) delay so you can see the five characters arrive on
the screen one by one.
Arduino Uno Step 2. The schematic diagram in Figure 17.5 shows the
connections from an Arduino Uno module to logic-level-converter circuits,
and to an XBee module. Note the use of separate logic-conversion circuit for
5-V-to-3-V logic and for 3-V-to-5-V logic. Pay attention to the notes below
and in Figure 17.5 that explain additional connections not shown in the diagram for the sake of clarity:
l
On LLC 5-to-3, connect a 1-kohm resistor (brown-black-red) between pins
1 and 2.
l
On LLC 3-to-5, connect pin 2 to ground.
l
On both logic-level-converter devices, connect pins 11, 12, 13, and 22 to ground.
l
On both logic-level-converter devices, connect pin 1 to 5 volts.
l
On both logic-level-converter devices, connect pins 23 and 24 to 3.3 volts.
Note that pin numbers on an Arduino Uno board start with pin 0. DO NOT count
pins, use the pin designation and numbers printed on the Arduino Uno board.
Important: People often run into problems because their circuits lack a
common ground. You must ensure you have a ground connection that links

146

Two-Way Communications with XBee Modules

all the power-supply and circuit grounds used in an experiment. In this case,
you need a common ground between the Arduino Uno module, the logictranslation circuits, and the XBee breadboard.
Arduino Uno Step 3. Turn on power to your breadboard and to the logiclevel-converter circuits.
Label the wire, or use a colored wire, from the logic-level-converter
circuit to the Arduino Uno pin 0 (RX) and remove it from the Arduino
Uno connector. Leave the other end connected to the logic-level-converter
circuits. Likewise, label the wire from the logic-level-converter circuit to the
Arduino Uno pin 1 (TX) and remove it from the Arduino Uno connector. Leave
the other end connected to the logic-level-converter circuits. You will reconnect these wires after you download a program to the Arduino Uno MCU. (The
USB connection also uses the MCU UART, so temporarily removing the two
wires eliminates the possibility of conflicts caused by simultaneous use of the
UART pins by the USB connection and the logic-level-converter circuits.)
Load the program EX17_Uno_Five into the Arduino compiler, compile it
and load it into the MCU.
Replace the wires in the Arduino Uno connector at positions Arduino Uno pin
0 (RX) and Arduino Uno pin 1 (TX). Press the Arduino Uno Reset pushbutton.
Arduino Uno Step 4. In your terminal emulator you should see a blank
text window. (If you just completed Experiment 16, you might see information
remaining from old transmissions.)
Type four characters, such as ASDF, into your terminal emulator.
Depending on your emulator setting, you might not see these characters in its
window. Now type a fifth character. You should see the characters appear in the
emulator’s window. (Some terminal emulator programs do not “echo” characters as you type them. So you might not see characters as you type them. Only
the characters sent from the MCU would appear at your PC. HyperTerminal
does not “echo” what you type, but the X-CTU Terminal window does.)
The Arduino Uno module received the five characters and saved them in an
array. Upon receipt of the fifth character, the MCU transmitted the five characters back to the terminal emulator via the XMTR to the RCVR module.
Arduino Uno Troubleshooting. If you did not see the characters, you
likely had incorrect UART settings in the Arduino Uno MCU or in your terminal emulator. Recheck your settings so they match 9600 bits/second or 9600
baud. You also need eight data bits, no parity, and one stop bit, and the Arduino
Uno will default to these settings. Also ensure you have a common ground
connection among all your circuits.
Arduino Uno Step 5. In the steps above, the Arduino Uno module simply received five characters and transmitted them back to the terminal emulator. But the MCU also could interpret received information and take actions
based on commands you send it. The next program, EX17_Uno_FiveT, modifies the earlier Arduino Uno code so the MCU will recognize receipt of a “T”
or a “t” (without the quotes). The MCU will respond with the five characters,
and will transmit a short message to acknowledge it received “T” or “t” among
the characters.

Using an Arduino Uno Module

147

Arduino Uno Program EX17_Uno_FiveT
/*
Experiment 17 Arduino Uno
EX17_Uno_FiveT.pde
Jon Titus, 07-07-2011
*/
char charrcvd[5];
int counter;
char alphachar;

// Set up array for rcvd bytes
// Set counter variable
// Use a byte for a flag value

void setup()

// Set serial port for 9600
// bits/sec

{
Serial.begin(9600);
}
void loop()
// main loop starts here
{
alphachar = 0;
// clear the alphachar flag
counter = 0;
// set counter to zero to start
while(counter < 5)
// while count is less than 5
{
// go through this loop
if (Serial.available() > 0)
// check UART for any new data
{
charrcvd[counter] = Serial.read(); // detected new UART
// data, so get
// URAT byte
if ((charrcvd[counter] == 0x54) || (charrcvd[counter] ==
// 0x74))
//test for T or t
{
alphachar = 1;
// found T or t, so set
// alphachar flag
}
counter = counter + 1;
// increment counter by one
}
}
// received five characters,
// so exit while loop
counter = 0;
// set counter to zero to start
while(counter < 5)
// while counter is less than 5
{
// go through this loop
Serial.print(charrcvd[counter],BYTE);
// print character
// as a byte code
delay(100);
// wait 100 msec between
// characters
counter = counter + 1;
// increment counter by one
}
Serial.print("\n\r");
// "print" new line
if (alphachar == 1)
// if alphachar flag set,
// print message
{
Serial.print("T Received.\n\r");
}
}
// printed five characters,
// so exit while loop



//end of code, but execution returns to loop()

148

Two-Way Communications with XBee Modules

The added steps first set the variable alphachar to 0 and check received
characters to determine if they match the hex value for “T” or “t.” If a character code matches either 0x54 or 0x74, alphachar gets set to 1. Thus alphachar
serves as a “flag” that lets the MCU know whether or not the received characters include “T” or “t.” Note the double upright bars, ||, are not the characters
for the numeral 1 or lowercase Ls. Find the “bar” character on most keyboards
with the backslash character, \. The two bars indicate a logical OR condition
within the if statement. So, if either the (charrcvd[counter] == 0x54) OR
the (charrcvd[counter] == 0x74) condition is true, the program assigns
alphachar the value 1.
After the program transmits the five characters back to the XMTR module,
and thus to your terminal emulator, it uses an if statement; if (alphachar ==
1) to test alphachar. If alphachar equals 1, which means the five characters
contained a “T” or a “t,” the Arduino Uno transmits the message “T Received.”
Note in the C language, the double equal-sign notation = = indicates a test
for equality between two values. If you want to assign a value to a variable,
use = and not = =.
Temporarily remove the wires inserted into Arduino Uno pin 0 (RX) and
into Arduino Uno pin 1 (TX). You will reconnect these wires after you download a program to the Arduino Uno MCU.
Load the program EX17_Uno_FiveT into the Arduino compiler, compile it
and load it into the MCU.
Replace the wires in the Arduino Uno connector at positions Arduino
Uno pin 0 (RX) and Arduino Uno pin 1 (TX). Press the Arduino Uno Reset
pushbutton.
When you run the EX17_Uno_FiveT program, you should see the same
results obtained with the first program except that typing a “T” or a “t” will
cause the reply to include the “T Received.” message.
Please jump ahead to “Control of Remote XBee Modules with MCU AT
Commands” at the end of the ARM mbed section of this experiment.

USING AN ARM MBED MODULE
ARM mbed Step 1. The ARM mbed module uses code written in the C language to communicate with an external device via its UART. You can give
the serial port a name, select the pins used to transmit and receive information, establish the UART operating conditions, and then write code with C
commands such as print and printf. The ARM mbed module’s serial ports
default to the format that uses eight data bits, no parity, and one stop bit. Refer
to the ARM mbed online “Handbook” for information about all serial-port
commands: www.mbed.org.
The C-language software for program EX17_mbed_Five will monitor the
MCU’s UART to “watch” for information received from the XMTR module.
When the MCU UART signals the receipt of a byte, it will save it in an array.
After the MCU receives five bytes, it will send them to the XMTR module that

Using an ARM mbed Module

149

will transmit them wirelessly to the RCVR module. The RCVR module will
send the bytes to your PC, which will display them in its terminal-emulator
window. Don’t enter program EX17_mbed_Five at this time.

ARM mbed Program EX17_mbed_Five.cpp
/*
Experiment 17 ARM mbed
EX17_mbed_Five
Jon Titus, 07-07-2011
*/
#include "mbed.h"
Serial XBeePort(p9, p10);
int charrcvd[5];
int counter;
int main()

//
//
//
//
//

assign UART pins
9 and 10
set up array for rcvd
bytes
set counter variable

// main program starts
// here

{
XBeePort.baud(9600);

// set UART bit rate

while(1)

// outside loop starts
// here

{
counter = 0;
// set counter to 0
while(counter <5)
// while count less than 5
{
// go through this loop
if (XBeePort.readable())
// does UART have a byte?
{
charrcvd[counter] = XBeePort.getc(); //yes, get
// UART byte
counter = counter + 1;
// increment
// counter
}
}
XBeePort.printf("\n\r");
// rcvd 5 bytes, so "type"
// new line
counter = 0;
// reset counter to 0
while(counter < 5)
// while count less than 5
{
// go through this loop
XBeePort.putc(charrcvd[counter]);
//print
// character as a byte
counter = counter + 1;
// increment counter
wait_ms(100);
}
XBeePort.printf("\n\r");
// printer all 5
// characters, "type"
// a new line

}
}
//end of code but execution returns to outside loop

150

Two-Way Communications with XBee Modules

The line #include "mbed.h" causes the ARM mbed compiler to use a file
that defines many operations so you do not have to control individual MCU
registers to configure the UART.
The while(1) loop will run “forever,” or until you change your code
or turn off the ARM mbed module. Within the while(1) loop, the first
while(counter <5) loop uses the command XBeePort.readable() to determine when the UART has received a character. You don’t want to try to get
data from the UART if it contains nothing new. Other MCUs behave in a
similar fashion; that is, they provide a “flag” that software can test to determine if a UART or other device is ready or not ready, full or empty, on or off,
and so on.
When the program determines the UART has a new byte it stores that byte
in the charrcvd array until the array contains five values.
Next, the last while(counter <5) loop gets the bytes stored in the charrcvd
array and sends them back to the XMTR XBee module one at a time. The module immediately transmits the wireless information to the RCVR module. The
wait_ms(100) command causes a 100-millisecond (0.1-second) delay between
transmitted characters, so they appear one at a time in the terminal-emulator
window as transmitted from the XMTR to the RCVR module.
ARM mbed Step 2. The circuit diagram Figure 17.6 shows the ARM
mbed module connections to the XBee XMTR module. Make these connections now. Because an ARM mbed module provides 3.3-volt logic levels, you
do not need logic-level-converter circuits. The ARM mbed module obtains
power from its USB connection.
+3.3V
Top View
To mbed Module
pin 10 (Rx)
To mbed Module
pin 9 (Tx)

To mbed Module
pin 1 (GND)

1

20

2

19

3

18
17

4
5

XBee XB24

16

6

15

7

14

8

13

9

12

10

11

FIGURE 17.6 ARM mbed-to-XBee circuit connections.

Using an ARM mbed Module

151

Important: People often run into problems because their circuits lack a
common ground. You must ensure you have a ground connection between the
ARM mbed module and the XBee breadboard.
Connect your ARM mbed module to your PC via a USB cable and load the
program EX17_mbed_Five.cpp into the compiler. Compile the program and
load it into the MCU. Note: An ARM mbed module acts like an external USB
drive, so you simply “save” your code to the ARM mbed module. On my PC,
the ARM mbed module appeared as the F: drive. Refer to the mbed.org web
site for tutorial and reference information.
Turn on power to your XBee RCVR module in the breadboard.
Push the ARM mbed pushbutton to start your program. In your terminal emulator you should see a blank text window. (If you just completed
Experiment 16, you might see information remaining from old transmissions.)
Type four characters, such as ASDF, into your terminal emulator. Now type
a fifth character. You should see all five characters appear in the emulator’s
window.
The ARM mbed module received the five characters and saved them
in an array. Upon receipt of the fifth character, the ARM mbed transmitted
the five characters back to the terminal emulator via the XMTR and RCVR
modules.
ARM mbed Troubleshooting: If you did not see the five-character
response from the ARM mbed module, you likely had incorrect UART settings
in the ARM mbed MCU or in your terminal emulator. Recheck your settings
so they match 9600 bits/second, or 9600 baud. You also need eight data bits, no
parity, and one stop bit, along with no flow control.
Because the ARM mbed uses a USB port to communicate with its
Web-based development software, ensure you have selected the “USB Serial
Port” for the USB-to-XBee adapter board when you set up your terminal
emulator. Do not use the COM port for the ARM mbed module. That COM
port serves as the programming and debugging port for the ARM mbed
compiler.
Recheck your circuit to ensure you have a common ground between all circuit elements. Also check the transmit and receive wires to ensure they connect
to the proper points.
ARM mbed Step 3. In the steps above, the ARM mbed module simply
received five characters and transmitted them back to the terminal emulator.
But, the ARM mbed also could interpret received information and take actions
based on the commands it receives. The next program modifies the EX17_
mbed_Five program to recognize receipt of a “T” or a “t.” The MCU will still
transmit the five characters it received, and will transmit a short message to
acknowledge it received “T” or “t” among the characters.

152

Two-Way Communications with XBee Modules

ARM mbed Program EX17_mbed_FiveT.cpp
/*
Experiment 17 ARM mbed
EX17_mbed_FiveT
Jon Titus, 07-07-2011
*/
#include "mbed.h"
Serial XBeePort(p9, p10);
int charrcvd[5];
int counter;
int alphachar;
int main()

//
//
//
//
//
//
//
//

assign UART pins
9 and 10
set up array for
rcvd bytes
set counter variable
set up flag value
main program starts
here

{
XBeePort.baud(9600);

// set UART bit rate

while(1)

// outside loop starts
// here

{



alphachar = 0;
// set flag value to 0
counter = 0;
// set counter to 0
while(counter <5)
// while count less than 5
{
// go through this loop
if (XBeePort.readable())
// does UART have a byte?
{
charrcvd[counter] = XBeePort.getc(); //yes, get
//UART byte
if ((charrcvd[counter] == 0x54) || (charrcvd
// [counter] == 0x74))
{
alphachar = 1;
}
counter = counter + 1;
// increment
// counter
}
}
XBeePort.printf("\n\r");
// rcvd 5 bytes, so
// "type" new line
counter = 0;
// reset counter to 0
while(counter < 5)
// while count less than 5
{
// go through this loop
XBeePort.putc(charrcvd[counter]);
//print
// character as a byte
counter = counter + 1;
// increment counter
wait_ms(100);
}
XBeePort.printf("\n\r");
// printer all 5
// characters, "type"
// new line

Control of Remote XBee Modules with MCU AT Commands

153

if (alphachar == 1)
// if alphachar = 1,
{
// print "T Received." message
XBeePort.printf("T Received.\n\r");
}
}
}
//end of code but execution returns to outside loop

The added steps in the new program, EX17_mbed_FiveT, first set the
variable alphachar to 0. Instructions then check received characters to determine if they match the hex value for “T” or “t.” If a character code matches
either 0x54 or 0x74, alphachar gets set to 1. Thus, alphachar serves as a
“flag” that lets the computer know whether or not the received characters
include a “T” or a “t.” Note the double upright bars, ||, are not the characters
for the numeral 1 or lowercase Ls. Find the “bar” character on most keyboards
with the backslash “\” character. The two bars indicate a logical OR condition within the if statement. So, if either the (charrcvd[counter] == 0x54)
OR the (charrcvd[counter] == 0x74) condition is true, the program assigns
alphachar the value 1.
After the program transmits the five received characters back to the
XMTR module, and thus to your terminal emulator, it uses an if statement;
if (alphachar == 1). If alphachar equals 1, which means the five characters
contained a “T” or a “t,” the MCU transmits the message, “T Received.” Note
that in the C language, the notation = = indicates a test for equality between
two values. If you want to assign a value to a variable, use = and not = =.

CONTROL OF REMOTE XBEE MODULES WITH MCU
AT COMMANDS
In this experiment you saw how an MCU connected to a remote XBee module could respond to a command represented by the letter T or t. Could you
have the MCU control the remote XBee module to turn on an LED at the AD1DIO1 pin when it has received the letter T or t? Assume the LED connects
from 3.3 volts through a resistor to pin 19 (Figure 17.7).
When you send an API command packet to change the AD1-DIO1 pin to
a logic-0 condition, you use the command D1 4, or in hex 0x44 0x34 0x04.
So you might think an API command would work in this situation, too.
Unfortunately, configuration instructions for the remote XBee module in this
experiment did not include a step to enable the API capability. But even though
the XBee module operates in transparent mode with the factory-default values,
it will still respond to AT commands just as if sent from the X-CTU Terminal
window. The following example shows the ATD1 command used to change the
AD1-DIO1 pin to a logic 0 on a module attached to a PC:
+++OK

2B 2B 2B 4F 4B 0D

ATD14


41 54 44 31 34 0D

OK

4F 4B 0D

154

Two-Way Communications with XBee Modules
+3.3V
220
Top View
To MCU Module
UART Rx Input
To MCU Module
UART Tx Output

GND

20
1
19
2
18
3
17
4
5 XBee XB24 16
15
6
14
7
13
8
12
9
11
10

LED
AD1–DI01

FIGURE 17.7 LED connection for local control of an XBee module by a microcontroller.

The boldface characters indicate those typed and sent from the X-CTU
Terminal window. This information contains a subtle but important difference
between the “D1 4” command sent in an API command packet and the same command sent from the Terminal window. The API packet uses a hex value for the
parameter you want to change, but the AT command uses the code for the equivalent ASCII character. So to change the AD1-DIO1 pin to a logic 0 with an AT
command you send the character string “ATD1 4[Enter]” or “ATD14[Enter]”. The
latter corresponds to the hex values 0x41 0x54 0x44 0x31 0x34 0x0D, where the
0x0D represents the [Enter]. To re-emphasize, the AT command uses the value for
the numeral 4 (0x34) while an API command uses the hex value of 4 (0x04).
For this command to work, though, the MCU software must ensure some
“quiet time” before it sends the . That quiet time, or guard time, comes
preset in XBee modules for a 1-second period. After it sends the  the
MCU must wait for the “OK” and then send the AT command. When an XBee
module receives the three plus signs it waits to determine if any other bytes
will follow. If none do within the following one second, the XBee module
transmits “OK.” After that, the MCU can respond with its AT command.
Although the MCU software should wait to receive the “OK” reply before
it proceeds, to simplify things the program snippet below for an ARM mbed
module simply waits for 1.5 seconds and then transmits the ATD14[Enter]
string to the XBee module. In C programs, the “\r” provides a byte equivalent to pressing the Enter key. (You can add similar steps to software for an
Arduino Uno module or other MCU.)
wait_ms(1500);

// 1.5 second quiet time

XBeePort.printf("+++");

// send three plus signs

wait_ms(1500);

// wait 1.5 seconds

XBeePort.printf("ATD14\r");

// transmit ATD0 4 command



Control of Remote XBee Modules with MCU AT Commands

155

Now comes another subtle but important point about the AT commands. The
XBee modules have an AT Command-Mode Timeout parameter preset for 10
seconds. That setting means after an XBee module receives an AT command, it
waits for 10 seconds before it exits the AT command mode. You should ensure no
serial communications to the XBee module occur during this time or they might
get interpreted as additional AT commands, which you don’t want to happen.
During the 10-second AT Command-Mode Timeout period, the state of
the AD1-DIO1 pin will not change. The change occurs only after the timeout
period ends. So, if you add code to the software for your MCU, do not expect
to see an immediate change at the AD1-DIO1 pin. You must wait for the command mode to time out.
You can change the CT – AT Command-Mode Timeout period in the Modem
Configuration window for an attached XBee module from the 10-second default
value (0x64) in steps of 100 msec. You also can change the GT – Guard Time
setting, which has a 1-second default period. Although by convention equipment uses a sequence of three plus signs, , to start an AT command period,
you may change this character to any other you wish with the CC – Command
Sequence Character parameter. I recommend you leave it set for 0x2B, or “.”
It would prove easier to simply turn on an LED at an MCU I/O pin than to
control one on an XBee module, but I thought it important to explore AT commands in a bit more depth.

Notes
Note A. In the programs in this experiment, the MCU code expected five characters, so it will wait in the while (counter < 5) loop until it receives five
characters. Of course, you could set the while loops to receive and transmit
more or fewer than five characters, but the software would have the same problem: It would continue to remain “stuck” in the loop until it received all the
characters.
You can overcome this problem in two ways:
l
Always send the same number of characters. If you don’t have enough
characters for a transmission, “pad” the end of the message with enough
bytes, perhaps 0x00, to give you the proper number to transmit.
l
Include a byte count early in a transmission. Remember from earlier experiments that transmissions all started with the same “start” byte, 0x7E, followed by two bytes that indicated the message length. You could use a
similar type of format for your own communication protocol.
Note B. The programs in this experiment have a small problem that does
not affect operation but could cause confusion if you modify them. The programs all use the same while statement: while(counter <5) in two places, first
to keep track of the number of received bytes and second to track the number of
transmitted bytes. Suppose you decide to receive and transmit six bytes and you
change the value in the first while loop: while(counter <6), but you forget to
change the next while statement, so it stays in the program as: while(counter
<5). The program received six characters but transmits only five.

156

Two-Way Communications with XBee Modules

To overcome this problem, use a variable such as
the value 6 at the start of the program:

int maxbytes 6;

maxbytes

and assign it

//number of bytes to receive and transmit

and then set the two while statements to:

while(counter < maxbytes)

Now, one variable, explained with a comment, governs both the transmit
and receive counts. And, if you need to know the number of bytes elsewhere in
this program, you just use the variable maxbytes. You don’t have to track down
every use of a value “hard coded” in a program.

Experiment | 18

How to Discover
Nearby XBee Modules
Objective: Understand how to discover and identify wireless devices available
for communications.

REQUIREMENTS
2 or 3 XBee modules
1 or 2 XBee adapter boards
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
1 Arduino Uno or ARM mbed microcontroller module
1 5-V-to-3.3-V logic-conversion circuit or module (Arduino Uno only)
1 3.3-V-to-5-V logic-conversion circuit or module (Arduino Uno only)
1 1000-ohm (1 kohm), 1/4-watt resistor (brown-black-red)
1 220-ohm, 1/4-watt resistor (red-red-brown)
1 LED
1 Pushbutton (optional)
1 Double-pole double throw (DPDT) toggle switch (Arduino Uno only)
Terminal-emulation software such as HyperTerminal for Windows (ARM
mbed only)
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In previous experiments you learned how to use the AT command set and API
command packets to communicate with remote XBee modules when you know
their addresses. But suppose you do not know the address of a nearby wireless
module. Or, suppose someone adds another XBee device to your small network. How can you determine which modules the network can communicate
with? You can use an AT command or an API packet to request that all other
XBee modules within range respond with their address and name information.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

157

158

How to Discover Nearby XBee Modules

Table 18.1 Module Information
Module 1

Module 2

Module 3

MY – 16-Bit Address
NI – Node Identifier
SH – Serial Number High
SL – Serial Number Low
Note: Module 3 optional.

In this experiment, you will use two or three XBee modules; one that
connects to a microcontroller (MCU) and one or two remote XBee modules
that will operate via wireless communications. I used three XBee modules
in the following steps. There is no X-CTU configuration file needed for this
experiment.
Step 1. To start, I recommend you first use the X-CTU software to restore
the factory-default settings. You can do this for each XBee module before you
make the configuration changes in the following instructions. Place one of
your XBee modules in the USB-to-XBee adapter and click the Restore button in the X-CTU software. Next click on Read to read the module’s Modem
Configuration information.
l
Under the heading Networking & Security, go to the MY – 16-Bit Source
Address. If no address exists, or if it shows a zero, click on the label and
type in as many as four hexadecimal values. Write your module’s MY
information in Table 18.1.
l
Move down to the last item last item under the Networking & Security
heading: NI – Node Identifier and click on this label. Then click on the
Set button that appears to the right of this label and type in a name for
the module. You can use as many as 20 characters, but I recommend you
use four or five characters and meaningful names, such as END, RCVR,
MOD1, and so on. Write the NI information for the module in Table 18.1.
l
Look under Serial Interfacing heading for the label, AP – API Enable, and
click on it. Choose 1 – API ENABLED.
l
Write the SH – Serial Number High and, and SL – Serial Number Low
information for the module in Table 18.1.
l
Finally, click on Write to save this configuration in the attached module.
This step enables the API interface on your modules and gives it a name
you can recognize.
Repeat Step 1 for each XBee module. All modules in this experiment will have
the same configuration.
In this experiment I used three XBee modules, labeled RCVR, XMTR,
and END for the NI settings.

Introduction

159

Top View
+3.3 V

GND

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 18.1 Power and ground connections for any XBee modules on a solderless
breadboard for this experiment. Remove any other connections.

Step 2. Place one XBee module in an adapter on your solderless breadboard. Place your second XBee module in the USB-to-XBee adapter connected to your PC. If you have a third XBee module, place it in a second XBee
adapter on the solderless breadboard. For now, the breadboard XBee module or
modules require only power and ground, as shown in Figure 18.1. The breadboard modules should not have any other connections.
It doesn’t matter which modules you place in XBee adapters on your
breadboard, but you must have one module in the USB-to-XBee adapter
attached to your PC.
Step 3. Turn on power to the breadboard and ensure you have power at
the XBee module on the USB-to-XBee adapter. If not already running, start
the X-CTU program. Go to the X-CTU PC Settings window and click on
Test/Query to ensure you have an active communication link between the PC
and the module in the USB-to-XBee adapter. (Ensure you have set the X-CTU
program for the proper COM port used by the USB-to-XBee adapter.)
Step 4. Go to the X-CTU Terminal window and clear the screen. Click on
Show Hex to split the Terminal window vertically into a hex-value side (right)
and an ASCII-character side (left).
Step 5. The AT command set includes ND—Node Discover, which causes
the XBee module attached to the PC to transmit a message that all modules
within range will respond to. The XBee modules default to use radio channel C,
so all modules will transmit and receive on this channel. If you had configured
a module for a different channel, it could not communicate with those set for
channel C.
Step 6. Now that you have one or two remote XBee modules set up and
powered you can issue an ND command to the XBee module attached to your
PC to determine what modules it can communicate with.
Go to the X-CTU Terminal window and clear it. Move your cursor into the
left column. When told to, you will type  to put the USB XBee module

160

How to Discover Nearby XBee Modules

into the AT-command mode. The XBee module attached to your PC will reply
with OK. After you see the OK, you will type ATND[Enter].
Go ahead and type , wait for OK to appear, and then type ATND[Enter].
Do not type anything else and wait a few seconds. What did you observe?
In my X-CTU Terminal window, I saw the information shown in Figure 18.2.
+++OK

2B 2B 2B 4F 4B 0D

ATND

41 54 4E 44 OD

89FA

38 39 46 41 0D

13A200

31 33 41 32 30 30 0D

4049E1E6

34 30 34 38 45 31 45 36 0D

24

32 34 0D

END

45 4E 44 0D
0D

1AB

31 41 42 0D

12A200

31 33 41 32 30 30 0D

4049E0EC

43 30 34 39 45 30 45 43 0D

2C

32 43 0D

XMTR

58 4D 54 52 0D
0D
0D

FIGURE 18.2 Data from responses to an ATND command as taken from the X-CTU
Terminal window.

If you did not see a response from the XBee module connected to your
PC, use the X-CTU Modem Configuration window to read the settings from
your attached module. Confirm you have the API set to: (1) API Enable for the
XBee module connected to your PC via a USB cable. You do not need the API

Introduction

161

enabled in modules to discover them, but I recommend you enable API in all
modules used in this experiment so they all have the same settings and you can
interchange them, if you choose to.
The top two lines in the X-CTU Terminal window show the  command sent, the OK received, the ATND command sent, and the hex value
0x0D. The five lines that start with 89FA in the left column indicate:
89FA

= MY – 16-Bit Source Address

13A200

= SH – Serial Number High

4049E1E6

= SL – Serial Number Low

24

= DB – Received Signal Strength

END

= NI – Node Identifier

The next section provides the same types of information from my second
remote XBee module, named XMTR:
1AB

= MY – 16-Bit Source Address

13A200

= SH – Serial Number High

4049E0EC

= SL – Serial Number Low

2C

= DB – Received Signal Strength

XMTR

= NI – Node Identifier

Note the information in each line shown in Figure 18.2 ends with 0x0D,
the ASCII value for carriage return, which forces the Terminal cursor to move
to the line below. Each section for a given XBee module ends with two 0x0D
values. Software could detect the single 0x0D and the 0x0D pair and then
properly parse, or separate, the MY, SH, SL, DB, and NI information so you
could identify individual replying XBee modules. That approach requires a lot
of work for two reasons:
l
You need the hex codes, such as 0x01 and 0xAB, to address a remote
module, not the ASCII bytes for numerals, such as 0 (0x30), 1 (0x31),
A (0x41), and B (0x42), which the ATND command returns.
l
The SH value, for example, uses four bytes of information (0013A200), but
the response to the ATND command leaves off the leading zeros (13A200),
which commands require to address XBee modules.
Because you set all XBee modules for AIP mode, you can get around this
problem by sending an API command packet, rather than an ATND command,
to the XBee module connected to your computer. The response to the API
command returns the needed hex values, and not ASCII character values.
Keep in mind you send the API ND command to the XBee module connected to your PC. That module performs the node-discovery operations and
replies with information about discovered XBee devices. You do NOT send the
ND command to the remote modules.

162

How to Discover Nearby XBee Modules

FIGURE 18.3 Responses to an API ND command packet as seen in the X-CTU Terminal
window.

Step 7. Clear the X-CTU Terminal window and click on Assemble Packet.
Click on the HEX radio button in the lower-right corner of the Send Packet
window. Within the Send Packet window, type:
7E 00 04 08 52 4E 44 13

You have seen this format in previous experiments. The hex information
represents:
7E

= start byte

0004

= 4 bytes in message

08

= AT Command Request byte

52

= frame identifier value (all experiments use this value)

4E

= hex code for letter "N"

44

= hex code for letter "D"

13

= checksum for previous four bytes

You do not see MY, SH, or SL information in the packet above because
it commands the XBee module directly attached to your PC to perform the
ND action. Correct any typing errors. Then, click on Send Data. What do you
observe in the Terminal window?
Figure 18.3 shows the information I found for two remote XBee modules,
named XMTR and END. You will see different values from your module or
modules, but the information will follow the same format. The letter R in the
RND information appears because it’s the ASCII character equivalent of the
0x52 frame-identifier value used in all experiments.
~..RND.

7E 00 04 08 52 4E 44 13 7E 00 14 88

~...RND.....

52 4E 44 00 89 FA 00 13 A2 00 40 49

..@I..$END..

E1 E6 24 45 4E 44 00 10 7E 00 15 88

~..RND.....

52 4E 44 00 01 AB 00 13 A2 00 40 49

..@I..

EO EC 2A 58 4D 54 52 00 68 7E 00 05

*XMTR.h~...R

88 52 4E 44 00 93

ND..

In the top line, you can see the API command packet sent: 7E 00 04 08 52
4E 44 13. Next you find three responses, which always start with 7E:

Introduction

163

Response 1:
7E 00 14 88 52 4E 44 00 89 FA 00 13 A2 00 40 49 E1 E6 24 45 4E
44 00 10

Response 2:
7E 00 15 88 52 4E 44 00 01 AB 00 12 A2 00 40 49 E0 EC 2A 58 4D
54 52 00 68

Response 3:
7E 00 05 88 52 4E 44 00 93

Although I used only two remote modules in this experiment, the X-CTU
Terminal window displayed three responses, which I’ll explain shortly.
You can break down the first response as:
7E

= start byte

0014

= message length (24 bytes)

88

= packet type (Remote AT Command Response)

52

= frame identifier value (all experiments use this value)

4E44

= command name (ND)

00

= status byte (OK)

89FA

= MY – 16-Bit Source Address

0013A200

= SH – Serial Number High

4049E1E6

= SL – Serial Number Low

24

= signal strength

45 4E 44

= NI – Node Identifier (END)

00

= null value 0x00, identifies end of NI characters

10

= checksum for this message

Note the MY, SH, and SL information now provides the proper number of
bytes:
MY — 2 bytes, 0x89 and 0xFA
SH — 4 bytes, 0x00, 0x13, 0xA2, and 0x00
SL — 4 bytes, 0x40, 0x49, 0xE1, and 0xE6
Response 3 provides a reply from the XBee module attached to a PC via a
USB-to-XBee adapter. It repeats the ND command and includes a status byte
that would indicate any error that arises from acting upon the ND command:
0x00  OK, 0x01  Error, 0x02  Invalid Command, and 0x03  Invalid
Parameter.

164

How to Discover Nearby XBee Modules

The final response does not indicate the number of XBee modules that
responded or that no modules responded. It simply tells you the module
attached to your PC properly executed the ND command.
Step 8. As an exercise, use the information in Response 2 (or from your
second remote XBee module, if you have one) and parse the data into the
proper categories shown here:
____________   start byte
____________   message length (number of bytes)
____________   packet type (Remote AT Command Response)
____________   frame identifier value (all experiments use this value)
____________   command name (ND)
____________   status byte
____________   MY – 16-Bit Source Address
____________   SH – Serial Number High
____________   SL – Serial Number Low
____________   signal strength
____________   NI – Node Identifier
____________   null value 0x00, identifies end of NI characters
____________   checksum for this message
Did you get the information you expected from the second remote XBee
module? Check the information from your module or modules against the
information you wrote earlier in Table 18.1.
Because the Node Identifier (NI) can use as many as 20 bytes, the API
response uses a null (0x00) to indicate the end of this string of characters. The
byte count includes the null value. It does not include the checksum byte, though.
Step 9. When you use an API command, responses from XBee modules
provide a consistent number of bytes for the MY, SH, and SL data. Thus software could parse the response from an API node-discovery command to yield
useful MY, SH, SL, and NI information for each discovered XBee module.
In the next section you will see how an MCU can issue an API ND command to discover remote XBee modules. For the most part, the code in this
experiment does not include error-checking steps that could alert you to a
problem transmission or bad data in a response. The program does, though, use
the checksum to test for receipt of a bad packet.
When a UART operates at 9600 bits/second, or 104 microseconds/bit, an
MCU has about one millisecond to decide what to do with each received byte. So
software could take two routes. First, determine what to do with each byte as it
arrives, or second, save all the received bytes in an array and process them later.
This experiment assumes you know how many remote XBee modules will
respond and it will store the information from each module in an array. In
other experiments you will learn how to determine the number of XBee modules in a network and how to use the information “discovered” for each one.
In my lab I had three XBee modules; two connected to power and ground
on a solderless breadboard and one connected to power and ground via the
USB-to-XBee adapter and a USB cable. In the steps that follow I connected

Using an Arduino Uno Module

165

one of the XBee modules on the breadboard to an MCU. The XBee module
in the USB-to-XBee adapter remained connected to my PC, but it simply
obtained power via the USB connection.
As you examine the code that follows, keep in mind the message-length
count in a packet comprises two bytes. So far, API messages and responses have
taken fewer than 30 or so bytes. But cases might occur when a message exceeds
0xFF (255) bytes. So a program that receives and processes messages should
include the most-significant byte in the byte count. This software multiplies
the most-significant byte-count value by 256 and adds it to the least-significant
byte-count value to create an accurate byte-count value from 0 to 65,535,
although it’s unlikely a packet will contain that many bytes.

EXPERIMENT 18 SOFTWARE FLOW CHART
The flow chart in Figure 18.4 shows the operations the code will perform.
Descriptions of software operations and instructions for the Arduino Uno and
ARM mbed MCU modules follow.

USING AN ARDUINO UNO MODULE
Uno Step 1. The diagram in Figure 18.5 shows the connection from the
Arduino Uno module to an XBee module in a breadboard adapter. You can add
an optional double-pole double-throw toggle switch to disconnect the logiclevel-conversion circuits from the Arduino Uno module, as explained later.
If you don’t use a switch, wires will suffice. Make these connections now.
Pay careful attention to the notes below and in Figure 18.5 that explain
additional connections not shown in the diagram for the sake of clarity:
l
On LLC 5-to-3, connect a 1-kohm resistor (brown-black-red) between pins
1 and 2.
l
On LLC 3-to-5, connect pin 2 to ground.
l
On both logic-level-converter devices, connect pins 11, 12, 13, and 22 to
ground.
l
On both logic-level-converter devices, connect pin 1 to 5 volts.
l
On both logic-level-converter devices, connect pins 23 and 24 to 3.3 volts.
Uno Step 2. The circuit for the Arduino Uno module also requires an LED, a
pushbutton switch, and two resistors. The LED indicates completion of module
discovery and the pushbutton signals the MCU to start the main program steps.
The circuit diagram in Figure 18.6 shows the added LED and pushbutton
switch. Make these connections now. You can place the LED and resistors on a
solderless breadboard.
Because the Arduino Uno module will use one UART to communicate
with an XBee module and the host PC USB connection, maintaining the serial
connections between an Arduino Uno module and an XBee module when
downloading code can cause an electrical conflict. So you MUST manually
disconnect (or use a small switch to open) the two serial-port connections
between an Arduino Uno module and any external device while the compiler

166

How to Discover Nearby XBee Modules
Definitions
Serial Input function
preset number of modules

Wait for ground on TestPin

Transmit API packet “ND”

Done
LED on

Yes

All XBee modules
done?

No

Print XBee
Data

Wait for 0xFE

Get message-byte-count bytes
Calculate byte count
Yes
Get message data byte
Save byte in dataND array
Add checksum bytes

Checksum OK?

No
No

All bytes received?

Transmit error message
Flash LED

Yes

FIGURE 18.4 Flowchart for a program to save XBee module information.

Using an Arduino Uno Module
+3.3V

Top View

LLC 3–to–5
To Arduino Uno Pin 0 (RX)
To Arduino Uno Pin 1 (TX)
DPDT Switch

3

2

21

DOUT
DIN

LLC 5–to–3
3

21
1 kohm

To Arduino POWER GROUND

167

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

GND
Logic–Level–Converter (LLC) Connections:
Ground at pins 11, 12, 13, 22.
+5 volts at pin 1; +3.3 volts at pins 23, 24.
On LLC 5–to–3: 1 kohm resistor between pins 1 and 2.
On LLC 3–to–5: ground pin 2.

FIGURE 18.5 Connections between an XBee module and an Arduino Uno module require
logic-level-converter circuits.

To Uno Pin 5V
1000 ohms
To Uno Pin 7
To Uno Pin GND

Momentary
Contact

220 ohms
LED

To Uno Pin 13

FIGURE 18.6 The Uno module requires these extra components and connections for this
experiment.

downloads code to the Arduino Uno board. I used a small toggle switch to disconnect the connections between the logic-level-conversion circuits and the
Arduino Uno module during code downloads. Individual wires will work, too.

Arduino Uno Software
The program shown in Program EX18_Uno_ND provides the code used in this
section. You can download code examples at: http://www.elsevierdirect.com/
companion.jsp?ISBN=9780123914040.

168

How to Discover Nearby XBee Modules

Program EX18_Uno_ND
/*
*
*
*
*
*
*
*/

EX18 Arduino Uno Module Rev. D
Program EX18_Uno_ND
Send ND API command packet to "hub" module and identify set
number of modules. Save information in an array and print
results as hex data.
Jon Titus 08-29-2011

// define API "ND" packet
byte packetND[] = {0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x44,0x13};
byte packetNDlength = 8;
// define number of modules here as a constant, change to suit
const byte numb_of_modules = 2;
// and define the number of bytes in array dataND[]
const byte dataNDlength = 40;
byte XBee_numb;
byte dataND[numb_of_modules][dataNDlength];
byte testdata;
// Define digital I/O pins
int
TestPin = 7;
int
LedPin = 13;
//define
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

other variables
int bytecount_hi;
int bytecount_lo;
int bytecount;
int counter;
int chksum;
int chksum_temp;

// function SerialInput reads UART after it has data
byte SerialInput()
{
while (Serial.available() == 0)
// wait for UART to have
// new data
{
}
return (Serial.read());
// get new data, return
}
// Set up conditions for I/O pins and UART bit rate
void setup()
{
Serial.begin(9600);
pinMode(TestPin, INPUT);
pinMode(LedPin, OUTPUT);
digitalWrite(TestPin, HIGH);
digitalWrite(LedPin, HIGH);
// turn test LED off
// to start
}

Using an Arduino Uno Module

169

// Main loop for Arduino Uno code. Arduino Uno does not use
// void main()...
void loop()
{
while (digitalRead(TestPin) == HIGH)
{
}
delay(500);
Serial.write (packetND, packetNDlength);

// wait for ground
// contact on TestPin

// half-second delay
// transmit "ND" API
// packet to XBee

// This portion of the program gets serial data sent by XBee
// modules and saves the data in an array of bytes for each module.
for (XBee_numb = 0; XBee_numb < numb_of_modules; XBee_numb++)
{
testdata = SerialInput();
if (testdata == 0x7E);
// serial
// byte == 0x7E?
{
bytecount_hi = SerialInput();
bytecount_lo = SerialInput();
bytecount = (bytecount_hi * 256) + bytecount_lo; // get #
// of bytes in msg
counter = 0;
chksum_temp = 0;
// clear
// checksum value
for (counter; counter < bytecount; counter++)
// put
// XBee data in
// until done
{
dataND[XBee_numb][counter] = SerialInput();
chksum_temp = chksum_temp + dataND[XBee_numb][counter];
}
chksum = SerialInput();
// get
// checksum--last byte
if (chksum != (0xFF - (chksum_temp & 0xFF)))
// do
// checksums match
{
while(1)
// no
// match, flash LED
// forever
{
// error
// handling could go
digitalWrite(LedPin, LOW);
// here
// instead.
delay(1000);
digitalWrite(LedPin, HIGH);
delay (500);
}
}

170

How to Discover Nearby XBee Modules

}

// do it
// for next module

}

// OK,
// got data for all
// XBee modules

digitalWrite(LedPin, LOW);
delay(500);
Serial.print("\n\n\r");

// half-second delay
// go to a new line
// in text window
// Test routine to print data in each XBee array as hex
// characters
// Data goes to PC terminal emulator
XBee_numb = 0;
for (XBee_numb; XBee_numb < numb_of_modules; XBee_numb++)
{
counter = 0;
for (counter; counter < 40; counter++)
{
if (dataND[XBee_numb][counter] < 0x10)
{
Serial.print("0");
}
Serial.print(dataND[XBee_numb][counter], HEX);
Serial.print(" ");
}
Serial.print("\n\n\r");

// go to a new line
// in text window

while(1)

//
//
//
//

}

{
}

end program in an
infinite
do-nothing
loop

}
// Arduino Uno void loop() code ends here

The EX18_Uno_ND program first defines variables. The array packetND[ ]
sets up eight bytes for the API ND command. Other definitions set the length
of this packet (8), the number of expected modules (2), and the number of
bytes (40) allocated for each module’s response:
byte packetNDlength = 8;
const byte numb_of_modules = 2;
const byte dataNDlength = 40;

If you plan to use only one remote XBee module (total of two overall, one
remote and one attached to the Arduino Uno), change the value in const byte
numb_of_modules = 2; to const byte numb_of_modules = 1; in this experiment, the number of modules refers to those NOT connected to the Arduino

Using an Arduino Uno Module

171

Uno module. Remember, you may leave an XBee module in the USB-to-XBee
adapter. It will obtain power from your PC and will not communicate with it.
Instead of repeating serial-input commands throughout the program, the
code includes a SerialInput function that tests for a byte of unread information at the Arduino Uno UART. As soon as a new byte arrives from an XBee
module, the function returns the newest byte to the main loop.
The setup section of code establishes the UART data rate at 9600
bits/second, sets the mode for the two MCU I/O pins defined earlier (see
Figure 18.6), and sets the initial conditions for those pins. Unlike many MCU
compilers that use a void main() definition to create the core of a program,
the Arduino compiler uses a void loop(). The Arduino Uno runs some underlying code, so the loop simply operates “on top” of that code in its own loop.
Within the main loop, the software first waits for a logic 0 at the TestPin
input (pin 7). As soon as the code detects this condition it proceeds to the command delay(500) that creates a half-second quiet period. Next, the MCU
code transmits the eight values in the packetND array that holds the API
ND-command packet:
Serial.write (packetND, packetNDlength);

The loop for (XBee_numb... provides the XBee-response processing steps. It waits for the value 0x7E to arrive from the XBee module via the
UART. When that value arrives, the code gets the next two bytes—the mostsignificant byte and then the least-significant byte—that represent the total
byte count for the message. The bytecount math operation calculates the total
number of bytes in the message. Remember, the bytecount value does not
count the checksum byte.
The next for loop takes the arriving bytes and saves them in the array
dataND, which can store as many as 40 values, and then adds the received
bytes to calculate a checksum. When the routine receives the checksum byte
from the XBee module, the code compares it with the calculated checksum.
If the checksums do not match, the code branches into a short loop that continuously pulses the LED shown previously in Figure 18.6.
After the program receives all the values from the preset number of remote
XBee modules, it displays the hex values of the remote-module information
so you can easily review them. The version of the C language for the Arduino
Uno module does not include a command that formats hex values with leading
zeros. So an if statement checks for hex values from 0x00 to 0x0F and gives
then a 0 prefix in the Arduino Serial Monitor window. Thus you will see results
such as AB 00 13 A2 00 rather than AB 0 13 A2 0.
Uno Step 3. If you have not included a DPDT switch in your Arduino Uno
circuit as shown in Figure 18.5, you must label the two wires that connect to
the two Uno serial-port pins, TX and RX. Temporarily disconnect these wires
from the Uno module’s serial-port pins. (Or flip the switch to disconnect these
signals.) You can simply remove the wires from the female connector strip and
reinsert them later.

172

How to Discover Nearby XBee Modules

Load the program EX18_Uno_ND into the Arduino Uno compiler, compile
it, and correct any errors. When the compiler completes loading the code into the
Arduino Uno module, as indicated by the Done Saving message in the bottom text
area, reconnect the wires (or flip the switch) from the logic-level-converter circuit
to the serial-port pins on your Uno module. Now you have the Arduino Uno module reconnected to the logic-level-conversion circuits and the XBee module.

Arduino Uno Troubleshooting
When you compile and load a program into an Arduino Uno MCU, do not
leave the logic-level-converter circuits, or any other device, connected to
the Arduino Uno serial-port pins, RX --0 and TX→1. Signal conflicts at
the MCU UART input can cause the compiler to display the error message
“Problem uploading to board.” Don’t worry; just temporarily disconnect the
two signal wires from the logic-level-conversion circuits to the Arduino Uno
module and recompile and download the program code. When the compiler
indicates: Done uploading, reconnect the wires or flip the switch.
Uno Step 4. After you successfully compile the EX18_Uno_ND program
and it has loaded into your Arduino Uno, press the Uno reset button. An LED
on the Arduino Uno will flash several times and turn off. Click on the Arduino
Serial Monitor button to open its window.
Either press the pushbutton shown in Figure 18.6 or make a quick ground
connection to the Uno-Pin-7 end of the 1000-ohm resistor. Grounding this
connection lets the EX18_Uno_ND program proceed.
As soon as the MCU has processed the information from the remote XBee
module or modules, the LED shown in Figure 18.6 will turn on. (Don’t confuse this LED with the small LEDs on the Uno module.) At this point, you
should see characters, such as:
~...RND.

in the Serial Monitor window. These characters represent the eight bytes
in the transmitted API ND-command packet. In a second or two you also
should see information from your XBee modules—40 bytes per module—that
looks like:
88 52 4E 44 00 12 34 00 12 A2 00 40 49 E0 28 2D 52 43 56 52 00
00 00 ...

88 52 4E 44 00 89 FA 00 12 A2 00 40 49 E1 E6 1D 45 4E 44 00 00
00 00 ...

The C code displays all 40 values in each dataND array for an XBee module because the software defined each array with 40 elements. The information
matched what I expected based on the data shown earlier in Figure 18.3 for my
two remote modules.

Using an Arduino Uno Module

173

You might wonder why you see the ~ . . . RND., or similar information, at the
start. The Arduino Uno module has only one UART output, so the Arduino Serial
Monitor “sees” the 8-byte ND command sent to the XBee module attached to the
Arduino Uno as well as the XBee information the MCU transmits to the Serial
Monitor. Not all hex codes in the API packet represent printing ASCII characters,
thus the odd symbols. This “mixing” of API-command and XBee-response data
illustrates the problem of sharing a UART between two external devices.
Remember, the EX18_Uno_ND software identified the one or two XBee
modules with only power and ground connected to them. The “//Test routine to print data...” portion of the EX18_Uno_ND program formats the
bytes so they appear as hexadecimal characters. Then the program ends in an
infinite while(1) loop.

Arduino Uno Conclusion
In this experiment you learned how to use an API packet with the ND command to request identification information from modules on the same default
radio channel. You also learned the responses from XBee modules provide useful information. In this experiment, an Arduino Uno MCU served as the “hub”
for communications with other XBee modules.
Because the program saved the information from each XBee module in an
ordered fashion, as shown earlier in Step 7 in the first part of this experiment
that did not involve an MCU, you can locate information at specific places in
the dataND array. Thus the XBee SH address for XBee module 0 in the dataND
array exists in array elements dataND[0][7] through dataND[0][10], and the
SL value exists in array elements dataND[0][11] through dataND[0][14].
To simplify retrieving information for a given XBee module, and give others insight into what you have programmed, you might use a structure in a
C program to store the replies from XBee modules. This structure declaration
sets up arrays of bytes for XBee data MY (2 bytes), SH (4 bytes), SL (4 bytes),
and NI (20 bytes plus a null). You could expand it to hold other information, too.
struct XBeedata
{

byte MY[2];
byte SH[4];
byte SL[4];
byte DS[1]
byte NI[21]

} XBee[2];

The

at the end of the structure definition creates two structures,
and XBee[1], for two remote modules. Then the loop that obtains
replies from XBee modules could put the information in the structure XBee[0]
or XBee[1] as the bytes arrive from the UART.
Please skip ahead to the Final Steps section.
XBee[0]

XBee[2]

174

How to Discover Nearby XBee Modules

USING AN ARM MBED MODULE
mbed Step 1. The diagram in Figure 18.7 shows the connections from the
ARM mbed module to an XBee module. Make these connections now.
The ARM mbed module does not require logic-level-conversion circuits
because it operates at 3.3 volts, which makes it compatible with the logic
levels on an XBee module.
mbed Step 2. The circuit for the ARM mbed module requires a few added
components: an LED, a pushbutton switch, and two resistors. The LED indicates completion of module discovery and the pushbutton signals the MCU to
start the main program steps.
The circuit diagram in Figure 18.8 shows the added LED and pushbutton
switch. Make these connections now. You can place the LED and resistors on a
solderless breadboard.

+3.3V
Top View
To mbed Module
Pin 10 (Rx)
To mbed Module
Pin 9 (Tx)

To mbed Module
Pin 1 (GND)

DOUT
DIN

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

FIGURE 18.7 An ARM mbed module operates with 3.3-volt logic, so it can connect
directly to an XBee module.

To ARM mbed Pin VOUT +3.3V
1000 ohms
To ARM mbed Pin 7
To ARM mbed Pin GND

Momentary
Contact

220 ohms
LED

To ARM mbed Pin 13

FIGURE 18.8 The ARM mbed module requires these extra components and connections
for this experiment.

Using an ARM mbed Module

175

ARM mbed Software
The program shown in EX18_mbed_ND provides the code used in this section. You can download code examples at: http://www.elsevierdirect.com/
companion.jsp?ISBN=9780123914040.
The EX18_mbed_ND program first defines variables. The array packetND[ ]
sets up eight bytes for the API ND command, sets the length of this packet (8),
the number of expected modules (2), and the number of bytes (40) allocated
for each module’s response:
int packetNDlength = 8;
const int numb_of_modules = 2;
const int dataNDlength = 40;

If you plan to use only one remote XBee module (total of two overall, one remote and one attached to the ARM mbed), change the value in
const int numb_of_modules = 2; to const int numb_of_modules = 1;
in this experiment, the number of modules refers to those NOT connected
to the ARM mbed module. Remember, you may leave an XBee module in
the USB-to-XBee adapter. It will obtain power from your PC and will not
communicate with it.
The ARM mbed serial ports default to 9600 bits/second, so there’s no need
to specify this bit rate in the code. Serial port Sport connects to pin 9 (MCU
UART transmitter) and pin 10 (MCU UART receiver). A second, predefined
MCU serial port, pc, connects to your host PC as a virtual serial port via the
module’s USB connection. The two UARTs operate independently of one
another. Thus, the pc serial connection lets you use a terminal-emulator program to display information separate from the MCU serial port at pins 9 and
10 that connects to an XBee module.
Instead of repeating serial-input commands throughout the program, the
code uses a SerialInput function to test for a new byte of data at the serial
input and then return the byte. As soon as a new byte arrives from an XBee
module, the function returns the newest byte to the main loop.
Within the main loop, the software first waits for a logic 0 at the TestPin
input (pin 7). As soon as the code detects this condition it proceeds to the command wait(0.5) that creates a half-second quiet period. Then it proceeds to
the statements:
counter = 0;
while (counter < packetNDlength)
{
Sport.putc(packetND[counter]);
counter = counter +1;
}

176

How to Discover Nearby XBee Modules

This loop transmits the eight values in the packetND array to the Sport
UART.
The loop for (XBee_numb... provides the XBee-response processing
steps. It waits for the value 0x7E to arrive from the serial port. When an 0x7E
value arrives, the code gets the next two bytes—the most-significant byte and
then the least-significant byte—that represent the total byte count for the message. The bytecount math operation calculates the total number of bytes in
the message, 0 to 65,535. Remember, the bytecount value does not count the
checksum byte. (A response from an XBee module in API mode always starts
with the hex value 0x7E.)
The next for loop takes the arriving bytes and saves them in the array
dataND, which can store as many as 40 elements, and then adds the received
bytes to calculate a checksum. When the routine receives the checksum byte
from the XBee module it compares it with the calculated checksum. If the
checksums do not match, the code branches into a short loop that continuously
pulses the LED shown previously in Figure 18.8.
After the program receives all the values from the preset number of remote
XBee modules, it displays the hex values of the information so you can easily
review them.

ARM mbed Program EX18_mbed_ND.cpp
/*
*
*
*
*
*
*
*/

EX18 ARM mbed Module Rev. E
Program EX18_mbed_ND
Send ND API command packet to "hub" module and identify set
number of modules. Save information in an array and print
results as hex data.
Jon Titus 08-29-2011

#include "mbed.h"
// Define API "ND" command-packet array here
int packetND[] = {0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x44, 0x13};
int packetNDlength = 8;
//Define number of modules here as a constant
const int numb_of_modules = 2;
//and define the number of bytes in array dataND[] for XBee modules
const int dataNDlength = 40;
int dataND[numb_of_modules][dataNDlength];
//Input-output and serial I/O definitions
DigitalIn
TestPin(p7);
DigitalOut LedPin(p13);
Serial Sport(p9, p10);
Serial pc(USBTX, USBRX);

Using an ARM mbed Module

177

//Define additional variables
int XBee_numb;
int testdata;
int MSbits, LSbits;
unsigned int bytecount_hi;
unsigned int bytecount_lo;
unsigned int bytecount;
unsigned int counter;
unsigned int chksum;
unsigned int chksum_temp;
//Function SerialInput reads UART after it has new data
int SerialInput()
{
while (Sport.readable() == 0)
//wait for UART to have
//new data
{
}
return (Sport.getc());
//get new data, return
}

//Main XBee program

int main(void)
{
LedPin = 1;
while (TestPin == 1)
{
}
wait(0.5);

//turn test LED off to start
//wait for ground contact on TestPin

//half-second delay

//Transmit packetND
counter = 0;
while ( counter < packetNDlength)
{
Sport.putc(packetND[counter]);
counter = counter + 1;
}
//This portion of the program gets serial data sent by XBee
//modules and saves the data in an array of bytes for each module.
for (XBee_numb = 0; XBee_numb < numb_of_modules; XBee_numb++)
{
testdata = SerialInput();
if (testdata == 0x7E); //first serial byte == 0x7E?
{
//yes
bytecount_hi = SerialInput();
bytecount_lo = SerialInput();
bytecount = (bytecount_hi * 256) + bytecount_lo;
//get # of bytes in msg

178

How to Discover Nearby XBee Modules

chksum_temp = 0;
//clear checksum value
for (counter = 0; counter < bytecount; counter++)
//put XBee data in array
{
dataND[XBee_numb][counter] = SerialInput();
chksum_temp = chksum_temp + dataND[XBee_numb][counter];
}
chksum = SerialInput();
//get checksum--last byte
if (chksum != (0xFF - (chksum_temp & 0xFF)))
//do checksums match
{
while(1)
//NO MATCH, flash LED forever
{
//Error handling could go
LedPin = 0;
//here instead.
wait(1);
LedPin = 1;
wait(0.5);
}
}
}
//YES MATCH, do it for next module
}
//OK got data for all XBee modules
LedPin = 0;
wait(0.5);

//turn on LED
//half-second delay

//Routine to print data in each XBee array as hex characters
//Data goes to PC terminal emulator
for (XBee_numb = 0; XBee_numb < numb_of_modules; XBee_numb++)
{
pc.printf("\n\r");
for (counter = 0; counter < dataNDlength; counter++)
{
pc.printf("%02X ", dataND[XBee_numb][counter]);
}
pc.printf("\n\r");
//go to a new line in text window
}
while(1)

//end program in an infinite
//do-nothing loop

{
}
}

mbed Step 3. After you load the program EX18_mbed_ND into the ARM
mbed compiler, compile it and correct any errors. When you have an error-free
program, you will see Success! appear in the Compiler Output area at the bottom of the compiler window. You will also see a file-download window appear.
You want to save the compiler output, so click Save. In the Save As window,
choose the ARM mbed “drive.” (The ARM mbed module looks like a USB
memory stick to your PC. It operated as the F: drive on my lab PC.) Then save
the compiler output on the ARM mbed. If necessary, you can overwrite a program with the same name on the ARM mbed module. Someone else might

Using an ARM mbed Module

179

have used the ARM mbed, or you might have revised or corrected a program
with the same name several times. An overwrite is OK.
mbed Step 4. Start your terminal emulator program and ensure it connects to
the virtual serial port that links the ARM mbed to your PC. On a Windows PC, use
the Device Manager to find the proper serial port, labeled ARM mbed Serial
Port. Check the emulator settings to ensure they match 9600 bits/second, eight
data bits, no parity, one stop bit (8N1, and no flow control).
mbed Step 5. Turn on power to your breadboard and press the ARM mbed
reset button. The module’s blue LED will flash several times and then turn on.
Press the pushbutton shown in Figure 18.8 or make a brief contact between the
ARM mbed-pin-7 end of the 1000-ohm resistor and ground. DO NOT try to
touch ground to pin 7 on the mbed module itself. You risk damaging the MCU.
As soon as the ARM mbed MCU has processed the information from the
remote XBee modules, the external LED will turn on. Next you should see information in the terminal emulator—40 bytes per reply—that looks something like:
88 52 4E 44 00 12 34 00 12 A2 00 40 49 E0 28 2D 52 43 56 52 00
00 00 ...

88 52 4E 44 00 89 FA 00 12 A2 00 40 49 E1 E6 1D 45 4E 44 00 00
00 00 ...

My code displayed all 40 values in each of the two dataND arrays because I
defined each array with 40 elements. This information matched what I expected
based on the information in Figure 18.3 for my two remote modules.
Remember, you have identified the XBee module with only power and
ground and any XBee module attached to the USB-to-XBee adapter that
connects to your PC.
The "//Test routine to print data..." portion of the program formats
the bytes so they appear as hexadecimal characters. Then the program ends in
an infinite while(1) loop.

ARM mbed Conclusion
In this experiment you learned how to use an API packet with the ND command to request identification information from modules on the same default
radio channel. You also learned the responses from XBee modules provide useful information. In this experiment, an ARM mbed MCU served as the “hub”
for communications with other XBee modules.
Because the program saved the information from each XBee module in an
ordered fashion, as shown earlier in Step 7 in the first part of this experiment
that did not involve an MCU, you can locate information in specific elements in
the dataND array. Thus the XBee SH address for XBee module 0 in the dataND
array exists in array elements dataND[0][7] through dataND[0][10], and the
SL value exists in array elements dataND[0][11] through dataND[0][14].

180

How to Discover Nearby XBee Modules

To simplify retrieving information for a given XBee module, and give others insight into what you have programmed, you might use a structure in a
C program to store the replies from XBee modules. This structure declaration
sets up arrays of bytes for XBee data MY (2 bytes), SH (4 bytes), SL (4 bytes),
and NI (20 bytes plus a null). You could expand it to hold other information, too.
struct XBeedata
{

char MY[2];
char SH[4];
char SL[4];
char DS[1]
char NI[21]

} XBee[2];

The

at the end of the structure definition creates two structures,
and XBee[1], for two remote modules. Then the loop that obtains
replies from XBee modules could put the information in the structure XBee[0]
or XBee[1] as the bytes arrive from the UART. By using the structure elements
XBee[0].MY[0] and XBee[0].MY[1] you know right away a program uses the
first and second bytes of the MY address for the XBee 0 module in your network.
Please continue with the next section.
XBee[2]

XBee[0]

FINAL STEPS
This experiment assumed you knew how many remote modules you plan to
communicate with and that you used this number as the numb_of_modules
constant in the program. But in many situations you might have from one
to, say, 10 modules. How would you create a program to determine when all
remote modules had responded to a node-discovery (ND) command?
The XBee modules provide a possible solution: When you assembled and
sent the API packet for the ND command, the response included information
from the powered remote modules, as well as the “extra” information as noted
in Step 7 in the first part of this experiment that did not involve an MCU. This
extra information takes the form:
7E 00 05 88 52 4E 44 00 93
7E

= start byte

0005

= message length (5 bytes)

88

= packet type (Remote AT Command Response)

52

= frame identifier value (all experiments use this value)

4E44

= command name (ND)

00

= status byte (OK)

93

= checksum for this message

Important Notes

181

From this response you only know the hub XBee module properly executed
and completed the ND command operations (status byte  0x00). You do not
know whether the hub received any responses or the number of responses received.
In addition to processing the information about remote modules, your code
also could examine incoming data for the packet shown above. Perhaps if you
received a message with a byte count of 0x0005, a program could check the
status byte, leave the data-gathering routine, and proceed with other parts of
your program. I don’t recommend that approach, though.
In a later experiment you will learn how to more easily overcome the problem
of discovering and counting modules when you have an unknown number of them.

IMPORTANT NOTES
The code in this experiment used a variable, packetNDlength, to specify
the preset length of the ND command packet. You could have used a sizeof
function to determine the number of elements in the array. But working with
arrays in C can get tricky, so I prefer to use a fixed value rather than a calculation. And don’t try to calculate an array length when you “pass” an array to
a function, because the compiler only gives the function a pointer to the array
and not the complete array to work with.
l
The ND command has two related configuration settings, NO – Node
Discovery Options and NT – Node Discovery Time.
The Node Discovery Option lets you decide whether or not to have the hub
XBee module that discovers other modules also “discover” itself. If you enable
this option (NO  1), you will receive a complete packet of information just as
you would for a discovered remote XBee module. I recommend you leave the
NO set to its factory-default setting, 0, which disables the option.
The Node Discovery Time lets you set a value from 100 milliseconds
(0x01) to 25.2 seconds (0xFC) during which the hub XBee module will wait
for remote XBee modules to respond. The NT setting has a default value of
0x19, or 2.5 seconds. I recommend you leave the NT setting at its factorydefault value. Multiply the NT value by 100 msec to obtain the delay period.
During this period, remote XBee modules can respond. At the end of this
period, when we expect all remote XBee modules have responded, the hub XBee
module responds with the information shown earlier in this Final Steps section.
l

Experiment | 19

How to Set Up a Small
XBee Network
Objective: Understand how to associate modules in a network as they turn on,
how to “take attendance” of associated End-device modules, how to address
modules by name, and how to detect network errors. This experiment includes
critical information about how to reset a Coordinator module.

REQUIREMENTS
2 or 3 XBee modules
1 or 2 XBee adapter boards
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
2 LEDs
2 330-ohm, 1/4-watt, 10% resistors (orange-orange-brown)
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In previous experiments you learned how to communicate with remote XBee
modules and query them to determine serial numbers, obtain information about
digital and analog signals, and exchange other information. In this experiment
you will learn how to associate XBee modules in a non-beacon network that
comprises one Coordinator module and one or more End-device modules.
The diagram in Figure 19.1 shows the arrangement of two End devices and a
Coordinator module.
Until now, experiments assumed no other wireless devices in your vicinity
would operate on the same wireless channel assigned by default to XBee modules. The factory settings cause each module to operate on the C channel, one
of 16 between 2.405 and 2.480 gigahertz (GHz). The C channel (0x0C) operates at 2.410 GHz. But other XBee modules or wireless devices that comply
with the IEEE 802.15.4 wireless standard could operate on that channel, too.
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

183

184

How to Set Up a Small XBee Network

Two-Way Wireless Links
XBee
XBee
End Device
PC

End Device
XBee

USB Connection
Coordinator

FIGURE 19.1 In a non-beacon network, one XBee module acts as the Coordinator and
other XBee devices act as End devices. Communication between End devices must go
through the Coordinator.

To avoid communication conflicts, in a non-beacon network of XBee modules, a Coordinator can perform three network-related operations:
l
Scan all 16 wireless channels to find one with no radio signals, or one with
the smallest amount of radio-frequency (RF) energy. It will use this channel for communications with End-device modules.
l
Reassign the Personal-Area Network (PAN) number, which has a factory
default of 3332. The Coordinator should not use a PAN value already assigned
to a nearby network, so it will test channels to determine PAN values for existing networks within its range and will then choose an unused PAN value.
l
Let any XBee device associate with it, or not let XBee devices associate
with it. In almost every case, you will allow association unless you have
an established network and do not expect to add any extra modules or do
not want rogue modules to associate with a network. After you establish a
network, you might not want to allow any other XBee devices to enter the
network after it reaches a limit of, say, 12 End devices.
End devices also can operate in several ways. They can:
l
Associate with any Coordinator with any PAN ID, or only with a Coordinator
that has the same preset PAN ID.
l
Associate with a Coordinator that operates on any wireless channel, or
only with a Coordinator on the same channel.
l
Block any association attempts, or try to associate with a Coordinator until
it can form an association with one. In other words, continue to try to associate indefinitely.
l
Ask the associated Coordinator for any pending information the End
device should receive after it comes out of a sleep mode, or do not ask for
any information upon awaking.

Introduction

185

In this experiment, you will set up one Coordinator module that will:
l
Find an unused wireless channel, and
l
Let any End device associate with it.
You will set up one or more End-device modules that will:
l
Associate with a Coordinator on any channel, and
l
Attempt to associate with a Coordinator indefinitely.
The Coordinator will remain attached to your host PC via the USB-to-XBee
adapter and USB cable, and you will communicate with the Coordinator via
the X-CTU software. The End-device module or modules will operate on their
own. I used four XBee modules in the following steps: three modules operated
as End devices and one served as the Coordinator. The Coordinator and End
modules require different configuration steps.
In the following steps, remember that modules called a Coordinator or an
End device remain standard XBee modules. You simply configure them for specific functions, and you can always reconfigure with the factory-supplied settings.
Step 1. End Module or Modules: If you don’t know the configuration of
your XBee module, I recommend you restore it with the factory-default values. Within the X-CTU window, click on the Modem Configuration tab and
in turn place each module in the USB-to-XBee adapter and click on Restore
under the Modem Parameters and Firmware heading. You will find the Modem
Configuration profile for the End-device modules in the file EX19_End.pro.
Place one of your designated End-device XBee modules in the USB-toXBee adapter and use the X-CTU software to Read its Modem Configuration
information.
l
Under the heading, Networking & Security, go to the MY – 16-Bit Source
Address. If no address exists, or if it shows a zero, click on the label and
type in as many as four hexadecimal values. If a MY value exists, you can
use it as is or type in a new Source Address.
l
Ensure you have a value of 0 for CE – Coordinator Enable and a value of
0x1FFE for SC – Scan Channels.
l
For the A1 – End Device Association, select the setting 6 – 0110B, where
the B stands for binary. This setting establishes the conditions: associate with a Coordinator on any channel, and attempt to associate with a
Coordinator indefinitely.
l
Move down to the last item under the Networking & Security heading:
NI – Node Identifier and click on this label. Next, click on the Set button that
appears to the right of this label and type in a name for the module. You can
use as many as 20 characters, but I recommend you use only four or five.
l
Look under the Serial Interfacing heading for the label, AP – API Enable,
and click on it. Choose 1 – API ENABLED.
l
In Table 19.1, write the name (NI) of each End-device module and its MY,
SH, and SL information. You will need this information later so you can
compare it with responses from your modules.
l
Finally, click on Write to save this configuration in the End-device module.
This step enables the API interface on your modules, gives it a name you

186

How to Set Up a Small XBee Network

Table 19.1 End-Device Module Information
End-Device 1

End-Device 2

End-Device 3

MY – 16-Bit Address
NI – Node Identifier
SH – Serial Number High
SL – Serial Number Low
Note: End-device modules 2 and 3 are optional.

can recognize, and sets it as an End device. (I named my three End-device
modules XMTR, PRO, and END.)
Repeat Step 1 for each XBee module you will use as an End device and set
aside these modules.
Step 2. Coordinator Module: Place the XBee module designated as your
Coordinator in the USB-to-XBee adapter and use the X-CTU software to Read
its Modem Configuration information. You will find the Modem Configuration
profile for the Coordinator modules in the file EX19_Coord.pro.
l
Under the heading, Networking & Security, go to the MY – 16-Bit Source
Address. If no address exists, or if it shows a zero, click on the label and
type in as many as four hex values. If a MY value exists, you can use it as
is or type in a new Source Address.
l
Ensure you have a value of 0x1FFE for SC – Scan Channels.
l
In the line labeled CE – Coordinator Enable, select 1 – COORDINATOR
which lets the Coordinator find an unused wireless channel, and lets any
End device associate with it.
l
For the A2 – Coordinator Association setting, select 6 – 110B, where the
B stands for binary. This setting establishes the conditions: find an unused
wireless channel and let any End device associate with this Coordinator.
l
Move down to the last item under the Networking & Security heading:
NI – Node Identifier and click on this label. Next, click on the Set button
that appears to the right of this label and type in a name for the module. You
can use as many as 20 characters, but I recommend you use four or five.
l
Look under the Serial Interfacing heading for the label, AP – API Enable,
and click on it. Choose 1 – API ENABLED.
l
Finally, click on Write to save this configuration in the attached module. This
step enables the API interface on your modules, gives it a name you can recognize, and sets it as an End device. (I gave my Coordinator the name RCVR.)
Step 3. Leave the Coordinator module in the USB-to-XBee adapter. Place
the End-device module or modules in separate XBee adapters on the same or
separate breadboards. I recommend placing no more than two XBee modules
and adapters in one solderless breadboard.

Introduction

187

Top View
+3.3 V

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

DIO5 – Associate

LED

330 ohms

GND

FIGURE 19.2 Power, ground, and LED connections for each XBee module used as an
End device.

Each End-device module requires only power, ground, and an LED connection as shown in Figure 19.2. Make these connections now. The LED serves
as an Association indicator to let you know an End-device module has properly
associated with a Coordinator. You should not have any other connections on
End-device modules at this time.
Note: An End-device XBee module does not require an Associate LED.
It simply serves as a visual indicator for testing and debugging. Because an
LED consumes power, you might eliminate it in battery-powered End devices.
If you don’t need the Association LED, you can use the DIO5 pin for analog
inputs or digital I/O signals.
Step 4. Ensure you have the Coordinator module connected to your host
PC via a USB cable. Start the X-CTU program. Go to the X-CTU PC Settings
window and click the Test/Query button to ensure you have an active communication link with your Coordinator module.
Step 5. Turn on power to your End-device modules. Each LED should turn
on and stay on. After about three seconds, the LEDs should start to flash. One
End-device module will start to flash its LED first because it associated with
the Coordinator first. The LED on each associated End-device module will
continue to flash for as long as you have the module powered.
If an End-device module LED does not turn on when you apply power,
recheck your connections and the polarity of the LED. If after five or six seconds
the LED still does not flash, recheck the module’s Modem Configuration settings.
Also check to ensure you are not “off by one pin” when you inserted the module
in the breadboard adapter and that you did not plug in a module backwards.
Step 6. Go to the X-CTU Terminal window and clear the screen. If the
hexadecimal column is open, you may close it. Type in the  characters
and wait for the OK reply from the Coordinator attached to your host PC.

188

How to Set Up a Small XBee Network

Type in ATND[Enter], which you used in Experiment 18 to perform a nodediscovery operation. You should see information for each associated End-device
module. In my Terminal window, I saw the information shown next:
+++OK
ATND
FFFE

FFFE

FFFE

13A200

13A200

13A200

4049E0EC

4049E1E6

406AF5AB

2C

26

4B

XMTR

END

PRO

Your results should look similar, depending on how many End-device
XBee modules you set up. The results for one End device indicate:
FFFE

MY – 16-Bit Source Address

13A200

SH – Serial Number High

4049E0EC

SL – Serial Number Low

2C

DB – Received Signal Strength

XMTR

NI – Node Identifier

The 0xFFFE value for the 16-bit source address (MY) seems unexpected. You probably set the MY parameter to some other 2-byte value, such
as 0x89AB or 0x1234, and expected to see it instead of FFFE. According to
Digi’s manual for the XBee and XBee PRO modules:
When an End Device associates to a Coordinator, its MY parameter
is set to 0xFFFE to enable 64-bit addressing. The 64-bit address of
the module is stored as SH and SL parameters. To send a packet to a
specific module, the Destination Address (DLDH) on the sender must
match the Source Address (SLSH) of the desired receiver.
The 0xFFFE MY setting holds true for as long as you have an End device
associated with a Coordinator. If you later use the X-CTU program to read the
Modem Configuration information from an End-device module not associated with a network, you will find the original 16-bit MY value you set earlier
in Step 1. Thus, an MY setting of 0xFFFE represents a temporary value for
associated End-device modules.
Step 7. Clear the X-CTU Terminal window, click on Show Hex, and click
on Assemble Packet. In the Send Packet window, go to the space labeled
Display, click on HEX. Within the Send Packet window, type:
7E 00 04 08 52 4E 44 13

This set of hex values represents the API ND command packet used to discover
XBee modules. You can use this command to discover modules in a network, too.

Introduction

189

Check your typing and correct any errors. Then click on Send Data. What
do you observe in the X-CTU Terminal window? Figure 19.3 shows what I
observed for my three End-device modules, XMTR, PRO, and END.

FIGURE 19.3 Responses to an API ND command packet as seen in the X-CTU Terminal
window for two associated End devices. Boldface type helps separate the four response
packets.
~...RND.

7E 00 04 08 52 4E 44 13 7E 00 15 88

~...RND.....

52 4E 44 00 FF FE 00 13 A2 00 40 49

..@I..

E0 EC 40 58 4D 54 52 00 01 7E 00 14

@XMTR..

88 52 4E 44 00 FF FE 00 13 A2 00 40

~...RND.....

6A F5 AB 4B 50 52 4F 00 5B 7E 00 14

..@j..KPRO.

88 52 4E 44 00 FF FE 00 13 A2 00 40

[~...RND....

49 E1 E6 32 45 4E 44 00 88 7E 00 05

...

88 52 4E 44 00 93

@I..2END..
~...RND..

Step 8. Use the template that follows to separate bytes in one packet shown
in Figure 19.3 into useful information:
____________

= start byte

____________

= message length (number of bytes)

____________

= packet type (Remote AT Command Response)

____________

= frame identifier value (all experiments use this value)

____________

= command name (ND)

____________

= status byte

____________

= MY – 16-Bit Source Address

____________

= SH – Serial Number High

____________

= SL – Serial Number Low

____________

= signal strength

____________

= NI – Node Identifier

____________

= null value 0x00, identifies end of NI characters

____________

= checksum for this message

190

How to Set Up a Small XBee Network

The fourth message has a slightly different format that provides status
information from the Coordinator module.

WHY ASSOCIATE XBEE MODULES IN A NETWORK?
You might wonder, “If I can get the same information from remote modules by
using an API ND command packet, why go through the steps to form a nonbeacon network of modules?” By creating a network with many End devices
and one Coordinator you avoid problems that could disrupt module-to-module
communications.
A module configured as a Coordinator can perform an energy scan to
find an unused channel. Without this capability you would have to assign
each module to the same wireless channel and hope no nearby networks use
that channel. This sort of “keep-your-fingers-crossed” approach might work
in a lab, but many devices now operate within the same frequency span as
the XBee modules, so letting a Coordinator seek an open channel for a network provides a better result. Likewise, a Coordinator can find an unused
personal-area network (PAN) ID and use it to keep one network separate from
others nearby.
A non-beacon network of XBee modules also lets you “take attendance”
quickly to determine if specific End-device modules have associated with the
Coordinator. This technique uses a new command, DN – Destination Node.
Step 9. You should have written the NI – Node Identifier for one or more
End-device modules in Step 1, Table 19.1. Now you can use those End-device
module names to determine if they still exist in your network.
With your network powered and operating—the End-device LEDs should
continue to flash—go to the X-CTU Terminal window and clear the screen.
Now you will get ready to send the AT command ATDN[your_module_name_
here][Enter] to the Coordinator. You could send this command in an API
packet, but for now the stand-alone AT command will work.
Refer to Table 19.1 and write the names (NI – Node Identifier information)
of your End-device modules in the space below.

Again clear the X-CTU Terminal window and have the window set to display hex values. In the left-hand column, type  and wait for the OK
reply. Next, type ATDN followed immediately by the name you assigned one
of your End-device modules. (I typed ATDNXMTR[Enter].) Be sure to use the
same upper- or lower-case characters used as your End-device Node Identifier.

Why Associate XBee Modules in a Network?

191

When I performed this step, I saw:
+++OK
ATDNXMTR
OK

So I know the End-device module named XMTR still operates in the network, associated with my Coordinator module. Suppose you type the name
of a nonexistent End device after the ATDN. What would happen? Try it. You
should see something like:
+++OK
ATDNtest
ERROR

If you have a network with several End devices, you could write an MCU
program to transmit DN commands in an API packet with the names of End
devices to quickly ensure all expected End-device modules exist and can operate. Your program might use a table of Node Identifier names that it would
send to the Coordinator and then wait for a response of either OK or ERROR
for each name sent over the network. If the number of End-device modules
or their names change, you could use the ND – Node Discovery command to
determine the modules you now have in a network.
Step 10. A Coordinator module can provide information about the association process and status when sent an AI – Association Indication command.
See the Digi manual “XBee/XBee-PRO RF Modules” for complete information about all 20 responses an AI command could produce.
Within the X-CTU Terminal window, type  and wait for the OK
reply. Then, type: ATAI[Enter]. The result should display only a zero, 0, to
indicate a successful completion of the association between the Coordinator
and End-device modules.
Other responses include error messages and status information about locating a PAN, timing out of a scan for unused frequencies, and so on. When you
write software for a non-beacon network of several End-device modules, you
should include steps that issue an AI command and test for a returned value of
0 before the program proceeds. If the returned value does not equal zero, your
code should indicate the type of error or condition.
Step 11. Again issue an ATND command to the Coordinator module from
the X-CTU Terminal to ensure all your End-device modules remain in your
network. If they do not, remove power from the End-device modules, wait a
few seconds and reapply power. The modules should join the Coordinator’s
network and their Associated LED should flash.
Turn off power to one of your End-device modules. Wait a few seconds and
use the X-CTU Terminal window to send an ATND node-discover command to

192

How to Set Up a Small XBee Network

the Coordinator. You should see a response only from the powered End-device
module or modules.
Turn power on to the unpowered End-device module and watch its LED.
How long does it take for this End-device module to re-associate with the
Coordinator? I found it took four to five seconds with two other End-device
modules in my network. So if an End-device XBee module loses power and
has power restored, the XBee module quickly associates with the network
Coordinator. An End-device module in a network with many more modules
might take a bit longer to re-associate. Use the ATND command again to
ensure the Coordinator can discover all your End-device modules.
Step 12. Disconnect the Coordinator and USB-to-XBee adapter from
the USB cable to turn off the Coordinator. Did you notice any change at the
End-device LEDs? The LEDs will continue to flash as if they still belonged to
the Coordinator’s network. The LEDs on my three End-device modules still
flashed 30 minutes after I disconnected the Coordinator. As a result, I recommend using the Associated LED for testing, rather than rely on it for a true
indication of network association.
Re-connect the Coordinator and USB-to-XBee adapter to the USB cable
attached to your PC. Now you will use the X-CTU Terminal window to send
the Coordinator an ATND command. The X-CTU Terminal software has a
quirk or bug so it will not communicate with the Coordinator until you first
go to the PC Settings window and click on Test/Query. So do this now and
wait for message “Communication with modem..OK.” Then click on OK and
switch to the Terminal window.
Type  , wait for the OK reply, and type ATND[Enter]. What do
you observe? My Coordinator module simply replied with a 0x0D byte for a
“carriage return.” When you have powered End-device modules in a network
and the Coordinator loses power, it will not automatically re-associate with
the End-device modules. To force a re-association, you send the Coordinator
an FR – Force Reset command.
In the Terminal window, type  and wait for the OK reply. Then type
ATFR[Enter]. You should see an “OK” in the Terminal window along with two
packets in the hex window:
7E 00 02 8A 01 74 and 7E 00 02 8A 06 6F

The 0x8A byte indicates a modem-status response. In the first packet, the
0x01 byte signifies a watch-dog timer reset and in the second packet, the 0x06
indicates a “coordinator started” condition. Now if you type  and then
the ATND[Enter] sequence, you will find your End devices have re-associated
with the Coordinator.
You can reset an XBee module by placing its Reset pin at ground for at
least 200 nanoseconds. When I grounded the Reset pin my reset Coordinator
replied:
7E 00 02 8A 00 75 and 7E 00 02 8A 06 6F

Conclusion

193

In the first packet, the 0x8A and 0x00 bytes signify a hardware reset and
in the second packet, the 0x8A and 0x06 bytes indicate a “coordinator started”
condition. But after waiting for at least 15 seconds after grounding the Reset
pin and seeing the response above, sending the Coordinator an ATND command yielded mixed results. Most of the time the reset Coordinator replied
with 0x0D rather than the expected information from the End-device modules.
A Coordinator will likely lose power at some time, so I recommend an
attached microcontroller issue an ATFR command after it resets from power
loss and before your code tries to communicate with the Coordinator. It cannot
hurt to pulse the XBee module Reset pin, but send the ATFR command, too.
If you wish, you can send the Force Reset command in an API command
packet rather than as an AT command:
07 00 04 08 52 4E 44 0D

It shouldn’t take more than a few seconds for your End-device modules to
re-associate with the reset Coordinator.

CONCLUSION
In this experiment you learned how to configure a Coordinator module and one
or more End-device modules for use in a network. You saw how End-device
modules can quickly associate with a Coordinator and how you can obtain
information about the modules in a network. You also learned how to address
an End-device module by name and how to check the status of the network
association process. You saw the importance of using the Force Reset command
to re-establish a network when a Coordinator Module temporarily loses power.

Experiment | 20

Digital and Analog
Measurements in a
Network
REQUIREMENTS
2 or 3 XBee modules
1 or 2 XBee adapter boards
2 Solderless breadboards
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
1 Microcontroller with a serial port (Arduino Uno or ARM mbed)
1 5-V-to-3.3-V logic-conversion circuit or module (Arduino Uno only)
1 3.3-V-to-5-V logic-conversion circuit or module (Arduino Uno only)
1 10-kohm potentiometer
1 10-kohm, 1/4 watt, 10% resistor (brown-black-orange)
1 4700-ohm, 1/4 watt, 10% resistor (yellow-violet-red)
1 1000-ohm, 1/4 watt, 10% resistor (brown-black-red)
3 330-ohm, 1/4 watt, 10% resistors (orange-orange-brown)
3 LEDs
Terminal-emulation software such as HyperTerminal for Windows (ARM
mbed only)
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In previous experiments you learned how to use AT commands or API packets to communicate with XBee modules and you learned how to associate
modules in a small personal-area network (PAN). Those steps also showed
you how to obtain information about End-device modules in your network. In
this experiment, an MCU will issue a command to one or more End-device
195
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

196

Digital and Analog Measurements in a Network

modules in a network to obtain data from their analog and digital inputs. You
performed similar steps with individual XBee modules in Experiment 14.
This experiment designates one XBee module as a Coordinator and one
or more XBee modules as End devices. In my lab, I used the module named
RCVR as the Coordinator and three modules named XMTR, PRO, and END
as End devices. After you complete this experiment, you can go directly to
Experiment 21 with the same equipment setup, but you may turn off power
to your equipment. You can download the MCU code and XBee configuration files for this experiment at: http://www.elsevierdirect.com/companion.
jsp?ISBN=9780123914040.
At this point, you should know how to use the X-CTU program without
detailed instructions about what window to open, what control to click, and
so on. You also should know how to set up and use a terminal-emulation program that can display information received from an MCU module. I’ll provide
details only when necessary.
Step 1. End Module or Modules: If you don’t know the configuration of
your XBee module, I recommend you restore it with the factory-default values. Within the X-CTU window, click on the Modem Configuration tab and
in turn place each module in the USB-to-XBee adapter and click on Restore
under the Modem Parameters and Firmware heading. You will find the Modem
Configuration profile for the End-device modules in the file EX20_End.pro. If
you load the configuration file into an X-Bee module, you must change the
NI – Network Identifier information so you have a different “name” for each
module.
Place one of your designated End-device XBee modules in the USB-toXBee adapter and use the X-CTU software to Read its Modem Configuration
information.
l
Ensure you have a value of 0 for CE – Coordinator Enable and a value of
0x1FFE for SC – Scan Channels.
l
For the A1 – End Device Association, select the setting 6 – 0110B, where
the B stands for binary. This setting establishes the conditions: associate with a Coordinator on any channel, and attempt to associate with a
Coordinator indefinitely.
l
Move down to the last item under the Networking & Security heading: NI
– Node Identifier and click on this label. Next, click on the Set button that
appears to the right of this label and type in a name for the module. You
can use as many as 20 characters, but I recommend you use only four or
five.
l
Look under the Serial Interfacing heading for the label, AP – API Enable,
and click on it. Choose 1 – API ENABLED.
l
In Table 20.1, write the name (NI) of each End-device module and its SH,
and SL information. You will need this information later so you can compare it with responses from these modules and modify settings in the MCU
software.

Introduction

197

Table 20.1 Information for Your End-Device Modules
Module 1

Module 2

Module 3

NI – Node Identifier
SH – Serial Number High
SL – Serial Number Low
Note: Modules 2 and 3 optional.

Double check your Modem Configuration settings with those shown here:
CE – Coordinator Enable	  0
SC – Scan Channels	  0x1FFE
NI – Node Identifier	  your choice of 3 or 4 characters
AP – API Enable	  1 – API ENABLED
A1 – End Device Association	  6 – 0110B
RN – Random Delay Slots	  2
DO NOT click Write.
l
Move down to the section labeled I/O Settings and change your End-device
module settings to match the ones below. DO NOT change the settings for
D7 or D5. DO NOT change any other settings.
D3 – DIO3 Configuration 2 – ADC Analog-to-digital converter
D2 – DIO2 Configuration 3 – DI
Digital input
D1 – DIO1 Configuration 2 – ADC Analog-to-digital converter
D0 – DIO0 Configuration 3 – DI
Digital input
Double check your DIO settings.
l
Finally, click on Write to save this configuration in the attached module.
This step enables the API interface on your modules, gives it a name you
can recognize, sets it as an End device, and enables four I/O pins as inputs.
Set aside this End-device module to keep it separate from the Coordinator
XBee module configured in the next steps.
Repeat Step 1 for each XBee module you will use as an End device and set
aside these modules.
Step 2. Coordinator Module: Place the XBee module designated as your
Coordinator in the USB-to-XBee adapter and use the X-CTU software to Read
its Modem Configuration information. You will find the Modem Configuration
profile for the Coordinator modules in the file EX20_Coord.pro.
l
Under the heading Networking & Security, go to the MY – 16-Bit Source
Address. Type in as many as four hexadecimal values.
l
Ensure you have a value of 0x1FFE for SC – Scan Channels.
l
In the line labeled CE – Coordinator Enable, select 1 – COORDINATOR
which lets the Coordinator find an unused wireless channel, and lets any
End device associate with it.

198

Digital and Analog Measurements in a Network
+3.3 V
Top View

+3.3 V

1
2
3
4
5 XBee
6
7
8
9
10

XB24

20
19
18
17
16
15
14
13
12
11

DIO0
DIO1
DIO2
DIO3
DIO5
V REF

+3.3 V

10 K
+3.3 V

GND

4700

10 K
+3.3 V
Associate
LED
330

GND

FIGURE 20.1 Circuitry needed to provide an End-device module with two digital and two
analog inputs.

For the A2 – Coordinator Association setting, select 6 – 110B, where the
B stands for binary. This setting establishes the conditions: find an unused
wireless channel and let any End device associate with this Coordinator.
l
Move down to the last item under the Networking & Security heading: NI –
Node Identifier and click on this label. Next, click on the Set button that
appears to the right of this label and type in a name for the module. You can
use as many as 20 characters, but I recommend you use four or five.
l
Look under the Serial Interfacing heading for the label, AP – API Enable,
and click on it. Choose 1 – API ENABLED.
l
Finally, click on Write to save this configuration in the attached module.
This step enables the API interface on your modules, gives it a name you
can recognize, and sets it as an End device. (I gave my Coordinator the
name RCVR.)
Leave the Coordinator module in the USB-to-XBee adapter connected to
your PC.
Step 3. Place one of your End-device modules in an XBee adapter on your
solderless breadboard and add the components shown in Figure 20.1. If the
module has any other components or wires attached to it, please remove them
now. The two digital inputs and two analog inputs provide information this
End-device module will transmit to the Coordinator module.
Step 4. If you have configured more than one End-device module, ensure
you have turned off power to your breadboard and place the second Enddevice module in an XBee adapter and insert it into your solderless breadboard. Connect the LED-and-resistor circuit at this module’s DIO5 – Associate
pin (pin 15) as shown in Figure 20.2. Then add the other connections to ground
and 3.3 volts as shown in the same figure. If this XBee adapter has any other
components or wires connected to it, remove them now. If you have more
than two End-device modules, I recommend you place additional End-device
modules in separate solderless breadboards.
l

Introduction

199

Top View
+3.3V

1
2
3
4
5 XBee
6
7
8
9
10

XB24

20
19
18
17
16
15
14
13
12
11

DIO0
DIO1
DIO2
DIO3
DIO5
V REF

+3.3 V
+3.3 V

+3.3 V
Associate
LED
330

GND

FIGURE 20.2 Minimum added circuitry for a second, or other End-device modules.

Step 5. After you have set up the circuitry shown in Figure 20.1—and in
Figure 20.2 for additional End-device modules—turn on power to these modules. The End-device XBee module or modules should associate with the
Coordinator attached to your PC, and the LED at each End-device module
should flash to indicate proper network association. Use the X-CTU Terminal
window to send an ATND command to the Coordinator to ensure it can discover all End-device modules, which should respond with their addresses.
Remember these hexadecimal addresses do not include leading zeros.
Step 6. The set of XBee commands includes IS – Force Sample, which causes
an XBee module to immediately reply with information from all enabled digital
I/O lines and 10-bit analog-measurement values. So I thought use of the IS command in a broadcast API packet would force all End-device modules to immediately respond with their analog and digital information from their I/O pins. But
based on experiments I performed, and duplicated by people at Digi International,
the IS command does not behave this way. Thus we must address individual Enddevice modules with their serial number, or 64-bit (8-byte) address.
Use the X-CTU Terminal to send an API command packet for the IS –
Force Sample command to one of your End-device modules identified by its
64-bit address. My End-device module named XMTR has the serial number
SH  0x0013A200 and SL  0x4049E0EC, so I used the following packet.
The underlined bytes represent the address of the XMTR module I want to
execute the IS command:
7E 00 0F 17 52 00 13 A2 00 40 49 E0 EC FF FE 02 49 53 FD

I inserted the address as shown and calculated the checksum to end the
packet. The following information from past experiments will refresh your
knowledge of the API command packet format:
7E

= start byte

000F

= 15 bytes in the message

200

Digital and Analog Measurements in a Network

17

= Remote AT Command Request byte

52

= frame identifier value (all experiments use this value)

0013A2004049E0EC

= 64-bit End-device address

FFFE

= value needed to force 64-bit addressing above

02

= value that causes immediate actions

49

= hex code for letter I

53

= hex code for letter S

FD

= checksum

The response packet from my End-device module appeared in the following familiar format:
7E 00 18 97 52 00 13 A2 00 40 49 E0 EC FF FE 49 53 00 01 14 05
00 01 01 47 03 FF 0E

This packet breaks down as follows:
7E

= start byte

0018

= message length (24 bytes)

97

= packet type (Remote Command Response)

52

= frame-identifier byte (52 for all experiments)

0013A2004049E0EC

= 64-bit address of responding module

FFFE

= 16-bit value set for 64-bit addressing

49

= hex code for letter I

53

= hex code for numeral S

00

= status byte

01

= number of samples of digital and analog data

14

= first Active-Signal Byte, AD3 and AD1 active

05

= second Active-Signal Byte, DIO2 and DIO0 active

00

= first Digital-Data Byte

01

= second Digital-Data Byte, DIO2 = 0, DIO0 = 1

0147

= hex value from AD1 ADC

03FF

= hex value from AD3 ADC

0E

= checksum for this message

Introduction

201

Step 7. You do not want to manually configure a network and obtain 64-bit
addresses from each End-device module before someone installs them. That
would take a lot of work and someone might inadvertently include errors in
the list of hexadecimal addresses. You can automate the process. In this experiment you will see how to automate collection of the analog and digital information. In the next experiment you will learn how to discover modules when
you don’t know how many exist in a network.
In Experiment 18 you learned how a microcontroller (MCU) attached to a
Coordinator can transmit an ND – Node Discovery command and obtain 64-bit
module addresses and node-identifier information from all associated End
devices. Once an MCU attached to a Coordinator has the 64-bit addresses for
End-device modules it can send commands to specific modules. This experiment will use software to send an API command packet for the IS command.
The software will include a standard packet for the IS command, into which
it inserts the address for an End-device module. The length of the message
will remain constant because all End-device modules have 64-bit, or 8-byte,
addresses. Thus, the template for the IS API command packet looks like:
7E 00 0F 17 52

FF FE 02 49 53 ??

The blank spaces leave openings for the eight bytes of an End-device
module address, with the most-significant address byte first (left) and the
least-significant byte last (right). The template cannot include the checksum,
because it will change based on the address values. But the software will
calculate the checksum as the MCU transmits the packet bytes. Then it will
append the checksum byte at the end of the packet. Remember, the checksum
does not add the packet-start byte 0x7E or the following two bytes that indicate
message length. And, obviously, it cannot add itself.
The people at Digi International told me it’s unlikely the SH, 0x0013A200,
portion of XBee module addresses (or identification number) will ever change
because the remaining four address bytes provide for as many as 4.3 billion
addresses, which cover many XBee modules. So you can simplify the template
and include the four SH address bytes right from the start. Then the software
need insert only the four SL address bytes and the checksum. The program
in this experiment uses the simplified format with the four SL address bytes
shown as blank spaces below:
7E 00 0F 17 52 00 13 A2 00

FF FE 02 49 53 ??

Step 8. To keep the software simple, you will enter the SH, SL and NI
information for each End-device module you plan to communicate with into an
array of bytes rather than use an ND API command packet to gather that information from End-device modules. This simulation approach simplifies testing
the code. Programmers take a similar approach and simulate information that
lets them test programs before they connect MCUs to real hardware. It costs
less to test furnace-control software with data that simulates furnace behavior
than to connect the MCU to the furnace and have a software bug blow it up!

202

Digital and Analog Measurements in a Network
1. Transmit first part of IS API packet
2. Transmit 4-byte SL address
3. Transmit last part of IS API packet
4. Transmit calculated checksum

Put response from addressed
End-device module in the dataIS array

No

All End-device
modules done?

Yes
Print raw End-device data

No

All End-device
modules done?

Yes

See Fig. 20.4

FIGURE 20.3 The flow chart for the software in this experiment shows how a program
requests analog and digital data from each End-device module in your personal-area
network. The program listing provides details.

The flow charts in Figures 20.3 and 20.4 show how the program works,
but they do not include details such as all the declarations of variables and
arrays or the SerialInput routine. You can read the comments in the complete
listing for the Arduino Uno or ARM mbed boards to better understand that
information. The software first transmits an IS API command packet to the first
End-device identified in the dataND array entry. After it transmits the packet,
the MCU waits for a response and saves it in another array named dataIS.
As soon as the software has received responses from all identified End-device
modules it prints the raw End-device data as hexadecimal values and checks
that data for any errors. If it detects an error, it prints an error message and

Introduction

203

Start with first
XBee End device

No

More XBee
Responses?

Yes

Byte[0] = 0×97?

No

Error-handling code
Incorrect message-start byte

No

Error-handling code
Incorrect UART data-frame

Yes
while(1)
Program ends

Byte[1] = 0×52?

Yes

Byte[14] ! = 0?

Yes

Error-handling code
1 = Error
2 = Invalid command
3 = Invalid parameter
4 = No response

No

Byte[15] = 1

No

Error-handling code
More than one sample

Yes
Print state of D0 input
Print state of D2 input
Print value for ADC1 input
Print voltage for ADC1 input
Print value for ADC3
Print voltage for ADC3

FIGURE 20.4 This flow chart shows the error-checking steps performed in the software
for this experiment.

goes on to the next module’s data. The flow chart in Figure 20.4 shows the
error-checking steps.
If data for an End device comes through error free, which it almost always
does, the program goes through each End-device module’s data and extracts
the information for the digital D0 and D2 inputs and the two analog inputs on
each module. The formatted results look like:
XBee Module: XMTR
D0  Logic 0
D2  Logic 1

204

Digital and Analog Measurements in a Network

A1 Value  335
A1 Voltage  1.08
A3 Value  810
A3 Voltage  2.61
Important Note: If you send an IS (Force Sample) command to a module
with no active I/O pins, that module indicates an error in its status byte in the
reply to the network Coordinator.
The code for each MCU addresses specific elements in the dataIS array
to obtain information received from each End-device module. Thus, the location dataIS[x][15] points to the number of I/O data samples in the packet
and dataIS[x][14] refers to the status byte received from a module. The
arrangement of bytes conforms to the structure shown prior to Step 7 in this
experiment.
Step 8. Now you will add a microcontroller to your network to control the
Coordinator. The following sections use an ARM mbed module or an Arduino
Uno module.

USING AN ARM MBED MODULE
Turn off power to the breadboard and leave the End-device module with the
resistors and potentiometer attached to it in the breadboard (see Figure 20.1).
Remove the Coordinator module from the USB-to-XBee adapter, and set it
aside.
If you have a second End-device module in your breadboard, remove it,
and set it aside. If you do not have a second adapter socket in your breadboard,
insert one and add the LED and resistor shown in Figure 20.5. Make the power
(pin 1) and ground (pin 10) connections to the second adapter. If this adapter
has any other connections, please remove them now. Connect the ARM mbed
module to this adapter and insert the Coordinator module.
+3.3 V
Top View
To mbed Module
Pin 10 (Rx)

DOUT
DIN

To mbed Module
Pin 9 (Tx)

To mbed Module
Pin 1 (GND)

1
2
3
4
5 XBee
6
7
8
9
10

XB24

20
19
18
17
16
15
14
13
12
11

DIO5
Associate
LED
330

GND

FIGURE 20.5 Circuit for the XBee module used in a breadboard as the Coordinator with
an ARM mbed module.

Using an ARM mbed Module

205

If you have set aside a second End-device module, you can place it in
another breadboard and add the connections shown earlier in Figure 20.2.
You also could place an additional End-device module in the USB-to-XBee
adapter. This XBee module would obtain power through the USB cable, but it
will not communicate with the PC.
The photograph in Figure 20.6 shows a typical setup of a Coordinator and
an End-device module. In my lab, I had additional End-device modules powered by two D-size dry cells on tables several meters from the Coordinator.
The program used for the ARM mbed will print the raw data as received by
the MCU from End-device modules followed by formatted data about the digital and analog signals. If you do not want to see the raw hexadecimal information, “comment out” or remove this section of code.
Important: The code for this experiment assumes you have three (3) Enddevice modules. If you have a different number, change the boldface value in
the statement below to indicate the proper number of End-device modules you
will use in this experiment:
//Define number of modules here as a constant
const int numb_of_modules = 3;

Important: The code also assumed a 3.3-volt reference for the analog-todigital converter in the End-device module wires as shown in Figure 20.1. If
you use a different external voltage reference, say 2.5 volts, change the Vref
declaration in the code to your reference voltage:
//define ADC reference -voltage input
float Vref = 3.3;

FIGURE 20.6 This image shows the arrangement of the End-device and Coordinator
modules in a solderless breadboard.

206

Digital and Analog Measurements in a Network

In the array declaration that follows you enter the SH and SL address information (underlined) and the NI bytes (highlighted) for each End-device module. For a long NI “name,” add bytes as needed for additional ASCII character
values in hexadecimal format. Just ensure you end the group of NI bytes with
a null, 0x00. My NI names in the dataND declaration correspond to XMTR,
PRO, and END (see Table 20.1).
//Set up array with End -device 64-bit address starting at
dataND[ ][7]
//remember, dataND[ ][ ] array starts with dataND[0]
char dataND[3][dataNDlength] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE0, 0xEC , 0x00, 0x58,
0x4D, 0x54, 0x52, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x6A, 0xF5, 0xAB , 0x00, 0x50,
0x52, 0x4F, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE1, 0xE6 , 0x00, 0x45,
0x4E, 0x44, 0x00, 0x00}
};

You will see the messages sent by the ARM mbed module on a terminalemulator program set for 9600 bits/second, 8 data bits, no parity, 1 stop bit (8N1),
and no flow control. You will not see anything in the X-CTU terminal window.
You can load the code shown in Program EX20_mbed_IS and run it. When
you compile the code you will get warning messages “Expression has no
effect” and “Expected a statement,” but you can ignore them. The program will
compile properly and you can download it to your ARM mbed module.
After the LED on the ARM mbed board stops flashing, start your terminal
emulator program and set it for 9600 bits/second, 8 data bits, no parity, 1 stop
bit, and no flow control. The terminal emulator uses the same USB cable
the compiler used to download the code. You can use the Windows Device
Manager to determine which virtual serial port the ARM mbed connects to.
Change your view so you can see the terminal emulator window.
Remember to turn on power to your Coordinator and End-device modules
in the breadboard. Press the reset button on the ARM mbed module to start the
EX20_mbed_IS program.

Using an ARM mbed Module

207

Program EX20_mbed_IS
/*
*
*
*
*
*
*
*
*
*/

EX20 ARM mbed Module Rev. F
Program EX20_mbed_IS
Send IS API command packet to Coordinator for each End -device
module identified in dataND array. Save information in dataIS array,
print raw results as hex data, and print formatted analog and
digital data on PC terminal emulator.
Output to LED on pin 13 indicates errors.
Jon Titus 09-04-2011 @ 1120H

#include "mbed.h"
//*************** Declarations & Assignments ***************
//Create start-of-API packet for IS command with this array of
//bytes.
//Byte count 0x0F does not include first 3 bytes or the checksum
//byte.
int packetIS_start[] = {0x7E, 0x00, 0x0F, 0x17, 0x52, 0x00, 0x13,
0xA2, 0x00};
int packetIS_start_len = 9;
//Create end-of-API packet for IS command
int packetIS_end[] = {0xFF, 0xFE, 0x02, 0x49, 0x53};
int packetIS_end_len = 5;
//Define number of modules here as a constant
const int numb_of_modules = 3;
//Define number of bytes in arrays as constants
const int dataISlength = 40;
const int dataNDlength = 40;
//Set up array with End-device 64-bit address starting at
//dataND[x][7]
//remember, dataND[] array starts with dataND[x][0]
//array definitions require a constant value
char dataND[numb_of_modules][dataNDlength] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE0,
0xEC, 0x00, 0x58, 0x4D, 0x54, 0x52, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x6A, 0xF5,
0xAB, 0x00, 0x50, 0x52, 0x4F, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE1,
0xE6, 0x00, 0x45, 0x4E, 0x44, 0x00, 0x00}
};
//Create an array for the response from each End-device module
char dataIS[numb_of_modules][dataISlength];
//Define bit masks for expected digital bits at DIO0 and DIO 2 pins
int D0_mask = 0x01;
// 00000001
int D2_mask = 0x04;
// 00000100
//Define ADC reference-voltage input, change as needed.
float Vref = 3.3;

208

Digital and Analog Measurements in a Network

//Define serial I/O ports: "Sport" for Coordinator, "pc" for
//terminal emulator at your PC
Serial Sport(p9, p10);
Serial pc(USBTX, USBRX);
//Define digital-output pin for optional "error" LED
DigitalOut LedPin(p13);
//Define
int
int
int
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
int
float
int

additional temporary variables
XBee_numb;
testdata;
MSbits, LSbits;
int
bytecount_hi;
int
bytecount_lo;
int
bytecount;
int
counter;
int
chksum;
int
chksum_temp;
analog_temp;
analog_voltage;
NIcounter;

//*************** Serial-Input Routine ***************
//Function SerialInput reads UART after it has new data
int SerialInput()
{
while (Sport.readable() == 0) //wait for UART to have new data
{
}
return (Sport.getc());
//get new data, return
}
//*************** Main Program ***************
int main(void)
{
//Send IS command to each End-device module and get results
XBee_numb = 0;
for (XBee_numb; XBee_numb < numb_of_modules; XBee_numb++)
{
//Transmit IS packet with 64-bit address
chksum = 0;
//Start with array counter = 0
counter = 0;
//Transmit the start-of-API packet bytes and calculate checksum
//only on the message portion of the packet. Do not compute
//checksum on first three bytes--0x7E and byte count
while(counter < packetIS_start_len)
{
Sport.putc(packetIS_start[counter]);
if (counter > 2)
//Start checksum only after
{
//first three packet bytes sent
chksum = chksum + packetIS_start[counter];
}
counter++;
}

Using an ARM mbed Module

209

//Transmit 64-bit (8-byte) address from dataND[] array
//start at byte 11 in the dataND[ ][ ] array.
counter = 11;
while (counter < 15 )
{
Sport.putc(dataND[XBee_numb][counter]);
chksum = chksum + dataND[XBee_numb][counter];
counter++;
}
//Transmit the end-of-API packet, reset counter for
//packetIS_end array
counter = 0;
while (counter < packetIS_end_len)
{
Sport.putc(packetIS_end[counter]);
chksum = chksum + packetIS_end[counter];
counter++;
}
//Calculate checksum and send it
//AND operator (&) saves only eight least-significant
//bits for the subtraction
Sport.putc(0xFF - (chksum & 0xFF));

}

//Get responses from End-device modules via mbed serial port
testdata = SerialInput();
if (testdata == 0x7E);
//first serial byte == 0x7E?
{
//yes
bytecount_hi = SerialInput();
bytecount_lo = SerialInput();
bytecount = (bytecount_hi * 256) + bytecount_lo;
//get # of bytes in msg
chksum_temp = 0;
//clear checksum value
for (counter = 0; counter < bytecount; counter++)
//put XBee data in array
{
dataIS[XBee_numb][counter] = SerialInput();
chksum_temp = chksum_temp + dataIS[XBee_numb][counter];
}
chksum = SerialInput();
//get checksum--last byte
if (chksum != (0xFF - (chksum_temp & 0xFF)))
//do checksums match?
{
while(1)
//NO MATCH, flash LED forever
{
//Error handling code could go
LedPin = 0;
//here instead. For now
wait(1);
//flash an LED
LedPin = 1;
wait(0.5);
}
}
}
//YES MATCH, do it for next module

wait(0.5);

//OK, got data for all XBee modules
//half-second delay

210

Digital and Analog Measurements in a Network

//Routine to print data in each XBee array as hex characters
//Data goes to PC terminal emulator
XBee_numb = 0;
//print raw hexadecimal data in this loop, from here...
for (XBee_numb; XBee_numb < numb_of_modules; XBee_numb++)
{
pc.printf("\n\r");
for (counter = 0; counter < dataISlength; counter++)
{
pc.printf("%02X ", dataIS[XBee_numb][counter]);
}
pc.printf("\n\r");
//go to a new line in text window
}
//to here.
//Process analog and digital data from each End-device module.
//First, check for transmission errors
for (XBee_numb = 0; XBee_numb < numb_of_modules; XBee_numb++)
{
if (dataIS[XBee_numb][0] != 0x97)
{
//error routine here--wrong response to remote API command
pc.printf("Incorrect API identifier for module
# %d \n\r\n\r", XBee_numb);
goto error_exit;
}
if (dataIS[XBee_numb][1] != 0x52)
{
//error routine here --incorrect UART frame ID #, break out
pc.printf("Incorrect UART frame API identifier for module
# %d \n\r\n\r", XBee_numb);
goto error_exit;
}
if (dataIS[XBee_numb][14] != 0)
{
pc.printf("Error %d for module
#: %d\n\r\n\r",dataIS[XBee_numb][14], XBee_numb);
goto error_exit;
}
if (dataIS[XBee_numb][15] != 1)
{
//handle sample error here, expected only 1 sample
pc.printf("Incorrect sample number for module
# %d \n\r\n\r", XBee_numb);
goto error_exit;
}
//No errors, go ahead and process analog and digital data here
//NIcounter points to start of Node Identifier name
//in dataIS array, saved for each End-device module.
//Print "XBee Module:" followed by NI name
//Start with first byte of NI data in dataIS array
NIcounter = 16;
pc.printf("XBee Module: ");

Using an ARM mbed Module

211

while(dataND[XBee_numb][NIcounter] != 0x00)
//Print ASCII characters until null
{
pc.putc(dataND[XBee_numb][NIcounter]);
NIcounter++;
}
pc.printf("\n\r");
//Now print formatted digital information
//Test only bit D0 in digital-data bytes in dataIS array
if ((dataIS[XBee_numb][19] & D0_mask) > 0)
{
pc.printf("D0 = Logic 1\n\r");
}
else
{
pc.printf("D0 = Logic 0\n\r");
}
//Test only bit D2 in digital data byte
if ((dataIS[XBee_numb][19] & D2_mask) > 0)
{
pc.printf("D2 = Logic 1\n\r");
}
else
{
pc.printf("D2 = Logic 0\n\r");
}
//Expect 2 analog values per End-device module
//First input from AD1/DIO1 input pin
analog_temp = dataIS[XBee_numb][20] * 256;
analog_temp = dataIS[XBee_n umb][21] + analog_temp;
pc.printf("A1 Value: %d\n\r", analog_temp);
analog_voltage = analog_temp * Vref / 1024;
pc.printf("A1 Voltage: %.2f\n\r", analog_voltage);
//Second input from AD1/DIO1 input pin
analog_ temp = dataIS[XBee_numb][22] * 256;
analog_temp = dataIS[XBee_numb][23] + analog_temp;
pc.printf("A3 Value: %d\n\r", analog_temp);
analog_voltage = analog_temp * Vref / 1024;
pc.printf("A3 Voltage: %.2f\n\r", analog_voltag e);
//print two blank lines to separate information
pc.printf("\n\r\n\r");
error_exit:
}
while(1)
{
}
}

//program comes here after printing an error
//message for a given module
//end program in an infinite do-nothing
//loop
//main() program ends here

After you run the program and see the formatted data, change the logic-inputs
from ground to 3.3 volts, and vice versa on an End-device module. Adjust the
potentiometer on your End-device module. You should see changes in the data.

212

Digital and Analog Measurements in a Network

Optional: Suppose weak batteries or a tripped circuit breaker causes one
of the End-device modules to go “off line.” How do you think the software will
react? You can disconnect power to one of your end-device modules and run
the software again. What happened?
The software still transmitted an IS API command packet to the “missing”
End-device module, which cannot respond. The software gets stuck in a loop
constantly waiting for that End-device module to respond. In the next experiment you will learn how to overcome that type of problem.
Optional: Turn off power to your modules and program one of your Enddevice modules so that you have disabled all of its AD/DIO pins, with the
exception of D7 (1 – CTS FLOW CONTROL) and D5 (1 – ASSOCIATED
INDICATOR). Put this End-device module back in its adapter and run the
ARM mbed program again. The newly programmed module will cause an
error because it has no I/O pins programmed. You should see an error message
in the terminal-emulator window, but without the NI name. You could add program steps to identify the End-device module by name.
This optional step shows the importance of having the software configured
to “look for” the same I/O configuration present in all End-device modules.
You might use the analog and digital active-signal bytes to determine which
digital and analog bits and bytes provide useful information, but that would
take a lot more software.
Suppose you need two digital inputs on one End-device module, one digital and two analog inputs on another, and finally two digital and two analog
inputs on a third. I recommend you simply configure all End-device modules
for two digital inputs and two analog inputs. You can simply ignore the information you don’t need. But all End-device modules have the same settings.
This approach also simplifies replacing modules in the field.

ARM mbed Troubleshooting
If End-device modules do not associate with a Coordinator, recheck the configurations you saved in the modules when you set them in Steps 1 and 2. Check
that you have power and ground properly connected to each XBee module in
your breadboard.
Check the wiring of your breadboard circuits as shown in Figures 20.1,
20.2, and 20.5.
Ensure you have set the SH, SL, and NI information properly for each Enddevice module. Any error in the address bytes will cause the program to stall
and you will see nothing happen. If you still have problems, recheck the first
End-device module entry in the dataND array. Set the numb_of_modules = 1
and try the program again. If you succeed, check the information for the
second module and increase the numb_of_modules value to 2.
If the LED at your End-device or Coordinator module does not turn on,
ensure you have it plugged in correctly. Try reversing the LED leads. They are
sensitive to the polarity of current flow.

Using an Arduino Uno Module

213

Check the configuration of the your terminal-emulator software to ensure
you have 8 data bits, 1 stop bit, no parity, and no flow control for 9600
bit/second transmissions. Do you have the emulator set for the proper COM
port? Have you told the emulator to connect to the ARM mbed computer via
a COM port? Remember, you want the emulator to communicate with the
ARM mbed module and not to any XBee module attached to the USB-toXBee adapter. Although an End-device module plugged into the USB-to-XBee
adapter receives only power from the adapter, your PC will still “see” the
adapter as a COM port.
You have reached the end of this experiment for the ARM mbed module.
If you plan to go immediately to Experiment 21, leave your hardware set up,
but you may turn off power to your equipment.

USING AN ARDUINO UNO MODULE
Turn off power to the breadboard and leave the End-device module with the
resistors and potentiometer attached to it in the breadboard (see Figure 20.1).
Remove the Coordinator module from the USB-to-XBee adapter, and set
it aside.
If you have a second End-device module in your breadboard, remove it,
and set it aside. If you do not have a second adapter socket in your breadboard, insert one and add the LED and resistor shown in Figure 20.7. Make
the power (pin 1) and ground (pin 10) connections, and connect the logiclevel-conversion circuits and the Arduino Uno module as shown. If you have
other connections to this adapter, please remove them and then insert the
Coordinator module.
If you have set aside a second End-device module, you can place it in
another breadboard and add the connections shown earlier in Figure 20.2.

LLC 3–to–5
To Arduino Uno Pin 0 (RX)

3

To Arduino Uno Pin 1 (TX)

2

+3.3 V
DOUT
DIN

21

LLC 5–to–3
DPDT Switch

3

21
1000

To Arduino POWER GROUND

Top View
1
20
2
19
3
18
4
17
5 XBee XB24 16
6
15
7
14
8
13
9
12
10
11

Associate
LED
330

GND
Logic – Level – Convertor (LLC) Connections:
Ground at pins 11, 12, 13, 22.
+5 volts at pin 1; +3.3 volts at pins 23, 24.
On LLC 5–to–3: 1000–ohm resistor between pins 1 and 2.
On LLC 3–to–5: ground pin 2.

FIGURE 20.7 Circuit for the XBee module used as the Coordinator with an Arduino Uno
module.

214

Digital and Analog Measurements in a Network

You also could insert an End-device module in the USB-to-XBee adapter. This
XBee module would obtain power through the USB cable, but it will not communicate with the PC.
Pay attention to the notes below and in Figure 20.7 that explain additional
connections not shown in Figure 20.7 for the sake of clarity:
l
On LLC 5-to-3, connect a 1000-ohm resistor (brown-black-red) between
pins 1 and 2.
l
On LLC 3-to-5, connect pin 2 to ground.
l
On both logic-level-converter devices, connect pins 11, 12, 13, and 22 to
ground.
l
On both logic-level-converter devices, connect pin 1 to 5 volts.
l
On both logic-level-converter devices, connect pins 23 and 24 to 3.3
volts.
The image in Figure 20.8 shows the arrangement of an End-device module,
a Coordinator module, and the logic-level-conversion circuits. In my lab,
I had additional End-device modules powered by two D-size dry cells on
tables several meters from the Coordinator.
The program used for the Arduino Uno will print the raw data as received
by the MCU from End-device modules followed by formatted data about the
digital and analog signals. If you do not want to see the hexadecimal information, “comment out” or remove this section of code.
Important: The code for this experiments assumes you have three (3)
End-device modules. If you have a different number, change the boldface value

FIGURE 20.8 End-device module (left), Coordinator module (right), and logic-levelconversion circuits (bottom) in solderless breadboards.

Using an Arduino Uno Module

215

in the statement below to indicate the proper number of End-device modules
you will use in this experiment:
//Define number of modules here as a constant
const int numb_of_modules = 3;

Important: The code also assumed a 3.3-volt reference for the analogto-digital converter in the End-device module wires as shown in Figure 20.1.
If you use a different external voltage reference, say 2.5 volts, change the Vref
declaration in the code to your reference voltage:
//define ADC reference -voltage input
float Vref = 3.3;

In the array declaration that follows enter the SH and SL address information (underlined) and the NI bytes (highlighted) for each End-device module.
For a long NI “name,” add bytes as needed for additional ASCII character values in hexadecimal format. Just ensure you end the group of NI bytes with
a null, 0x00. My NI names in the dataND declaration correspond to XMTR,
PRO, and END (see Table 20.1).
//Set up array with End -device 64-bit address starting at
dataND[ ][7]
//remember, dataND[ ][ ] array starts with dataND[0]
char dataND[3][dataND length] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE0, 0xEC , 0x00, 0x58,
0x4D, 0x54, 0x52, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x6A, 0xF5, 0xAB , 0x00, 0x50,
0x52, 0x4F, 0x00, 0x00},

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE1, 0xE6 , 0x00, 0x45,
0x4E, 0x44, 0x00, 0x00}
};

216

Digital and Analog Measurements in a Network

You will see the messages sent by the Arduino Uno in the Serial Monitor
window in the Arduino compiler. You will not see anything in the X-CTU
terminal window.
You can load the code shown in Program EX20_Uno_IS and run it.
Remember to turn on power to your Coordinator and End-device modules in
the breadboard. Ensure all circuits have a common ground. Press the reset button on the Arduino Uno module to start the EX20_Uno_IS program.
Important: As noted in other experiments, the Arduino Uno module
shares its UART with an XBee module and the host PC USB connection, so
maintaining the serial connection between a Uno module and an XBee module when downloading code can cause an electrical conflict. You MUST manually disconnect (or use a small switch to open) the two serial-port connections
between an Arduino Uno module and any external serial device while the compiler downloads code to the Uno. I used a small DPDT toggle switch to disconnect the signals between the logic-level-conversion circuits and the Arduino
Uno module during code downloads. Remember to reconnect these wires, or
flip the switch, before you run the program.

Program EX20_Uno_IS
/*
*
*
*
*
*
*
*
*
*/

EX20 Arduino Uno Module Rev. B
Program EX20_Uno_IS
Send IS API command packet to Coordinator for each End -device
module identified in dataND array. Save information in dataIS
array, print raw results as hex data, and print formatted
analog and digital data in Serial Monitor window.
Output to LED on pin 13 indicates errors.
Jon Titus 09-04-2011 @ 1120H

//*************** Declarations & Assignments ***************
//Create start-of-API packet for IS command with this array of
//bytes.
//Byte count 0x0F does not include first 3 bytes or the checksum
//byte.
byte packetIS_start[] = {0x7E, 0x00, 0x0F, 0x17, 0x52, 0x00, 0x13,
0xA2, 0x00};
int packetIS_start_len = 9;
//Create end-of-API packet for IS command
byte packetIS_end[] = {0xFF, 0xFE, 0x02, 0x49, 0x53};
int packetIS_end_len = 5;
//Define number of modules here as a constant
const int numb_of_modules = 3;
//Define number of bytes in arrays as constants
const int dataISlength = 40;
const int dataNDlength = 40;

Using an Arduino Uno Module

217

//Set up array with End-device 64-bit address starting at
//dataND[x][7]
//remember, dataND[] array starts with dataND[x][0]
//array definitions require a constant value
byte dataND[numb_of_modules][dataNDlength] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE0,
0xEC, 0x00, 0x58, 0x4D, 0x54, 0x52, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x6A, 0xF5,
0xAB, 0x00, 0x50, 0x52, 0x4F, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0xA2, 0x00, 0x40, 0x49, 0xE1,
0xE6, 0x00, 0x45, 0x4E, 0x44, 0x00, 0x00}
};
//Create an array for the response from each End-device module
byte dataIS[numb_of_modules][dataISlength];
//Define bit masks for expected digital bits at DIO0 and DIO2 pins
byte D0_mask = 0x01;
// 00000001
byte D2_mask = 0x04;
// 00000100
//Define ADC reference-voltage input, change as needed.
float Vref = 3.3;
//Define digital-output pin for optional "error" LED
int
LedPin = 13;
//Define
int
int
int
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
int
float
int

additional temporary variables
XBee_numb;
testdata;
MSbits, LSbits;
int
bytecount_hi;
int
bytecount_lo;
int
bytecount;
int
counter;
int
chksum;
int
chksum_temp;
analog_temp;
analog_voltage;
NIcounter;

//*************** Serial-Input Routine ***************
//Function SerialInput reads UART after it has new data
int SerialInput()
{
while (Serial.available() == 0)
//wait for UART to have new data
{
}
return (Serial.read());
//get new data, return
}
//*************** Setup Operations ***************
void setup()

218

Digital and Analog Measurements in a Network

{
Serial.begin(9600);
pinMode(LedPin, OUTPUT);
digitalWrite(LedPin, HIGH);
}
//*************** Main Loop ***************
void loop()
{
//Send IS command to each End-device module and get results
XBee_numb = 0;
for (XBee_numb; XBee_numb < numb_of_modules; XBee_numb++)
{
//Transmit IS packet with 64-bit address, clear checksum
chksum = 0;
//Start with array counter = 0
counter = 0;
//Transmit the start-of-API packet bytes and calculate
//checksum only on the message portion of the packet. Do not
//compute checksum on first three bytes--0x7E and byte count
while(counter < packetIS_start_len)
{
Serial.write(packetIS_start[counter]);
if (counter > 2)
//Start checksum only after
{
//first three packet bytes sent
chksum = chksum + packetIS_start[counter];
}
counter++;
}
//Transmit 64-bit (8-byte) address from dataND[] array
//start at byte 11 in the dataND[ ][ ] array.
counter = 11;
while (counter < 15 )
{
Serial.write(dataND[XBee_numb][counter]);
chksum = chksum + dataND[XBee_numb][counter];
counter++;
}
//Transmit the end-of-API packet, reset counter for
//packetIS_end array
counter = 0;
while (counter < packetIS_end_len)
{
Serial.write(packetIS_end[counter]);
chksum = chksum + packetIS_end[counter];
counter++;
}
//Calculate checksum and send it
//AND operator (&) saves only eight least-significant
//bits for the subtraction
Serial.write(0xFF - (chksum & 0xFF));

Using an Arduino Uno Module

219

//Get responses from End-device modules via mbed serial port
testdata = SerialInput();
if (testdata == 0x7E);
//first serial byte == 0x7E?
{
//yes
bytecount_hi = SerialInput();
bytecount_lo = SerialInput();
bytecount = (bytecount_hi * 256) + bytecount_lo;
//get # of bytes in msg
chksum_temp = 0;
//clear checksum value
for (counter = 0; counter < bytecount; counter++)
//put XBee data in array
{
dataIS[XBee_numb][counter] = SerialInput();
chksum_temp = chksum_temp + dataIS[XBee_numb][counter];
}
chksum = SerialInput();
//get checksum--last byte
if (chksum != (0xFF -(chksum_temp & 0xFF)))
//do checksums match?
{
while(1)
//NO MATCH, flash LED forever
{
//Error handling code could go
digitalWrite(LedPin, LOW);
//here instead. For now
delay(1000);
//flash an LED
digitalWrite(LedPin, HIGH);
delay(500);
}
}
}
//YES MATCH, do it for next module
}
delay(500);

//OK, got data for all XBee modules
//half-second delay

//Routine to print data in each XBee array as hex characters
//Data goes to PC terminal emulator
XBee_numb = 0;
//print raw hexadecimal data in this loop, from here...
for (XBee_numb; XBee_numb < numb_of_modules; XBee_numb++)
{
Serial.print("\n\r");
for (counter = 0; counter < dataISlength; counter++)
{
if (dataIS[XBee_numb][counter] < 0x10)
{
Serial.print("0");
}
//insert leading zero, if needed
Serial.print(dataIS[XBee_numb][counter], HEX);
Serial.print(" ");
}
Serial.print("\n\r");
//go to a new line in text window
}
//to here.
//Process analog and digital data from each End-device module.
//First, check for transmission errors

220

Digital and Analog Measurements in a Network

for (XBee_numb = 0; XBee_numb < numb_of_modules; XBee_numb++)
{
if (dataIS[XBee_numb][0] != 0x97)
{
//error routine here--wrong response to remote API
//command
Serial.print("Incorrect API identifier for module # ");
Serial.print(XBee_numb);
Serial.print("\n\r\n\r");
goto error_exit;
}
if (dataIS[XBee_numb][1] != 0x52)
{
//error routine here--incorrect UART frame ID #,
//break out
Serial.print("Incorrect UART frame API identifier for module # ");
Serial.print(XBee_numb);
Serial.print("\n\r\n\r");
goto error_exit;
}
if (dataIS[XBee_numb][14] != 0)
{
Serial.print("Error ");
Serial.print(dataIS[XBee_numb][14]);
Serial.print(" for module ");
Serial.print(XBee_numb);
Serial.print("\n\r\n\r");
goto error_exit;
}
if (dataIS[XBee_numb][15] != 1)
{
//handle sample error here, expected only 1 sample
Serial.print("Incorrect sample number for module # ");
Serial.print(XBee_numb);
Serial.print("\n\r\n\r");
goto error_exit;
}
//No errors, go ahead and process analog and digital
//data here
//NIcounter points to start of Node Identifier name
//in dataIS array, saved for each End-device module.
//Print "XBee Module:" followed by NI name
//Start with first byte of NI data in dataIS array
NIcounter = 16;
Serial.print("XBee Module: ");
while(dataND[XBee_numb][NIcounter] != 0x00)
//Print ASCII characters until null
{
Serial.write(dataND[XBee_numb][NIcounter]);
NIcounter++;
}
Serial.print("\n\r");
//Now print formatted digital information
//Test only bit D0 in digital-data bytes in dataIS array

Using an Arduino Uno Module

221

if ((dataIS[XBee_numb][19] & D0_mask) > 0)
{
Serial.print("D0 = Logic 1\n\r");
}
else
{
Serial.print("D0 = Logic 0\n\r");
}
//Test only bit D2 in digital data byte
if ((dataIS[XBee_numb][19] & D2_mask) > 0)
{
Serial.print("D2 = Logic 1\n\r");
}
else
{
Serial.print("D2 = Logic 0\n\r");
}
//Expect 2 analog values per End-device module
//First input from AD1/DIO1 input pin
analog_temp = dataIS[X Bee_numb][20] * 256;
analog_temp = dataIS[XBee_numb][21] + analog_temp;
Serial.print("A1 Value: ");
Serial.print(analog_temp);
Serial.print("\n\r");
analog_voltage = analog_temp * Vref / 1024;
Serial.print("A1 Voltage: ");
Serial.print(analog_voltage);
Serial.print("\n\r");
//Second input from AD1/DIO1 input pin
analog_temp = dataIS[XBee_numb][22] * 256;
analog_temp = dataIS[XBee_numb][23] + analog_temp;
Serial.print("A3 Value: ");
Serial.print(analog_temp);
Serial.print("\n\r");
analog_voltage = analog_temp * Vref / 1024;
Serial.print("A3 Voltage: ");
Serial.print(analog_voltage);
Serial.print("\n\r");
//print two blank lines to separate information
Serial.print("\n\r\n\r");
error_exit:
while(0) { }
//message for a given
}
while(1)
{
}

//program comes here after printing an error
//do-nothing statement to satisfy compiler
module

}

//main loop() ends here

//end program in an infinite do-nothing loop

After you run the program and see the formatted data, change the logicinputs at an End-device module from ground to 3.3 volts, and vice versa.
Adjust the potentiometer on your End-device module. You should see changes
in the data when you again run the EX20_Uno_IS program. Just press the
Arduino Uno reset pushbutton.

222

Digital and Analog Measurements in a Network

Optional: Suppose weak batteries or a tripped circuit breaker causes one
of the End-device modules to go “off line.” How do you think the software will
react? You can disconnect power to one of your end-device modules and run
the software again. What happened?
The software still transmitted an IS API command packet to the “missing”
End-device module, which cannot respond. The software gets stuck in a loop
constantly waiting for that End-device module to respond. In the next experiment you will learn how to overcome that type of problem.
Optional: Turn off power to your modules and reprogram one of your
End-device modules so you have disabled all of its AD/DIO pins, with the
exception of D7 (1 – CTS FLOW CONTROL) and D5 (1 – ASSOCIATED
INDICATOR). Put this End-device module back in its adapter and run the
Arduino Uno program again. The newly programmed module will cause an
error because it has no I/O pins programmed.
This optional step shows the importance of having the software configured to
“look for” the same I/O configuration present in the modules. You might use the
analog and digital active-signal bytes to determine which digital and analog bits
and bytes provide useful information, but that would take a lot more software.
Suppose you need two digital inputs on one End-device module, one digital and two analog inputs on another, and finally two digital and two analog
inputs on a third. I recommend you simply configure all End-device modules
for two digital inputs and two analog inputs. You can simply ignore the information you don’t need. But all End-device modules have the same settings.
This approach also simplifies replacing modules in the field.

Arduino Uno Troubleshooting
As noted earlier, you must disconnect connections from the Arduino Uno
module RX←0 and TX→1 to the logic-level-conversion circuits when
you compile and download a program. If you forget you might see an error
message in the compiler text window.
If End-device modules do not associate with a Coordinator, recheck the
configurations you saved in the modules when you set them in Steps 1 and
2. Check that you have power and ground properly connected to each XBee
module in your breadboard. All circuits must have a common ground.
Check the wiring of your breadboard circuits as shown in Figures 20.1,
20.2, and 20.7. Recheck the connections to the logic-level-conversion circuits.
It’s easy to mix up the receiver and transmitter signals.
If the LED at your End-device module does not turn on, ensure you have
it plugged in correctly. Try reversing the LED leads. They are sensitive to the
polarity of current flow.
You have reached the end of this experiment for the Arduino Uno module.
If you plan to go immediately to Experiment 21, leave your hardware set up,
but you may turn off power to your equipment.

Experiment | 21

How to Handle
an Unknown Number
of XBee Modules
REQUIREMENTS
2 or 3 XBee modules
2 or 3 XBee adapter boards
1 or 2 Solderless breadboards
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
1 Microcontroller with a serial port (ARM mbed or Arduino Uno)
1 5-V-to-3.3-V logic-conversion circuit or module (for Arduino Uno only)
1 3.3-V-to-5-V logic-conversion circuit or module (for Arduino Uno only)
3 LEDs
3 330-ohm, 1/4 watt, 10% resistors (orange-orange-brown)
1 4700-ohm, 1/4 watt, 10% resistor (yellow-violet-red)
1 10-kohm, 1/4 watt, 10% resistor (brown-black-orange)
1 10-kohm potentiometer
Terminal-emulation software such as HyperTerminal for Windows (for
ARM mbed)
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In Experiments 18, 19, and 20 you learned how to associate XBee modules in
a personal-area network (PAN), identify them, and obtain analog and digital
information from them. Previously you preset microcontroller (MCU) software to work with one or more End-device modules. But you might not always
know how many End-device modules a personal-area network (PAN) will
have. An MCU that expects a preset number of modules could get “stuck” in an
endless loop, waiting, waiting, and still waiting for information from modules
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

223

224

How to Handle an Unknown Number of XBee Modules

no longer in the PAN. Likewise, if new modules join the PAN, the MCU would
miss receiving their data because it expected data from only x number of modules and it could not account for the new members of the PAN.
This situation causes a problem: How long should the MCU wait for
responses from remote XBee modules before it goes on to other tasks? In this
experiment you will learn how to use an MCU timer, interrupt, and interruptservice routine (ISR). By using a timer, the MCU will wait sufficiently long for
all modules to respond without knowing how many exist. Later you will learn
about an alternate approach to this timing problem. The software in this experiment does not include a preset value for the number of modules in a PAN;
the MCU will determine that number. The software examples will run on an
Arduino Uno or on an ARM mbed module. The main differences center on the
use of a timer specific to each MCU.
You can download the MCU code and XBee configuration files for this experiment at: http://www.elsevierdirect.com/companion.jsp?ISBN=9780123914040.
If you have just completed Experiment 20 and have not changed your module configurations or circuits, skip ahead to Step 6. Otherwise, please continue
with Step 1.
Step 1. End-Device Module or Modules: If you don’t know the configuration of an XBee module, I recommend you restore it with the factory-default
values. Within the X-CTU window, click on the Modem Configuration tab and
in turn place each module in the USB-to-XBee adapter and click on Restore
under the Modem Parameters and Firmware heading. You will find the Modem
Configuration profile for the End-device modules in the file EX21_End.pro. If
you load the configuration file into an X-Bee module, you must change the
NI – Network Identifier information so you have a different “name” for each
module.
Place one of your designated End-device XBee modules in the USB-toXBee adapter and use the X-CTU software to Read its Modem Configuration
information.
l
Ensure you have a value of 0 for CE – Coordinator Enable and a value of
0x1FFE for SC – Scan Channels.
l
For the A1 – End Device Association, select the setting 6 – 0110B, where
the B stands for binary. This setting establishes the conditions: associate with a Coordinator on any channel, and attempt to associate with a
Coordinator indefinitely.
l
For the RN – Random Delay Slots, enter 2.
l
Move down to the last item under the Networking & Security heading:
NI – Node Identifier and click on this label. Next, click on the Set button
that appears to the right of this label and type in a name for the module.
You can use as many as 20 characters, but I recommend you use only four
or five.
l
Look under the Serial Interfacing heading for the label, AP – API Enable,
and click on it. Choose 1 – API ENABLED.

Introduction

225

Table 21.1 Information for Your End-Device Modules
End-Device 1

End-Device 2

End-Device 3

NI – Node Identifier
SH – Serial Number High
SL – Serial Number Low
Note: End-device modules 2 and 3 are optional.

Write the name (NI) of each End-device module and its SH, and SL
information in Table 21.1. You will need this information later so you can
compare it with responses from these modules.
Double check your Modem Configuration settings with those shown here:
CE – Coordinator Enable	  0
SC – Scan Channels	  0x1FFE
NI – Node Identifier	  your choice of 3 or 4 characters
AP – API Enable	  1 – API ENABLED
A1 – End Device Association	  6 – 0110B
RN – Random Delay Slots	  2
Do not click Write. (It’s OK if you did, though. Just continue.)
l
Move down to the section labeled I/O Settings and change your End-device
module settings to match the ones below. DO NOT change the settings for
D7 or D5 and DO NOT change any other settings.
D3 – DIO3 Configuration 2 – ADC Analog-to-digital converter
D2 – DIO2 Configuration 3 – DI
Digital input
D1 – DIO1 Configuration 2 – ADC Analog-to-digital converter
D0 – DIO0 Configuration 3 – DI
Digital input
Double check your DIO settings.
l
Finally, click on Write to save this configuration in the attached module.
This step enables the API interface on your modules, gives it a name you
can recognize, sets it as an End device, and enables four I/O pins as inputs.
Set aside this End-device module to keep it separate from the Coordinator
XBee module configured in the next steps.
Repeat Step 1 for each XBee module you will use as an End device and set
aside these modules.
Step 2. Coordinator Module: Place the XBee module designated as your
Coordinator in the USB-to-XBee adapter and use the X-CTU software to Read
its Modem Configuration information. You will find the Modem Configuration
profile for the Coordinator modules in the file EX21_Coord.pro.
l
Ensure you have a value of 0x1FFE for SC – Scan Channels.
l
In the line labeled CE – Coordinator Enable, select 1 – COORDINATOR
which lets the module serve as a Coordinator in a PAN.
l

226

How to Handle an Unknown Number of XBee Modules
+3.3 V
Top View

+3.3 V

1
2
3
4
XBee XB24
5
6
7
8
9
10

20
19
18
17
16
15
14
13
12
11

DIO0
DIO1
DIO2
DIO3
DIO5
V REF

10 K

+3.3 V
GND

+3.3 V

4700

10 K
+3.3 V
Associate
LED
330

GND

FIGURE 21.1 Circuitry needed to provide an End-device module with two digital and two
analog inputs.

For the A2 – Coordinator Association setting, select 6 – 110B, where the
B stands for binary. This setting establishes the conditions: find an unused
wireless channel and let any End device associate with this Coordinator.
l
Move down to the last item under the Networking & Security heading:
NI – Node Identifier and click on this label. Next, click on the Set button
that appears to the right of this label and type in a name for the module. You
can use as many as 20 characters, but I recommend you use four or five.
l
Look under the Serial Interfacing heading for the label, AP – API Enable,
and click on it. Choose 1 – API ENABLED.
l
Finally, click on Write to save this configuration in the attached module.
This step enables the API interface on your modules, gives it a name you
can recognize, and sets it as an End device. (I gave my Coordinator the
name RCVR.)
Leave the Coordinator module in the USB-to-XBee adapter connected to
your PC.
Step 3. Place one of your End-device modules in an XBee adapter on your
solderless breadboard and add the components shown in Figure 21.1. If the
module has any other components or wires attached to it, please remove them
now. The two digital inputs and two analog inputs provide information this
End-device module will transmit to the Coordinator module.
This experiment can use an LED and 330-ohm resistor at pin 13 on the
Arduino Uno or ARM mbed module as an optional status or error indicator.
This LED circuit is not necessary to complete the experiment, but you may add
it if you wish. (See Figure 18.6 for the LED-resistor circuit diagram.)
Step 4. If you have configured more than one End-device module, ensure you have turned off power to your breadboard and place the
second End-device module in an XBee adapter and insert it into your
l

Introduction

227

Top View
+3.3 V

1
2
3
4
XBee XB24
5
6
7
8
9
10

20
19
18
17
16
15
14
13
12
11

DIO0
DIO1
DIO2
DIO3
DIO5
V REF

+3.3 V
+3.3 V

+3.3 V
Associate
LED
330

GND

FIGURE 21.2 Minimum added circuitry for additional End-device modules.

solderless breadboard. Connect the LED-and-resistor circuit at this module’s
DIO5 – Associate pin (pin 15) as shown in Figure 21.2. Then add the other
connections to ground and 3.3 volts as shown in the same figure. If this
XBee adapter has any other components or wires connected to it, remove them
now. If you have more than two End-device modules, I recommend you place
additional End-device modules in separate solderless breadboards.
Step 5. After you have set up the circuitry shown in Figure 21.1—and in
Figure 21.2 for additional End-device modules—turn on power to these modules. The End-device XBee module or modules should associate with the
Coordinator attached to your PC, and the LED at each End-device module
should flash to indicate proper network association. Use the X-CTU Terminal
window to send an ATND command to the Coordinator to ensure it can discover all End-device modules, which should respond with their addresses.
Remember the hexadecimal addresses do not include leading zeros. A response
from one End-device module should appear in this form:
+++OK
ATND
FFFE
13A200
406AF5AB
51
PRO

Information will vary from that shown here due to different serial numbers and wireless signal strengths, but it always includes a complete response
from each End device. If you do not get a response from a module, check its
configuration settings. If an End device does not respond at all and its associate LED does not flash, check its electrical connects and its configuration
information.

228

How to Handle an Unknown Number of XBee Modules

Step 6. Continue this experiment with either an ARM mbed or an Arduino
Uno module after the following explanation of how the software operates.

MCU SOFTWARE
The software in this experiment will control the XBee Coordinator module and
will receive SH and SL address information from all associated End-device
modules. If the MCU does not receive a response from the Coordinator module within a set period, it “times out” and assumes all modules have replied. In
this way it will not endlessly wait for nonexistent XBee modules to respond.
Yet the MCU will wait long enough to obtain information from all associated
End devices. For non-programmers, an abbreviated explanation, shown later in
Table 21.2, will help clarify the overall serial-input operations.

PROGRAM DESCRIPTION
Flow charts in Figures 21.3a and 21.3b show how the program operates. After
the MCU transmits the ND API command packet it begins the SerialInput
routine, shown in an oval in Figure 21.3a and in detail in Figure 21.3b.
Instructions start an internal MCU timer and enable the timer’s interrupt.
The timer runs independently and doesn’t interfere with other MCU operations, so in effect the timer runs in the “background.” When the timer reaches
the end of its preset period, established with the constant start_value, it
causes an interrupt. The interrupt forces the MCU to leave the SerialInput
routine and execute the instructions in the timer’s associated interrupt-service
routine (ISR), as diagrammed in Figure 21.4.
Because you cannot know when the timer will need attention, you cannot
include statements to perform frequent timer operations in the normal program flow. But a timer that causes an interrupt requires immediate attention, so
the MCU will stop what it is doing, mark its place so it can return to the main
program, and branch to the timer ISR. After the MCU performs the operations in
the ISR, it goes back to where it left off in the main program. Many other MCU
devices use interrupts so the MCU will quickly respond to their operations.
The timer’s simple ISR increments the timer_count value, resets the timer
with the start_value, restarts the timer, and returns to the SerialInput routine. So timer interrupts occur at fixed intervals and each interrupt causes the
timer_count value to increase by one.
As soon as the SerialInput routine receives information from the Coordinator
module, it disables the timer interrupt. Then it returns the received serial byte
to the main program for processing. The main program will continue to use the
SerialInput routine to obtain additional bytes from the Coordinator module, but
without using the timer or causing any interrupts. The timer and its ISR only get
used in the program when the MCU waits for the first byte—the start byte, 0x7E—
in a packet. That start byte suffices to let the MCU know the Coordinator has discovered another End-device module and has started to send its information to the
MCU. After the MCU processes information from an End-device module, it turns
the interrupt on again and waits for another start byte in a new packet.

Program Description
(a)

229

Definitions
Set up Serial Input Routine

Transmit API packet “ND”

Serial Input Routine

Call Serial Input Routine

Yes

No
testdata = 0?

Break

No
testdata = 0×7E?
Yes
Transmit error message
Flash LED

Get message byte count
Get message data byte
Save byte in dataND array
Add checksum bytes

No

All bytes received?

Yes

Yes

Checksum OK?

No
Increment XBee_numb

No
Transmit error message
Flash LED

FIGURE 21.3 (a) Flow chart for code in the main routine that counts modules and uses a
timer and an interrupt to break out of a loop waiting for nonexistent XBee modules. Note
that the MCU can only exit this code via the Break shown on the left side of the diagram.
(b) This flow chart shows the serial-input routine (top) that starts an 8-bit MCU up-timer
with a preset value and enables a timer interrupt, and the interrupt-service routine (ISR) for
the timer (bottom).

What happens when the SerialInput routine never receives another
byte from the Coordinator module? The routine can now handle this
condition because it continually tests the timer_count value to determine
if it exceeds 255 (0xFF). Remember, the timer continues to periodically
interrupt the serial-input routine and its ISR adds one to the timer_count
value. When the timer has interrupted the serial-input routine more than 255

230

How to Handle an Unknown Number of XBee Modules
(b)

timer_count = 0
load counter with start_value

Serial Input

Enable Timer Interrupt

Yes

Serial data available?

No

Disable Interrupt
Return with serial data

timer_count > 255?

No

Note: timer_count >80 for
ARM mbed code
Yes
Disable Timer Interrupt
Return 0

Timer ISR

Reload counter with start_value
Increment timer_count

Return from ISR

FIGURE 21.3 (Continued)

Timer Period

Timer Period

Serial_Input
Interrupt
. . . ISR

Timer Period

Serial_Input
Interrupt
Timer ISR

Timer Period

Serial_Input

Serial. . .

Interrupt
Timer ISR

Timer ISR

FIGURE 21.4 This timing diagram shows how the timer interrupts the Serial_Input
function at fixed intervals. The MCU branches to the ISR, performs the ISR operations and
then goes back to where the MCU left the Serial_Input function. (Not drawn to scale.)

Program Description

231

times, the serial-input routine turns off the timer and returns to the main program with a testdata value of 0 (0x00). This value indicates the serial-input
routine has remained idle—no serial data received from the Coordinator—for
about eight seconds. (You can increase this period, if necessary.)
In essence, the result of the statement if (testdata == 0) indicates either
“Aha, there’s a module out there; let’s get all its data,” or “I’ve waited for 8
seconds and received no additional response, so stop waiting and go back to
the main program.”
Note that the software only checks the testdata value with the if (testdata == 0) statement when it waits for the start byte in a packet from the
Coordinator. If you try to test the testdata for a value of 0 when the software calls the SerialInput function at other places in the program, the program cannot distinguish between a 0 in the data from an XBee module and a 0
created when the MCU has waited for more than eight seconds.
Important: Remember that the software sends the ND API command packet
to the Coordinator, which queries all associated devices. The software DOES
NOT issue a broadcast ND API command packet. The latter will give you
unpredictable results. Again, the Coordinator received a local ND command.

Explanation for Non-programmers
Flow charts in Figures 21.3a and 21.3b show how the program operates, but
you can think of the operation of the first section of the program that involves a
timer and an interrupt as the steps shown in Table 21.2.

Table 21.2 Analogy for Program Steps
Step

Analogy

Program

1

You email several friends and ask them to come over
to your lab bench, but you don’t know how many will
show up.

Transmit the ND API command
packet.

2

You set your watch to beep every 10 seconds.

Set up timer.

3

You go to your office door and decide to wait five
minutes, or 30 10-second periods.

SerialInput routine.

4

Each time your watch beeps, you make a mark.

Timer interrupt-service routine (ISR).

5

If a friend arrives, take him or her to your lab bench.
Erase your timing marks and go back to the door.

Return from SerialInput
routine with XBee data.

6

Have you made 30 marks yet? If not, go back to Step
4. If so, continue.

Within SerialInput routine.

7

Five minutes have elapsed since a friend arrived, so
go to your lab bench and explain your latest project
to the people there.

Return from SerialInput
routine with testdata  0.

232

How to Handle an Unknown Number of XBee Modules

Three key sections of C-language code:
Set up a timer that will interrupt the processor. The timer has a long period.
l
Include a short interrupt-service routine (ISR) that resets the timer and
increments a count. Thus, whenever the timer reaches a set value, or overflows, the ISR increments the timer_count value.
l
Include statements in the SerialInput routine that set the timer_count
value to 0, load the MCU timer with a starting value, and turn on the
timer’s interrupt. When the timer exceeds a preset value, it interrupts the
MCU and increments timer_count. When timer_count exceeds a preset
value, the code aborts the SerialInput routine and returns a 0x00 value
to the main program.
The code in this experiment sets up an array for a maximum of five (5) Enddevice modules when it defines the dataND array, but you can change the value
of numb_of_modules depending upon the maximum number of modules you
will allow in your PAN. You might include a few more than the maximum
number of End-device modules expected. The definition:
l

dataND[numb_of_modules][dataNDlength]

simply assigns array space for data. Remember, array-element numbers start at
zero; that is dataND[0][0].
Step 7. Now you will add a microcontroller to your network to control the
Coordinator. The following sections use an ARM mbed module or an Arduino
Uno module.

USING AN ARM MBED MODULE
Turn off power to the breadboard and leave the End-device module with the
resistors and potentiometer attached to it in the breadboard (see Figure 21.1).
Remove the Coordinator module from the USB-to-XBee adapter, and set it
aside.
If you have a second End-device module in your breadboard, remove it,
and set it aside. If you do not have a second adapter socket in your breadboard,
insert one and add the LED and resistor shown in Figure 21.5. Make the power
(pin 1) and ground (pin 10) connections to the second adapter. If this adapter
has any other connections, please remove them now. Connect the ARM mbed
module to this adapter and insert the Coordinator module.
If you have set aside a second End-device module, you can place it in
another breadboard and add the connections shown earlier in Figure 21.2.
You also could place an additional End-device module in the USB-to-XBee
adapter. This XBee module would obtain power through the USB cable, but it
will not communicate with the PC.
l
Turn on power to the Coordinator module and then power the End-device
module or modules. After a few seconds you should see the LED on the
Coordinator module start to flash, followed by flashes from the LED

Using an ARM mbed Module
+3.3 V

DOUT
DIN

To mbed Module
Pin 10 (Rx)
To mbed Module
Pin 9 (Tx)

To mbed Module
Pin 1 (GND)

233

Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

DIO5
Associate
LED
330

GND

FIGURE 21.5 Circuit for the XBee module used as the Coordinator with an ARM mbed
module.

attached to each End-device module. The flashing LEDs indicate the
End-device modules have associated with the Coordinator module.
Program EX21_mbed_ND provides the C-language code you will run on
your ARM mbed module.

l

Program EX21_mbed_ND
Code for an ARM mbed module to control a Coordinator and determine the
number of End-device modules you have in a personal-area network (PAN).
/*
*
*
*
*
*
*
*
*
*/

EX21 ARM mbed Module Rev. B
Program: EX21_mbed_ND
Obtain information about XBee End-device modules in a network,
regardless of number of modules. Store information in an array,
print hex data.
Uses Timer0 and an interrupt
Optional LED on pin 13 for debugging and error notification.
Jon Titus 09-06-2011 @1010H

#include "mbed.h"
//*************** Declarations & Assignments ***************
//Define API "ND" API command-packet array here
int packetND[] = {0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x44, 0x13};
int packetNDlen = 8;
int

XBee_numb;
//counter for number of module responses

234

How to Handle an Unknown Number of XBee Modules

const int
const int
char

numb_of_modules = 5;
//max number of expected modules, change as needed
dataNDlength = 40;
//max length of dataND array
dataND[numb_of_modules][dataNDlength];
//set up response array for XBee modules

//define additional variables
int testdata;
int output_data;
int packet_start_byte = 0x7E;
DigitalOut
LedPin(p13);
//Set pin 13 as indicator LED output
Serial
Sport(p9,p10);
//Serial port pins 9 & 10 for XBee
Serial
pc(USBTX, USBRX);
//Set up communications with host PC
unsigned int timer_count;
unsigned int bytecount_hi;
unsigned int bytecount_lo;
unsigned int bytecount;
unsigned int counter;
unsigned int chksum;
unsigned int chksum_temp;
unsigned int XBee_total_numb;
unsigned int Timer0_start_value = 2398000;
//approx. 100 msec.
//*************** Set up Timer0 ***************
//Set up Timer0 here
void timer0_init(void)
{
LPC_SC->PCONP |=1<1; //timer0 power on
LPC_TIM0->MR0 = Timer0_start_value;
LPC_TIM0->MCR = 3;
//interrupt and reset control
}
//3 = interrupt & reset timer0 on match
//1 = interrupt only, no reset of timer0
//*************** Timer0 Interrupt Svc Routine ***************
extern "C" void TIMER0_IRQHandler (void)
//compile as a "C" function
{
if((LPC_TIM0->IR & 0x01) == 0x01)
//if interrupt from MR0, then
{
LPC_TIM0->IR |= 1 << 0;
//clear MR0 interrupt flag
timer_count++;
//increment timer_counter value
}
}
//*************** Serial-Input Routine ***************
//function will read serial port as soon as it has data ready
char SerialInput()
{
timer_count = 0;
//set outer-loop count
NVIC_EnableIRQ(TIMER0_IRQn);
//enable Timer0 interrupt
LPC_TIM0->TCR = 1;
//enable Timer0
while (Sport.readable() == 0)
//stay in this loop until character received

Using an ARM mbed Module

235

{
if (timer_count > 80)
//test outer-loop counter incremented by Timer0 ISR
{
//CPU has waited too long for UART response
NVIC_DisableIRQ(TIMER0_IRQn);
//turn off timer interrupt
return (0);
//abort, return with value of 0
}

}

}
NVIC_DisableIRQ(TIMER0_IRQn);
//UART now has data, so turn off timer interrupt
return (Sport.getc()); //return with UART data

//************ Function to send ND API Command Packet ************
//function will send command packet
void SendPacket(int packet2send[], int packetlength)
{
counter = 0;
//loop counter for bytes in API packet
while( counter < packetlength )
{
Sport.putc(packet2send[counter]);
//transmit API-packet byte
counter++;
}
}
//*************** MAIN PROGRAM ***************
int main(void)
{
timer0_init();
LedPin = 1;
wait(0.5);

//initialize Timer0
//LED at pin 13 off to start
//half-second delay

SendPacket(packetND, packetNDlen);
//Send API packet to XBee Coordinator
XBee_numb = 0;

//Start with zero XBee End devices

// This portion of the program gets serial data sent by XBee
// modules and saves the data in an array of bytes for each module.
while(1)
//you can only "break" out of this loop
{
testdata = SerialInput();
//go get UART data, if any
if (testdata == 0)
//SerialInput function aborted--no UART data
{
//break out of while(1) loop
break;
}
if (testdata != packet_start_byte)
//UART has data, so check for start-byte
{
while(1)
//First byte is not valid start byte
{
//Error handling could go here.
LedPin = 0;
wait(0.05);
LedPin = 1;
wait(0.05);

236

How to Handle an Unknown Number of XBee Modules
}

}

else

//OK, found proper packet-start-byte
{
bytecount_hi = SerialInput();
//Next two bytes give msg byte count
bytecount_lo = SerialInput();
bytecount = (bytecount_hi * 256) + bytecount_lo;
//calculate # of bytes in msg
chksum_temp = 0;
for (counter = 0; counter < bytecount; counter++)
//put all bytes in array until done
{
dataND[XBee_numb][counter] = SerialInput();
chksum_temp = chksum_temp + dataND[XBee_numb][counter];
//tally checksum
}
chksum = SerialInput();
//get checksum--last byte in packet
if (chksum != (0xFF - (chksum_temp & 0xFF)))
//do checksums match?
{
while(1)
//no match, flash LED forever
{
//error handling code could go here instead of
LedPin = 0; //LED-flash loop
wait(1);
LedPin = 1;
wait(1);
}
}
XBee_numb++;
//increment XBee-numb module count
}
}
//get data from next Xbee module
//break out of while(1) loop comes here
//if
//
//
//

(XBee_numb > 0) //for the ND command, remove 1 count
{
//so final status packet from Coordinator
XBee_numb--;
//does not count as a module.
}

//Print the number of modules detected and the hex data from
//each discovered
//End-device module.
XBee_total_numb = XBee_numb;
LedPin = 0;
//turn on external LED
wait(0.5);
//half-second delay
pc.printf("\n\r\n\r");
pc.printf("Number of modules: ");
//print number of discovered modules
pc.printf("%d ", XBee_total_numb);
pc.printf("\n\r");
//loop to print hex data from each End-device XBee module
//data saved in dataND[][] array
for (XBee_numb = 0; XBee_numb < XBee_total_numb; XBee_numb++)
{

Using an ARM mbed Module

237

pc.printf("\n\r");
for (counter = 0; counter < 40; counter++)
{
output_data = dataND[XBee_numb][counter];
pc.printf("%02X ",output_data);
//print double zeros for zero value
}
pc.printf("\n\r"); //go to a new line in text window
}
while(1)
{
}

//end program in an infinite do-nothing
//loop. Press reset button to run again

}
//Program ends
//================================================================
l

l

Compile the EX21_mbed_ND program and correct any typing errors.
The compiler will download the program into the ARM mbed module as
if it exists as an external USB memory stick. On my PC, the ARM mbed
module appeared as the F: drive.
After the LED on the ARM mbed board stops flashing, start your terminal emulator program and set it for 9600 bits/second, 8 data bits, no parity,
1 stop bit, and no flow control. The terminal emulator uses the same USB
cable the compiler used to download the code. You can use the Windows
Device Manager to determine which virtual serial port the ARM mbed connects to. Change your view so you can see the terminal emulator window.
Press the reset pushbutton on the ARM mbed module. Remember, the
MCU will wait until the timer count ends before it sends the XBee module
to your PC. When I ran the code with two end devices, I observed in the
terminal emulator window:
Number of modules: 3
88 52 4E 44 00 FF FE 00 13 A2 00 40 6A F5 AB 3F 50 52 4F 00 00
00 00...
88 52 4E 44 00 FF FE 00 13 A2 00 40 49 E1 E6 4A 45 4E 44 00 00
00 00...
88 52 4E 44 00 00 00...

For clarity I have excluded many 00 values at the end of each data set.
The response from the MCU indicates an “extra” End-device module
because the Coordinator sends a short acknowledgement, which the program counts as a module. The software includes four commented-out lines
that do not execute:
//if (XBee_numb > 0)
//
{
//
XBee_numb--;
//
}

238

l

How to Handle an Unknown Number of XBee Modules

To not count the Coordinator’s acknowledgement message as an End-device
module, “un-comment” these statements so the code decreases the module
count by one.
For the first response, the packet breaks down as follows:
88

= AT Command response

52

= frame-identifier byte (52 for all experiments)

4E44

= hex code ND

00

= status byte (OK)

FFFE

= 16-bit MY value

0013A200406AF5AB

= 64-bit address of responding module

3F

= signal strength

50

=P

52

=R

4F

=O

00

= null, end of NI information

The displayed information came from the dataND array. Note the array
saved the 64-bit (8-byte) address for each End-device module in locations
dataND[x][7] through dataND[x][14]. The software in Experiment 20
used the SL address bytes, dataND[x][11] through dataND[x][14] within
an IS API command packet to address a specific End-device module. So
the dataND information gathered here would easily “plug into” the code in
Experiment 20 so you could discover modules and obtain analog and digital information from them.
l
Turn off power to one of your XBee modules and wait 10 seconds. Now
run the program again. Did it detect the proper number of remaining Enddevice modules? In my lab, I had two End devices, so the program now
counted only the single powered XBee End-device module. If you have
only one End device and turn off its power you should see: Number of
modules: 0.
Skip ahead to the Conclusion section at the end of this experiment.

USING AN ARDUINO UNO MODULE
Turn off power to the breadboard and leave the End-device module with
the resistors and potentiometer attached to it in the breadboard (see Figure
21.1). Remove the Coordinator module from the USB-to-XBee adapter, and
set it aside.

Using an Arduino Uno Module

239

+3.3 V
Top View

LLC 3-to-5
3

To Arduino Uno Pin 0 (RX)
To Arduino Uno Pin 1 (TX)

2

DOUT

21

DIN

LLC 5-to-3
DPDT Switch

3

1

20

2

19

3

18
17

4
5

21
1000

To Arduino POWER GROUND

XBee XB24

16

6

15

7

14

8

13

9

12

10

11

Associate
LED
330

GND
Logic-Level-Converter (LLC) Connections:
Ground at pins 11, 12, 13, 22.
+5 volts at pin 1; +3.3 volts at pins 23, 24.
On LLC 5-to-3: 1000-ohm resistor between pins 1 and 2.
On LLC 3-to-5: ground pin 2.

FIGURE 21.6 Circuit for the XBee module used as the Coordinator with an Arduino Uno.

If you have a second End-device module in your breadboard, remove it,
and set it aside. If you do not have a second adapter socket in your breadboard,
insert one and add the LED and resistor shown in Figure 21.6. Make the power
(pin 1) and ground (pin 10) connections, and connect the logic-level-conversion
circuits and the Arduino Uno module as shown. If you have other connections
to this adapter, please remove them and then insert the Coordinator module.
If you have set aside a second End-device module, you can place it in
another breadboard and add the connections shown earlier in Figure 21.2. You
also could insert an End-device module in the USB-to-XBee adapter. This
XBee module would obtain power through the USB cable, but it will not communicate with the PC.
Pay attention to the notes below and in Figure 21.6 that explain additional
connections not shown in the diagram for the sake of clarity:
l
On LLC 5-to-3, connect a 1000-ohm resistor (brown-black-red) between
pins 1 and 2.
l
On LLC 3-to-5, connect pin 2 to ground.
l
On both logic-level-converter devices, connect pins 11, 12, 13, and 22 to
ground.
l
On both logic-level-converter devices, connect pin 1 to 5 volts.
l
On both logic-level-converter devices, connect pins 23 and 24 to 3.3 volts.
l
Turn on power to the Coordinator module and then power the End-device
module or modules. After a few seconds you should see the LED on the
Coordinator module start to flash, followed by flashes from the LED
attached to each End-device module. The flashing LEDs indicate the Enddevice modules have associated with the Coordinator module.
Important: As noted in other experiments, the Arduino Uno module shares its
UART with an XBee module and the host PC USB connection, so the serial
connection between an Arduino Uno module and an XBee module when

240

How to Handle an Unknown Number of XBee Modules

downloading code can cause an electrical conflict. You MUST manually disconnect (or use a small switch to open) the two serial-port connections between
an Arduino Uno module and any external device while the compiler downloads
code to the Arduino Uno. I used a small double-pole double-throw (DPDT)
toggle switch to disconnect the signals between the logic-level-conversion
circuits and the Arduino Uno module during code downloads. Remember to
reconnect these wires, or flip the switch, before you run the program.
l
Disconnect the wires between the logic-level-converter circuits and the
Arduino Uno module RX and TX pins (pin 0 and pin 1). If you don’t
use a switch, colored wires will help you keep track of the TX and RX
connections.
Program EX21_Uno_ND provides the C-language code you will run on your
Arduino Uno module.

Program EX21_Uno_ND
Code for an Arduino Uno module to control a Coordinator and determine the
number of End-device modules you have in a personal-area network (PAN).
/*
*
*
*
*
*
*
*
*
*/

EX21 Arduino Uno Module Rev. B
Program: EX21_Uno_ND
Obtain information about XBee End-device modules in a network,
regardless of number of modules. Store information in an array,
print hex data.
Uses Timer2 and an interrupt.
Optional LED on pin 13 for debugging and error notification.
Jon Titus 09-05-2011 @1525H

//*************** Declarations & Assignments ***************
// Define API "ND" command-packet array here
byte
packetND[] = {0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E,
0x44, 0x13};
byte
packetNDlen = 8;
//packet ND length in number of bytes
byte
const byte
const int
byte
byte
byte
int

XBee_numb;
//counter for number of module responses
numb_of_modules = 5;
//max number of expected modules, change as needed
dataNDlength = 40;
//max length of dataND array
dataND[numb_of_modules][dataNDlength];
//Set up response array for XBee modules
testdata;
//variable for incoming data
packet_start_byte = 0x7E;
LedPin = 13;
//Set pin 13 as optional indicator LED output

//define additional variables
unsigned int timer_count;
unsigned int bytecount_hi;

Using an Arduino Uno Module
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

int
int
int
int
int
int
int

241

bytecount_lo;
bytecount;
counter;
chksum;
chksum_temp;
XBee_total_numb;
Timer2_start_value = 0x02;

//*************** Set up Timer2 ***************
//Set up Timer2
//see Atmel manual for ATmega328P 8-bit MCU family. www.atmel.com
int SetupTimer2()
{
TCCR2A = 0;
//Timer2 mode 0, normal operating mode
TCCR2B = 1<255
if (timer_count > 255)
//test outer-loop counter incremented by Timer2 ISR
{
//CPU has waited too long for Coordinator response
TIMSK2 = 0< 0)
//Coordinator includes acknowledgement
//
{
//so decrease module count by one
//
XBee_numb--; //so Coordinator doesn't count as an
//
}
//End-device module
XBee_total_numb = XBee_numb;
digitalWrite(LedPin, LOW);
//turn on LED to show data ready
delay(500);
//half-second delay
Serial.print("\n\r\n\r");
//print module count
Serial.print("Number of modules: ");
Serial.print(XBee_total_numb, HEX);
Serial.print("\n\r");
//Test routine to print data in each XBee array as hex characters
for (XBee_numb = 0; XBee_numb < XBee_total_numb; XBee_numb++)
{
Serial.print("\n\r");
for (counter = 0; counter < dataNDlength; counter++)
{
if (dataND[XBee_numb][counter] < 0x10)
//format single-digit hex values
{
Serial.print("0");
}
Serial.print(dataND[XBee_numb][counter], HEX);
Serial.print(" ");
}
Serial.print("\n\r");
}
//go to a new line in text window
while(1)
{
}

//end program in an infinite do-nothing
//loop

}
//Program ends
//================================================================

244
l

l

How to Handle an Unknown Number of XBee Modules

Compile the EX21_Uno_ND program and correct any typing errors. Load
the code into the Arduino Uno. After you see the message “Done uploading,” reattach the wires between the logic-level-conversion (LLC) circuits
and the Arduino Uno module RX and TX pins. Do not disconnect the USB
cable between the Arduino Uno module and your PC.
Open the Arduino Uno compiler’s Serial Monitor window to see messages
produced by the downloaded software. If you have the X-CTU program
open, I recommend you close it.
Press the reset button on the Arduino Uno module to start the program.
After the program acquires data from all XBee End-device modules and
the SerialInput routine times out, the Arduino Uno will send End-device
information to the Serial Monitor window. Remember, the MCU will wait
until the timer count ends before it sends the XBee module to your PC.
When I ran the program with two end devices, the Serial Monitor window
showed:
~...RND.
Number of modules: 3
88 52 4E 44 00 FF FE 00 13 A2 00 40 6A F5 AB 3F 50 52 4F 00 00
00 00...
88 52 4E 44 00 FF FE 00 13 A2 00 40 49 E1 E6 4A 45 4E 44 00 00
00 00...
88 52 4E 44 00 00 00...

l

For clarity I have excluded many 00 values at the end of each data set. (I
used software to format single-digit hex values with a leading zero.)
Because the Arduino Uno module UART transmits data to both the USB
port and to the Coordinator, you see the outgoing ND command along with
symbols on the first line in the Serial Monitor window. Next, the program
displayed the number of XBee End-device modules in the network followed by the raw information from each one. Remember, you did not preset the number of modules in the code for this experiment.
The response from the MCU indicates an “extra” End-device module because
the Coordinator sends a short acknowledgement, which the program counts as
a module. The software includes four commented-out lines that do not execute:
//if (XBee_numb > 0)
//

{

//

XBee_numb --;

//

}

Conclusion

l

l

245

To not count the Coordinator’s acknowledgement message as an Enddevice module, “un-comment” these statements so the code decreases the
module count by one.
For the first response from my modules, the packet breaks down as follows:
88

= AT Command response

52

= frame-identifier byte (52 for all experiments)

4E44

= hex code ND

00

= status byte (OK)

FFFE

= 16-bit MY value

0013A200406AF5AB

= 64-bit address of responding module

3F

= signal strength

50

=P

52

=R

4F

=O

00

= null, end of NI information

The displayed information came from the dataND array. Note the array
saved the 64-bit (8-byte) address for each End-device module in locations
dataND[x][7] through dataND[x][14]. The software in Experiment 20
used the SL address bytes, dataND[x][11] through dataND[x][14] within
an IS API command packet to address a specific End-device module. So
the dataND information gathered here would easily “plug into” the code in
Experiment 20 so you could discover modules and then obtain analog and
digital information from them.
Turn off power to one of your XBee modules and wait 10 seconds. Now run
the program again. Did it detect the proper number of remaining End-device
modules? In my lab, I had two End devices, so the program now counted
only the single powered XBee End-device module. If you have only one
End device and turn off its power you should see: Number of modules: 0.

CONCLUSION
When you have an unknown number of modules in a PAN, you can use a program such as EX21_Uno_ND or EX21_mbed_ND to issue a command and
wait until all modules in range have had an opportunity to reply. The use of
a timer and an interrupt lets you set a limit on how long an MCU will wait
for responses until it assumes no other XBee modules will associate with the
Coordinator.
You can take an alternate approach, though, if you feel uncomfortable with
software that includes an interrupt. (Interrupts can prove difficult to debug.)

246

How to Handle an Unknown Number of XBee Modules

The ND – Node Discovery command has an associated NT – Node Discover
Time number that lets you set the period during which a Coordinator will
wait for responses from XBee modules. Periods range from 100 milliseconds
(0x01) to 25.2 seconds (0xFC). At the end of this period, the Coordinator
sends a short acknowledgement message, 0x88 0x52 0x4E 0x44 0x00 0x00
0x00... to an MCU. You could write software to examine incoming packets
for this series of bytes—or a subset of these bytes—to indicate the “time out”
of the node-discovery period. (The software could look for 0x44 in the fourth
message byte followed by at least three 0x00 bytes.)
The XBee command set also includes an NO – Node Discover Options
command for XBee modules that lets you turn on or off a complete response
from the Coordinator that includes the same information as that for an Enddevice module. Unless you need the Coordinator’s address, I recommend you
leave the NO option set at 0, its factory default.
Feel free to modify this software and use it as you wish. I hope you
will share your code on the http://www.elsevierdirect.com/companion
.jsp?ISBN=9780123914040 Web site.

Experiment | 22

Exploring Cyclic-Sleep
Operations
REQUIREMENTS
2 XBee modules
1 XBee adapter board
1 Solderless breadboard
1 USB-to-XBee adapter
1 USB cable—type-A to mini-B
2 LEDs
2 330-ohm resistors, 1/4 watt, 10% resistor (orange-orange-brown)
1 4700-ohm resistor, 1/4 watt, 10% resistor (yellow-violet-red)
1 10-kohm resistor, 1/4 watt, 10% resistor (brown-black-orange)
1 10-kohm potentiometer
Digi X-CTU software running on a Windows PC, with an open USB port

INTRODUCTION
In this experiment you will learn how to use the cyclic-sleep capabilities of
XBee modules in a network. These capabilities let you place modules in sleep
modes that save power and extend battery life. Keep in mind the cyclic-sleep
modes do not let communications occur in real time due to delays as modules
wake up from, or remain in, sleep conditions. In remote-controlled robots or
medical-patient monitors, for example, you’ll probably want real-time operations. In temperature-sensing applications, irrigation controllers, or heating/
ventilating equipment, though, changes will occur slowly and you can probably make measurements every 10 to 15 seconds, or with even longer periods
between samples. External circuits, though, can cause an immediate wake-up
and data transmission. This experiment does not require a microcontroller.
The cyclic-sleep operations offer two ways to communicate between Enddevice and Coordinator modules in a personal-area network (PAN). In the
first case, End-device modules can awaken at fixed intervals, sample I/O pins,
and report results to a Coordinator module. In the second case, End-device
The Hands-on XBee Lab Manual.
© 2012 Elsevier Inc. All rights reserved.

247

248

Exploring Cyclic-Sleep Operations

modules can awaken and poll the Coordinator to ask if it has a command or
data for them. If so, the addressed module performs the requested operation.
If not, the module goes back to sleep for another set period. You will see how
to use both sleep modes in this experiment.
In Experiment 9 you used an external pin to control a hibernate or a doze
sleep mode to control how long a module remained in a sleep state. The cyclicsleep modes explored in this experiment use timers internal to XBee modules
to control sleep operations at regular intervals.
Important: After I set up an End-device module in a cyclic-sleep mode
for this experiment often it took several attempts to read and write its Modem
Configuration information. I suspect the End-device module goes into its sleep
mode when powered from a PC through the USB-to-XBee adapter. Just click
on the Read or Write button in the X-CTU Modem Configuration window
several times to catch the module in its awake state. I don’t know a way to
overcome this situation.

PERIODIC WAKE-UP WITH I/O REPORT
You might choose to have each End-device module go into a sleep mode and
wake-up periodically to report digital or analog information. Assume you want
an End-device module to wake up every 15 seconds and transmit information
about its analog or digital inputs to the Coordinator module. Your End-device
module would use the following settings to establish the sleep mode and its
timing:
Sleep Mode (SM). This setting offers two choices for cyclic-sleep operation. You can let an XBee module operate on its own (SM  4) or you can let
it operate on its own but with an external pin wake-up control signal (SM  5).
The external signal will override the internal timing for a sleeping End-device
module:
0  Disabled (no sleep mode) default setting
1  Pin Hibernate (see Experiment 9)
2  Pin Doze (see Experiment 9)
4  Cyclic Sleep Remote
5  Cyclic Sleep Remote with Pin Wakeup
This experiment uses modes 4 and 5. (Digi reserves mode 3 (SM  3) for a
later undefined use.)
Sleep Options (SO). You use this setting to cause the End-device module
to sample the active digital and analog inputs and transmit that information
upon wake-up.
Cyclic Sleep Period (SP). The SP value determines the sleep period for
End-device modules, with a limit of 268 seconds, or 4 minutes and 28 seconds.
Time Before Sleep (ST). An XBee End-device module will go into sleep
mode only if it detects no radio communications for this length of time. This value
defaults to 5 seconds (0x1388), but you can extend it for as long as 65.5 seconds
(0xFFFF). Always use a Time Before Sleep value greater than the Guard Time

Periodic Wake-Up with I/O Report

249

(GT), which defaults to one second (0x3E8). The Guard Time establishes the
quiet time before and after an AT command. I recommend you not modify the GT
setting and always use an ST setting greater than one second.
In this section, you will configure one XBee module as a Coordinator
and one as an End device. You may add a second End-device module if you
wish, but I recommend you first run the experiment with one module and then
go through the experiment again with additional End-device modules, if you
have them.

Set Up an End-Device Module
Step 1. Place your End-device XBee module in the USB-to-XBee adapter and
use the X-CTU software to Read its Modem Configuration information. (This
section uses configuration settings in the file EX22_End_A.pro.)
l
Under the heading Networking & Security, ensure you have a value of 0 for
CE – Coordinator Enable and a value of 0x1FFE for SC – Scan Channels.
l
For the A1 – End Device Association value, select the setting 6 – 0110B,
where the B stands for binary. This setting establishes these conditions:
associate with a Coordinator on any channel and attempt to associate
indefinitely with a PAN Coordinator.
l
Set the RN – Random Delay Slots to a value of 2. This setting helps prevent collisions between simultaneous transmissions from several End
devices. Even if you have only one End-device module, I recommend you
use this setting. (I found errors in transmissions from End-device modules
when I used the default value of 0 for RN.)
l
Move down to the last item under the Networking & Security heading,
NI – Node Identifier, and click on this label. Next, click on the Set button
that appears to the right of this label and type in a name for the module. You
may use as many as 20 characters, but I recommend you use four or five.
(I named my End-device module XMTR.)
l
Look under the Sleep Modes (NonBeacon) heading and set the following
configurations:
SM – Sleep Mode	  4 – CYCLIC SLEEP REMOTE
ST – Time Before Sleep	  1388 (default, 5 seconds: 1-msec units)
SP – Cyclic Sleep Period	  3E8 (10 seconds: 10-msec units)
SO – Sleep Options	  0 (poll and sample)
Note: The ST parameter uses increments of one millisecond and the SP
parameter uses units of 10 milliseconds. Thus, 0x1388  5000, which converts to 5000 milliseconds, or 5 seconds. And, 0x3E8  1000, which converts to 10,000 milliseconds, or 10 seconds.
l
Look under Serial Interfacing heading for the label, AP – API Enable, and
click on it. Choose 1 – API ENABLED.
l
Write the hexadecimal SH and SL information for your End-device module
or modules in Table 22.1. You will need this information later.
Recheck your Modem Configuration settings.

250

Exploring Cyclic-Sleep Operations

Table 22.1 End-Device Module Information
End-Device 1

End-Device 2

SH – Serial Number High
SL – Serial Number Low
Note: End-device modules 2 and 3 are optional.

Move down to the section labeled I/O Settings and change your End-device
module settings to match the ones below.
D8 – DI8 Configuration
0 – DISABLED
D7 – DIO7 Configuration 1 – CTS FLOW CONTROL
D6 – DIO6 Configuration 0 – DISABLED
D5 – DIO5 Configuration 1 – ASSOCIATED INDICATOR
D4 – DIO4 Configuration 0 – DISABLED
D3 – DIO3 Configuration 2 – ADC (Analog-to-digital converter)
D2 – DIO2 Configuration 3 – DI   (Digital input)
D1 – DIO1 Configuration 2 – ADC (Analog-to-digital converter)
D0 – DIO0 Configuration 3 – DI   (Digital input)
Recheck your DIO settings.
l
Finally, click on Write to save this configuration in the attached End-device
module. This step enables the API interface on your module, gives it a
name you can recognize, sets it as an End device, establishes sleep operations and times, and enables four I/O pins as inputs.
After you have programmed the End-device module, remove it from the USBto-XBee adapter and set it aside separate from the XBee module you will use
in the next steps.
l

Set Up a Coordinator Module
Step 2. Place the XBee module you will use as the Coordinator in the
USB-to-XBee adapter and use the X-CTU software to Read its Modem
Configuration information. (This section uses configuration settings in the file
EX22_Coord_A.pro.)
l
Ensure you have a value of 0x1FFE for SC – Scan Channels.
l
In the line labeled CE – Coordinator Enable, select 1 – COORDINATOR.
l
For the A2 – Coordinator Association value, select the setting 6 – 110B,
where the B stands for binary. This setting establishes two conditions: It
lets the Coordinator find an unused wireless channel and it lets any End
device associate with this Coordinator.
l
Look under the Sleep Modes (NonBeacon) heading and if necessary, set
the following configurations:
SM – Sleep Mode	  0 – NO SLEEP (default)
ST – Time Before Sleep	  1388 (default, 5 seconds)
SP – Cyclic Sleep Period	  0 (default)

Periodic Wake-Up with I/O Report

251

Move down to the last item under the Networking & Security heading:
NI – Node Identifier and click on this label. Next, click on the Set button
that appears to the right of this label and type in a name for the module.
You can use as many as 20 characters, but I recommend you use four or
five. (I named my Coordinator module RCVR.)
l
Look under Serial Interfacing heading for the label, AP – API Enable, and
click on it. Choose 1 – API ENABLED.
Recheck your settings.
l
Finally, click on Write to save this configuration in the attached
Coordinator module. This step enables the API interface on your module,
gives it a name you can recognize, sets the cyclic-sleep times, and sets it
as a Coordinator. Note that the Coordinator will NOT go into a sleep state
because you set the Sleep Mode to 0.
Leave the Coordinator module in the USB-to-XBee adapter.
Step 3. Place your End-device modules in an XBee adapter in your solderless breadboard and add the components shown in Figure 22.1 to this module. The two digital inputs (DIO0 and DIO2) and two analog inputs (DIO1
and DIO3) provide information this End-device module can transmit to the
Coordinator you programmed earlier. This circuit also includes an LED for
the module’s clear-to-send (CTS) output at pin 12. If the adapter has any other
electrical connections, please remove them now.
Step 4. The Coordinator module already has power connected via the
USB-to-XBee adapter. Turn on power to your End-device module and note the
behavior of the LEDs. What do you observe on the LEDs?
I saw both LEDs turn on and remain on for about four seconds and then
turned off. The LEDs remained off for 10 seconds, after which the Associate
l

+3.3 V
10 K

Top View
+3.3 V

1
2
3
4
5
XBee
6
7
8
9
10

XB24

DIO0
20
GND
DIO1
19
DIO2
+3.3 V
18
DIO3
17
16
DIO5
15
V REF
+3.3 V
14
13
330
DIO7
12
CTS
11

+3.3 V
10 K
4700
Associate
+3.3 V
330

FIGURE 22.1 Add this circuitry to an End-device module so it has two digital and two
analog inputs as well as an Associate and a Clear-to-Send (CTS) LED.

252

Exploring Cyclic-Sleep Operations
Data to Coordinator
25 msec

Logic Level

1
CTS

Time Before Sleep

Cyclic Sleep Period

0
1
Associate
0
0
1
2
3
Time (seconds)

4

5

10

15

FIGURE 22.2 This diagram shows the relationship between the time an End-device module wakes and sends information to a Coordinator, the Time Before Sleep Period, and the
Cyclic Sleep Period.

LED flashed several times and the CTS LED turned on. Both LEDs remained
active for five seconds. They repeated this pattern every 15 seconds.
The CTS LED indicates the wake condition for the End-device module.
You set a 5-second Time Before Sleep and a 10-second Cyclic Sleep Period.
These times sum to 15 seconds. The module requires a 5-second quiet time
with no receipt of messages or commands addressed to it before it enters
the Cyclic Sleep Period. Thus the Coordinator module receives a transmission about the digital- and analog-input data every 15 seconds, as shown in
Figure 22.2.
Important: An End-device module remains awake during the Time Before
Sleep period, and you can still communicate with it during this time—the
associate LED flashes and CTS LED remains on. Each communication that
involves this End-device module restarts the Time Before Sleep period. So,
you could communicate back and forth with this End-device module for many
minutes as long as you never allow more than five seconds between communications. After the final transmission, the End-device module waits for
the 5-second Time Before Sleep Period, and absent another communication
addressed to it, it goes into the Cyclic Sleep Period.
Open the X-CTU Terminal window. You should see a new packet such as
the one that follows every 15 seconds. The packets on my PC looked like this:
7E 00 14 82 00 13 A2 00 40 49 E0 EC
3B 00 01 14 05 00 04 01 47 03 62 6D

You can change the states of the digital inputs and adjust the potentiometer to see how they affect the information in the received bytes, such as those
shown above.

Periodic Wake-Up with I/O Report

253

This packet breaks down as follows:
7E

= start byte

0014

= message length (20 bytes)

82

= packet type (Remote Command Response)

00

= frame-identifier byte (52 for all experiments)

0013A2004049E0EC

= 64-bit address of responding module

3B

= signal strength

00

= status byte

01

= number of samples of d igital and analog data

14

= first Active-Signal Byte, AD3 and AD1 active

05

= second Active-Signal Byte, DIO2 and DIO0 active

00

= first Digital-Data Byte

04

= second Digital-Data Byte, DIO2 = 1, DIO0 = 0

0247

= hex value from AD1 ADC

0362

= hex value from AD3 ADC

6D

= checksum for this message

The API frame specifications in the Digi International “XBee/XBee-PRO RF
Modules” manual do not include information about packet types 0x82 or 0x83.
A 0x82 packet type indicates 64-bit addressing for I/O-pin information and a
0x83 indicates 16-bit addressing for I/O-pin information. I found this information in the “API Support” subsection of the “RF Module Operation” chapter.
If you have a second XBee module to use as an End device, follow the
programming sequence in Step 1. Then place this module in an adapter in a
solderless breadboard and connect pin 1 to 3.3 volts and pin 10 to ground.
If you wish you can add the other components shown in Figure 22.1. Turn on
power to your second End-device module. You should see data arrive from
both modules. Differences in the SL – Serial Number Low bytes lets you tell
the difference between data from each End device.
Step 5. Optional: You might want the flexibility to force an End-device
module to transmit I/O information based on an external signal, perhaps a signal from an MCU or a switch closure. The Sleep Request input at pin 9 on an
End-device module gives you the capability to do this when you program its
Sleep Mode (SM) for: 5 – Cyclic Sleep Remote w/ Pin Wakeup.
Program the End-device module with the attached potentiometer
for SM  5. Then make a connection between the End-device module’s

254

Exploring Cyclic-Sleep Operations
+3.3 V

Vset–point
Temperature
sensor

Vtemp

3

LTC1441
+

7

4 –

2

1

To XBee Module
Sleep Request (pin 9)
AD2-DIO2 (pin 18)

GND

FIGURE 22.3 A basic comparator circuit can trigger the Sleep-Request pin with a logic-1
to a logic-0 transition when the voltage from a sensor exceeds a set-point voltage.

Sleep-Request pin (pin 9) and 3.3 volts on your breadboard. Power the
End-device module and let it associate with the Coordinator. After you start to
see data in the X-CTU Terminal window, wait until the CTS LED turns off to
indicate the module has started a sleep cycle.
Then make a brief connection between ground and the wire that goes to
pin 9 on the End-device module. This ground connection changes the logic
state at pin 9 to a 0 and triggers the module to wake up and transmit to the
Coordinator. (There are better ways to trigger a transmission, but the wire
works for a simple experiment.)
Note: The DIO pins on XBee modules have internal pull-up resistors you
can enable or disable with the PR setting in the X-CTU Modem Configuration
window. A setting of PR  0x40 would enable the pull-up resistor on pin 9.
The XBee/XBee-PRO manual from Digi describes the other pull-up pin settings. The I/O pins default to the pull-up-resistor-on condition: PR – Pull-up
Resistor Enable  0xFF. These resistors will “pull up” an unconnected pin so
it assumes a logic-1 state.
For every logic-level transition from a logic 1 to a logic 0 at the SleepRequest pin (pin 9) with the End-device module in its sleep state you should
see a response in the Terminal window from the End-device module. But after
the XBee module goes into its awake state, logic transitions on the SleepRequest pin do nothing. This pin only triggers a sleeping module. You can’t
wake up a module that’s already awake.
If you have set a long delay between measurements of analog and analog
signals, you might want to trigger an extra transmission via the Sleep-Request
pin if, say, a temperature exceeds a limit or if someone actuates an emergency
switch.
The circuit diagram in Figure 22.3 shows how a temperature-sensor device
provides a voltage to one of the ADC inputs on an End-device module, which
reports temperature data, say, every 10 minutes. But when the temperature rises
past an alarm set-point, you want an immediate report. The LTC1441 comparator continuously compares the sensor voltage to a set-point voltage that represents the upper-limit temperature for the process or equipment monitored by

Periodic Wake-Up with Coordinator Polling
+3.3 V

C
+

100 k
4
7
2
6

100 k
+

8 NE555
V+
3

OUT
RST
DISCHG
TRIG
5
THR
CV
GND

4.7 uF/16V

1

255

1
2

To XBee Module
Sleep Request (pin 9)

14
3
7

C
GND

+3.3 V

Temperature
Sensor

Vtemp

3
Vset–point

+

7

4 –

2

LTC1441
1
To XBee Module
AD2–DIO2 (pin 18)
GND

FIGURE 22.4 In this circuit the comparator output switches from a logic 0 to a logic 1
when the voltage from a sensor exceeds a set-point voltage. That logic 1 lets pulses from
the NE555-timer circuit trigger the Sleep-Request pin about once a second.

the End-device module. When the sensor voltage exceeds the set-point voltage, the comparator output changes from a logic 1 to a logic 0, which triggers
the Sleep-Request pin on the End-device module. The information transmitted
to the network Coordinator could immediately alert an attached computer to
sound an alarm or take other actions to decrease the temperature.
As shown in Figure 22.4, the comparator might also gate an oscillator built
with an NE555-timer IC that would pulse the Sleep-Request pin, say, every
second until the voltage from the temperature sensor drops below the set-point
voltage. That way packets of I/O information from the End-device module
would reach the Coordinator regularly until the temperature decreased below
the set point.
Remember that once you wake a module with a logic-level change at the
Sleep-Request pin, the module remains awake for the 5-second Time Before
Sleep period after it transmits the input-pin information.
If you performed this optional step, please reprogram the End-device module you used so that SM  4 CYCLIC SLEEP REMOTE. Then proceed to the
next section.

PERIODIC WAKE-UP WITH COORDINATOR POLLING
You just learned how to put XBee End-device modules in a cyclic-sleep mode
that lets them wake up periodically under their own control and report analog
and digital information to a Coordinator module.
You also might need End-device modules that respond with information only when asked, yet still let them take advantage of low-power sleep
states. In this cyclic-sleep mode, when an End-device module wakes up periodically it automatically sends a short polling query to the PAN Coordinator

256

Exploring Cyclic-Sleep Operations
1. Poll Request
End-device
Module

2. Acknowledge
(No Data)

Coordinator
Module

1. Poll Request
2. Acknowledge
(No Data)
End-device
Module

3. Data/Command

Coordinator
Module

4. Acknowledge

FIGURE 22.5 The sequences in this diagram show how an End-device module will poll a
Coordinator when it wakes up and how the Coordinator will respond.

module, as shown in Figure 22.5. If the Coordinator has no command or data
for the End-device module the Coordinator module replies with a no-data
acknowledgement.
On the other hand, when the Coordinator has a command or data for the
awakened End-device module, the Coordinator responds with a data acknowledgement, followed by the command or data in a standard API packet. After
the End-device module receives the command, it replies to the Coordinator
with an acknowledgement message to signal the command arrived properly. (Digi refers to this as an indirect transmission, but it seems more like a
deferred transmission.)
Assume you want an End-device module to wake up every 10 seconds
and ask the Coordinator if it has a command for it. The indirect- or deferredmessage configurations use the same sleep settings described previously: Sleep
Mode (SM), Sleep Options (SO), Cyclic Sleep Period (SP), and Time Before
Sleep (ST). Commands directed to a sleeping module must use the 64- or
16-bit address for each End device. Do not try to use broadcast messages with
sleeping modules.
In this section, you will configure one XBee module as a Coordinator and
one XBee module as End device. Many of the configurations set for the previous Periodic Wake-Up with I/O Report section still apply here.
You may add a second End-device module if you wish, but I recommend
you first run the steps that follow with one module and then go through the
experiment again with additional End-device modules, if you have them.

Periodic Wake-Up with Coordinator Polling

257

Set Up the End-Device Module
Step 6. Place your End-device XBee module in the USB-to-XBee adapter
and use the X-CTU software to Read its Modem Configuration information.
(This section uses configuration settings in the file EX22_End_B.pro.)
Look under the Sleep Modes (NonBeacon) heading and change the Sleep
Options as shown below:
SO – Sleep Options   2 (poll, no sample)
Click on Write to save this configuration in the attached End-device module.
After you have programmed the End-device module, remove it from the
USB-to-XBee adapter and set it aside and keep it separate from the XBee
module you will use in the next steps.

Coordinator Module
Step 7. Place the XBee module you will use as the Coordinator in the
USB-to-XBee adapter and use the X-CTU software to Read its Modem
Configuration information. (This section uses configuration settings in the file
EX22_Coord_B.pro.)
Look under the Sleep Modes (NonBeacon) heading and change the Cyclic
Sleep Period as shown below:
SP – Cyclic Sleep Period   3E8 (10 seconds)
You might wonder why the Coordinator requires a Cyclic Sleep Period if it
will never enter a sleep mode. The Coordinator module should have its Cyclic
Sleep Period set to the longest Cyclic Sleep Period of any of the End-device
modules in your network. The Coordinator module must know this timing
value so it can hold a command or data for an End-device module for two and a
half times (2.5x) this period, as shown in Figure 22.6. Say you set a 10-second
Cyclic Sleep Period for your End-device modules and the Coordinator. The
Coordinator will hold for 25 seconds a command or data for an End device.
That long period ensures the End-device modules will all wake up at least two
times during this 25-second period. If an End-device module does not pick up
its message during this 25-second period, the Coordinator purges the waiting
command and sends an error message via its UART TX pin. A host microcontroller could interpret this message and take appropriate action.
Recheck your setting. Then click on Write to save this configuration in the
attached Coordinator module.
Leave the Coordinator module in the USB-to-XBee adapter.
Step 8. Place your End-device module in the XBee adapter in your solderless breadboard that already has the connections shown earlier in Figure 22.1.
The Coordinator module already has power connected via the USB-toXBee adapter. Turn on power to your End-device module and note the behavior of the LEDs.
I saw both LEDs turn on and remain on for about four seconds, after which
they turned off. After remaining off for 10 seconds the LEDs flashed briefly

258

Exploring Cyclic-Sleep Operations
2.5 time Longest Cyclic–Sleep Period

Coordinator Receives Command for End–device X

Periodic End–device Wake Ups
End device C

End device D

Longest Cyclic–Sleep Period

FIGURE 22.6 This diagram shows the times at which the Coordinator receives short
polling messages from End-device modules C and D that have different cyclic-sleep periods. Device D has the longest period, so you set the Coordinator’s cyclic-sleep period equal
to that for Device D. Thus the Coordinator holds data or a command for any End-device
module for 2.5 times this period. That extended period allows enough time for all End
devices to poll the Coordinator at least twice and receive data or a command addressed
to them.

and turned off. They produced a short flash again every 10 seconds, which
corresponds to the Cyclic Sleep Period (SP) set for the End-device module.
The periodic LED flashes correspond to the time when the module wakes up
and polls the Coordinator for any waiting commands. You haven’t sent the
Coordinator data or a command for the End-device module, so it just goes
back to sleep.
Step 9. Open the Terminal window in the X-CTU software, click on Clear
Screen, then on Show Hex, and finally on Assemble Packet. Now you will create an API packet for the Force Sample (IS) command to force the End-device
module to transmit information about the four input pins you set up earlier.
Use the packet framework shown below:
7E 00 0F 17 52 __ __ __ __ __ __ __ __ FF FE 02 49 53

__

Insert the eight address bytes for your End-device module and calculate the
checksum. Insert the checksum as the last byte on the right. Go to Table 22.1
for the address information. In the Send Packet window, go to the bottom right
corner and select HEX. Type in your hex characters for the API packet.
Step 10. Move your cursor over the Send Data button but do not click it
now. Watch the LEDs on the End-device module. A second or two after they
turn off, click on Send Data, and watch the X-CTU Terminal window. What
happens in the Terminal window?

Periodic Wake-Up with Coordinator Polling

259

I saw my transmitted packet and about nine seconds later the window displayed the information transmitted to the Coordinator from my End-device
module, as shown in bold type below:
7E 00 0F 17 52 00 13 A2 00 40 49 E0
EC FF FE 02 49 53 F1 7E 00 18 97 52
00 13 A2 00 40 49 E0 EC FF FE 49 53
00 01 14 05 00 04 01 47 02 24 E7

Based on information in Experiment 20, you can parse the End-device
module’s information to learn about the state of the digital and analog inputs.
Adjust the potentiometer and send the API packet again. Can you see a difference in the data you receive?
Step 11. While the End-device module is in its sleep state (CTS LED off),
watch the LEDs as you send the API packet again. What do you observe when
the End-device module wakes up?
In my lab I saw the Associate LED flash and the CTS LED remained lit for
five seconds. This period corresponds to the Time before Sleep you set at five
seconds for the End-device module. So the module remained active for that
period. If you transmit the API packet while the CTS LED remains lit, you will
see an immediate response to the IS command packet. Now the Coordinator
does not have to wait for the module to wake up, so it sends your command
immediately.
Step 12. Clear the Terminal window and position the cursor over the Send
Data button. Click on the Send Data button and when the CTS LED turns on,
click on the Send Data button again and again. You should see many responses
in the Terminal Window.
After the End-device module sends the last response, it waits again for
five seconds before it goes back into the sleep mode. During its awake period,
the End-device module responds immediately. And each communication to or
from the End-device module restarts the 5-second timer.
You could use this mode and the IS command when you have devices that
only need to report information when commanded by a computer or MCU
attached to the Coordinator module’s serial port. There’s no need to have them
wake up and report information if you don’t need it. And such periodic wakeups use precious battery energy.
Step 13. Suppose you send an API command to an End-device module that
has a dead battery, has sustained damage, or got moved out of range. What will
happen?
Turn off power to your End-device module and clear the X-CTU Terminal
window. Now click on Send Data button in the Send Packet window. What
happens? You will have to wait for a while to find out.

260

Exploring Cyclic-Sleep Operations

After 25 seconds, my Terminal window displayed:
7E 00 0F 17 52 00 13 A2 00 40 49 E0
EC FF FE 02 49 53 F1 7E 00 0F 97 52
00 13 A2 00 40 49 E0 EC FF FE 49 53
04 6F

Why the 25-second delay? The Coordinator module will hold the command packet for the full two and a half times the Cyclic Sleep Period, which
you set to 10 seconds. During this period it expects the addressed End-device
module to wake up and get its message. But with no End-device module available, the 25-second period times out and the Coordinator responds with an
error message. The next-to-the-last byte (0x04  No Response) in the message
above lets you know the Coordinator module had no response from the module
with the 64-bit address:
SH  0013A200 and SL  4049E0EC
during the 25-second period shown earlier in Figure 22.6. Of course, you can
alter the Time Before Sleep and the Cyclic Sleep Period to any times you
choose rather than the times used in this experiment.
Important: An XBee Coordinator can hold only two (2) pending messages. As far as I know, you cannot have a microcontroller query a Coordinator
to determine how many messages—if any—it has waiting to send to sleeping
End devices. Software could increment a count for every message sent to a
Coordinator and decrement the counter when the MCU receives a response. That
count should give you the number of messages still pending in the Coordinator.

The Hands-on XBee
Lab Manual

The Hands-on XBee
Lab Manual
Experiments that Teach you XBee
Wireless Communications

Jonathan A. Titus

AMSTERDAM • BOSTON • HEIDELBERG • LONDON
NEW YORK • OXFORD • PARIS • SAN DIEGO
SAN FRANCISCO • SINGAPORE • SYDNEY • TOKYO
Newnes is an imprint of Elsevier

Acknowledgments
Thanks go to the technical-support people at Digi International for their courteous and timely help answering questions and for pointing me to application
notes that helped overcome several problems. I also found useful information
on Web pages that cater to experimenters and on highly technical Web sites.
I also appreciate the book-proposal reviews from Bradley J. Thompson,
Alex Mendelsohn, Ken Gracey, and Dr. Michael Batchelder. All had worthwhile comments and suggestions that improved this book.

xiii

Dedication
I dedicate this book to Jane, my wife and companion for over 40 years, and to
our grandchildren, Delia, Samuel, and Laney.

Newnes is an imprint of Elsevier
The Boulevard, Langford Lane, Kidlington, Oxford OX5 1GB, UK
225 Wyman Street, Waltham, MA 02451, USA
First edition 2012
Copyright © 2012 Elsevier Inc. All rights reserved
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means electronic, mechanical, photocopying, recording or
otherwise without the prior written permission of the publisher
Permissions may be sought directly from Elsevier’s Science & Technology Rights
Department in Oxford, UK: phone (44) (0) 1865 843830; fax (44) (0) 1865 853333;
email: permissions@elsevier.com. Alternatively, you can submit your request online
by visiting the Elsevier web site at http://elsevier.com/locate/permissions, and selecting
Obtaining permission to use Elsevier material
Notice
No responsibility is assumed by the publisher for any injury and/or damage to persons
or property as a matter of products liability, negligence or otherwise, or from any use
or operation of any methods, products, instructions or ideas contained in the material
herein. Because of rapid advances in the medical sciences, in particular, independent
verification of diagnoses and drug dosages should be made
British Library Cataloguing-in-Publication Data
A catalogue record for this book is available from the British Library
Library of Congress Cataloging-in-Publication Data
A catalog record for this book is available from the Library of Congress
ISBN: 978-0-12-391404-0
For information on all Newnes publications
visit our web site at books.elsevier.com
Typeset by MPS Limited, Chennai, India
www.adi-mps.com
Printed and bound in United States of America
12 13 14 15

10 9 8 7 6 5 4 3 2 1

Introduction
This book will appeal to engineers, product designers, entrepreneurs, teachers,
experimenters, and students who want to learn how to use the popular XBee
wireless-communication modules from Digi International without having to
master radio engineering or complicated communication protocols. You can
power an XBee module and have it communicate with other XBee modules in
a few minutes. As always, though, the devil is in the details, so the experiments
start with basic information about how to use the Digi International X-CTU
software that simplifies the setup and use of XBee modules. You will learn
how to use one-way communications from remote modules that report digital
and analog information. Experiments also explain how to set up 2-way communications between separate modules or among modules in a small wireless
network.
As you learn about communications, you’ll gather other information
not explained in other books or application notes. That includes using sleep
modes, causing a remote module to immediately wake up, how to use pulsewidth modulation, and so on. Later experiments introduce the Arduino Uno
and ARM mbed microcontroller (MCU) modules and provide code that
allows for two-way communications between a PC and a remote MCU module. Instructions explain how to use either an ARM mbed or an Arduino Uno.
Software experiments also show how to identify an unknown number of XBee
modules in a small network and how to obtain remote digital and analog information and provide it in useful formats. Keep in mind this book does not
describe a series of projects, rather it explains how XBee modules communicate digital and analog information, how to understand that information, how
to configure modules, how to set up a network of modules, and so on. Then
you apply your creativity and design products or build projects based on what
you learned here.
When I started to investigate how to use XBee modules I downloaded the
technical manual from Digi’s Web site and reviewed the specifications and
settings. I also looked in forums and technical-support pages to find information about how to use XBee modules. Unfortunately, the technical manual
describes a lot of commands and operating conditions, but it doesn’t explain
how to use that information to do useful things. The forums and tech-support
Web sites often addressed specific questions such as “I have a problem getting
ABC to work…” or “How do I connect an XBee to a pressure sensor?” That
type of information helps only a few people solve a specific problem.
So, I decided to jump into the XBee “experience” to learn what the
modules could do and how to use them without prior knowledge. Thus the

xv

xvi

Introduction

experiments explain how you can use the XBee modules to communicate with
each other and I leave the details of what to communicate up to each reader.
Some people might need to transmit analog signals from sensors and others
might choose to monitor alarm switches on doors and windows. How you use
the modules is up to you, and you will know how to use the XBee modules
after you go through the experiments in this book. These experiments do not
cover ZigBee-protocol networks. Other books provide that information.
The experiments use standard XBee modules and readily available and
inexpensive components and supplies. You can run most of the experiments
without any knowledge of electronics or programming, but experience programming with a language such as BASIC or C will help in a few experiments.
Experience using digital logic and breadboarding circuits will help, too. You
must read schematic diagrams, place components in breadboards, and make
connections accordingly. The text explains what to do.
Some explanations might seem elementary, but I find it better to address
people unfamiliar with electronics and let experts skip through basic information. Although each unit can serve as a stand-alone experiment, I encourage
readers to start with Experiment 1 and go through them sequentially.
I recommend the Digi XBee modules, model number XB24-ACI-001, that
operate in the 2.4 GHz Industrial, Medical, and Scientific (ISM) band that
requires no license, complies with international standards, and conforms to
the Institute of Electrical and Electronic Engineers (IEEE) 802.15.4 standard.
You can purchase modules directly from Digi International or from distributors
worldwide.
In a few cases, I had an XBee module go off into “unknown territory,”
probably because of an error in one of my configuration settings. If that happens, you can quickly reset a module with its factory-default settings and get
back on track.
The XBee modules can respond to 68 commands, many of which I never
used and I doubt most users will need to use. A book of experiments cannot
cover every command, so you experiment as you see fit. Because I worked
on a lab bench and within a small building I did not change the output radiofrequency power-level (PL) setting from the factory default. Nor did I use any
of the seven diagnostic commands.
Before you start the experiments, download and print the latest manual, “XBee/XBee-PRO RF Modules” from the Digi International Web site
at: www.digi.com. I had the manual version 90000982_B. This document
describes the control commands, the parameters they need, and what they do.
You must have the free Digi X-CTU software that runs on a Windows
PC. This software lets you easily monitor XBee activity, send an XBee module command, test communications with a remote XBee module, and configure modem settings. Digi uses the word “modem” for the control portion of
an XBee module, but this book simply calls the XBee devices modules. My

Introduction

xvii

modules had firmware version 10E6. Digi used hexadecimal values for version
numbers and you can check the version number through the X-CTU software.
I ran into a couple of problems with the X-CTU software that deserve mention. First, set up a USB-to-XBee adapter and connect it to your PC via a USB
cable before you start the X-CTU software. At times when I started the software first, it did not recognize the USB-to-XBee adapter when I plugged it
in. Second, on occasion the X-CTU software quit unexpectedly if I used the
mouse trackball or scroll wheel to move up or down within an X-CTU window. If you have set up a long command packet you will lose it. Third, you
cannot save packets from within the X-CTU software, so write them down.
Finally, if you have boxes open within the X-CTU Modem Configuration window and use a mouse trackball or wheel, the choices in the open box will scroll
rather than the larger configuration window.
Now some information specific to the experiments.

CODE DOWNLOADS
You can download all code used in the experiments and use it freely:
http://www.elsevierdirect.com/companion.jsp?ISBN  9780123914040
Each experiment has a folder that holds the necessary code or XBeeconfiguration information, although a folder marked “None” indicates an
experiment has no corresponding software. To save time, experiment folders
include Modem Configuration files, which have the .pro file extension, to use
with the X-CTU software to set XBee-module parameters. If you get stuck and
something doesn’t seem to work, load the provided configuration file into the
X-CTU software and save it in the module.
I consider my code open source and hope readers will modify it and share
it with others. The code includes an Excel spreadsheet, Packet Creator 2, that
will help you create hexadecimal messages or packets used in some experiments or in microcontroller code. You should purchase a calculator that can
handle hexadecimal values. Texas Instruments and Casio have several such
inexpensive models.
I will post comments, corrections, new code, and other information on the
http://www.elsevierdirect.com/companion.jsp?ISBN9780123914040 site and
readers can contact me directly at jontitus@comcast.net. I will do my best to
answer questions but cannot guarantee a personal reply. But before you contact
me or post a question on a forum, locate helpful XBee-related information on
the Internet, on the Digi tech-support pages, and on the support pages for the
ARM mbed and Arduino Uno products.

CODING STYLE AND ERROR CHECKING
I have kept programs and flow charts simple so people who do not have much
experience can follow their operations. Feel free to change the software to

xviii

Introduction

meet your needs. You can always restore XBee modem configurations to
factory-fresh settings and it’s unlikely you will damage a microcontroller by
running programs that contain errors. The C compilers catch syntax errors but
not logical errors; those in which you use an incorrect value, perform an incorrect operation, and so on.
In some cases I provide working code that lacks all the steps a professional
programmer would include to detect errors and take corresponding actions.
In many cases, error-detection code can take as much room as your “working” code. I’ll put a “place holder” in the code and include a note about testing for errors where it seems appropriate. Never assume that your code works
properly until you test it thoroughly. And never assume errors cannot occur. I
make no claim to special programming expertise and welcome suggestions that
help others create better or more-efficient code.
I use a programming “style” that vertically aligns code sections and subsections and find it easier to follow code in this form:
byte SerialInput()
{
while(Serial.available() == 0)
{
more code here...
}
return (Serial.read());
}

rather than code in the following form:
byte SerialInput(){
while(Serial.available() == 0){
}
return (Serial.read());
}

where it’s difficult to identify pairs of braces that define code sections. Of
course, you can use any format you wish.

DEBUGGING CODE
You can do some debugging on an MCU by using an output pin to drive an
LED. When the MCU gets to a certain place, it can turn the LED on or off, or
flash it at a preset rate. You also can easily track variables and print messages
at “checkpoints” in your code. The ARM mbed module provides a separate
USB virtual serial port that will send debugging or test information to your
PC. For the ARM mbed module I used the Windows HyperTerminal to print
such information.
The Arduino Uno module has a USB connection with a host PC, but it
shares its serial port with the TX and RX pins on the board, which can cause
conflicts unless you do not connect devices to the Uno’s serial-port pins. The

Introduction

xix

newer Arduino Mega2560 module and the Digilent chipKIT Uno32 have extra
serial ports, but I have not used these modules.

DIGITAL LOGIC NOTATION
The experiments that follow use digital signals that exist in either a logic-0 or
a logic-1 state. By convention, engineers use an “over-bar” above the corresponding signal name to indicate a logic-0 level will cause an action to occur,
enable another digital device, cause a reset, and so on. Even with a word processor, creating an over-bar causes headaches, so a forward slash (/) in front of
a signal name will indicate a logic 0 causes the named action. Thus, a signal
named /RESET will reset the device the signal goes to. On the other hand, an
input named LOAD, for example, requires a logic 1 to cause a loading action.
Some authors use an asterisk in front of signal names in place of a slash.

SCHEMATIC DIAGRAMS OF CIRCUITS
The schematic circuit diagrams in the experiments and appendices use standard electronic symbols for components. Sometimes when people draw circuits and then convert them to a computer-drawn diagram, errors occur. When
you see signals come together as shown in Figure I.1a, you might wonder
whether they connect at this point or one signal simply passes over the other.
To avoid confusion, the experiment circuit diagrams have no 4-point connections. Instead, you see only 3-way connections as shown in Figure I.1b. This
drawing style eliminates ambiguity.

INTERMITTENT ARDUINO UNO PROBLEMS
I had intermittent problems with Arduino Uno modules because they use the
same serial port at pin 0 (RX) and pin 1 (TX) to connect with external serial
devices, such as XBee modules and with the host PC USB connection used
–

–
No connection

2
1

(a)

–

2
1

A
B

–

(b)

FIGURE I.1 (a) In this book, the intersection of two lines means a “fly over” of two separate wires. It is not a 4-way connection of signals. (b) A dot on the lines indicates when
three signals connect at A and at B. To avoid ambiguity, this book uses only three-wire connections in schematic diagrams.

xx

Introduction

to download programs. Often my Arduino compiler window would display the
following information in the bottom text-message window:
Problem uploading to board: See http://www.arduino.cc/en/Guide/
Troubleshooting#upload for suggestions.
Binary sketch size: 2284 bytes…etc…
The Arduino Uno Troubleshooting Guide recommends several solutions,
including removing anything connected to pin 0 and pin 1. I found this step annoying and used a switch to disconnect pins Uno 0 and 1 from my external circuits
during a code download. I don’t know how the Arduino people expect experimenters, hobbyists, and others to continually disconnect and reconnect circuits to the
pin 0 and pin 1 contacts. The Arduino Mega and the Digilent chipKIT Uno32 modules provide extra serial pins and do not share them with a PC USB connection.
On occasion, the Arduino Uno compiler would not “find” the attached Uno
module and would report finding only the COM1 port. Connecting and reconnecting the Uno module, pressing its reset button and starting and restarting
the Uno software did not help.
I also ran into another problem in later experiments that transmit information from the Arduino Uno module to the host PC for display in the Serial
Monitor window available within the Uno programming framework. Data
transmitted to the Serial Monitor also went to any attached XBee module.
This “dual connection” means the XBee module “sees” the data going to the
Serial Monitor as a string of bytes that might inadvertently include a valid but
unwanted command, or the bytes might cause the XBee module to return an
error packet. In several cases, after sending information from the Uno module
to the host PC, the XBee module attached to the Uno acted in unexpected ways.
The experiments that use a Uno module include steps that help circumvent these
problems, but after a short time, disconnecting and reconnecting serial-port
lines becomes annoying. Use a switch as described in the relevant experiments.
The Arduino Uno Web site provides information about how to use other
I/O pins for serial communications implemented in MCU code rather than in
hardware. The limitations of these software-serial communications prevent
their use in these experiments with XBee modules. Frankly, if I started writing
again I would drop the Arduino Uno and use a newer board that offers several
serial ports. Help is at hand.

A NEW 32-BIT UNO BOARD
Shortly after I completed the Arduino Uno experiments, Digilent and Microchip
Technology announced the chipKIT Uno32 board that offers software and hardware compatibility with the Arduino Uno module. The chipKIT Uno32 gives
you an 80-MHz 32-bit processor (PIC32MX320F128H) that provides a wide
variety of I/O devices, 128 kbytes of flash memory, and 16 kbytes of static
memory. The MCU includes two UARTs, one for the USB connection with a
host PC and one for use with your own devices, such as displays, XBee modules, a small printer, and so on. So you should not have problems with serialport conflicts. The PIC32MX320F128H MCU connects the extra UART, #2, via

Introduction

xxi

the SDI2 (serial-data input) and SDO2 (serial-data output) pins on the Uno32
SPI connector (J8). The MASTER and SLAVE jumpers at JP5 and JP7 let you
change the pinouts for the SDO2 and SDI2 signals. Unfortunately, the Digilent
schematic diagram for the Uno32 module does not show the difference between
the MASTER and SLAVE modes, which simply swap the serial lines on the
SPI connector between pins 1 and 4. Pin 6 provides a ground connection.
In time I’ll post some code for the chipKIT Uno 32 that shows how to use
the SDI2 and SDO2 UART.

LOGIC-LEVEL CONVERSION
Because the XBee modules operate with a 3.3-volt power source they should
not connect to 5-volt logic signals. The Appendices include information about
how to construct two logic-level-conversion circuits that solve this problem.
If you use a 3.3-volt MCU or MCU board such as the ARM mbed, you don’t
need to convert logic levels.

EQUIPMENT
The Bill of Materials in Appendix F lists the minimum and recommended
quantities of components for the experiments. And this appendix includes
information about electronic equipment and suppliers.

FREE-SOFTWARE CODE LICENSE
Readers have access to the software included in this book under the following
Massachusetts Institute of Technology free-software license:

Copyright © 2012 by Jonathan A. Titus
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the “Software”), to
deal in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


xxii

Introduction

ACKNOWLEDGMENTS
Thanks go to the technical-support people at Digi International for their courteous and timely help answering questions and for pointing me to application
notes that helped overcome several problems. I also found useful information
on Web pages that cater to experimenters and on highly technical Web sites.
XBee and XBee-PRO are trademarks of Digi International. Other trademarks belong to their respective owners. I have no financial interest in any of
the companies or products mentioned in this book.
Jonathan A. Titus, KZ1G
Herriman, Utah, USA

Foreword to The Hands-on
XBee Lab Manual
The late 20th century saw the birth of connectivity. From simple computer networks the Arpanet grew into the Internet. At first the playground of academics,
nearly everyone is now connected to the “net” and therefore to everyone else
and to vast amounts of data.
The 21st century has seen the dawn of the wireless era. Cell phones are
no longer telecomm devices; they’re part of the vast Internet. Now we’re all
connected all of the time, in the office or at the beach. Some of us use a smart
phone more for data communications that voice transmissions. Indeed, that
mobile device may have four or more antennas: one with a link to satellites
in space for navigation, another to the 3G network, a wi-fi connection and
Bluetooth for near-field links to headsets and the like.
Radio data communications surround us, from messages sent to the smart
sign hanging over the highway to science instruments transmitting their findings from remote Arctic regions to a lab in some pastoral setting via a satellite
uplink.
Why have a Bluetooth link from the phone to a headset? A wired approach
is a nuisance. It’s bulky, in the way, and snags on things. Electronics is cheap;
connectors are not, and the wireless version likely saves money and is more
reliable. Messing with a tangle of cables in a lab or even with your PC is awkward. It won’t be long before those all go away.
It’s much more complicated to establish a link over an RF connection
than with a wire, but smart hardware costs little today, and canned software is
increasingly available. One popular option is Digi International’s line of XBee
prepackaged radio modules. You don’t need to understand the nuances used,
like direct-sequence spread spectrum coding or offset quadrature phase-shift
keying, because those details are all taken care of by the modules.
You do need to understand how to use and interface to the modules, which
is not made any easier by the terse and sometimes cryptic manuals. And XBee
also uses the old AT command set, which is increasingly hard to find information about. For these reasons Jon Titus’s Hands on XBee Lab Manual is
invaluable.
We learn in different ways. For many of us a hands-on approach is much
more efficient than slogging through data books. Jon has taken that approach
here, in a series of experiments designed teach by doing. From the very beginning you’ll be putting together components that make something neat happen.
Early experiments emulate a single-direction wire: a receiver module’s output
pin mirrors the input pin on the transmitter. Look Ma—no wires!
xi

xii

Foreword to The Hands-on XBee Lab Manual

Each lesson is progressively more complicated and useful. Send analog
data through the ether. Control multiple XBee modules. Connect other embedded components, like an Arduino Uno or ARM mbed board to the XBee modules. That, of course, is really the basis of embedded wireless networking.
Explore personal-area networks. These are self-assembling communications links where the network discovers at run time which XBee modules are
operating. Jon shows how to do this, and how to piece the network together.
Along the way you’ll learn to handle interrupts, a crucial concept in the world
of embedded systems.
Complex stuff. But fear not: Jon shows every step of each experiment. The
lavish illustrations leave no chance for confusion. Whether it’s a screen shot of
a communications tool or a drawing of how to connect a LED, nothing is left
out.
Welcome to the second decade of the 21st century, the age of wireless data
communications. This book is your essential guide to using XBee modules to
toss off the shackles of wires.
Jack Ganssle

Appendix A
Logic-Level-Conversion
Circuits
Most microcontroller (MCU) chips, boards, and modules operate with either a
5-volt or a 3.3-volt power source. The XBee modules, for example, require a
3.3-volt power supply and create logic signals with the following voltages:
3.3-volt logic: Logic 1  2.4 to 3.3 volts
 	
Logic 0  0.0 to 0.4 volts
An MCU module such as the Parallax BASIC Stamp BS2 module and the
Arduino Uno board operate with 5-volt logic signals and they operate with
signals in the following ranges:
5-volt logic:
Logic 1  2.4 to 5 volts
 	
Logic 0  0.0 to 0.4 volts
At first glance the logic levels seem somewhat compatible, and you can
find schematic diagrams for resistor-only circuits that convert 5V-to-3.3V logic
levels. But converting 3V logic signals to 5V signals requires semiconductors.
The SparkFun Electronics BOB-08745 board handles four signals, two for
5V-to-3.3V logic signals and two for 3.3V-to-5V logic signals. I have not tried
this circuit, though.
While creating the experiments in this book, I used a Texas Instruments
SN74LVC4245 “Octal Bus Transceiver” integrated circuit (IC) that shifts the
logic level of as many as eight separate signals. The IC lets you choose to
have it convert either 3.3V to 5V logic signals or 5V to 3.3V logic levels. Thus
you would need two SN74LVC4245 ICs. Because the IC comes in a 24-pin
small-outline integrated circuit (SOIC) surface-mount package, it cannot drop
into a solderless breadboard with contacts on 0.1-inch centers. A small board
such as the SchmartBoard “1.27 mm Pitch SOIC to DIP adapter,” part number
204-0004-01, will handle SOIC devices and connect them to pins on 0.1-inch
centers. See the Bill of Materials in Appendix F for component information.
I used two such boards, one for 5V-to-3.3V conversions and a second for
3.3V-to-5V conversions. The diagram in Figure A.1 shows the pin numbers
and signal names for an SN74LVC4245. You supply 5 volts, 3.3 volts,
and ground. The Output Enable (/OE, pin 22) always connects to ground. The
Direction (DIR) input connects to 5 volts through a 1000-ohm resistor for
261

262

Appendix A

5V-to-3.3V conversions or it connects to ground for 3.3V-to-5V conversions.
The “A” side of the SN74LVC4245 IC always operates with 5-volt input or
output signals, while the “B” side always operates with 3.3-volt input or output
signals. In Figures A.2 and A.3, the large arrow drawn within the 74LVC4245
+5 Volts
DIR
A1
A2
A3
A4

5V Logic

A5
A6
A7
A8
GND
GND

1

24

2

23

3

22

4

21

74LVC4245

5

20

6

19

7

18

8

17

9

16

10

15

11

14

12

13

+3.3V
+3.3V
/OE
B1
B2
B3
B4
B5

3.3V Logic

B6
B7
B8
GND

FIGURE A.1 Pin numbers and corresponding signal names for an SN74LVC4245 logiclevel-conversion IC in a 24-pin SOIC package.

+5V

+5V

1000 ohms

+3.3V

1
2
A1
A2
A3
A4

5V Logic

A5
A6
A7
A8

24
23

DIR

3
4
5

/OE
74LVC4245

22
21
20

6

19

7

18

8

17

9

16

10

15

11
12

14

GND
GND

GND

B1
B2
B3
B4
B5

3.3V Logic

B6
B7
B8

13

GND

FIGURE A.2 Connections for an SN74LVC4245 IC used to convert 5-volt to 3.3-volt
logic levels. Note the 1000-ohm resistor at pin 2 (large upward arrow) and its connection
to 5 volts. The right-pointing arrow indicates the direction of signal flow. Always ensure
you have a common ground between 5-volt and 3.3-volt power sources.

Appendix A

263

indicates the signal flow. The up or down arrow points to the direction-control
portion of the circuit so you make the proper connection for the type of
conversion you need.
In the experiments, you will see the logic-level-converter circuits referred
to as “LLC-3-to-5” (three to five) for the 3.3V-to-5V conversions and as “LLC5-to-3” (five to three) for the 5V-to-3.3V conversions. Again, the “A” side of
each LLC always operates with 5V signals (in or out) and the B side always
operates with 3.3V signals (in or out).
For the SN74LVC4245 ICs mounted on adapters I used only 24 header
pins and placed the pins and the IC to the far left as shown in Figure A.4. I
recommend you make somewhat permanent connections to power and ground,
and leave the adapters in a breadboard, as shown in Figure A.5.
The SchmartBoard adapters use a unique way to hold devices in place during soldering and the pads alone provide enough solder. You do need a hightemperature soldering iron with a fine tip. Visit the SchmartBoard Web site for
soldering information.
When you solder a board like this to pins on 0.1-inch centers, place the
header pins in a solderless breadboard to start, next place the circuit board on
the headers, and then solder the pins. This technique properly aligns the pins

+5V

+3.3V

1
2
GND

A1
A2
A3
A4

5V Logic

A5
A6
A7
A8

24
23

DIR

3
4
5

/OE
74LVC4245

22
21
20

6

19

7

18

8

17

9

16

10

15

11

14

12

GND
GND

GND

B1

GND

B2
B3
B4
B5

3.3V Logic

B6
B7
B8

13

GND

FIGURE A.3 Connections for an SN74LVC4245 IC used to convert 3.3-volt to 5-volt
logic levels. Note the ground connection to ground at pin 2 (large downward arrow).
The left-pointing arrow indicates the direction of signal flow. Always ensure you have a
common ground between 5-volt and 3.3-volt power sources.

264

Appendix A

FIGURE A.4 A SchmartBoard 28-pin SOIC adapter with an SN74LVC4245 IC and
header pins soldered in place.

FIGURE A.5 Two logic-level-conversion circuits in a solderless breadboard. Note the
labels that indicate the conversion that occurs in each adapter.

and holds them in place for soldering. Keep the board in the solderless breadboard when you solder the IC pins. It’s easier to solder when the breadboard
provides stability.
SparkFun Electronics: www.sparkfun.com.
SchmartBoard: www.schmartboard.com.

Appendix B
Hexadecimal Numbers and
Checksums
The Digi X-CTU software that configures XBee modules uses hexadecimal
values represented by digits 0–9 and letters A–F, which equal the decimal values 0 through 15. This hexadecimal numbering system provides an easy way to
represent four-bit binary numbers that comprise only 1s and 0s. Each hex digit
represents a 4-bit binary value, from 00002 through 11112, or from 0x0 to 0xF
as shown in Table B.1. The prefix of zero followed by the letter x indicates a
value expressed in the hexadecimal numbering system. To represent an 8-bit

Table B.1 Equivalent Decimal, Hexadecimal, and Binary Values
Decimal

Hexadecimal

Binary

0

0

0000

1

1

0001

2

2

0010

3

3

0011

4

4

0100

5

5

0101

6

6

0110

7

7

0111

8

8

1000

9

9

1001

10

A

1010

11

B

1011

12

C

1100

13

D

1101

14

E

1110

15

F

1111

265

266

Appendix B

byte, people use two hex digits such as 0x5E, which corresponds to 9410, or
010111102. Two-digit hex values range from 0x00 to 0xFF, or in binary from
000000002 to 111111112, or in decimal from 0 to 255.
Instead of trying to learn how to manipulate hexadecimal numbers, I recommend you buy an inexpensive calculator that can do hex math and convert
to and from decimal (base-10) numbers. Texas Instruments and Casio sell
calculators with decimal, hexadecimal, and binary modes for under $US 20.
(Practice using a calculator with hex values because you can easily confuse a
lower-case B (b) with the numeral 6 on a 7-segment liquid-crystal display. A 6
usually has a top segment while a b does not.)

CHECKSUMS
Many digital-communication protocols sum the bytes in a packet of information to create a checksum that lets a receiving device detect an error. A simple
checksum scheme simply adds the bytes in a message and appends the sum at
the end of the message. So if you transmit the hexadecimal values:
0x09 0xFF 0x4F 0x56 0xA4 0x3B 0x1F
you would add the hex values and get a sum of 0x2AB. Because the communication uses bytes, you could send 0x02 followed by 0xAB. Many devices,
though, send only the 0xAB byte—the two least-significant hex digits from
the sum. The XBee modules do something similar. But instead of sending the
entire sum, they take the two least-significant (rightmost) hex digits of the
sum—0xAB in the example above—and subtract them from 0xFF to yield a
checksum. In the example above, the XBee module would calculate the checksum value as:
0xFF

− 0xAB = 0x54

which would then become the last byte sent, as shown in Table B.2.
An XBee module will automatically reject a command with an incorrect checksum. At times, though, you might need to perform a checksum
calculation on incoming data. When that need arises, a microcontroller
attached to an XBee module can add the received bytes and use this sum in
two ways:
l
Take the sum of the received bytes and keep only the two least-significant
hex digits. Subtract those digits from 0xFF. The result should match the

Table B.2 An Example of a Checksum for a Message Included in a Packet
0x09 0xFF 0x4F 0x56 0xA4 0x3B 0x1F

0x54

Message Bytes

Checksum
Packet

Appendix B

267

received checksum value. If it does not, the message contained an error.
Again for the message above:


l



0x09 + 0xFF + 0x4F + 0x56 + 0xA4 + 0x3B + 0x1F = 0x2AB
0xFF – 0xAB = 0x54

The checksum value you calculate should equal the checksum value appended
to the end of the message. If it does not, the message contains an error.
Take the sum of the received bytes and keep only the two least-significant
hex digits. Then add them to the received checksum. In the case of the
example above:
0x09 + 0xFF + 0x4F + 0x56 + 0xA4 + 0x3B + 0x1F = 0x2AB
0xAB + 0x54 = 0xFF

This calculation should always yield 0xFF unless the message contains an error.
Several software examples in this book use the first method, but you could
modify them to use the second method.
Important: The checksum used in XBee command and message packets
does not sum all of the bytes in a message or packet. An XBee packet starts with
the “start byte” 0x7E followed by two bytes that indicate the number of bytes
in the message or command portion of the packet, as shown in Figure B.1. The
checksum involves only the command or message bytes.

0x7E

MSByte
LSByte

Start Byte

Message-Length Bytes
0x1 to 0xFFFF

Message or Command
Bytes

Sum only these bytes to
calculate the checksum

Checksum

Figure B.1 Checksum calculations for XBee communications do not include the checksum
value, the start byte, or the two bytes that indicate the length of a message. Sum only the
Message or Command bytes.

268

Appendix B

A checksum will detect an error in a transmission caused by one bit that
changes state, but it cannot tell you which bit or in which byte. Other errordetection and -correction techniques can overcome this shortcoming, but they
go beyond the scope of this book. Visit the Wikipedia Web site for an article on
“Error detection and correction.”

Appendix C
Default ModemConfiguration Settings for
XBee (XB24) Modules
Table C.1 Default XBee Modem-Configuration Settings (Firmware version 10E6)
Networking & Security
(C) CH – Channel
(3332) ID – PAN ID
(0) DH – Destination Address High
(0) DL – Destination Address Low
(0) MY – 16-Bit Source Address
(XXXXXXXX) SH – Serial Number High (Depends on module)
(XXXXXXXX) SL – Serial Number Low (Depends on module)
(0) MM – MAC Mode
(0) RR – XBee Retries
(0) RN – Random Delay Slots
(19) NT – Node Discover Time
(0) NO – Node Discovery Options
(0) CE – Coordinator Enable
(1FFE) SC – Scan Channels
(4) SD – Scan Duration
(0) A1 – End Device Association
(0) A2 – Coordinator Association
(0) AI – Association Indication
(0) EE – AES Encryption Enable
KY – AES Encryption Key
( ) NI – Node Identifier

(Continued…)

269

270

Appendix C

Table C.1 Default XBee Modem-Configuration Settings (Firmware version 10E6)
(continued)
RF Interfacing
(4) PL – Power Level
(2C) CA – CCA Threshold

Sleep Modes
(0) SM – Sleep Mode
(1388) ST – Time Before Sleep
(0) SP – Cyclic Sleep Period
(3E8) DP – Disassociated Cyclic Sleep Period
(0) SO – Sleep Options

Serial Interfacing
(3) BD – Interface Data Rate
(0) NB – Parity
(3) RO – Packetization Timeout
(0) AP – API Enable
(FF) PR – Pull-up Resistor Enable

I/O Settings
(0) D8 – DI8 Configuration
(1) D7 – DIO7 Configuration (CTS Flow Control)
(0) D6 – DIO6 Configuration
(1) D5 – DIO5 Configuration (associated Indicator)
(0) D4 – DIO4 Configuration
(0) D3 – DIO3 Configuration
(0) D2 – DIO2 Configuration
(0) D0 – DIO0 Configuration
(1) IU – I/O Output Enable
(1) IT – Samples before TX
(0) IC – DIO Change Detect
(0) IR – Sample Rate

I/O Line Passing
(FFFFFFFFFFFFFFFF) IA – I/O Input Address
(FF) T0 – D0 Output Timeout

(Continued…)

Appendix C 
Table C.1 Default XBee Modem-Configuration settings (Firmware version 10E6)
(continued)
(FF) T1 – D1 Output Timeout
(FF) T2 – D2 Output Timeout
(FF) T3 – D3 Output Timeout
(FF) T4 – D4 Output Timeout
(FF) T5 – D5 Output Timeout
(FF) T6 – D6 Output Timeout
(FF) T7 – D7 Output Timeout
(1) P0 – PWM0 Configuration (RSSI)
(0) P1 – PWM1 Configuration
(FF) PT – PWM Output Timeout
(28) RP – RSSI PWM Timer

Diagnostics
(10E6) VR – Firmware Version
(1744) HV – Hardware Version
(0) DB – Received Signal Strength
(0) EC – CCA Failures
(0) EA – ACK Failures
(10000) DD – Device Type Identifier

AT Command Options
(64) CT – AT Command Mode Timeout
(3E8) GT – Guard Times
(2B) CC – Command Sequence Character
Highlighted configuration parameters are read-only.

271

Appendix D
Electronic and XBee
Resources
RESISTORS AND THEIR COLOR CODES
Resistors come in a variety of shapes and sizes, from near-microscopic
surface-mount chips to heating elements in electric stoves. The experiments
in this book use standard carbon-film 1/4-watt resistors with tolerances of 5
or 10 percent. These cylindrical resistors measure about six or seven milli­
meters in length and two millimeters in diameter and electrical leads extend
from each end.
Resistor manufacturers have adopted a standard that uses narrow colored
bands to “encode” a resistance value. The colors indicate two digits followed
by a multiplier. If you see a resistor marked with yellow-violet-red-gold bands,
you can use a color-code chart to determine its value. In this case, yellow  4,
violet  7, and red  2 zeros, or 4700 ohms. The gold band indicates a resistance tolerance of 5%. Find a good color-code chart on the Internet at: www.
michaels-electronics-lessons.com/resistor-color-code.html.
You can buy fixed resistors and potentiometers (trimmer resistors)
from electronics distributors such as Jameco Electronics, Digi-Key, Allied
Electronics, Mouser, and SparkFun Electronics. Resistor assortments include
standard values of carbon-film resistors, and those with a 5 or 10 percent
tolerance will suffice. See the list of suppliers and Web links at the end of this
Appendix.

BREADBOARDS
For the experiments I used solderless breadboards that measure about 2.25-by6.5 inches (5.7-by-16.5 cm). I like the large breadboards because I can fit a lot
of circuitry on them and they include power buses. I recommend people insert
some 0.1 microfarad (0.1 μF) disc-ceramic capacitors with a rating of at least
20 volts across breadboard power and ground buses. They, and a few 2.2 μF
50V aluminum electrolytic capacitors across the power rails, help attenuate
noise spikes. (Electrolytic capacitors have polarity, so connect the  terminal
to the  power-supply line.)

273

274

Appendix D

WORK AREA
I always use a static-dissipating mat under electronic projects to reduce the possibility of damage caused by electrostatic discharges between me and sensitive
components. If you do a lot of electronics work, in the long run a static-dissipating
work surface will save you money and frustration. The 3M 8810 ESD Rubber Mat,
for example, costs about US$75. You must connect such a mat to a good ground.
I also recommend you wear a static-dissipating wrist strap that connects to a snap
on the mat. Many distributors sell electrostatic-protection products.

XBee MODULES AND BREADBOARD ADAPTERS
I purchased XBee modules directly from Digi International. Companies such
as DigiKey, Parallax, and SparkFun Electronics also sell XBee modules.
Review the bill of materials (BOM) in Appendix F to identify the type of
module used in the experiment. If you cannot purchase these specific devices,
XBee modules for other frequency bands should work equally well and might
give you a longer range of wireless communications.
The XBee modules have connectors with pins on 2.0-millimeter centers,
but solderless breadboards have receptacles on 0.1-inch centers, so you will
need XBee adapters to connect XBee modules to breadboards. I purchased
adapters from Parallax and SparkFun Electronics.
The SparkFun adapter, or break-out board (part no. BOB-08276), does not
come with 0.1-inch male pins or 2-mm sockets, which you buy separately. This
board brings out all 20 pins from an XBee module and leaves enough space so
you can make either one or two connections to each pin via a breadboard.
The Parallax adapter (part no. 32403) comes with the needed pins and
sockets but it provides 22 pins for your breadboard, which might cause confusion when you count pins on an XBee module and want to make a connection to the Parallax adapter. I made a separate pin-out diagram for the Parallax
adapter so I could quickly decide which pins I needed to use. Appendix J
provides the XBee module pin-out information. The SparkFun adapter directly
follows the XBee module pin numbers.
When you solder pins to an adapter, place the pins in your breadboard and
then drop the adapter on them. The breadboard will keep the pins aligned as
you solder.
Pay careful attention to module orientation! If you reverse a module when
you plug it into an adapter and apply power, you could damage its electronics.
The adapters show the orientation of an XBee module. Orient all XBee modules
in the same direction. I always put the beveled end of an XBee module to my left.

XBee MODULES AND USB ADAPTERS
The experiments require a USB-to-XBee adapter so you can program configuration parameters in an XBee module and also communicate from a host PC to
an XBee module. I purchased two XBee USB Adapter Boards (part no. 32400)
from Parallax and used them throughout the experiments. These boards have

Appendix D

275

through-hole solder pads for pins on 0.1-inch centers, so if you wish you can
plug them into a solderless breadboard. I didn’t use the boards this way, though.
The USB-to-XBee adapter requires a Type-A-to-Mini-A USB cable, through
which the XBee module obtains its power from a host PC. Four LEDs on the
adapter indicate received signal strength (RSSI), power, Associate, and Sleep. I
found the LEDs helpful indicators of XBee operations.
Blue LED	PWM0-Received Signal Strength Indicator (RSSI), XBee
pin 6
Red LED
Associate-AD5-DIO5, XBee pin 15
Yellow LED Power at board
Green LED
ON-Sleep, pin 13

POWER SOURCES
I used two Extech Instruments model 382203 power supplies because I already
had them in my lab. You can purchase power supplies with fixed 3.3- or 5-volt
outputs or with a variable-voltage output. In most cases a well-regulated “wallwart” power cube will suffice. You also can buy open-frame power supplies,
but I highly recommend you NOT use this type of supply on a lab bench unless
you cover the line-power terminals. Otherwise they present a shock hazard.
Even some enclosed power-supply modules have exposed connections to line
voltage.
Amazon.com lists several suppliers of adjustable power supplies that will
power the circuits in this book. Even when an adjustable power supply comes
with a meter, I recommend you purchase an inexpensive digital multimeter
(DMM) so you can better adjust the power-supply output voltage and also test
voltages in your circuits.
As a fall-back, you could use two D-size batteries as a 3-volt power supply
and four D cells as a 6-volt power supply. By running the 6 volts through a
large diode, such as a 1N5401, you reduce the voltage sufficiently to power
5-volt devices and modules. You can buy plastic battery holders with electrical
terminals for a few dollars each.

TOOLS
Soldering requires a soldering iron with a fine tip. I do a lot of soldering and
use a Weller WESD51 solder station with variable-temperature control. You
not might need a complete station, but you will need a fine tip with a temperature of at least 670 degrees Fahrenheit, or 355 Celsius.
While debugging and testing experiments I used a Saleae “Logic” logic
analyzer, which decodes the serial packets transmitted to and from XBee modules and displays them as hex values or ASCII characters. Without the small
Logic pod I would not have penetrated some of the mysteries of how the XBee
modules operate or communicate. You don’t need a logic analyzer to complete
the experiments, but keep the inexpensive Saleae unit in mind if you need to
troubleshoot digital signals.

276

Appendix D

I used a Link Instruments MSO-19 combination digital storage oscilloscope, logic analyzer and pattern generator to capture analog signals and the
pulse-width-modulation signals from XBee modules. The MSO-19 and the
Logic module connect to a PC via USB cables.

SUPPLIERS
Allied Electronics, www.alliedelec.com
Amazon, www.amazon.com
BusBoard Prototype Systems, www.busboard.us
Digi-Key, www.digikey.com
Digi International, www.digi.com
Jameco Electronics, www.jameco.com
Link Instruments, www.linkinstruments.com
Mouser Electronics, www.mouser.com
Parallax, www.parallax.com
Saleae, www.saleae.com
SchmartBoard, www.schmartboard.com
SparkFun Electronics, www.sparkfun.com
Note: Mention of suppliers and products does not constitute an
endorsement. I have no financial interest in any companies or products used or
mentioned in this book.

Appendix E
Excel Spreadsheet
Packet-Creator Tool
The Excel spreadsheet Packet Creator 2.xls will help you create command
packets of bytes used in several XBee-module experiments. The spreadsheet converts decimal numbers and ASCII (American Standard Code for
Information Interchange) characters into their equivalent hexadecimal values
and calculates a checksum. It also helps you determine the byte count in a
message and will insert that value in the packet as two bytes.
To create an API command packet that uses an AT command or other information, run Excel and open the Packet Creator 2 spreadsheet (Figure E.1). The
sheet has a fixed Start Byte of 0x7E and you will not need to change this value.
The spreadsheet provides sample information so you can see how it works.
Do not enter values for message-length values Length MSBy or Length
LSBy because the spreadsheet calculates them for you.
Start at Msg Byte Count 1 and insert hexadecimal or decimal values, or
ASCII characters for the information you need to include in a command
packet. You can mix hex, ASCII, and decimal values as you wish. If you have
more than one value in a row, the spreadsheet always uses the left-most value.
Suppose you have entered values such those shown in Table E.1.
The first row produces a value of 0x9F, the second 0x5B, and the last 0x57,
the hex equivalent of the letter W. To avoid problems, enter only one value in
each row.
The Packet column provides the hexadecimal values for your packet. The
Decimal column on the right side serves only to compute the checksum. You
can ignore or hide this column, but DO NOT delete it.
After you insert all your values for a packet, the spreadsheet computes
the checksum. You MUST append the checksum hex value to the end of your
packet. The spreadsheet does not do that for you, which prevents you from
counting the checksum byte among your message bytes.
Use the numbers in the Msg Byte Count column to determine the length
of your message and insert that value in the Message Bytes box at the bottom
of the spreadsheet. The proper hex values appear automatically in the Length
MSBy and Length LSBy cells at the start of your packet.
Feel free to change or improve this spreadsheet as you wish. I provide it
under the license arrangements described in the Introduction to this book. If
you want to share your changes, let me know and I’ll post them for others.

277

278

Appendix E
Msg Byte Count

Hexadecimal

Start Byte
Length MSBy
Length MSBy
API Identifier

ASCII

Decimal

Packet

Decimal

7E
00
10
17
52
00
00
00

126
0
16
23
82
0
0
0

7E
0
16
1

17

2
3

52
00

4
5

00
00

Figure E.1 This portion of the Packet Creator 2 spreadsheet shows the columns in which
you may place hexadecimal or decimal values, or ASCII characters.

Table E.1 Examples of Entries in the Excel PacketCreator Spreadsheet
Hexadecimal

ASCII

9F

A

Decimal

21

5B
W

125

TROUBLESHOOTING
If you run into results that display #NAME? in a cell, install and load the
Analysis ToolPak add-in for Excel.

Appendix F
XBee Experiments Bill of
Materials
Line

Minimum Recommended Description
Qty
Qty

Supplier

Part No.

1

2

3

XBee XB24 module
(XB24-ACI-001)

Digi International
Parallax
SparkFun Electronics

X24-ACI-001
32406
WRL-08664

2

1

1

USB-to-XBee adapter

Parallax
SparkFun
Electronics

32400
WRL-08687

3

2

3

XBee adapter

Parallax
SparkFun Electronics

32403
BOB-08276

4

1

1

USB cable, type-A to
mini-B

Local supplier

5

1

2

Power supply, 3.3 volts

DigiKey

285-1887-ND

6

1

2

Battery holder, two
D cells

DigiKey

176K-ND

7

1

1

Power supply, 5 volts

DigiKey

285-1890-ND

8

1

1

Battery holder, four
D cells

DigiKey

BH24DL-ND

9

2

3

Solderless
breadboard

DigiKey
Jameco Electronics
SparkFun Electronics
BusBoard Prototype
Systems

438-1045-ND
2125026
PRT-00112
BB830

10

100-ft

100-ft

Wire, 22- or 24-gauge, Jameco Electronics
solid conductor
LED, any color

DigiKey
Jameco Electronics
Parallax
SparkFun
Electronics

11

5

10

12

1

1

Small screwdriver, flat
blade

Local hardware
store

13

1

1

Pushbutton, normally
open

Jameco Electronics

26623

(Continued ...)

279

280

Line

Appendix F

Minimum Recommended Description
Qty
Qty

Supplier

Part No.
21977

14

1

1

Switch, double-pole,
double throw (DPDT)

Jameco Electronics

15

10

10

220-ohm, 1/4-watt,
10% resistor

Jameco Electronics

16

10

10

330-ohm, 1/4-watt,
10% resistor

Jameco Electronics

17

10

10

1000-ohm, 1/4-watt,
10% resistor

Jameco Electronics

18

10

10

4700-ohm, 1/4-watt,
10% resistor

Jameco Electronics

19

10

10

10-kohm, 1/4-watt,
10% resistor

Jameco Electronics

20

1

1

10-kohm variable
resistor (trimmer)

Jameco Electronics

43001

22

1

1

Arduino Uno
microcontroller module

SparkFun Electronics
Jameco Electronics

DEV-11021
2121105

23

1

1

ARM mbed
microcontroller module

DigiKey
SparkFun Electronics

568-4916-ND
DEV-09564

24

2

2

SOIC adapter boards

SchmartBoard

204-0004-01

25

2

2

SN74LVC4245
integrated circuit

DigiKey

296-149111-ND

26

1

10

39-kohm, 1/4-watt,
10% resistor

Jameco Electronics

27

1

1

Photocell, CdS, 23 to
33 kohms

DigiKey

PDV-P90031-ND

Notes by part line number:
All	Part numbers and information are current as of February 2012. From time to time, suppliers drop products or
do not have parts in stock. You can find components and supplies at other companies. I note these specific
companies because I have purchased products from them and found them reliable and fair.
3	The SparkFun adapter requires purchase of separate receptacles, PRT-08272, and pins, PRT-00116.
5, 6	You can use two D-size 1.5-volt dry cells in series to provide power for 3.3-volt devices if you don’t want a
plug in power supply.
7, 8	You can use four D-size 1.5-volt dry cells in series to provide a 6-volt power supply. Put a 1N5401 diode in
series with the 6 volts and you will have about 5.25 volts, which will not damage 5-volt devices. You only need
a 5-volt supply if you plan to use an Arduino Uno microcontroller board.
5, 6, 7, 8	SparkFun sells a small power-regulator that delivers either 5 or 3.3 volts from a wall-wart-type power unit. If
you need a maximum of one ampere, these $10 kits deserve a look. SparkFun part no. PRT-00114.
10	Jameco offers the best price on 100-foot spools of 22-gauge hookup wire. I recommend you use two or three
colors.
11
You can buy small LEDs from many suppliers. I recommend the 5- or 3-mm-diameter LEDs.
15-19, 25	Rather than buy small quantities of individual resistor values, look for an assortment, such as the Jameco part
no. 81832. The experiments specify 10-percent-tolerance resistors, but 5-percent-tolerance resistors are fine.
23	Look under the “SMT to DIP Adapters” heading. You need only one of these microcontroller boards to perform the
experiments. I preferred the ARM mbed because it does not need logic-level-conversion circuits and has several
serial ports, which simplified experiments.
25, 26
Optional for Experiment No. 6.

Appendix G
American Standard
Code for Information
Interchange (ASCII)

281

282

Table G.1 Decimal and Hexadecimal Values for ASCII Characters
Hex

Character

Decimal

Hex

Character

Decimal

Hex

Character

Decimal

Hex

Character

0

0

NUL

32

20

space

64

40

@

96

60

`

1

1

SOH

33

21

!

65

41

A

97

61

a

2

2

STX

34

22

"

66

42

B

98

62

b

3

3

ETX

35

23

#

67

43

C

99

63

c

4

4

EOT

36

24

$

68

44

D

100

64

d

5

5

ENQ

37

25

%

69

45

E

101

65

e

6

6

ACK

38

26

&

70

46

F

102

66

f

7

7

BEL

39

27

'

71

47

G

103

67

g

8

8

BS

40

28

(

72

48

H

104

68

h

9

9

TAB

41

29

)

73

49

I

105

69

i

10

A

LF

42

2A

*

74

4A

J

106

6A

j

11

B

VT

43

2B



75

4B

K

107

6B

k

12

C

FF

44

2C

,

76

4C

L

108

6C

l

13

D

CR

45

2D

-

77

4D

M

109

6D

m

14

E

SO

46

2E

.

78

4E

N

110

6E

n

15

F

SI

47

2F

/

79

4F

O

111

6F

o

16

10

DLE

48

30

0

80

50

P

112

70

p

Appendix G

Decimal

17

11

DC1

49

31

1

81

51

Q

113

71

q

18

12

DC2

50

32

2

82

52

R

114

72

r

19

13

DC3

51

33

3

83

53

S

115

73

s

20

14

DC4

52

34

4

84

54

T

116

74

t

21

15

NAK

53

35

5

85

55

U

117

75

u

22

16

SYN

54

36

6

86

56

V

118

76

v

23

17

ETB

55

37

7

87

57

W

119

77

w

24

18

CAN

56

38

8

88

58

X

120

78

x

25

19

EM

57

39

9

89

59

Y

121

79

y

26

1A

SUB

58

3A

:

90

5A

Z

122

7A

z

27

1B

ESC

59

3B

;

91

5B

[

123

7B

{

28

1C

FS

60

3C



92

5C

\

124

7C

|

29

1D

GS

61

3D



93

5D

]

125

7D

}

30

1E

RS

62

3E



94

5E

^

126

7E

~

31

1F

US

63

3F

?

95

5F

_

127

7F

DEL

Appendix G
283

284

Appendix G

Table G.2 Non-Printing ASCII Information and its Corresponding Action
Symbol

Action

ACK

Acknowledge

BEL

Bell (ring a bell at the receiver)

BS

Backspace

CAN

Cancel

CR

Carriage return

DC1

Device Control 1

DC2

Device Control 2

DC3

Device Control 3

DC4

Device Control 4

DEL

Delete

DLE

Data link escape

EM

End of message

ENQ

Enquire

EOT

End of transmission

ESC

Escape

ETB

End of text block

ETX

End of text

FF

Form feed

FS

File separator

GS

Group separator

LF

Line feed

NAK

Negative acknowledge

NUL

Null

RS

Record separator

SI

Shift in

SO

Shift out

SOH

Start of header

STX

Start of text

SUB

Substitute

SYN

Synchronous idle

TAB

Tab

US

Unit separator

VT

Vertical tab

Appendix H
Troubleshooting
No matter how carefully you construct an electronic circuit, mount components, and create software, you will run into problems, probably more often
than you like. The following suggestions will help you overcome problems
that might arise as you perform the XBee-module experiments in this book.
I base these suggestions and thoughts on experience.
Many electrical problems stem from poor power supplies. Always ensure
that you have an adjustable power supply properly set for the voltage or voltages you need. Even though a supply might have terminals marked for, say 5
volts, for a fixed output, have a digital multimeter handy so you can measure
voltages at power-supply terminals. Power supplies can have problems, too.
I like to have an LED on breadboards to indicate the presence of power.
A quick look lets me know I have power available. Remember an LED needs a
current-limiting resistor.
Use wire with sufficient current-carrying capability to not cause a voltage
drop between a power supply and a circuit. I have seen some power leads that
looked robust, but their thick insulation held fairly thin conductors.
Even if you have power at a power supply and breadboard, it’s easy to
forget to provide power and ground to a circuit. Always double check power
connections to circuits, XBee adapters, and components.
Power supplies that connect to a circuit require a common ground that
gives all of the components a common reference of zero volts. Many problems
arise because people forget to provide such a ground. I recommend you use
one point in a circuit as a common ground point rather than run ground wires
here and there. The common-ground point also makes it easy to connect a voltmeter, logic analyzer, or oscilloscope ground lead and make measurements
referenced to the same point.
In the bill of materials I recommend using solid-conductor hookup wire of
several colors. Engineers commonly use red for power and black for ground.
In my lab, I have pre-stripped blue, yellow, and orange wires of several lengths
so I can assign one color to one type of signal. Keep your connections short.
On solderless breadboards I usually have 0.1 μF disc-ceramic capacitors
along with a few 2.2 or 4.7 μF electrolytic capacitors that can help absorb
power glitches common in circuits. I place these capacitors at intervals
between ground and power on a breadboard. Some breadboards have “split”
power rails that go halfway across the top or bottom. Remember to use a short

285

286

Appendix H

jumper to bridge these gaps. Otherwise you’ll wonder why one side of the
breadboard has power and the other doesn’t.
When you plug components into solderless breadboards, ensure pins and
wires go into the receptacles. I have seen dual inline-package integrated circuits pressed into a breadboard but with a lead bent up under the IC body. The
IC appears properly inserted, but one lead never connects with the breadboard
conductor. The same sort of thing can happen with discrete components. They
might appear inserted in a breadboard receptacle, but a lead might not contact
a conductor.
Integrated circuits, transistors, diodes, XBee modules, and other semiconductor devices can suffer irreversible damage if you reverse their power
connections. Power “reversal” comes from human error—either improper connection of power from a power supply, incorrect power connections in a breadboard, or improper insertion of a device in a breadboard or socket. Always
insert semiconductor devices with power off and carefully check power connections and device orientation. I once saw a series of 5-volt integrated circuits
go up in smoke because someone improperly connected power and ground to
signal inputs. In the early 1970s, I burned out a microprocessor chip by making
wrong power connections. That was an expensive lesson—the chip cost $360!
Because XBee devices use wireless communications, ensure you have a
clear area around their antennas. Placing metal objects near an antenna will
affect its radio-frequency radiation pattern and might even shield an antenna
completely. I have heard several stories about equipment designers who
enclosed a GPS antenna within a metal chassis. Obviously, the GPS receiver
did not pick up any satellite signals.
I have had a few cases of “balky” XBee modules. Apparently when we
configure XBee modules for sleep modes, they stay in those modes when
placed in a USB-to-XBee adapter. Thus it can take several attempts to communicate with a module via the Digi International X-CTU software. Don’t give
up and think you have a “dead” module. Eventually you will connect with the
XBee module and can restore the default XBee settings.
If you doubt the configuration information in an XBee module, you can
almost always connect it to a PC that runs the X-CTU software, read the configuration setup, compare it with what you expect, and make changes. You also
can restore the factory-default settings.
The X-CTU software lets people update the XBee-module firmware when
they save configuration information in a module. I recommend against doing
so because a “partial” upgrade—one interrupted part way through—can render
a module inoperative. Remember, internal software controls an XBee module
and you don’t want to mess it up.
If you truly cannot communicate with an XBee module via the X-CTU
software, try a new USB cable. We tend to take cables for granted and they can
get damaged when run underneath computer cases, run over by chair wheels,
stepped on, and so on. Some imported USB-cable manufacturers use cheap,

Appendix H

287

thin wires and pay little attention to quality. For lab use, brand-name USB
cables usually do not fail.
One problem I ran into several times involved changing a packet to send in the
X-CTU program and forgetting to change the number-of-bytes information at the
start of the packet. If you modify a packet, change the number of bytes accordingly. Also, do not add the start byte or the following two bytes that provide the
number of bytes in the message portion of a packet when you calculate the checksum. The Packet Creator 2 Excel spreadsheet can help bypass this problem.
Several experiments use microcontroller boards or modules. Always ensure
you connect them to a common ground. The small receptacles on an Arduino
Uno and the tiny pins on an ARM mbed make it a challenge to connect wires.
I like the small grabber-type clip leads for those types of connections. Before
you connect anything to serial inputs and outputs, make a diagram that shows
how the serial signals will go out and in. It’s easier than you think to confuse
a serial input with a serial output and mix up what signal goes where. Serial
communications can cause quite a few problems.
The default XBee-module configuration has UARTs set for 9600 bits/
second, 8 data bits, no parity bit, and 1 stop bit noted in engineering jargon
as “8N1.” Always ensure you have the same 9600 bits/second, 8N1 settings
at both ends of a serial-communication link. Some terminal-emulator programs and some serial-port software lets users set “flow control” so hardware
or software can indicate when it’s ready for communications. These experiments assume you have set any flow-control settings to “NONE.” An incorrect
flow-control setting caused me an hour of grief one evening.
The XBee modules can communicate at a higher bit rate, but I recommend you stay with the 9600 bits/second rate. I did not use a higher rate in the
experiments.
If you do not program in the C language, I recommend two books:
l
“C in a Nutshell,” by Peter Prinz and Tony Crawford,” O’Reilly Media,
ISBN: 978-0596006976, and,
l
“Practical C Programming,” by Steve Oualline, O’Reilly Media, ISBN:
978-1565923065.
I used both books as references when working with the Arduino Uno and
ARM mbed modules. My work doesn’t involve full-time programming, so
I needed some refreshing in C syntax and structure.
Many software errors result from poor logic; that is, a poor understanding
of what we want a computer chip to do. The chips do exactly what we program
them to do, but our program errors lead them astray. I often uncovered the following problems in the code I wrote:
l
Typing errors. As a two-finger typist I do fairly well, but sometimes I hit
two keys or hit the wrong key.
l
Syntax errors. I would forget the occasional brace, {or}, in a program that
would cause errors. Leaving a semicolon off the end of a C statement can
cause compilation errors and a compiler may not detect the error until well

288

Appendix H

past the error. Don’t rely on a compiler to precisely identify the location of
a problem.
l
Undeclared variables and constants. I got better as I went along, but sometimes I thought I had declared a variable only to find I hadn’t.
l
Off-by-one errors. In a conditional statement it’s easy to cause off-by-one
errors. Do I want this loop to end when counter equals 15 or 14? Is the last
element in an array data [76] or data [77]?
When writing MCU software I find it handy to have a couple of LEDs connected to output pins and a pushbutton connected to an input pin. I can use the
LEDs to let me know I reached a certain point in code and I often used short
loops to flash an LED at different rates, depending where the program got to.
In several experiments I left an LED and “switch” in the code so you know
when software reached a given point, or when it detected an error. That type of
debugging aid proved invaluable several times.
If you run out of troubleshooting or testing ideas, take a break and come
back to your lab bench with a fresh outlook. Then look at your hardware and
software and ask yourself, “What does the result tell me?” In one case I could
not get a remote XBee module to respond to any command I sent it. I knew the
XBee module didn’t have a problem because I could put it in a USB-to-XBee
adapter and communicate with it and get it to respond to commands from the
X-CTU program. So I put the XBee module back in its remote breadboard,
poured a glass of iced tea and read a magazine for 15 minutes. When I returned
to my lab bench and reviewed the problem—absolutely no response from the
remote module—it dawned on me I sent AT commands to the local XBee module connected to my PC instead of sending remote AT commands. When I corrected the command packets, the XBee module across the room responded
properly.

Appendix I
Blank Tables

The blank tables in this appendix let you enter information from your experiments and interpret the results. Feel free to make copies of the tables so you
have them in a form convenient to your work.

Table I.1 Active-Signal Byte Table
First Active-Signal Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

A5

A4

A3

A2

A1

A0

D8

Data

Second Active-Signal Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

289

290

Appendix I

Table I.2 Digital-Data Byte Table
First Digital-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

X

D8

Data

Second Digital-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

D7

D6

D5

D4

D3

D2

D1

D0

Data

Appendix I

Table I.3 Analog-Data Byte Table
First Analog-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

X

X

X

X

X

X

A9

A8

Data

Second Analog-Data Byte
First Hex Character

Second Hex Character

Bit Position

B7

B6

B5

B4

B3

B2

B1

B0

Bit Function

A7

A6

A5

A4

A3

A2

A1

A0

Data

291

Appendix J
XBee Connection
Information
The diagrams in this appendix provide a pin-out drawing for an XB24 XBee
module (Figure J.1), and a drawing that labels all XBee signals (Figure J.2).
Feel free to copy the first and use it to sketch circuit diagrams. You also can
copy the second diagram and keep it near your breadboards to make it easier to
find the proper pins and signals.
Top View
1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

Figure J.1 A pin-out diagram for use in XBee schematic diagrams.
Top View
+3.3 V
UART Data Out
UART Data IN – /CONFIG
DO8*
/RESET
PWM0 – RSSI
PWM1
[Reserved]
/DTR – SLEEP_RQ – DI8
GND

1
2
3
4
5
6
7
8
9
10

XBee XB24

20
19
18
17
16
15
14
13
12
11

AD0 – DIO0
AD1 – DIO1
AD2 – DIO2
AD3 – DIO3
AD6 – DIO6 – /RTS
AD5 – DIO5 – Associate
VREF
ON – /SLEEP
DIO7 – /CTS
AD4 – DIO4

* DO8 not supported at this time.

Figure J.2 This diagram labels the pins on an XBee module to make them easy to identify.

293

294

Appendix J

The software files you can download from www.elsevierdirect.com/
companions.jsp?ISBN=9780123914040 include an XBee-module component
for the free schematic-capture software available from ExpressPCB (www.
expresspcb.com). This custom component simplifies drawing circuits that
require an XBee module.

Glossary
ADC see Analog to Digital Converter
American Standard Code for Information Interchange (ASCII) a code used to communicate 128 unique letters, numbers, punctuation, symbols, and special commands.
Although the original ASCII code used only seven bits, the extended ASCII code uses
eight bits and includes non-Roman letters and currency symbols.
Ampere a unit of measure for the quantity of current that flows in a circuit and a basic
International System of Units (SI) measurement. Named after the French physicist and
mathematician André Marie Ampère (1775–1836).
Analog in electronics, a type of signal that can vary without discrete steps.
Analog to digital converter (ADC) an electronic circuit that converts an analog signal into
a value represented by n discrete steps. The number of steps and the ADC reference
voltage determine the step size and input-measurement range. A 10-bit ADC, for example, has a resolution of 210 (102410) values, for a theoretical accuracy of 1 part in 1024,
or 0.097 percent. Resolution, though, does not directly represent accuracy. In practice,
an ADC with a 10-bit resolution offers eight or nine bits of accuracy due to electrical
noise and other electronic effects. An ADC requires a stable internal or external reference voltage upon which it bases the conversions and which establishes the range for the
converter.
Anode The positive terminal of a power source or an electronic component that has a polarity; that is, a positive and a negative terminal. An LED, for example, has an anode that
connects to a positive voltage and a cathode that connects to a negative voltage, or
ground (zero volts). See also Cathode.
API see Application Programming Interface
Application programming interface (API) a set of high-level programming functions that
automatically perform complicated operations without involving a programmer in their
details. Manufacturers of microcontrollers and software suppliers offer APIs specific to
their products. An API function such as read_port_C used in a program might handle
all the steps needed to read values from Port C on a microcontroller. A programmer can
use this API function without having to know what connects to Port C, how to control
Port C, or what other parts of a program also use Port C.
ASCII see American Standard Code for Information Interchange
Asynchronous the lack of coordinated timing between events, or the lack of a common
clocking signal for electronic events.
AT command A set of lettered commands established in the early 1980’s to control dial-up
modems. A modem would respond to commands that started with the letters AT, which
stands for “attention.” Over the years, communication-device manufacturers created
their own sets of AT commands, such as ATFR for a forced reset, or ATID for “identify
yourself.” These types of commands simplify control of communication devices such as
XBee modules.
Baud Now a synonym with bits per second (bits/sec.), a measure of the speed of asynchronous communications between electronic equipment. Named after Jean Baudot,
who invented the Baudot code, an early 5-bit representation of, letters, numbers, and
punctuation.
Binary a numbering system that uses only one of two values, 0 or 1, in each numeral position. Binary numbers use 2 as their base, which means positions indicate 16’s, 8’s, 4’s,
2’s, and 1s. Thus the binary number 01012  4  1 or 510. Each position represents 2n,
where n increases by 1 as bit positions move to the left, as in 25, 24, 23, 22, 21, 20.

295

296

Glossary

Bit a single-digit binary value of either 1 or 0.
Breadboard originally a piece of wood on which hobbyists, students, and engineers
constructed electrical circuits by attaching them to the board, perhaps even a bread
breadboard. Present breadboards use plastic strips with rows and columns of metal
receptacles, a printed-circuit board with etched pads that allow for soldered connections,
or perforated boards in which people insert components, sockets, and wires.
Byte a group of eight continuous bits, such as 101100012. A byte has a most-significant bit
(MSB) on the left because its bit position has the largest value of all eight bits, either 0
or 128 (27). Conversely, the least-significant bit (LSB) on the right contributes the smallest value; either 0 or 1 (20). The byte shown here has a value of 17710. See also Binary
and Bit.
Capacitor an element that stores charge.
Cathode The negative terminal of a power source or an electronic component that has a
polarity; that is, a positive and a negative terminal. An LED, for example, has a cathode
that connects to a negative voltage, or ground (zero volts), and an anode that connects to
a positive voltage. See also Anode.
Checksum a value computed from information contained in a defined packet and sent with
that packet to help a receiver detect an error that occurred during transmission. The
receiving device can calculate a checksum in the same manner and compare it to the
received checksum. A difference in the checksum usually indicates an error. Modern
techniques better detect errors and help correct them, but for short communications, a
checksum usually suffices.
COM port a communication port on a personal computer, usually a serial port labeled
“10101” near a connector on the back or side of a computer. Many new computers do
not provide a COM port, but instead employ a USB port as a virtual serial port that lets
application software “think” it communicates with a serial port. The receiving device
includes a USB-converter integrated circuit the receiver “sees” as a serial port that connects to a PC. COM ports have a numeric designation, such as COM0 for a built-in
serial port, and, say, COM19 for a USB-to-XBee adapter.
Comparator an electronic component that compares two voltages. A comparator comes in
handy when you only need to know if one voltage rose above another or dropped below
another. A comparator has one output and a plus and a minus input. When input voltage
V exceeds the voltage at the V pin, the comparator output changes from a logic 1 to
a logic 0.
Digital in electronics, a signal that can exist in discrete voltage steps or discrete values.
Firmware a computer program and data held semipermanently in a microcontroller or similar device. The firmware governs how the device operates. Some applications require an
occasional or periodic firmware update, say, a postal meter that needs new postal rates,
or an automated toll-collection booth that needs new information about tolls.
Ground an electrical or electronic reference point that represents zero volts in a circuit.
Distinct from a ground used in household line-power circuits that include an earth
ground.
Hexadecimal a numbering system that represents a digit with a single symbol for the 16
values 0 through 15, with numerals 0 through 9 and letters A through F. The numerals 0
through 9 equal their assigned value, and letters A through F represent values 11 through
15. Hexadecimal numbers simplify the notation of byte values, which can split into
two portions, for example, 110001112, or 1100 0111. The maximum value for four bits
comes to 15, so the binary number 1100 0111 (artificially divided for clarity) becomes
C7. Hexadecimal numbers in computer programs have a zero-x prefix, thus 0xC7. Also
referred to as hex.
I/O shorthand notation for input/output. Often used in “I/O port” to designate an electronic
connection or connections used by a microcontroller or similar device to communicate
with electronic devices.
Interrupt an immediate-attention condition caused by hardware or software that stops
normal program flow as a processor branches off to handle the cause of the interrupt.
An external device could cause an interrupt because it has data the processor must

Glossary

297

immediately respond to, or software could cause an interrupt if an error occurs, perhaps
from a divide-by-zero operation. See also Interrupt-Service Routine.
Interrupt-service routine (ISR) software separate from the normal program flow and written specifically to handle an interrupt for a specific device. An internal timer would have
its own ISR, separate from an ISR written to handle an interrupt from an analog-todigital converter. See also Interrupt.
ISR see Interrupt-Service Routine
Jumper a piece of wire, usually insulated, that connects two points in a circuit. Often a temporary connection.
LED see Light-emitting diode
Light-emitting diode a semiconductor device that emits light with an intensity that depends
on the current flow through it. LEDs usually have a narrow wavelength emission, thus
you can find, red, green, orange, yellow, and blue LEDs. LEDs also can emit light at
infrared or ultraviolet wavelengths.
Logic-level converter a circuit designed to convert the logic-level voltages for one family of
devices to the levels appropriate for another family. The 3.3-volt logic in an XBee module cannot directly connect to a microcontroller that uses 5-volt logic. Special integrated
circuits perform the conversions to and from 3.3- and 5-volt logic families.
Low-pass filter an electrical or electronic circuit that allows only low-frequency signals to
pass. Filter-design software and formulas simplify the design of such filters. You also
can have high-pass filters. A band-pass filter allows a specific continuous range of frequencies to pass. A notch filter acts to block signals at a specific frequency.
MCU see Microcontroller
Microcontroller an integrated circuit that provides a central processor that performs math
and logic operations and can move information from place to place. The microcontroller includes memory for storage of program code and to store information. Peripheral
devices within the IC include timers, input-output ports, analog-to-digital converters,
pulse-width modulators, serial ports, and specialized communication devices.
Microsecond one millionth of a second.
Millisecond one thousandth of a second.
Modem an acronym for modulator-demodulator used for phone-line communications
between terminals and remote computers, later between two or more computers. (Digi
International refers to some of its modules as modems, which they are, but because
modem sounds anachronistic, I identify the Digi products as XBee modules.)
Node an end point in a wired or wireless network or a junction between components in a
schematic diagram or circuit.
Ohm the unit used to define the resistance of an electrical component. Named after Georg
Ohm (1789–1854), a German physicist.
Op-amp see Operational Amplifier
Operational amplifier a versatile integrated-circuit amplifier that uses external components
such as resistors and capacitors to tailor its function to specific analog-signal applications. An op-amp circuit can add two voltages, amplify two voltages, operate as part of a
filter circuit, and so on.
Packet a “package” of information that conforms to a specific structure that governs its
arrangement of data, the use of a checksum, and other characteristics.
PAN see Personal Area Network
Parity a system that helps communication equipment and memories detect errors in information by including an extra bit. An even-parity arrangement appends a bit to a series of
bits so the result has an even number of 1 bits. Say you want to send the byte 11000111
with an even parity bit, as agreed with the recipient in advance. To have an even number
of 1’s in the data, you must append a 1 to the communication: 110001111. The parity
bit, shown in boldface type, now gives an even number of 1’s in the data. If you sent
the data 00110011 with even parity, you would append a zero and transmit: 001100110
because the data already has an even number of 1’s. Odd parity works the same way, but
it ensures an odd number of 1’s in a transmission.
Personal area network (PAN) a network with only a few devices under your control.

298

Glossary

Port usually electrical connections on a computer that communicate with a specific type of
device. Computers have serial ports, Ethernet ports, USB ports, and so on. Engineers
often call a group of signals an I/O port.
Pot see Potentiometer
Potentiometer a device that lets a person control a resistance that varies from 0 ohms to
x ohms, as specified by the potentiometer manufacturer. Small potentiometers, often
called a trimmer, pot, or trim pot, let technicians or service people make slight adjustments to a resistance.
Pull-up part of a circuit that “pulls up” a pin or connection to a voltage, usually through a
resistor.
Pulse-width modulation (PWM) also pulse-width modulator; a technique that varies the
width of a continuous train of electrical pulses that occur at a preset frequency. Pulse
widths can vary from 0 to 100 percent. The PWM technique lets a device such as a
microcontroller create a semi-analog output that, with a low-pass filter, becomes a true
analog voltage.
PWM see Pulse-Width Modulation
Resistor an element that impedes the flow of electricity.
Serial port a connection to a UART, or UART-like device, for asynchronous-serial communications. See also Universal Asynchronous Receiver Transmitter.
Start bit the first bit, a logic 0, in a transmission from a UART.
Stop bit the last bit, a logic 1, in a transmission from a UART.
Trigger an electronic signal that initiates an event.
Trimmer see Potentiometer
UART see Universal Asynchronous Receiver Transmitter
Universal asynchronous receiver transmitter (UART) usually hardware designed specifically for serial communications at standard bit rates. A UART transmits and receives
information in a standard format with equally timed bits. A logic-0 start bit begins each
transmission, followed by five to as many as eight data bits. An optional parity bit can
follow the data bits. At the end of the data, a UART sends one or two stop bits (logic 1).
The transmitting and receiving UARTs must have the same settings for the transmission rate, the number of data bits (usually eight), the type of parity (usually none), and
the number of stop bits (usually one). The bits appear at a UART one right after the
other without any “space” or “dead time” between them. The output uses a non-returnto-zero format, which means no signal transition occurs between consecutive 1’s or 0’s
in a transmission. Infrequently programmers implement a UART in software.
Universal serial bus (USB) a standardized bus for high-speed communications between a
computer and an external device such as a DVD player, printer, or electronic instrument.
A USB connection operates at several standard data rates and USB cables employ several types of standard connections.
USB see Universal Serial Bus
Volt the standard unit for the measurement of electrical potential, named for Alessandro
Volta (1745–1827), perhaps best known for the for the invention of the battery.
XBee a wireless type of module manufactures by Digi International.
X-CTU a Windows program created by Digi International that simplifies communication
between a PC and XBee modules as well as the display of communicated information,
testing and configuring XBee devices.

ACKNOWLEDGEMENT
Thanks go to Wikipedia for information about Ampère, Ohm, and Volta.

Index
A

Active-Signal Byte, 20, 20t, 21, 46, 114,
289t
ADC, see Analog to digital converter
American Standard Code for Information
Interchange (ASCII), 1, 79, 281
decimal and hexadecimal values for,
282–283
non-printing information and action, 284
Analog inputs, 63
Analog voltage, 31
Analog-Data Byte Table, 291t
Analog-to-digital converter (ADC), 32, 54
Anode, 28, 28f
API, see Application Programming Interface
API command, 153
API ND command, 161
Application programming interface (API)
Application programming interface packets
local XBee Module, 77
remote I/O lines, 95
remote XBee Modules, 85
Arduino Uno module, 131–134, 132f, 143–
148, 167, 213–222, 238–245
troubleshooting, 146, 172–173, 222
Arduino Uno Program EX17_Uno_Five,
144–146
Arduino Uno Program EX17_Uno_FiveT,
147–148
ARM mbed module, 134–137, 136f, 140–
141, 148–153, 204–213, 232–238
troubleshooting, 136–137, 151, 212–213
ARM mbed Program EX17_mbed_Five,
149–151
ARM mbed Program EX17_mbed_FiveT,
152–153
ARM mbed software, 175–176
ASCII, see American Standard Code for
Information Interchange
Asynchronous, 130
AT command, 5, 10, 85, 95–98, 117, 155
ATFR command, 193
ATND command, 161
ATVR command, 6

B

Bill of materials, 279
16-bit MY address, remote module's, 92

16-bit Source Address, 105
Bit-Function, 20
Blank tables, 289
Breadboard, 14–15, 14f, 273
Broadcast message, 123
Bytecount math operation, 171, 176

C

Cadmium-sulfide (CdS) photoresistor, 50
Cathode, 28, 28f
Checksums, 266–268, 267f
COM port, 2–3
Command Options, 93
Comparator, 254f, 255, 255f
Computer-to-computer communications,
139, 140f
Coordinator module, 190, 191
Cyclic Sleep Period, 248
Cyclic-sleep operations, 247
periodic wake-up with coordinator
polling, 255–260
periodic wake-up with I/O report, 248–255

D

Debugging and testing tools, 275
Default XBee Modem-configuration
Settings, 269
Destination Node (DN), 190
Digi International, 1, 2, 5, 40
Digi Web site, 2, 5, 42
Digi XBee/XBee-PRO RF Modules, 67, 106
Digital and analog devices, remote control
of, 43
Digital and analog measurements, 195
Digital and analog pins, 111
Digital multimeter (DMM), 275
Digital-Data Bytes, 46, 47t, 114–115, 115t,
290t
DOZE mode, 63

E

End device (coordinator), 185
End-device module, 191, 198
End-device XBee module(s), 224
Excel spreadsheet Packet Creator tool, 277,
278f, 278t
EX21_mbed_ND program, 233–238
EX21_Uno_ND program, 240–245

299

300

Index

F

Force Reset (FR) command, 192

H

Hex math calculator, 80
Hexadecimal numbers, 265–266, 265t
HIBERNATE mode, 63

I

IC – DIO Change Detect settings, 55, 55t
Institute of Electrical and Electronic
Engineers (IEEE), 9
Interrupt-service routine (ISR), 228, 230f
I/O Settings
one-way digital-input communications,
17
XBee modules transfer and control analog
signals, 34
IS command, 99
ISR, see Interrupt-service routine

L

LED, see Light-emitting diode
LED circuit, 104
Light-emitting diode (LED), 28, 29f
Logic transitions, 60–61
Logic-level change, data transmission, 53
Logic-level conversion circuit (LLC), 132–
133, 146, 261, 264f
Low-pass filter, 38–39, 40f

M

3M 8810 ESD Rubber Mat, 274
mbed program EX16_mbed_Hello, 135–136
MCU, see Microcontroller
med program EX16_mbed_Alpha, 137
Microcontroller (MCU), 1, 78, 95–96, 110
software, 154, 228
and XBee Module, 127
Microcontroller-to-computer
communications, 127, 128f
MSO-19 link instruments, 276

N

ND command, 163–164, 191
Node Discovery Option, 181
Node Discovery Time, 181
Node Identifier (NI), 164
Non-beacon network, 183, 184f

O

Ohm's law, 41
One-way digital-input communications, 13
Op-amp, see Operational amplifier
Operational amplifier, 41, 42
Operational-amplifier (op amp), 41

P

PAN, see Personal area network
Personal area network (PAN), 184, 195–196,
223–224, 233–237, 240–244, 247–248
Pot, see Potentiometer
Potentiometer, 32, 33f
Power sources, 275
Program EX20_mbed_IS, 207–212
Program EX21_mbed_ND, 233–238
Program EX20_Uno_IS, 216–222
Program EX21_Uno_ND, 240–245
Pull-up resistors, 60
Pulse-width modulation (PWM), 38, 39f
outputs, 103
PWM, see Pulse-width modulation

R

Received signal strength indicator (RSSI), 42
Reference voltage (VREF), 40, 67
Resistors and color codes, 273

S

SchmartBoard adapters, 263, 264f
Serial port, 77, 78
Single-pole double-throw (SPDT), 60
Sleep Mode, 69, 248
Sleep Options, 248
Sleep-mode timing, 69
SN74LVC4245 logic-level-conversion ICs,
261
Soldering tools, 275
Start bit, 77, 78f
Status Byte, 81, 81t
Stop bit, 77, 78f

T

Terminal-emulation software, 131
Terminal-emulator program, 131
Time Before Sleep, 248–249
Trimmer, see Potentiometer
Troubleshooting, 285
Two-Way Communications with XBee
Modules, 139
software, 140–143

U

UART, see Universal asynchronous receiver
transmitter
Universal Asynchronous Receiver Transmitter
(UART), 1, 77, 129–131, 144–145
Uno Program EX16_Uno_Alpha, 134
Uno Program EX16_Uno_Hello, 132–134

W

While() loop, 150
Windows HyperTerminal program, 143

Index
Work area, 274
WR command, 122, 123

X

XB24 XBee module, 3
modem configuration, 8f
pin-and-signal designations, 8f
XBee commands, 188
XBee connection information, 293
XBee modules, 1, 40, 67, 123, 157
API Packets, 77, 85
and breadboard adapters, 274
with broadcast commands, 119
configurations, 7
flowchart, 165, 166f
microcontroller and, 127
for remote control, 25
in sleep modes, 69
transfer and control analog signals, 31
two way communication, 139
unknown number, 223
and USB adapters, 274–275
wireless communications, 157

301

XBee network, 183
XBee receiver module (RCVR) module
parameters, 15
analog inputs, 65
digital and analog devices, 50
logic-level change, 56
modem configuration settings for, 26
sleep modes, 72
XBee transmitter (XMTR) module, 15, 33,
75
configurations, 64
XBee transmitter (XMTR) module
configurations
analog inputs, 64
digital and analog devices, 49
logic-level change, 54–55
sleep modes, 72
X-CTU software, 1, 7
hardware problems, 4f
XMTR module, connections, 87f, 113
XMTR transmitter, 85



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Modify Date                     : 2013:10:29 19:22:47+02:00
Creator                         : PdfCompressor 3.1.34
Producer                        : CVISION Technologies
Create Date                     : 2013:10:28 07:24:12+04:00
Author                          : .4<8=8AB@0B>@
Page Count                      : 304
Page Mode                       : UseOutlines
EXIF Metadata provided by EXIF.tools

Navigation menu