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

BMM150 not getting X Y Z values

#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
#define BMM150_SLAVE_ADDRESS 0x13

#define BMM150_REGISTER_X_MAG_LSB           0x42        //´Å³¡XÖáµÍλ
#define BMM150_REGISTER_X_MAG_MSB           0x43
#define BMM150_REGISTER_Y_MAG_LSB           0x44
#define BMM150_REGISTER_Y_MAG_MSB           0x45
#define BMM150_REGISTER_Z_MAG_LSB           0x46
#define BMM150_REGISTER_Z_MAG_MSB           0x47

#define BMM150_REGISTER_0x4B                0x4B        //Default:0x01
#define BMM150_PWR_SUSPEND_MODE             0x00        //¹ÒÆðģʽ
#define BMM150_PWR_OTHER_MODE               0x01        //ÆäËû¹¤×÷ģʽ
#define BMM150_SOFT_RESET                   0x82        //Èí¼þ¸´Î»


#define BMM150_REGISTER_0x4C                0x4C        //Default:0x06
#define BMM150_DATA_RATE_10HZ               (0x00 << 3) //´Å³¡Êý¾Ý¸üÐÂÂÊ Ä¬ÈÏ10hz
#define BMM150_DATA_RATE_2HZ                (0x01 << 3)
#define BMM150_DATA_RATE_6HZ                (0x02 << 3)
#define BMM150_DATA_RATE_8HZ                (0x03 << 3)
#define BMM150_DATA_RATE_15HZ               (0x04 << 3)
#define BMM150_DATA_RATE_20HZ               (0x05 << 3)
#define BMM150_DATA_RATE_25HZ               (0x06 << 3)
#define BMM150_DATA_RATE_30HZ               (0x07 << 3)
#define BMM150_PWR_NORMAL_MODE              (0x00 << 1)//Õý³£¹¤×÷ģʽ
#define BMM150_PWR_FORCAD_MODE              (0x01 << 1)
#define BMM150_PWR_SLEEP_MODE               (0x03 << 1)//ÐÝÃßģʽ
#define BMM150_OPEN_SELF_TEST               0x01
#define BMM150_CLOSE_SELF_TEST              0x00

#define BMM150_REGISTER_0x4D                0x4D
#define BMM150_REGISTER_0x4E                0x4E        //Default:0x07
#define BMM150_READY_EN                     0x80        //DATA READY PINʹÄÜ
#define BMM150_XYZ_CHANNEL_EN               (0x0 << 3)
#define BMM150_XY_CHANNEL_EN                (0x4 << 3)
#define BMM150_Z_CHANNEL_EN                 (0x3 << 3)

#define BMM150_REGISTER_0x51                0x51        //Default:0x00 (nXY=1+RepXY*2)
#define BMM150_REPXY_LOWPWR                 0x01        //3
#define BMM150_REPXY_REGULAR                0x04        //9
#define BMM150_REPXY_ENHANCED_REGULAR       0x07        //15
#define BMM150_REPXY_HIGH_ACCURACY          0x17        //47

#define BMM150_REGISTER_0x52                0x52        //Default:0x00 (nZ=1+RepZ)
#define BMM150_REPZ_LOWPWR                  0x02        //3
#define BMM150_REPZ_REGULAR                 0x0E        //15
#define BMM150_REPZ_ENHANCED_REGULAR        0x1A        //27
#define BMM150_REPZ_HIGH_ACCURACY           0x52        //83

/* Mode for LM75B. */
#define NORMAL_MODE 0U

/* 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);

/**
 * @brief Function for setting active mode.
 */
void BMM150_set_mode(void)
{
  BMM150_write(BMM150_REGISTER_0x4B, 0x01);
  BMM150_write(BMM150_REGISTER_0x4C, 0x06);      // Turn on the sensor with ODR = 100Hz normal mode.
//BMM150_write(BMM150_REGISTER_0x4E, 0x4C); 
  BMM150_write(BMM150_REGISTER_0x52, 0x00); 
  BMM150_write(BMM150_REGISTER_0x51, 0x00); 
// BMM150_write(BMM150_REGISTER_0x4F, 0x02);// High-pass filter (HPF) enabled with 0.2Hz cut-off frequency for INT1 (AOI1) interrupt generation only.
 // BMM150_write(BMM150_REGISTER_0x4D, 0x3F);      // ACC AOI1 interrupt signal is routed to INT1 pin.
//  //BMM150_write(BMM150_REGISTER_0x51, 0x40);
 nrf_delay_ms(300);
}


/**
 * @brief TWI events handler.
 */
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {

            }
            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 TWI initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_lm75b_config = {
       .scl                = 11,
       .sda                = 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);
    printf("twi");
    nrf_drv_twi_enable(&m_twi);
}

void BMM150_write(uint8_t addr, uint8_t wdata)
{
   ret_code_t ret;
   uint8_t tx_data[2] = {addr, wdata};
   ret=nrf_drv_twi_tx(&m_twi, BMM150_SLAVE_ADDRESS, tx_data, sizeof(tx_data), false);
}

/*Read  */
uint8_t BMM150_read(uint8_t addr)
{
 ret_code_t ret;
   uint8_t receive_data;
    ret = nrf_drv_twi_tx(&m_twi, BMM150_SLAVE_ADDRESS, &addr, 1, true);
      nrf_delay_ms(100);
    ret = nrf_drv_twi_rx(&m_twi, BMM150_SLAVE_ADDRESS,&receive_data, 1);     
    return receive_data;
}



/**
 * @brief Function for main application entry.
 */
int main(void)
{
    printf("\r\nTWI sensor example started.");
    uint8_t rx_buffer[5]={};
    int16_t *x_value,*x,*y,*z;
    twi_init();
    BMM150_set_mode();  
    while (true)
    {
   rx_buffer[0]=BMM150_read(BMM150_REGISTER_X_MAG_LSB);
   rx_buffer[1]=BMM150_read(BMM150_REGISTER_X_MAG_MSB);
   rx_buffer[2]=BMM150_read(BMM150_REGISTER_Y_MAG_LSB);
   rx_buffer[3]=BMM150_read(BMM150_REGISTER_Y_MAG_MSB);
   rx_buffer[4]=BMM150_read(BMM150_REGISTER_Z_MAG_LSB);
   rx_buffer[5]=BMM150_read(BMM150_REGISTER_Z_MAG_MSB);
   *x_value = (rx_buffer[1]<<8)|rx_buffer[0];
   *y_value = (rx_buffer[3]<<8)|rx_buffer[2];
   *z_value = (rx_buffer[5]<<8)|rx_buffer[4];
   printf("%d\n",*x_value);
    nrf_delay_ms(250); 
    }
}

/** @} */
Hi

i m using Bmm150 magnetometer sensor. i m trying to read x y z values.However, im not able to obtain the correct magnetometer values. I'm getting 0000 as values in all directions. 

here is my code

Parents
  • Hi,

    I would really recommend you to check the error codes from the TWI driver function calls, i.e. pass 'ret' to APP_ERROR_CHECK(). It is also not good practice to use delays between transfers when you run the driver in non-blocking mode. You should rather set a flag in the event handler and wait for this flag before proceeding with new transfers.

    There is no delay between the calls to BMM150_write() inside BMM150_set_mode(), and you are not checking the return codes. Most likely, all these calls except the first one return NRF_ERROR_BUSY. This leads to the TWI sensor not being initialized correctly.

    Best regards,
    Jørgen

Reply
  • Hi,

    I would really recommend you to check the error codes from the TWI driver function calls, i.e. pass 'ret' to APP_ERROR_CHECK(). It is also not good practice to use delays between transfers when you run the driver in non-blocking mode. You should rather set a flag in the event handler and wait for this flag before proceeding with new transfers.

    There is no delay between the calls to BMM150_write() inside BMM150_set_mode(), and you are not checking the return codes. Most likely, all these calls except the first one return NRF_ERROR_BUSY. This leads to the TWI sensor not being initialized correctly.

    Best regards,
    Jørgen

Children
No Data
Related