temperature reading not stable: please help!

Hy,
i'm not an expert and i ask your help to understand where i'm wrong.
that's the code i wrote, reading a humidity sensor and a temp sensor (lm35).

const int inPin0 = 0; // analog pin
const int inPin1 = 1; // analog pin
void setup()
{
Serial.begin(9600);
}
void loop()
{
int value0 = analogRead(inPin0);
float millivolts = (value0 / 1024.0) * 5000;
float celsius = millivolts / 10; // sensor output is 10mV per degree Celsius
Serial.print(celsius);
Serial.print(" degrees Celsius, ");
int value1 = analogRead(inPin1);
float millivolts1 = (value1 / 1024.0) * 2310; // conversion to %hr
float rh = millivolts1 / 30; // sensor output is 30mV per °RH%
Serial.print(rh); Serial.println("rh");
delay(1000); // wait for one second
}

While the humidity signal is stable, the temp signal jump without logic. Just the first value is correct, then the others go to from 10 to 40°C.
Many thanks in advance for everybody can help me.
Regards.
Andrea.

Firstly learn to use the // code tags for inline code snippets - the # button when composing.

Need to see the circuit - in particular exactly how the power and LM35 are wired up - a photo is good. Often such issues are down to not understanding grounding.

I got the same thing until I stopped powering the system from the USB port and provided a stable external power supply that was rock solid on 5V. The sensor is very sensitive to voltage variations as you are calculating assuming you have exactly 5 volts powering the sensor. if you have 4.5 V you can be wildly out in the temperature reading.

The humidity sensor is just based on a proprtion of full scale and is therefore much more tolerant of supply voltage.

Many many thanks for your answers. For markT i'll post a picture this evening and thanksin adavance when you'll have a look! For Marco_c i'm running with usb power. This evening I'll connect the board with an external switching power supply.
But my doubt is that there's something wrong in the sketch. I'm starting now to program and probably i did a mistake. Please guys try again to get a look at it and tell me if it's correct.
thanks again for your help.
Andrea.

Meanwhile have a look at blink without delay, so you can have your sketch do other things in that second you're wasting now (just a suggestion for future development) :slight_smile:

Code look ok to me. For future postings, use the #button to post your code as it is more readable in a separate scrollable window.

Here's something else to try. This code uses the 1.1V reference in the Arduino to calibrate what the actual value of the nominal 5V supply is. If you want to use the USB power supply, call readVcc and use the value returned instaed of the 5000 as the divisor in the temperature calculation.

int readVcc()
// Calculate current Vcc in mV from the 1.1V reference voltage
{
  long result;

  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  
  return(result);
}

void setup() {
  Serial.begin(57600);
}

void loop() {
  Serial.println( readVcc(), DEC );
  delay(1000);
}
  float millivolts = (value0 / 1024.0) * 5000;
  float celsius = millivolts / 10;  // sensor output is 10mV per degree Celsius
  ...
  float millivolts1 = (value1 / 1024.0) * 2310; // conversion to %hr
  float rh = millivolts1 / 30;  // sensor output is 30mV per °RH%

If I were you, I would think seriously if I need floating point math here.

Hy,
many many thanks evreybody gave a suggestion to solve the problem. I,ve tried to take out the float but no way, i tried to take out the delay but no way. For Marco_c thanks for your code, i tried but again nothing. As i wrote if temp runs alone is perfect, with the rh sensor start to jump. Strange is that the first reading is perfectly correct, then from the second data wrong numbers. Some time the correct value appear. I definitely think (and hope) an external power is needed.
Thanks again.
Andrea

How long are the leads between the sensor and the Arduino? And is the signal lead screened?

You need to "intify" the formulas for the millivolts so they do no premature rounding.

  long millivolts = (5000 * value0) / 1024;  // turning the math around prevents premature rounding
  int celsius = millivolts / 10;  // sensor output is 10mV per degree Celsius

  // or in one step
  int celsius = (500 * value0) / 1024;

rH should be a piece of cake now..

i read here before that it might b a good idea to throw away the first reading after an ADMUX change...
the datasheet doesnt say it, but maybe it helps?

what if u do it like this:

void loop()
{
  analogRead(inPin0);
  int value0 = analogRead(inPin0);
  float millivolts = (value0 / 1024.0) * 5000;
[...]

In a project I did a couple years ago on a PIC18 the compiler online help said a small delay (around 20us IIRC) was required between adc channel selection and adc read; the reason was the adc mux needed some time to stabilize after selection.

maybe it helps?

They definitely help, when the code is incorrectly written.

RIDDICK:
i read here before that it might b a good idea to throw away the first reading after an ADMUX change...
the datasheet doesnt say it, but maybe it helps?

The analogRead() code in the Arduino core sets the multiplexer and then starts the ADC conversion in the very next instruction. I think this is plain stupid for a general purpose function. It just about works if the source resistance to the analog inputs is no more than a few kohms, but otherwise it doesn't give the sample capacitor time to charge. Reading the pin twice and throwing away the first reading helps, but doubles the analog read time and still doesn't work very well with high source resistances. I generally either use my own code for reading analog inputs, or patch the Arduino core to insert a delay between setting the multiplexer and starting the conversion. A value of 1us per 10K of source resistance works well.

Bear in mind that the input resistance of the ADC is quoted as 100Mohms typical, so if you have more than about 100K of source resistance, accuracy will be degraded.

dc42:
Reading the pin twice and throwing away the first reading helps, but doubles the analog read time and still doesn't work very well with high source resistances.

OMG YES! This is the solution to the problem!

I'm digging this 5 years old thread, because it's one of top google results and all other don't help.

It blows my mind, how full of fake information is arduino community. I read tutorials, how to use LM35 and they literally tell you lies, they mistake ground with power, tons of people were asking why their LM35 is getting extremely hot, but nope, author won't fix his article. I LITERALLY BURNED MY FINGERS touching it after following that stupid tut.
I checked other tutorials - nowhere to be found how to get proper readings. They just give you same basic code everywhere.