LM 35 Temperature sensor accuracy

G'day all,

I'm a very raw newbie who has been playing around with my shiny new Arduino Uno for 5 days or so, and have somehow got a bit of a project working :)

It simply reads data from an LM35 temperature sensor and belts it out the serial port every 30 seconds. A C# app running on my PC scans the serial port and uploads the data to a database.

Finally, it's presented in a very basic page on the web. Feel free to have a look : http://autohouse.dode.com.au:8001

This page returns the last 500 reads, but as you may notice, there are some fairly large fluctuations (some in excess of 4 degrees Celcius), which, over such a small time frame (30-60 seconds) seems unlikely to me.

The circuit is super simple - +5V and gnd to the power legs of the LM35, with the data line connected to A0 on the Arduino.

Here's a code snippet that shows the conversion (seems very elementary to me, but I read a number of posts on forums that said this was the way).

  temperatureValue = analogRead(temperatureSensorPin); 
  float degC=temperatureValue/2.00;

Do I need any other components around the LM35, is there a better way in math to achieve the conversion, or am I simply barking up the wrong tree?

Any and all thoughts are welcomed.

Cheers,

Melbfella.

How is your Arduino Uno powered ? I hope not only the USB bus. If you use the +5V reference, the value changes if the voltage changes. If you have selected 1.1V reference, it is no problem. http://arduino.cc/it/Reference/AnalogReference http://arduino.cc/playground/Main/LM35HigherResolution

You should take the average of 10 to 20 samples. There is always some ADC noise, and noise from the circuit. You could even add a delay of about 100ms between the samples. If your power supply is good, taking the average should make a smooth line !

How is your hardware ? If you have long wires to the sensor, there must be a decoupling capaciter of 100nF.

There are many other things that could cause this: a draft by opening a door; electric noise; a bad switching adapter; and so on.

I'm not sure which pages you read, but you need to read this one.

Hi Krodal,

Thanks for your prompt and informative reply.

In answer to your questions :

How is your Arduino Uno powered ? I hope not only the USB bus.

Until I read your post, it was only powered by the USB bus. It now has a 12V 1A Nokia router power supply plugged in. Is this suitable? I'm not sure how to set the ref voltage on the Arduino. The sensor is powered directly off the +5V pin on my Uno.

How is your hardware ? If you have long wires to the sensor, there must be a decoupling capaciter of 100nF.

I do have a wire attached to the sensor that's about 1 metre long. I have no electronics training, so could you please explain where I should place the 100nF cap?

I do understand that opening doors etc could create a quick temperature change, but as the graph shows, it's all over the place, and doors are not being opened that often.

Changing to the plug in power supply has not changed the big jumps, so I'm hopeful the cap suggestion (once I know where to put it) might help.

Thanks again for your time,

Melbfella.

AWOL: I'm not sure which pages you read, but you need to read this one.

Hi AWOL,

I have read the pages you put in your extremely brief post, in fact before I posted my message - was there something I missed, making my question inappropriate? I was unsure whether I have a programming or hardware issue, so it seemed to be a good place to start.

'm not sure how to set the ref voltage on the Arduino.

Here?

I have read the pages you put in your extremely brief post, in fact before I posted my message - was there something I missed

Perhaps the bit about posting ALL of your code.

AWOL:

'm not sure how to set the ref voltage on the Arduino.

Here?

I clearly stated that I am a complete noob and have no background in electronics. If this annoys you, try to remember when you started out.

A post from someone like Krodal is extremely helpful, and I am now reading those pages.

Moderator edit: tags corrected

AWOL:

'm not sure how to set the ref voltage on the Arduino.

Here?

I have read the pages you put in your extremely brief post, in fact before I posted my message - was there something I missed

Perhaps the bit about posting ALL of your code.

ok, here's ALL the code. Not sure what other parts of it are at all relevant to calculating the value, but rules is rules :

int temperatureSensorPin = 0; //temperature  sensor is connected to analog pin 0 
int temperatureValue; // variable to store the value coming from the temp sensor 

void setup(){
   Serial.begin(9600); 
   delay(700);
}

void loop()
{
  temperatureValue = analogRead(temperatureSensorPin);  
  
  float degC=temperatureValue/2.01;
    
  Serial.print(millis());
  Serial.print(":A");
  Serial.print(temperatureSensorPin);
  Serial.print(":");
  Serial.print(temperatureValue);
  Serial.print(":");
  Serial.println(degC);
  delay(30000); 
   
}

Power Supply of 12V is a good, but a bit high. Check the voltage regulator on the Arduino Board to see if it doesn't get too hot (put your finger on the component next to the power plug).

Read those two links I posted: http://arduino.cc/it/Reference/AnalogReference http://arduino.cc/playground/Main/LM35HigherResolution

The analog reference voltage is the reference voltage inside the microcontroller. All analog inputs are read with that reference voltage as the maximum.

1 meter of cable is long. You need to place 100nF over the sensor at +5V and GND.

And yes, we like the whole sketch. We also like schematic diagrams, photos and url links. But most important is that you have fun with Arduino.

You have to use the average of a number of samples. That would probably solve 80% of all problems. Can you make a function that returns the temperature ?

Where in Melbourne are you that got 30 C over the last few days? I've been freezing.

I would agree with the other guys. Take 1000 samples and send the average every 30 seconds.

[quote author=Nick Gammon link=topic=118077.msg888804#msg888804 date=1344641856] ... I would agree with the other guys. Take 1000 samples and send the average every 30 seconds. [/quote]

Now that I think of it, taking many samples during the whole period of 30 seconds would be the best. So the ideal program keeps on going to take samples (and remember how many). If it is time to send them, the average is send, and taking many samples starts over again.

I think that a sample per second will do. If I use a sensor, I start with the average of 5, and mostly that is enough.

G’day all,

Thanks so much for all your input.

After adding the average functionality to the code ( based on an example found on Arduino site in article regarding smoothing), as the web page shows (http://autohouse.dode.com.au:8001, the curve is much smoother now.

The sample size is 850 reads, which is being written to the database every 2 seconds or so. Anything larger than 850 caused the Uno to crash? ie no output to the serial monitor/port.

It’s writing way too much data, but at least it appears to be more accurate.

Thanks again all.

Here’s the current code, for those interested. As always, any suggestions/criticisms/enhancements are always welcomed :slight_smile:

int temperatureSensorPin = 0; //temperature  sensor is connected to analog pin 0 
int temperatureValue; // variable to store the value coming from the temp sensor 

const int numTemperatureReadings = 850;
 
int temperatureReadings[numTemperatureReadings];      // the readings from the analog input
int temperatureIndex = 0;                  // the index of the current reading
float temperatureTotal = 0.00;                  // the running total
float temperatureAverage = 0.00;                // the average

void setup(){
   Serial.begin(9600); 
   // initialize all the readings to 0: 
   for (int thisReading = 0; thisReading < numTemperatureReadings; thisReading++){
     temperatureReadings[thisReading] = 0;   
   }
   //Wait a bit before accessing the sensor to avoid noise
   delay(700);
}

void loop()
{

  temperatureValue = analogRead(temperatureSensorPin);  



  float degC=temperatureValue/2.01;

  // add the value to the array :  
   temperatureReadings[temperatureIndex] = degC; 
  // add the reading to the total:
   temperatureTotal = temperatureTotal + degC;
   
  // advance to the next position in the array:  
   temperatureIndex = temperatureIndex + 1;             

  

  if (temperatureIndex >= numTemperatureReadings)
  {              
    
    // calculate the average:
   temperatureAverage = temperatureTotal / numTemperatureReadings;   
    Serial.print(millis());
    Serial.print(":A");
    Serial.print(temperatureSensorPin);
    Serial.print(":");
    Serial.println(temperatureAverage);
    
     // ...wrap around to the beginning: 
    temperatureIndex = 0;
   temperatureTotal = 0;   
  }

  delay(2);
   
}

[quote author=Nick Gammon link=topic=118077.msg888804#msg888804 date=1344641856] Where in Melbourne are you that got 30 C over the last few days? I've been freezing.

I would agree with the other guys. Take 1000 samples and send the average every 30 seconds. [/quote]

hehe Nick, it's freezing here too, apart from the little office I have with an electric heater running most of the time :)

Expensive, but effective....

PS Are you able to point me to any info regarding Arduino user groups/meets in Melbourne? I'm in the SE suburbs, not far from Moorabbin... I've found a bit of stuff here and there on the web, but none of it was current....

Melbfella: The sample size is 850 reads, which is being written to the database every 2 seconds or so. Anything larger than 850 caused the Uno to crash? ie no output to the serial monitor/port.

Well you have an array of 850 x 2 bytes which is 1700 out of the 2048 of RAM your Uno has. But you don't have to save them all.

Just zero out a variable (a long, say) take your 1000 readings, then divide what you got by 1000. You don't have to keep each one.

But anyway, 850 is plenty.

Are you able to point me to any info regarding Arduino user groups/meets in Melbourne?

No idea, sorry.

Where is this sensor? Inside or outside? If outside it looks too high to me. If inside, maybe the heater is kicking in and out.

[quote author=Nick Gammon link=topic=118077.msg888922#msg888922 date=1344667310] Where is this sensor? Inside or outside? If outside it looks too high to me. If inside, maybe the heater is kicking in and out. [/quote]

it's in the office, just a few feet from me. The heater does kick in and out using it's own in built thermostat, so small fluctuations are expected once the room is up to temperature....

The 'float' in Arduino is actually a 'double'.

Something like this:

double totalTemp;
double averageTemp;
int count;

count = 0;
totalTemp = 0.0;

some while or for loop
{
  temperature =  analogRead(...) / 2.01;     // calculate temperature.
  totalTemp += temperature;
  count++;
}

averageTemp = totalTemp / count;

If you take too many samples, the accuracy will no longer increase. But up to 1000 samples is no problem.

Question: Is that electric heater with a temperature control. Since the temperature is going up and down, it might be due to the electric heater switching on and off.

The 'float' in Arduino is actually a 'double'.

No, the double in Arduino is actually a float.

Why bother with floating point at all for the sum of the readings? analogRead returns an int, so just sum those.

Krodal: The 'float' in Arduino is actually a 'double'.

Something like this:

double totalTemp;
double averageTemp;
int count;

count = 0; totalTemp = 0.0;

some while or for loop {   temperature =  analogRead(...) / 2.01;     // calculate temperature.   totalTemp += temperature;   count++; }

averageTemp = totalTemp / count;




If you take too many samples, the accuracy will no longer increase. But up to 1000 samples is no problem.

Question: Is that electric heater with a temperature control. Since the temperature is going up and down, it might be due to the electric heater switching on and off.

yep, the heater is thermostatically controlled, and the curve now matches when it turns on and off :)

I still haven't put the 100nF cap across ground and 5V on the sensor - could you tell me what voltage that cap should be?

Krodal: The 'float' in Arduino is actually a 'double'.

double is actually a float.

http://arduino.cc/en/Reference/Double

The double implementation on the Arduino is currently exactly the same as the float, with no gain in precision.