XBee radio communication between PICs
Overview
Typically, two pics communicate by RS-232, a wired transmission. However, it may be desirable to communicate via a wireless link. This wiki page demonstrates using XBee radio modems which conform to the IEEE 802.15.4 protocol. These radios will allow for wireless communication between two PICs and between a PIC and a computer.
The IEEE 802.15.4 is a point-point/point-multipoint communications protocol (similar to Bluetooth) designed for low-power devices. Like Bluetooth, the IEEE 802.15.4 specification also uses the 2.4 GHz ISM band. The ZigBee protocol, which deals with mesh networking and routing, is built upon the IEEE 802.15.4 specification.
The XBee radios, made by Digi (formerly Maxstream), are shipped with firmware implementing the IEEE 802.15.4 protocol, but can be loaded with the ZigBee protocol stack, which can be downloaded from the Digi website. Note that ZigBee is still in its infancy and devices from different manufacturers may not be compatible. The range for an XBee Pro indoors is up to 300 feet while line of site, outdoor communication is up to a mile. (XBee Manual)
The XBee chip is designed to be mounted in specific sockets (Note: These sockets don't fit in a standard bread board!) We soldered wires directly to the socket, which were then placed in a breadboard. (Printed circuit boards are being created to fix this issue.) The Xbee also requires a 3.3 voltage regulator.
For the pin locations, see page 7 of XBee Manual or the figure to the right.
For PIC to computer interface, a terminal program such as X-CTU needs to be used. Although other terminal programs might work as well, X-CTU software was designed specifically for the XBee, and in addition to its terminal functions, it also has functions for testing signal strength, reading, saving, and writing the state of the XBee, and updating firmware. The X-CTU program is run on the PC while connected to a X-Bee via a serial port. The X-CTU software can be downloaded from X-CTU Site.
Circuit
The XBee module can be connected directly to the UART port on the PIC. To connect it to a RS-232 port, one must use a voltage shifting transceiver chip because RS232 signals are from -15V to + 15V. The MAX232/ST232 chip will convert voltage level from RS-232 to TTL logic levels and vice versa. The chip requires 4 external capacitors (the fifth is a bypass capacitor) in order to operate.
The transceiver data sheet can be found here.
In the circuit shown above, the serial port uses a DE9F 9-pin connector (Digikey part number 209FE-ND), which is used to connect the computer's serial port to the circuit.
In order to communicate PIC to PIC, two of the circuits shown on the left should be used.
In order to communicate PIC to computer, one of each of the circuits should be used. A better solution to connecting a PC to an XBee module is to use a cable that connects to the PC's USB port and converts to RS-232, as described on this PIC RS232 page.
XBee Interface Board
Code
Communication PIC to Computer
First you will need to get your PC speaking RS-232. You can try hyperterminal (standard on the PC) or zterm or similar for the Mac for simple interactive RS-232. See this page for an example of RS-232 communication using matlab. Or you can try this C++ library from within a Win32 C++ program. In any case, you are likely to need a special adapter cable to connect your PC to the XBee as described on the PIC RS232 page.
The PIC code below will wait for the character '+' to appear on the serial port, and when it does, it will add the next two single digit numbers that are entered and return the result back to the computer. In order to connect with the PIC, the program X-CTU must be used on the computer as discussed above.
#include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT #use delay(clock=20000000) // 20 MHz crystal on PCB //#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1) // you can use any pins for software uart... #use rs232(baud=9600, UART1) // hardware uart much better; uses RC6/TX and RC7/RX // characters tranmitted faster than the pic eats them will cause UART to hang. #include <stdlib.h> int a; char abuff[2]={0}; int b; char bbuff[2]={0}; char x; int sum; void main() { while (TRUE) { if (kbhit()) { x = getc(); } if (x=='+'){ while (!kbhit()){} abuff[0] = getc(); a = atoi(abuff); while (!kbhit()){} bbuff[0] = getc(); b = atoi(bbuff); sum = a+b; printf("sum=%u\r\n",sum); x=0; } } }
Communication PIC to PIC
In this communication, each PIC has its own code, which is shown below.
Transmitter
/* pic2pic_transmit.c ME333 Lab 5 The transmitter checks to see if PIN A0 is high or low. If the pin is high, the transmitter sends the signal 'a' to the receiver and turns on an LED. If the pins is low, the transmitter sends the signal 'b'. */ #include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT #use delay(clock=20000000) // 20 MHz crystal on PCB //#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1) // you can use any pins for software uart... #use rs232(baud=9600, UART1) // hardware uart much better; uses RC6/TX and RC7/RX // characters tranmitted faster than the pic eats them will cause UART to hang. #include <stdlib.h> #define LED_0 PIN_D0 void main() { while (TRUE) { if (input(PIN_A0)){ output_high(LED_0); printf("a"); //sends signal a } else{ output_low(LED_0); printf("b"); //sends signal b } } }
Receiver
/* pic2pic_receive ME 333 Lab 5 The receiver checks the signal from the XBEE and if the signal is 'a', the receiver turns on an LED. */ #include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT #use delay(clock=20000000) // 20 MHz crystal on PCB //#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1) // you can use any pins for software uart... #use rs232(baud=9600, UART1) // hardware uart much better; uses RC6/TX and RC7/RX // characters tranmitted faster than the pic eats them will cause UART to hang. #define LED_0 PIN_D0 #include <stdlib.h> char x; void main() { while (TRUE) { if (kbhit()) { x = getc(); } if (x=='a'){ output_high(LED_0); } else{ output_low(LED_0); } } }
Using the XBee Radio
Using X-CTU
Note: Setting up the radios will require the X-CTU terminal program. Select your settings under the PC Settings tab and click on Test/Query. Unfortunately, there is no easy way to tell what the current baud rate of the radio is set at (default is 9600), so you might have to try them all. Whoever had the radio before you may have changed the settings of the radio, so after your radio is successfully detected, you may wish to use command ATRE to reset the radio to factory defaults, and ATWR to save your settings.
Parameters AT Commands
AT commands enable you to set the parameters of the XBee radio. To enter AT command mode, open X-CTU (program discussed in overview), make sure your radio is detected, click on the terminal tab, and type in "+++" (without the quotes). The chip should respond with an "OK". Then, you can enter the commands. If the radio doesn't receive a commands for a while (default 10s), then it will exit command mode and return to normal operation mode; you can also force a return to normal operation mode with a ATCN command. All parameters are in hexadecimal format.
Commands are usually entered in the following formats (after entering command mode):
To read parameters: AT<parameter>
To write parameters: AT<parameter> <value>
For example, to read the ID of the radio, you could enter:
+++ ATMY
To set the value of the radio's ID to 1 you could enter:
+++ ATMY 1
The radio will start using the updated parameters after exiting the command mode, or if an ATAC (apply changes) command is given. If you want your changes to persist after rebooting the radio, make sure you use the ATWR command).
Specific instructions and descriptions of allowable parameters to send can be found in Section 3 of the XBee Product Manual.
Some commonly used commands:
Parameter | Description | Command | Value |
---|---|---|---|
Basic Commands | Enter command mode | +++ | N/A |
Exit command mode | ATCN | ||
Apply changes | ATAC | ||
Write current parameter values to non-volatile memory (must reset or use ATAC for changes to take effect) | ATWR | ||
Restore defaults | ATRE | ||
Reset | ATFR | ||
For items below, type command followed by a value to set the parameter or without a value to check the current value. | |||
Baud Rate | Sets the baud rate at which the XBee communicates with the serial device it is physically connected to. See the XBee manual for information on setting non-standard baud rates |
ATBD | 0-7 (standard baud rates) 0 = 1200 bps |
Radio Channel | The XBee can only communicate with other radios using the same channel. | ATCH | Uses 802.15.4 protocol channel numbers. 0x0B - 0x1A (XBee) |
Personal Area Network (PAN) ID | The radio can transmit to a specific network number, or use 0xFFFF to broadcast messages to all PANs | ATID | 16-bit |
Serial Number | Every radio has a 64-bit, read-only serial number. It can be identified by other radios using this number. | ATSH (high byte) | N/A |
ATSL (low byte) | N/A | ||
16-bit Device ID | You can identify a specific XBee using a 16-bit Device ID instead of the 64-bit serial number. See Destination ID for more information. | ATMY | 16-bit |
Destination ID | Specify the device ID of a specific XBee to transmit to or use 0x000000000000FFFF to broadcast to the entire PAN. To use 16-bit addressing, set the high byte to 0 and the low byte to the 16-bit Device ID of the XB you are transmitting to. |
ATDH (high byte) | 16-bit |
ATDL (low byte) | 16-bit | ||
API Mode | Gives you more control over communications between XBees, including non-standard packet sizes. Refer to the XBee manual for more information on API/Transparent Mode. | ATAP | 0 = API disabled (use Transparent Mode) 1 = API enabled |
Transparent Operation
By default, the radios are set to work in transparent mode (as opposed to API mode).
Unicast/Multicast Mode
(see section 2.4.1 in the manual)
A radio will be able to send send data to any other radio having the same channel (CH parameters), PAN-ID (ID parameter), and has a source address (MY in 16-bit address mode, SL+SH parameters in 64-bit address mode; see 2.4 in the manual for more about 16-bit versus 64-bit addressing) equal to the destination address (DL parameter in 16-bit addressing mode, DL+DH in 64-bit addressing mode) of the sending radio. You can set these parameters using the AT commands.
Broadcast Mode
(see section 2.4.2 in the manual)
To make your XBee broadcast packets, set the DL parameters to FFFF and the DH parameter to 0.
Proprietary API mode
To use the API mode, set the AP parameter to 1 or 2, depending on whether you will need escape characters (see 3.4 in the manual for more information).
The API mode allows users to send data in a packet structure. Commands and specific destination addresses can be embedded into packets, which allows you to give the radio commands without having to enter the AT command mode. The packet also inclues a checksum (the packet won't be sent/received if this is wrong), and receiving packets will have things like source address and signal strength embedded.
Writing software for the API mode may be more difficult, as you have to assemble a packet and calculate a checksum. You may wish to use API mode if you need to be able to detect corrupt data or if you need to communicate to many different radios individually.
ZigBee Mode
Maxstream provides a ZigBee stack for the XBee, but the firmware must be changed. The firmware can be changed with X-CTU, X-CTU can uplink to a server and download the correct firmware.
Setting up Your XBee Network
Although the XBee radios will be able to communicate with each other straight out of the box, they will be in broadcast mode, which means that your radio will be sending data to every other radio in the room, which is in most cases undesirable. Your radio will also be transmitting in broadcast mode, which could interfere with someone else's communications.
In order for two or more XBee radios to communicate, they must
- Have the same channel ID
- Have the same network ID
- The source ID on the receiving radio must match the destination ID of the sending radio.
To set the radios for point-to-point communication, there are four things to consider:
- Source ID - The Source ID is the ID number of your particular radio. You can read or write this parameter using the AT command ATMY.
- Destination ID - The Destination ID is the ID of the radio that you want to send to.
- PAN (Personal Area Network) ID is the ID of the network. Your radio will only send to radios with the same PAN ID unless you set your own ID to 0xFFFF, which will make you broadcast across all networks on the same channel.
- Channel - This is the radio channel of your XBee radio. Radios must be on the same channel in order to communicate. You can reduce interference between different XBee networks by using a different channel.
Your radio has two source IDs:
- A unique 64-bit serial number that is set at the factory and cannot be changed.
- A 16-bit ID that you can change.
Example: Serial Cable Replacement (2 radios)
If you simply want a pair of radios to communicate, the best way is to use the unique 64-bit serial number of your radio, which will eliminate the problem of someone else using the same channel, PAN ID, and IDs that you are using. Configure your radios by doing the following:
For both radios,
- Set the channels to be the same.
- Set the PAN ID to be the same.
- Set DH and DL to be equal to the SH and SL of the other radio, respectively.
- Set the MY parameter to 0xFFFF. This will block any messages with a 16-bit destination address.
Example: In this example, we set the channel, PAN ID, source ID, and destination ID. (The things that you type into the terminal are bold, the reply from the radio is plain.)
Radio1:
- +++OK
- ATCH C
- OK
- ATID 3332
- OK
- ATSH
- 13A200 Note: This serial number will be unique to your hardware
- ATSL
- 40088B78
- ATMY FFFF
- OK
- ATWR
- OK
- ATCN
- OK
Now, go to your other radio.
Radio2:
- +++OK
- ATCH C
- OK
- ATID 3332
- OK
- ATDH 13A200
- OK
- ATDL 4088B78
- OK
- ATSH
- 13A200
- ATSL
- 40088B96
- ATMY FFFF
- OK
- ATWR
- OK
- ATCN
- OK
Back to Radio1:
- +++OK
- ATDH 13A200
- OK
- ATDL 4088B78
- OK
- ATWR
- OK
- ATCN
- OK
Round Trip Latency Testing
A test measuring the round trip time of the Xbee radio was performed to gain a sense of the average latency of the XBee radios communicating over the 802.15.4 protocol.
Experimental Setup
One XBee radio was connected to a computer running Windows XP with a standard USB->RS232 cable. As programmed in Visual Studio C++ Express, the computer performed a "loopback" protocol; the computer wrote the data it received (to the serial port) upon the receipt of a byte (from the serial port). In this sense, the computer simply echoes the data it receives on the serial port.
A second XBee radio was connected to a PIC184520 with a 40MHz crystal. Using the PIC-C programming language, the XBee radio is controlled using the pic's hardware EUSART. A variety of baud rates were tested as listed in the table below.
To capture the round trip time, the pic was programmed to set a digital output high, and send a byte of data. Upon receipt of the data (from the loopbacked PC), the pic subsequently set the digital output low. By viewing the digital output on an oscilloscope, the width of the pulse was measured to determine the amount of time between sending and receiving a single byte of data.
- Note that the latency of the computer is included in this test. For this test, it was assumed that the latency of the computer would be insignificant relative to the radios' communication time. To remove this additional latency in the future, one should create a hardware loopback by powering the first Xbee radio and physically connecting this radio's Rx and Tx line via a wire (no computer or PIC needed).
Results
Baud Rate (bps) |
Round Trip Latency (ms) |
9600 |
2.2 |
19200 |
1.2 |
38400 |
1.0 |
57600 |
0.5 |
115200 |
0.2 |