Updated: LM35 output - should it be stable?

Hi All

I've connected a simple circuit comprising of a single LM35, looking at the flat side facing me...

left - 5v Supply
center - A0
right - Gnd

The output I measure at A0 fluctuates massively when doing nothing at the LM35. Does this indicate a dead LM35 please?

I have checked the functionality of A0 with a potentiometer and it correctly reports 0-1024 within the Serial Monitor/Logger.

Here's the code I am using:

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(200);        // delay in between reads for stability
}

And here's the weird plot from Serial Monitor

Nobody interested in helping me here?

Too hard to see exactly what's going on, but suggest mains hum is getting in - try decoupling both the +ve supply and the analog input pin with capacitors - 10uF and 100nF to ground respectively.

Allan.

Should be steady I would think.

I do try to avoid delays when programming on an arduino.
The serial routines kick in out of the main loop for example so it's better to let them do their stuff
instead of holding them up.

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.
*/
// global declare
  unsigned long oldtime,currtime;
  int wanteddelay=200; // this assumes reading + serial write takes less than 200 ms 
  int sensorvalue;
  

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  oldtime=millis();
  oldtime = oldtime-(oldtime % wanteddelay)+wanteddelay; //nice to be rounded abs not needed.

}

// the loop routine runs over and over again forever:
void loop() 
{
 // read the input on analog pin 0:
 currtime=millis();
 if((currtime - oldtime) < wanteddelay )
 {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  oldtime=oldtime+wanteddelay; // not oldtime = currtime if you want things to run precisely.. you add unwanted drift here else
 }
}

IDK what else I can help you with tbh. Add some photographs, maybe someone will notice something. /shrug

allanhurst:
Too hard to see exactly what's going on, but suggest mains hum is getting in - try decoupling both the +ve supply and the analog input pin with capacitors - 10uF and 100nF to ground respectively.

Allan.

Hi Allan - apologies sir, not sure what you mean by this, so dare not connect any capacitors anywhere until I know where to connect them. Will do some research on how to do what you've suggested though, many thanks.

Phoenixxl:
Should be steady I would think.

I do try to avoid delays when programming on an arduino.
The serial routines kick in out of the main loop for example so it's better to let them do their stuff
instead of holding them up.

IDK what else I can help you with tbh. Add some photographs, maybe someone will notice something. /shrug

https://circuits.io/circuits/4463234-themusicman-s-lm35-circuit/edit

Many thanks for this. I tried the code, and still get this awful variation in signal on A0. I tried some other Analogue ins too, and get the same thing.

When I connect a potentiometer to the same pins and vary the resistance, the Serial Plotter reports accurately and is stable according to the position of the pot.

I have ordered a new batch of 5 LM35's :slight_smile:

If you've got factory reject's from eBay, learn that lesson - some of the stuff on eBay is counterfeit or reject,
its a risk you have to take.

MarkT:
If you've got factory reject's from eBay, learn that lesson - some of the stuff on eBay is counterfeit or reject,
its a risk you have to take.

Yep - you are right!

The LM35 I have came included in an Arduino Uno starter kit I bought off Amazon (admittedly from a Chinese reseller). I've ordered some new ones from a UK supplier now - I've had the order despatched email and will hopefully be here tomorrow. I will update the thread with the results.

Add some DS18B20 's and some DHT22 & DHT11 's to your collection while you're ordering.
You will have some fun figuring out how they work and you'll be able to compare results.
There's more precise than that but these seem to be the ones ppl buy to take their first steps when programming and you'll find lots of info on them too.

As for the Chinese seller thing.. it all depends... If you get a good one remember the name for later.
If what you buy is a 10th of the price of what you buy here buy a spare.
Also check before connecting. I had a cheapuino 2 weeks ago that had it's barrel connected in short circuit, it had a huge blob of solder on the bottom connecting all pins. I desoldered and removed the barrel connector. It can finish it's life connected to a USB port /shrug.

Phoenixxl:
Add some DS18B20 's and some DHT22 & DHT11 's to your collection while you're ordering.
You will have some fun figuring out how they work and you'll be able to compare results.
There's more precise than that but these seem to be the ones ppl buy to take their first steps when programming and you'll find lots of info on them too.

As for the Chinese seller thing.. it all depends... If you get a good one remember the name for later.
If what you buy is a 10th of the price of what you buy here buy a spare.
Also check before connecting. I had a cheapuino 2 weeks ago that had it's barrel connected in short circuit, it had a huge blob of solder on the bottom connecting all pins. I desoldered and removed the barrel connector. It can finish it's life connected to a USB port /shrug.

Many thanks for this info.

I have just ordered a nice DHT11 :slight_smile:

A stupid question.... are you quite sure it's wired correctly?

You give your pinout as L-R - but pins up or down? ....

Check carefully against the TI data sheet.

Very few new semiconductors are faulty.

Allan

Hi,
If you look at the pins connections in the TI datasheet your are looking the pins from the bottom. So you need to switch the left with the right. The middle pins it is the output pin. In the datasheet show the left it is the Vcc and the right pin it is the ground. In the picture you have the ground in the left and the voltage in the right.

If you both were referring to the circuits.io link I added at the bottom of my reply it's ok now I think.

I was mainly using the virtual arduino to test the code. Might also have reconnected it wrongly while cleaning it up before pasting the link. I originally had it wired up on the top part of the virtual breadboard with the ic hiding the wires so I turned it up side down, wasn't happy with the lettering on the IC, then moved it to the bottom part. /shrug. It showed 50 something while testing the code didn't check after cleanup.

From OP's post though I think he has it wired up correctly.

EDIT:
While fixing up the thing just now I saw you can apparently set the temperature of the virtual LM35 too.
Learn something every day :slight_smile:

Hi all

Yep, I'm pretty sure I connected it correctly. I have a 5 pack of lm35's being delivered today so am looking forward to checking them out. I'll post the results on the thread, too.

Really appreciate everyone's comments here, thank you all.

OK, so LM35DZ's arrived, and I am definitley getting much more stable readings now, however they don't seem to be representative of the temperature in my room just now. The value returned on A0 is 47/48 which is not the temp in my room in F or C!

If I hold my finger on the LM35, A0 rises quite quickly to 66 - again not a temperature reading I would expect.

So, does the LM35 need calibrating at all or is there a scale map function I should be using?

The LM35 is specced to be accurate to < 1/2 C at 0..25C , 3/4 C at -55..125.

Big inaccuracies are down to something else.

Allan

@op
Fiddle around with the circuits.io diagram I posted a link to earlier.
If you click the actual LM35 , like i noticed in my prev post, you can set the temperature while running.

0 celcius seems to read 0 on A0
100 seems to be 205 on A0

So I'm guessing they aim to be twice celsius ?

Divide what you read by 2 and pretend it's celcius , else you'll have to account for the 205 instead of 200.

Since the thing goes up to 150 you can always lather it up in epoxy (2 component glue) , let it dry then stick it in a pot of boiling demineralised water, read the value.
Same with a glass of melting ice.

If you have a few more things where you can be what temperature they are you can measure them and draw a nice curve.
A golden retriever for example has an internal temperature of about 38.5, I wouldn't though , he'll never look at you the same way again... :o

Have fun experimenting.

So, I managed to get it sorted with an Arduino software calibration to map the value received at the AnalogueIn pin to the actual temperature. A little bit of brain use and it's sorted.

Here's the code I used.

int val;
int tempPin = 2;
int alarmPIN = 13;
int alarmTemp = 80;
int sampleTime = 1000; //in ms

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

void loop()
{
val = analogRead(tempPin);
float mv = ( val/1024.0)*5000;            //milivolts = input/1024 (for % of range) then x Vsupply 
float cel = mv/10;                        //LM35 has 10mv per degreeC
float farh = (cel*9)/5 + 32;

//Serial.print("TEMPRATURE = ");
Serial.println(farh);
//Serial.print("*F");
//Serial.println();

//Code to check for temp greater or equal to alarmTemp
//if so, set internal LED to on, otherwise set internal LED to off
if ( farh >= alarmTemp )
{ 
  digitalWrite(alarmPIN, HIGH);
}
else
{ 
  digitalWrite(alarmPIN, LOW);
}
  delay(sampleTime);
}

Yes, you should always calibrate, and the code from post#0 is too basic for stable readings.
Try this. It uses 1.1volt Aref and smoothing (slowing things down).

Ignore the LCD part. My LDC shield is using A0 for buttons, so sensor output has to go to A1.
Read all the comments.
Leo..

// 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 = 25; // 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, 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
}

Phoenixxl:
...Same with a glass of melting ice.

Works for the TMP36, but not for the LM35, because the LM35 does not go down to zero C by default.
Leo..