Posts

Playing Xbee. Part 4 – API.

Setting serial speed on Xbee module

Setting serial speed on Xbee module


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.

51 comments to Playing Xbee. Part 4 – API.

  • Amit Rana

    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.

  • Rodrigo

    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 ).

  • DAT DANG

    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.

  • DAT DANG

    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

  • erooll

    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!

  • Manu

    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.

  • Manu

    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

  • amit rana

    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

  • Manu

    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.

  • Rthamburan

    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.

  • Rthamburan

    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

  • Rthamburan

    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

  • Vigoti

    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.

  • TUYEN PHUNG

    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!

  • Denz

    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

  • DUNG

    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

  • Matt

    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?

  • K.Or

    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?

  • Hape

    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

  • peter manoj

    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

  • Milestone

    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!

  • Cass

    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??

  • Cass

    Hi Oleg,

    If my USART pin (RC6/RC7) already using for connect with the MCP2551 (can bus transmitter), how can i connect with xbee?

  • WantoKnow

    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?

  • Ricardo

    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.

  • shaqa

    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

  • kavejska

    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.

  • Peter

    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?

  • Husam

    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.

  • konstantina

    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.