I believe I have the LM35 wired up correctly and I believe I'm calculating the analog value of the LM35 to °C correctly.
My problem is that the sensor reads the temperature 5 °C too high. My room has 22 °C but the sensor reads 27 - 28 °C.
I've been googling for hours like crazy. I have found many different ways to calculate the analog value to °C, I tried all of them and all of them result in about the same degree celsius value.
So the standard formula to calculate the temperature is:
So my question is, is it possible that my LM35 is faulty? It is a brand new LM35 that was included in the Fritzing starter kit.
The temperature is always 5 - 6 °C too high. When I touch the LM35, the temperature goes up. When I release it the temperature goes slowly down back to 27 °C again. So the sensor does seem to work... kinda.
I'm kinda frustrated that I don't get the right temperature reading from the sensor and I've been looking for a mistake on my part for hours. Now I start to believe it is the sensor that is faulty.
The 1023 in your calculation should be 1024, however that will make only a small difference. If the LM35 shares a ground connection with any output devices, resistance in that ground connection will affect the reading. To avoid this, connect the ground side of the LM35 to one of the Arduino ground pins, and use the remaining Arduino ground pins for all other ground connections.
Also you need to be aware of self-heating and heat radiation before you dismiss the values as wrong.
Any small electronic device will self-heat according to the power dissipated in it and the thermal resistance to getting rid of this heat energy. In still air this can be a noticeable effect even for 1mW or less. A temperature probe would normally have the sensor thermally bonded to a metal heatsink that both reduces self-heating and allows the sensor to be brought to the temperature of the thing to be sensed.
You can eliminate this effect by forced air flow - place in the airflow from a small computer fan and let it equilibrate - switch off the fan and see how much it warms up.
Secondly you are at about 30 to 35 degrees and you radiate far infra-red at about 500W/m^2. The room at 20C will radiate IR back to you at about 420W/m^2 - that's a net difference of around 80W/m^2 heat radiation from you to anything at 20C (8mW/cm^2). If you are leaning over the temperature sensor as you take the reading you will be warming it up - perhaps enough to raise it by a degree or two.
Again forced air-flow will reduce this heating effect and bring the sensor close to the actual air temperature of the room.
dc42:
The 1023 in your calculation should be 1024, however that will make only a small difference. If the LM35 shares a ground connection with any output devices, resistance in that ground connection will affect the reading. To avoid this, connect the ground side of the LM35 to one of the Arduino ground pins, and use the remaining Arduino ground pins for all other ground connections.
This was exactly my problem. Thank you very much for your help!
Try a sketch that uses the stable 1.1volt reference.
Like the one I wrote for the TMP35, TMP36 and LM35.
Works on serial monitor and LCD shield.
Read the comments.
Leo..
// TMP35 or TMP36 temp sensor connected to Analogue input A1, 3.3volt and ground
// or LM35 temp sensor connected to A1, 5volt and ground
// temp range ~2C to ~105C
// display on serial monitor and/or LCD
// for a TMP36 (-40C to ~55C), change line 45 to: tempC = total * Aref * 0.1 / numReadings - 50.0;
//
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // your LCD pins could be different
byte ledPin = 10; // backlight pin
const byte numReadings = 32; // number of readings for smoothing (max 64)
int readings[numReadings]; // readings from the analog input
byte index = 0; // index of the current reading
unsigned int total = 0; // running total
int inputPin = A1; // the pin that the TMP35 is connected to
float Aref = 1.0759; // change this value to the actual Aref voltage of ---YOUR--- Arduino (1.0 - 1.2), or adjust to get accurate readings
float tempC; // Celcius
float tempF; // Fahrenheit
void setup() {
//analogWrite(ledPin, 200); // optional dimming
analogReference(INTERNAL); // use the internal ~1.1volt reference | change (INTERNAL) to (INTERNAL1V1) for a Mega
Serial.begin(115200); // ---set serial monitor to this value---
lcd.begin(16, 2); // shield with 2x16 characters
lcd.print("Thermometer"); // info text
lcd.setCursor(0, 1); // second row
lcd.print("0-100 Celcius");
for (index = 0; index < numReadings; index++) { // fill the array for faster startup
readings[index] = analogRead(inputPin);
total = total + readings[index];
}
index = 0; // reset
delay(2000); // info display time
}
void loop() {
total = total - readings[index]; // subtract the last reading
readings[index] = analogRead(inputPin); // one unused reading to clear ghost charge
readings[index] = analogRead(inputPin); // read from the sensor
total = total + readings[index]; // add the reading to the total
index = index + 1; // advance to the next position in the array
if (index >= numReadings) // if we're at the end of the array
index = 0; // wrap around to the beginning
// convert value to temp
tempC = total * Aref * 0.1 / numReadings; // value to celcius conversion
tempF = tempC * 1.8 + 32; // Celcius to Fahrenheit conversion
// print to LCD
if (total == 1023 * numReadings) { // if overflow
lcd.clear();
lcd.print("---TOO HOT---");
}
else {
lcd.clear();
lcd.print(tempC, 2); // two decimal places
lcd.setCursor(6, 0); // position 6, first row
lcd.print("Celcius");
lcd.setCursor(0, 1); // second row
lcd.print(tempF, 1); // one decimal place
lcd.setCursor(6, 1); // position 6, second row
lcd.print("Fahrenheit");
}
// print to serial monitor
Serial.print("Raw average = ");
Serial.print(total / numReadings);
if (total == 1023 * numReadings) {
Serial.println(" ----too hot----");
}
else {
Serial.print(" The temperature is ");
Serial.print(tempC, 2);
Serial.print(" Celcius ");
Serial.print(tempF, 1);
Serial.println(" Fahrenheit");
}
delay(1000); // use a non-blocking delay when combined with other code
}
The 1,1 V reference is not available on all boards.
The easiest way to get some better accuracy is to wire AREF to 3,3 V (if it is a 5V Arduino and if the 3,3 V isn't heavily used). An unused 3,3V is usually precise to +- 2-3%.
68tjs:
Be careful the datasheet indicates that vref is given for 1.1V +/- 0.1V.
The 1.1volt A ref is STABLE, but not precise.
How to calibrate is in the comments of the sketch.
68tjs:
You can measure the exact value of the reference voltage:
set reference to "external reference".
with a voltmeter measure voltage on Aref: it is equal to vref: you have to get a measure between 1.0 V and 1.2 V.
Sure. Done that.
Better to finetune to the right temperature.
The reference voltage isn't the only variable.
68tjs:
Second point:
Whenever you change the configuration of the ADC:
first measurement
Change Reference
change of input pin
and so on ..
NEVER keep the first measure: IT IS WRITTEN IN THE DATASHEET !
Don't get the "first measure" part.
Is you look through the sketch, you see that the pin IS read twice.
MiFi:
The 1,1 V reference is not available on all boards.
The easiest way to get some better accuracy is to wire AREF to 3,3 V (if it is a 5V Arduino and if the 3,3 V isn't heavily used). An unused 3,3V is usually precise to +- 2-3%.
Can you make a list of the boards that don't have 1.1vot Aref.
Be carefull to wire Aref directly to an external voltage.
You could damage the Aref that way.
@Wava
I never said your program were bad, in fact I do not read it and I did not answer it.
I think it is probably perfect.
I replied to Simon 83 and I gave him advice and information on the operation of the ADC from Atmel.
I think this kind of advice is not to be included in a program because it is general knowledge, but I admit that you thought otherwise.
@Simon83
I give you advice : read the information on the microcontroller on the Arduino site is to do but always check the Atmel datasheet because the site Arduino contains errors such as famous 40 mA per pin: if you read the datasheet you will see that :
40 mA per pin are actually 20 mA per pin in permanent use.
Imax for Vcc and Vee (GND) does not exceed 200 mA --> 10 pins at 40 mA = 400 mA !
So with Arduino Information: mistrust,mistrust.