Go Down

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

Oliver

Feb 16, 2008, 11:57 am
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 0float temperature = 0;                      //variable which will be calculated in processint redLED=12;                              //Pin12 = Red LEDint yellowLED=11;                           //Pin11 = Yellow LEDint greenLED=10;                            //Pin10 = Green LEDlong val=0;                                 //variable to store the value coming from the sensorvoid 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...`

Oliver

MikMo

#1
Feb 16, 2008, 02:25 pm
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

#2
Feb 17, 2008, 10:12 pm
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 pmLast 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

#4
Feb 18, 2008, 04:47 am
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

#5
Feb 19, 2008, 01:53 am
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

#6
Feb 28, 2010, 02:48 pm
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 pinModeSoftwareSerial 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 pmLast 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

#8
Mar 01, 2010, 10:07 am
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

#9
Mar 01, 2010, 09:39 pm
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 will NOT respond to personal messages, I WILL delete them, use the forum please ]

Xrim

#10
Mar 02, 2010, 08:32 am
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

#11
Mar 08, 2010, 11:43 am
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 pinint tempc = 0; // temperature variablesint samples[8]; // variables to make a better precisionint maxi = -100,mini = 100; // to start max/min temperatureint 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 precisionif(tempc > maxi) {maxi = tempc;} // set max temperatureif(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