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

Wake on motion in nrf52

Hello,

I am trying to implement wake on motion functionality of MPU9250 with nRF52. I am writing below sequence code for wake on motion configuration:

void MPU6500_StartMotionDetection(void) { uint8_t val; uint32_t err_code;

// Make sure accelerometer is running
val = 0x09;
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_1, 0x09);

// Enable accelerometer, disable gyro
val = 0x07;
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_2, 0x07);

// Set Accel LPF setting to 184 Hz Bandwidth
val = 0x01;
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_ACCEL_CONFIG_2, 0x01);

// Enable Motion Interrupt
val = 0x40;
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_INT_ENABLE, 0x40);

// Enable Accel Hardware Intelligence
val = 0xC0;
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_MOT_DETECT_CTRL, 0xC0);

// Set Motion Threshold
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_WOM_THR, 0x06);

// Set Frequency of Wake-up

i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_LP_ACCEL_ODR, 6);

// Enable Cycle Mode (Accel Low Power Mode)
val = 0x29;
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_1, 0x29);

// Clear interrupt
i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_INT_STATUS, 0x29);

printf("%s: MPU6500_StartMotionDetection\r\n", print_timestamp());

}

and I am calling it inside mpu initialization after mpu_int_cfg_pin() function. Before that I am setting gpio config as shown below:

static void gpio_init(void) { ret_code_t err_code;

err_code = nrf_drv_gpiote_init();
printf("%s: nrf_drv_gpiote_init_err_code: %lu\r\n", print_timestamp(), err_code);
APP_ERROR_CHECK(err_code);

nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);

err_code = nrf_drv_gpiote_in_init(MPU9250_INT_PIN, &in_config, int_pin_handler);
printf("%s: nrf_drv_gpiote_in_init_err_code: %lu\r\n", print_timestamp(), err_code);
APP_ERROR_CHECK(err_code);

nrf_drv_gpiote_in_event_enable(MPU9250_INT_PIN, true);

}

But I am getting error in it.

Is it the proper way for configuring ?

  • It does not look like it to me. For instance this line from the link: writeI2C_1Byte(MPU9250_DEFAULT_ADDRESS, MPU9250_ACCEL_CONFIG2, 0b00000101) does not look like the same as the line i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_ACCEL_CONFIG_2, 0x01) from your code (0b00000101 and 0x01 is not the same value).

  • Sorry for confusion but I changed it and I am using below configuration

    uint32_t MPU6500_StartMotionDetection(void)

    {

    uint32_t err_code[CONFIGURATION_CHECK_LENGTH];
    
    
    //*********************************************************************************//
    // Make sure accelerometer is running
    //In PWR_MGMT_1 (0x6B) make CYCLE = 0, SLEEP = 0 and STANDBY = 0
    err_code[0] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_1, 0x00);
    
    //Set DIS_XA, DIS_YA, DIS_ZA = 0 and DIS_XG, DIS_YG, DIS_ZG = 1
    err_code[1] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_2, 0x07);
    
    // Set Accel LPF setting to 184 Hz Bandwidth
    //ACCEL_CONFIG 2 (0x1D) set ACCEL_FCHOICE_B = 1 and A_DLPFCFG[2:]=1(b001)
    err_code[2] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_ACCEL_CONFIG_2, 0x05);
    
    // Enable Motion Interrupt
    err_code[3] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_INT_ENABLE, 0x40);
    
    // Enable Accel Hardware Intelligence
    //In MOT_DETECT_CTRL (0x69), set ACCEL_INTEL_EN = 1 and ACCEL_INTEL_MODE = 1
    err_code[4] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_MOT_DETECT_CTRL, 0xC0);
    
    // Set Motion Threshold
    //In WOM_THR (0x1F), set the WOM_Threshold[7:0] to 1~255 LSBs (0~1020mg)
    err_code[5] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_WOM_THR, 0xFF);
    
    // Set Frequency of Wake-up
    //In LP_ACCEL_ODR (0x1E), set Lposc_clksel[3:0] = 0.24Hz ~ 500Hz
    err_code[6] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_LP_ACCEL_ODR, 0x03);
    
    // Enable Cycle Mode (Accel Low Power Mode)
    //In PWR_MGMT_1 (0x6B) make CYCLE =1
    err_code[7] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_1, 0x03);
    //*********************************************************************************//
    

    }

  • According to the MPU-9250 Register Map and Descriptions document, CYCLE should be bit 5 of PWR_MGMT_1 register. Can you try changing last write to 0x20?

  • I tried to change last write

    // Enable Cycle Mode (Accel Low Power Mode) //In PWR_MGMT_1 (0x6B) make CYCLE =1

    err_code[7] = i2c_write_registers(I2C_MPU9250_ADDR, MPU_REG_PWR_MGMT_1, 0x20);

    but no effect, still no interrupt.

  • Thank you Jorgen for help, I have solved the problem of wake on motion functionality. Apparently I was doing double configuration for interrupt in MPU initialization and in MPU_wake on motion functionality. when excluded interrupt initialization from MPU_init function, it started to work fine. But thank you so much for help

Related