Hi Mark,
First of all, let me check with you your program. If I well understand:
- The arduino init the sensor and then goes into sleep mode (the sensor is also in sleep mode).
- When the transient function is triggered, the MMA8451 switches to normal mode.
- I guess the sensor interrupt is catched by your arduino and this wake it up. This is just strange how you coded it. It should be an external interrupt handler and not called in a loop.
void setup()
{
}
void pin2Interrupt(void)
{
detachInterrupt(digitalPinToInterrupt(pin2));
Serial.println("ISR Arduino Awake!");
exitSleep();
}
void exitSleep(void)
{
sleep_disable();
Serial.println("Arduino exiting sleep");
}
void enterSleep(void)
{
Serial.println("Loop Arduino entering sleep");
attachInterrupt(digitalPinToInterrupt(pin2), pin2Interrupt, LOW);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
}
void loop()
{
enterSleep();
while ((x <= reps) && (cumS < minLift))
{
}
}
- then the arduino try to compute the displacement from the acceleration
Am I wrong?
About your MMA8451 configuration:
| Register | Value | Description |
|---|
| CRTL_REG1 | 0x21 | Active mode, Normal ODR=50Hz, Sleep ODR=50Hz |
| CRTL_REG2 | 0x1E | SleepMode= Low Power, NormalMode=High Resolution, AutoSleep enabled |
| CRTL_REG3 | 0x40 | Transient function wakes the system |
| CRTL_REG4 | 0x20 | Transient Interrupt enabled |
| CRTL_REG5 | 0x20 | Interrupt routed on INT1 |
| XYZ_DATA_CFG | 0x00 | FSR to +/-2g |
| ASLP_COUNT | 0x03 | Minimum period of activity = 3 / SleepODR = 60ms |
| TRANSIENT_CFG | 0x08 | Transient detection on Z axis enabled |
| TRANSIENT_THS | 0x05 | Threshold set to 0.063*5 = 315 mg |
| TRANSIENT_COUNT | 0x03 | Debounce set to 3/SleepODR = 60ms (Sleep mode to normal mode wake up) |
According to your application, I'm not sure the MMA8451 settings are well chosen.
Firstly, the sleep mode/active mode option is not really valuable as you only change the Power/Resolution Mode and not the ORD. In fact your ODR in normal mode seems pretty slow, I would recommend you to increase it to have a better resolution for the displacement calculation.
The threshold is set to 315mg. This will not work as the Z-axis see the 1-g Earth gravity. If you want to use the function in a "relative" mode, you need to enable the internal High-Pass filter to remove it.
The debounce (TRANSIENT_COUNT) value of the transient function can be an obstacle for the Z motion detection. With the current parameter, the Z-acceleration must be higher than the threshold during at least 60 ms. You have to make sure it is. It could be better to increase the threshold and reduce the debounce value.
I highly recommend you to collect data in a real use case. This can help you to well set the transient function. Below an example of datalog of the Z-axis in a "lift" case.

About the displacement calculation, usually, we don't recommend our customer to play with that. The double integration of the g value is pretty dangerous, as is can bring a high error and make your result not accurate at all.
In order to make it more reliable, you should sample it at a high rate (interval value as small as possible) and also use the trapezoidal rule approximation for the integration instead of the rectangular methods.

I hope this will help you.
Regards,
Anthony