Switching to API mode
Until now, you have seen the XBee module work in AT mode or transparent mode. Any data the XBee module receives on its serial port is transmitted as it is by the radio, and any data received by the radio is forwarded through the serial port directly.
AT mode can be useful for simple point-to-point radio links, or when talking to existing serial devices (where you have no control over the serial protocol used). Transparent mode can also be used to upload sketches to a remote Arduino through the air (not covered in this book). Most examples and tutorials available on the Internet use this transparent mode for communicating.
However, AT mode is also limited. Data can only be sent to a single preconfigured address. When receiving data, there is no indication as to the source of a received byte. Furthermore, when receiving data from multiple nodes, their messages might end up being interleaved if no special care is taken. Finally, AT mode does not support sending more advanced ZigBee messages, which are needed to interoperate with some existing ZigBee devices—for example, using the ZigBee Home Automation protocol.
To alleviate these limitations, the XBee modules support API (Application Programming Interface) mode. In this mode, all serial communication uses a binary protocol, consisting of API frames (also called API packets). Each of these frames starts with the 0x7E
byte to indicate the start of the frame and contains a frame length, a checksum, a frame type, and extra type-specific data.
Examples of frames that can be sent to an XBee module are Transmit Request and AT Command; examples of frames sent by the XBee module are Receive packet, AT Command Response, or Modem status.
Each of these frame types has its own structure, containing a number of parameters that indicate the operation that should take place, or the event that occurred. If you look at the Transmit request frame, for example, this contains a field for the destination address, some transmission options, and the actual data to send.
Because of this format, it is easy to send data to different nodes, without having to change any configuration. Since data received is similarly wrapped in frames, you will know about the source of every message received too, which allows you to build more complex networks.
Because API mode uses a binary frame format, it is a bit harder to talk to the XBee module manually (you cannot just open up a serial console and start typing like you did before). However, for configuration and testing, the XCTU utility can take care of the frame generation and parsing for you; on the Arduino, there is a good library to do this.
For the XBee ZB S2/S2B modules, there is a separate firmware for AT mode and for API mode. To switch from AT mode to API mode, or vice versa, you have to replace the firmware. For the other XBee modules (including the XBee ZB S2C), a single firmware can run in both modes. Using the default setting of AP=0
, they run in AT mode; however, by configuring AP=1
or AP=2
, they run in API mode. There are two variants of API mode: with (AP=2
) and without (AP=1
) escaping some special characters (see the product manual for how exactly this escaping works).
In the rest of this book, all XBee modules will be configured for API mode with escaping enabled (AP=2
), for maximum flexibility and robustness for your sensor network (note that the Arduino library used currently requires the use of escaping too). AT mode will not be covered in this book beyond what you have seen so far, but check out the product manual and resources online for more info on AT mode if you need it.
First module in API mode
To take advantage of API mode, you will need to configure your modules to use it. First, try switching your coordinator to API mode:
- For XBee S2/S2B modules, replace its firmware with the ZigBee Coordinator API version, as shown earlier. This step is not needed for other modules.
Remember to change
ID
and change it back again on the other XBee module when you replace the coordinator's firmware, to force the other module to join the new network. - Set
AP=2
to enable escaping. XCTU will detect that escaping mode is now enabled and automatically applies the escaping to all data it sends and receives.
With this change, the XBee module will no longer allow typing of messages directly into the serial console, but expects to receive properly formatted API frames instead.
Sending data
To send these frames, head over to the Consoles working mode at the top-right again. Click on Open connection like before to connect to your XBee module.
You will notice that the window looks different from before. The screen is still divided into two parts horizontally, where the left part (directly under Frames log) will show all API frames sent to or received from the XBee module. This includes any frames sent by XCTU automatically (for example, when changing configuration parameters or doing a network scan), any replies to frames sent, as well as any data packets received by the radio. The right part shows details for any selected API frame.
Right now, this area should be empty, but you are going to change that by telling the XBee module to send out a message again. To do so, you will create a ZigBee Transmit Request API frame using XCTU and send it to the XBee module. At the bottom of the window, there is a Send frames section, which can be used to send API frames to the module. To prepare an API frame to send, click the Add frame button:
In the first input box, you can input a descriptive name for the frame. In the second input box, you can enter the raw bytes of the API frame. You could dig through the product manual to figure out how to construct a ZigBee Transmit Request API frame manually (which is still a good exercise), but it is easier to use the Frames Generator tool included with XCTU. You can access this tool by clicking the button at the bottom of the window:
In the Frames Generator tool, leave the Protocol value at the default, which should be appropriate for your module. The Frame type drop-down list shows all frame types defined for your particular device and protocol. Note that it also includes frame types that are normally only sent by the module, such as Receive packet. These are included for completeness, but will be ignored by the module when you send them to the module.
Tip
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
The frame you need looks like this:
This selects the Transmit request frame type (called ZigBee Transmit Request in the product manual). Most of the other parameters are fine at their defaults. Under 64-bit dest. address, enter 00 00 00 00 00 00 FF FF
. This is the same broadcast address you configured in DH
and DL
before. When using API mode, these configuration values are unused; instead, the target address is specified for each outgoing frame individually.
Under RF Data, you can enter the actual message data to be sent.
After confirming with Ok, XCTU now shows the raw bytes of your Hello, world!
frame. If you look closely, you can discover the 0x7e
start byte, 0x001b
as the frame length, 0x10
as the frame type, and the destination addresses:
Click on Apply changes to make the frame show up in the Send frames list. To actually send it to the router module, select it and click on Send selected frame to the right.
Doing this immediately makes two frames show up in the Frames log. The first is the Transmit Request frame sent to the module, followed by a Transmit Status reply. Clicking the frames shows their details to the right. If everything went right, the status frame will show a Delivery status of 00 (Success), indicating that the frame was successfully sent.
Now, head back to the serial monitor that shows the output from your Arduino. This should show the "Hello, world!" message you transmitted:
Starting.... 48 65 6C 6C 6F 2C 20 57 Hello, W 6F 72 6C 64 21 orld!
As you can see, you can exchange data between nodes running in AT and API mode just fine; each will just output the received data to the serial port in its own mode. You could try sending a bit of data back from the Arduino to the coordinator as well, to see how that shows up in XCTU.
Second module in API mode
To complete the transition to API mode, you should switch over the second XBee module, too. For this, plug it into the XBee Explorer module temporarily to replace the firmware if needed and set AP=2
.
Then plug the second XBee module back into the Arduino shield and the first one back into the Explorer. If you use XCTU as before to let the first module send the "Hello, World!" message again, the Arduino serial monitor output will look different from before:
Starting.... 7E 00 19 90 00 13 A2 00 ~....... 40 D8 5F 9D 00 00 02 48 @._....H 65 6C 6C 6F 2C 20 57 6F ello, Wo 72 6C 64 21 3B rld!;
Instead of printing just the message, a full API frame is printed. The message is contained inside, but also the API frame type (0x90
), sender address (0x0013A20040D85F9D
), message length (0x0019
), and so on. Check out the section on API operation in the product manual to figure out exactly what each byte means.
If you try typing some data into the Arduino serial monitor now, you will see that this data no longer shows up in XCTU like before. The XBee module expects to receive a correct binary API frame, which is unlikely to happen if you just type some letters. In the next chapter, you will see how to use an Arduino library to properly format these API frames.