Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BMI270 + BMM150 Interrupt not generating by BMI270 shuttle board when data ready

    BMI270 + BMM150 Interrupt not generating by BMI270 shuttle board when data ready

    vamshi
    Established Member

    Hi Team,

    I'm using BMI270 Shuttle board 3.0 + BMM150 mounted on it to read data (Acc, Gyro, Mag). Present we are reading data using interrupt method. According to BMM270 datasheet when data is ready it need to generate interrupt (Falling). But interrupt is not generating by sensor, until and unless we move it by our hand. Using INT2 for interrupt detection in P1 see below image. Here we are unable to find what's happening.

    Why interrupt is generating only when we move/touch interrupt pin.? Please help me to resolve this issue. please find the attached code which reads Acc, Gyro, Mag data. Do I need to do anything to generate interrupt by sensor.
    I will provide more info if required. Any help would be very thankful.

    BMI270_BMM150.PNG

     

     

    #include <Arduino.h>
    #include <SPI.h>
    #include "Wire.h"
    #include "bmi2.h"
    #include "bmi2_defs.h"
    #include "bmi270.h"
    #include "bmm150.h"
    #include "bmm150_defs.h"
    #include "bmm150_common.h"
    
    #define CONFIG_INT_WDT_CHECK_CPU0 0
    #define CONFIG_INT_WDT_CHECK_CPU1 0
    /*! I2C interface communication, 1 - Enable; 0- Disable */
    #define BMI270_INTERFACE_I2C UINT8_C(0)
    
    /*! SPI interface communication, 1 - Enable; 0- Disable */
    #define BMI270_INTERFACE_SPI UINT8_C(1)
    
    static int8_t bmi2_set_config(struct bmi2_dev *bmi2_dev);
    #if BMI270_INTERFACE_I2C == 1
    /*! Variable that holds the I2C device address or SPI chip selection */
    static uint8_t i2c_bus;
    #elif BMI270_INTERFACE_SPI == 1
    static uint8_t spi_bus;
    #endif
    
    uint8_t gu8DataFlag;
    
    // Interrupt Pin - Digital Pin2
    // Most Arduino Boards can use digital pin 2 as pin interrupt
    const byte interruptPin = 5;
    #define BMI270_CS       10
    
    /* Create an instance of sensor data structure */
    struct bmi2_sensor_data sensor_data[2] = { 0, };
    
    /* Structure to define BMI2 sensor configurations */
    struct bmi2_dev bmi2;
    // Sensor initialization configuration. 
    struct bmm150_dev dev;
    
    struct bmm150_mag_data mag_data;
    
    /*!
     *  @brief This internal API is used to set configurations powermode, odr and interrupt mapping.
     *
     *  @param[in] dev       : Structure instance of bmm150_dev.
     *
     *  @return Status of execution.
     */
    static int8_t set_config(struct bmm150_dev *dev);
    
    /*!
     *  @brief This internal API is used to get gyro data.
     *
     *  @param[in] dev       : Structure instance of bmm150_dev.
     *
     *  @return Status of execution.
     */
    static int8_t get_data(struct bmm150_dev *dev);
    
    
    /******************************************************************************/
    
    int8_t BMI270_write_spi(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr)
    {
      uint32_t cnt;
      int8_t rev = 0;
      (void)(intf_ptr);
      digitalWrite(BMI270_CS, LOW);
      SPI.transfer(reg_addr);
      for (cnt = 0; cnt < length; cnt++)
      {
        SPI.transfer(*(reg_data + cnt));
      }
      digitalWrite(BMI270_CS, HIGH);
      return rev;
    }
    
    int8_t BMI270_read_spi(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr)
    {
      uint32_t cnt;
      int8_t rev = 0;
      (void)(intf_ptr);
      reg_addr = 0x80 | reg_addr;
      digitalWrite(BMI270_CS, LOW);
      SPI.transfer(reg_addr);
      for (cnt = 0; cnt < length; cnt++)
      {
        *(reg_data + cnt) = SPI.transfer(0x00);
      }
      digitalWrite(BMI270_CS, HIGH);
      return rev;
    }
    
    
    void bmi2xy_hal_delay_usec(uint32_t period_us, void *intf_ptr)
    {
      delayMicroseconds(period_us);
    }
    
    
    int8_t bmi2_accel_gyro_set_config(struct bmi2_dev *bmi2_dev)
    {
      /* Variable to define result */
      int8_t rslt;
    
      /* Initialize interrupts for gyroscope */
      uint8_t sens_int = BMI2_DRDY_INT;
    
    
      /* List the sensors which are required to enable */
      uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO};
    
      /* Structure to define the type of the sensor and its configurations */
      struct bmi2_sens_config config[2];
    
      /* Configure type of feature */
      config[0].type = BMI2_ACCEL;
      config[1].type = BMI2_GYRO;
    
    
      /* Enable the selected sensors */
      rslt = bmi2_sensor_enable(sens_list, 2, bmi2_dev);
    
      if (rslt == BMI2_OK)
      {
        /* Get default configurations for the type of feature selected */
        rslt = bmi2_get_sensor_config(config, 2, bmi2_dev);
    
        if (rslt == BMI2_OK)
        {
           config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ;
    
          /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */
          config[0].cfg.acc.range = BMI2_ACC_RANGE_2G;
          config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4;
          config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE;
    
          /* The user can change the following configuration parameter according to their requirement */
          /* Output data Rate. By default ODR is set as 200Hz for gyro */
          config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ;
          /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps */
          config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000;
          config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE;
          config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE;
          config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE;
    
          /* Set the accel configurations */
          rslt = bmi2_set_sensor_config(config, 2, bmi2_dev);
    
          if (rslt == BMI2_OK)
          {
            /* Map interrupt to pins */
            rslt = bmi2_map_data_int(sens_int, BMI2_INT2, bmi2_dev);
          }
        }
      }
    
      return rslt;
    }
    
    int8_t bmi2_accel_set_config(struct bmi2_dev *bmi2_dev)
    {
      /* Variable to define result */
      int8_t rslt;
    
      /* Initialize interrupts for gyroscope */
      uint8_t sens_int = BMI2_DRDY_INT;
    
      /* List the sensors which are required to enable */
      uint8_t sens_list = BMI2_ACCEL;
    
      /* Structure to define the type of the sensor and its configurations */
      struct bmi2_sens_config config;
    
      /* Configure type of feature */
      config.type = BMI2_ACCEL;
    
      /* Enable the selected sensors */
      rslt = bmi2_sensor_enable(&sens_list, 1, bmi2_dev);
    
      if (rslt == BMI2_OK)
      {
        /* Get default configurations for the type of feature selected */
        rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev);
    
        if (rslt == BMI2_OK)
        {
    
          config.cfg.acc.odr = BMI2_ACC_ODR_100HZ; // changed from 25Hz
    
          /* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */
          config.cfg.acc.range = BMI2_ACC_RANGE_2G;
          config.cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4;
          config.cfg.acc.filter_perf = BMI2_PERF_OPT_MODE;
    
          /* Set the gyro configurations */
          rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev);
    
          if (rslt == BMI2_OK)
          {
            /* Map interrupt to pins */
            rslt = bmi2_map_data_int(sens_int, BMI2_INT2, bmi2_dev);
          }
        }
      }
    
      return rslt;
    }
    
    int8_t bmi2_gyro_set_config(struct bmi2_dev *bmi2_dev)
    {
      /* Variable to define result */
      int8_t rslt;
    
      /* Initialize interrupts for gyroscope */
      uint8_t sens_int = BMI2_DRDY_INT;
    
      /* List the sensors which are required to enable */
      uint8_t sens_list = BMI2_GYRO;
    
      /* Structure to define the type of the sensor and its configurations */
      struct bmi2_sens_config config;
    
      /* Configure type of feature */
      config.type = BMI2_GYRO;
    
      /* Enable the selected sensors */
      rslt = bmi2_sensor_enable(&sens_list, 1, bmi2_dev);
    
      if (rslt == BMI2_OK)
      {
        /* Get default configurations for the type of feature selected */
        rslt = bmi2_get_sensor_config(&config, 1, bmi2_dev);
    
        if (rslt == BMI2_OK)
        {
          /* The user can change the following configuration parameter according to their requirement */
          /* Output data Rate. By default ODR is set as 200Hz for gyro */
          config.cfg.gyr.odr = BMI2_GYR_ODR_100HZ; //changed from 25Hz
          /* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps */
          config.cfg.gyr.range = BMI2_GYR_RANGE_2000;
          config.cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE;
          config.cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE;
          config.cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE;
    
          /* Set the gyro configurations */
          rslt = bmi2_set_sensor_config(&config, 1, bmi2_dev);
    
          if (rslt == BMI2_OK)
          {
            /* Map interrupt to pins */
            rslt = bmi2_map_data_int(sens_int, BMI2_INT2, bmi2_dev);
          }
        }
      }
    
      return rslt;
    }
     
    void setup() {
    
      /* Variable to define result */
      int8_t rslt;
      pinMode(BMI270_CS, OUTPUT);
      pinMode(interruptPin, INPUT_PULLUP);
      digitalWrite(BMI270_CS, HIGH);
      //  Wire.setModule(0);
      Serial.begin(115200);
    
      spi_bus = BMI270_CS;
      /* To initialize the hal function */
    
      SPI.begin();
      bmi2.intf_ptr = &spi_bus;
      bmi2.intf = BMI2_SPI_INTF;
      bmi2.read = BMI270_read_spi;
      bmi2.write = BMI270_write_spi;
      bmi2.read_write_len = 32;
      bmi2.delay_us = bmi2xy_hal_delay_usec;
    
      /* Config file pointer should be assigned to NULL, so that default file address is assigned in bmi270_init */
      bmi2.config_file_ptr = NULL;
    
      /* Initialize bmi270 */
      rslt = bmi270_init(&bmi2);
    
      Serial.println("bmi270_init done");
    
      rslt = bmi2_accel_gyro_set_config(&bmi2);
    
      if (rslt == BMI2_OK)
      {
        Serial.println("Accel data Ready : X Y Z ");
        Serial.println("Gyro data Ready : X Y Z ");
      }
    
    
      rslt = bmm150_interface_selection(&dev);
        if (rslt == BMM150_OK)
        {
            rslt = bmm150_init(&dev);
    
            if (rslt == BMM150_OK)
            {
                Serial.println("BMM150 Init Done");
                rslt = set_config(&dev);
    
                if (rslt == BMM150_OK)
                {
                   Serial.println("BMM150 Config Done");
                   // rslt = get_data(&dev);
                }
    
            }
        }
    
    /*******************Mag Ends*************************************************/
      // Interrupt PINs configuration
      struct bmi2_int_pin_config data_int_cfg;
      data_int_cfg.pin_type = BMI2_INT2;
      data_int_cfg.int_latch = BMI2_INT_NON_LATCH;
      data_int_cfg.pin_cfg[0].output_en = BMI2_INT_OUTPUT_ENABLE; // Output enabled
      data_int_cfg.pin_cfg[0].od = BMI2_INT_PUSH_PULL;      // OpenDrain disabled
      data_int_cfg.pin_cfg[0].lvl = BMI2_INT_ACTIVE_LOW;      // Signal Low Active
      data_int_cfg.pin_cfg[0].input_en = BMI2_INT_INPUT_DISABLE;  // Input Disabled
    
      rslt =  bmi2_set_int_pin_config( &data_int_cfg, &bmi2);
    
      pinMode(interruptPin, INPUT);
      attachInterrupt(digitalPinToInterrupt(interruptPin), RawDataHandler, FALLING);
    
    }
    
    /*!
     *  @brief This internal API is used to set configurations like powermode, odr and interrupt mapping.
     */
    static int8_t set_config(struct bmm150_dev *dev)
    {
        /* Status of api are returned to this variable. */
        int8_t rslt;
    
        struct bmm150_settings settings;
    
        /* Set powermode as normal mode */
        settings.pwr_mode = BMM150_POWERMODE_NORMAL;
        rslt = bmm150_set_op_mode(&settings, dev);
        bmm150_error_codes_print_result("bmm150_set_op_mode", rslt);
    
        if (rslt == BMM150_OK)
        {
            /* Setting the preset mode as Low power mode
             * i.e. data rate = 10Hz, XY-rep = 1, Z-rep = 2
             */
            settings.preset_mode = BMM150_PRESETMODE_LOWPOWER;
            rslt = bmm150_set_presetmode(&settings, dev);
    
            if (rslt == BMM150_OK)
            {
               Serial.println("BMM150 Preset-LPM Done");
                /* Map the data interrupt pin */
                settings.int_settings.drdy_pin_en = 0x02;
                rslt = bmm150_set_sensor_settings(BMM150_SEL_DRDY_PIN_EN, &settings, dev);
     
            }
        }
    
        return rslt;
    }
    
    
    void loop() {
    if (gu8DataFlag == 1)
    {
      gu8DataFlag = 0;
    
        Serial.print("Accel x = ");
        Serial.print(sensor_data[0].sens_data.acc.x);
        Serial.print("\t");
        Serial.print("Accel y = ");
        Serial.print(sensor_data[0].sens_data.acc.y);
        Serial.print("\t");
        Serial.print("Accel z = ");
        Serial.print(sensor_data[0].sens_data.acc.z);
        Serial.print("\t");
    
        Serial.print("Gyro x = ");
        Serial.print(sensor_data[1].sens_data.gyr.x);
        Serial.print("\t");
        Serial.print("Gyro y = ");
        Serial.print(sensor_data[1].sens_data.gyr.y);
        Serial.print("\t");
        Serial.print("Gyro z = ");
        Serial.println(sensor_data[1].sens_data.gyr.z);
        Serial.print("\t");
        delay(100);
    
        Serial.print("Mag x = ");
        Serial.print(mag_data.x);
        Serial.print("\t");
        Serial.print("Mag y = ");
        Serial.print(mag_data.y);
        Serial.print("\t");
        Serial.print("Mag z = ");
        Serial.print(mag_data.z);
        Serial.print("\t");
    
    }
         
    }
    
    
    void RawDataHandler()
    {
      float accel_x = 0, accel_y = 0, accel_z = 0;
    
      sensor_data[0].type = BMI2_ACCEL;
      sensor_data[1].type = BMI2_GYRO;
      bmi2_get_sensor_data(sensor_data, 2, &bmi2);
      bmm150_read_mag_data(&mag_data, &dev);
    
      gu8DataFlag = 1;
    }

     

     

     
     

     

    11 REPLIES 11

    BSTRobin
    Community Moderator
    Community Moderator

    Hi vamshi,

    There are BMI270 example code on github, https://github.com/BoschSensortec/BMI270-Sensor-API/tree/master/bmi270_examples

    What is ODR you used? And how often do you expect to read the data by interrupt?

    vamshi
    Established Member

    Hi @BSTRobin,

    Thank you for the reply,

    I have referred the examples provided by you. But I've faced issue with "coines" files. The above arduino code is to read data based on interrupt using SPI interface. Can you please look into above problem in detailed and help me to resolve my issue. Is there any arduino working project which reads Acc, Gyro Data & Mag data if possible from BMI270 Shuttle Board 3.0.

    I used ODR = BMI2_ACC_ODR_100HZ. I need to read whenever data is ready, through interrupt handler. My main problem is "Interrupt is not generating when data is ready". data is getting only when we move INT2 line intentionally. Please try to resolve my issue or if possible, provide any working project using SPI interface.

    Any help would be very thankful.

    BSTRobin
    Community Moderator
    Community Moderator

    Hi vamshi,

    After you install Coines software, you could see Coines file under "C:\COINES\v2.6.0\coines-api" folder. Currently BMI270 reference code was written by C language, not on Arduino platform.

    You could refer https://github.com/BoschSensortec/BMI270-Sensor-API/blob/master/bmi270_examples/accel_gyro/accel_gyr... example and use data ready interrupt to read sensor data, ensure that the host MCU is configured with the correct interrupt trigger mode, the data ready interrupt of BMI270 is mapped to INT1 or INT2, and connected to the host MCU.

    For 100 Hz ODR, an interrupt will be received every 10ms.

    vamshi
    Established Member

    Thank you for the reply @BSTRobin ,

    Ok I will try with the above examples. We are using BMI270 Shuttle Board 3.0 where BMM150 mopunted on it. So, we need to read BMM150 (Mag) Data also. Is there any driver for BMM150 to read Mag data ? So that, I can try Acc, Gyro, Mag Data reading with single project.

    Any help would be very thankful 

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist