lm35 + keypad lcd shield unstable temperature

hi all,

i'm trying to use the lm35 sensor and a keypad lcd, but when I use the code below, the value of temperature is very very strange. without the code for the buttons it work fine. Can someone help me to understand where is the error in my code?

This is the value from the serial monitor, the first value look correct, the other is very strange.

thank you.

temp value 20.02
setting value 0
temp value -17.32
setting value 0
temp value -15.86
setting value 0
temp value -113.18
setting value 0
temp value -134.18
setting value 0
temp value -139.55
setting value 0
temp value -130.76
setting value 0
temp value -136.62
setting value 0
temp value -138.09
setting value 0
temp value -133.69
setting value 0
temp value -17.32
setting value 0
temp value -115.63
setting value 0
temp value -137.11
setting value 0
temp value -16.35
setting value 0
temp value -131.74
setting value 0
temp value -17.81
setting value 0
temp value -121.00
setting value 0
temp value -17.81
setting value 0
temp value -17.32
setting value 0
temp value -127.34
setting value 0
temp value -136.62
setting value 0
temp value -139.55
setting value 0
temp value -134.67
setting value 0
temp value -138.57
setting value 0
temp value -131.74
setting value 0
temp value -139.55
setting value 0
temp value -124.41
setting value 0
temp value -139.55
setting value 0
temp value -133.69
setting value 0
temp value -139.06
setting value 0
temp value -139.06

#include <LiquidCrystal.h>
#include <LCDKeypad.h>

LCDKeypad lcd;

float temp=22;
float sens=0.5;
int setting=0;
const int pin_sonda=A2;
float sonda;
float reading;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2);
  //lcd.setCursor(0,0);
  //lcd.print("Temp: ");
}

void loop()

{
  reading=analogRead(pin_sonda);
  sonda =((reading/1024.0)*5000)/10;
  Serial.println (sonda);
  
  pushit ();
  
  mostra();  
}

void pushit() {

  int buttons = lcd.button();
  
  for (int i=0; i<5; i++);
  
  switch (buttons) {
    case KEYPAD_UP:
       switch (setting) {
         case 1:
           temp=temp+0.1;
           break;
         case 2:
           sens=sens+0.1;
       }   
      break;
    case KEYPAD_DOWN:
      switch (setting) {
         case 1:
           temp=temp-0.1;
           break;
         case 2:
           sens=sens-0.1;
       }   
      break; 
    case KEYPAD_LEFT:
      setting--;
      if (setting==-1) {
        setting=2;
      }  
      break;
    case KEYPAD_RIGHT:
      setting++;
      if (setting==3) {
          setting=0;
      }
  }
 Serial.println(setting);
 Serial.print (buttons);
 delay(200);
}  
  
void mostra()
{
  lcd.clear();
  switch (setting){
    case 0:
      lcd.print ("temperatura");
      lcd.setCursor (12,0);
      lcd.print(sonda);
      break;
    case 1:
      lcd.print("imposta temp");
      lcd.setCursor (0,1);
      lcd.print(temp);
      break;
    case 2:
      lcd.print("imposta sensi");
      lcd.setCursor (0,1);
      lcd.print(sens);
    }    
}
  for (int i=0; i<5; i++);

WTF?

This is the value from the serial monitor, the first value look correct, the other is very strange.

Nonsense. All that output looks like crap. Add some text to identify what you are printing. A jumble of numbers is useless.

sorry for the "for" i forgot to remove it.
I added text in the printing.

I added text in the printing.

So, you modified your initial post, to make me look like an idiot. I see.

PaulS:
So, you modified your initial post, to make me look like an idiot. I see.

sorry.

try to avoid serialprint & lcd.print statement same at time. please share us circuit diagram for LM35.

I try just the lcd and the problem is the same.
if I change the code in this way:

#include <LiquidCrystal.h>
#include <LCDKeypad.h>

LCDKeypad lcd;

float temp=22;
float sens=0.5;
int setting=0;
const int pin_sonda=A2;
float sonda;
float reading;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2);
}

void loop()

{
  reading=analogRead(pin_sonda);
  sonda =((reading/1024)*5000)/10;
  Serial.print ("temp: ");
  Serial.println (sonda);
  
  //pushit ();
  
  mostra();  
  delay(1000);
}

/*void pushit() {

  int buttons = lcd.button();
  
  switch (buttons) {
    case KEYPAD_UP:
       switch (setting) {
         case 1:
           temp=temp+0.1;
           break;
         case 2:
           sens=sens+0.1;
       }   
      break;
    case KEYPAD_DOWN:
      switch (setting) {
         case 1:
           temp=temp-0.1;
           break;
         case 2:
           sens=sens-0.1;
       }   
      break; 
    case KEYPAD_LEFT:
      setting--;
      if (setting==-1) {
        setting=2;
      }  
      break;
    case KEYPAD_RIGHT:
      setting++;
      if (setting==3) {
          setting=0;
      }
  }
 delay(500);
}  
*/  
void mostra()
{
  lcd.clear();
  switch (setting){
    case 0:
      lcd.print ("temperatura");
      lcd.setCursor (12,0);
      lcd.print(sonda);
      break;
    case 1:
      lcd.print("imposta temp");
      lcd.setCursor (0,1);
      lcd.print(temp);
      break;
    case 2:
      lcd.print("imposta sensi");
      lcd.setCursor (0,1);
      lcd.print(sens);
    }    
}

This is what show the serial print:

temp: 21.97
temp: 21.97
temp: 21.97
temp: 21.97
temp: 21.97
temp: 21.48
temp: 21.48
temp: 21.97
temp: 21.48
temp: 21.48
temp: 21.97

the circuit is very simple, like this. but with the keypad lcd shield.

const int pin_sonda=A2;

Which analog pin are the LCD switches connected to?

PaulS:

const int pin_sonda=A2;

Which analog pin are the LCD switches connected to?

A0, it's missing on shield. I see one thing, maybe can help, if I push a button UP or DOWN to change the value, the temperature value is correct and stable. when I release the button became unstable again.
could be a problem of shield?

i recommed you just connect lm35 IC to arduino. write code to get temperature output.

As i told dont use serial& LCD print same @ time.

Here two simple code to try it out

float tempC;
int reading;
int tempPin = 0;

void setup()
{
Serial.begin(9600);
analogReference(INTERNAL);
}

void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.print("temp:");Serial.println(tempC );
delay(1000);

}
int val;
int tempPin = 1;

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  val = analogRead(tempPin);
  float mv = ( val/1024.0)*5000; 
  float cel = mv/10;
  float farh = (cel*9)/5 + 32;

  Serial.print("TEMPRATURE = ");
  Serial.print(cel);
  Serial.print("*C");
  Serial.println();
  delay(1000);
}

Reading an LM35 with the default Aref (post#0 code) is not a very good idea.
A temp of 22 degrees C is only ~44 digital values.
Displaying that with two decimal places is mostly guessed information.

Using the internal 1.1volt Aref improves two things.
The A/D resolution gets 5x better, and the reading becomes independent of power supply fluctuations (think code execution and/or USB supply dips).

AMPS-N's first code uses the internal 1.1volt Aref.

This code uses the internal 1,1volt Aref and averaging.
And I have included LCD and serial readout.
Works with the same LCD shield as on the picture.
LM35 sensor connects to A1
Up to you to add any button code.
Leo..

// LM35 temp sensor connected to Analogue-in 1, 5volt and ground
// ~2 to ~102 degrees C
//
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // your LCD pins could be different
int ledPin = 10; // backlight pin
unsigned long total; // readings
float tempC; // Celcius
float tempF; // Fahrenheit
//
void setup() {
  analogReference(INTERNAL); // use the internal ~1.1volt reference, change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(115200); // ---set serial monitor to this value---
  //analogWrite(ledPin, 255); // optional dimming
  lcd.begin(16, 2); // shield with 2x16 characters
  lcd.setCursor(0, 0); // first row
  lcd.print("Thermometer"); //info text
  lcd.setCursor(0, 1); // second row
  lcd.print("0-100 Celcius");
  delay(2000); // info display time
}
//
void loop() {
  analogRead(1); // one unused reading
  for (int x = 0; x < 50; x++) { // 50 readings for averaging
    total = total + analogRead(1); // add each value to a total
  }
  // convert value to temp
  tempC = total * 0.00207617; // calibration maths, depends on actual Vref, (0.001953125 * Vref in volts)
  tempF = tempC * 1.8 + 32; // Fahrenheit conversion
  // print to LCD
  if (total == 51150) { // 50*1023
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("---TOO HOT---");
  }
  else {
    lcd.clear();
    lcd.setCursor(0, 0); // first row
    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 * 0.02, 1); // 1/50 of 50 readings, one decimal place
  if (total == 51150) { // max value with 50 readings
    Serial.println("  ----too hot----");
  }
  else {
    Serial.print("   The temperature is  ");
    Serial.print(tempC, 2); // two decimal places
    Serial.print(" Celcius  ");
    Serial.print(tempF, 1); // one decimal place
    Serial.println(" Fahrenheit");
  }
  delay(1000); // slows readings
  total = 0; // reset value
}

Hi,
Have you got a 0.1uF capacitor across the V+ and gnd pins of the LM35.
Place it at the LM35 as close as possible.

Tom.... :slight_smile:

Wawa:
Using the internal 1.1volt Aref improves two things.
The A/D resolution gets 5x better, and the reading becomes independent of power supply fluctuations (think code execution and/or USB supply dips).

your code function very well, but the buttons don't work with the internal reference. the difference with and without is huge. so now, I have to find another way instead for the buttons.

the other code work fine, the problem is the same. impossible to use buttons and sensor together.

please send your complete code using LCD sheild.

i think u should try to take average of 10 sample they try to display on LCD sheild . which might help you get o/p exactly.

AMPS-N:
please send your complete code using LCD sheild.

i think u should try to take average of 10 sample they try to display on LCD sheild . which might help you get o/p exactly.

the library too? if not the complete code is in the first post.

i try more sample of code, but when i insert in the sample with buttons the sensor or viceversa, the result is the same. buttons work, but the value of the temperature are very unstable.

I tried the code in this link too

nothing change.