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

BMM150 SENSOR

I am trying to interface the BMM150 magnetometer with the nRF58240 MICRCONTROLLER, Iam able to establish the I2C connection and get the return value from the reg 0x40 and the Chip ID of 0x32 where it reads 0x13 as the slave address.I configured 0x4B, 0X4C, 0X4D and 0x4E register and i am getting incorrect values from X,Y,Z registers.When sensor module is stationary the values are not inside the specified range as it needs to be.Help me configure the register and read the correct values.Thank you. 

Parents
  • Hi,

    Are you working out of an example from the SDK? If so, which example and SDK version are you using?
    If you could provide the modifications you have made to the example, that would be helpful as well.

    As I understand it, you are able to successfully read the Chip ID register and 0x40, but unable to get correct values from 0x42(DATAX_LSB), 0x43(DATAX_MSB), etc?
    Have you seen the section 4.3 Sensor output data from the BMM150 datasheet? It specifies that all data is stored using two's compliment. Does your code account for this? Could this be the reason you see incorrect data?

    I configured 0x4B, 0X4C, 0X4D and 0x4E

    Please elaborate on how you configured these.

    Best regards,
    Karl

     

  • Hi sir,

    YES I am working on one of the examples from SDK, the TWI sensor example from version SDK 17. As said iam unable to read the correct data from 0x42 to 0x47 which are MSB and LSB's of X,Y,Z.

    BMM150_write(0x4B,0x01)
    BMM150_write(0x4C,0x01)
    BMM150_write(0x4D,0x3F)
    BMM150_write(0x4E,0x3C)

    The above mentioned registers are the ones configured as given in the data sheet.

    And i have'nt gone through section 4.3 sensor output data from the datasheet as mentioned above by yourself.

    For your kind info I have attatched the code below.

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* Common addresses definition for temperature sensor. */
    //#define LM75B_ADDR          (0x90U >> 1)
    //#define LM75B_ADDR       0x5B
    //
    //#define LM75B_REG_TEMP      0x00U
    //#define LM75B_REG_CONF      0x01U
    //#define LM75B_REG_THYST     0x02U
    //#define LM75B_REG_TOS       0x03U
    //
    ///* Mode for LM75B. */
    //#define NORMAL_MODE 0U
    
    //#define HMC5883L_ADDR        (0x3DU >> 1)
    #define BMM150_ADDR        0x13
    //#define HMC5883L_RD        0x3C
    
    //#define HMC5883L_REG_CONF_A       (0x00U)
    //#define HMC5883L_REG_CONF_B       (0x01U)
    //#define HMC5883L_REG_MODE         (0x02U)
    //#define HMC5883L_REG_X_MSB        (0x03U)
    //#define HMC5883L_REG_X_LSB        (0x04U)
    //#define HMC5883L_REG_Y_MSB        (0x05U)
    //#define HMC5883L_REG_Y_LSB        (0x06U)
    //#define HMC5883L_REG_Z_MSB        (0x07U)
    //#define HMC5883L_REG_Z_LSB        (0x08U)
    //#define HMC5883L_REG_STATUS       (0x09U)
    //#define HMC5883L_REG_ID_A         (0x10U)
    //#define HMC5883L_REG_ID_B         (0x11U)
    //#define HMC5883L_REG_ID_C         (0x12U)
    
    
    
    #define BMM150_REG_OUT_X_LSB        (0x42)
    #define BMM150_REG_OUT_X_MSB        (0x43)
    #define BMM150_REG_OUT_Y_LSB        (0x44)
    #define BMM150_REG_OUT_Y_MSB        (0x45)
    #define BMM150_REG_OUT_Z_LSB        (0x46)
    #define BMM150_REG_OUT_Z_MSB        (0x47)
    //#define BMM150_REG_OUT_HALL_LSB     (0x48)
    //#define BMM150_REG_OUT_HALL_MSB     (0x49)
    //#define BMM150_REG_TEMP_MSB         (0x08)
    #define BMM150_REG_CONFIG_1         (0x4B)
    #define BMM150_REG_CONFIG_2         (0x4C)
    #define BMM150_REG_CONFIG_3         (0x4D)
    #define BMM150_REG_CONFIG_4         (0x4E)
    //#define BMM150_REG_SET_RESET        (0x4D)
    
    /* Mode Control */
    #define  BMM150_NORMAL_MODE     0b00000000
    #define  BMM150_FORCED_MODE     0b00000001
    #define  BMM150_SLEEP_MODE      0b00000011
    
    /* Output Data Rate */
    
    #define  BMM150_DATA_RATE_10HZ    0b00000000
    #define  BMM150_DATA_RATE_02HZ    0b00000001
    #define  BMM150_DATA_RATE_06HZ    0b00000010
    #define  BMM150_DATA_RATE_08HZ    0b00000011
    #define  BMM150_DATA_RATE_15HZ    0b00000100
    #define  BMM150_DATA_RATE_20HZ    0b00000101
    #define  BMM150_DATA_RATE_25HZ    0b00000110
    #define  BMM150_DATA_RATE_30HZ    0b00000111
    
    ///* Full Scale */
    //#define RNG_2G          0b00000000
    //#define RNG_8G          0b00010000
    ///* Over Sample Ratio */
    //#define OSR_512         0b00000000
    //#define OSR_256         0b01000000
    //#define OSR_128         0b10000000
    //#define OSR_64          0b11000000
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    /* Buffer for samples read from temperature sensor. */
    static int8_t m_sample[6];
    int16_t x,y,z;
    
    /**
     * @brief Function for setting active mode on MMA7660 accelerometer.
     */
    void BMM150_set_mode(void)
    {
        ret_code_t err_code;
    
        /* Writing to LM75B_REG_CONF "0" set temperature sensor in NORMAL mode. */
       // uint8_t reg[2] = {LM75B_REG_CONF, NORMAL_MODE};
    	uint8_t reg[2] = {BMM150_REG_CONFIG_1, 0x01};
    	uint8_t reg1[2] = {BMM150_REG_CONFIG_2, 0xC0};
    	uint8_t reg2[2] = {BMM150_REG_CONFIG_3, 0x3F};
            uint8_t reg3[2] = {BMM150_REG_CONFIG_3, 0x3C};
            err_code = nrf_drv_twi_tx(&m_twi, BMM150_ADDR, reg, sizeof(reg),false); 
             if(err_code==NRF_SUCCESS){
       printf("1");
        }
            APP_ERROR_CHECK(err_code);
    	nrf_delay_ms(200);
            err_code = nrf_drv_twi_tx(&m_twi, BMM150_ADDR, reg1, sizeof(reg1), false);  
            if(err_code==NRF_SUCCESS){
       printf("2");
        }
            APP_ERROR_CHECK(err_code);
            nrf_delay_ms(200);
    	err_code = nrf_drv_twi_tx(&m_twi, BMM150_ADDR, reg2, sizeof(reg2), false);  
            if(err_code==NRF_SUCCESS){
       printf("3");
        }
           APP_ERROR_CHECK(err_code);
    
    //
    //    reg[0] = 0x02;
    //    m_xfer_done = false;
    //    err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg, 1, false);
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    //    reg1[0] = 0x00;
    //    m_xfer_done = false;
    //    err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg, 1, false);
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    //    reg2[0] = 0x00;
    //    m_xfer_done = false;
    //    err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, reg, 1, false);
    //    APP_ERROR_CHECK(err_code);
    //    while (m_xfer_done == false);
    
    
    
        //while (m_xfer_done == false);
    }
    
    /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Temperature in Celsius degrees read from sensor.
     */
    __STATIC_INLINE void data_handler(int8_t m_sample)
    {
    
        NRF_LOG_INFO("Temperature: %d Celsius degrees.", m_sample);
        
    }
    
    /**
     * @brief TWI events handler.
     */
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
    ret_code_t err_code;
    
        switch (p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
                {
    
    //               data_handler(&m_sample);
                    
                }
                m_xfer_done = true;
                break;
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:
              printf("\n\rNRF_DRV_TWI_EVT_ADDRESS_NACK\r\n");
    	  break;
           case NRF_DRV_TWI_EVT_DATA_NACK:
    	  printf("\n\rNRF_DRV_TWI_EVT_DATA_NACK\r\n");
    	   break;
            default:
                break;
        }
    }
    
    /**
     * @brief UART initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_lm75b_config = {
    //       .scl                = ARDUINO_SCL_PIN,
    //       .sda                = ARDUINO_SDA_PIN,
           .scl                = NRF_GPIO_PIN_MAP(0, 11),
           .sda                = NRF_GPIO_PIN_MAP(0, 12),
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
    if(err_code==NRF_SUCCESS){
        printf("okieee  ");
        }
    
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    uint16_t read_register()
    {
    
    
    }
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
    static void read_sensor_data()
    {
    
       ret_code_t err_code;
       m_xfer_done = false;
       uint8_t packet[6] = {0x42,0x43,0x44,0x45,0x46,0x47};
       err_code = nrf_drv_twi_tx(&m_twi,BMM150_ADDR, packet, sizeof(packet), true);  
       if(err_code==NRF_SUCCESS){
    //    NRF_LOG_INFO("The Register read = 0x%x", m_sample);
    //    printf("checked");
        }
    
         nrf_delay_ms(10);
    
    //    /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
        err_code = nrf_drv_twi_rx(&m_twi, BMM150_ADDR,&m_sample, sizeof(m_sample));
        if(err_code==NRF_SUCCESS){
    //    NRF_LOG_INFO("The Register read_0 = %d", m_sample[0]);
    //    NRF_LOG_INFO("The Register read_1 = %d", m_sample[1]);
    //    NRF_LOG_INFO("The Register read_2 = %d", m_sample[2]);
    //    NRF_LOG_INFO("The Register read_3 = %d", m_sample[3]);
    //    NRF_LOG_INFO("The Register read_4 = %d", m_sample[4]);
    //    NRF_LOG_INFO("The Register read_5 = %d", m_sample[5]);
    //    NRF_LOG_INFO("The Register read = %d", m_sample[0]);
    //    printf( "\n\buff %2d %2d\r\n",m_sample[0],m_sample[1]);
    //    printf( "\n\buff1 %2d %2d\r\n",m_sample[2],m_sample[3]);
    //    printf( "\n\buff2 %2d %2d\r\n",m_sample[4],m_sample[5]);
      
         x = ((int16_t)m_sample[1] << 8) | m_sample[0];
         y = ((int16_t)m_sample[3] << 8) | m_sample[2];
         z = ((int16_t)m_sample[5] << 8) | m_sample[4];
          printf("x value %2d\n",x);
          printf("y value %2d\n",y);
          printf("z value %2d\n",z);
          
        }
    
    //    APP_ERROR_CHECK(err_code);
    
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
      //  uint8_t reg[1] ={0x01};
        NRF_LOG_INFO("\r\nTWI sensor example started.");
        NRF_LOG_FLUSH();
        twi_init();
        BMM150_set_mode();
        ret_code_t err_code;
        while (true)
        {
            nrf_delay_ms(500);
    
            do
            {
                __WFE();
            }while (m_xfer_done == false);
    //        err_code = nrf_drv_twi_tx(&m_twi, HMC5883L_ADDR, &reg, sizeof(reg), true);
    //   
    //        APP_ERROR_CHECK(err_code);
    
            read_sensor_data();
            NRF_LOG_FLUSH();
        }
    }
    

  • Boopathi said:
    from version SDK 17

     I assume you meant SDK v16.0.0.

    Boopathi said:
    And i have'nt gone through section 4.3 sensor output data from the datasheet as mentioned above by yourself.

    If you have not read the sensors datasheet, then I recommend that you read it to get familiar with how the data is stored and accessible through TWI.
    It is especially important to know which format the data is stored in, so you know what to expect when receiving the data. In this case, the sensor stores its data in Two's complement.
    So this might be why the data seem incorrect to you.

    Boopathi said:
    For your kind info I have attatched the code below.

    Do I understand you correctly, that you code is compiling and being flashed to your device and works as it should - with the only exception to this being incorrect data read from the data registers? If so, my first thought is that the data is in fact correct, but read wrong.

    Boopathi said:
    For your kind info I have attatched the code below.

    Could you please provide the UART log from running your application? Along with a description of what you expected to see, and where it differed from this.
    For future reference and easier debugging, I suggest that you clear out all the commented out lines of code before having someone else look at it. The comments drastically decreases readability.

    Best regards,
    Karl

     

     

Reply
  • Boopathi said:
    from version SDK 17

     I assume you meant SDK v16.0.0.

    Boopathi said:
    And i have'nt gone through section 4.3 sensor output data from the datasheet as mentioned above by yourself.

    If you have not read the sensors datasheet, then I recommend that you read it to get familiar with how the data is stored and accessible through TWI.
    It is especially important to know which format the data is stored in, so you know what to expect when receiving the data. In this case, the sensor stores its data in Two's complement.
    So this might be why the data seem incorrect to you.

    Boopathi said:
    For your kind info I have attatched the code below.

    Do I understand you correctly, that you code is compiling and being flashed to your device and works as it should - with the only exception to this being incorrect data read from the data registers? If so, my first thought is that the data is in fact correct, but read wrong.

    Boopathi said:
    For your kind info I have attatched the code below.

    Could you please provide the UART log from running your application? Along with a description of what you expected to see, and where it differed from this.
    For future reference and easier debugging, I suggest that you clear out all the commented out lines of code before having someone else look at it. The comments drastically decreases readability.

    Best regards,
    Karl

     

     

Children
No Data
Related