Hello!
I am currently working on a project that aims to detect activity, inactivity and free-fall motion. I am using ADXL345 with a DSP. I have tried in first to have to activity, inactivity and data ready interrupt, it works fine. However I can’t detect free fall interrupt.
For detect a fall with a motion, I use very small values for the threshold 130mg and a large value for the time 500ms. I have taken a data rate of 100Hz.
This is a part of my code. Could you please say if you see something wrong.
Thanks a lot
Julien Chaix
// **************************** ADXL345 Accelerometer Registers **************************************
//
#define ADXL345_DEVID 0x00 // Device ID register with value 0xE5.
#define ADXL345_THRESH_TAP 0x1D // Threshold for normal tap detection. 62.5 mg/LSB (that is, 0xFF = 16 g).
#define ADXL345_OFSX 0x1E // X axis offset
#define ADXL345_OFSY 0x1F // Y axis offset
#define ADXL345_OFSZ 0x20 // Z axis offset
#define ADXL345_DUR 0x21 // Maximum time that an event must be above the THRESH_TAP threshold to qualify as a tap event. 625 µs/LSB
#define ADXL345_LATENT 0x22 // Time to start detection of possible second tap, 1.25 ms/LSB.
#define ADXL345_WINDOW 0x23 // Time window in which a second tap can be detected. 1.25 ms/LSB
#define ADXL345_THRESH_ACT 0x24 //Activity threshold
#define ADXL345_THRESH_INACT 0x25 //Inactivity threshold
#define ADXL345_TIME_INACT 0x26 //Inactivity time
#define ADXL345_ACT_INACT_CTL 0x27 //Axis enable control for activity and inactivity detection
#define ADXL345_THRESH_FF 0x28 //Free-fall threshold
#define ADXL345_TIME_FF 0x29 //Free-fall time
#define ADXL345_TAP_AXES 0x2A // A 1 in the TAP_X, Y or Z bits enables respective axis participation in tap detection.
#define ADXL345_ACT_TAP_STATUS 0x2B // Bits indicating ACT_x, y, z sources and TAP_x, y, z sources
#define ADXL345_BW_RATE 0x2C // Data rate power and power mode controle
#define ADXL345_POWER_CTL 0x2D // Power-saving features & measurement control
#define ADXL345_INT_ENABLE 0x2E // Set bits to a value of 1 to enable their respective functions to generate interrupts
#define ADXL345_INT_MAP 0x2F // Any bits set to 0 in this register send their respective interrupts to the INT1 pin
#define ADXL345_INT_SOURCE 0x30 // Register bits flag the source of interrupt that was generated on INT1 or INT2
#define ADXL345_DATA_FORMAT 0x31 // Data format and acceleration range register..
#define ADXL345_DATAX0 0x32 // X-Axis Data 0
#define ADXL345_DATAX1 0x33 // X-Axis Data 1
#define ADXL345_DATAY0 0x34 // Y-Axis Data 0
#define ADXL345_DATAY1 0x35 // Y-Axis Data 1
#define ADXL345_DATAZ0 0x36 // Z-Axis Data 0
#define ADXL345_DATAZ1 0x37 // Z-Axis Data 1
#define ADXL345_FIFO_CTL 0x38 // FIFO control
#define ADXL345_FIFO_STATUS 0x39 // FIFO status
// Parameters for POWER_CTL register
#define ADXL345_LINK_ACTIVITY_INACTIVITY 0x20 // Set bit with both the activity and inactivity functions enabled delays the start of the activity function until inactivity is detected.
#define ADXL345_AUTO_SLEEP 0x10 //
#define ADXL345_MEASUREMENT_ON 0x08 // Set bit to start Accelero measurement.
#define ADXL345_SLEEP_ON 0x04
// Parameter for FIFO_CTL
#define ADXL345_FIFO_MODE_BYPASS 0x00
#define ADXL345_FIFO_MODE_FIFO 0x40
#define ADXL345_FIFO_MODE_STREAM 0x80
#define ADXL345_FIFO_MODE_TRIGGER 0xA0
#define ADXL345_FIFO_TRIGGER_LINK_INT2 0x20
#define ADXL345_FIFO_TRIGGER_LINK_INT1 0x00
#define ADXL345_ONE_SAMPLE 0x01
// Parameters for INT_MAP/INT_SOURCE/INT_ENABLE registers
#define ADXL345_INT_DATA_READY 0x80
#define ADXL345_INT_SINGLE_TAP 0x40
#define ADXL345_INT_DOUBLE_TAP 0x20
#define ADXL345_INT_ACTIVITY 0x10
#define ADXL345_INT_INACTIVITY 0x08
#define ADXL345_INT_FREE_FALL 0x04
#define ADXL345_INT_WATERMARK 0x02
#define ADXL345_INT_OVERUN 0x01
// Parameters for DATA_FORMAT register
#define ADXL345_SELF_TEST 0x80 // Enable self test mode
#define ADXL345_SPI_3_WIRES_MODE 0x40 // Enable 3-wire SPI mode otherwise the 4-wire SPI mode is enabled
#define ADXL345_INT_INVERT 0x20 // Set the interrupt to active low.
#define ADXL345_FULL_RES 0x08 // Set the full resolution mode the output resolution increases with the g range set by the range bits to maintain a 4 mg/LSB scale factor.
#define ADXL345_JUSTIFY 0x04 // Selects left-justified (MSB) mode otherwise selects right-justified mode with sign extension.
#define ADXL345_ACCELERATION_16G 0x03 // Define pour acceleration 16G.
#define ADXL345_ACCELERATION_8G 0x02 // Define pour acceleration 8G.
#define ADXL345_ACCELERATION_4G 0x01 // Define pour acceleration 4G.
#define ADXL345_ACCELERATION_2G 0x00 // Define pour acceleration 2G.
//Parameters for ADXL345_THRESH_FF
#define ADXL345_THRESH_FF_6G 0x60
#define ADXL345_THRESH_FF_5G 0x50
#define ADXL345_THRESH_FF_4G 0x40
#define ADXL345_THRESH_FF_3G 0x30
#define ADXL345_THRESH_FF_2G 0x20
#define ADXL345_THRESH_FF_1G 0x10
#define ADXL345_THRESH_FF_625mg 0x0A
#define ADXL345_THRESH_FF_325mg 0x05
#define ADXL345_THRESH_FF_260mg 0x04
#define ADXL345_THRESH_FF_195mg 0x03
#define ADXL345_THRESH_FF_130mg 0x02
#define ADXL345_THRESH_FF_65mg 0x01
//Parameters for ADXL345_TIME_FF
#define ADXL345_TIME_FF_500ms 100
#define ADXL345_TIME_FF_200ms 40
#define ADXL345_TIME_FF_100ms 20
#define ADXL345_TIME_FF_10ms 2
void test_ADXL345(void)
{
int i;
struct MsgObj msg_axe;
int status_int;
int axe;
ADXL345_rwrite( ADXL345_POWER_CTL, ADXL345_MEASUREMENT_ON );
//Set the output data rate to 100Hz
ADXL345_rwrite( ADXL345_BW_RATE,0x0A);
// Set the acceleromter in 16G mode
ADXL345_rwrite( ADXL345_DATA_FORMAT, ADXL345_ACCELERATION_16G );
// Bypass the FIFO.
ADXL345_rwrite( ADXL345_FIFO_CTL, ADXL345_ONE_SAMPLE + ADXL345_FIFO_MODE_BYPASS );
// All the interrupt are mapped to INT1
ADXL345_rwrite( ADXL345_INT_MAP, 0 );
// Set the free fall threshold to 130mg
ADXL345_rwrite( ADXL345_THRESH_FF, ADXL345_THRESH_FF_130mg);
// Set the time free fall to 100ms
ADXL345_rwrite( ADXL345_TIME_FF, ADXL345_TIME_FF_500ms);
// Enable Free fall interrupt
ADXL345_rwrite( ADXL345_INT_ENABLE,ADXL345_INT_FREE_FALL );
// Clear the interrupt flag by read the INT_SOURCE register
status_int=(int)ADXL345_rread(ADXL345_INT_SOURCE);
do
{
// check the interrupt
do
{
}while(! (IOINDATA2 & GPIO_INT1_ACC));
// Clear the interrupt flag by read the INT_SOURCE register
status_int=(int)ADXL345_rread(ADXL345_INT_SOURCE);
// Print a message on the screen
if (status_int & ADXL345_INT_FREE_FALL)
{
send_mbx_to_print_msg_lcd(&msg_axe, 0, LCD_LINE_2, "FREE FALL");
}
}while(1);
}