Software

 

The XBee communicates with the base station in binary “packets”. They’re not sent in text format, so they’re a mess to sort out. Fortunately Amit Snyderman has written a Python module that provides XBee packet translation. Save this code as ‘xbee.py’ somewhere in your Python path and “import xbee” in your program(s).


Here’s a display of one packet:

app_id: 0x83, address_16: 1, rssi: 79, address_broadcast: False, pan_broadcast: False, total_samples: 1, digital: [[-1, -1, -1, -1, -1, -1, -1, -1, -1]], analog: [[518, 470, 427, -1, -1, -1]]


Most of that information is useless — all we really want is the first three analog values, corresponding to the accelerations in the z, y, and x directions. We can refer to just one of these values with the analog_samples packet object:

     a_x = xb.analog_samples[0][2]

The [0] refers to the sample number (there’s only one sample per packet here, so it’s 0.) The 2 refers to the third item in that particular sample number, 427 in this case. Now there’s just the question of why that value is 427 rather than something reasonable like “9.8”.


Here’s what’s happening. The XBee has a 10-bit analog-to-digital (A/D) converter. That means that the entire range of what it can measure is broken up into 210 = 1024 slices. The reference voltage (Pin 14, Vref) is 3.3V so 427 corresponds to a voltage of (427/1024)*3.3 = 1.38 V. (Note that this 10-bit resolution is a limitation on the precision of the measurement also: all measurements are good to only 1 part in 1024.) We still need to convert that voltage to an acceleration measurement, but to do that we need two “known” measurements. Gravity provides these for free! We get the average measurement of a_x with the x axis pointing up (a = 9.8), and the average of a_x with the x axis pointing down (a = -9.8), and then use the fact that the A/D converter is linear to convert the numbers directly to acceleration:

This is our first sensor, after a particularly poor choice of acceleration measurements.


The rest of the pictures and data on this site are from our second sensor...

Does that all make sense? Hopefully...


The next problem is timing. Sometimes you don’t need accurate timing — you might just want to know maximum accelerations or something. But if you DO need accurate time information, you can’t depend on the XBee’s timing. Just because you tell it to take samples every 10 ms doesn’t mean that the samples will be taken every 10 ms. They do seem to be taken at regular intervals, but the clock speed is anybody’s guess.


To get around this problem, I used the ‘time’ module in Python to record the time at which each packet arrived. This isn’t the best solution, but it seems to work to within a millisecond or so which is good enough for an introductory lab.


There’s one more problem. The FTDI driver is something of a hack, the xbee.py module is something of a hack, and Murphy’s Law never sleeps... I’ve found that when you start taking data from the XBee, there’s a good chance that one of the first few packets will be “skewed” so that the xbee.py program misreads values. Sometimes this makes the program crash so hard that the computer can’t find its USB port afterwards. I got around this by ignoring the first couple dozen packets to arrive. (Actually I drop the first 50 packets, which is overkill!) This is not aesthetically satisfying, but it works.


Finally, here’s my program that takes data from one channel for a set time and plots the results. If you want to run it on your computer, make sure Gnuplot and gnuplot.py are installed and working on your system.