LM35 temp sensor - Filter to stabilise output?

Hello. I'm using an LM35DZ temp sensor. For those who don't know, in the 'standard' configuration it ranges from 0oC-100oC (0mV-1000mV - 10mV/oC). Also it has an accuracy of +-0.5oC at room temp. This means by using 5V as the analog reference voltage i have 4.88mV(per adc value) resolution which is higher than the minimum needed (5mV for 0.5oC accuracy). As filtering i'm using a 47nF capacitor on between the output signal. Even with this i get fluctuations of +-2oC. I've tried using: - Higher resolution (2.5mV(per adc value) using the internal analog reference of my leonardo - aref=2.56V) - Changed int to float/double/Multiply int at calculation by factors of 10 to get higher resolution) - Averaging the values - Using a pull-up resistor - Combinations of the above

Still the same problem. In comparison, i have a cheap clock with temp reading, is 'accurate' to 0.1oC and it works really stable. If i measure the signal output with my multimeter is stable to 1mV (0.1oC). Let's say output is 277mV (27.7oC) on my multimeter it will read 277+-1mV). Which leads me to believe there is a filter on the multimeter which is better than my simple capacitor. I think using a higher capacitor will smooth it out but i don't have any at the moment.

Can someone give some advice? (i've checked lots of threads about this and couldn't find a good working solution to this)

Thanks

You should only be getting about 1LSB of toggling noise on your readings. If they are much higher, then there is noise present, perhaps from serial comms or other internal CPU features that you might have enabled such as PWM. Another thing that can make noise on the analog inputs is the digital aspect of the pin. Aparently if the Data Direction Register sets the digital mode of the pin to input, that it will be floating when the pin is connected to the ADC. This apparently generates noise on the ADC reading.

Since it doesn’t take long, I like to take a bunch of samples in sequence (oversample) and then divide with truncation (decimate) the total. I have an LM34 set up here that gives me very smooth results. It’s all on a solderless breadboard right now.

//  Temperature measuring stuff
#define TEMP_IN_F .1074  // multiply by this to convert to fahrenheit
int LM34Pin = A3;    // Analog pin 3
int x;
unsigned int temp = 0;
unsigned long temptot = 0;

  //  Sample the LM34 a bunch of times then compute a nice smooth average temperature
  temptot = 0;                     //  clear the accumulator
  //  Read the ADC 64 times and compute a total
  for(x = 0; x < 64; x++) {    
    temptot += analogRead(LM34Pin);
  }
  //  divide by 64 to decimate, could divide by 16 and keep a legitimate 12 bit result
  temp = temptot >> 6;

I've found that the LM3X temp sensors really need a 500ohm resistor to ground to get stable readings, otherwise they fluctuate. See the spec sheet; they use a 499 ohm resistor to ground.

The most likely reasons you are seeing so much fluctuation are:

  1. You have used the same ground pin to connect both the ground side of the LM35 and the ground side of an output device, or the ground side of the power supply. You should dedicate one of the ground pins on the Arduino to use only for the ground sides of analog inputs.

  2. There is noise on the +5V supply (which you are using as the analog reference), perhaps because you are powering it from USB, or because you are also powering output devices from the +5V supply. Try using the 3.3V pin as the analog reference instead.

Thanks for the replies. I have connected all 3 grounds from the leonardo to the breadboard. After messing with many capacitors and a resistor it was stabilised. After i removed them and used a single 1KOhm attached between the signal and ground and it is ultra stable. The datasheet only says about adding one to increase the range..cptdondo can you explain why this works? (and why to use 500ohm..?)

St0RM53: Hello. I'm using an LM35DZ temp sensor. For those who don't know, in the 'standard' configuration it ranges from 0oC-100oC (0mV-1000mV - 10mV/oC). Also it has an accuracy of +-0.5oC at room temp. This means by using 5V as the analog reference voltage i have 4.88mV(per adc value) resolution which is higher than the minimum needed (5mV for 0.5oC accuracy). As filtering i'm using a 47nF capacitor on between the output signal.

Can someone give some advice? (i've checked lots of threads about this and couldn't find a good working solution to this)

Thanks

Digitally filter the signal. That is, take maybe 25 or 50 or 100 consecutive analog readings, add them up, then divide by the number of samples you took (i.e. average the data). This will result in nice, clean, jitter free data.

St0RM53: I have connected all 3 grounds from the leonardo to the breadboard.

Although that's better than having just one ground pin connected, it will still give rise to interference between the output devices and the sensors. You should dedicate a ground pin to the analog sensors.

Thanks for the responses. As you can see from my last reply the problem was solved!

St0RM53: Thanks for the responses. As you can see from my last reply the problem was solved!

Just because you've got rid of the jitter, it doesn't mean that you don't have a systematic error in the temperature reading caused by voltage drop on a shared ground wire and/or power supply droop. But you haven't said what output devices you are driving, so we don't now what the ground current is.

How can i allocate a different ground? Aren't all ground pins connected to each other?

Yes all the grounds are connected - but not by superconductors, so they are not the same voltage if any currents are flowing. For digital logic a few mV of IR voltage drop is totally irrelevant, but here you are measuring a small analog voltage on the mV level so it does matter - you don't want any siginificant currents sharing your ground-return with an analog sensor, otherwise you'll add in error from the IR drop. 50mA flowing along a 0.05ohm pcb trace will generate 2.5mV error for instance, and these are entirely plausible values in a real system.

Yes i understand this. In cars we always try to ground any electronic modules to the same ground point, and on or close to the engine. But on the arduino board how can i minimise the ground noise? I can increase resolution of the adc with a lower reference voltage but i still had the same problem, so it was an interference problem?

St0RM53: Yes i understand this. In cars we always try to ground any electronic modules to the same ground point, and on or close to the engine. But on the arduino board how can i minimise the ground noise?

Think of the Arduino board itself as the common ground point to which all grounds should be connected. So ideally, every device that needs a ground connection should have its ground wire connected to a different Arduino ground pin. However, there are only 3 ground pins on a Uno, so in practice you have to share ground wires. What you mustn't do is share ground connections for input devices with anything other than more input devices.

I am very much of a beginner so it may be a bit preposterous of me to try and solve your problem.

However, it just so happens that I have (today, in fact) run into the same difficulty with an LM35 (in a TO-92 package), and my first attempt to solve the problem seems to work. It stabilises the output.

What I did was to initialise 2 values in the beginning:

int smoothedValue = 400;  //initial value - corresponds to 20°C
int smoothingFactor = 8;

and then, in the loop, do this:

void loop () 
{ //read input pin, update smoothedValue, and map to displayValue
  smoothedValue = smoothedValue + (analogRead(A0)*10 - smoothedValue)/smoothingFactor;
  int displayValue = map (smoothedValue, 0, 10230, 0, 521);

"displayValue" is then displayed. The display starts off at 20 and then gradually changes to the end value if this differs from 20 - takes a few seconds if "smoothingFactor" is set at 8.

I think it boils down to a kind of software-implemented low-pass filter. The higher the value of “smoothingFactor”, the more immune the display is to noise (and – the downside - the slower is the response).

Thanks for the replies!

Thank you bc42, your advice has been very useful for me too. Arduino UNO + LM35 + BC337 + realy: with the right use of GND pins the noise disappeard from temperature reading when realy was drove to ON). Bye

dc42: The most likely reasons you are seeing so much fluctuation are:

  1. You have used the same ground pin to connect both the ground side of the LM35 and the ground side of an output device, or the ground side of the power supply. You should dedicate one of the ground pins on the Arduino to use only for the ground sides of analog inputs.

  2. There is noise on the +5V supply (which you are using as the analog reference), perhaps because you are powering it from USB, or because you are also powering output devices from the +5V supply. Try using the 3.3V pin as the analog reference instead.

You made my day! Thanks for your help: I had horrible noise on my LM35 signal when switching a relay ON. After using a different ground pin from my Pro Mini for the analog signal then the one used for the relay the noise was gone.