May 06

Arduino and TMP100

As you can see from my previous articles, I’m a big fan of I2C. There are many components and full devices that can connect through I2C, today we’ll be looking at the TMP100. This is one in a family of digital I2C temperature sensors from Texas Instruments; they all function in a similar way but have slightly different features. Sensing temperature is a useful function to incorporate in your projects. Whether you are creating a thermostat, monitoring computer temperatures or building a beer brewing system, you need to know the temperature (and sometimes it helps to know the temperature from several different spots).

The TMP100 has 2 features that made me choose it over the other versions:
1) It supports input voltages of 2.7v to 5.5; as opposed to the 102 which needs to be between 1.4v and 3.6v
2) It has 2 address pins which allows for up to 8 of these sensors on a single I2C bus

One Tiny Chip

The TMP100 comes in the very tiny SOT23 package. This is a surface mount device (SMD), because of its size you’ll need a breakout board to work with it on a breadboard. This brings up the issue of soldering SMD components. Sparkfun offers both the breakout board and some great tutorials on soldering SMDs. I ended up soldering it with a 3rd hand, magnifying glass, tweezers and patience.

TMP100 Soldered on Breakout Board

TMP100 Addresses

The I2C address of the TMP100/101 is determined by the ADD0 and ADD1 pins.

ADD1ADD0I2C ADDRESS
001001000
0Float1001001
011001010
101001100
1Float1001101
111001110
Float01001011
Float11001111

This means you can include up to 8 of these chips into a project.

TMP100 Accuracy

The accuracy or resolution with which the TMP100 reads the current temperature is able to be configured by the user. By default it reads the temperate in 0.5 degrees Celsius increments but can be as accurate at 0.0625 degrees Celsius. This feature is set by writing the desired value to the configuration bit. This accuracy comes at a price which is the speed it can calculate the temperature. More accuracy means slower chip. See the table below for the exact trade off.

BitsResolutionConversion Time
9Bits(0.5°C)40ms
10Bits(0.25°C)80ms
11Bits(0.125°C)160ms
12Bits(0.0625°C)320ms

Wiring

In this example I’ve connected the chip to an Arduino and grounded ADD0 to set the address to “1001011”

TMP100 to Arduino Wiring

Sample Sketch

This code has 2 configurable settings at the top, the TMP100 address (as defined in the table above) and the temperature resolution.

// Display TMP100 readout to serial
// Fork Robotics 2012
//

// Set the TMP Address and Resolution here
int tmpAddress = B1001011;
int ResolutionBits = 10;

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  SetResolution();
}

void loop(){
  getTemperature();
  delay(200);
}

float getTemperature(){
  Wire.requestFrom(tmpAddress,2);
  byte MSB = Wire.read();
  byte LSB = Wire.read();

  int TemperatureSum = ((MSB << 8) | LSB) >> 4;

  float celsius = TemperatureSum*0.0625;
  float fahrenheit = (1.8 * celsius) + 32;

  Serial.print("Celsius: ");
  Serial.println(celsius);
  Serial.print("Fahrenheit: ");
  Serial.println(fahrenheit);
}

void SetResolution(){
  if (ResolutionBits < 9 || ResolutionBits > 12) exit;
  Wire.beginTransmission(tmpAddress);
  Wire.write(B00000001); //addresses the configuration register
  Wire.write((ResolutionBits-9) << 5); //writes the resolution bits
  Wire.endTransmission();

  Wire.beginTransmission(tmpAddress); //resets to reading the temperature
  Wire.write((byte)0x00);
  Wire.endTransmission();
}

I have to give credit to the guys at bildr for the getTemperature function. They have an article about the TMP102 which is very similar. See their write up here: http://bildr.org/2011/01/tmp102-arduino/

Summary

The TMP101 is a simple, easy to implement component that can be integrated into many projects. In addition to this direct, continuous way of reading temperatures it’s also possible to do more with this chip. It has a shutdown mode that can save power and allow you to get a single temperature on demand instead of the chip reading it constantly; a great feature for a battery powered device. If you don’t need as many devices in your project you can check out the TMP101 and TMP102 which can function in Thermostat mode where the Alert Pin will go high when a certain temperature threshold is passed.

Apr 26

Basic Arduino Robot

The Arduino is a great way to get started in the world of DIY electronics and robotics. This project pulls together a few key items to interface with an Arduino. This robot is controlled through the joystick of a Wii Nunchuck (although you could just as easily use the accelerometer) and has a 2 wheel drivetrain similar to the design used by iRobot’s Roomba. Here are all the supplies needed for this project:

Supplies

  • 1 Arduino
  • 1 breadboard
  • 2 full rotation servos
  • 2 servo wheels
  • Breakaway headers
  • 1 Ball Caster
  • 1 Wii Nunchuck
  • 1 WiiChuck adapter
  • 1 9v battery with connector (or other battery pack)
  • 4 AA batteries and holder
  • Blank CD
  • 2 sided tape

Construction

The blank CD provides a frame for the robot. The servos are attached to the top with 2 sided foam tape and a ball caster is taped to the bottom of the CD in the front. This is called a two wheel drivetrain and is controlled by the speed each wheel rotates at. If both wheels spin at the same speed the robot goes forward, if one spins faster than the other then the robot goes in the direction of the slower wheel.

Wiring the robot is the next step. An easy way to keep this organized and allow for future expansion is to setup the wiring on a small breadboard. Servo’s typically come with a 3pin female connector; to be able to plug these into the breadboard you need breakaway headers. The Wiichuck is plugged directly into the analog pins of the Arduino.

This robot requires different power sources for the Arduino and for the servos. Servos draw a high current so if only one battery pack is used the Arduino would lose power when the wheels started to spin. One thing to remember when using multiple power sources is to tie them all to a common ground.

Here is a diagram of the setup:

Once everything is connected, all you need to do is stack the components onto the platform and connect the power. You can also wrap a rubber band around the breadboard, Arduino and battery pack to prevent it from slipping

Sketch

Here is the code to make the whole thing run:

// Simple Robot controlled with Wii Remote
// ForkRobotics
//

#include <Servo.h>
#include <Wire.h>
#include "nunchuck_funcs.h"

//Create Servo Object for Left Wheel
Servo RightWheel;
Servo LeftWheel;

int loop_cnt=0;
int speed,direction,LeftRotate,RightRotate;

void setup()
{
  RightWheel.attach(5);  // attaches the Right Wheel to pin 5
  LeftWheel.attach(6);  // attaches the Left Wheel to pin 6

  // initilization for the Wiichuck
  nunchuck_setpowerpins();
  nunchuck_init();
}

void loop()
{
  if( loop_cnt > 100 ) { // every 100 msecs get new data
    loop_cnt = 0;

    nunchuck_get_data();
    speed  = nunchuck_joyy(); // reads joystick y axis (range of 38-232)
    direction  = nunchuck_joyx(); // reads joystick x axis (range of 25-223)

    // Converts the joystick input to the servo output range
    speed = map(speed, 38, 232,0,180);
    direction = map(direction, 25, 223,-90,90);

    // The joystick floats a little, this reduces jitters when it's near center
    if (speed >= 87 && speed <= 93) speed = 90;
    if (direction >= 87 && direction <= 93) direction = 90;

    // Translates the joystick reading to the rotation speed for each wheel
    RightRotate=speed-direction;
    LeftRotate=(180-speed)-direction;

    // Writes the rotation speed to the servos
    RightWheel.write(RightRotate);
    LeftWheel.write(LeftRotate);
  }
  loop_cnt++;
  delay(1);
}

If you try to upload or verify this code directly you will get this error:

Before you can compile and upload the code you need to put a copy of the nunchuck_funcs.h file from the WiiChuck Project http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available in the same folder as the sketch. Follow these steps:

  1. Save the sketch
  2. Close Arduino IDE
  3. Copy the nunchuck_funcs.h file into the sketch folder
  4. Reopen the sketch
  5. Upload

The result

The result is a basic robot that has direct control through the Wii remote.

I consider this a starting point for more complex projects. Adding bumpers or distance sensors would allow for the robot to do obstacle avoidance or a camera pointed through the hole of the CD could allow line tracing.

Apr 16

Run Arduino Code on an ATtiny

I’ve been in this situation many times: I just finished an Arduino project, I’m happy with it and would love to save it, but I only have 2 Arduino boards.  Do I sacrifice one to keep this project intact or pull everything off the breadboard and move on? For all the Arduino enthusiasts that can relate to this, thankfully that’s not the only 2 choices.

In my last post I mentioned the Arduino-Tiny project that allows you to use ATtiny chips as an alternative to a full Arduino in projects. For smaller projects that only need a couple pins, this is a great solution. It’s pretty simple to do and in most cases you probably have everything you need to do it. To upload the Arduino code to an ATtiny you can use a dedicated hardware programmer or you can use an Arduino as an in-system programmer (ISP). Here is how the whole process works:

Components you’ll need:

  • ATtiny chip (in this example I’m using an ATtiny85 but many others are supported)
  • Arduino (Uno or Duemilanove)
  • Breadboard
  • Jumper wires
  • 10 uF Capacitor (only if using an Arduino Uno)
  • 1 LED with resistor
  • 3 LEDs of different colors with resistor (Optional)

Step 1

UPDATE 5/28/2012: There was a bug in version 1.0 of the Arduino software that broke the ArduinoISP sketch. This bug has been fixed in version 1.0.1 of the Arduino software. Please upgrade before performing this step.

First we need to upload the ArduinoISP sketch so we can use the Arduino to program the ATtiny.

  1. Open up the Arduino software
  2. click File>Examples>ArduinoISP
  3. upload the sketch.

Step 2

Next we have to setup the wiring to allow the Arduino to program the ATtiny.

Here is how the connections need to be made:

ArduinoISP Wiring Diagram

As stated above the LEDs are optional but can help if you run into issues. Here is what they mean:

Pin 9: Heartbeat – shows the programmer is running

Pin 8: Error – Lights up if something goes wrong

Pin 7: Programming – In communication with the slave

You are going to need to setup this wiring every time you want to upload code to an ATtiny chip so I would recommend setting up a breadboard dedicated for this purpose. I had a proto-shield lying around so I decided to use that. Here is a picture of my setup:

ArdunioISP wiring on Protoboard

Step 3

This guide assumes you have Arduino IDE version 1.0, to install support for programming ATtiny chips you need to:

  1. Download the latest Arduino Tiny code: http://code.google.com/p/arduino-tiny/downloads/list
  2. Create a “hardware” folder inside the Arduino Sketch folder
  3. Extract the zip file to the hardware folder you just created.
  4. Open Arduino and check the Tools>Board submenu. You should have ATtiny chips as optionsATtiny Chips in Arduino Boards Menu

Step 4

Now you are ready to upload a test program to your ATtiny:

Here is the pinout for the ATtiny85:ATtiny85 Pinout

For a more complete reference for the pinouts of various ATtiny chips refer to: http://www.akafugu.jp/posts/resources/reference-sheet/

A good test here is to upload the Blink sketch.

  1. First hook up an LED to the D4 pin on the ATtiny
  2. Open File>Examples>Basics>Blink
  3. Change the sketch from using pin 13 to use pin 4
  4. Go to Tools>Board and select the ATtiny chip you are programming
  5. Go to Tools>Programmer and select “Arduino as ISP”
  6. Then click the Upload button
  7. Your LED should start blinking now

This is just a basic example but as you can see you have 6 usable pins on this little chip. If you want to expand the functionality of this there is also an I2C library that works on ATtiny chips and acts as a sender or receiver.

Mar 03

Recognizing Over-Engineering

I’ve been working on a small pet project to control my garage doors through my Arduino. This is my first step in a home automation project which will eventually be web based. Because this is going to be a distributed system to control things throughout the house I decided to use i2c as the platform. The chip I decided on for the remote locations was a PCF8574A. It’s called an I/O extender because it gives you 8 digital pins that can be used for input or output and since it hooks into I2C it only takes up the 2 analog pins on the Arduino. I was pretty excited about this and my mind filled with possibilities… then I got the chip.

I ran into several problems using the chip for this project:

1. It is only capable of sourcing .3 mA per pin which isn’t really enough to even power an LED. It can however sink up to 25ma per pin. This means designing the whole circuit in reverse as this forum post pointed out: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1173047782/5

2. If you want to use any of the pins as inputs they need to be set to on (HIGH), if they are off(low) then they will not read anything.

3. This chip is not only made by TI, the same chip is also made by NXP (Philips). One thing to note about the TI chip as opposed to the NXP version is that the TI lacks pull up resistors on each of the pins. Depending on how you use the chip this may cause issues. For me, this resulted in days of inconsistent behavior until I found this post: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233786313/2

4. To properly control each individual pins on the PCF8574A I ended up spending hours coding a serial based menu with the bitwise math to back it up.

5. The relays I purchased for this project may require too much current to switch because I could only switch 1 relay at a time.

6. Other people didn’t need transistors to switch relays with this chip but I decided to try it anyway and still no luck.

At this point I looked down at the circuit I had built and it hit me that I had wandered into the all too common mistake of over engineering a solution. In this case I was trying to shoehorn this chip into my project regardless that several of these factors above should have tipped me off that this was not the right chip for the job.

So I went back to the drawing board and started looking for other I2C options. I found the Arduino-Tiny project that provides everything you need to run a modified version of the Arduino platform on ATtiny family of chips. And they have a library to make it addressable over I2C! Not only does this fit the need of switching the 2 relays but also opens up a lot of options for imbedding ATtiny chips in projects instead of a whole Arduino!