Go Down

Topic: Analogue input accuracy (LM35 thermometer) (Read 3 times) previous topic - next topic

Oliver

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...

Code: [Select]

/*
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

MikMo

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 :-) )

Oliver

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

mem

#3
Feb 17, 2008, 11:17 pm Last Edit: Feb 17, 2008, 11:19 pm by mem Reason: 1
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);

nkcelectronics

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.

Oliver

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

Xrim

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

Code: [Select]
#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!

KenH

#7
Feb 28, 2010, 09:24 pm Last Edit: Feb 28, 2010, 09:25 pm by KenH Reason: 1
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>


Xrim

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.

MarkT

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 ]
[ I won't respond to messages, use the forum please ]

Xrim

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!

Bobbo

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

Code: [Select]



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
}

Go Up