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:
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:
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.
The last handle we need is to have the sensor start (and stop) reading temperature data:
|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 : ((0x0c * 256 + 0x9c) / 4) * 0.03125 Out: 25.21875
The measurement here is close to the reading from SensorTag’s iPhone application:
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 : 0x0c Out: 12 In : bin(0x0c) Out: '0b1100' In : 0x9c Out: 156 In : bin(0x9c) Out: '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 : int('00001100', 2) Out: 12 In : int('10011100', 2) Out: 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 : int('0000110010011100', 2) Out: 3228 In : (0x0c * 256 + 0x9c) Out: 3228
The next part of the formula performs the right shift by two (explained in the sensor specifications above):
In : int('00001100100111', 2) Out: 807 In : ((0x0c * 256 + 0x9c) / 4) Out: 807
And finally, we multiply by 0.03125, also mentioned in the sensor specifications:
In : int('00001100100111', 2) * 0.03125 Out: 25.21875 In : ((0x0c * 256 + 0x9c) / 4) * 0.03125 Out: 25.21875
Hope you enjoyed, and maybe learned something. It took me some time, and digging to fully comprehend this specification.