How’s the weather? TMP102 + Arduino

Thursday, January 20 th , 2011

The TMP102 is a very simple, yet accurate, ambient temperature sensor which is capable of detecting .0625ºC changes between -25 and +85°C, with an accuracy of 0.5°C. And the real kicker… It does all of this while only consuming 10µA (10 millionths of an amp). The thing is quite tiny, so SparkFun has put it on a breakout board to make things easier.

Naturally, you probably already ordered a few of these for your room-to-room sensor-network to prove to your landlord that the heat is dropping below the agreed temperature. Wait… That’s just me? You just want to know how to hook one up to your Arduino? Ok… I can help with that.

The TMP102 is an I2C device, so when we are done with it, it will actually tell you the temperature, not send an analog signal that you then need to interpret. But that also means it is a little harder (code-wise) than just using an ADC and reading an analog voltage. But, in return for the added complexity, It is also more accurate then any analog reading the Arduino is capable of. So, if you actually care what the ambient temperature is, and not just checking to see if the temperature has changed, this is your guy. I say ambient temperature because it would be a little hard to connect this to anything, and it doesn’t support a thermocouple.

For this, and all other I2C devices connected to your arduino, all you need to know is that I2C is a 2-wire serial connection, SDA (Data) and SCL (Clock) – On your Arduino (everything but the mega) SDA is on analog pin 4, and SCL is on analog pin 5. On an arduino mega, SDA is digital 20, and SCL is digital 21. Like most I2C devices, when communicating with one on an Arduino, we will be using the Wire library to do so.

The sensor has an address pin (ADD0) that is used to change the address the sensor is located at. This is useful if you need more than one of these hooked up to one Arduino, you can still call them independently even on the same bus. We are grounding this pin so that the sensor will use the address of 72 (0×48 in hex). Connecting this pin to V+ (3.3v on the arduino) would set the address to 73 (0×49 in hex), and you would just need to change that address at the top of the code ( int tmp102Address = 0×49; ).

The code for the TMP102 is the easiest I2C device I have yet run across, and accessing the value from it is just a few lines of code. To please the greatest ammount of people, we are going to output the values in both Celsius and Fahrenheit. But if you wanted to do the math, and had your reasons, you could output Réaumur or even Delisle.

Arduino 1.0 Compatible

//Arduino 1.0+ Only
//Arduino 1.0+ Only

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Simple code for the TMP102, simply prints temperature via serial
//////////////////////////////////////////////////////////////////

#include <Wire.h>
int tmp102Address = 0x48;

void setup(){
  Serial.begin(9600);
  Wire.begin();
}

void loop(){

  float celsius = getTemperature();
  Serial.print("Celsius: ");
  Serial.println(celsius);


  float fahrenheit = (1.8 * celsius) + 32;  
  Serial.print("Fahrenheit: ");
  Serial.println(fahrenheit);

  delay(200); //just here to slow down the output. You can remove this
}

float getTemperature(){
  Wire.requestFrom(tmp102Address,2); 

  byte MSB = Wire.read();
  byte LSB = Wire.read();

  //it's a 12bit int, using two's compliment for negative
  int TemperatureSum = ((MSB << 8) | LSB) >> 4; 

  float celsius = TemperatureSum*0.0625;
  return celsius;
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Conclusion

So, there you have it: Connecting the TMP102 digital thermometer to your Arduino. I hope this was helpful, and make sure to keep checking the site for more tutorials.

As always, if you have questions, comments, concerns, or know of a way to improve this article, please let us know in the discussion area.

We want you to blog with us

bildr is looking for anyone interested in writing any sort of blog post for bildr. If you think you would like to help bildr by writing something, or have an idea for a post you think should be written, please contact us at blog@bildr.org or let us know in the forum.

Turn on a light, or 10. Arduino control over serial

Tuesday, January 18 th , 2011

This is something I use all the time, so I figured I would share it with you. Controlling an Arduino over serial can be extremely simple if you let it, and extremely useful if you know how to use it. Many languages such as Processing and ActionScript 3 (with a proxy) have ways to communicate over serial, and typically you see people using this so they can display the output of an Arduino, or use firmata to send information to the arduino but end up loosing a lot of programming space and overcomplicating the arduino side. But, you can go the other way and build interfaces that are able to control the arduino without firmata and pretty easily at that.

This may sound totally obvious, and it may be, but I’m going to show you anyways. For this example I’m going to use the serial monitor built in to the Arduino software, but you can use anything that will write serial to the Arduino. And, although I’m only showing the hookup for LEDs, bildr is all about simple things that you can easily expand / change to make something really cool. So, not to leave you out in the cold, I’ll talk about next steps and how you could expand on this in a bit.

Keeping it simple

Sending a long serial string in Arduino is super simple ( Serial.print(“Hello”) ) , but reading one is a little more difficult. To simplify things, the commands we will send to the Arduino will all be single character. It may sound limiting, but you have 100 or so usable single characters (about 200 if you use special characters) so you can call that many functions over serial in like 3 lines of code. Later in the article, I will also use the single character calls as an advantage other than just saving coding time.

The core code setup for this is:

if (Serial.available()) {
	char ser = Serial.read();
	//OR
	int ser = Serial.read();
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

What this does is it checks to see if any serial is available in the arduino’s buffer, and if it is, it reads the next available byte as either a character (char) or an integer (int). If you read the serial byte as an int, the read byte will be stored as its ASCII decimal value. So “a” will be read as 97, 0 as 48, 1 as 49 and so on. If they are read as a characters (char), “a” will be read as ‘a’, and numbers will be read as characters as well. So 1 will be read as ’1′. This is not the number 1, but the character ’1′. He can not be used as a number, and must be compared as a string, not an int (1 != ’1′; ’1′ == ’1′). – NOTE: in Arduino, the use of single ‘ and double ” quotes are not interchangeable. Single quotes signify a character, while double quotes signify a string.

Naturally you would think that reading the value as a “char” would make life easier because you could just do something like this:

if (Serial.available()) {

    char ser = Serial.read();

   if(ser == 'a'){
    //do this 
   }else if(ser == '1'){
    //do that 
   }
 }
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

This is simple, and if you are going to have a long list of commands, you could just use a switch case statement instead a long list of if/else if.

But if you read the serial as INTs, you can use the read values as numbers, and use them to tell the arduino what pins to power. By simply knowing that the decimal equivalent of 0 through 9 in ASCII is 48 through 57, and knowing we want to write to pins 2 – 11… We can just subtract 46 from the ascii value, and use the difference as the pin number.

if (Serial.available()) {

  int ser = Serial.read();    //read serial as ascii integer

  if(ser >= 48 && <= 57){    //is this serial byte the ASCII equivalent of 0 through 9?
    int usePin = ser - 46;

    digitalWrite(usePin, HIGH); //make that pin output HIGH
  }

}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

With that simple code, you can send serial 0 – 9 to turn on pins 2 – 11. There is a good reason I choose pins 2-11 by the way. Pins 0 and 1 are used for serial, so you could connect another serial device to the arduino to these pins and be able to trigger the code, and pin 13 blinks 3 times on startup, and I’d rather my pins not do anything I didn’t tell them to do. (incase I had a relay or something hooked up to it)

Without further ado, here is the same thing written 2 different ways.

Both of these examples will read from the serial port looking for numbers 0-9 and control pins 2-11 respectively.

void setup(){
  Serial.begin(9600);

  //Set all the pins we need to output pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop (){
  if (Serial.available()) {

    //read serial as ascii integer
    int ser = Serial.read();
    //Print the value in the serial monitor
    Serial.println(ser);

     if(ser >= 48 && ser <= 57){    
      //The ascii equivilent of numbers 0 - 9 are 48 - 57
      // so subtracting 46 from the ascii gives us 2 - 12 (the pins we want to use)
      int usePin = ser - 46;

      triggerPin(usePin);
     }

  }

}

void triggerPin(int pin){
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

AND

void setup(){
  Serial.begin(9600);

  //Set all the pins we need to output pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop (){
  if (Serial.available()) {

    //read serial as a character
    char ser = Serial.read();

    //NOTE because the serial is read as "char" and not "int", the read value must be compared to character numbers
    //hence the quotes around the numbers in the case statement
    switch (ser) {
      case '0':
        triggerPin(2);
        break;
      case '1':
        triggerPin(3);
        break;
      case '2':
        triggerPin(4);
        break;
      case '3':
        triggerPin(5);
        break;
      case '4':
        triggerPin(6);
        break;
      case '5':
        triggerPin(7);
        break;
      case '6':
        triggerPin(8);
        break;
      case '7':
        triggerPin(9);
        break;
      case '8':
        triggerPin(10);
        break;
      case '9':
        triggerPin(11);
        break;
    } 
  }
}

void triggerPin(int pin){
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
  delay(250);
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Advantages of single characters commands

Because we are using single character commands, we can actually send a long list of commands as one string. In your serial monitor, sending “0123456789″ will actually queue up all of these, and execute them one by one. So this would turn on/off pin 2,3,4,5,6,7,8,9,10,11 in order. This can be really cool if you enter a really long pattern, or get creative and make this do something else.

Extending the idea

So now that you have some examples, let’s talk about extending this idea. LEDs are lame. Sorry, but everyone has done it. But who has controlled 10 blenders over serial? Put different amounts of water in each one and make a song with the different noises. This can be done so easily too. Just swap the LEDs for these: http://www.sparkfun.com/products/9842 – These will switch 10 amps, and can be controlled by the arduino power with no transistor or external power.

Or… Go high power 12v and control motors, or lamps, whatever. Just strap one of these to it: http://www.sparkfun.com/products/10305 – Now you can control up to 8 amps and 12v per channel. Pneumatic air valves are 12v! Make a paint ball gun that can shoot from 6 different barrels (think different colors). You could even sequence it to paint something!

In conclusion

I hope you think outside the box with this one and see how easy it can be to use serial commands on the arduino. And if you do expand on this idea, please let us know what you do with this, we would love to post it here in the blog.

Arduino + MLX90614 IR Thermometer

Saturday, January 15 th , 2011

——-

« Older Entries