View previous topic :: View next topic |
Author |
Message |
feitanx
Joined: 21 Mar 2010 Posts: 37
|
How to multiplex the adc channel on this code |
Posted: Fri May 28, 2010 2:23 am |
|
|
Code: | #include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOCPD,NOBROWNOUT
#device *=16 ADC=8
#use delay(clock=4000000)
#use rs232(uart1,baud=9600,xmit=PIN_C6,rcv=PIN_C7,PARITY=N,BITS=8,STOP=1)
#use STANDARD_IO(D)
#use STANDARD_IO(A)
#use STANDARD_IO(C)
#bit ADFM_BIT = 0x9F.7
void main(void){
int8 V,V1;
int16 V2;
ADFM_BIT = 1;
setup_adc_ports(A_ANALOG_RA3_REF);
setup_adc(ADC_CLOCK_DIV_32);
for(;;){
for(V=1;V<=40;V++)
V2=0;
{
set_adc_channel(0);
V2+=read_adc();
delay_ms(300);
}
V1=V2/40;
//output_d(V1);
printf("%2u", V1);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri May 28, 2010 2:49 am |
|
|
Several comments:
You set V2=0 as the only operation inside your for loop. Means it won't contain the sum...
You need to set V2=0 _once_ outside the summing loop.
Then to use multiple ADC channels, sequence is always the same:
1) Select the channel.
2) Delay for the ADC aquisition time.
3) Read the channel.
So, something like:
Code: |
for(;;){
V2=0;
V3=0; //Initialise the value _outside_ the summing loop
for(V=1;V<=40;V++) {
set_adc_channel(0);
delay_us(10); //aquisition time
V2+=read_adc();
set_adc_channel(1);
delay_us(10);
V3+=read_adc();
delay_ms(300);
}
V0=V2/40;
V1=V3/40;
printf("%2u %2u", V0,V1);
}
|
You will need suitable declarations for V0, and V3 obviously.
Best Wishes |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Fri May 28, 2010 10:00 am |
|
|
when I initialize before the summing loop the answer is different When I initialize after the for(V=1;V<=10;V++) and before the brace. why? which one more correct? when I initialize after the for(V=1;V<=10;V++) and before the brace the answer seem to be more correct. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri May 28, 2010 10:07 am |
|
|
If you initialise inside the summing loop as you show, V2, will only contain _one_ reading. The summing loop will effectively do nothing, and you just get the last reading. Then you divide this by 40.
To get the sum, you must initialise before the loop.
If the value from the former appears 'more correct', then something is wrong with the voltage coming in, or your assumptions of what the value will be.
Best Wishes |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Fri May 28, 2010 7:46 pm |
|
|
Why is it that if I set only two variables before the loop the answer is right but if set the three variable before the loop the answer is wrong(big answer)?
Last edited by feitanx on Fri May 28, 2010 9:51 pm; edited 1 time in total |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Fri May 28, 2010 8:10 pm |
|
|
I use 3 variable before the summing loop by the way |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Sat May 29, 2010 6:13 am |
|
|
Please help me, My problem is when I have 3 variable(V2,V4,V6) before the loop answer is wrong:
Code: |
#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOCPD,NOBROWNOUT
#device *=16 ADC=8
#use delay(clock=4000000)
#use rs232(uart1,baud=9600,xmit=PIN_C6,rcv=PIN_C7,PARITY=N,BITS=8,STOP=1)
#use STANDARD_IO(D)
#use STANDARD_IO(A)
#use STANDARD_IO(C)
#bit ADFM_BIT = 0x9F.7
void main(void){
int8 A,A1,B1,C1;
int16 V2,V4,V6;
ADFM_BIT = 1;
setup_adc_ports(A_ANALOG_RA3_REF);
setup_adc(ADC_CLOCK_DIV_32);
for(;;){
V2=0;
V4=0;
V6=0;
for(A=1;A<=40;A++)
{
set_adc_channel(0);
delay_us(150);
V2+=read_adc();
set_adc_channel(1);
delay_us(150);
V4+=read_adc();
set_adc_channel(2);
delay_us(150);
V6+=read_adc();
delay_ms(150);
}
A1=V2/40;
B1=V4/40; //output_d(C1);
C1=V6/40;
printf("%2u\n", A1);
printf("%2.2u\n", B1);
printf("%2u\n" ,C1);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat May 29, 2010 1:49 pm |
|
|
Quote: |
My problem is when I have 3 variable(V2,V4,V6) before the loop answer is wrong.
|
1. Tell us the answer that you expect to see, and tell us what you are
getting. How do you know the answer is wrong ?
2. Are you testing this in hardware or in Proteus ?
3. What is your compiler version ? |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Sun May 30, 2010 6:56 am |
|
|
1. I expect to see voltage reading in single digit like 3 , 1 etc..
Instead I'am getting 150, 120 and etc..
I supply the analog pin with a measured voltage and it is so different with the result
2. I'am testing this in hardware
3. I'am using PCWHD Version 4.078
please help |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sun May 30, 2010 7:44 am |
|
|
Your A/D should return a value between 0 and 255. If you sum this 40 times and divide by 40 you will get a value between 0 and 255.
Consider what reference and signal voltages you are applying to the A/D and what numbers you expect it to return. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Sun May 30, 2010 7:26 pm |
|
|
When I use only 2 variable (V2, V4 or V6) the answer is what I expect, but I use 3 the answer is big and what I expected.
For example I inputted 3v but the output is 105.
What's wrong in initializing 3 variables to the loop? Where did I make the mistake? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun May 30, 2010 11:09 pm |
|
|
I don't see a problem in your code. May be V4.078 (a rather old version) has a problem, but I'm not aware of. You can printout intermediate values during program execution and see what's going on. Or use a debugger. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon May 31, 2010 4:05 am |
|
|
For example:
- Supply voltage is 5V
- Vref=4V
- AN2 = 3V
Expected reading is then: (3V/4V) * 255 = 191
What is the supply voltage to your PIC?
What is the voltage to the Vref pin (Pin A3)?
What is the analog (test) voltage you provide? And the reading you get? |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Mon May 31, 2010 6:24 am |
|
|
supply voltage is 5
Vref is 5
AN2 is 3v
EXPECTED READING for 1.5v--->(1.5/5)*255=76.9
readings=73
FOR 3v
(3/5)*255=153
readings=148 |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon May 31, 2010 7:49 am |
|
|
Quote: | EXPECTED READING for 1.5v--->(1.5/5)*255=76.9
readings=73 | (1.5/5)*255=76.5
73/76.5 *100% = 4.6% error
Quote: | FOR 3v
(3/5)*255=153
readings=148 | 148/153 * 100% = 3.3% error
So with this we can say your question has changed to "How can I get a more accurate reading?"
Possible causes:
1) The ADC is not perfect. See the datasheet table 17-14. You can have a few LSb offset and at lower voltages this is a relative large % error.
2) Is the source impedance of your analog signal < 2.5kOhm?
3) How accurate is your measurement of the input voltage? Cheap voltage meters will introduce an error
4) How stable is the input voltage? Is it decoupled, etc?
5) How stable is the power supply voltage? No ripple, 100nF close to the PIC, etc.
6) What is the reading if you connect the Vref pin to the PIC 5V power supply? It should read 255.
7) Why are you using the Vref pin if it is the same voltage as the PIC is running? You can save 1 I/O pin here.
More tips can be found searching this forum. Personally I like Google better than the search function provided by the forum. Go to Google and type: "site:ccsinfo.com read_adc accuracy" (without the quotes) |
|
|
|