I am new to Arduino, but not new to the microcontroller world. I figured I would see what I was missing out on. I got a Ardino Uno starter kit and made a project merging 2 projects right out of the projects book which interested me. The project entails using a supplied TMP36, the Arduino UNO, and the LCD display. I copied the circuit right out of the book examples and modified code from two projects to make a digital thermometer that reads degrees F. It kind of works, but the sensor does not seem to be linear. When the probe is in ice water, I get about 34 degrees. At room temperature in my house, which is currently 72, my reading is 53.78 degrees. I am sending a picture of my rig, as well as my code. If I can figure out how. It says that new users can't upload attachments, so Im not sure how to give you my project picture.
Just maybe...
Try (5.0/9.0) +32.0
Or use a digital sensor....
Please read the "how to post" sticky.
That will show you how to post inline instead of an image.
Bad example code, written by someone who doesn't understand the Arduino A/D.
There are many good TMP36 examples on this site that use "analogReference(INTERNAL); in setup.
That are the examples where the readout only depends on temperature and not on power supply variations, which your bad example unfortunately does.
Use the search field on top of this page.
Leo..
(9/5) evaluates to 1 because 9 and 5 are integers.
You want:
float tempf = (tempc * 9) / 5 + 32;
That would have gotten you 71.204 instead of 53.78
Good catch johnwasser.
I always use tempF = tempC * 1.8 + 32.0;
Simple stable code to test your sensor, but do calibrate in ice (keep sensor/wires dry!).
Leo..
// connect TPM36 to the 'cleaner' 3.3volt supply, A0 and ground
// calibrate temp by changing the last digit(s) of "0.1039"
const byte tempPin = A0;
float calibration = 0.1039;
float tempC; // Celcius
float tempF; // Fahrenheit
void setup() {
Serial.begin(9600);
analogReference(INTERNAL); // use internal 1.1volt Aref
}
void loop() {
tempC = (analogRead(tempPin) * calibration) - 50.0;
tempF = tempC * 1.8 + 32.0; // C to F
Serial.print("Temperature is ");
Serial.print(tempC, 1); // one decimal place
Serial.print(" Celcius ");
Serial.print(tempF, 1);
Serial.println(" Fahrenheit");
delay(1000); // use a non-blocking delay when combined with other code
}
Well you were correct, there is a lot to be said about the difference between multiplying by 5/9 vs 1.8. Thanks guys. I believe that the board that my sensor resides in needs some capacitance. I get some what seem to be random surges in temperature from time to time which may be static electricity. I am also averaging 10 reads.
Is that with or without analogReference changed to INTERNAL.
As said, without that the temperature also will depend on supply variations.
And, you can't display meaningful decimal places (with Aref internal you just can have one).
Leo..
I have not tried analogReference internal "yet" because I don't fully understand the interaction of the internal 1.1 Aref, the 3.3 supply voltage, and the degrees/mv ratio that it implies with the calibration constant. I also see that it you have given me everything on a silver platter and it should work, and I appreciate that. I wanted to fully understand what I am doing before I go unsoldering and repairing a board that I made.
It just seemed logical to me that if there can be wide swings of several degrees at random and be stable for a while, and I hear that the 5v supply is unstable, it seems like the hardware can be easily improved. The board and enclosure I am using would easily be an antenna for static charges, and it may be wise to place capacitor(s) on the supply line close to the sensor anyway as good practice.
I realize that you are telling me that the uno has better hardware to use, I was wanting to try both scenarios to see if I get similar outcomes.
The TPM36 outputs 0.75volt at 25C room temp, and has a resolution of 10mV/degreeC.
If you measure that with the 1.1volt reference, then you get a higher resolution than with the default 5volt Aref (1024 values spread over 1.1volt or 1024 steps spread over 5volt).
If you calculate that to temperature steps, then you get about two steps per degreeC with 5volt Aref and about 10 steps per degreeC with 1.1volt Aref.
Which makes 1.1voltAref the only option to display one decimal place.
With an absolute/voltage sensor, like the TMP36, temperature also depends on Aref voltage.
Default Aref is potentially not very stable, 1.1voltAref is.
*Note that a stable Aref is not good for ratiometric sensors, like potentiometers.
While the 1.1volt Aref is stable, it is not factory trimmed.
It can be anything between 1volt and 1.2volt.
0.1039 is pre-calculated from the actual 1.1volt reference voltage * 100 / 1024.
In my case (Uno) it was 1.064volt, 100 is 10mV(sensor) to volt, 1024 is the resolution of the Uno's 10-bit A/D.
The TMP36 can be powered from 5volt or 3.3volt.
The 3.3volt supply of an Uno is unused, so 'cleaner' (noise).
Leo..
Thank you for your help
Eric
I have implemented all recommended changes, and I would say it is a success. I noticed something that causes a noticeable instability. I am using an Uno version 3, and I am powering it using a 9v battery plugged into the power input jack. While the thermometer is running, it is stable within .2 degrees “sometimes “, other times better. If I touch the Empty USB jack on the UNO with my finger, the temperature may rise up to one degree, and return when you let go. I assume this is from static on my fingers interacting with the grounding system on the UNO and changing the relationship between Aref to ground. The plastic box I built my project in probably has similar or larger charges in it. Is there a way to counter this?
Sounds like a build problem.
Are the wires to the sensor short and twisted together?
Long wiring could pick up hum from your finger.
A 100n decoupling cap across sensor supply (near/on the sensor) might help. And/or a low value resistor in series with the output and a 100n cap from A0 to ground (near the Arduino).
Solutions like this are also mentioned in the TMP36 datasheet.
Maybe you should ditch this analogue sensor after this learning experiment, and replace it with a digital one, like the DS18B20. Beware of fake ones though.
Leo..
Sounds like a good idea. I want to post a picture of the hardware, coming shortly.
@eweisbard
What's in the black battery box (2 X 18650) ?
Just a Duracell 9v battery. Cute holder bought from Amazon. Poorly made, but pretty handy.
I hope this is only for short tests,
otherwise put another box of Duracell batteries next to it, and change the battery every 6 hours.
9volt batteries belong in smoke alarms.
A cellphone charger connected to the USB socket would make more sense.
Leo..