Radio communication part 2

Radio should be used when transmitting data over long distances, or when cables are impractical or undesirable. This is the second in a series of articles that use XBee S2 radios to build a wireless sensor network. In this article, API packets will be sent and received between a PC, co-ordinator device and an end device (see Figure 1).

wireless sensor network

Figure 1: Wireless sensor network using XBee S2 radios (a.k.a XB24-ZB)

Parts list

For this article the following parts were used:

  1. 2 Adafruit XBee adapter kits (see html)
  2. 2 XBee S2 radios (see html)
  3. FTDI serial cable

Extending the API library

The firmware developed in part 1 (see html) was extended to include remote AT commands. In particular, the following packet types were added:

  • Remote AT Command Request (ATRemoteTx)
  • Remote Command Response (ATRemoteResponse)

The ATRemoteTx packet is used query or set parameters on a remote radio. The ATRemoteResponse packet is received from the remote radio and signals whether or not the AT command was successful. The response packet is sent to the local radio's UART (and, in this case, to the PC).

Hardware

The second Xbee S2 was then flashed with firmware ZIGBEE ROUTER API v.23a7 (as described in the first article). The first radio still had the ZIGBEE COORDINATOR API firmware v.218C installed.

Since the second radio was remote, it needed it's own power source. This was provided by the 5V and GND pins of a spare development board, which was in turn powered by a 9V battery.

Result

The packet was sent with the local radio and responded to by the remote radio. The destination address was left to the default (broadcast) which meant that every radio that received the message would respond. After fixing a problem with memory allocation and pointers, the software output the following:

Transmit:
  Type: ATRemoteTx
  Frame ID: 0x52
  AT command: BD
  AT value: 
  Destination address: 000000000000ffff
  Network address: fffe

Response:
  Frame type: ATRemoteResponse
  Frame ID: 0x52
  Status: OK
  AT command: BD
  AT value: 9600

Discussion

It would be nice if this all went as smoothly as it seemed to, but it did not.

An important debugging technique that was used during this article was being able to make the system fail predictably. This is especially important when you can't see what is going on. For example, turning off a remote radio and sending a ATRemoteTx packet should result in no response packet. With the program written as it is, it just waits indefinitely for a response. While this test may seem trivial, it is extremely important to make sure that the system is actually doing what it appears to be doing.

At the moment it is unclear why there is both a 64-bit destination address and a 16-bit network address is required for packets. The datasheet seems to indicate that the network address is only used once the radio has been added to the network, presumably by the co-ordinator device. See the update below for further investigation into this.

The API packet library has been challenging so far, but the real test will be in the next article. For that, the software will need to be compiled for both a PC and an ATmega MCU. The ability to switch between g++ and avr-g++ has been tested along the way, but there will no doubt be other problems.

Conclusion

Second step complete! Communication has successfully occurred between a PC and a remote XBee S2 over radio. The next step is to send and receive data from a remote radio. This is decidedly more complex, as the data will have to be managed by an MCU and stored at the end device.

Update: networks and addressing

The Personal Area Network (PAN) is a special ZigBee networking protocol.

AT label range description
ID PAN ID 0 - 0xfffffffffffffffff Personal Area Network ID the device should join. If ID=0, the device will join any PAN.
SC Scan channels 0 - 0xffff A "bitfield" list of channels to scan when joining a PAN. It is not clear yet what this means, though 0xffff should mean all.
SD Scan duration 0 - 0x07 Scan duration when attempting to join a channel. Scan duration = SC*(2^SD)*15.36ms. Maximum duration per channel then is about 2s.
ZS ZigBee stack Profile 0 - 2 0 = network specific, 1 = ZigBee-2006, 2 = ZigBee-PRO
NJ Node join time 0 - 0xff The time that the device will allow other devices to join it. If 0xff, device will always allow joining. Time = NJ*1sec
NW Network watchdog t/out 0 - ? If non-zero, Router will leave network if it does not receive a valid communication within (3*NW) minutes. Reset after each received packet.
JV Channel verification 0/1 Router will verify co-ordinator exists on the same channel after joining and leave if it cannot be found (i.e. if NJ=0xff).
JN Join notification 0/1 Router will transmit a broadcast node ID frame on power up and join. This blinks the Assoc LED rapidly on all devices that receive the data. Should be disabled (0) for large networks.
OP Operating PAN - Read the operating PAN ID.
OI Operating 16-bit PAN ID - Read the 16-bit operating PAN ID.
CH Operating channel - Read the operating channel number.
NC Number of children - Read the number of remaining end device children that can join this device.

The following AT commands were then queried of the remote radio:

AT Response
OP RSS LED flash, No response packet,
OI RSS LED flash, ATRemoteResponse packet, Status = OK, AT value = 0xc916, and
CH RSS LED flash, ATRemoteResponse packet, Status = OK, AT value = 0x13

The values that were returned did indeed match those on the radio.

Pondering these results, it occured that maybe the OP and network address variables only works once a radio is connected to a PAN? If the co-ordinator PAN ID is set to zero, then a random PAN ID is chosen. So instead, the co-ordinator and router radios were both then flashed with the following values:

  • ID = 0x01, that is, the same PAN ID
  • SC = 0xffff, scan all possible channels
  • SD = 0x0003, for a scan duration of about 120ms per channel
  • NJ = 0xff, always allow nodes to join
  • NW = 0, no watchdog timeout
  • JV = 0, don't verify channel
  • JN = 1, notify on joining channel

The previous AT commands were then queried of the remote radio again:

AT Response
OP RSS LED flash, ATRemoteResponse packet, Status = OK, AT value = 0x01
OI RSS LED flash, ATRemoteResponse packet, Status = OK, AT value = 0x12ca
CH RSS LED flash, ATRemoteResponse packet, Status = OK, AT value = 0x16

As expected, turning off the remote radio caused these commands to fail.

The next thing that was investigated was the Destination Address variable. Using the X-CTU software the remote radio was given a Destination Address of 0x01. The network address was left as 0xfffe. The co-ordinator radio had a Destination Address of 0x00. Then, using these two radios, a remote AT command with a Destination Address was used to query the baud rate:

Transmit:
  Type: ATRemoteTx
  Frame ID: 0x52
  AT command: BD
  AT value: 
  Destination address: 0000000000000001
  Network address: fffe

Response:
  Frame type: ATRemoteResponse
  Frame ID: 0x52
  Status: Tx Failure
  Dest addr: 0000000000000001
  Netw addr: fffe
  AT command: BD

Failure! The only feedback from the remote radio was the red RSS LED flashed once for 4 seconds upon sending the packet. This indicates that it may yet have received the packet, but did not respond.

Next, using two radios, a remote AT command was sent with a broadcast address that queried the DH and DL variables (destination high and destination low respectively).

Transmit:
  Type: ATRemoteTx
  Frame ID: 0x52
  AT command: DH
  AT value: 
  Destination address: 000000000000ffff
  Network address: fffe

Response:
  Frame type: ATRemoteResponse
  Frame ID: 0x52
  Status: OK
  Dest addr: 0013a20040c049c1
  Netw addr: 0b69
  AT command: DH
  AT value: 00000000

Transmit:
  Type: ATRemoteTx
  Frame ID: 0x52
  AT command: DL
  AT value: 
  Destination address: 000000000000ffff
  Network address: fffe

Response:
  Frame type: ATRemoteResponse
  Frame ID: 0x52
  Status: OK
  Dest addr: 0013a20040c049c1
  Netw addr: 0b69
  AT command: DL
  AT value: 00000001

This response was very interesting. Even while the AT command response shows a destination address of 0x0000000000000001, the address of the remote radio returning the response is 0x0013a20040c049c1. The only explanation I can think of is that these values have different functions, at least for routers. It is unknown as yet how to set this destination address explicitly.

A remote baud rate query was sent with this new destination address:

Transmit:
  Type: ATRemoteTx
  Frame ID: 0x52
  AT command: BD
  AT value: 
  Destination address: 0013a20040c049c1
  Network address: fffe

Response:
  Frame type: ATRemoteResponse
  Frame ID: 0x52
  Status: OK
  Dest addr: 0013a20040c049c1
  Netw addr: 0b69
  AT command: BD
  AT value: 9600

Success! As expected, turning off the remote radio caused this command to fail.