cancel
Showing results for 
Search instead for 
Did you mean: 

Only getting 0's from LSM303AGR accelerometer.

SHold.1
Associate

Hi,

I've got a STEVAL-MKI173V1 board hooked up to my uC. I ported over the driver from:

https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lsm303agr_STdC

I'm able to read valid magnetometer values but almost always get 0's from the accelerometer.

Here is the code:

    uint8_t whoamI, rst;
    int pDataM[3];
    int pDataA[3];
    int16_t pDataARaw[3];
    int16_t pDataMRaw[3];
    float acceleration_mg[3];
    float magnetic_mG[3];
    uint32_t ret;
 
    whoamI = 0;
   ret = lsm303agr_xl_device_id_get(COMPASS_ACCL_ADDR, &whoamI);
 
    //if ( whoamI != LSM303AGR_ID_XL )
    //  while (1); /*manage here device not found */
 
    whoamI = 0;
    ret = lsm303agr_mag_device_id_get(COMPASS_MAG_ADDR, &whoamI);
 
    //if ( whoamI != LSM303AGR_ID_MG )
      //while (1); /*manage here device not found */
 
 
    ret = lsm303agr_mag_reset_set(COMPASS_MAG_ADDR, PROPERTY_ENABLE);
 
 
 
    do {
       lsm303agr_mag_reset_get(COMPASS_MAG_ADDR, &rst);
     } while (rst);
 
 
    ret = lsm303agr_xl_block_data_update_set(COMPASS_ACCL_ADDR, PROPERTY_ENABLE);
    ret = lsm303agr_mag_block_data_update_set(COMPASS_MAG_ADDR, PROPERTY_ENABLE);
 
 
 
 
    /* Set Output Data Rate */
    ret = lsm303agr_xl_data_rate_set(COMPASS_ACCL_ADDR, LSM303AGR_XL_ODR_1Hz);
    ret = lsm303agr_mag_data_rate_set(COMPASS_MAG_ADDR, LSM303AGR_MG_ODR_10Hz);
 
    ret = lsm303agr_xl_full_scale_set(COMPASS_ACCL_ADDR, LSM303AGR_2g);
 
    lsm303agr_mag_set_rst_mode_set(COMPASS_MAG_ADDR,
                                   LSM303AGR_SENS_OFF_CANC_EVERY_ODR);
 
    /* Enable temperature compensation on mag sensor */
    ret = lsm303agr_mag_offset_temp_comp_set(COMPASS_MAG_ADDR, PROPERTY_ENABLE);
 
    /* Enable temperature sensor */
    lsm303agr_temperature_meas_set(COMPASS_ACCL_ADDR, LSM303AGR_TEMP_ENABLE);
 
    lsm303agr_xl_operating_mode_set(COMPASS_ACCL_ADDR, LSM303AGR_HR_12bit);
 
    /* Set magnetometer in continuous mode */
    ret = lsm303agr_mag_operating_mode_set(COMPASS_MAG_ADDR,
                    LSM303AGR_CONTINUOUS_MODE);
 
 
 
    USTIMER_Delay(200 * MILLI_SEC);
 
    //val = 0;
    lsm303agr_xl_status_get(COMPASS_ACCL_ADDR,&reg.status_reg_a );
 
    printf("reg.status_reg_a.zyxda: %x\n\n\n", reg.status_reg_a.zyxda);
 
 
    memset(pDataARaw, 0x00, 3 * sizeof(int16_t));
    ret = lsm303agr_acceleration_raw_get(COMPASS_ACCL_ADDR,
                    pDataARaw);
    acceleration_mg[0] = lsm303agr_from_fs_2g_hr_to_mg(
                    pDataARaw[0]);
    acceleration_mg[1] = lsm303agr_from_fs_2g_hr_to_mg(
                    pDataARaw[1]);
    acceleration_mg[2] = lsm303agr_from_fs_2g_hr_to_mg(
                    pDataARaw[2]);
 
 
    printf("Acceleration raw:%d %d  %d\r\n",
                    pDataARaw[0], pDataARaw[1], pDataARaw[2]);
 
    printf("Acceleration [mg]:%4.2f  %4.2f  %4.2f\r\n",
            acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
 
    ret = lsm303agr_mag_status_get(COMPASS_MAG_ADDR, &reg.status_reg_m);
 
    memset(pDataMRaw, 0x00, 3 * sizeof(int16_t));
    ret = lsm303agr_magnetic_raw_get(COMPASS_MAG_ADDR, pDataMRaw);
    magnetic_mG[0] = lsm303agr_from_lsb_to_mgauss(
                    pDataMRaw[0]);
    magnetic_mG[1] = lsm303agr_from_lsb_to_mgauss(
                    pDataMRaw[1]);
    magnetic_mG[2] = lsm303agr_from_lsb_to_mgauss(
                    pDataMRaw[2]);
 
    printf("Magnetic field [mG]:%4.2f  %4.2f  %4.2f\r\n",
            magnetic_mG[0], magnetic_mG[1], magnetic_mG[2]);
 
    heading =  getHeading(magnetic_mG[X], magnetic_mG[Y]);
 
    printf("heading: %f\n", heading);

The results are as follows (sitting on my desk):

$ c2
reg.status_reg_a.zyxda: 1
 
 
Acceleration raw:0 0  0
Acceleration [mg]:0.00  0.00  0.00
Magnetic field [mG]:39.00  -31.50  -202.50
Mag[Y]: -31, May[X]: 39
heading: 321.519806
$ c2
reg.status_reg_a.zyxda: 1
 
 
Acceleration raw:0 0  0
Acceleration [mg]:0.00  0.00  0.00
Magnetic field [mG]:34.50  -31.50  -195.00
Mag[Y]: -31, May[X]: 34
heading: 317.642548

I need to do pitch and roll correction for the compass.

Any ideas as to what I'm doing wrong?

Thanks,

-Steve

1 ACCEPTED SOLUTION

Accepted Solutions
Eleon BORLINI
ST Employee

Hi Steve @SHold.1​ ,

since the magnetometer is correctly working, I believe this is an issue related to the configuration or communication of the accelerometer.

From the hardware side, if you are using the SPI protocol, can you please check if you are correctly setting the CS_XL pin (chip select of the accelerometer), while you are acquiring the accelerometer data?

From the firmware side, in the accelerometer configuration, can you please check whether you enabled the X, Y and Z axis?

You should refer to the Xen, Yen and Zen bits of the CTRL_REG1_A (20h) register (datasheet, p.47)

If my the issue you are facing is one of these, please click on Select as Best at the bottom of this post. This will help other users with the same issue to find the answer faster. 

-Eleon

View solution in original post

3 REPLIES 3
Eleon BORLINI
ST Employee

Hi Steve @SHold.1​ ,

since the magnetometer is correctly working, I believe this is an issue related to the configuration or communication of the accelerometer.

From the hardware side, if you are using the SPI protocol, can you please check if you are correctly setting the CS_XL pin (chip select of the accelerometer), while you are acquiring the accelerometer data?

From the firmware side, in the accelerometer configuration, can you please check whether you enabled the X, Y and Z axis?

You should refer to the Xen, Yen and Zen bits of the CTRL_REG1_A (20h) register (datasheet, p.47)

If my the issue you are facing is one of these, please click on Select as Best at the bottom of this post. This will help other users with the same issue to find the answer faster. 

-Eleon

SHold.1
Associate

Hi Eleon,

I'm embarrased. While the XYZ bits were enabled, when I read back the CTRL_REG1_A reg I noticed that the ODR bits were all low. I tried to set the it to 0x1 (1Hz).

In going down through my code I noticed that the when I came out of the write function the ODR bits were switched to 0x0 (OFF). Digging a little deeper I realized I made a stupid mistake. In my platfom I2C function to write, I had inadvertantly pasted in the read function. So it was never enabling it (or doing anything else) to the ACC section of the chip.

Stupid mistake.

Thanks for the help

-Steve

Glad to hear you easily solved the issue! 🙂

-Eleon