View previous topic :: View next topic |
Author |
Message |
jpm
Joined: 09 Apr 2006 Posts: 5
|
ADC - how do I read AN0 and AN1 simultaneously? |
Posted: Sun Apr 09, 2006 5:31 am |
|
|
Hi, I am a newbie in PIC programming and CCS C, I doing a simple routine to read analog output from sensors via PIN AN0 and AN1 -> convert them to digital values and compare which is higher - AN0 or AN1. I am using 16F877A and CCS C 2.235
Inputs of AN0 will be stored in variable temp0 and while AN1 will be stored in temp1.
Code: | set_tris_a(ALL_IN) ;
set_tris_d(ALL_OUT); // MOTOR PORTS SET AS OUTPUT
PORTD=0; // set all pins to low
set_tris_b(ALL_OUT);
PORTB=0; // set all pins to low
setup_port_a( ALL_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );
delay_us(10);
temp0=read_adc() ;
set_adc_channel( 1 );
delay_us(10);
temp1=read_adc() ; |
I am not getting the correct outputs and I am wondering if there is something wrong with the code. Please do correct me of any mistakes. Would appreciate advices from the pros around here. |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Sun Apr 09, 2006 5:37 am |
|
|
Can you post your #fuse settings and are you operating in 8 or 10 bit ADC mode ?
What values are you expecting and what values do you actually get ? _________________ Regards,
Simon. |
|
|
jpm
Joined: 09 Apr 2006 Posts: 5
|
|
Posted: Sun Apr 09, 2006 6:03 am |
|
|
Hi,
These are my fuse and other relevant configurations
Code: | #include <16F877A.H>
#device ADC=10 *=16
#case
#fuses HS,NOWDT,NOPROTECT, BROWNOUT, NOLVP, PUT
#use DELAY(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#define RUN_BUTTON PIN_B7
#define RUN_LED PIN_B6
#define USER_LED PIN_D0
#define ALL_OUT 0
#define ALL_IN 0xFF
#byte PORTB=6
#byte PORTD=6 |
I am expecting a +5V output but I am only getting 0V. The other output pins (status LEDs etc) works fine. |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Sun Apr 09, 2006 6:43 am |
|
|
You also need to post the bit of code that is doing the actual output !!! or a complete program that shows the problem.
All you have supplied is the reading of ADC's, and some of the I/O setup code ... a bit more is required if you are having problems at the output stage. _________________ Regards,
Simon. |
|
|
jpm
Joined: 09 Apr 2006 Posts: 5
|
|
Posted: Sun Apr 09, 2006 7:25 am |
|
|
Sorry sorry, my bad....I thought posting the full code will make everything very lengthy.
Code: | #include <16F877A.H>
#device ADC=10 *=16
#case
#fuses HS,NOWDT,NOPROTECT, BROWNOUT, NOLVP, PUT
#use DELAY(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#define RUN_BUTTON PIN_B7
#define RUN_LED PIN_B6
#define USER_LED PIN_D0
#define ALL_OUT 0
#define ALL_IN 0xFF
#byte PORTB=6
#byte PORTD=6
int temp0=0;
int temp1=0;
int temp3=0;
void main()
{
if (input(RUN_BUTTON) )
{
output_high(RUN_LED);
output_high(USER_LED);
while (TRUE)
{
set_tris_a(ALL_IN) ;
set_tris_d(ALL_OUT); // MOTOR PORTS SET AS OUTPUT
PORTD=0; // set all pins to low
set_tris_b(ALL_OUT);
PORTB=0; // set all pins to low
setup_port_a( ALL_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );
delay_us(10);
temp0=read_adc() ;
set_adc_channel( 1 );
delay_us(10);
temp1=read_adc() ;
output_high(PIN_B6) ; //Run LED
output_high(PIN_D0) ; //User LED
temp3=temp0-temp1 ;
if (temp3 > 1) // turn left
{
output_high(PIN_B3) ; //MD11
output_low(PIN_B5) ; //MD12
output_low(PIN_B0) ; //MD21
output_high(PIN_B2) ; //MD22
output_high(PIN_D4) ; // turn fan ON
output_low(PIN_D6) ;
}
if (temp3 < 1) //turn right
{
output_low(PIN_B3) ; //MD11
output_high(PIN_B5) ; //MD12
output_high(PIN_B0) ; //MD21
output_low(PIN_B2) ; //MD22
output_high(PIN_D4) ; // turn fan ON
output_low(PIN_D6) ;
}
if (temp3 >0 && temp3 <1 ) // go straight
{
output_high(PIN_B3) ; //MD11
output_low(PIN_B5) ; //MD12
output_high(PIN_B0) ; //MD21
output_low(PIN_B2); //MD22
output_high(PIN_D4) ; // turn fan ON
output_low(PIN_D6) ;
}
}
}
}
|
It is a simple robot that seeks out the light of a candle in a dark room and then puts it out with a DC motor fan (LM35 thermistors are too slow to react). I am cheating a bit here but it's alright, it's just for demonstration. |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Sun Apr 09, 2006 7:30 am |
|
|
You are using
Code: | int temp0=0;
int temp1=0;
int temp3=0;
|
which are 8 bit ints (-127 to +127) to store a 10 bit (0 to 1024) value in !!! Change these to int16 and give it a try.
I also hope that you have a hardware driver on the pin that is driving the fan !
You also need to change the logic of the temp3 'if' statements to use 'else if' and re-arrange them so that only ONE thing happens based on temp3.
What is supposed to happen for a temp3 value of 0.5 ?? go straight or turn right !!!!!
you could remove temp3 and make things easier to read.
example ...
Code: |
if (temp0 > temp1)
{
// do something
}
else if (temp0 < temp1)
{
// do something else
}
else
{
// do the other thing
}
|
_________________ Regards,
Simon. |
|
|
jpm
Joined: 09 Apr 2006 Posts: 5
|
|
Posted: Sun Apr 09, 2006 9:45 am |
|
|
Quote: | I also hope that you have a hardware driver on the pin that is driving the fan ! |
Yups I have a set motor drivers for all the DC motors, I didn't realize that there is a data type int16. Thanks for the tip, will modify my code accordingly now.
Thanks again. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Apr 09, 2006 12:44 pm |
|
|
Quote: | which are 8 bit ints (-127 to +127) to store a 10 bit (0 to 1024) value in |
Not true for CCS. An int by default is 0-255 (which is still not big enough). For a signed int, you must specify "signed int" to get -127 to 127 |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Sun Apr 09, 2006 2:54 pm |
|
|
thanks Mark, but I bet you missed my other gross error
Quote: |
What is supposed to happen for a temp3 value of 0.5 ?? go straight or turn right !!!!!
|
if temp3 is an int or int16 it will never be 0.5 !!!
having said that ...
Code: | if (temp3 >0 && temp3 <1 ) // go straight
|
will NEVER be true. _________________ Regards,
Simon. |
|
|
jpm
Joined: 09 Apr 2006 Posts: 5
|
|
Posted: Sun Apr 09, 2006 3:21 pm |
|
|
Quote: | you could remove temp3 and make things easier to read.
example ...
Code:
if (temp0 > temp1)
{
// do something
}
else if (temp0 < temp1)
{
// do something else
}
else
{
// do the other thing
} |
Actually the reason I made 1 as a reference is because I am just currently prototying the sensors (LDR) on a vero board, and I can't get the sensors to calibrate properly to give the same reading. A difference of 0.1V between the different sensors output are inevitable unless I do some elaborate stuff to calibrate them - which I do not have the time nor the interest to undertake at this point of time.
So the value 1 was placed there as some sort of a 'margin' to compensate for the error. Come to think of it...wouldn't it be better if i were to change them to float or double?
Thanks for the tip everybody, this is a very useful place to learn abt uC. |
|
|
|