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 support@ccsinfo.com

LM35 with PIC16F877A - getting wrong values

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
adison.mhanna



Joined: 03 Jun 2013
Posts: 3

View user's profile Send private message

LM35 with PIC16F877A - getting wrong values
PostPosted: Mon Jun 03, 2013 9:25 am     Reply with quote

hello guys.
I really get stuck!!!
I am designing a temperature logger on the PC. I am using LM35 with PIC16F877A microcontroller with its built-in ADC
I want to send the value of the temperature to the PC using MAX232 to log it somewhere in my database
I don't need to display the temperature on an LCD, all I need is to get the value from the LM35 and send it through the RS232 serial port
I tried so many times with the same wrong result: I am getting values that is always changing even if I am putting a fixed voltage instead of the LM35 sensor.
I have only one analog input.
this is the code that I am using:

Code:
#include <16f877a.h>
#device adc=10
#fuses XT,NOLVP,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

unsigned int temp;

void main()
{   
    set_tris_a(0x01);
    SETUP_ADC(ADC_CLOCK_INTERNAL);
    SETUP_ADC_PORTS(ALL_ANALOG);
    SET_ADC_CHANNEL(0);
    delay_ms(100);
    output_a(0x00);
   
   while(1) // infinite loop
   {
     temp = read_adc();
     delay_ms(1000);
     printf("%u C\n",temp);     
   }
}


here is a sample of the output:
34 C
32 C
75 C
11 C
64 C
32 C
25 C
63 C
73 C
32 C
18 C
73 C
4 C
32 C
44 C
9 C
38 C
19 C
.
.
.
.

In this case, i left the A2 and A3 not connected to anything, is that true? or should I do something else?
i need to solve this as an urgent issue !!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 9:42 am     Reply with quote

Quote:
void main()
{
set_tris_a(0x01);
SETUP_ADC(ADC_CLOCK_INTERNAL);
SETUP_ADC_PORTS(ALL_ANALOG);
SET_ADC_CHANNEL(0);
delay_ms(100);
output_a(0x00);

In the line in bold above, you have set all pins on PortA to be outputs.

Look at the .LST file below. It shows what the compiler is doing:
Code:

....................     output_a(0x00); 
0090:  BSF    STATUS.RP0
0091:  CLRF   TRISA            <===  Set TRISA to 0x00 (all outputs)
0092:  BCF    STATUS.RP0
0093:  CLRF   PORTA


Here is what the 16F877A data sheet says:
Quote:

11.3 Configuring Analog Port Pins
The ADCON1 and TRIS registers control the operation
of the A/D port pins. The port pins that are desired as
analog inputs must have their corresponding TRIS bits
set (input). If the TRIS bit is cleared (output), the digital
output level (VOH or VOL) will be converted.

The data sheet says the analog pin must have the TRIS set as an input.
You are violating this specification with the output_a() statement.

CCS is designed to be easy for newbies. Most of the built-in functions
automatically set the correct tris for you. This is the standard default
mode of the compiler. If you want to control the TRIS yourself, then
you need to tell the compiler to use Fast I/O mode. See the CCS manual.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 10:40 am     Reply with quote

Hi,

If you use the "Search" function of this forum you will find a driver I posted some time ago for the LM35.

http://www.ccsinfo.com/forum/viewtopic.php?t=48525&highlight=lm35
Use the updated version on my second post.

Things you should know:
- the circuit for the LM35 is as per Figure7 on the datasheet.
- if you are powering your circuit with 5V you do not need the Charge pump.
- the driver uses 2 (TWO) ADC channels for +/- temperatures.

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
adison.mhanna



Joined: 03 Jun 2013
Posts: 3

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 11:37 am     Reply with quote

Quote:

Quote:
void main()
{
set_tris_a(0x01);
SETUP_ADC(ADC_CLOCK_INTERNAL);
SETUP_ADC_PORTS(ALL_ANALOG);
SET_ADC_CHANNEL(0);
delay_ms(100);
output_a(0x00);

In the line in bold above, you have set all pins on PortA to be outputs.

Look at the .LST file below. It shows what the compiler is doing:


I got your idea and I removed it... the same problem

now I am working using this code:



Code:
#include <16f877a.h>
#device adc=10
#fuses XT,NOLVP,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

unsigned int temp;

void main()
{   
    set_tris_a(0x01);
    SETUP_ADC(ADC_CLOCK_INTERNAL);
    SETUP_ADC_PORTS(ALL_ANALOG);
    SET_ADC_CHANNEL(0);
    delay_ms(100);

   while(1) // infinite loop
   {
     temp = read_adc(ADC_START_AND_READ);
     delay_ms(500);
     printf("%u C\n",temp);     
   }
}


I am getting this result:
76 C
55 C
27 C
77 C
114 C
130 C
115 C
141 C
13 C
27 C
51 C
55 C
13 C
110 C
76 C
.
.
.
.

PLEASE can anyone provide me with a simple code in how to get the real adc value and how to implement the circuit diagram?
maybe I should set the VREF + and VREF- values ??
please I am getting crazy about this small project !!! Mad Mad Mad
I've been working on it for more than 10 days with no result !!!
what should I do ?
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 1:28 pm     Reply with quote

Code:
void main()
{   
    SETUP_ADC_PORTS(sAN0);              // I like to select *Ports  first
    SETUP_ADC(ADC_CLOCK_INTERNAL);       // WRONG ADC TIME CONSTANT FOR 4MHZ
    SET_ADC_CHANNEL(0);          
    delay_ms(100);

   while(1) // infinite loop
   {
     temp = read_adc();
     temp *= 0x1E8;                                          // Ive added the ADC const
     printf("%u C\n\r",temp);
     delay_ms(500);
   }
}


try that... but first, check what is the correct TAD for a 4MHZ clock


also, you are not "scaling" your ADC reading... the ADC give you a count of how many steps it took to the closest value you where reading... NOT the voltage.

you need to multiply your ADC value (temp) by a constant which is dependent on voltage...

for 1023 bit res @5V i use:

ADC_Const = ((5/1023)*100,000)

Which basically reduces to: 0x1E8
Ive added this to your code...

now temp should contain Volts... which for the LM35 equal Temp in C.

since you apparently are only interested in positive temps, you only need 5v, GND, and Vout to AN0.


EDIT: MOST IMPORTANTLY

Temp is an 8 int variable... it cant hold a 10 bit number thus what you are seeing are only the last 8 bits of your reading...
Make temp an int16.

G
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 1:34 pm     Reply with quote

Several things:

First is ADC_CLOCK_INTERNAL correct for your system?. Read the data sheet. What does it say about this selection, and frequencies above 1MHz?.

Then the count from the ADC, is not going to be in degrees. The ADC is operating from 0 to 5v. Each 'step' is approximately 4.8mV. The sensor gives 10mV per degree. So you need to divide the output by just over 2, to get degrees.

Only setup the channel you are using to feed the ADC. Every extra signal you have connected to the ADC multiplexer increases noise.

Now, the accuracy and repeatability of the result will be dependent on how smooth and stable your 5v rail is.

Best Wishes
SherpaDoug



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

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 1:42 pm     Reply with quote

Gabriel's comment is most important. If you put a 10 bit number in an 8 bit variable you throw out the MOST SIGNIFICANT bits.

Also be sure to get it working with a known voltage or resistor divider first. Those temperature sensors can sometimes oscillate which will give just the sort of noise you are seeing. Do you have an oscilloscope you can put on the temperature wire?
_________________
The search for better is endless. Instead simply find very good and get the job done.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Mon Jun 03, 2013 3:46 pm     Reply with quote

what is your CIRCUIT??
care to post it ??
what is your ADC reference voltage and how is it derived?

i have used the LM34 and never the LM35 - as there is more output and better resolution over biologically useful temperature ranges using the LM34 and converting to degrees C in software. if you are in the range of
mammalian temperatures - you will only have a signal of less than .4V to read.

if using a noisy 5V Vdd as the implied ADC reference - you are not going to get spectacularly good resolution or low conversion noise either. In my own work , i would solve your problem by adding clean OP amp GAIN to the LM34, and then using methods like this to get low noise readings:

http://www.ccsinfo.com/forum/viewtopic.php?t=50320

http://www.ccsinfo.com/forum/viewtopic.php?t=50354
adison.mhanna



Joined: 03 Jun 2013
Posts: 3

View user's profile Send private message

problem solved
PostPosted: Mon Aug 05, 2013 5:58 am     Reply with quote

hello guys again.
first of all thank you for your support, I've been away for a long period due to some force reasons.
regarding the project, it worked finally!!! Very Happy Very Happy
The problem was that I was missing some filters for the DC power. I've added a 1000 uf capacitor to the 5 V DC after putting a regulator after the 12 v for having 5 V with 5 A supply power. Before I used to put the power of 5 V only coming from a 700 MA power adapter.
THANK YOU ALL
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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