Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC code not working. Please help!

Status
Not open for further replies.

isaac12345

Member level 2
Joined
Mar 24, 2010
Messages
47
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,634
Hi,

I'm trying to read the value of a TMP36 temperature sensor with the help of an ADC of the pic16f877a. Below is my code. I'm using the CCS C compiler.

Code:
#include "16F877A.h"
#device ADC=10
#use fast_io(A)

void main() //********************************************
{
	int adc_value;
	int temperature;
	set_tris_a(1); //setting port A to output
	set_adc_channel(0); //channel 0 selected or pin RA0 selected for adc
	setup_adc(ADC_CLOCK_DIV_8);
	setup_adc_ports(RA0_ANALOG);
	output_high(PIN_D1);
	
	adc_value=read_adc(); //read value off adc

	temperature= adc_value/2; //convert adc raw value into temperature in degree celsius
	
	if(temperature>=45) //if temperature is more than specified limits, switch off pin D0
		output_low(PIN_D1);
}

The problem is that the ADC returns such a value that the PIC goes into the IF statement and switches off the pin, even if the temperature read by the TMP36 is less than 45C. Is this problem due to some configuration of the ADC that I've missed?
 

I don't have time to review ur code but you can test ur in debug mode and see where is the problem.

Regards
Chanchal
 

Your problem is in your calculation of the temperature. I may be gravely misunderstanding something, but I'm not sure where you got the idea that dividing the output of the ADC by two will give you the temperature. Looking at the TMP36 datasheet, the voltage/temperature curves don't show that.

Assuming you are using the ADC as as most do (i.e. TMP36 output is connected directly to the analog pin of the uC), and you are driving the circuitry with 5V, the ADC will output 0 when the TMP36 is outputting 0 volts, and it will output 1023 when the TMP36 is outputting 5 Volts.

Your circuitry will turn off the LED when the ADC value is greater than 90. 90/1023 x 5V is 0.44 volts. Figure 6 on page 5 of the TMP36 datasheet says that when the TMP36 is outputting 0.44 volts, it is measuring a temperature of around -10 degrees Celsius. Unless you are measuring inside a freezer or are outside somewhere very south in the southern hemisphere right now, it will always measure more than -10 and your light will always be off.

r.b.
 

Thanks for the replies. I did realise that there was a problem with my temperature calculation and changed the code to the following. The problem now is that the PIC doesnt go into the IF statement at all.
Code:
#include "16F877A.h"
#device ADC=8 //will return 8bit integer
#use delay(clock=4000000)

void main() //********************************************
{
	INT8 adc_value_int8; 
	float temperature;
	float resolution = 5/255;
	set_adc_channel(0); //channel 0 selected or pin RA0 selected for adc
	setup_adc(ADC_CLOCK_INTERNAL);
	setup_adc_ports(RA0_ANALOG);
	output_high(PIN_D1);
	
	delay_ms(1000);
	adc_value_int8=read_adc(); //read value off adc
	(float)temperature = adc_value_int8*(float)resolution; //convert adc value into volts (5V ref,10bit resolution)
	(float)temperature = (((float)temperature-0.75)*100)+25; //convert volts into *C for TMP36
	if((float)temperature>10) //if temperature is more than specified limits,
		output_low(PIN_D1); // switch off pin D1

}

I would appreciate some help with the 'ADC value to volts to temperature' conversion.
 

CCS depands on variables mounting a lot try HITECH or C18.
 

Have you tried to test a simple program.just read the adc value and display it on the hyperterminal

Code:
#device adc=10

void main()
{
   float adc1,adc2,adc3;
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   while(1)
  {
   set_adc_channel(0);
   delay_ms(10);
   adc1=read_adc();
   adc2=(adc1*5)/1023;//for your voltage conversion
   printf("adc1=%f\r\n",adc2);
   delay_ms(500);
  }
}
If this works then you add this
Code:
float range=10.0;
if(adc2>=range)
{
 output_low(PIN_D1);
}
else
{
 output_high(PIN_D1);
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top