This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF52 with ICM20948 wake up on motion issue

Hello,

I'm having an issue with my nrf52832 with and ICM20948 IMU attached. My issue is related to wake up on motion. I believe I've set it right but I can't make it work.
I've searched through the forums and related posts, yet I'm missing something. I'll also post this in the invensense forums.

Links I've used:
https://devzone.nordicsemi.com/f/nordic-q-a/20159/wake-on-motion-in-nrf52
https://devzone.nordicsemi.com/f/nordic-q-a/10617/how-to-wake-up-nrf51-from-sleep-mode-by-a-motion-event
https://devzone.nordicsemi.com/f/nordic-q-a/48616/how-to-do-wake-up-on-motion-with-icm-20948
https://devzone.nordicsemi.com/f/nordic-q-a/48556/sleep-and-wake-nrf52832-with-icm20948


I'm not sure if my issue is due to the IMU configuration or the Nordic device.

In my code, what I do first is setting the pin to catch the interrupt:

nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_HIGH); 



Then I do the IMU initialisation and after that I do the following:

1. Make sure that the IMU is not sleeping.
2. Make sure that the IMU is in continuous mode.
3. Enable only the accelerometer (by enabling accelerometer and disabling gyroscope and temperature).
4. Enable the Wake On Motion interrupt.
5. Enable Wake On Motion feature.
6. Set threshold for IMU movement.

Here I leave my code for reference:
/* Make sure that the IMU is not sleeping */
int8_t reg = ReadReg(imu, ICM20948_PWR_MGMT_1);

/* Sleep: set the SLEEP bit */
reg |= ICM20948_BIT_SLEEP; //((uint8_t)0x40)

WriteReg(imu, ICM20948_PWR_MGMT_1, reg);

/* Make sure that the IMU is in continuous mode */
uint8_t reg;
reg = 0x00;
reg = ICM20948_BIT_ACCEL_CYCLE | ICM20948_BIT_GYRO_CYCLE; // ((uint8_t)0x20) | ((uint8_t)0x10)

WriteReg(imu, ICM20948_LP_CONFIG, reg);

/* Enable only the accelerometer */
uint8_t pwrManagement1;
uint8_t pwrManagement2;

pwrManagement1 = ReadReg(imu, ICM20948_PWR_MGMT_1);
pwrManagement2 = 0;

/* To enable the accelerometer clear the DISABLE_ACCEL bits in PWR_MGMT_2 */
pwrManagement2 &= ~( ICM20948_BIT_PWR_ACCEL_STBY ); //((uint8_t)0x38)

/* To disable gyro write the DISABLE_GYRO bits in PWR_MGMT_2 */
pwrManagement2 |= ICM20948_BIT_PWR_GYRO_STBY; //((uint8_t)0x07)

/* To disable the temperature sensor write the TEMP_DIS bit in PWR_MGMT_1 */
pwrManagement1 |= ICM20948_BIT_TEMP_DIS; // ((uint8_t)0x08)

/* Write back the modified values */
WriteReg(imu, ICM20948_PWR_MGMT_1, pwrManagement1);
WriteReg(imu, ICM20948_PWR_MGMT_2, pwrManagement2);

/* Enable the Wake On Motion interrupt */
uint8_t intEnable;
intEnable = ICM20948_BIT_WOM_INT_EN; // ((uint8_t)0x08)

/* Write value to register */
WriteReg(imu, ICM20948_INT_ENABLE, intEnable);

nrf_delay_ms(50);

/* Enable Wake On Motion feature */
WriteReg(imu, ICM20948_ACCEL_INTEL_CTRL, ICM20948_BIT_ACCEL_INTEL_EN | ICM20948_BIT_ACCEL_INTEL_MODE ); // ((uint8_t)0x02) | ((uint8_t)0x01)

/* Set threshold for IMU movement */
WriteReg(imu, ICM20948_ACCEL_WOM_THR, womThreshold ); // womThreshold is a byte value I've been modifying in different tests



After this I set a timer that will make the nrf52 enter a system off sleep mode.
sd_power_system_off();



The sensor goes to sleep right. But I'm not able to wake it up, I get no crashes or error codes.
I did some testing using another interrupt pin and a couple cables to see if I could get out of sleep by sending a pulse and it worked nicely.

Using the following interrupt pin initialisation, when the device goes to sleep it automatically wakes up the first time and the second time it goes to sleep never wakes up.

nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_HIGH); 


If i use the following interrupt pin initialisations, the device goes to sleep and automatically wakes up in loop.
nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_LOW);
 

If I use the following interrupt pin initialisation, the devices goes to sleep the first time and never wakes up.
nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH); 



I've also moved the threshold value up and down for the wake up on motion to see if this was the issue, but the testing results are the same as above.

I would appreciate any tips to get me going in the right direction.

Thanks in advance,

PauDC

Parents
  • Hi,

    As far as I can see from the datasheet of the sensor, the INT_PIN_CFG register has a reset value of 0x00. This should mean that "0 – The logic level for INT1 pin is active high", unless you configure it otherwise.

    The best option should then be to configure the input pin on the nRF52 to sense transition to high, with a pulldown to make sure that the pin is in the state you want it until the sensor pulls it high:

    nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH); 

    Have you verified with a scope/logic analyzer that the input pin actually receives an interrupt signal from the sensor?

    If not, the Invensense forum may be able to provide you with the correct configuration needed to enable the interrupt signal.

    Best regards,
    Jørgen

Reply
  • Hi,

    As far as I can see from the datasheet of the sensor, the INT_PIN_CFG register has a reset value of 0x00. This should mean that "0 – The logic level for INT1 pin is active high", unless you configure it otherwise.

    The best option should then be to configure the input pin on the nRF52 to sense transition to high, with a pulldown to make sure that the pin is in the state you want it until the sensor pulls it high:

    nrf_gpio_cfg_sense_input(4, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH); 

    Have you verified with a scope/logic analyzer that the input pin actually receives an interrupt signal from the sensor?

    If not, the Invensense forum may be able to provide you with the correct configuration needed to enable the interrupt signal.

    Best regards,
    Jørgen

Children
No Data
Related