Hello,
I am using MMA8451 Accelerometer in vehicle tracking system.
How to measure the dynamic acceleration using this MMA8451? !
From reading how i can understand whether the vehicle is moving or not?
Reg,
Amreen
Hello Amreen,
If your goal is general detection whether vehicle is moving or not, then you can set threshold output values of acceleration and then use exceeding this threshold value as evidence of moving vehicle vibrations.
If you need exact measurement then task becomes more complicated. Output signal provided by accelerometer represents the change of velocity in time unit. This means that if your car will move with constant speed (e.g. 20 km/h), the acceleration reported by sensor will be equal (if vibration neglected) to zero - as there is no velocity change. Exactly the same signal will be reported in case of car standing on parking (also no velocity change), so for distinguish between both different situations using only acceleration signal you have to know initial values (velocity in initial moment of measurement). You can use also info from other sources (e.g. wheel rotation detector, speedometer, previous measurement result, ... ), so there is many solutions possible.
Some basic but helpful examples you can see in App Notes (e.g. AN4070, AN4068, AN4399, ... ) posted under Documentation tab on MMA8451 product summary page (MMA8451Q Product Summary Page ).
Regards,
Wlodek_D.
Hello Wlodek_D.
I have refer App note AN4070 for configuring motion detection.
I am working with FRDM board with CW 10.3
My initialization is as
MMA8451_WriteReg(MMA8451_CTRL_REG_1, 0x018);
//Set the device in 100 Hz ODR, Standby
MMA8451_WriteReg(0x15, 0xC8);
//Set Configuration Register for Motion Detection
MMA8451_WriteReg(0x17, 0x16);
// Motion detection of > 1g
MMA8451_WriteReg(0x18, 0x0A);
// Set De bounce counter 100 ms/10 ms (steps) = 10 counts;
MMA8451_WriteReg(0x2D, 0x04);
//Enable Motion/Freefall Interrupt Function in the System
MMA8451_WriteReg(0x2E, 0x04);
//Route the Motion/Freefall Interrupt Function to INT1
MMA8451_ReadReg(MMA8451_CTRL_REG_1,(uint8_t*)&xyz,1);
CTRL_REG1_Data = xyz[0];
CTRL_REG1_Data |=0x01;
MMA8451_WriteReg(MMA8451_CTRL_REG_1, CTRL_REG1_Data);
//Set active mode
I have set the threshold only for X axis.
At power on i am getting an interrupt but when i read 0X0C resister its value is 0x00 instead of 0x04
My interrupt routine is as
MMA8451_ReadReg(0x0C, (uint8_t*)&Data,1); | |
if(Data[0]==0x04) | |
{ | |
MMA8451_ReadReg(0x16, (uint8_t*)&Data,1); | |
Green_LED_SetVal(NULL); | |
} |
I am not getting interrupt after this reading 0x0C.
Please guide me if i am going in wrong direction.
Hello Amreen,
First, sorry for not responding sooner, I have been out of the office the last couple of days.
From your code I see that the freefall/motion interrupt is enabled and mapped to the INT1 pin. Both IPOL and PP_OD bits in the CTRL_REG3 register have their default values, so the INT1 pin is push-pull and active low. It is therefore necessary to configure the PTA14 pin which is connected to the INT1 pin for falling edge interrupts as follows, for example:
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; // Turn on clock to Port A module
PORTA_PCR14 |= (0|PORT_PCR_ISF_MASK|
PORT_PCR_MUX(0x1)| // PTA14 is configured as GPIO
PORT_PCR_IRQC(0xA)); // PTA14 is configured for falling edge interrupts
You may have the PTA14 pin initialized in other section of your source code, I included it here just to be sure.
Furher, in your ISR you need to acknowledge an IRQ by writing a logic one to the ISF bit in the PORTA_PCR14 register:
PORTA_PCR14 |= PORT_PCR_ISF_MASK; // Clear the interrupt flag
You correctly read the FF_MT_SRC register to clear the SRC_FF_MT status bit. However, I would recommend to read both registers in your main loop to keep the ISR as short as possible. In the ISR, I would just acknowledge an IRQ and set another flag to indicate the motion event in the main loop.
I hope it helps.
Regards,
Tomas
Hello Thomas,
Thanks for the reply.
I have already implemented your suggestion regarding PTA14 interrupt pin.
I am using ode warrior 10.3. I set the PTA14 Pin as a interrupt using processor expert service.
After setting all commands with interrupt pin setting i am not getting any interrupt.
Then i tried to use polling method by reading STATUS resister as
MMA8451_WriteReg(MMA8451_CTRL_REG_1, 0x018);//0x018 // Set the device in 100 Hz ODR(10mS), Standby
MMA8451_ReadReg(MMA8451_CTRL_REG_1,(uint8_t*)&xyz,1);
CTRL_REG1_Data = xyz[0];
CTRL_REG1_Data |=0x01;
MMA8451_WriteReg(MMA8451_CTRL_REG_1, 0x19); // set active mode
MMA8451_ReadReg(0x00, (uint8_t*)&abc,1);
if(abc[0]> 0x00)
{
data_ready_Flag=1;
}
In this case also my data_ready_Flag is not set.
Also i added delay of 200mS between each "MMA8451_ReadReg" function call but the result is same.
Then i checked whether my accelerometer is in active mode or not as
MMA8451_WriteReg(MMA8451_CTRL_REG_1, 0x018);//0x018 // Set the device in 100 Hz ODR(10mS), Standby
MMA8451_ReadReg(MMA8451_CTRL_REG_1,(uint8_t*)&xyz,1);
CTRL_REG1_Data = xyz[0];
CTRL_REG1_Data |=0x01;
MMA8451_WriteReg(MMA8451_CTRL_REG_1, CTRL_REG1_Data); // set active mode
MMA8451_ReadReg(MMA8451_CTRL_REG_1, (uint8_t*)&abc,1);
I got that MMA8451_CTRL_REG_1=0x18. though i am setting it as 0x19 befor reading.
I am not getting why device is not in active mode.
Amreen,
Currently I am not really sure what is causing it, but in the meantime I created a simple bare metal example code that illustrates how to use the embedded motion detection function. It is written in the CW 10.3 for the FRDM-KL25Z board.
I hope you will find it useful.
Regards,
Tomas