Example Code for a TMP102 I2c Thermometer

I've fairly extensively commented the code, hopefully it makes sense.

Example code for talking to a TMP102 I2C thermometer, like those available from Sparkfun, for example. Rather heavily based on some code I found in the forums, some samples, and a bit of personal investigation to make it all work.

Based on my testing, the sensor overreads by around 5 degrees C at room temperature. Not too sure if it is a percentage or a constant error. I know some of the analogue sensors are prone to incorrect readings if the reference voltages are off, but as we're using a digital output, this shouldn't affect it. Any ideas? Mention them here.

For those using the Sparkfun logic converters with I2C, here are the pin connections:

  • Low voltage to the 3.3v pin of the Arduino
  • High voltage to the 5.0v pin
  • High voltage Channel 1 Txo to the SDA pin (analog 4)
  • High voltage Channel 2 Txo to the SCL pin (analog 5)
  • Low voltage Channel 1 Txi to the SDA pin of tmp102
  • Low voltage Channel 2 Txi to the SCL pin of tmp102
  • The RX pins of the logic converter are not used
  • V+ of tmp102 connected to 3.3v
  • ADD0 of tmp102 connected to ground
  • ALT of tmp102 not connected
  • All grounds connected together.

You can instead use resistors to voltage divide the signal lines, but I've not figured out how to do that yet.

  1. #include "Wire.h"
  2. #define TMP102_I2C_ADDRESS 72 /* This is the I2C address for our chip.
  3. This value is correct if you tie the ADD0 pin to ground. See the datasheet for some other values. */
  4.  
  5.  
  6. void setup() {
  7.   Wire.begin(); // start the I2C library
  8.   Serial.begin(115200); //Start serial communication at 115200 baud
  9. }
  10.  
  11.  
  12. void getTemp102(){
  13.   byte firstbyte, secondbyte; //these are the bytes we read from the TMP102 temperature registers
  14.   int val; /* an int is capable of storing two bytes, this is where we "chuck" the two bytes together. */
  15.   float convertedtemp; /* We then need to multiply our two bytes by a scaling factor, mentioned in the datasheet. */
  16.   float correctedtemp;
  17.   // The sensor overreads (?)
  18.  
  19.  
  20.   /* Reset the register pointer (by default it is ready to read temperatures)
  21. You can alter it to a writeable register and alter some of the configuration -
  22. the sensor is capable of alerting you if the temperature is above or below a specified threshold. */
  23.  
  24.   Wire.beginTransmission(TMP102_I2C_ADDRESS); //Say hi to the sensor.
  25.   Wire.send(0x00);
  26.   Wire.endTransmission();
  27.   Wire.requestFrom(TMP102_I2C_ADDRESS, 2);
  28.   Wire.endTransmission();
  29.  
  30.  
  31.   firstbyte      = (Wire.receive());
  32. /*read the TMP102 datasheet - here we read one byte from
  33.  each of the temperature registers on the TMP102*/
  34.   secondbyte     = (Wire.receive());
  35. /*The first byte contains the most significant bits, and
  36.  the second the less significant */
  37.     val = ((firstbyte) << 4);  
  38.  /* MSB */
  39.     val |= (secondbyte >> 4);    
  40. /* LSB is ORed into the second 4 bits of our byte.
  41. Bitwise maths is a bit funky, but there's a good tutorial on the playground*/
  42.     convertedtemp = val*0.0625;
  43.     correctedtemp = convertedtemp - 5;
  44.     /* See the above note on overreading */
  45.  
  46.  
  47.   Serial.print("firstbyte is ");
  48.   Serial.print("\t");
  49.   Serial.println(firstbyte, BIN);
  50.   Serial.print("secondbyte is ");
  51.   Serial.print("\t");
  52.   Serial.println(secondbyte, BIN);
  53.   Serial.print("Concatenated byte is ");
  54.   Serial.print("\t");
  55.   Serial.println(val, BIN);
  56.   Serial.print("Converted temp is ");
  57.   Serial.print("\t");
  58.   Serial.println(val*0.0625);
  59.   Serial.print("Corrected temp is ");
  60.   Serial.print("\t");
  61.   Serial.println(correctedtemp);
  62.   Serial.println();
  63. }
  64.  
  65. void loop() {
  66.   getTemp102();
  67.   delay(5000); //wait 5 seconds before printing our next set of readings.
  68. }


Comments

Hello, thanks too for this code. I noticed that it does not work for negative temperatures now it is getting colder outside ;-) To my opinion the problem is in line 37. If the highest bit is 1 also the 4 highest bit of the integer have to be set. I replaced this line with:
    val = firstbyte;
    if ((firstbyte & 0x80) > 0) {
      val |= 0x0F00;
    } 
    val <<= 4;

Share