Xbee module supports two modes of operation – transparent mode and API mode. To create simple point-to-point links, Xbee works nicely in transparent mode without much coding. However, if your goal is to build a network consisting of more than two devices, AT mode becomes too difficult to bear. You will spend almost all the time switching in and out of command mode, wasting time and draining batteries in the process. On the other hand, in API mode commands and data travel in specially formatted frames and no switching is necessary. Another advantage of API mode is that serial speed on transmitters doesn’t have to match – one can be configured for 115200bps, another for 2400bps, third left with default 9600bps. There is another nice feature called remote command; you can remotely request the state of Xbee module pins, for example, or change an output pin level. It means that for simple measuring and control applications no MCU is even necessary at the sensor.
API mode requires re-flashing module firmware and some extra coding on both sides of the link. I started with upgrading the firmware. Picture on the right shows X-CTU screen with serial speed drop-down expanded – along with loading API firmware I’m changing the speed of coordinator Xbee to 115200.
At the end of re-flashing you need to reset a module. Keep a piece of wire or a pair of tweezers handy to short reset pin to ground when asked by X-CTU. You then need to go to “PC Settings” tab and check “Enable API” to restore communications to the module.
After flashing API coordinator firmware to one Xbee module and API End device to another, it’s time to run a quick test to make sure we still can communicate. The following project contains API mode test routines, you will need to compile it, program the PIC and run. In this code I started using reset line, which runs from Xbee reset pin ( 5 ) to PIC pin RC2 ( 13 ), make sure you have it on your board.
First two functions are contained in xbee_api.c module. The first one performs Xbee initialization. Function releases Xbee module from reset on line 10 and waits for “Modem status reset” frame from the module. First ‘while’ loop on line 11 checks incoming character for frame delimiter 0x7e. After that, it grabs next 5 bytes from the USART receive buffer and compares it to “modem_reset” pattern. If everything is good, it terminates returning TRUE. After this function finishes, we can start sending data to Xbee.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* Xbee initialization */ /* De-asserts reset and waits for modem status "reset" from Xbee */ BOOL Xbee_init( void ) { BYTE modem_reset[ 5 ] = { 0x00, 0x02, 0x8a, 0x00, 0x75 }; //modem status "Reset" frame including checksum BYTE buf[ 5 ] = { 0 }; BYTE i = 0; BYTE tmp; DWORD delay = uptime + 2000; //2 seconds from current uptime XBEE_RST = 1; //release reset while( uptime < delay ) { if( CharInQueue()) { tmp = recvchar(); if( tmp == 0x7e ) { //waiting for frame delimiter break; } } } if( tmp != 0x7e ) { //fail if no frame delimiter was received in 2 sec. Typical reset time is 300ms return( FALSE ); } while(( i < 5 ) && ( uptime < delay )) { if( CharInQueue()) { buf[ i ] = recvchar(); i++; } } if( memcmp( (const far char *)modem_reset, (const far char *)buf, 5 ) == 0 ) { //if received packet is modem status "Reset" return( TRUE ); } else { return( FALSE ); } } |
Next function is written to generate a transmit packet. It is straightforward sending of necessary bytes and calculating checksum.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* sends transmit request to addr, network */ /* 256 bytes max.payload; Xbee max.payload is 100 bytes */ void Xbee_xmit_request( BYTE *addr64, WORD network, BYTE nbytes, BYTE *data, BYTE frameid, BYTE bradius, BYTE options ) { WORD tmpword = 0; BYTE checksum = XMIT_REQ; //frame type is added since it BYTE tmpbyte; char i; char *byteptr = NULL; sendchar( FRM_DLM ); //send frame delimiter tmpword = nbytes + 14; //payload plus frame type, frame ID, addr, network, broadcast radius, options byteptr = ( char *)&tmpword; //little-endian assumed for( i = 1; i > -1; i-- ) { sendchar( *( byteptr + i )); } sendchar( XMIT_REQ ); //send frame type /* starting calculating checksum from here */ checksum += sendchar( frameid ); //send frame ID for( i = 7; i > -1; i-- ) { //send address tmpbyte = *( addr64 + i); checksum += sendchar( *( addr64 + i )); } byteptr = ( char *)&network; for( i = 1; i > -1; i-- ) { //send network checksum += sendchar( *( byteptr + i )); } checksum += sendchar( bradius ); //send broadcast radius checksum += sendchar( options ); //send options for( i = 0; i < nbytes; i++) { //send payload tmpbyte = *data; checksum += sendchar( *data ); data++; } checksum = 0xff - checksum; sendchar( checksum ); } |
Next function is a simple test sending “Hello!” string to the coordinator. It is part of the main module. The coordinator 64-bit address is all zeroes, the 16-bit address is 0xfffe. This function simply calls “Xbee_xmit_request” with necessary parameters.
1 2 3 4 5 6 | void APItest( void ) { char tmpstr[] = "Hello\r"; BYTE coord[ 8 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; Xbee_xmit_request( coord, 0xfffe, 6, tmpstr, 1, 0, 0 ); } |
Finally, let’s take a look at the main routine:
1 2 3 4 5 6 7 8 9 10 11 | void main ( void ) { Board_init(); USART_init(); if( Xbee_init() == FALSE ) { while( 1 ); } while(1) { //main loop APItest(); } } |
The routine calls “Xbee_init()” and goes to infinite loop if initialization fails. This way, if something is wrong with the setup, we can catch it in the debugger. If initialization is successful, the main routine enters next infinite loop sending a packet to the coordinator.
Assuming our PIC test program is loaded and running, let’s now move to the coordinator side. The first test can be done right from X-CTU. Connect the USB coordinator with USB explorer to a PC running X-CTU, start the program, check connectivity from the PC Settings tab and switch to the Terminal tab. The following screenshot shows what you will see if your communication works. If everything is good here, we can move the coordinator to its final destination – Linux machine.
The Linux part is written in Python using pySerial module. This module is available for almost all platforms; however, it’s not part of a standard Python distribution and may need to be installed first. Connect USB explorer with coordinator Xbee to the Linux machine, open your editor and type the following text:
#!/usr/bin/env python import serial TTY = '/dev/ttyUSB0' ser_port = serial.Serial( TTY, 115200, rtscts = 1 ) print ser_port.portstr while True: if( ser_port.inWaiting() ): print( ser_port.read() ) |
Save the file with name ‘try.py’ and run it like that:’./try.py’. The following screenshot shows what you should see if everything works correctly. If you can see it, congratulations!
Oleg.
Hey, am designing P18 and zigbee based sensor network
Am using only one xbee with pic and rest 3 xbees with 3 sensors,
how to receive and distinguish the data received at PIC? please help
You can distinguish by sensor address or give them names and distinguish by name.
You can use API mode. When Xbee sends data using frame ID 0x10, receiving Xbee gets data in 0x90 frame ID. The sender’s address is part of 0x90 frame format. See doc for more info.
oleg, you say “You can distinguish by sensor address…” you mean that or you meant “You can distinguish by ZIGBEE address…”
Zigbee addresses are dynamic – that what coordinator assigns to endpoints when they register. Each radio has unique factory-programmed address, I suggested using this one because it is constant. You can configure textual name to the radio and use this name to distinguish between radios (this is going to be two step process – first your software discovers name to address relation, then use this address to get to particular radio, much like in DNS ).
I’m working on the project about Zigbee. My supervisor forces me to use the AT mode in Zigbee to set up the network among many devices, He said I didn’t need to use API mode. There is another way to do that without using API mode. He didn’t tell me about that ,he advised me to find out. Do you have any idea abou this problem.
You can switch destinations using AT commands. There is a sample code on my site demonstration going in and out of command mode. The commands to set destination are documented in the user manual. This is going to be very slow, around 3-4 seconds to switch destinations. If you have 20 end devices it would take a minute to talk to all of them. API mode is much faster when more than 2 devices are involved.
My system is very simple, I have three Zigbee modules , all of them will transmit data to one Zigbee center, it looks like multi-point to point. So if I use AT mode ,it could take nearly 10 seconds . I’m wondering that if three Zigbee modules transmit data to one Zigbee center AT THE SAME TIME.
How could the Zigbee center deal with this case in API mode?
Which one Zigbee center could choose to receive the data?
Thanks for your help
You don’t need to worry about simultaneous transmissions, it gets sorted out automagically.
Hi. I have experience with module in transparent mode, now I want use API to send data.
It’s strictly necesary have one module as coordinator and others as end devices, or only set same PAN and Channel in all’s modules?
thanks
You don’t have to set anything manually. What you need is to load coordinator firmware in one xbee, and end device firmware in other. PAN and channel would be set in coordinator automatically and end devices would join this PAN automatically also.
I’m not really familiar with the PIC18F you’re using – can you please tell me which interrupt you’re hooking for the lowPriorityISR? Is it just the 1ms timer (using CCP2)? Or is that just the highPriorityISR? Thanks!
Low priority ISR is used for USART transmissions, high priority – for 1ms timer.
Hi Oleg,
I’m working with API mode and PIC18, I have various Zigbee modules (router or End-devices) that are continuously transmitting measures to the Coordinator (this works fine), but sometimes Coordinator must send some data to a ZIgbee module and read the response to this data.
My problem is when Coordinator is sending data while he should be receiving measures, the PIC can not do both things at once. HOw do you think I could fix this? Maybe using USART interrupts??
Thanks and best regards
How many modules do you have? I never had problems with simultaneous transmission and receiving. And yes – I am using interrupt-driven serial routines in my PIC code, they work better in general so I use them everywhere.
Hi Oleg, I’ve used #INT_RDA interrupt and PICs work much better. From here I’ll always use USART interrupts for transmit and receive
Thanks
hii am using xbee connected to pic18f4520 and 3xbees with 3 sensors
how to distinguish them?? am unable to find proper
programming technique for my PIC to do so?
how to identify the received bytes at PIC am using
C programmig and mikroC compiler
please help
I think you should work with API mode.
When a frame is received by the coordinator, this frame have a field with the address of the device that transmitted it.
I want to communicate using 4 xbee.ie one coordinator and 3 end devices.The end devices must send and receive data from other end devices.How can i configure xbee.I want to use AT mode or API mode ? i am using xbee pro series2
For this scenario, I would use API mode. As far as configuration, nothing special needs to be done, just load API firmware to your modules and you’re ready to go.
I have already loaded the API firmware.But i have one doubt.If i wants to send data from end device1 to end device3 what should be Destination address.Next time if I want to send data from end device1 to end device2 how can i change the destination address.I am interfacing the zigbee device to microcontroller.Can u help me giving the document
The destination address should be address of a module where data is sent. It’s a field in any API packet, you would set it for every transmission. You need to read this -> http://ftp1.digi.com/support/documentation/90000976_D.pdf
I tried to send the API command from the microcontroller to the UART of zigbee for changing the vales of the source zibee as well as the remote zigbee, but it is not working.But when I send these commands directly from the computers serial(COM) port to the UART of zigbee it is working.I think the time taken to send API commands from microcontroller is somewhat high. What must be the time interval to send the API commands. Give me one solution to overcome this problem
I have three Xbee series 1(802.15.4) devices,and my goal is building a wireless sensor network beetween them,but i don’t know how to configure for Xbee to transmit and revieve data beetween Nodes.I only know X-CTU software for test and configure simply.So you can tell me how to do that problem,and which software should i use to do that?thanks a lot.
My system is very simple, I have three Zigbee modules , all of them will transmit data to one Zigbee center, it looks like multi-point to point.How can i configure xbee.I want to use API mode in X-CTU?
Please show me the way to load API firmware to my modules.
Thanks for your help!
The website below explains how to load API firmware onto your xbee. It’s not mention in the XBee product manual.
http://ftp1.digi.com/support/firmware/Instructions%20for%20firmware%20upgrades.pdf
To understand better of API modes, refer to Chapter 9 of API operation from the Xbee product manual
Hi!I dont know how to use AS in AT command. Can you explain to me in detail. Thankyou very much!
I just finished my first project connecting avr32 with XBee
hope it can help someone.
http://snatgassensor.blogspot.com/
Oleg tried to post you first in private but didn’t found how
I’m using a PIC24HJ64GP502, I’ve configured two XBees using X-CTU to be in API mode. I’ve used libraries that have written by another person plus some of my own code for PIC24 in order to get it to write to UART_TX. I’ve connected one XBee to the PIC and the other to the comp running X-CTU terminal. The code I have creates a packet (as far as I know) and it is sending something to the XBee, but it’s not transmitting anything at all and the second XBee isn’t receiving anything, for obvious reasons. I’ve tried everything I know of, which really isn’t much, I’ve no idea what else to try.
Were you able to make your two Xbees talk in serial emulation mode? Also, are you using proper firmware, i.e., coordinator on one of Xbees, router/end device on the other?
I don’t upgrade firmware of xbee. I don’t know that why ??? Please,described for me
Thank you.
There are several different firmware images for Xbee – coordinator, end device, etc. By design, two end devices won’t talk to each other, and two coordinators won’t talk to each other either. They come from the factory flashed as end devices, you need to reflash one of your Xbees to coordinator.
This is true for Xbees I’m talking about here, i.e., ver.2.[0,5] and API mode. There are many others, which are different.
Hi, i’have developped an application for pic18f2620 with xbee series 2.
my application works fine when I use the method of reading parameters COMMAND MODE (I write “+ + +” , “ATNI”, “ATDH”, “ATDL” …. etc) and I can read perfectly by micorcontroler interrupts the Xbee module parameters. When I start to use frames Xbee API in the microcontroller is blocked in this line “while (DataRdyUSART ())”.. The Xbee module not respond to API frame..
For example if i send the following array CArray char [] = (0x7e, 0x00, 0x04, 0x08, 0x01, 0x6e, 0x69, 0x1f); ” i want to read the NODE IDENITFIER PARAMETER device from the Xbee Device but not respond … DataRdyUSART() dont receives nothing.
Whi?
Hi Oleg,
I want to send data from end node to coordinator in API mode. The end node is connected to PIC18f452, I’m trying to send simple data ASCII 1 (API frame = 7E 000F 10 01 0000 0000 0000 0000 FFFE 00 00 31 C0) to coordinator, but the coordinator can not receive the data (the coordinator is connected to computer using X-CTU). Then i’m trying to use your code from this page (with some modification so it can fit my circuit), but it still can not send the data. I think there is no problem with the XBee firmware, cause i’ve tried to connect both device by using two computers, the data can be sent. Is there any additional requirement that i’ve missed in order to connect XBee with MCU ?
Thx
Hi Oleg,
There is a coexistence between ZigBee and Bluetooth results in interference, i saw a bluetooth module to address the same. Can you explain more on this module. I await for your reply via my email ID manomactech@gmail.com
Hi, i have picked a zigbee related project for my design class. I am trying to establish a connection between two zigbees (series2,usb enabled). One attached to the output of the smoke detector and one connected to the computer. I want to establish communication between the smoke detector and the computer through these zigbees.
Any idea!
Hi Oleg,
i’m using PIC18F258 as canbus connect with sensor and sent data to pc though zigbee.
My question is did the PIC can direct connect with xbee without any radio chip??
PIC talks to xbee via USART; the answer to your question is ‘yes’.
Thanks… I had some problem to connect the xbee with PIC. which pin of PIC should i use to connect with the Tx/Rx of Xbee to make the connection??
Hi Oleg,
If my USART pin (RC6/RC7) already using for connect with the MCP2551 (can bus transmitter), how can i connect with xbee?
You will need to do bit bang serial. There is plenty of examples on the net how to do it.
Hi Oleg,
thanks for your tuto.
I try to develop a network with one coordinator and four end-devices.
in a first time, i send at command to switch adress destination, but this was very very too slow. ( about 2s)
So i decided to use API mode:
1- I send the At command ATAP 1 to enable API on coordinator module without change module firmware (10A1)
2- So when end-device send data to the coordinator ( with X-CTU, or a C function), coordinator can received a API sentence with the data.
3-But when coordinator send data in API sentence ( with mine or your function) to a end-device, none data are sending. I use a RS232 analyser to be sure.
4- When coordinator send AT command with API sentence, xbee module put the corresponding answer.
So my questions is :
A) Does it REALLY necesary to load Coordinator firmware on coordinator zigbee to send API sentence to end-device?
B) When i try to load API firmware ( ZIGBEE PRO COORDINATOR API (BETA) version 8114 for coordinator or ZIGBEE PRO ROUTERAPI (BETA)version 8314 for End-Device ), i always have a Big problem, when X-CTU want to send AT parameter whereas i check API enable: It stop with a failed message. X-CTU can’t recognised the module, and i can’t do anything!!Have you any suggestions?
C) If coordinator with API Enable can receive data from end-device with API Disable, Does End-Device with API Disable can receive data from coordinator module with API Enable ?
Best Regards
I haven’t been involved in Xbee projects lately so I start forgetting the details. Have you looked in the manual yet – there is plenty of information there?
Hello..I have to do a network xbee,where there is one coodinator and there are two end devices too.I need that all xbee’s modules will communicate,the coordinator will send the information and the other modules will recive the information.Now how can I make that network??? Please Help me!! thanks…
Hello !
I need a help about send API commands. I want obtain measure from analogic port of the far module. I don’t know as send command and obtain return of the measure. I use the manual but I don’t understand, I make many frame formats but don’t work.
i am using pic33fj128gp802 with xbee radio….i m just sending “hello” from my software everything going fine checksum,transmit func etc but radio is not transmiting so i want to know what problem will be?
is it problem of some kind of interval ?
reply as soon as possible
Hello!
I have a problem triggering digital output (like DO0) on the remote ZigBee.
Case 1:
I know I can trigger it like this:
– setting digital input on the base ZigBee
– setting digital output on the remote ZigBee (DO LOW)
– and if configured right the input state on the base ZigBee is transferred to the digital output on remote ZigBee
I managed to do that, but I would like to trigger it via data packets.
Case 2:
So I tried with setting API packets that set the digital output on the remote ZigBee. I managed to change the digital output on remote ZigBee with commands ATD0=4 (DO LOW) ATD0=5 (DO HIGH).
DO LOW API command:
7E 00 10 17 05 00 13 A2 00 40 08 C9 80 00 02 02 44 30 04 21
DO HIGH API command:
7E 00 10 17 05 00 13 A2 00 40 08 C9 80 00 02 02 44 30 05 20
Problem:
But the problem I have is that sometime the communication between the base and remote might be lost. And if the digital output on the remote ZigBee is set to 3,3V (DO HIGH) and the communication is lost, the digital output would stay at the 3,3V. I want it to “reset” to 0V. In “case 1” when I tried to trigger the digital output with digital input, you can set the reset timer for that digital output (command ATT0) and it did the work (the digital input reset to value 0V), but you can’t use that in the case 2.
Question:
Does anybody know what is the API format of the packet to simulate case 1 – I/O line passing (case 1 data packets)?
Do you have any other ideas how to “reset” the digital output to 0V.
Hi,
I am using your code to send data from my xbeepro2b coordinator to a xbeepro2b router.
When I change the pic you selected to PIC18F4550 I get the following errors:
Clean: Done.
Executing: “C:\MCC18\bin\mcc18.exe” -p=18F4550 “USARTio.c” -fo=”USARTio.o” -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Users\Puchito\Desktop\Senior Project\New folder\Project\New folder\API\USARTio.c:60:Error [1205] unknown member ‘RA7’ in ‘__tag_33’
C:\Users\Puchito\Desktop\Senior Project\New folder\Project\New folder\API\USARTio.c:60:Error [1118] scalar type expected in ‘while’ statement
C:\Users\Puchito\Desktop\Senior Project\New folder\Project\New folder\API\USARTio.c:129:Warning [2054] suspicious pointer conversion
Halting build on first failure as requested.
Any advice to fix these errors?
What should I configure to fit the program to PIC18F4550?
Thanks Oleg, This is really helpful.
I have a quick and simple question:
– When should I use the 16 bit address and when the 64-bit address used, what do you recommend ?
Thanks.
Use one that works for you.
Hello. In my project, i will use THE pic24fh64ga102. In the pic, should i debug the code that you written above??? Should I download any library for the XBee? Also, my pc with the pic communicates through UART communication. The same communication will be used between the pic and the XBee.