Pages: [1]   Go Down
Author Topic: Analogue input accuracy (LM35 thermometer)  (Read 2809 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Copenhagen / Denmark
Offline Offline
Edison Member
*
Karma: 6
Posts: 2360
Do it !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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);
« Last Edit: February 17, 2008, 05:19:47 pm by mem » Logged

USA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 452
Freeduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Luleå, Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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!
Logged

Mobile, AL
Offline Offline
Sr. Member
****
Karma: 0
Posts: 314
CAUTION!-Slow Learner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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>

« Last Edit: February 28, 2010, 03:25:41 pm by KenH » Logged

Luleå, Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11690
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ]
Logged

[ I won't respond to messages, use the forum please ]

Luleå, Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:


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
}
Logged

Pages: [1]   Go Up
Jump to: