|
|
View previous topic :: View next topic |
Author |
Message |
Horizons
Joined: 03 Apr 2006 Posts: 4
|
Multiple ADC inputs on a PIC 18F2520 |
Posted: Mon Apr 03, 2006 4:38 pm |
|
|
I am having trouble using multiple ADC inputs. I am referencing the High voltage lvl for the ADC to 3.3V because I will have IR sensors with a max output of 3.3V and I need as close to 100% resolution as possible.
The trouble I am running into is using multiple ADC channels and getting full resolution as I vary the voltage on the input. Each ADC channel works perfectly if it is the only channel being used in the program.
But when I have it change between channels the outputed values are not correct. I should see varying voltages between 0-255 as I ramp up the voltage to 3.3V on the input but instead I am hitting 255 as soon as 1V or so. The printf statements are used to send the value out the UART to be sent across bluetooth. The third ADC input is used to know when voltage level is crossed to start checking the ADC sensor inputs.
I am using version 3.242 of the compiler.
Any help will be appreciated.
Code: |
#include<18F2520.h>
#device adc=8
#fuses NOWDT,NOMCLR,INTRC_IO,NOPBADEN,NOBROWNOUT,PUT,NOLVP
#use delay(clock=1000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
void main()
{
int sensor0, sensor1, trigger;
setup_oscillator(OSC_1MHz);
//adc setup
setup_adc_ports(ALL_ANALOG | VSS_VREF); //sets voltage ref to 0V - 3.28V
setup_adc(ADC_CLOCK_INTERNAL);
delay_ms(200);
while(true)
{
set_adc_channel(2);
delay_us(1000);
trigger = read_adc();
printf("trigger: %u\n\r",trigger);
while(trigger > 180) // goes into statment if voltage is above 2.4V
{
trigger=0;
delay_ms(1000);
set_adc_channel(0); //to read a voltage comming from IR Distance Sensor 1
delay_us(1000);
sensor0 = read_adc();
set_adc_channel(1); //to read a voltage comming from IR Distance Sensor 2
delay_us(1000);
sensor1 = read_adc();
if(sensor0>=sensor1) //output highest value between the two sensors
{
printf("Sensor 0: %u\n\r",sensor0);
}
else
{
printf("Sensor 1: %u\n\r",sensor1);
}
sensor1=0;
sensor0=0;
set_adc_channel(2); //to read a voltage comming from IR Distance Sensor 1
delay_us(1000);
trigger = read_adc();
delay_ms(500);
}
}
}
|
Last edited by Horizons on Mon Apr 03, 2006 7:35 pm; edited 2 times in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 03, 2006 5:28 pm |
|
|
Where does the Vref+ voltage on pin A3 for the A/D converter come from ?
Did you know that there is no internal connection between the A/D
converter and the Vref module ?
However, the Vref module can be configured to put the Vref voltage
out on Pin A2. You can connect pins A2 and A3 externally.
The reference manual says that Pin A2 should be configured as a
digital input pin when used for Vref output. The PIC comes up
in that condition upon power-on reset, so it should work OK.
Note that the option to have Vref go out on Pin A2 is wrongly
called "VREF_F5" in the 18F2520.H file. It should be called "VREF_A2".
Also, I recommend that you check the Vref voltage on Pin A2
with a voltmeter to make sure that it's the correct voltage. |
|
|
Horizons
Joined: 03 Apr 2006 Posts: 4
|
|
Posted: Mon Apr 03, 2006 7:03 pm |
|
|
I have the vref+ pin tied to the output of a 3.3 volt regulator and that fixed the resolution problem. However, when I run the program it only reads the first adc (channel 2). The results of the other two are always constant values around 200 (8 bit adc setting). Any ideas what I could be doing wrong? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 03, 2006 7:21 pm |
|
|
Remove the ADC_READ_ONLY parameter on Channel 0. |
|
|
Horizons
Joined: 03 Apr 2006 Posts: 4
|
|
Posted: Mon Apr 03, 2006 7:32 pm |
|
|
we tried that and have removed it, the microcontroller will still only read the first channel(2) correctly |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 03, 2006 7:58 pm |
|
|
Try the following program, in which I have removed all your if()
statements. I've tried to keep as much of your program as possible.
It just reads the three A/D channels and displays them. Also, I've gotten
rid of the internal A/D clock and put in one derived from the oscillator
instead, per the data sheet.
Code: |
#include<18F2520.h>
#device adc=8
#fuses NOWDT,NOMCLR,INTRC_IO,NOPBADEN,NOBROWNOUT,PUT,NOLVP
#use delay(clock=1000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
void main()
{
int8 result;
setup_oscillator(OSC_1MHz);
setup_adc_ports(ALL_ANALOG | VSS_VREF);
setup_adc(ADC_CLOCK_DIV_2);
delay_ms(200);
while(1)
{
set_adc_channel(0);
delay_us(1000);
result = read_adc();
printf("Channel 0: %u\n\r", result);
set_adc_channel(1);
delay_us(1000);
result = read_adc();
printf("Channel 1: %u\n\r", result);
set_adc_channel(2);
delay_us(1000);
result = read_adc();
printf("Channel 2: %u\n\r", result);
printf("\n\r");
delay_ms(500);
}
} |
|
|
|
Horizons
Joined: 03 Apr 2006 Posts: 4
|
|
Posted: Tue Apr 04, 2006 1:26 pm |
|
|
Thanks for your help, I appreciated it. Problem turned out to be with the ground that our sensors were sharing. The adc's work great now!! |
|
|
|
|
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
|