Novice : Need help to use ADC to measure 0 - 15V voltage

General discussion on mikroC.
Author
Message
crocu
Posts: 71
Joined: 18 Jun 2008 09:28
Location: France, Macon

Novice : Need help to use ADC to measure 0 - 15V voltage

#1 Post by crocu » 02 Feb 2010 10:45

Hello


Can someone put me on the way to use AN0 with 16F876A , i would like to measure a voltage from 0V to 15V and display the result on a LCD.

Can you show me a code example that would set RA0 as AN input and do calculations for display the measured voltage ?

I will appreciate your help,
Many thanks,

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#2 Post by kottaho » 02 Feb 2010 13:07

Hello crocu,

Check the mikroC ADC to LCD example. the PIC you are using will determine your register settings.

the only difference from the example is that you want to measure 15 volts, and microcontrollers can only handle up till 5V.
so you will have to use a voltage divider circuit (that when max voltage = 15V the voltage at circuit output will be 5V) so that the voltage that will be at the ADC channel pin will vary along as the 15V varies, but will never go beyond 5V (due to your resistors ratio).
KNOWLEDGE IS POWER.

pwdixon
Posts: 1431
Joined: 13 Apr 2005 11:14
Location: UK

#3 Post by pwdixon » 02 Feb 2010 15:23

Do limit the values of your divide resistors as the A/D input has a limited input impedance and your measurements will be corrupted.

crocu
Posts: 71
Joined: 18 Jun 2008 09:28
Location: France, Macon

#4 Post by crocu » 02 Feb 2010 16:03

Regarding impedance, is the following correct ?

Image

If Vcc ( max voltage input ) = 15V and then R1 = 470 ohms & R2 ajustable ~ 235 ohms, Vout max will vary from 0V to 5V.

Is this correct regarding impedance requirements ?


If so, how determinate the ADC occuracy if i proceed with divide resistors ?

Many thanks,

pwdixon
Posts: 1431
Joined: 13 Apr 2005 11:14
Location: UK

#5 Post by pwdixon » 02 Feb 2010 16:50

The PIC datasheet will tell you what the A/D input impedance is so you only need to check that the A/D doesn't load your divider circuit too much.

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#6 Post by kottaho » 02 Feb 2010 21:09

your R2 have to be 1/3 of R1 that is all you need. then just chose the smallest values that you can get. I don't know what the value of the input impedance of the ADC is. but it will entertain average values of resistors. to be sure you can check your datasheet.

the whole thing about impedance is that asume you have two resistors in series if one of them is really bigger than the other most of the power will be dissipated on the one with the most size. It is really noticeable in merging (connecting) pre amplifier to amplifier.
KNOWLEDGE IS POWER.

crocu
Posts: 71
Joined: 18 Jun 2008 09:28
Location: France, Macon

#7 Post by crocu » 02 Feb 2010 21:49

I have designed my schematic as follow :

AN inputs ( max 15V ) will be made with 100 ohm / 33 ohm resistor divider.

Image

I need to monitor 4 x AN inputs, can someone be kind to post a code snippet that would show me how to set the AN inputs and do calculations in order to display the voltages ?

I would like to have the inputs read every second and displayed on a LCD 4 x 20

Many thanks for your help,

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#8 Post by kottaho » 02 Feb 2010 22:00

If the impedance is too big it will take longer time to charge the sampling capacitor of the ADC. and this will result in wrong reading. remember that it is the sampling time that the couter use to determine the value of your input voltage.
KNOWLEDGE IS POWER.

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#9 Post by kottaho » 02 Feb 2010 22:03

I sent these posts before your last post was online.
KNOWLEDGE IS POWER.

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#10 Post by kottaho » 02 Feb 2010 22:23

here below is a funtion that help you to split the value into single digit. you can change the uart to lcd funtion. hope this will help.

Code: Select all

//*************** SplitValue. 
void SplitValue(int value){ 
int buffer=0, firstdigit=0, seconddigit=0, thirddigit=0, fourthdigit=0; 
firstdigit = value/1000; 
buffer = value - firstdigit * 1000; 
seconddigit = buffer / 100; 
buffer = buffer - seconddigit * 100; 
thirddigit = buffer / 10; 
buffer = buffer - thirddigit * 10; 
fourthdigit = buffer; 


UART1_Write(firstdigit + 48); 
UART1_Write(seconddigit + 48); 
UART1_Write(thirddigit + 48); 
UART1_Write(fourthdigit + 48); 
}//end SplitValue 
//******************************************************************* 
Here below is a function that reads adc from three different channels you can adjust it and add the mikroC lcd exaple to it.

Code: Select all


int temp_res;
 
//*************** AccelerometerRead. 
void AccelerometerRead(){ 
// ADCON0.ADON = 1; 
 Delay_ms(1); 
 temp_res =ADC_Read(2);          // get ADC value from channel 2 = RA2 (PORTA.2). 
 temp_res = temp_res * 5;        // multiply reg result with ((5/1024)*1000) = 4.88 . this converts it to milivolts. 
SplitValue(temp_res);  

 Delay_ms(1); 
 temp_res =ADC_Read(3);          // get ADC value from channel 3 = RA3 (PORTA.3). 
 temp_res = temp_res * 5;        // multiply reg result with ((5/1024)*1000) = 4.88 . this converts it to milivolts. 
SplitValue(temp_res);

 Delay_ms(1); 
 temp_res =ADC_Read(4);          // get ADC value from channel 4 = RA5 (PORTA.5). 
 temp_res = temp_res * 5;        // multiply reg result with ((5/1024)*1000) = 4.88 . this converts it to milivolts. 
SplitValue(temp_res);
 
 //ADCON0.ADON = 0; 
}//end AccelerometerRead. 
//******************************************************************* 


If you dont want to include your file
KNOWLEDGE IS POWER.

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#11 Post by kottaho » 02 Feb 2010 22:26

ignore the last line of incomplete sentence in the last post.
KNOWLEDGE IS POWER.

kottaho
Posts: 78
Joined: 18 Nov 2009 10:47
Location: The Netherlands

#12 Post by kottaho » 02 Feb 2010 22:41

Placing an external capacitor from circuit output to ground gets around the problem as it will appear to the adc sampling cap as a low impedance. So for slow signals such as measuring battery voltage, you can use high value resistors in the voltage divider to lessen the power draw and still get the adc accuracy.
10nF or 100nF will work, it would be great to approximate the capacitor size you need.
KNOWLEDGE IS POWER.

crocu
Posts: 71
Joined: 18 Jun 2008 09:28
Location: France, Macon

#13 Post by crocu » 02 Feb 2010 22:51

Thanks for the codes examples, i found from my side this code and i tested it :

Code: Select all

hold = ADC_Read(0);
IntToStr(hold, txt);

LCD_Chr(3,1,5*hold/1024+48);             // first digit
LCD_Chr(3,2,46);                         // display "."
LCD_Chr(3,3,(50*hold/1024)%10+48);       // 2sd digit
LCD_Chr(3,4,(20*hold/41)%10+48); //20/41 =~ 500/1024  // 3rd digit
LCD_Chr(3,5,86);                         // display "V"                                                         
Lcd_Out(4,1,txt);                        // display numeric value
But when i set AN0 to Pic Vcc voltage = 5.20V, AN0 reads = 4.98V
and ADC value displayed is 1022.

Should i not get 5V and 1024 instead, maybe calculations are wrong ?

Then, i also tried to connect 15V input with resistor divider ( 100 ohms / 33 ohms ) and of course occuracy is worst.

Has someone an idea to have better results ?

pwdixon
Posts: 1431
Joined: 13 Apr 2005 11:14
Location: UK

#14 Post by pwdixon » 03 Feb 2010 11:19

A resistor chain of 100 and 33 will produce a divisor of approx 1/4 not 1/3. With the circuit in your diagram you can only get ratios between 1/4 and 0.

Your A/D input will also depend on the output impedance of the analogue signal source of course.

Note the A/D input should not exceed the PIC supply.

pwdixon
Posts: 1431
Joined: 13 Apr 2005 11:14
Location: UK

#15 Post by pwdixon » 03 Feb 2010 11:22

Also, the max ADC value is 1023 not 1024 as the reading is 1024 levels from and including 0.

Post Reply

Return to “mikroC General”