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 support@ccsinfo.com

adc calculations

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







adc calculations
PostPosted: Fri Jul 07, 2006 3:19 pm     Reply with quote

hi
i've got problem with converting adc value cause i'm not sure what kind of variable to use
here is my code
Code:

#include <18F458>
//#define adc=10
#fuses HS, NOWDT, PUT ,nolvp
#use delay(clock=1000000)

#include <math>
#include <flex_lcd>   

int16 result1;

int32 accx;




 void main()
 {
 lcd_init();
 lcd_init();
 delay_ms(200);
 setup_adc_ports(ALL_ANALOG);
 setup_adc(ADC_CLOCK_DIV_64);

delay_ms(200);
while(true)
{

set_adc_channel(0);
   delay_us(1000);
   result1=0;
   result1 = read_adc();
   accx=0;
   accx=((result1*15.68)-8035);
//calculation to transform the adc_number to acceleration
   printf(lcd_putc , "\fAcc X: %06u", accx);
   
}


the formula i want to use is ((adc-value*15.68)-8035)=accx
(i wanted to avoid the floating point but stil no luck Sad
(which is acceleration going from -5000mg to +5000mg ; (the adxl320 sensor gives 0,94V(at -5G) to 4,06(at+5G acceleration)

so the question is where i am wrong- with the type of accx or the format( i tried with float but the numbers that came out had no sense) or smt else

10x in advance
Martin
Bulgaria
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Fri Jul 07, 2006 5:08 pm     Reply with quote

I would use

accx = ((read_adc() - midscale)*1568)/100;

where midscale is whatever the A/D reads for zero acceleration, probably something close to 2048 for a 12 bit A/D.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Ttelmah
Guest







PostPosted: Sat Jul 08, 2006 2:43 am     Reply with quote

I might modify this to cast the adc result to a signed int32 though. Otherwise the arithmetic is almost sure to wrap.

Best Wishes
martines
Guest







still problem
PostPosted: Sat Jul 08, 2006 5:23 am     Reply with quote

ok
the formula i'm using is (((adc_num*1000)/64) - 8000)=result(in mG)
Code:


    int32 result1;
    int32 result2;
    int16 x;
    int16 y;
    float accx;
    Float accy;
    int8 i;


void main()
{

   setup_adc_ports(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);

   lcd_init();
 lcd_init();
 delay_ms(200);


 while(true)
 {

   set_adc_channel(0);
   delay_us(1000);
   result1=0;
   for(i=1;i<=8;i++)
   result1+= read_adc();
   result1/=8;                           /8samples of the adc and dev by8

 
   
   result1=(result1*1000);
   result1=(result1/64)           
//works so far ,shows 00000-15000mG (but the zeroG should be around 2.5V so i need to subtract by smt around 7500

   result1=(result1-8000);   
   accx=result1;

      printf(lcd_putc  ,"\fAcc.X: %03.0f", accx);               
   
      printf(lcd_putc,"mG");
     delay_ms(100);
}
}

the problem comes when i try to substract "result1" with a constant number

if i apply 5V on AN0 channel -shows 7000mG which is ok but if i grounded
shows -256 ?????? its obvious that the problem is with the negative numbers and i need help to solve it Rolling Eyes

10x
p.s the other probllem is that if i increase yhe delay time in the last code line to lets say 300ms and the PIC stops working Confused
Ttelmah
Guest







PostPosted: Sat Jul 08, 2006 7:04 am     Reply with quote

Multiple things.
The result values, need to be _signed_ int32 values, if the result is ever going to go below zero.
Don't fiddle around converting to float. This implies the printf arithmetic, has to be done in floating point, and will be large/slow. Leave the value as an integer, and use %03ld, or if you want it to display in 'G' (rather than mG), use %04.3w, which will scale the output by 1000.
Also, as an aside, put the 'mG' into the same printf statement. Each seperate 'constant' string, incurs an overhead for it's header.

Best Wishes
martines
Guest







10x
PostPosted: Sat Jul 08, 2006 10:22 am     Reply with quote

@Ttelmah

its workinggggggggg Very Happy Smile Smile Smile
10x a lot ,

and if its not rude another question : waht has to be done to slow down the refreshing rate of the lcd (lets say 3-4-5 times per second)

10x again
Ttelmah
Guest







PostPosted: Sat Jul 08, 2006 10:41 am     Reply with quote

I'd suggest putting a delay in the ADC reading loop. As it stands,you pause for 1mSec, then take eight ADC readings (only takes perhaps 0uSec each), then do the maths, output the data,and pause another 100mSec. Now you don't show the chip's clock rate, so the exact times can't be worked out, but obviously faster than you want. You can obviously increase the delay after the display to any vaue you want, but a slight delay between the ADC readings might also be worth considering.
As another comment, be aware, that ADC_CLOCK_INTERNAL, is _not_ recommended on many chips running at faster clock rates. You may want to use another source, depending on your master clock.

Best Wishes
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