7

I am trying to read a LM35 temperature sensor with Arduino UNO which I got as a gift. The issue is the fact, that my readings of sensor are, well, suspicious at least - they jump with each reading some 5 °C up or down.

I had used several posts how to wire the thing to Arduino board and for and program the reading (1, 2, 3) and produced the code posted below. The sensor reading fluctuates really a lot - it jumps by some 3 to 7 °C after each reading regardless of reading frequency (tested with reading each 0.5 s, 1.0 s or 2.5 s). (Unfortunately I do not own a multi-meter to check actual values.) To mitigate the issue I implemented an averager, but underlying problem stays. Expected values are something like 23 or 24 °C as measured by digital weather station and bimetallic thermometer respectively.

Have you met this before ? Do you have any ideas what might be source of this ? I am beginner to electronics as well as to Arduino, trying to learn and mainly understand it.

The complete code:

#include <WString.h>

//Stores read analog values 
int readLM35;
const int sensorAnalogPin = 0;
const float voltsToTemperature = 1.1 / 1023 * 100; // (1.1V supply / 10bit resolution) * (10 mV/°C = 1 V / 100 °C)
//Stores the temperature in °C
float temp;
//Averager
float temps[8];
byte position = 0;
float averageTemp;

void setup() {
    Serial.begin(9600);
    pinMode(LED_BUILTIN, OUTPUT);

    //For setting internal analog reference voltage to 1.1V
    analogReference(INTERNAL);
}

void loop() {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(50);
    digitalWrite(LED_BUILTIN, LOW);

    //Measure temperature
    readLM35 = analogRead(sensorAnalogPin);
    temp = readLM35  * voltsToTemperature;

    //Save it
    temps[position] = temp;
    if (position == 7) {
        position = 0;
    } else {
        position++;
    }

    //Get average
    averageTemp = 0;
    for (byte i = 0; i < 8; i++) {
        averageTemp += temps[i] / 8;
    }

    //Write
    Serial.println(String(readLM35) + " => " + String(temp, 1) + " deg. C, avg. " + String(averageTemp, 1));
    delay(2500);
}

Example of output (note the first numbers - actual reading):

211 => 22.7 deg. C, avg. 22.5
186 => 20.0 deg. C, avg. 21.9
234 => 25.2 deg. C, avg. 22.7
173 => 18.6 deg. C, avg. 21.9
237 => 25.5 deg. C, avg. 22.6
185 => 19.9 deg. C, avg. 21.9
231 => 24.8 deg. C, avg. 22.4
193 => 20.8 deg. C, avg. 22.2
223 => 24.0 deg. C, avg. 22.3
206 => 22.2 deg. C, avg. 22.6
197 => 21.2 deg. C, avg. 22.1
225 => 24.2 deg. C, avg. 22.8
183 => 19.7 deg. C, avg. 22.1
240 => 25.8 deg. C, avg. 22.8

Experimental setup

migrated from electronics.stackexchange.com Oct 17 '17 at 1:39

This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.

  • 3
    I don't see any decoupling capacitors (100 nF typically) at the LM35. Check the datasheet for recommendations. – Transistor Oct 13 '17 at 11:22
  • I tried to take a look at datasheet ti.com/lit/ds/symlink/lm35.pdf and Fig 13 suggests 10 nF bypass. Did you meant something like it? (N.B. I do not understand electronics very good, so please bear with me). – Rao Oct 13 '17 at 13:40
  • 1
    I give +1 for your debugging work and the care preparing this question. – user31481 Feb 14 '18 at 7:36
  • 2
    +1 more for same. Very good question. I would give another +1 for the averaging code if I could. You're on the right track. I always use .1 uF caps on my analog inputs like this. Non-electrolytic. I avoid ceramic but tantalum and mica are fine. It can be larger in value but won't help much. A little will help. But perhaps a tad more than the aluminum foil & Saran Wrap. ;-) (By the way, @analogsystemsrf, you remind me of doing something similar with newspapers on the coffee table. Feeding audio into the primary on a hi-V transformer then the secondary to the foil makes a speaker) – SDsolar May 4 '18 at 2:28
  • @SDsolar ... can you explain why you avoid ceramic (and non-electrolytic)? – Michel Keijzers Feb 13 at 15:59
0

Try :-

const int temperaturePin = A0;

void setup() {
  // put your setup code here, to run once:

        Serial.begin(9600);
    }


double getVoltage(int pin)
{

  return (analogRead(pin) * 0.004882814);

    }

void loop() {

      double degree,voltage;
      degree = analogRead(temperaturePin)*0.48875855;
      voltage = getVoltage(temperaturePin);
      Serial.print(voltage);
      Serial.print(degree);
      delay(1000);

    }
  • Thank you for idea, I will try it. But in the meantime, can you please elaborate a bit more on how you got those magic numbers 0.004882814 and 0.48875855? I suspect something like 5V / 1024 (but this differs at last digit; note 1024) and 5V / 1023 * 100 (this one is with 1023), respectively. Why different 1000s? – Rao Oct 16 '17 at 7:57
  • computers start counting at 0 instead of 1... – dandavis Oct 17 '17 at 6:03
  • I am well aware of this, but why you once count with 1023 and other time with 1024? (If my assumptions were valid.) Seems like one you once use 'last item is #1023' and other time 'we have 1024 items'. – Rao Oct 17 '17 at 9:33
0

I guess when 0 = 0 and 5V = 1023, then you should divide by 1023. Looking at the question, I notice that you use AnalogPin = 0. Myself, I would stick to AnalogPin = A0. A0 is defined as:

define PIN_A0 (14)

so it is not equivalent to 0. Are you sure you're reading the right pin? Also try another pin like A3.

  • 1
    Using 0, A0 or 14 will read from the same analog pin. – gre_gor Jun 11 '18 at 20:33
0

this is a known issue for all Arduino sensors (fluctuations and drift), I also had this problem with humidity sensor and water level sensor with LM393 comparator, what I tried to do to make the fluctuations less was trying to calculate average readings instead of single reading:

for (int i = 0; i < 100; i++) 
{
levelSensorValue = levelSensorValue + analogRead(levelSensorPin);
moistureSensorValue = moistureSensorValue + analogRead(moistureSensorPin);
}
levelSensorValue = levelSensorValue / 100;
moistureSensorValue = moistureSensorValue / 100;

generally speaking, all sensors have a linear range witch cannot be reliable beyond it, and also calibration for them is necessary.

0

Why have you done 1.1/1023. Your saying that the supply is 1.1v but your supplying it 5v. I use (readLM35/1024)*500 to get temperature value in °C and it is on par with a thermometer I have bought. If this doesn't work try with another lm35. You might just have a faulty one.

Also the LM35 is factory calibrated for voltage. So you have to calibrate it according to the Arduino you use. I would recommend the ds18b20 as it's calibrated for temperature. Using the Dallas temperature library makes it easier to use as well

I found this on the Arduino forum some time back

0

many answers, stick to the code or the LM35 itself rather than the main part, the ADC. when you are reading a [approximately] right temperature, well, then the code, vRef and pin config is right. I had problem with ADCs as I had to measure many voice signals for my thesis. here are some problems which may occur :

  • double check if the board itself, has proper AVCC/AREF decoupling caps. many clone boards doesn't pay attention to production failures. decoupling caps usually connect between ground (GND) and a positive supply line(like VCC) to filter out noise.
  • if you have access to the AVCC/AREF pin, connect 2 or 3 paralleled 100nf caps between them and ground. the values are not critical. anything in the 10nF up to 10uF range is fine. you can use different values for each cap.
  • check your input power supply noise. computer USB port is the most trusted power supply. other power supplies (wall adapters, cheap power banks etc.) have some unimaginable noise.
  • use caps (decoupling caps. the caps which are connected between + and - pins) on every single component or sensor. like LCDs, LM35 sensor... .
  • try to use the exact code and sensor on other analog pins and if you got any, another Arduino. if the problem insists, then you can check for another LM35, or the code like the others said. but if the problem didn't exist, then the board has a problem. any faulty component in supply line can cause this. from regulators to a bad joint or PCB via.
  • While I agree that a computer's USB port power is a lot cleaner than a Chinese power brick, it is not the cleanest. There are various DC-DC modules that will provide a very clean output, and if you want perfectly smooth power you can't beat a chemical battery. I never design for these but I do use them for troubleshooting. – Peter Wone Aug 21 at 22:58
0

The cause is the low sinking capabilities of LM35 output. This makes the output sensitive to EMI. Yes, the output output impedance is stated as 0.5 ohms but only for sourcing current. The sinking current is limited to 1uA which is easily achieved by the environment noise. enter image description here

You need to add a low impedance load between LM35 output and ground, can be 200 ohm as the data sheet recommends for heavy capacitive loads but I wouldn't go that far, might be 1k or 2k to avoid self heating errors.

No software only solution can solve this error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.