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

Schock and vibrations analysis using adxl330 accelerometer

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



Joined: 29 Jul 2007
Posts: 3

View user's profile Send private message

Schock and vibrations analysis using adxl330 accelerometer
PostPosted: Mon Jul 30, 2007 12:06 am     Reply with quote

I'm a newbie to CCs picc compiler but have good c systems programming background. I'm considering buying dspic kit if this will help with the final year project.

As student my final year project is on recording vibrations and shock using accelerometer. I've at the moment a 16f877a chip & an adxl330 tria-axles accelerometer to use bcoz it gives an anoloque output. I would like to get reading from the three axis of the accelerometer and store them into an array(which could be analized in real time later by microprocessor possibly dspic). The project will build from there whereby I'll be considering using a dspic chip for further data analysis in real time. I've written the following code to calibrate the accelerometer and also simply test if adxl330 works. But it does not work at all. I tried using MPLAB7.6 simulator after commenting out printf() function but nothing seems to work. What am i doing wrong?
thank.


Code:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device adc=10
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

double *x;
double *y;
double *z;
double accel[2];
double adxCalib[2];

const double x_ZeroG=250;   //Zero_G
const double y_ZeroG=250;   //Zero_G
const double z_ZeroG=250;   //Zero_G

void Adxl330_Calibrate()
{
unsigned double adc_x,adc_y, adc_z = 0;
int8 chan;
for (chan=0; chan<2; chan++)
   {
      set_adc_channel(chan);
      adxCalib[chan]=read_adc();
      delay_us(10);
   
   }
      adc_x = adxCalib[0];                  // get ADC value for X channel
      adc_y = adxCalib[1];                  // get ADC value for Y channel
      adc_y = adxCalib[2];                  // get ADC value for z channel
     
      printf("%4d %d4 %4d",adc_x,adc_y,adc_z);
}

//=============================================================================
//  get xyz
//=============================================================================

void Gadxl330getxyz()
{

   int i,j;
    for(j=0; j<256; j++)
     {

   for(i=0;i<2;i++)       //this loop is used to read adc values from channel 0,1,2 etc
   {
             set_adc_channel(chan);
        accel[chan]=read_adc();       //Acceleration z, y, z
           
   }

   x[j]=accel[0] - x_ZeroG;             //Acceleration x
   y[j]=accel[1] - y_ZeroG;            //Acceleration y
   z[j]=accel[2] - z_ZeroG;           //Acceleration z
 
  }
Gvlauesdisplay(x,y,z);
}

void Gvlauesdisplay(double* x, double* y, double* z)
{
   int8 j;
   printf("printing 256 data points acceleration values from x,y,z axis\n\n");
   for(j=0; j<256; j++)
     {
       printf("%4d %d4 %4d",x[j],y[j],z[j]);
     }
}

void main()
{
   setup_adc_ports(ALL_ANALOG);
        setup_adc(ADC_CLOCK_INTERNAL);
    Adxl330_Calibrate();       //use for obtaining x_ZeroG,y_ZeroG,z_ZeroG calibration values

   while(1)
   {
                 delay_Ms(500)
    Gadxl330getxyz();         //will print 256 data points of the x,y,z acceleration values every half a second
   
   }
   
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 30, 2007 12:41 am     Reply with quote

Quote:
int i,j;
for(j=0; j<256; j++)

In CCS, an 'int' is an unsigned 8-bit value. It can only go up to 255.

Turn on the compiler Warnings. Here's what it says about the 'for' line:
Quote:
>>> Warning 203 "C:\Program Files\PICC\Projects\PCM_Test\pcm_test.c" Line 12(1,1): Condition always TRUE

It's an endless loop. It will never exit.
See this post, about looping through all 256 elements with an 8-bit index:
http://www.ccsinfo.com/forum/viewtopic.php?t=30469&start=11


Quote:

double *x;
double *y;
double *z;
x[j]=accel[0] - x_ZeroG; //Acceleration x
y[j]=accel[1] - y_ZeroG; //Acceleration y
z[j]=accel[2] - z_ZeroG; //Acceleration

You've created pointers to doubles x,y,z, but the pointers are never
initialized to point to any array or block of allocated memory.
Then you start using them as arrays. That's not going to work.

Also, in this PIC, you're extremely limited on RAM. You can't do a
'double' array with 256 elements. You can't do even one, let alone three.
The largest array you can have with a 16F877A in CCS is 96 bytes.

If you want large arrays, you need to go to an 18F-series PIC.
Schmittz



Joined: 29 Jul 2007
Posts: 3

View user's profile Send private message

Acceleration
PostPosted: Mon Jul 30, 2007 5:17 am     Reply with quote

Thanks PCM Programmer for your input. This has indeed made it very clear to me now. But I still didn't understand when you mentioned that I cannot used pointers when not initialised. what if I declar my arrays as int8 x[256],y[256],z[256] then cast them to double later on. Will this solve my problem? How can I initialize pointers to arrays in CCS PICC?
I'm definelty going to change the IC to 18f452.
here is modified version of my previous, it still does not work...
Thanks again
Embarassed

Code:
#include <18F452.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOOSCSEN                 //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

int8 x[256];
int8 y[256];
int8 z[256];
double accel[2];
double adxCalib[2];

const double x_ZeroG=250;   //Zero_G
const double y_ZeroG=250;   //Zero_G
const double z_ZeroG=250;   //Zero_G
void Adxl330_Calibrate()
{
unsigned double adc_x,adc_y, adc_z = 0;
int8 chan;
for (chan=0; chan<2; chan++)
   {
      set_adc_channel(chan);
      adxCalib[chan]=read_adc();
      delay_us(10);
   
   }
      adc_x = adxCalib[0];                  // get ADC value for X channel
      adc_y = adxCalib[1];                  // get ADC value for Y channel
      adc_y = adxCalib[2];                  // get ADC value for z channel
     
      printf("%4d %d4 %4d",adc_x,adc_y,adc_z);
}

//=============================================================================
//  get xyz
//=============================================================================

void Gadxl330getxyz()
{

   int i,j;
    for(j=0; j<255; j++)
     {

   for(i=0;i<2;i++)       //this loop is used to read adc values from channel 0,1,2 etc
   {
        set_adc_channel(chan);
        accel[chan]=read_adc();       //Acceleration z, y, z
           
   }

   (double)x[j]=accel[0] - x_ZeroG;             //Acceleration x
   (double)y[j]=accel[1] - y_ZeroG;            //Acceleration y
   (double)z[j]=accel[2] - z_ZeroG;           //Acceleration z
 
  }
Gvlauesdisplay(x,y,z);
}

void Gvlauesdisplay(double* x, double* y, double* z)
{
   int8 j;
   printf("printing 256 data points acceleration values from x,y,z axis\n\n");
   for(j=0; j<255; j++)
     {
       printf("%4d %d4 %4d",x[j],y[j],z[j]);
     }
}

void main()
{
   setup_adc_ports(ALL_ANALOG);
        setup_adc(ADC_CLOCK_INTERNAL);
    Adxl330_Calibrate();       //use for obtaining x_ZeroG,y_ZeroG,z_ZeroG calibration values

   while(1)
   {
                 delay_Ms(500)
    Gadxl330getxyz();         //will print 256 data points of the x,y,z acceleration values every half a second
   
   }
   
}
 
 
 





libor



Joined: 14 Dec 2004
Posts: 288
Location: Hungary

View user's profile Send private message

Re: Acceleration
PostPosted: Mon Jul 30, 2007 6:45 am     Reply with quote

Schmittz wrote:
I'm definelty going to change the IC to 18f452.

That's an obsolete part, use the 18F4520 instead, or even better (with double the rom and ram size) the 18F4620.
...however I think with the possible DSP requirements of your project, you will soon run into the dsPIC33Fxxxx range, though you will have to wait some more time for a working CCS compiler for these chips.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 30, 2007 2:22 pm     Reply with quote

Quote:
#FUSES LVP

The LVP fuse can cause the PIC to lock-up if the PGM pin is taken to a
high level. Change that fuse to NOLVP. Do this in all your programs.

Quote:
unsigned double adc_x,adc_y, adc_z = 0;

There is no 'unsigned' qualifier for the 'double' data type.
If you compiled your program, you would see the following error,
so I don't think you're compiling it:
Quote:
*** Error 38 "PCH_Test.c" Line 9(10,16): This type can not be
qualified with this qualifier


Quote:
int8 x[256];
int8 y[256];
int8 z[256];

(double)x[j]=accel[0] - x_ZeroG;
(double)y[j]=accel[1] - y_ZeroG;
(double)z[j]=accel[2] - z_ZeroG;

This won't work. You can't convert an array from an int8 to a double
array at run-time. The amount of memory allocated for the array is
determined at compile-time. An 'int8' takes one byte per array element.
A 'double' takes four bytes per element. If you cast an array element to
a double in an int8 array, you'll just overwrite the data in other elements.

You need to take a step back and study C some more, before proceeding.
Schmittz



Joined: 29 Jul 2007
Posts: 3

View user's profile Send private message

Thanks PCM Programmer
PostPosted: Tue Jul 31, 2007 4:26 am     Reply with quote

Thanks pcm programmer, I appreciate your explanation.It does make thing clear.
I'm very stuck now since I can't get any other way to be able to use arrays to store accelerometer reading. I was trying cast to see if this may help.

Secondly I've tried to simulate the code on MPLAB7.6 but it does not work at all.The simulator runs through the function without looping(i.e. it does not even when the for loop is encountered). Does this mean there is incompatibity of my software with MPLAB7.6?
Thanks again


Code:
#include <18F452.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOOSCSEN                 //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

int8 x[256];
int8 y[256];
int8 z[256];
double accel[2];
double adxCalib[2];

const double x_ZeroG=250;   //Zero_G
const double y_ZeroG=250;   //Zero_G
const double z_ZeroG=250;   //Zero_G
void Adxl330_Calibrate()
{
 double adc_x,adc_y, adc_z = 0;
int8 chan;
for (chan=0; chan<2; chan++)
   {
      set_adc_channel(chan);
      adxCalib[chan]=read_adc();
      delay_us(10);
   
   }
      adc_x = adxCalib[0];                  // get ADC value for X channel
      adc_y = adxCalib[1];                  // get ADC value for Y channel
      adc_y = adxCalib[2];                  // get ADC value for z channel
     
      printf("%4d %d4 %4d",adc_x,adc_y,adc_z);
}

//=============================================================================
//  get xyz
//=============================================================================

void Gadxl330getxyz()
{

   int i,j;
    for(j=0; j<255; j++)
     {

   for(i=0;i<2;i++)       //this loop is used to read adc values from channel 0,1,2 etc
   {
        set_adc_channel(chan);
        accel[chan]=read_adc();       //Acceleration z, y, z
           
   }

   x[j]=accel[0] - x_ZeroG;             //Acceleration x
   y[j]=accel[1] - y_ZeroG;            //Acceleration y
   z[j]=accel[2] - z_ZeroG;           //Acceleration z
 
  }
Gvlauesdisplay(x,y,z);
}

void Gvlauesdisplay(double* x, double* y, double* z)
{
   int8 j;
   printf("printing 256 data points acceleration values from x,y,z axis\n\n");
   for(j=0; j<255; j++)
     {
       printf("%4d %d4 %4d",x[j],y[j],z[j]);
     }
}

void main()
{
   setup_adc_ports(ALL_ANALOG);
        setup_adc(ADC_CLOCK_INTERNAL);
    Adxl330_Calibrate();       //use for obtaining x_ZeroG,y_ZeroG,z_ZeroG calibration values

   while(1)
   {
                 delay_Ms(500)
    Gadxl330getxyz();         //will print 256 data points of the x,y,z acceleration values every half a second
   
   }
   
}
 
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 31, 2007 11:13 am     Reply with quote

Quote:

Secondly I've tried to simulate the code on MPLAB7.6 but it does not
work at all. The simulator runs through the function without looping.

No, you are not doing this. How do I know ? Because I pasted your
code into MPLAB and tried to compile it. It gave these errors:
Quote:

*** Error 45 "PCH_Test.c" Line 49(24,25): Subscript out of range
*** Error 116 "PCH_Test.c" Line 51(40,45): Printf variable count (%) does not match actual count ::
*** Error 12 "PCH_Test.c" Line 67(25,29): Undefined identifier chan
*** Error 12 "PCH_Test.c" Line 68(15,19): Undefined identifier chan
*** Error 12 "PCH_Test.c" Line 77(1,15): Undefined identifier Gvlauesdisplay
*** Error 116 "PCH_Test.c" Line 86(42,43): Printf variable count (%) does not match actual count ::
*** Error 76 "PCH_Test.c" Line 99(5,19): Expect ;
7 Errors, 0 Warnings.


The first one is "Subscript out of range". It's on this line:
Code:
   adc_y = adxCalib[2];

It occurs because you're trying to access the 3rd element in an array
that is declared as having only two elements:
Code:
double adxCalib[2];

In C, array indexes start at 0, but the declaration size is done with whole
numbers.

I don't want to help you anymore, or at least for the time being.
The reason is, first, you need to study C. Take a class in it. Learn the
data types and the essentials. 2nd, you have a habit of claiming things
that you're not actually doing, such as claiming that a program is being
run in MPLAB simulator when it won't even compile. Until you fix both
those things, there's no point in asking questions on this board.
My advice is to go study C and come back in a few weeks.
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