# LM35 with PIC16F877A - getting wrong values

Status
Not open for further replies.

##### Newbie level 4
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.
this is the code that I am using:

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

float temp;

void main()
{
delay_ms(100);

while(1) // infinite loop
{
delay_us(100);
printf("%2.1f C\n",temp);
}
}

I think the error is in the VREF settings. Actually I don't know how to set it and what should I connect to it.
I've already done so many researches in google and in this forum, and I got no answer for my problem. The circuit diagram is the same as the following circuit posted in this forum:

I am getting those values on my PC HyperTerminal while of course the temperature did not changed that way in few seconds :!::!::!:
68.0 C
44.0 C
27.0 C
38.0 C
89.0 C
57.0 C
102.0 C
77.0 C
76.0 C
59.0 C
68.0 C
77.0 C
38.0 C
38.0 C
51.0 C
64.0 C
44.0 C
.
.
.
.

please I need a very urgent help in fixing this issue.
Thank you

#### ysba

Try to use an integer variable type instead of 'float'. Try 'unsigned int'.

shareef suliman

### shareef suliman

Points: 2

##### Newbie level 4
dear, I already tried all kinds of variable types, such as int, float, long.. allways same issue. can you privide me with a complete solution?? thanks in advance

#### ysba

Oh... Now I looked with better attention. The issue may be that your delay time (100 us) is smaller than the time you need to transmit the string "%2.1f C\n". Running at 9600 bps, you'll need 1.04 ms to transmit each char. Try using a much bigger delay, something like 200 ms, between your transmissions. Hope this helps.

##### Newbie level 4
do you know how to deal with vref?

#### ysba

I don't know how to do this with the CCS compiler... I use the Microchip compilers and set the SFRs by myself. Well, PIC16F877 have two registers, ADCON0 and ADCON1. Setting their values will configure the ADC module operation. There's a setting that you set the positive and negative references to VDD and VSS internally, without the need of connect analog values in some pin. You should check the CCS documentation to see what it says about. You need to confirm if this is the default configuration.

But I don't think this is your problem. First, as I mentioned before, you need to guarantee a minimum time between your transmissions (like 100 or 200 ms). And after that, check out the line SETUP_ADC(ADC_CLOCK_INTERNAL);. See what options do you have as clock parameter. See if there's something like "CLOCK_DIV_BY_[SOME VALUE]". Choose the value that is bigger (I think it is 64). This is the clock to your AD conversion. If it is much fast, your conversion will give wrong values. Since you are taking temperature measures, slowing down will not cause trouble, cause temperature doesn't change so fast. Try it and post your result here

##### Banned
Change this printf("%2.1f C\n",temp); to this printf("%5.2f C\n",temp);

##### Newbie level 4
i tried all of what you said !!! same problem
i am getting the same wrong values that are changing:
106.00 C
64.00 C
74.00 C
43.00 C
42.00 C
42.00 C
45.00 C
82.00 C
58.00 C
69.00 C
85.00 C
58.00 C
22.00 C
.
.
.

I've changed the code as you told me and here is the new code that I am using but with same result:

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

float temp;

void main()
{
delay_ms(100);

while(1) // infinite loop
{
delay_ms(1000);
printf("%5.2f C\n",temp);
}
}

note that I added a delay of 1000 ms after reading the adc value, but nothing changed !
I am using the AN0 as input and the others are not connected to anywhere, is that right ?
so now what should I do ?

- - - Updated - - -

I also tried the "SETUP_ADC_PORTS(A_ANALOG_RA3_RA2_REF);" instead of "SETUP_ADC_PORTS(AN0);". I wired a 5v to the RA3/AN3/VREF+ and 0v to the RA2/AN2/VREF-
and i got the same result. but if I put 0v to the RA3/AN3/VREF+, then the result will always be "1023.00 C" as if it is giving the maximum value even when changing the input analog value

#### ysba

Looks like you are reading an unconnected pin... In this CCS compiler, do you have to say in somewhere if the pins are input or output? In the PIC MCU's, there's the TRIS registers. Each bit says to one pin if it is IN or OUT. Check if the compiler have this option, and if so, do this before all the configuration.

#### avineshb006@gmail.com

##### Member level 3
HI

I think you are struck up with the port bit direction, because hear you are using the PORT A Bit 0 as a input, so you need to direct it...

set_tris_a(0x01);

delay_ms(100);

output_a(0x00);

Try this and tell what u are getting..

##### Newbie level 4
delay_ms(100);

output_a(0x00);

Try this and tell what u are getting..

avineshb006@gmail.com,
for the above code, i tried the following:

Code:
#include <16f877a.h>
#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);
delay_ms(100);
output_a(0x00);

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

and I got the same kind of result :----(
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?

Yasba, as you said:
Looks like you are reading an unconnected pin... In this CCS compiler, do you have to say in somewhere if the pins are input or output? In the PIC MCU's, there's the TRIS registers. Each bit says to one pin if it is IN or OUT. Check if the compiler have this option, and if so, do this before all the configuration.

I dont know if I did it once as you said, at least while working with digital only and not using the ADC. It's my first time that I am using the ADC in the PIC16F877A

#### ysba

In the PIC MCU's, you always need to tell the direction of the pins. It doesn't matter if they are analog or digital, or if they will be simples IO or will be connected internally at some peripheral. You always need to configure the TRIS registers.

Well, in another post, I said to you something about the [SETUP_ADC(ADC_CLOCK_INTERNAL);] line. By that time, we didn't mentioned the pin directions issue... Now it is alright. I'll suggest you to to change this line again to [setup_adc(ADC_CLOCK_DIV_64);]. I took a look at the PIC16F877A datasheet. When you say that the AD clock is internal, you are using an internal RC clock. The datasheet says that if you are using a frequency above 1MHz, you should use this kind of clock only in the sleep mode. This is not your case. You are running at 4MHz. It's better to slow down the AD conversion clock. This may the cause of your problem... Once I tried it by myself. I put a AD clock faster than recommended, and a similar thing occurred.

##### Newbie level 4
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!!!
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