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

adc help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
azykazy



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

adc help
PostPosted: Thu Nov 03, 2011 7:03 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 03, 2011 7:13 am     Reply with quote

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: 9228
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Nov 03, 2011 7:15 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Thu Nov 03, 2011 7:49 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 03, 2011 8:46 am     Reply with quote

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

View user's profile Send private message

Re: adc help
PostPosted: Thu Nov 03, 2011 10:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 03, 2011 11:01 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Nov 04, 2011 2:22 am     Reply with quote

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! Cool Very Happy

Azmat
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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