This page was written for Mature ZigBit modules. Click here for information on the newer modules.
This page describes how to setup Peer to Peer communication between two Zigbit modules using Atmel's Lightweight Mesh wireless stack.
The Zigbit is a family of Atmel RF modules containing an AVR microcontroller and an Atmel RF transceiver. All Zigbit modules contain an ATmega1281 microcontroller. The 2.4GHz Zigbit modules contain an AT86RF230 radio, while the 900MHz Zigbit module implements the AT86RF212 radio. Data transfer between the microcontroller and the transceiver occurs through each device's SPI interface. The ATZB-24-A2 Zigbit module was used for this project.
- Link Budget: 104 dB
- Power Consumption: <20 mA active, <6 uA sleep mode
- Memory: 128K bytes of flash, 8K bytes RAM, 4K bytes EEPROM
- Serial Communication Ports: UART, USART, I2C, SPI (reserved), 1-Wire
- Antenna Options: Chip, Balanced RF Out
Atmel Lightweight Mesh (ALM) Overview
Atmel Lightweight Mesh software stack implements a proprietary low power wireless mesh network protocol. It is designed to work with all 802.15.4 transceivers from Atmel and can be loaded to any AVR microcontroller from Atmel. It can be used in a broad range of wireless applications including Alarms and Security, Automatic Meter Reading, Home Automation, as well as simple wire replacement applications.
- Stack allows for up to 65535 nodes in a single network
- Up to 65535 PANs at a single frequency
- Up to 15 application endpoints
- No special procedure for node to join network
- Automatic route discovery
- Less than 8kB of Flash and 4 kB of RAM for typical application
The latest version of ALM can be dowloaded for free from Atmel's website here:
Atmel Studio 6 can be used to add a user application on top of the wireless stack. Atmel Studio 6 can be dowloaded for free from Atmel's website here:
ALM Peer to Peer Application
The ALM download includes various pre-written Atmel Studio projects for multiple platforms, including Zigbit. The Peer to Peer project is designed to implement a 2 Node network using the ALM stack. There is no parent-child relationship within the ALM protocol, so this project displays true Peer to Peer behavior. The following describes how the Peer to Peer project is intended to operate.
Figure 1: Peer to Peer Communication
When either of the Zigbits receives data on the respective UART_RX line from an external device, the characters are immediately transmitted over the air to the opposite Zigbit. Whenever either of the Zigbits receives data over the air, the data is transmitted through the Zigbit's UART_TX line to an externally connected device. An example of an external device would be a PC with some sort of hyperterminal software. In this way, characters typed on PC 1 could be printed on PC 2.
The ALM does not provide a way to auto-assign an application ID on the fly to a node attempting to join the network. It is up to the designer to assign a unique ID within the application code of each device. The Zigbit Peer to Peer project includes a configuration file called config.h which can be used to assign the application ID. For two devices to communicate properly using the Peer to Peer application, define one device's application address as 0 and the other device's application address as 1. The application channel, PANID, endpoint, security key, and flush timer interval should be the same for both devices. If the user is using a PC with a hyperterminal program, it would be a good idea to add the following line of code to the HAL_UartBytesReceived() function in Peer2Peer.c:
immediately following the HAL_UartReadByte() function call. This will echo keystrokes entered from the keyboard.
Step by Step Peer to Peer Example using ALM
For this example, two Zigbit modules will be used to communicate between two different hyperterminal programs on separate computers using topology similar to that shown in Fig. 1. When the user enters keystrokes in one hyperterminal program, the characters are displayed in the second hyperterminal program.
Two Zigbit modules with integrated chip antenna (ATZB-24-A2) were used for this example. Additional items used include JTAGICE3 programmer/debugger (ATJTAGICE3-ND), and two UART/USB bridge cables (768-1015-ND). The Zigbit modules were mounted onto a break out board for easy evaluation. The cables used in this example allow the user to communicate to the Zigbit UART through a USB port of a PC.
- Tera Term - This is a free, open source, terminal emulator which includes a built in macro scripting language. It can be downloaded for free from multiple sources via a quick internet search. Any hyperterminal program that supports serial port communication can be used, but Tera Term was used for this example. Download Tera Term from CNET
- Atmel Studio 6 - This is a free IDE which can be downloaded from Atmel for free here. It allows easy manipulation of code and programming/debugging devices.
- Atmel Lightweight Mesh (ALM) - This is a low power proprietary mesh network wireless stack from Atmel. It can be downloaded free here.
Figure 2 below shows the external connections between each Zigbit and the respective PC. The UART of the Zigbit was connected to the PC using the UART/USB bridge cable (768-1015-ND). The serial port settings were set to:
- Baud: 38400
- Data: 8 bit
- Parity: None
- Stop: 1 bit
- Flow Control: None
The JTAGICE3 was connected between the PC and Zigbit using the standard cables included in the kit. A general purpose LED was connected to GPIO0 of the Zigbit module to monitor status.
Figure 2: Zigbit Connections
Figure 3 shows the proper connections between the Zigbit UART and the PC serial port.
Figure 3: UART/PC Connections
Note: If using the UART/USB bridge cable from FTDI (768-1015-ND) to connect the Zigbit to the PC, the cross-over connections shown in Fig. 3 are already done within the cable. Consult the cable datasheet for a pinout of the cable connector and simply connect TXD of cable to TXD of UART. Do likewise for RXD, CTS, and RTS.
Warning: The FTDI cable draws power from the USB port. Therefore, the Vcc line on the cable will source 5.0V to the target. Make sure Vcc of the cable is not directly connected to Vcc of the Zigbit or damage to the device could occur. Use a voltage regulator to drop the voltage to 3.3V or use an external 3.3V source to power the Zigbit module.
In this section the two Zigbit modules will be referred to as Device 1 and Device 2. For this example we will only make a few additions on top of the stack to get the user familiar with how and where the stack should be modified.
- Download Atmel Studio 6 and ALM.
- In the ALM download folder, navigate to apps -> Peer2Peer -> astudio. Open ZigBit_ATmega1281_Rf230 in Atmel Studio.
- Connect JTAGICE3 to Device 1. The Zigbit module ships with the CPU clock set to 1 MHz. For the ALM timing to be completely accurate, the CPU clock should be running at 8 MHz. To check this, in Atmel Studio navigate to Tools -> Device Programming. Select JTAGICE3 from the Tool dropdown. From the Device dropdown, select ATmega1281. For Interface, select JTAG and click Apply. On the left side, select Fuses. Find the CKDIV8 fuse and make sure the box is unchecked. The Fuse registers should read 0xFE, 0x9D, and 0xC2. If not, change them and select Program. Close the Device Programming dialog box.
- Before making any modifications to the stack, try building the project and programming Device 1. If you run into issues consult the common issues section below. If the device programs correctly, continue to step 5.
This step describes how to configure a GPIO pin of the Zigbit and also how to create a miscellaneous application software timer within the ALM. To be able to use the LED, GPIO0 needs to be configured as a digital output pin. For this example, we will use the LED as a heartbeat for the module that toggles every second, indicating power up and proper function. If the user does not want to use an LED or configure a software timer, skip to step 6. In Atmel Studio, in the Solution Explorer window, navigate to hal.h and add the following line of code:
Also within hal.h, add the following lines of code under the function prototypes:
Navigate to hal.c. Add the following two lines of code to the HAL_Init() function:
Navigate to Peer2Peer.c and add the following variable declaration:
Add the following lines of code at the end of the appInit() function to configure a 1 second heartbeat software timer:
Add the software timer somewhere above the main function as shown below:
Now build the project and program Device 1. Make sure the LED is connected to Device 1 as shown in Fig. 2 above. If the LED is properly connected, it should toggle every second.
Since we are using a hyperterminal program, it may be desirable to echo keystrokes in the terminal window. To accomplish this, add the following line of code to the HAL_UartBytesReceived() function, after the HAL_UartReadByte() function call:
Now, as the user enters keystrokes in the hyperterminal program, the characters will be displayed in the terminal window.
By default, the ALM enables basic network security. For this example, we will also enable Ack signals between the two devices. In Peer2Peer.c, modify the options in the appSendData() function to enable Ack signals as show below:
Application configuration is based on definitions within config.h. For this example, we will leave the default configuration for Device 1. Navigate to config.h and verify the following definitions are made:
- Build the project and program Device 1. Verify that the heartbeat is toggling every second as intended. Ensure the serial port is configured properly and Device 1 is connected to the PC. See External Connections section above for proper serial port settings and connection to Device 1. Try typing characters in the terminal program. You should see correct characters appear in the terminal window as they are entered on the keyboard.
Connect Device 2 to the JTAGICE3. Verify proper fuse settings for Device 2 as described in Step 3 above. Navigate to config.h and make the following change:
All other definitions should be left alone.
- Build the project and program Device 2. Verify that the heartbeat is toggling every second. Ensure proper serial port settings on a second hyperterminal program and that Device 2 is connected properly. Try typing characters in the terminal program. You should see correct characters appear on both terminal windows as they are entered on the keyboard. If not, consult the Common Issues section below.
- Switch back to the first hyperterminal program and try entering characters. Correct characters should appear in both terminal windows. If UARTs are working properly, but no wireless transmission appears to be happening, try moving the devices closer together and/or removing objects between the two devices. If this doesn't enable wireless communication, consult Common Issues section below.
Figure 3 below shows an example output from the terminal window connected to each device when the following message is entered:
"Hello, My name is Zigbit"
From this basic example, the user should be able to transmit data from one device to another. Characters received over UART were used as the data source in this example, but anything can be used as a data source. A simple button press, or physical measurement from a sensor could also be used as a data source. The example uses a software timer to transmit every 20ms if data is present. However, it is up to the designer to determine when transmission occurs.
- Project will not compile and exits with code 9009.
- Navigate to Project -> ZigBit_ATmega1281_Rf230. On left side, click on Build Events. Delete both Post-build events and save.
- Project builds and programs but no heartbeat occurs.
- Verify that the LED is connected properly.
Verify that the program is getting through intialization properly. Start debug session or add the following code at the very start of the main() function:
If LED still doesn't turn on, there's a connection issue. If LED does turn on, verify that system initialization is being completed by moving the block of code after initialization.
- Project builds and programs, but the program gets stuck in initialization.
Navigate to the following variable declaration and remove 'static' keyword:
- Project builds, programs, and gets through intialization, but the UART doesn't appear to be working.
- Verify UART is connected properly. See External Connections section above for proper UART connections.
- Verify serial port settings are correct. ALM default UART settings are: Baud: 38400; Data: 8 bit; Parity: None; Stop: 1 bit; Flow Control: None;
If attempting to use a different Baud rate, ensure correct value is being loaded into Baud Rate Register. Refer to tables 22-9 to 22-12 in the ATmega1281 datasheet for exact register value. The brr equation used by the ALM is not correct for every Baud rate scenario due to integer drop-offs. However, the default 38400 baud does work correctly. Keep in mind the amount of error in the Baud rate being used. Different hyperterminal software may have stricter requirements on the amount of acceptable timing error.
If connections and configurations appear to be correct, navigate to the following variable declarations and remove 'static' keyword:
- Project builds, programs, and UART is working, but no wireless transmission is occuring.
- Ensure the two devices are sufficiently close to enable transmission. If possible, put the devices right beside each other.
- Ensure the devices are configured correctly. Navigate to config.h. The APP_ADDR should be 0 for one device and 1 for the other device for the Peer2Peer application. The APP_CHANNEL must be the same for each device. The APP_PANID must be the same for each device. The APP_ENDPOINT should be 1 for each device. The APP_SECURITY_KEY and APP_FLUSH_TIMER_INTERVAL should be the same for each device.
Ensure each radio is entering receive mode. Enter a debug session or navigate to phy.c and place the following lines of code in the phyHandleSetRequests() function:
Make sure an active low LED is connected to GPIO0 and GPIO0 is not given a logic level '0' anywhere else in the program. Build project and program device. If the LED doesn't come on, navigate to the following variable declaration and remove 'static' keyword:
and see if LED turns on. If it does, remove the GPIO0 code, reprogram, and the radio should enter receive mode as intended.
- Ensure data is being received by the radio. Observe SPI lines using an oscilloscope on the receiving device during transmission or navigate to at86rf230.h and use GPIO code as before inside phyInterruptHandler(). When the radio is in receive mode and picks up an incoming signal, phyInterruptHandler will trigger.
If data is being received by the radio, but no data is getting stored in the PHY receive buffer, navigate to the following variable declarations and remove the 'static' keyword:
Was this section helpful to you? Are you encountering an issue not covered by this section? Do you have a fix for an issue not talked about here? Email the author.
Contact the Author
The reader is strongly encouraged to fully read all documentation referenced on this page. Much of what is stated on this page appears somewhere in a devices datasheet. Many of the details of the functionality of the stack, radio, and microcontroller were not discussed on this page. Reading the ALM Developer Guide will give the reader a better understanding of the network protocol and how it compares to other wireless standards. For questions or concerns regarding this example usage of the ALM, contact me at firstname.lastname@example.org. I will continue to add common issues as they present themselves. Internal Zigbit schematics are available per request.