Added code to manage Orientation, FreeFall and Motion Detection. Data is also available via IRQ.
Dependents: Test_FRDM_MMA8451Q AccelTest FRDM-KL46-Template KL25Z_Demo ... more
Fork of MMA8451Q by
Revision 6:c52175d13e0a, committed 2013-05-28
- Comitter:
- clemente
- Date:
- Tue May 28 07:29:58 2013 +0000
- Parent:
- 5:695063448f2a
- Child:
- 7:ba0016258d5d
- Commit message:
- Added Orientation. To be completed and tested.
Changed in this revision
MMA8451Q.cpp | Show annotated file Show diff for this revision Revisions of this file |
MMA8451Q.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/MMA8451Q.cpp Tue May 28 04:39:42 2013 +0000 +++ b/MMA8451Q.cpp Tue May 28 07:29:58 2013 +0000 @@ -27,6 +27,10 @@ #define REG_FF_MT_SRC 0x16 #define REG_FF_MT_THS 0x17 #define REG_FF_MT_CNT 0x18 +#define REG_DBCNTM 0x11 +#define REG_DBNCE 0x12 +#define REG_BKFR 0x13 +#define REG_P_L_THS 0x14 // #define REG_OUT_X_MSB 0x01 #define REG_OUT_Y_MSB 0x03 @@ -182,6 +186,111 @@ } } +void MMA8451Q::OrientationDetect( void) +{ + OrientationDetect( Z_LOCKOUT_14, Z_BKFR_80, PL_THS_15, PL_HYS_0); +} + +void MMA8451Q::OrientationDetect( unsigned int Z_LockOut, unsigned int Z_BkFr, unsigned int PL_Thsld, unsigned int PL_Hyst) +{ + unsigned char t; + + // Step 1: Put the part into Standby Mode + Standby(); + + // Step 2: Set the data rate to 50 Hz (for example, but can choose any sample rate). + readRegs( REG_CTRL_REG_1, &t, 1); // Note: Can combine this step with above + t &= 0xC7; // Clear the sample rate bits + t |= 0x20; // Set the sample rate bits to 50 Hz + unsigned char data[2] = {REG_CTRL_REG_1, t}; + writeRegs(data, 2); // Write updated value into the register. + + + // Step 3: Set the PL_EN bit in Register 0x11 PL_CFG. This will enable the orientation detection. + readRegs( REG_DBCNTM, &t, 1); + data[0] = REG_DBCNTM; + data[1] = t | 0x40; + writeRegs(data, 2); + + // Step 4: Set the Back/Front Angle trip points in register 0x13 following the table in the data sheet. + // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the + // MMA8451Q. + readRegs( REG_BKFR, &t, 1); + t &= 0x3F; // Clear bit 7 and 6 + data[0] = REG_BKFR; + data[1] = t | Z_BkFr; + writeRegs(data, 2); // Write in the updated Back/Front Angle + + // Step 5: Set the Z-Lockout angle trip point in register 0x13 following the table in the data sheet. + // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the + // MMA8451Q. + readRegs( REG_BKFR, &t, 1); + t &= 0xF8; // Clear the last three bits of the register + data[0] = REG_BKFR; + data[1] = t | Z_LockOut; + writeRegs(data, 2); // Write in the updated Z-lockout angle + + // Step 6: Set the Trip Threshold Angle + // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the + // MMA8451Q. + // Select the angle desired in the table, and, + // Enter in the values given in the table for the corresponding angle. + // Refer to Figure 7 for the reference frame of the trip angles. + readRegs( REG_P_L_THS, &t, 1); + t &= 0x07; // Clear the Threshold values + data[0] = REG_P_L_THS; + data[1] = t | (PL_Thsld<<3); + writeRegs(data, 2); + + // Step 7: Set the Hysteresis Angle + // NOTE: This register is readable in all versions of MMA845xQ but it is only modifiable in the + // MMA8451Q. + // Select the hysteresis value based on the desired final trip points (threshold + hysteresis) + // Enter in the values given in the table for that corresponding angle. + // Note: Care must be taken. Review the final resulting angles. Make sure there isn’t a resulting trip value + // greater than 90 or less than 0. + // The following are the options for setting the hysteresis. + readRegs( REG_P_L_THS, &t, 1); + t &= 0xF8; // Clear the Hysteresis values + data[0] = REG_P_L_THS; + data[1] = t | PL_Hyst; + writeRegs(data, 2); + + // Step 8: Register 0x2D, Control Register 4 configures all embedded features for interrupt + // detection. + // To set this device up to run an interrupt service routine: + // Program the Orientation Detection bit in Control Register 4. + // Set bit 4 to enable the orientation detection “INT_EN_LNDPRT”. + readRegs( REG_CTRL_REG_4, &t, 1); + data[0] = REG_CTRL_REG_4; + data[1] = t | 0x10; // Set bit 4 + writeRegs(data, 2); + + // Step 9: Register 0x2E is Control Register 5 which gives the option of routing the interrupt to + // either INT1 or INT2 + // Depending on which interrupt pin is enabled and configured to the processor: + // Set bit 4 “INT_CFG_LNDPRT” to configure INT1, or, + // Leave the bit clear to configure INT2. + readRegs( REG_CTRL_REG_5, &t, 1); + data[0] = REG_CTRL_REG_5; + data[1] = t | 0x10; // Set bit 4 to choose the interrupt to route to INT1 + data[1] = t & 0xEF; // Clear bit 4 to choose the interrupt to route to INT2 + writeRegs(data, 2); + + // Step 10: Set the debounce counter in register 0x12 + // This value will scale depending on the application-specific required ODR. + // If the device is set to go to sleep, reset the debounce counter before the device goes to sleep. This setting + // helps avoid long delays since the debounce will always scale with the current sample rate. The debounce + // can be set between 50 ms - 100 ms to avoid long delays. + data[0] = REG_DBNCE; + data[1] = 0x05; // This sets the debounce counter to 100 ms at 50 Hz + writeRegs(data, 2); + + // Step 11: Put the device in Active Mode + Active(); + +} + void MMA8451Q::Active( void) { unsigned char t;
--- a/MMA8451Q.h Tue May 28 04:39:42 2013 +0000 +++ b/MMA8451Q.h Tue May 28 07:29:58 2013 +0000 @@ -46,6 +46,42 @@ * } * @endcode */ + +// Z-Lock Threshold Angles +#define Z_LOCKOUT_14 0 // Angle to 14° +#define Z_LOCKOUT_18 1 // Angle to 18° +#define Z_LOCKOUT_21 2 // Angle to 21° +#define Z_LOCKOUT_25 3 // Angle to 25° +#define Z_LOCKOUT_29 4 // Angle to 29° +#define Z_LOCKOUT_33 5 // Angle to 33° +#define Z_LOCKOUT_37 6 // Angle to 37° +#define Z_LOCKOUT_42 7 // Angle to 42° +// Back/Front Orientation Definition +#define Z_BKFR_80 0 // Back and Front trip angle +#define Z_BKFR_75 1 // Back and Front trip angle +#define Z_BKFR_70 2 // Back and Front trip angle +#define Z_BKFR_65 3 // Back and Front trip angle +// Threshold Angle Thresholds Lookup Table +#define PL_THS_15 0x07 // Set Threshold to 15° +#define PL_THS_20 0x09 // Set Threshold to 20° +#define PL_THS_30 0x0C // Set Threshold to 30° +#define PL_THS_35 0x0D // Set Threshold to 35° +#define PL_THS_40 0x0F // Set Threshold to 40° +#define PL_THS_45 0x10 // Set Threshold to 45° +#define PL_THS_55 0x13 // Set Threshold to 55° +#define PL_THS_60 0x14 // Set Threshold to 60° +#define PL_THS_70 0x17 // Set Threshold to 70° +#define PL_THS_75 0x19 // Set Threshold to 75° +// Trip Angles with Hysteresis for 45° Angle +#define PL_HYS_0 0x00 // Set Hysteresis to ±0° +#define PL_HYS_4 0x01 // Set Hysteresis to ±4° +#define PL_HYS_7 0x02 // Set Hysteresis to ±7° +#define PL_HYS_11 0x03 // Set Hysteresis to ±11° +#define PL_HYS_14 0x04 // Set Hysteresis to ±14° +#define PL_HYS_17 0x05 // Set Hysteresis to ±17° +#define PL_HYS_21 0x06 // Set Hysteresis to ±21° +#define PL_HYS_24 0x07 // Set Hysteresis to ±24° + class MMA8451Q { public: @@ -100,6 +136,8 @@ void FreFallDetection( void(*fptr)(void)); void MotionDetection( void(*fptr)(void)); + void OrientationDetect( unsigned int Z_LockOut, unsigned int Z_BkFr, unsigned int PL_Thsld, unsigned int PL_Hyst); + void OrientationDetect( void); private: I2C m_i2c;