Despite the ease with which I got the DS18B20 one wire temperature sensor running, I would prefer to use all I2C sensors for a modular system that lets me swap the data logging platform and the sensor housings in the field. The Texas Instruments TMP102 is very low power 12 bit sensor capable of reading temperatures to a resolution of 0.0625 °C and Sparkfun sells them on a breakout board for only six bucks.
There are plenty of basic starter scripts out there that just read the temperature register, and leave the units running at the default settings. However for my long term deployments I really wanted to make use of the “one-shot” mode that this sensor supports, where the unit auto-sleeps by default until you ask it to make another reading. While this doesn’t save that much power (it brings the sensors quiescent current from 10μA down to 1μA) I figured it could also reduce the noise on the I2C lines, and the BMA180 accelerometer that shares those lines is sensitive to absolutely everything.
For those who just want a library for this sensor, there is one here and here , but I wanted a more transparent approach, because sooner or later, I will need to integrate all my individual sensor scripts into the next Cave Pearl codebuild. If I hide my functions in a library, it will be that much harder to see where duplication might be eliminated.
Because this sensor stores data in 16 bit registers (outlined here, but their code is somewhat confusing) , you have to do some juggling to reconstitute the data after reading out two register bytes. This gets a little complicated if you reach temperatures below zero because the negative numbers are represented in binary twos complement format. Fortunately that is not an issue in caves, and the twos complement stuff does not need to be done on positive numbers. You also don’t need to get into the 13bit “extended” mode of this sensor unless you are measuring temperatures beyond the normal –25°C to +85°C range.
You can download my TMP102 script HERE, This code produces the following output:
Integer data before conversion: 458
Temperature in deg C = 28.6250
Success:TMP102 has been initialized
Temperature in deg C = 28.5625
Integer data before conversion: 458
Temperature in deg C = 28.6250
Integer data before conversion: 480
Temperature in deg C = 30.0000
Integer data before conversion: 485
Temperature in deg C = 30.3125
Integer data before conversion: 489
Temperature in deg C = 30.5625
Integer data before conversion: 492
Temperature in deg C = 30.7500
….
(Note: I had my finger on the sensor here, to show the readings changing…)
The readings stabilize pretty quickly on the desktop, which is always good to see with a new sensor. Now that I have it running, I will build a special test unit with the TMP102, the DS18B20 (identical to TMP102 specs: 0.0625 °C/lsb & ± 0.5°C), and one of the MS5803 pressure sensors installed (16 bit resolution of 0.01°C but poor accuracy ± 2.5°C). That should let me assess issues like offsets, drift and noise as I select the best temperature sensor to adopt. I will have the 102 potted in JB weld on the outside of the housings, so I suspect there will be some thermal lag to deal with as well. (I wonder if I could use some kind of heat pipe there?)
Addendum 2014-06-17:
If I have issues with the TMP102, I may try to get a hold of a TMP112 which is code compatible, and has a slope specification that can be calibrated for better accuracy.
Addendum 2014-12-08:
I will post more detail on this later, but since I just ran across this problem, and I thought I should post to let other people know about it: For a long time I though my TMP102’s had a weird spiky noise problem which I tried to hammer out with sample averaging, but it was not the sensor, it was the floating point calculations on the Arduino. The two graphs on the right were derived from the raw sensor data with exactly the same equation:
It’s possible that I caused this problem by forgetting to use proper casting in the calculations.
ie: TEMP_degC =TEMP_Raw*0.0625 vs TEMP_degC =(float)TEMP_Raw*0.0625
but just in case, I am going to avoid float calculations on the Arduino. You can always save your “raw” sensor data for processing later.