CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

LM35 temp sensor reading (10°C off)
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
STIX



Joined: 17 Jun 2006
Posts: 12

View user's profile Send private message

LM35 temp sensor reading (10°C off)
PostPosted: Thu Jun 28, 2007 12:37 pm     Reply with quote

Hi:

I connected a LM35 temperature sensor to my PIC16F877A MCU to take temperature readings. The following is my code:

Code:

#include <16F877A.h>
#device *=16
#device ADC=10
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT,NOLVP,NOCPD,NOWRT

#USE DELAY(clock = 4000000)
#use RS232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7)

void main ()
{
   int16 value, value1;
   setup_adc (ADC_CLOCK_DIV_8);
   setup_adc_ports (AN0);
   set_adc_channel (0);
   while (1)
   {
      delay_ms (500);
      value = read_adc ();
      value1 = 5 * value * 100/1024;
      printf ("Temp:%5.1fC\n\r", (float)value1);
   }
}


The LM35 is connected directly to AN0 on the MCU. However, the readings I get are always 10°C off. For example, the thermometer in the room will read 24°C, but the number I see on the hyperterminal is 14°C. If I increase the room temperature to like 25°C, the LM35 will read 15°C. Anyone know why this is happening? Thanks in advance.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Thu Jun 28, 2007 1:07 pm     Reply with quote

Put a voltmeter on the LM35 to see if it is a LM35 problem or a PIC problem. Also try putting the sensor in a glass of ice water to give a larger range of test data.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Steve H
Guest







PostPosted: Thu Jun 28, 2007 1:58 pm     Reply with quote

LM35's also like to oscillate - many times this oscillation looks like a reading that is way off and/or not particularly stable. Check the output with a scope or put the voltmeter that Sherpa suggested on AC millivolts - there should be no AC noise on the output of the LM35.

The data sheet shows how to prevent oscillation by the addition of a large C and a resistor.

HTH - Steve H.
caduhitec



Joined: 06 Feb 2007
Posts: 3

View user's profile Send private message

PostPosted: Thu Jun 28, 2007 7:08 pm     Reply with quote

use this

{
delay_ms (500);
value = read_adc ();
value1 = (value*49+1)/100;
printf ("Temp:%5.1fC\n\r", (float)value1);
}
STIX



Joined: 17 Jun 2006
Posts: 12

View user's profile Send private message

PostPosted: Mon Jul 02, 2007 12:55 pm     Reply with quote

Quote:

LM35's also like to oscillate - many times this oscillation looks like a reading that is way off and/or not particularly stable. Check the output with a scope or put the voltmeter that Sherpa suggested on AC millivolts - there should be no AC noise on the output of the LM35.

The data sheet shows how to prevent oscillation by the addition of a large C and a resistor.


1). The reading I get on the voltmeter is more consistent with the thermometer (e.g. thermometer: 22°C, voltmeter reading: 20°C). However, the hyperterminal is still showing numbers that are way off, something like 14°C.

2). I put the voltmeter on AC millivolts and I didn't see any reading so I assume there's not much oscillation.

3). I also put a large resistor (470k) and a large capacitor (10u) across the output and ground. It didn't make any difference on the hyperterminal reading.

Is there something wrong with my code? I also tried the code suggested by caduhitec, but it didn't make any difference. I don't think I have a bad PIC because I just got it. Can anyone make other suggestions? Thanks.
jma_1



Joined: 08 Feb 2005
Posts: 147
Location: Wisconsin

View user's profile Send private message

PostPosted: Mon Jul 02, 2007 5:13 pm     Reply with quote

Greetings,

Try explicitly casting your result as an int32. Your multiplication of a 10 bit adc by 5 and 100 -> 1023 * 5 * 100 = 511500. The maximum value of an int16 is 65536. Alternatively, declare value1 as an int32.

When debugging code, examine the basics. Print out the adc value of your channel only (without the formula applied to convert v to c). Is the value correct? Apply a known voltage. Does the voltage match the adc reading? This well help determine if your channel is setup correctly (correct reference voltage, channel, etc).

Do you need to try and convert the integer into a float for displaying it on the lcd? You will never have a fraction portion of the number (integers only).

Please post your results.

Cheers
BrunoCF



Joined: 14 Aug 2007
Posts: 2
Location: SP - Brasil

View user's profile Send private message MSN Messenger

PostPosted: Mon Sep 10, 2007 8:27 am     Reply with quote

I had a the same issue. Guess what was the problem: the power suply of my PIC was 4V instead of 5V... :P All my calculations were made for 5V, so they were all wrong.
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

LM35 ANSWER TO THE ISSUE
PostPosted: Tue Dec 04, 2007 8:50 pm     Reply with quote

HI
I was looking for same issue with u with lm35 and pic16f877a , i have find the answer.
take a look of my code for me have been worked wery well.
I think if u try the command i have pointed u with arrow it will work !!!
Code:


#include <16F877A.h>                <---------------------------
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT,NOLVP
#device  ADC=10                       <---------------------------
#use delay(clock = 4000000)
#byte PORTA=0X05
#byte PORTB=0X06

float oC=0;
float TempVal=0;
int counter=122;

void main()
{
PORTB=0X00;
PORTC=0X00;

set_tris_a(0xff);
set_RTCC(6);
setup_counters(RTCC_INTERNAL,RTCC_DIV_32);
enable_interrupts (INT_RTCC);
enable_interrupts (GLOBAL);

 while(true)
  {             
                       
           // -----ADC SETUP------------
 setup_adc_ports(AN0);                         // A0  Ref=Vdd
 setup_adc(ADC_CLOCK_INTERNAL);    // Internal 2-6us
 set_adc_channel(0);                          // use AN0

oC = read_ADC();               
TempVal = 5 * oC * 100/1024;


if(counter_thermo==30){
........=TempVal  //<------- u can put here  register of ur choice or what ever u want
                                    }
     counter_thermo=0;

               }   //  end while true
         }      //end    void main ()



 #int_RTCC       //  Timer0 interrupt
void interrupt()

{                           
if(--counter>0)return;
counter=122;

 ++counter_thermo;  // counter for start the show of thermometer

 }     

Now with ur code....try this!!!
Code:

#include <16F877A.h>
     //#device *=16 <----- u don't need this ,i don't so
#device ADC=10
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT,NOLVP,NOCPD,NOWRT

#USE DELAY(clock = 4000000)
#use RS232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7)

void main ()
{
   float value, value1; //<------ changed to float from int16
   setup_adc (ADC_CLOCK_INTERNAL); // <--- i have changed here!!!
   setup_adc_ports (AN0);
   set_adc_channel (0);
   while (1)
   {
      delay_ms (500);
      value = read_adc ();
      value1 = 5 * value * 100/1024;
   
     printf("Temp: %2.1fC" ,value1); //      <----here!!!
     
   }
}

try this and mail me if it work!!!
_________________
---- GREECE ----
Ttelmah
Guest







PostPosted: Wed Dec 05, 2007 4:13 am     Reply with quote

I'm sorry, but it is rare to see so many bad bits in one section of code....

First, *=16, is needed, if he is intending to write a larger main program, using more memory locations latter.
Second, using 'ADC_CLOCK_INTERNAL, is a bad decision. It will make the results _worse_, since it introduces extra randomness into the noise. Read the chip's data sheet. Note what it says under table 11-1, with regards to using the internal RC clock. If this made your code work, are you sure that you were using the right divider dfrom the processor clock...
Third, all you are doing, with your RTC code, is adding a long pause between the readings. If this fixed your problem, it suggests that you were not allowing long enough between the readings (the capacitor inside the ADC in the PIC, takes _time_ to charge, and is only charging when you are not reading). The existing code being tried, has a good delay present.

Now, the original poster, says he has put a large resistor and capacitor on the output. This is _not_ what is needed. The manufacturers recommended damping, when significant capacitance is present, is 75R, _in series_ with 1uF to the ground rail. Try this first. The PIC's ADC input, presents a lot of capacitance when it connects and switches during the conversion. Unless your voltmeter is able to see signals lasting for only a few uSec, it wont detect these spikes, and this could easily give the odd behaviour.
I the reading is then still consistently off, you really sould look doubly carefully at the supply rail. Again, it might look 'good' on a DVM, but if noise spikes are present on this, this would give spurious results. What damping is on this rail, how close to the PIC?.

Best Wishes
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

PostPosted: Tue Jan 01, 2008 2:38 pm     Reply with quote

Ttelmah wrote:
I'm sorry, but it is rare to see so many bad bits in one section of code....

First, *=16, is needed, if he is intending to write a larger main program, using more memory locations latter.
Second, using 'ADC_CLOCK_INTERNAL, is a bad decision. It will make the results _worse_, since it introduces extra randomness into the noise. Read the chip's data sheet. Note what it says under table 11-1, with regards to using the internal RC clock. If this made your code work, are you sure that you were using the right divider dfrom the processor clock...
Third, all you are doing, with your RTC code, is adding a long pause between the readings. If this fixed your problem, it suggests that you were not allowing long enough between the readings (the capacitor inside the ADC in the PIC, takes _time_ to charge, and is only charging when you are not reading). The existing code being tried, has a good delay present.

Now, the original poster, says he has put a large resistor and capacitor on the output. This is _not_ what is needed. The manufacturers recommended damping, when significant capacitance is present, is 75R, _in series_ with 1uF to the ground rail. Try this first. The PIC's ADC input, presents a lot of capacitance when it connects and switches during the conversion. Unless your voltmeter is able to see signals lasting for only a few uSec, it wont detect these spikes, and this could easily give the odd behaviour.
I the reading is then still consistently off, you really sould look doubly carefully at the supply rail. Again, it might look 'good' on a DVM, but if noise spikes are present on this, this would give spurious results. What damping is on this rail, how close to the PIC?.

Best Wishes

hi
For me my code works just fine...
Had had no problem...
Everything works just perfect...
Happy new year
_________________
---- GREECE ----
metalm



Joined: 22 Mar 2007
Posts: 23
Location: Buenos Aires, Argentina

View user's profile Send private message

PostPosted: Wed Jan 02, 2008 5:20 am     Reply with quote

The LM35 don't output few volts for connecting it directly to the AN pin of the pic? Don't need an operational amplifier??
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

PostPosted: Wed Jan 02, 2008 10:34 am     Reply with quote

metalm wrote:
The LM35 don't output few volts for connecting it directly to the AN pin of the pic? Don't need an operational amplifier??

Hi
No u don't need an amp ic cuz the sensor LM35 has a linear output 10mV/C.
See datasheets for more info.
Happy new year
_________________
---- GREECE ----
soulraven



Joined: 08 Feb 2009
Posts: 72
Location: campulung muscel

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Mon Mar 02, 2009 8:08 am     Reply with quote

but for negative temperature?how to use LM35?
Ttelmah
Guest







PostPosted: Mon Mar 02, 2009 8:57 am     Reply with quote

You have to add a -ve voltage source, and an external op-amp as a level shifter. Look at figure 2 in the data sheet, and then a simple op-amp 'adder'. Use this to add sufficient offset voltage so that the lowest reading you want to use is going to be above 0v.
Probably cheaper and simpler, to consider a different IC. The LM135, gives the same 10mV/degree, but with this starting at 0v=-273.15C. You get 2.73v, at 0C, and the IC itself happily works down to -40C (lower in some versions).

Best Wishes
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Mar 02, 2009 11:21 am     Reply with quote

i'ved used the LM-34 with the F886/887 - and rely on using an external 2.5 v V prec. ref -- to read temps mostly in the area of 150F to 212F.

looking at the schemo i drew - back when- - all i do is run the sensor on the same modestly regulated 5V as the PIC - but with a 4.7 uf tant cap on the 5V supply line to the sensor - the sensor cable is a flexible single pair audio cable - where the shield is the NEG return and the +5 and ret signal are the "pair" inside.

typical displacement is about 3 to 4 ft from the controller board.

i just tried one with 30 feet of cable and it still works FINE.

the receiver components going TO the pic are nothing more than a series 100 ohm resistor - shunted to ground by .1uF at the PIC pin input pin.

i get excellent matching at the 212F cal point ( +/- 1.5 deg F ) between LM34's and have never observed anything you could call instability.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group