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

Read MPU 9250 magnetometer

Hello,

I want to read the values from MPU9250 magnetometer i.e. from AK8963 I wrote a function just like accelerometer and gyroscope shown below:

uint32_t mpu_read_mag(mag_values_t * mag_values)

  {

    uint32_t err_code;
    uint8_t raw_values[6];
    err_code = mpu_read_registers1(REG_ST1, raw_values, 6);
    if(err_code != NRF_SUCCESS) return err_code;
    uint8_t *data;
    data = (uint8_t*)mag_values;
    for(uint8_t i = 0; i<6; i++)
    {
        *data = raw_values[5-i];
        data++;
    }
    return NRF_SUCCESS;
}

and then wrote separate function for mpu_read_register for giving separate AK8963 address shown below:

uint32_t mpu_read_registers1(uint8_t reg, uint8_t * p_data, uint32_t length)
{

    uint32_t err_code;
    uint32_t timeout = MPU_TWI_TIMEOUT;

    err_code = nrf_drv_twi_tx(&m_twi_instance, AK8963_ADDR, &reg, 1, false);
    if(err_code != NRF_SUCCESS) return err_code;

    while((!twi_tx_done) && --timeout);
    if(!timeout) return NRF_ERROR_TIMEOUT;
    twi_tx_done = false;

    err_code = nrf_drv_twi_rx(&m_twi_instance, AK8963_ADDR, p_data, length);
    if(err_code != NRF_SUCCESS) return err_code;

    timeout = MPU_TWI_TIMEOUT;
    while((!twi_rx_done) && --timeout);
    if(!timeout) return NRF_ERROR_TIMEOUT;
    twi_rx_done = false;

    return err_code;
}

Program gets compiled but doesn't show any output.

Parents
  • The AK8975 is actually its own separate TWI device inside the MPU9150. To be able to communicate with it you must enable "bypass mode" by setting the BYPASS_EN bit in register 0x37 "INT Pin / Bypass Enable Configuration". If you use the MPU library you can do it like this:

    mpu_int_pin_cfg_t bypass_config;
    bypass_config.i2c_bypass_en = 1;
    ret_code = mpu_int_cfg_pin(&bypass_config); // Set bypass mode
    APP_ERROR_CHECK(ret_code); // Check for errors in return value
    

    Before you have done this you won't get any response when you try to read or write to address 0x0C (and frankly I'm a bit surprised that you are not receiving any error codes). This is not very well documented in the MPU datasheets, but relevant chapters are 7.14 and 7.12 in the datasheet and 4.19 in the Register Map. I haven't tried reading or writing to the magnetometer registers, but at least I could see that the AK8975 was available on the TWI bus by using this example.

Reply
  • The AK8975 is actually its own separate TWI device inside the MPU9150. To be able to communicate with it you must enable "bypass mode" by setting the BYPASS_EN bit in register 0x37 "INT Pin / Bypass Enable Configuration". If you use the MPU library you can do it like this:

    mpu_int_pin_cfg_t bypass_config;
    bypass_config.i2c_bypass_en = 1;
    ret_code = mpu_int_cfg_pin(&bypass_config); // Set bypass mode
    APP_ERROR_CHECK(ret_code); // Check for errors in return value
    

    Before you have done this you won't get any response when you try to read or write to address 0x0C (and frankly I'm a bit surprised that you are not receiving any error codes). This is not very well documented in the MPU datasheets, but relevant chapters are 7.14 and 7.12 in the datasheet and 4.19 in the Register Map. I haven't tried reading or writing to the magnetometer registers, but at least I could see that the AK8975 was available on the TWI bus by using this example.

Children
Related