Unable to read accurate data from HMC5883L magnetometer sensor in nrf52840 MCU

Hello,

I am trying to interface nrf52840 with HMC5883L magnetometer sensor to read magnetic field x, y, z values.

When it comes to results, as far as i understood, values are not being read properly from the registers. I am configuring the sensor registers via i2c interface and trying to read the data.

I am not sure of the results. I am getting different values when  the sensor is interfaced with ESP32. But with nrf52840 the results for z axis are almost constant everywhere.

I tried using the code in this forum. Reading from HMC5883L using I2C 

Please find the code and output below and could you please let me know where i am going wrong and suggest any methods to read correct values from the registers and converting them to micro tesla

Magnetometer Test Result :

TWI scanner started.
TWI device detected at address 0x1e.

Raw Data ==> x : 526.000000, y : -228.000000, z : 0.000000

Result Data ==> x : 47.818180, y : -20.727272, z : 0.000000
*****************************
Raw Data ==> x : 528.000000, y : -229.000000, z : -3.000000

Result Data ==> x : 48.000000, y : -20.818182, z : -0.306122
*****************************
Raw Data ==> x : 526.000000, y : -228.000000, z : -1.000000

Result Data ==> x : 47.818180, y : -20.727272, z : -0.102041
*****************************
Raw Data ==> x : 527.000000, y : -228.000000, z : -2.000000

Result Data ==> x : 47.909088, y : -20.727272, z : -0.204082

*****************************

Code:

Definitions and Initializations:

#define HMC5883L_ADDR (0x3CU>>1)
#define HMC5883L_REG_CONF_A (0x00)
#define HMC5883L_REG_CONF_B (0x01)
#define HMC5883L_REG_MODE (0x02)
#define HMC5883L_REG_X_MSB (0x03)
#define HMC5883L_REG_X_LSB (0x04)

uint8_t reg[2] = { HMC5883L_REG_CONF_A, 0x70};
uint8_t reg1[2] = { HMC5883L_REG_CONF_B, 0x20};
uint8_t reg2[2] = { HMC5883L_REG_MODE, 0x00};

uint8_t reg3[1] = {HMC5883L_REG_X_MSB};

In Main:

//i2c is already initialized and did not paste that part of the code here.

err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg2, sizeof(reg2), false);
APP_ERROR_CHECK(err_code);
nrf_delay_ms(100);

err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg, sizeof(reg), false);
APP_ERROR_CHECK(err_code);
nrf_delay_ms(100);

err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg1, sizeof(reg1), false);
APP_ERROR_CHECK(err_code);
nrf_delay_ms(100);

uint8_t buff_t[6];
float combined_x, combined_y, combined_z, result_x, result_y, result_z;

while (true)
{
nrf_delay_ms(1000);

err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg3, sizeof(reg3),false); // Point to register
APP_ERROR_CHECK(err_code);

err_code = nrf_drv_twi_rx(&m_twi, HMC5883L_ADDR, buff_t, 6); // Read register and fill buffer
APP_ERROR_CHECK(err_code);

combined_x = (int16_t)((buff_t[1]) | (buff_t[0] << 8 ));
combined_y = (int16_t)((buff_t[5]) | (buff_t[4] << 8 ));
combined_z = (int16_t)((buff_t[3]) | (buff_t[2] << 8 ));

printf("\n Raw Data ==> x : %f,\ty : %f,\tz : %f\n", combined_x, combined_y, combined_z);

result_x = combined_x / 1100 * 100;
result_y = combined_y / 1100 * 100;
result_z = combined_z / 980 * 100;
printf("\n Result Data ==> x : %f,\ty : %f,\tz : %f\n",result_x, result_y, result_z);
printf("*****************************\n");
}

Parents
  • Hello

    I am not sure of the results.

    Please explain this in more detail. How do the results you see differ from the results you expect?

    the results for z axis are almost constant everywhere

    Are you sure this is inaccurate? Have you tried turning the sensor on its side?

    And most importantly, have you read the sensor's data sheet?

    Best regards,

    Einar

  • Hi,


    Thank you for your reply,

    Yes, i did read the datasheet  and it mentions that the values change based on the changes in the magnetic field around us. I tried testing on the operational examples mentioned in the datasheet and the result was the same as mentioned above.

    Regarding the results,

    I am not sure whether they are right or not. Because i have tried interfacing hmc5883l sensor with esp32 as it already has a library and followed the same calculations but the results were entirely different .

    I have tried turning the sensor around and also tried moving in different directions. The x and y values were varying but the z axis values were the the same as mentioned above while using nrf52840 even after changing its position and orientation. But, this was not the case with esp32 where the values of each axis were changing when position or orientation changed. That was the main reason i felt whether the results are right or not with nrf52840 and the other reason is i am a newbie when reading data directly from the registers. Hence i am not sure about the results as well as whether i am reading the registers properly or not. I would really appreciate any help on this.

    Please find the results of ESP32 tested code used with Adafruit hmc5388l U library placed at the same position when tested with nrf52840.

    ESP32 with HMC5883L Results:

    X: 3.55 Y: -14.09 Z: 39.80 uT
    Heading (degrees): 296.73
    X: 6.09 Y: -14.55 Z: 40.61 uT
    Heading (degrees): 20.18
    X: 15.64 Y: 2.18 Z: 20.00 uT
    Heading (degrees): 328.80
    X: 48.82 Y: -40.73 Z: -2.45 uT

    Regards,

    Shouri

Reply
  • Hi,


    Thank you for your reply,

    Yes, i did read the datasheet  and it mentions that the values change based on the changes in the magnetic field around us. I tried testing on the operational examples mentioned in the datasheet and the result was the same as mentioned above.

    Regarding the results,

    I am not sure whether they are right or not. Because i have tried interfacing hmc5883l sensor with esp32 as it already has a library and followed the same calculations but the results were entirely different .

    I have tried turning the sensor around and also tried moving in different directions. The x and y values were varying but the z axis values were the the same as mentioned above while using nrf52840 even after changing its position and orientation. But, this was not the case with esp32 where the values of each axis were changing when position or orientation changed. That was the main reason i felt whether the results are right or not with nrf52840 and the other reason is i am a newbie when reading data directly from the registers. Hence i am not sure about the results as well as whether i am reading the registers properly or not. I would really appreciate any help on this.

    Please find the results of ESP32 tested code used with Adafruit hmc5388l U library placed at the same position when tested with nrf52840.

    ESP32 with HMC5883L Results:

    X: 3.55 Y: -14.09 Z: 39.80 uT
    Heading (degrees): 296.73
    X: 6.09 Y: -14.55 Z: 40.61 uT
    Heading (degrees): 20.18
    X: 15.64 Y: 2.18 Z: 20.00 uT
    Heading (degrees): 328.80
    X: 48.82 Y: -40.73 Z: -2.45 uT

    Regards,

    Shouri

Children
Related