Getting what you need out of the xBee API Library for Arduino

Aside: All this code is tested on Series 2 and Pro models of the xBee. With that said understanding this code will allow you to write something very similar if you require the use of Series 1 modules.

Understanding this library was one of the major early challenges for my thesis project. Once I was able to get a handle on the structure of their code it became easy to write code to suit the application rather than the other way around.

The original library was written in 2009 by Andrew Rapp. There have been sporadic updates since then, but in order to get some semblance of an up-to-date version I had to go through a mailing list for the lib. [Update: it appears that the software serial release now exists officially, download your files from the main source]

Armed with what worked in the latest Arduino IDE I began to explore. [Aside: I often say ‘around line XXX’ to keep things simple and semi future compatible]

There are two files for the library: XBee.h and XBee.cpp.

Lets take the ‘get something together right away’ approach to learning this.

If you open the XBee.h file, you will notice a great deal of defined constants. Thankfully they have readable names and some sporadic comments to help us guess our way through this.

If you scroll down to around line 82 you will notice Api Id Constants. These will help us check what kind of packet is being sent or received. In my case I wanted to consider two packets in particular. TheZB_RX_RESPONSEand theZB_IO_SAMPLE_RESPONSEboth deal with received packets of the connected xBee. Note thatZBhere stands for ZigBee, which is the communication mode of the Series 2 xBee modules.

What do these constants represent? A HEX value that each packet uses to identify its nature to the recipient.

What else can we get from this file? The class structure, around line 151 you will notice theXBeeResponseclass being declared and it’s public methods listed.

If you are new to C++ don’t worry, I will describe what this means to us as end users. Public methods are the things we really care about, they are the ‘functions‘ that we would want to call on in our program.

The public methods directly in theXBeeResponseclass are a little high level for our purposes. How do we find what we need?

Earlier I mentioned theZB_IO_SAMPLE_RESPONSEconstant. If you search the file for that name, you will be drawn to somewhere around line 220. There you can see that we have thegetZBRxIoSampleResponsefunction. Lets click some pieces in: if you want to read a value of a pin on an external xBee (lets say you are looking to read a temperature sensor attached to it) you will be looking at an IO Response from that xBee.

The constant mentioned earlier defines how to verify that the packet you currently received is of a specific type, in this case theZB_IO_SAMPLE_RESPONSE. Once this is verified we can call the painfully namedgetZBRxIoSampleResponsefunction in order to get at the data available within.

Now that we are that far in our thought experiment lets look at how to get to the final stretch. Still in the XBee.h file, lets search for “ZBRxIoSampleResponse” (orgetZBRxIoSampleResponsewithout the “get”.) This brings us to a class that deals with this type of packet specifically.

To understand the structure of the XBee library better, it is very important that you note that this class is using another via the: public ZBRxResponse. This means that the public methods of that class are available to you when you callgetZBRxIoSampleResponse. This is chained all the way to the first class we looked at:XBeeResponse. And you can trace that back by searching backwards for “XBeeResponse.”

Now that that is out of the way, lets see packet specific functionality we have exposed to us:

  bool containsAnalog();
  bool containsDigital();
  /**
   * Returns true if the pin is enabled
   */
  bool isAnalogEnabled(uint8_t pin);
  /**
   * Returns true if the pin is enabled
   */
  bool isDigitalEnabled(uint8_t pin);
  /**
   * Returns the 10-bit analog reading of the specified pin.
   * Valid pins include ADC:xxx.
   */
  uint16_t getAnalog(uint8_t pin);
  /**
   * Returns true if the specified pin is high/on.
   * Valid pins include DIO:xxx.
   */
  bool isDigitalOn(uint8_t pin);

These are very well commented, so with that packet specifically we can quickly check:

  • Which pins are enabled /and/ set to analog or digital.
  • The data for those pins as stored in the packet.

For the use case of grabbing a sensor value on pin 1 this is all that we need to complete our code. Which brings me to the part I am sure you’ve all been waiting for.

The Code

  #include <XBee.h>

  XBee xbee = XBee();
  ZBRxIoSampleResponse ZBioSample = ZBRxIoSampleResponse();

  void setup() {
      Serial.begin(9600);
      xbee.begin(Serial);
  }

  void loop() {

    xbee.readPacket();

    if (xbee.getResponse().isAvailable()) {
      if (xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE) {

        xbee.getResponse().getZBRxIoSampleResponse(ZBioSample);

        if (ZBioSample.isAnalogEnabled(1)) {
          int data = ZBioSample.getAnalog(1);
          // now you have the pin data!
        }
      }
    }
  }

Tada, if you read the above explanation the meat of the loop there shouldn’t be surprising. With that said there are a few lines that are required by the library.

First we include it like any other Arduino library. Then we create an instance of XBee, allowing us to call it.

The next line is what might be confusing, what we are doing is creating aformfor our specific packet to fill (Just instance of theZBRxIoSampleResponsewe looked at above!). This is used to store that packet and call the functions I mentioned earlier on it.

In the setup we have a standard Serial begin and then we initialize our xbee passing the library the Serial ‘line’ we will communicate to it on. (Note that you can use software serial here as well, just begin it and pass it to an xbee)

Then we get to the stuff that actually does our work. First we want to constantly watch for a packet to come on, so we run thexbee.readPacket();function right in the main loop. Following we check if our xBee has received a packet (via the generalxbee.getResponse().isAvailable().) Once a packet is confirmed we can look back at our prior reasoning.

Check the ID of the packet, and reference it against the constant we want to look for (in our caseZB_IO_SAMPLE_RESPONSE.) Once that is also confirmed we finally know that we have an IO packet from our device!

We call the function we found earlier in order to populate theZBioSampleshell:

  xbee.getResponse().getZBRxIoSampleResponse(ZBioSample);

Now you have the latest packet data available to you viaZBioSample. With that just use any of the functions you find in theZBRxIoSampleResponseclass that we looked at earlier.

In our example we first check if pin one on the xBee is set to analog:ZBioSample.isAnalogEnabled(1)if that test passes we grab the data from the pin viaZBioSample.getAnalog(1);

Your Use Case

This is all fine and dandy if all you want to do is what I wanted to do. Which is why I spent all that time at the start showing you a couple of bits from the XBee.h file.

If you look through the defined Api ID constants again, and search for their respective classes you can quickly get your bearings and start dealing with many other types of packets that your xBee can receive. Once you know what type of data you want to grab or send, and have found the class that gets you to that the fastest take a look through the available methods. And don’t forget to check the classes that they reference for their methods as well. As an example, lets say I want to also grab the address of the xBee that sent that packet.

If you look through the methods provided by theZBRxIoSampleResponseclass you can see that it doesn’t appear to contain that method. Now lets look at the class that it is referencing:ZBRxResponse(Around line 381)

Note that it has a methodgetRemoteAddress16this can let us do just what we want, and we can still call it on theZBioSampleinstance we created earlier.

  ZBioSample.getRemoteAddress16();

This will now let us have the 16 bit address of the xBee, which we can use to give some more context to the prior sensor value.

The avid XBee.h explorer has probably also noticed thatZBRxResponseis also referencingRxDataResponse. If you can’t find what you are looking for, just try looking all the way down the rabbit hole!

I hope that this has been at least somewhat informative. I didn’t want to just throw a chunk of code out there. Lets call this ‘Teaching how to fish and giving you the first catch.’

For anyone that missed the link at the top, make sure to grab the library from the official source.

Setting up the BLE Mini from Red Bear Lab

I picked up four of these bluetooth low energy (BLE) modules with the intention of setting up three wireless sensors and a receiver. After a long struggle I managed to get some basic functionality going and would like to document that to hopefully save some time for anyone else trying them out.

Main components:

  1. BLE Mini
  2. Arduino Pro Mini 3.3v
  3. Analog Sensors

Other:

Bluetooth 4.0 compatible device. Here are some of the devices that support this:

  • Android
    • Nexus 4
    • Nexus 7
    • Samsung Note 3
  • iOS
    • iPhone 5 (all models)
    • iPhone 4S
    • iPad Air
    • iPad (3rd gen or later)
    • iPad mini (all models)
    • iPod touch (5th gen or later)

RedBearLab outlines some basic instructions on how to set the BLE mini up with iOS and Android here. With that said the instructions really need to be expanded further. Here is a breakdown of the iOS path:

Connect pins from BLE Mini “J4” to Arduino board
VIN > 5V
GND > GND
TX > Default RX (Pin 0)
RX > Default TX (Pin 1)

The Green LED at D1 should light up, otherwise please check the Troubleshooting section below.

Notes: VIN doesn’t need to be five volts, 3.3 volts will work just fine. For me, the LED did not light up on one device. I was able to fix that by uploading the latest firmware to it with the instructions a little further down.

Download our latest RedBearLab Library.

Notes: The ZIP file provided is the latest but if you want to dig through the source and be a bit more selective with the download here is the RBL GitHub page.

Although the device firmware was changed quite a few months ago a much older version appears to come with all the modules I purchased. Make sure you grab the latest from here and follow these instructions carefully 

Unzip the file and copy the “RBL_BLEMini” subfolder in BLEMini/Arduino/libraries to Arduino’s libraries folder.
For more information about Arduino’s libraries folder, please visit http://arduino.cc/en/Guide/Libraries.

Open our BleFirmata sketch: “File” > “Examples” > “RBL_BLEMini” > “BLEFirmataSketch”.

Compile and upload the program to your Arduino board.

Notes: Big note: use Arduino 1.0.5 and not the 1.5 nightlies, else BLEFirmata doesn’t compile.  Although this setup is fairly common, we will get to some problems with BLEFirmata a little bit later.

Download our BLE Arduino App from Apple’s iTunes Store.

Turn on Bluetooth on your iOS device. (*Please note that BLE Mini or any Bluetooth Low Energy device will not show in the “Devices” list as pairing to BLE device is not required)

Start our BLE Arduino App and press “Connect”.

Note: The main issue here is that you only get three board so chose from when you connect via the iOS app. This is pretty backwards and I don’t have any decent solutions. While testing the A(n) pins tend to be the same across boards, I used UNO and LEONARDO modes to test the minis. The only issue is that the UNO setting is the only one that shows the ‘analog’ option for the A(n) pins, which lets you see the analog signal live in the app. When set to ‘input’ on the LEONARDO setting no data is ever displayed on the iOS app.

Once that’s done you can puppeteer your Arduino of choice via the BLE App.

Some notes on BLEFirmata: Currently only UNO, MEGA and LEONARDO are officially supported. You can get something like the pro mini to work but you can run into issues with mismatched I/O and software serial. I wish I had a fix for this right now but I don’t even know where to begin.

RBL released a library for using one BLE Mini as a master and connecting slave devices to it. Unfortunately any version of the HCI library they provide that I try to upload to the boards ends up turning off the green status LED immediately. I am checking with support about this issue now.

Overall the impressive part of this module is the stability once it’s connected. I have been using a retina iPad to test the app, and once connected I haven’t had any kind of signal loss. Hopefully this stability can be translated into more custom projects.

Resources:

This thread provided some very good insight.

Although light on content the RBL zendesk support is worth a further examination.

A good project on instructables.com

Gesture Logging Garment

This is a project done with Laura Herrera Cisneros and Jess Peter for Kate Hartman’s wearable technology class.

Case:

Jim has a long string of interviews coming up with various companies. He has always been worried about his body language under stress, but wonders if he is overreacting. In order to verify whether he comes off as very closed off and unfriendly he decides to try out this gesture logging garment.

Jim activates it before the first interview and goes in. He is a little stressed but feels confident with his performance. When home he takes the SD card out of the garment and checks the graphs of his gestures over time. Everything seems reasonable, but he notices that he might appear to be too nervous as he scratches his collar bone a bit much as the interview progressed. By self-monitoring his body language, Jim is able to limit his nervous gestures so as to appear more confident in his following interviews.

Overview:

This garment logs a few basic gestures over any period of time. The wearer can then visualize them using a computer program. The following gestures are currently supported:

  1. Hold left and right side
  2. Grip left and right arm above the elbow
  3. Grip or scratch the collar bones on ether side of the neck.

The code:

There are two distinct areas for code, Arduino and Processing. The Arduino code can be seen in this gist. The goal was to minimize the code size and make it scalable by just adding a new set of values to the five major arrays. The following code excerpt demonstrates the basic logic in the program:

for(int i=0; i<6; i++){
    difference = data[1][i] - data[2][i];
    if (abs(difference) >= data[3][i]) {
        data[2][i] = data[1][i];
        logOut(i,currentMillis);
    } 
}

Each sensor has its own threshold that triggers its activation. If the threshold is met it goes on to write to the logger and adjust the old array value for the difference.

Processing Visualization code can be seen in this gist. And the result of the code can be seen below:

Grabbing the data is as easy as inserting the SD card into your computer and copying the log .txt file that you want to analyze. This breaks down the data in three distinct ways:

Visualization

  • The bar chart is meant to provide an easy way to see which gesture is performed most.
  • The body nodes show exactly where and how often each body part is pressed.
  • The line graph logs gestures over time allowing for a quick overview of what was done when.

Schematics:

Each sensor follows this basic schematic:

basictouchsensor

As there are six sensors this circuit is repeated six times and they all share a single power line while being attached to pins A0 – A5. The sensors were created using conductive fabric and Velostat, which varies in conductivity based on the pressure applied to it. All but the two sensors on the neck area are created with two contact points, reducing the chance for accidental presses. The two contact points act in series, and if only one is pressed the value passing through the sensor is still very low, as the second is highly non-conductive.

The data logger is a straight connection to the serial output of the FIO V.3.

Process Imagery

Final worn piece: