TI SensorTag Temperature Readings

Now that I’m a little more familiar with the Texas Instruments SensorTag, it’s time to process more of the sensors. I went over basic gatttool usage in my previous post, I would suggest giving that a read if you haven’t already.

This time I want to grab simple temperature reading from the BLE (Bluetooth Low Energy) handle. Reading the TearDown specs I managed to find the GATT table for the Infrared and Ambient temperature sensor:

screen-shot-2016-09-10-at-10-26-33-am

Apparently, this is using the TMP007 sensor. The specifications for this component are located at http://www.ti.com/lit/ds/symlink/tmp007.pdf. Section 7.3.7 gives of a bit of detail on how to calculate temperatures:

screen-shot-2016-09-10-at-10-30-39-am

Alright, with that out of the way, let’s get into reading reading some BLE handles.

The first handle from our GATT table is to read temperature data. It provides values for both IR and Ambient temperatures, and does so using MSB (most significant byte) and LSB (least significant bit). I’ll explain this in much more detail once we’ve gather some readings.

Handle Type Description/Value (text)
0x21 Temp Data ObjectLSB:ObjectMSB:AmbientLSB:AmbientMSB

The last handle we need is to have the sensor start (and stop) reading temperature data:

Handle Type Description/Value (text)
0x24 Temp Config Write “01” to start Sensor and Measurements, “00” to put to sleep

Let’s jump into gatttool and do some exploration:

$ sudo gatttool -b A0:XX:XX:XX:XX:XX -I
[A0:XX:XX:XX:XX:XX][LE]> connect
Attempting to connect to A0:XX:XX:XX:XX:XX
Connection successful

If we try to read from the temperature data handle, and the sensor is not measuring we will receive empty sets:

[A0:XX:XX:XX:XX:XX][LE]> char-read-hnd 0x21
Characteristic value/descriptor: 00 00 00 00

However, once we enable measuring, we get that sweet, sweet data 😀

[A0:XX:XX:XX:XX:XX][LE]> char-write-cmd 0x24 01
[A0:XX:XX:XX:XX:XX][LE]> char-read-hnd 0x21
Characteristic value/descriptor: 78 09 9c 0c

I’m now going to turn off measuring, we’ve captured the data we want.

[A0:XX:XX:XX:XX:XX][LE]> char-write-cmd 0x24 00

I’m going to take the values returned for ambient temperature and demonstrate converting to Celsius in Python:

In [1]: ((0x0c * 256 + 0x9c) / 4) * 0.03125
Out[1]: 25.21875

The measurement here is close to the reading from SensorTag’s iPhone application:

screen-shot-2016-09-10-at-10-49-58-am

So how does this formula work?

Well in the above example for ambient temperature, the MSB was 0c, while the LSB was 9c. Let’s have a look at these hexadecimal numbers in Python, with their binary representations:

In [1]: 0x0c
Out[1]: 12

In [2]: bin(0x0c)
Out[2]: '0b1100'

In [3]: 0x9c
Out[3]: 156

In [4]: bin(0x9c)
Out[4]: '0b10011100'

We know a binary byte consists of 8 bits, so the below should also make sense, I’m just padding our MSB with zeros to show a full binary byte:

In [1]: int('00001100', 2)
Out[1]: 12

In [2]: int('10011100', 2)
Out[2]: 156

So here is where it gets fun. What we do is merge the full binary representations of MSB and LSB and form 16 bit value, this is what the first part of the formula does:

In [1]: int('0000110010011100', 2)
Out[1]: 3228

In [2]: (0x0c * 256 + 0x9c)
Out[2]: 3228

The next part of the formula performs the right shift by two (explained in the sensor specifications above):

In [1]: int('00001100100111', 2)
Out[1]: 807

In [2]: ((0x0c * 256 + 0x9c) / 4)
Out[2]: 807

And finally, we multiply by 0.03125, also mentioned in the sensor specifications:

In [1]: int('00001100100111', 2) * 0.03125
Out[1]: 25.21875

In [2]: ((0x0c * 256 + 0x9c) / 4) * 0.03125
Out[2]: 25.21875

Hope you enjoyed, and maybe learned something. It took me some time, and digging to fully comprehend this specification.

Leave a Reply

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