AnsweredAssumed Answered

ADXL345 Free-Fall Inquiry

Question asked by JON_LO on Jul 30, 2013
Latest reply on Jul 10, 2017 by Anthony.DeSimone



I am currently working on a project that aims to detect free-fall motion. I am using ADXL345 with a CC2530 EM (onboard Texas Instruments's SmartRF05 Evaluation Board). I am using I2C connection, and have successfully read x,y,z accelerations accurately. However, I cannot detect free fall at all. My troubleshoot process:


1. I forced my CC2530 interrupt pin to a ground, and successfully confirmed the CC2530's interrupt service routine is working properly.

2. I tried both INT1 and INT2 pins, and both active high and active low methods.

3. I read the FREE_FALL (D2) bit inside register 0x30 - INT_SOURCE to check if it ever gets triggered, which is no. (Yes, the device is under multiple free-fall attempts while reading this bit)

4. I then reconfigured the 2 registers that trigger the free fall bit - THRESH_FF and TIME_FF.

5. I have tried almost all combinations of THRESH_FF and TIME_FF with multiple free fall tests. The most current value is 0.5625mg and 100ms.


Here is a cut down version of my code written in IAR Embedded Workbench. The full code is attached below if you don't mind reading all of it It would be greatly appreciated if someone could point out what I did wrong. THANKS A LOT



//I2C Connections


#define          SCL   P1_0

#define          SDA   P1_1    



#define SDADirOut P1DIR|=   0x02;   //SDA Output

#define SDADirIn  P1DIR&=~  0x02;   //SDA Input



#define          SlaveAddress                 0xA6    //Alternate I2C address of 0x53: 0xA6 read & 0xA7 write



//Free-fall values declaration


#define FREE_FALL_THRESHOLD 0x09    //62.5mg/LSB, 0x09=0.5625g

#define FREE_FALL_TIME               0x14    //5ms/LSB, 0x14=100ms



//Port 1 Interrupt Service Routine


#pragma vector = P1INT_VECTOR

__interrupt void P1INT_ISR(void)


  if(P1IFG == 0x04)


        printf("Freefall \n");  



    P1IFG = 0;




//Initialization ADXL345


void Init_ADXL345()


   Single_Write_ADXL345(0x31,0x0B);                 // +-16g, 13-bit mode, active low interrupt

   Single_Write_ADXL345(0x2C,0x0F);                 // Modulate power consumption at 12.5Hz.

   Single_Write_ADXL345(0x2D,0x08);                 // Power control D3 measure


   Single_Write_ADXL345(0x2E,0x1C);                 // Enable activity, inactivity, free fall interrupt

   Single_Write_ADXL345(0x2F,0x00);                 // Map all interrupts to INT1 pin

   Single_Write_ADXL345(0X28,FREE_FALL_THRESHOLD);  // 0.3125 g (Refer value to above)

   Single_Write_ADXL345(0x29,FREE_FALL_TIME);       // 100ms    (Refer value to above)


   Single_Write_ADXL345(0x1E,0x00);                 // X-axis offset

   Single_Write_ADXL345(0x1F,0x00);                 // Y-axis offset

   Single_Write_ADXL345(0x20,0x05);                 // Z-axis offset


   Single_Read_ADXL345(0x30);                       // Clear interrupts




//Main + ADXL check


void main()

   uchar devid;

   uchar intsource;

   P1DIR = 0x03;  // 00000011 to start P1_0 and P1_1 for SCL and SDA






   /* ---- Check ADXL initialization status --- */

   devid = Single_Read_ADXL345(0x00);

   if (devid == 0xE5)


     printf("ADXL Initialized\n");





   while(1)            //loop read


      intsource = Single_Read_ADXL345(0x30);

      printf("INTSOURCE is %x\n", intsource);



      Multiple_Read_ADXL345();      //Run multiple byte read command and save in BUF