CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

How to multiplex the adc channel on this code
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
feitanx



Joined: 21 Mar 2010
Posts: 37

View user's profile Send private message Yahoo Messenger

How to multiplex the adc channel on this code
PostPosted: Fri May 28, 2010 2:23 am     Reply with quote

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: 19513

View user's profile Send private message

PostPosted: Fri May 28, 2010 2:49 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Fri May 28, 2010 10:00 am     Reply with quote

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: 19513

View user's profile Send private message

PostPosted: Fri May 28, 2010 10:07 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Fri May 28, 2010 7:46 pm     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Fri May 28, 2010 8:10 pm     Reply with quote

I use 3 variable before the summing loop by the way
feitanx



Joined: 21 Mar 2010
Posts: 37

View user's profile Send private message Yahoo Messenger

PostPosted: Sat May 29, 2010 6:13 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat May 29, 2010 1:49 pm     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Sun May 30, 2010 6:56 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun May 30, 2010 7:44 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Sun May 30, 2010 7:26 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun May 30, 2010 11:09 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 31, 2010 4:05 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Mon May 31, 2010 6:24 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 31, 2010 7:49 am     Reply with quote

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)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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