1

I am working with the MMA8452q accelerometer by Freescale. I am trying to set it up to be in low power mode, to go to sleep when no motion has happened, and to wake up due to motion being detected and trigger the interrupt that corresponds to it. I am using Arduino.

I have verified the accelerometer works (i.e. can read off accelerometer data and communicate properly to it via I2C), and I have also verified that the interrupt and handler all work (by manually triggering the interrupt as compared to using the accelerometer). However, after initializing using the code below, my interrupt due to motion is not getting triggered.

-The datasheet can be found here: http://www.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf

-App note can be found here: http://cache.freescale.com/files/sensors/doc/app_note/AN4074.pdf

My code is as follows:

void MMA8452::initMMA8452(unsigned char fsr)
{
    //CONFIGURE THE ACCELEROMETER   
    MMA8452Standby();  // Must be in standby to change registers

    //Set up the full scale range to 2, 4, or 8g.
    if ((fsr==2)||(fsr==4)||(fsr==8))
        writeRegister(XYZ_DATA_CFG, fsr >> 2);  
    else
        writeRegister(XYZ_DATA_CFG, 0);

    writeRegister(CTRL_REG1, readRegister(CTRL_REG1) | bmRES1DOT56);  //1.56Hz resolution in both wake and sleep mode (lowest power)
    writeRegister(CTRL_REG2, readRegister(CTRL_REG2) | (LP << SMODS) | (LP << MODS) | (1 << SLPE));  //LOW POWER MODE IN SLEEP & ACTIVE STATES WITH LOWEST SAMPLING

    writeRegister(CTRL_REG3, (1 << WAKE_FF_MT));        //ONLY WAKE UP FROM MOTION DETECTION
    writeRegister(CTRL_REG4, (1 << INT_EN_ASLP) | (1 << INT_EN_FF_MT));  //ENABLE SLP/AWAKE INTERRUPT (INTERRUPT THROWN WHENEVER IT CHANGES) & MOTION INTERRUPT TO KEEP AWAKE
    writeRegister(ASLP_COUNT, ASLP_TIMEOUT);    //162s TIMEOUT BEFORE SLEEPING

    writeRegister(CTRL_REG5, (1 << INT_CFG_FF_MT) | (1 << INT_CFG_ASLP));  //INTERRUPT SLEEP AND FREE FALL TO INT1 PIN OF MMA8452 

    //SETUP THE MOTION DETECTION
    writeRegister(FF_MT_CFG, (1 << ELE) | (1 << OAE));      //MOTION DETECTION AND LATCH THE RESULT WHEN IT HAPPENS AS OPPOSED TO COMBINATIONAL REAL TIME
    writeRegister(FF_MT_THS, MOTION_THRESHOLD);             //MOTION DETECTION THRESHOLDS 
    writeRegister(FF_MT_COUNT, MOTION_DEBOUNCE_COUNT);      //TIME MOTION NEEDS TO BE PRESENT ABOVE THE THRESHOLD BEFORE INTERRUPT CAN BE ASSERTED

    MMA8452Active();
};
3

I played around more with it, and this code works:

void MMA8452::initMMA8452(unsigned char fsr, unsigned char dr, unsigned char sr, unsigned char sc, unsigned char mt, unsigned char mdc)
{
    MMA8452Standby();

//Set up the full scale range to 2, 4, or 8g.
if ((fsr==2)||(fsr==4)||(fsr==8))
    writeRegister(XYZ_DATA_CFG, fsr >> 2);  
else
    writeRegister(XYZ_DATA_CFG, 0);

writeRegister(CTRL_REG1, readRegister(CTRL_REG1) & ~(0xF8));
if (dr<= 7)
    writeRegister(CTRL_REG1, readRegister(CTRL_REG1) | (dr << DR0));
if (sr<=3)
    writeRegister(CTRL_REG1, readRegister(CTRL_REG1) | (sr << ASLP_RATE0));

writeRegister(CTRL_REG2, readRegister(CTRL_REG2) | (LP << SMODS) | (LP << MODS) | (1 << SLPE));  //LOW POWER MODE IN SLEEP & ACTIVE STATES WITH LOWEST SAMPLING
writeRegister(ASLP_COUNT, sc);

// Set up interrupt 1 and 2: 1 = wake ups, 2 = data
writeRegister(CTRL_REG3, (1 << WAKE_FF_MT) | (1 << IPOL));  // Active high, push-pull interrupts, sleep wake up from motion detection
writeRegister(CTRL_REG4, (1 << INT_EN_ASLP) | (1 << INT_EN_FF_MT) |  (1 << INT_EN_DRDY));  // DRDY ENABLE SLP/AWAKE INTERRUPT (INTERRUPT THROWN WHENEVER IT CHANGES) & MOTION INTERRUPT TO KEEP AWAKE
writeRegister(CTRL_REG5, (1 << INT_CFG_ASLP) | (1 << INT_CFG_FF_MT));  // DRDY on INT1, ASLP_WAKE INT2, FF INT2
writeRegister(CTRL_REG5, readRegister(CTRL_REG5));

//SETUP THE MOTION DETECTION
writeRegister(FF_MT_CFG, 0xF8);     /*MOTION DETECTION AND LATCH THE 
                                    //RESULT WHEN IT HAPPENS AS OPPOSED 
                                    //TO COMBINATIONAL REAL TIME*/
    writeRegister(FF_MT_THS, mt);       //MOTION DETECTION THRESHOLDS 
    writeRegister(FF_MT_COUNT, mdc);    //TIME MOTION NEEDS TO BE 
                                        //PRESENT ABOVE THE THRESHOLD BEFORE INTERRUPT CAN BE ASSERTED

    MMA8452Active();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.