desmond1310
Member level 1
LM35 + PIC16F877A: Incorrect conversion readings from ADC
I am using LM35 + PIC16F877A. My feature is to turn off my relay (linked to RC0) whenever the temperature hits 85'C.
Here's a sample program of the subroutine ADC code which is stated as below. I am currently using the same subroutine code with it. In the sample program also, the value of 400 correlates to 40'C, and 350 correlates to 35'C, which is also stated below.
This is the sample program's ADCON0 and ADCON1 settings and mine.
ADCON0
CHANNEL0 0b10000001 // AN0
CHANNEL1 0b10001001 // AN1
ADCON1
0b11000101
Mine
ADCON0
CHANNEL2 0b10010001 //AN2
ADCON1
0b11000011
As far as i have listed, I am using Fosc/64 and right justified.
Now, the problem is when I insert my limit as 850 or as known as 85'C, it NEVER triggers my relay, which meant my limit was too high.
After hours of troubleshooting, i found that by setting the value: 200 as my limit, it TRIGGERS my relay to off at precisely 85'C!
Why is 200 correlating to 85'C and not 850?
Can anyone find out my mistake? I'm still new to the ADC settings, ADCON1, ADCON0 settings and I believe my problem lies there.
Here's my piece of code that sets the limit:
I am using LM35 + PIC16F877A. My feature is to turn off my relay (linked to RC0) whenever the temperature hits 85'C.
Here's a sample program of the subroutine ADC code which is stated as below. I am currently using the same subroutine code with it. In the sample program also, the value of 400 correlates to 40'C, and 350 correlates to 35'C, which is also stated below.
Code:
void read_adc(void)
{
unsigned short i;
unsigned long result_temp=0;
for(i=2000;i>0;i-=1) //looping 2000 times for getting average value
{
ADGO = 1; //ADGO is the bit 2 of the ADCON0 register
while(ADGO==1); //ADC start, ADGO=0 after finish ADC progress
result=ADRESH;
result=result<<8; //shift to left for 8 bit
result=result|ADRESL; //10 bit result from ADC
result_temp+=result;
}
result = result_temp/2000; //getting average value
}
unsigned short read_temp(void)
{
unsigned short temp;
temp=result;
return temp;
}
Code:
if((tempA>400)&&(tempB<350))
{ //*LED A and Fan A activated only for
ledA=1; //*temperature A greater than 40'C*
ledB=0; //*and temperature B less than 35'C*
fanA=1;
fanB=0;
buzzer=0;
}
This is the sample program's ADCON0 and ADCON1 settings and mine.
ADCON0
CHANNEL0 0b10000001 // AN0
CHANNEL1 0b10001001 // AN1
ADCON1
0b11000101
Mine
ADCON0
CHANNEL2 0b10010001 //AN2
ADCON1
0b11000011
As far as i have listed, I am using Fosc/64 and right justified.
Now, the problem is when I insert my limit as 850 or as known as 85'C, it NEVER triggers my relay, which meant my limit was too high.
After hours of troubleshooting, i found that by setting the value: 200 as my limit, it TRIGGERS my relay to off at precisely 85'C!
Why is 200 correlating to 85'C and not 850?
Can anyone find out my mistake? I'm still new to the ADC settings, ADCON1, ADCON0 settings and I believe my problem lies there.
Here's my piece of code that sets the limit:
Code:
ADCON0 = CHANNEL2;
read_adc();
temp=read_temp();
tempA=temp;
if(tempA>200)
{
RC0 = 0;
}
Last edited: