I've been playing with Circuit #7: temperature sensor, from the Sparkfun Inventor's Kit. I've noticed that it is subject to electrical noise and have seen some methods to address that. I'm also currently just averaging lots of readings to get better stability. Except for when my hand gets near it, that works OK. The issue I have is with the 10 bit ADC which operates over a 0-5V range trying to deal with output that operates under 1.0V (I would hate to be in a 50C room!). To do this I employed the P2N2222A transistor with a 330 Ohm resistor. I'm not sure I've got it right. I've also added a Pot to calibrate with a reference thermometer. To make things even more fun, I've doubled up on the sensors for comparative purposes.
Here are the relevant data sheets:
http://ee-classes.usc.edu/ee459/library/datasheets/P2N2222A-D.PDF
My code, adapted from the Circuit #7 example code from the SIK:
/*
Based on
SparkFun Inventor's Kit
Example sketch 07
TEMPERATURE SENSOR
Use the "serial monitor" window to read a temperature sensor.
The TMP36 is an easy-to-use temperature sensor that outputs
a voltage that's proportional to the ambient temperature.
You can use it for all kinds of automation tasks where you'd
like to know or control the temperature of something.
More information on the sensor is available in the datasheet:
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Temp/TMP35_36_37.pdf
Hardware connections:
Be careful when installing the temperature sensor, as it is
almost identical to the transistors! The one you want has
a triangle logo and "TMP" in very tiny letters. The
ones you DON'T want will have "222" on them.
When looking at the flat side of the temperature sensor
with the pins down, from left to right the pins are:
5V, SIGNAL, and GND.
Connect the 5V pin to 5 Volts (5V).
Connect the SIGNAL pin to ANALOG pin 0.
Connect the GND pin to ground (GND).
This sketch was written by SparkFun Electronics,
with lots of help from the Arduino community.
This code is completely free for any use.
Visit http://learn.sparkfun.com/products/2 for SIK information.
Visit http://www.arduino.cc to learn about the Arduino.
Version 2.0 6/2012 MDG
*/
/*
* Changes made to sketch to deal with a second temperature sensor and
* a pot to make sensor B agree with sensor A at some initial temperature.
* I've also added a 330 Ohm resister and PN2222A transistor to each
* temperature sensor to amplify the range for more precission output.
*/
double getTemperature(int digitalSample);
double convertCtoF(double c);
const int temperaturePinA = 0;
const int temperaturePinB = 2;
const int potPinA = 1;
const int potPinB = 3;
void setup()
{
Serial.begin(9600);
}
void loop()
{
double degreesCA, degreesFA;
double degreesCB, degreesFB;
long vA, vB, vPotA, vPotB;
const int samples = 50;
int delayTime = 1000 / samples;
unsigned long timeStamp = 0;
vPotA = vPotB = vA = vB = 0;
for (int i = 0; i < samples; i++) {
vA += analogRead(temperaturePinA);
vB += analogRead(temperaturePinB);
vPotA += analogRead(potPinA);
vPotB += analogRead(potPinB);
delay(delayTime);
}
timeStamp = millis();
vA /= samples;
vB /= samples;
vPotA /= samples;
vPotB /= samples;
/*
* vPotA is used to calibrate sensor A to a reference thermometer.
* vPotB is used to calibrate sensor B to a reference thermometer.
*
* Due to the apparent nature of these sensors, while they agree with
* each other reasonably well, they don't seem to agree with the actual
* temperaure according to my laboratory grade thermometer. In this case,
* that thermometer is an Eastman Kodak thermometer for developing film.
*
* To make adjustment easier, the range of each pot is reduced in precision.
*/
const byte bitShift = 3;
const byte subtract = 63;
vPotA >>= bitShift;
vA += vPotA - subtract;
vPotB >>= bitShift;
vB += vPotB - subtract;
degreesCA = getTemperature(vA);
degreesCB = getTemperature(vB);
degreesFA = convertCtoF(degreesCA);
degreesFB = convertCtoF(degreesCB);
Serial.print("Time: ");
Serial.print(timeStamp);
Serial.print(" A: ");
Serial.print(vA);
Serial.print(" PotA: ");
Serial.print(vPotA - subtract);
Serial.print(" C: ");
Serial.print(degreesCA);
Serial.print(" F: ");
Serial.print(degreesFA);
Serial.print(" B: ");
Serial.print(vB);
Serial.print(" PotB: ");
Serial.print(vPotB - subtract);
Serial.print(" C: ");
Serial.print(degreesCB);
Serial.print(" F: ");
Serial.println(degreesFB);
delay(200);
}
/*
* This function is based on the TMP36 data sheet pages 5 and 8.
* Remember also that the Arduino analog inputs map 0V - 5V over
* a range of 0 - 1023. I've added a 330 Ohm resistor to the base
* of a P2N222A. Without the transistor, the TMP36 only puts out
* 750mV @ 25C. This goes to 1.0V @ 50C. This means that only about
* 8 bits are used in the analog inputs. I'm actually seeing less
* than 7 bits @ 25C.
*/
double getTemperature(int digitalSample)
{
return (digitalSample * (0.0048875855L / 4.0L) - 0.5L) * 100.0L;
}
double convertCtoF(double c)
{
return c * 9.0L / 5.0L + 32.0L;
}
Some sample output:
Time: 1567150 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1568400 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1569650 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1570900 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1572150 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1573400 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1574650 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1575901 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1577151 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
Time: 1578401 A: 558 PotA: 1 C: 18.18 F: 64.73 B: 557 PotB: 7 C: 18.06 F: 64.51
My worry is that my output is more dependent on the potentiometer settings than the actual sensor output. I am also not sure about my function getTemperature(). I'm attempting to expand the range of the temperature sensor using the transistor and then hoping I still have a linear(ish) output that gets the benefit of a full ten bits of sampling.
I'll try to attach a photo of my breadboard wiring. The temperature sensors are next to the pots I use to adjust the readings to match a reference thermometer.