View previous topic :: View next topic |
Author |
Message |
azykazy
Joined: 05 Oct 2011 Posts: 11 Location: South Africa
|
adc help |
Posted: Thu Nov 03, 2011 7:03 am |
|
|
Hi All,
I am trying to measure the voltage across a battery using the adc using a voltage divider network. Pic 18f4550 +Vref is +5v -Vref is ground. My ADC is not working any ideas whats wrong?
Code: |
#include<18f4550.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main(void)
{
int16 adc_value;
float32 volts;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_4);
set_adc_channel(0);
delay_us(20);
do{
read_adc(ADC_START_ONLY);
adc_value = read_adc(ADC_READ_ONLY);
volts = (float)(adc_value * 5)/1023.0;
if (volts > 12) output_high(PIN_D0);
if (volts < 12 && volts > 11){
output_high(PIN_D1);
output_low(PIN_D0);
};
if(volts < 11) {
output_high(PIN_D2);
output_low(PIN_D1);
};
}while(TRUE);
}
|
Compiler version is 4.093.
Thanks,
Azmat |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Nov 03, 2011 7:13 am |
|
|
1) Check the voltage on the A/D pin with a voltmeter to see if it is what you expect.
2) Print the A/D counts you get from read_adc() to make sure they are what you expect.
3) Tell us what results you expect and what results you are getting. "My ADC is not working" is not very helpful.
4) I suspect your line:
volts = (float)(adc_value * 5)/1023.0;
should be:
volts = ((float)adc_value * 5)/1023.0;
I suspect (adc_value * 5) is overflowing before it gets converted to a float. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Nov 03, 2011 7:15 am |
|
|
several things....
1) the ADC will NOT tolerate +12 volts on it !! In fact the PIC will NOT be happy and you may destroy it.
You MUST design and install a voltage divider to reduce the +12 to no more than +5 volts.The max the PIC ADC can read is +5,so the divider will allow the PIC to 'think' a +5 reading is your +12, +2.5 will be +6,etc.
When you design the voltage divider, be sure to use the MAXIMUM the battery will be. '12 volt' batteries usually are anywhere from 13.2 to 14.6 depending on the type they are.
2) your equation for calulating the battery voltage will have to be 'tweaked' by the ratio of the voltage divider to all it to display the real voltage.
3) your IF statements will require 12.0 not 12, 11.0 not 11. The compiler may think 12 is an integer not a float. |
|
|
azykazy
Joined: 05 Oct 2011 Posts: 11 Location: South Africa
|
|
Posted: Thu Nov 03, 2011 7:49 am |
|
|
I need to measure the battery voltage.
I have the appropriate voltage divider network in place and when the battery is at its peak 14V the voltage on adc is +5V.
How do I get a read out on the adc values? |
|
|
Battery David
Joined: 01 Feb 2010 Posts: 25
|
|
Posted: Thu Nov 03, 2011 8:46 am |
|
|
What resistor values are you using for your voltage divider? If they are too high, the ADC can't read it properly. There are a bunch of posts on that topic you can search for.
Something you didn't ask for but I'll volunteer anyway:
Rather than doing floating point math, figure out what ADC value you would get for the voltages you're interested in. Use those to compare, rather than the floating points. The code savings and speed improvements will be considerable. |
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
Re: adc help |
Posted: Thu Nov 03, 2011 10:32 am |
|
|
azykazy wrote: | Hi All,
I am trying to measure the voltage across a battery using the adc using a voltage divider network. Pic 18f4550 +Vref is +5v -Vref is ground. My ADC is not working any ideas whats wrong?
Code: |
#include<18f4550.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main(void)
{
int16 adc_value;
float32 volts;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_4);
set_adc_channel(0);
delay_us(20);
do{
read_adc(ADC_START_ONLY);
adc_value = read_adc(ADC_READ_ONLY);
volts = (float)(adc_value * 5)/1023.0;
if (volts > 12) output_high(PIN_D0);
if (volts < 12 && volts > 11){
output_high(PIN_D1);
output_low(PIN_D0);
};
if(volts < 11) {
output_high(PIN_D2);
output_low(PIN_D1);
};
}while(TRUE);
}
|
Compiler version is 4.093.
Thanks,
Azmat |
hi all what say for this
Code: | int1 done; // Put local variable at beginning of code block
int x; // Number of times to average ADC value
int32 temp_result;
set_adc_channel(0); // Select AN0
// Average ADC value
temp_result = 0;
for (x=1; x<=ADC_AVERAGE_COUNT; x++)
{
delay_ms(ADC_DELAY); //Charge capacitor
read_adc(ADC_START_ONLY); //Do A/D conversion
done == adc_done();
while(!done) {
done = adc_done();
}
temp_result += read_adc(); // Read A/D register . Pin A0 in an input
delay_ms(ADC_2TAD); // Wait 2 TADs before doing another A/D conversion
}
ADC_Value = temp_result / ADC_AVERAGE_COUNT;
tlong = (int32)ADC_Value*5000; //Convert the result in millivolts
tlong = tlong/1023; // 0..1023 -> 0-5000mV
ch = tlong/1000; // Extract volts (thousands of millivolts
volts =ch*fx // fx= voltage divider network factor |
now Ur requirement code
Code: | if (volts > 12) output_high(PIN_D0);
if (volts < 12 && volts > 11){
output_high(PIN_D1);
output_low(PIN_D0);
};
if(volts < 11) {
output_high(PIN_D2);
output_low(PIN_D1); |
_________________ sahu |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Nov 03, 2011 11:01 am |
|
|
Quote: | do{
read_adc(ADC_START_ONLY);
adc_value = read_adc(ADC_READ_ONLY);
|
This is unnecessary. You can replace it with:
Code: |
adc_value = read_adc();
|
Quote: | volts = (float)(adc_value * 5)/1023.0;
|
read_adc() will produce values from 0 to 1023.
Therefore, the maximum value the equation above will produce is 5.0 volts.
Quote: | if (volts > 12) output_high(PIN_D0);
if (volts < 12 && volts > 11){
|
Here you are comparing volts, which can be 5.0 max, to 12.
This code will never set Pin D0 to a high level. |
|
|
azykazy
Joined: 05 Oct 2011 Posts: 11 Location: South Africa
|
|
Posted: Fri Nov 04, 2011 2:22 am |
|
|
Thanks for the advice people.
PCM thanks for pointing that volts error out to me. Brilliant!
I am using the corresponding adc values to compare so the pic doesnt have to do unnecessary math calculations.
Thanks for the help guys much appreciated!
Azmat |
|
|
|