Capturing Temperature and Humidity Data from a Silicon Labs Sensor Puck on a BeagleBone Black.

Full Disclosure: Silicon Labs is a benefactor of a current project I am working on, and I was provided with a Sensor Puck for collecting ambient data.

The Silicon Labs Sensor Puck is certainly a neat little piece of kit. It can take readings on Temperature, Humidity, Light Intensity, and UV Radiation all on a board not much bigger than an Arduino Mini, and that’s not counting the Heart Rate Monitor mode, and sends all this data out through Bluetooth 4.0 Low Energy Advertising Packets.

Unfortunately, either I’m bad at finding the documenation, or it simply doesn’t exist at the moment. For those of us with not a whole lot of experience in BTLE, reading the device from anything that isn’t their official mobile app was certainly an exercise. This post will aim to make that process just a bit simpler, or put you on the right track.

For this example you will need:

  • A single board computer running a Debian derivative Linux operating system. For this example, I’m using a BeagleBone Black RevC.
  • A Bluetooth 4.0-capable USB module.

I am assuming you have a working Bluetooth daemon service running on your board, if you do not, then you can find instructions on setting up BlueZ on your single board computer here.

Once you have a running Bluetooth service, you can turn on your Sensor Puck and start sniffing for its advertising packets.

[shell]# hcitool lescan –duplicates &[/shell]

This will have your BeagleBone pulling down all the packets of nearby BTLE devices, but not exactly putting them anywhere.

To read the raw data, we will use hcidump.

[shell]# hcidump –raw[/shell]

You should see data flying in that look something like this.

[raw]> 04 3E 1F 02 01 03 00 XX XX XX XX XX 13 02 01 06 0F FF 35
12 00 11 84 29 1C 02 01 01 05 00 00 1E BF
> 04 3E 1F 02 01 03 00 XX XX XX XX XX 13 02 01 06 0F FF 35
12 00 11 84 29 1C 02 01 01 05 00 00 1E BC
> 04 3E 1F 02 01 03 00 XX XX XX XX XX 13 02 01 06 0F FF 35
12 00 11 84 29 1C 02 01 01 05 00 00 1E C2 [/raw]

Don’t worry so much about the XX‘s, they are broadcasting the device’s MAC address, so I’ve censored them.

This raw hexadecimal data may look scary, but your temperature and humidity are in there, in fact, they’re these four bytes:
[raw]> 04 3E 1F 02 01 03 00 XX XX XX XX XX 13 02 01 06 0F FF 35
12 00 11 84 29 1C 02 01 01 05 00 00 1E C2 [/raw]

The humidity is stored in the bold bytes, and temperature stored in the italics, but there’s something a little odd, the bytes are backwards! To explain better, the current humidity is 0x021C, and temperature is 0x0101. They also are encoded such that the temperature is in tenths of degrees Celcius, and humidity is in tenths of percent, so you must take that into account as well.

So this means that the humidity is 0x021C = 540, divide by ten, and we get 54.0%.

Likewise, temperature is  0x0101 = 257, divide by ten here, and we get 25.7 °C.

So, now that we know where the data is, I’ve written a quick Python script as an example to filter out other devices, as well as decode and print the temperature to a terminal.

[python]import subprocess

proc = subprocess.Popen([‘hcidump –raw’], stdout=subprocess.PIPE, shell=True)
while True:
line = proc.stdout.readline()
if “84 29” in line and “>” not in line:
humidity = (int(line.split()[6], 16) << 8) + int(line.split()[5], 16)
humidity = float(humidity)/10
print “Humidity: %f” %humidity
temp = (int(line.split()[8], 16) << 8) + int(line.split()[7], 16)
temp = float(temp)/10
print “Temperature: %f” %temp[/python]

Running this, you should start to see data like this output on the terminal:
[raw]Humidity:56.000000
Temperature:26.200000
Humidity: 56.000000
Temperature: 26.200000
Humidity: 56.000000
Temperature: 26.200000
Humidity: 56.000000
Temperature: 26.200000
[/raw]

Hopefully this quick-and-dirty example should help you out in collecting data off of the Silicon Labs Sensor Puck in your projects! Keep in mind that when the device is in Heart Rate Reading mode this data will be completely invalid, but it’s only meant to be the first example, sooner or later I should get around to having more robust data and scripts, but this should set you on your way.

Credit and thanks goes out to the #beagle IRC channel on Freenode for helping out with other resources on BTLE.

This entry was posted in Uncategorized. Bookmark the permalink.

5 Responses to Capturing Temperature and Humidity Data from a Silicon Labs Sensor Puck on a BeagleBone Black.

  1. Luke Beno says:

    Great blog post! Have you considered pushing this data to a service like data.sparkfun.com. Then you can plot the data over time using analog.io.

    • Amp says:

      Hey Luke,
      Actually you and I have talked already via email, you may not remember who I am. Now that I think of it, I think I’ll bring this up with my project manager to see if we might integrate analog.io into our project in some way.

  2. Tobster says:

    Great tutorial.
    I am using your code but I do get weird results when the temperature drops below 0°C (result ist something around 655C). Do you have the same problem and a solution?

    • Amp says:

      Ah, I hadn’t thought about that.

      I’ve got what I think is a good idea of what the problem is, though it will take some thought as to how to go about fixing it. As I no longer have a Puck on hand for testing, since the project I was working on has been seen to completion.

      At its core, I believe what’s going on is due to how Python handles numbers and the amount of memory they take up when converting ASCII to them. Look up “Two’s Complement” for supplemental material on what I think the core problem is.

  3. Robin says:

    Thanks for the article!

    Format for Rev 2.1:

    ENVIRONMENTAL = 0
    BIOMETRIC = 1

    / 0 / 0x02, / AD Length /
    / 1 / 0x01, / AD Type = Flags /
    / 2 / 0x06, / Flags = LE General Discoverable Mode, BR/EDR Not Supported /

    / 3 / ENV_DATA_SIZE – 4, / AD Length /
    / 4 / 0xFF, / AD Type = Manufacturer Specific Data /
    / 5 / 0x35, / Company ID LSB /
    / 6 / 0x12, / Company ID MSB /

    / 7 / ENVIRONMENTAL_MODE, / Measurement Mode /
    / 8 / 0x00, / Sequence /
    / 9 / 0x00, / Address LSB /
    / 10 / 0x00, / Address MSB /
    / 11 / 0x00, / Humidity LSB /
    / 12 / 0x00, / Humidity MSB /
    / 13 / 0x00, / Temperature LSB /
    / 14 / 0x00, / Temperature MSB /
    / 15 / 0x00, / Ambient Light LSB /
    / 16 / 0x00, / Ambient Light MSB /
    / 17 / 0x00, / UV Light Index /
    / 18 / 0x00, / Battery Voltage /

Leave a Reply

Your email address will not be published. Required fields are marked *