Analogue input accuracy (LM35 thermometer)

Hello,

I've created a simple circuit to measure temperature using a National Semiconductor LM35 chip (http://www.national.com/mpf/LM/LM35.html) .

Everything is connected up and working fine, including switching between 3 LED's depending on the temperature thats being measured.
The question I have, is that at the moment it's only outputting whole numbers. Is there any way to get decimal places?

This is the code I'm using...

/*
LM35 Thermometer
 *
 *LM35 simpy connected to:     5+
 *                             0V
 *                             Analog Pin 0
 */


int potPin = 0;                             //input read pin for LM35 is Analog Pin 0
float temperature = 0;                      //variable which will be calculated in process
int redLED=12;                              //Pin12 = Red LED
int yellowLED=11;                           //Pin11 = Yellow LED
int greenLED=10;                            //Pin10 = Green LED
long val=0;                                 //variable to store the value coming from the sensor


void setup()
{
  pinMode(redLED, OUTPUT);                    //LED set to output
  pinMode(yellowLED, OUTPUT);                  //LED set to output
  pinMode(greenLED, OUTPUT);                  //LED set to output
  Serial.begin(9600);  
  Serial.println("LM35 Thermometer    ");       //Print "LM35 Thermometer" once at start
}


void loop ()                                //loop below process
{

  val = analogRead(potPin);                 //read the value of sensor
  temperature = (5*val*100/1024);           //convert voltage to temperature
  Serial.println ((long)temperature);       //print temperature value on serial screen

  if (temperature >= 40)                      //Check if temp over x degrees C.
  {
    digitalWrite (redLED, HIGH);            //If so... turn LED on
    digitalWrite (yellowLED, LOW);          //and this LED off
    digitalWrite (greenLED, LOW);           //and this LED off
  }
  else if ((temperature < 40) && (temperature >25))  //if temperature does not meet above requirement but is between Y and Z... do below 
  {
    digitalWrite (redLED, LOW);            //turn LED off
    digitalWrite (yellowLED, HIGH);        //turn LED on
    digitalWrite (greenLED, LOW);          //turn LED off
  }
  else                                       //if temperature doesn;t meet eith of the above statements do...
  {
    digitalWrite (redLED, LOW);            //turn LED off
    digitalWrite (yellowLED, LOW);         //turn LED off
    digitalWrite (greenLED, HIGH);         //turn LED on
  }

  delay(20000);                               //wait for 20seconds

}                                      //End of process, go back to start of loop - ie check temp...

Thanks for reading

Oliver

From the datasheet i see that the sensor has a precision of 0.5 degree, so displaying the decimals would really not make much sense IMHO. (except that it would look cooler :slight_smile: )

Yeah, this is my first project, so I'm just trying to learn the ropes so to speak. So although the decimals aren't 100% necessary it'd be great if someone could shed some light on how to get them working.

Oliver

You could do something like this:

void printTenths( int value){
// prints a value of 123 as 12.3

Serial.print(value / 10);
Serial.print(".");
Serial.print( value % 10);
}

I prefer to do all my math as integers but if you are working in floats then:

float f = 12.3

printTenths(f * 10);

As you are writing the temp to the serial port, then you can format the real number (temperature) to a string using sprintf, then print the string to the serial port. sprintf is similar to printf, from the number formatting capabilities.

Thanks all for getting back to me so quickly. I've used mem's first suggestion and that all seems to work. Hopefully I'll be able to try out the other methods tomorrow.

Oliver

This thread has just the answer I'm looking for but I cant get it to work, I'm a newbie on programming and needs som help. I got a LM35DZ hooked up to my Arduino and a LCD to display the temp. However I wish to have decimals on the temp diplayed on the LCD. I have tried to insert the example mem put down above but I cant get i to work on my LCD

Where am I to insert it in my code

#include <SoftwareSerial.h>

int potPin = 1;
float temp = 0;
long val=0;



#define rxPin 4  // rxPin is immaterial - not used - just make this an unused Arduino pin number
#define txPin 14 // pin 14 is analog pin 0, on a BBB just use a servo cable :), see Reference pinMode
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup(){


   pinMode(txPin, OUTPUT);
   mySerial.begin(9600);      // 9600 baud is chip comm speed

   mySerial.print("?G420");   // set display geometry,  2 x 16 characters in this case
   delay(500);                
   
   mySerial.print("?Bff");    
   delay(1000);                

   mySerial.print("?c0");     
   delay(1000);               
   
    mySerial.print("?>4");       
   delay(300);                                  
                                                
   mySerial.print("?f");                   // clear the LCD
   delay(10);                                              
   
                                                  
   }

void loop(){

  val = analogRead(potPin);
  temp = (5*val*100/1024);
  mySerial.print("?>4"); 
  mySerial.print("?x00?y0");
   
  mySerial.print((long)temp);     
  mySerial.print("?<");
  mySerial.print("?x10?y0");
  mySerial.print("Grader");
  mySerial.print("?x10?y1");
  mySerial.print("C");
   
   
   delay(1000);                              
}

Any help and suggestions is welcome!

Starting with 0018 the solution is even simpler, at your Serial.print(val, 2); statement the val is your variable to be printed, and the 2 is the number of decimals you wish, use 1, or 2 or 3 depending on how many decimals you wish to print.

I'm not at all sure about the mySerial.print() statement you're using. Someone else will have to comment on that - try it with just Serial.print() and see how that works.

I just re-read your post and see you're trying to read out to a LCD display? Then use lcd.print(val, 1); to print to the LCD.

Ken H>

Thaks for the reply, I'll try it as soon as I'm home. The my.Serial is from the SoftwareSerial.h lib I'm using with a LCD117 serial board.

You are doing integer arithmetic - change the 5 to 5.0 and it will work. Basically an expression where everything is an integer variable or constant is calculated using integer arithmetic EVEN IF the result is then assigned to a float variable.

So change

  temperature = (5*val*100/1024);           //convert voltage to temperature

to

  temperature = 5*((float)val)*100/1024 ;           //convert voltage to temperature

or

  temperature = 5.0*val*100/1024 ;           //convert voltage to temperature

or to be really emphatic:

  temperature = 5.0*val*100.0/1024.0 ;           //convert voltage to temperature

[ I've removed spurious parentheses as well to unclutter the line ]

Hmmm, for some reason none of the above examples worked, might have to do with the lib I'm using. Thing is that I want to use the backpack since it has a big numer function that uses all four lines to diplay the numbers (up to four numbers or three numbers with a decimal).
The examples I've seen on the developers homepage clearly shows the LCD displaying bignumbers with decimal... I'll dig deeper... Thank you alot for the help!

Messy and un-commented code but I know it works and is pretty simple, same project I used as a introduction to Arduino.

int pin = 0; // analog pin
int tempc = 0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i;
int ledPinC = 11;
int ledPinW = 10;
int ledPinH = 9;
int brightness = 180;

void setup()
{
    Serial.begin(9600); // start serial communication
}

void loop()
{
  
  
for(i = 0;i<=7;i++){ // gets 8 samples of temperature
  
  samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
  tempc = tempc + samples[i];
  delay(50);

}

tempc = tempc/8.0; // better precision


if(tempc > maxi) {maxi = tempc;} // set max temperature
if(tempc < mini) {mini = tempc;} // set min temperature

  if (tempc < 28) {
    analogWrite(ledPinC,brightness);
    analogWrite(ledPinW,LOW);
    analogWrite(ledPinH,LOW);
  } 
  if (tempc > 28) {
    analogWrite(ledPinC,LOW);
    analogWrite(ledPinW,brightness); 
    analogWrite(ledPinH,LOW);
  }
  if (tempc > 30) {
    analogWrite(ledPinC,LOW);
    analogWrite(ledPinW,LOW);
    analogWrite(ledPinH,brightness);
  } 

Serial.println(tempc);

tempc = 0;

delay(50); // delay before loop
}