Thursday, December 26, 2013

TI SensorTag, Bluetooth Low Energy (BLE) and Linux

I've  been interested in wireless sensing of temperature and relative humidity. All the options I found previously were at least one of the following:

  • expensive, as in >€100
  • outdated, e.g. still using IEEE 802.11b
  • large
  • power-hungry
Then, I found the TI SensorTag. Texas Instruments calls it a development kit and uses it to promote its CC2541 Bluetooth Low Energy (BLE) chip. The whole board is small enough to fit into a box of matches, yet hosts temperature, humidity, 3d accelerometers and gyros, IR temperature and probably other sensors that I forgot.


Mike Saunby kindly reported on how to access this device using linux and the BlueZ utilities. He also provides a python script to retrieve the sensor's values in a scripty fashion and convert them to values meaningful to humans.

Pretty sweet! So I ordered two. And it works. My flat was built in the beginning of the last century, and using a Digitus DN-30210 Bluetooth dongle (Broadcom 20702), the lack of concrete allows a range of about 15m, with two "walls" in between. Great!

The only trouble was that the SensorTag would advertise (and wait for incoming connections) exactly 180 seconds, then shut down. This is a real problem if you're trying to use them for long-term data capture. You'd have to keep the connection alive permanently, and if it ever drops for more than 3 minutes (server restart, bugs etc.) you're disconnected. That might be ok at home, but not in remote locations. It's just not robust.

I read a lot about BLE, central devices, peripheral devices, masters and slaves, advertising and whatnot, but I could never find out whether it's possible in principle to connect to the SensorTag when it's NOT advertising. After all, I thought advertising is just to let others know you exist and what MAC you have, but accepting connections might still be possible without it. I still don't know, but I guess not.

TI does distribute the source-code for the firmware running on the SensorTag (it's one of the sample projects in their BLE stack, which is only partly open source). To get rid of the 180-second-timeout, I'd have to recompile this sample project without the timeout and flash it onto the SensorTag.

To flash new firmware, you'd either use the Texas Instruments CC Debugger ($49, international shipping is free), or, maybe, you can use an iOS-App from TI to flash the firmware wirelessly (TI calls this OAD, over-the-air download). Because I don't have Apple hardware and am scared of flashing firmware without cables, I ordered the debugger.

TI's toolchain for building software for the CC2541 is called "IAR Embedded Workbench for 8051", currently at version 8.30 (you need a recent version to work with v1.40 of the BLE stack). This software is closed, proprietary, and hideously expensive. Like, 4-figure expensive. And they guard it well.

You can download a "free" version that is limited to a 4kb code size. Nice, but quite useless, as the SensorTag's firmware boils down to around 400kb.

The other option is evaluating a full-featured version for 30 days. My evaluation period started yesterday night at 3 am.

So, after installing IAR Embedded Workbench and unzipping TI's BLE stack, you need to open
$TI_BLE_Stack\Projects\ble\common\cc2540\ti_51ew_cc2540b.xcl
in an editor and find the line
-Z(DATA)VREG+_NR_OF_VIRTUAL_REGISTERS=08-7F
 replace it with
-Z(DATA)VREG=08-7F
Now you can open
$TI_BLE_Stack\Projects\ble\SensorTag\CC2541DB\SensorTag.eww
 in IAR. In SensorTag.c, find the line
// General discoverable mode advertises indefinitely
#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_LIMITED
 and replace it with
#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
This line makes sure that advertising doesn't stop anymore. I have no idea how long the CR2032 battery will last if you keep advertising at the default rate of 10Hz forever, so I changed the advertising interval. Find the line
// What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL          160
and replace it with
#define DEFAULT_ADVERTISING_INTERVAL          16384
which means that advertising happens every 10.24 seconds. I read somewhere in TI's forums that this is the maximum value (and while I wonder what they use those other two bits for, I haven't tried going above 2^14).

You can also change the name that shows up when scanning for devices (default "SensorTag").

Now right-click on the project and select make. It should build fine and create
$TI_BLE_Stack\Projects\ble\SensorTag\CC2541DB\CC2541DK-Sensor\Exe\SensorTag.hex
In my case, that ended up like this:
md5sum aa086082c665d82e701fe2d061f710c0  SensorTag.hex
You can then try your luck using the OAD-iOS thingy, or use TI's SmartRF Flash Programmer to flash it to the SensorTag. I wrote the firmware to the primary location and didn't change that IEEE address (I think it's the bluetooth MAC, but I'm not sure).


And it works! The green LED flashes shortly every 10.24 seconds instead of 10Hz. And it has been doing that for a full 14 hours by now. I can connect using Mike's bluez-magic, fetch some values, disconnect and it will still advertise forever.

How long the battery lasts, I don't know. As soon as it stops flashing, I'll amend this post.

Dear TI, thank you very much for this great, cheap little device. But pleeeeeaaase, having to download proprietary compilers feels like the nineties. How about something that I can use GCC or LLVM with?

Dear OpenWRT, could you please package a more recent version of bluez than 3.36? Google told me a few people have tried it before, but it seems this never made it into trunk. I'd love to have my router query two or three SensorTags and populate some mysql-table!

9 comments:

  1. So is it still working on the initial bat ?? SensorTag seams to be a very nice toy but without IAR Workbench there is not much to do with it. BlueGiga stack for cc2541 seems to be more flexible to me do You have any experience with BLE112 or BLE113 modules ?

    ReplyDelete
  2. Could you provide the .bin files for OAD iOS app flashing? Apparently those need the IAR $$ compiler as well :-/. Thanks!

    ReplyDelete
  3. if you wouldn't touch the highest two bits, you should set: #define DEFAULT_ADVERTISING_INTERVAL 16384-1

    ReplyDelete
  4. Hello, let us know the bat status and if you can share the bin file. Thanks for this little tutorial!

    ReplyDelete
  5. Please read http://e2e.ti.com/support/low_power_rf/f/538/p/311948/1097759.aspx

    If you still want the firmware, send me an email at ben adler at gmx net, no spaces between first and last name.

    I have no real battery measurements to share, because I fiddled a lot with the SensorTag due to the problems described above.

    SFCounterfeiter: D'oh. Thanks!

    ReplyDelete
  6. Thanks! Finally I can place one sensortag outside. Now lets see how the battery holds (currently polling it evvery 5 minutes). I have soldered a battery holder with two AA cells to one of my sensortags for extended operation.

    ReplyDelete
  7. Hi, did you try to create multilink connection, two or more sensor(ble device) in active connection? Is it possible?

    ReplyDelete
  8. Is your SensorTag still operating on the same battery? If so, is that six months? Thanks for the incredible posting and contribution!

    ReplyDelete
    Replies
    1. Could you please reply to this post?

      Delete