Friday, June 20, 2014

I'll try to explain XBee API Mode and How to Set it Up

I've gotten hundreds of questions on XBee API mode.  API mode is necessary for setting up an XBee network of more than three devices because AT mode (also called transparent) will cause fragmentation and mixing of data over time.  I have a post somewhere about this that explains my experience when I finally exceeded what the XBee was capable of when using AT mode <link>.

So, what is API mode?  It's simply a protocol between the serial port on the XBee and your controller.  Be it Raspberry Pi, Arduino, Galileo, whatever, you talk to an XBee through a serial port and what goes over the serial port isn't what the XBees send amongst themselves.  First, a simple picture:
I'm not an artist, so use your imagination.  The term 'API mode' refers only to the two serial links that connect your controllers to the XBee.  What goes over the RF link is not affected and shouldn't be; that's something that Digi takes care of quite nicely.

In AT mode, what you send out the port is what you want to be sent to the other controller.  You want, "Hello World," that's exactly what you send.  The XBee will collect the characters and put them in an RF packet and send them to the other XBee.  If the other XBee is in AT mode as well, it will parse the characters out and send them through the serial port to the other controller.  Simple, easy to understand, and the way almost everyone starts out with the XBees.

Now a little bit about API mode.  API mode allows you to shape a packet complete with checksum, destination address, and other things that give you control over what goes on.  It also allows you confidence that what you send gets to the other end complete and in one piece.  See, AT mode will send some of it, wait, then send the rest of it.  This depends on traffic and RF noise, so it's possible to get part of a message, then the rest of it later.  If you have a number of XBees, you'll actually get messages that have been mixed together and made unusable.  You get all the stuff that was sent, but it may be jumbled up.  API mode is the way to go after you've played with AT mode some to get a feel for things.

So, how to you set up an XBee to transmit in API mode?  I only work with Series 2 and later XBees, so everything here applies to them, if you're working with series 1, you're going to have to look somewhere else for examples.  Remember that API mode only applies to the serial links; I've labeled them in the drawing, so there are two things you have to change to get API mode on the XBee: the software you load on the device, and the serial interface you choose.

I use modem setting 'XB24-ZB' and Function Set 'ZIGBEE COORDINATOR API'.  These are found in the Modem Configuration tab of XCTU up at the top.  I always choose that latest software version on the far right.  Here's a picture to help you find it:

This software, once you load it on the XBee will give you API mode.  The XBees come defaulted to AT mode, so you'll have to download XCTU and change them yourself.  Of course, if you're programming a router, choose 'ZIGBEE ROUTER API' as the 'Function Set.'

Now you have to change the various parameters to be specific for your usage.  Things like Pan ID, Channel, that kind of stuff.  I address these things in other posts, so look them up there, or use one of the jillion tutorials out there.  Once you get that stuff in, you can set which API mode you want to use.  On the Arduino using Andrew Rapp's XBee library, you'll need to use API mode 2.  For the Raspberry Pi using the XBee package, you'll need to use API mode 1.  Don't worry, they will work fine together.  Remember above where I told you API mode only affects the serial link to the controller and not the RF link between XBees?  This is the beauty of these little devices, the mode doesn't change how the XBees talk to each other, just how they talk to the controller.

API mode is set under 'Serial Interfacing' a little bit down the screen, so scroll down until you find it.  The values are (duh) 0, 1, or 2.  Zero means no API, 1 is for API mode 1, and 2 is for API mode 2.  What's the difference?  I talk about this and the interaction of the various modes here <link>.  Why do I need different API modes on the different controllers?  Because the authors of the libraries wrote them that way and we have to adjust ... or heaven forbid ... write our own code to handle it.

Write the parameters to the XBee and you have now set up the XBee to work in API mode using whichever mode ( 1 or 2 ) is appropriate.   In case you need to save this configuration, there is a profile save button on the screen.  Use it to keep the various profiles you try over time.  You can simply reload it and avoid all of this next time.

One other thing: now you have to change the settings on the first screen of XCTU to talk to it properly.

About half way down the screen there's a box 'API,' check the 'Enable API' setting, and depending on how you configured the XBee, check the 'Use escape characters' box.  In API mode 1, you don't check it; in API mode 2, you do.

Now you have to change the code you're running on the controllers to use the new mode.  It's worth it because you can check the checksum on a message to see if it got clobbered on its way to you, address specific XBees so you don't have unnecessary traffic.  Use end devices that don't have a controller attached, just use the native pins on the XBee.  It makes the little devices much more versatile.  For examples, I have posts about some of the libraries on this blog, Just type XBee in the search box on the upper left and look around.


  1. Hi Dave !
    Thank you so much for you blog and I cant believe it took you so little after my request on the other post to write this up.
    You are doing a great job in this blog. Thanks

  2. Hi Dave

    Thanks for the info, makes things alot easier to understand.
    How do you parse the rx packet on the arduino, do you use the library?


    1. Yes, there's a library for the XBee in almost every language, so I didn't want to reinvent the wheel. In various places on this blog I have examples of how to use the python and arduino libraries to get and send data.

  3. Hi Dave,

    Thank you for all your insightful work.

    I have a question regarding you XCTU configuration. Do you follow Andrew Rapp's suggested configuration for Xbee S2 in his documentation?

  4. Mostly, you can't follow it blindly though. Depending on the host it's hooked to, things may have to change.

    1. Yes, Thank you.
      To begin with your Tx example in Using the XBee Library Part 3 seems to work just fine.
      I'm now trying to stream sensor data instead of a string.

      I can't begin to explain what a huge help your site is compared to other examples out in the web.

      Thank you so much!