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

    BSTRobin
    Community Moderator

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

    Hi vamshi,

    With this example code on github, you could read accel, gyro, mag data with single project. https://github.com/BoschSensortec/BMI270-Sensor-API/blob/master/bmi270_examples/read_aux_data_mode/r...

    vamshi
    Member

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

    Hi @BSTRobin ,

    I have tried with the example provided by you in Arduino. In Hardware Pins are changed. Now Acc, Gyro data is getting for every 10miliseconds. But worry is about Magnetometer data. Getting constant values as -32768 every time.

    In the example code i'm little bit confused to read Mag data. My confusion is, BMI270 is SPI inerface where BMM150 Interface is I2C.How to link these two for getting proper Mag data. As per example i'm using "bmm150_aux_mag_data(sensor_data[2].sens_data.aux_data, &mag_data, &dev);" function @10millisec but getting constant values.

    Need some help in SPI to I2C interface for getting Mag Data. I will provide detailed Info if required. Please help me to resolve this issue.

     

    Thank you.

    BSTRobin
    Community Moderator

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

    Hi vamshi,

    On BMI270 shuttle board 3.0, BMM150 was connected to BMI270 AUX interface(I2C master). Host MCU connect to BMI270 via I2C or SPI.
    The host MCU is not directly connected to BMM150. The AUX interface of BMI270 is configured in the example program to obtain BMM150 data. Make sure you migrate the example program correctly.
    https://github.com/BoschSensortec/BMI270-Sensor-API/blob/master/bmi270_examples/read_aux_data_mode/r...

    vamshi
    Member

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

    Hi @BSTRobin,

    Thank you for the reply,

    I Have tried with the example you provided but after flashing the code to ESP32-C3 it is going to reset every time. Unable get any data. I think WDT is resetting the device.
    Why it is happening to it.? My ESP32-C3 is Connected to BMI270 via SPI interface and Below is the code I'm trying to get Mag data.
    Please help me to resolve this issue.

    /**\
     * Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved.
     *
     * SPDX-License-Identifier: BSD-3-Clause
     **/
    
    /******************************************************************************/
    /*!                 Header Files                                              */
    #include <Arduino.h>
    #include <SPI.h>
    #include <stdio.h>
    #include "bmi270.h"
    #include "bmm150.h"
    #include "Wire.h"
    //#include "coines.h"
    //#include "common.h"
    
    /******************************************************************************/
    /*!                Macro definition                                           */
    
    /*! Macros to select the sensors                   */
    #define ACCEL          UINT8_C(0x00)
    #define GYRO           UINT8_C(0x01)
    #define AUX            UINT8_C(0x02)
    
    /*! Macro define limit to print data */
    #define SAMPLE_COUNT   UINT8_C(20)
    
    /*! Earth's gravity in m/s^2 */
    #define GRAVITY_EARTH  (9.80665f)
    #define BMI270_CS         7
    
    #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
    uint8_t spi_bus;
    //#endif
    
    /*****************************************************************************/
    /*!         Structure declaration                                            */
    
    /* Sensor initialization configuration. */
    struct bmi2_dev aux_bmi2_dev;
    
        /* Status of api are returned to this variable. */
        int8_t rslt;
    
        /* Variable to select the pull-up resistor which is set to trim register */
        uint8_t regdata;
    
        /* Variable to define limit to print aux data. */
        uint8_t limit = SAMPLE_COUNT;
    
        /* Variable to print data set count of aux data. */
        uint8_t count = 1;
    
        /* Initialize the interrupt status of accel, gyro and aux. */
        uint16_t int_status = 0;
    
        /* Accel, Gyro and Aux sensors are listed in array. */
        uint8_t sensor_list[3] = { BMI2_ACCEL, BMI2_GYRO, BMI2_AUX };
    
        /* Structure to define the type of the sensor and its configurations. */
        struct bmi2_sens_config config[3];
    
        /* Sensor initialization configuration. */
        struct bmm150_dev aux_bmm150_dev;
    
        /* bmm150 settings configuration */
        struct bmm150_settings settings;
    
        /* bmm150 magnetometer data */
        struct bmm150_mag_data mag_data;
    
        /* Structure to define type of sensor and their respective data. */
        struct bmi2_sens_data sensor_data = { { 0 } };
    
        //struct bmi2_sensor_data sensor_data = { 0, };//{ { 0 } };// 
        /* Variables to define read the accel and gyro data in float */
        float x = 0, y = 0, z = 0;
    
    /*******************************************************************************/
    /*!                 Functions                                                  */
    
    /**
     * aux_i2c_read - Reads data from auxiliary sensor in data mode.
     *
     *  @param[in] reg_addr     : Register address.
     *  @param[out] reg_data    : Aux data pointer to store the read data.
     *  @param[in] length       : No of bytes to read.
     *  @param[in] intf_ptr     : Interface pointer
     *
     *  @return Status of execution
     *  @retval 0 -> Success
     *  @retval < 0 -> Failure Info
     */
    static int8_t aux_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr);
    
    /**
     * aux_i2c_write - Writes data to the auxiliary sensor in data mode.
     *
     *  @param[in] reg_addr     : Register address.
     *  @param[out] reg_data    : Aux data pointer to store the data being written.
     *  @param[in] length       : No of bytes to read.
     *  @param[in] intf_ptr     : Interface pointer
     *
     *  @return Status of execution
     *  @retval 0 -> Success
     *  @retval < 0 -> Failure Info
     */
    static int8_t aux_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr);
    
    /*!
     * @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the
     * APIs.
     *
     *  @param[in] period       : The required wait time in microsecond.
     *  @param[in] intf_ptr     : Interface pointer
     *
     *  @return void.
     */
    static void aux_delay_us(uint32_t period, void *intf_ptr);
    
    /*!
     *  @brief This function converts lsb to meter per second squared for 16 bit accelerometer at
     *  range 2G, 4G, 8G or 16G.
     *
     *  @param[in] val       : LSB from each axis.
     *  @param[in] g_range   : Gravity range.
     *  @param[in] bit_width : Resolution for accel.
     *
     *  @return Value in meter per second squared.
     */
    static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width);
    
    /*!
     *  @brief This function converts lsb to degree per second for 16 bit gyro at
     *  range 125, 250, 500, 1000 or 2000dps.
     *
     *  @param[in] val       : LSB from each axis.
     *  @param[in] dps       : Degree per second.
     *  @param[in] bit_width : Resolution for gyro.
     *
     *  @return Value in degree per second.
     */
    static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width);
    
    /*!
     *  @brief This API is used to print the execution status.
     *
     *  @param[in] rslt     : Error code returned by the API whose execution status has to be printed.
     *
     *  @return void.
     */
    static void bmm150_error_codes_print_result(int8_t rslt);
    
    /******************************************************************************/
    
    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;
    }
    
    /* This function starts the execution of program. */
    void setup()
    {
        config[ACCEL].type = BMI2_ACCEL;
        config[GYRO].type = BMI2_GYRO;
        config[AUX].type = BMI2_AUX;
    
        /* To enable the i2c interface settings for bmm150. */
        uint8_t aux_bmm150_dev_addr = BMM150_DEFAULT_I2C_ADDRESS;
        aux_bmm150_dev.intf_ptr = &aux_bmm150_dev_addr;
        aux_bmm150_dev.read = aux_i2c_read;
        aux_bmm150_dev.write = aux_i2c_write;
        aux_bmm150_dev.delay_us = aux_delay_us;
    
        /* As per datasheet, aux interface with bmi270 will support only for I2C */
        aux_bmm150_dev.intf = BMM150_I2C_INTF;
    
        SPI.begin();
        aux_bmi2_dev.intf_ptr = &spi_bus;
        aux_bmi2_dev.intf = BMI2_SPI_INTF;
        aux_bmi2_dev.read = BMI270_read_spi;
        aux_bmi2_dev.write = BMI270_write_spi;
        aux_bmi2_dev.read_write_len = 32;
    
        /* Interface reference is given as a parameter
         * For I2C : BMI2_I2C_INTF
         * For SPI : BMI2_SPI_INTF
         * 
         */
        //rslt = bmi2_interface_init(&aux_bmi2_dev, BMI2_I2C_INTF);
        //bmi2_error_codes_print_result(rslt);
    
        /* Initialize bmi270. */
        rslt = bmi270_init(&aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("bmi270_init done");
        }
        //bmi2_error_codes_print_result(rslt);
    
        /* Pull-up resistor 2k is set to the trim regiter */
        regdata = BMI2_ASDA_PUPSEL_2K;
        rslt = bmi2_set_regs(BMI2_AUX_IF_TRIM, &regdata, 1, &aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("bmi270_set done");
        }
    
        /* Get default configurations for the type of feature selected. */
        rslt = bmi270_get_sensor_config(config, 3, &aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("Get_bmi270_sensorconfig done");
        }
    
        /* Configurations for accel. */
        config[ACCEL].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE;
        config[ACCEL].cfg.acc.bwp = BMI2_ACC_OSR2_AVG2;
        config[ACCEL].cfg.acc.odr = BMI2_ACC_ODR_100HZ;
        config[ACCEL].cfg.acc.range = BMI2_ACC_RANGE_2G;
    
        /* Configurations for gyro. */
        config[GYRO].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE;
        config[GYRO].cfg.gyr.noise_perf = BMI2_GYR_RANGE_2000;
        config[GYRO].cfg.gyr.bwp = BMI2_GYR_OSR2_MODE;
        config[GYRO].cfg.gyr.odr = BMI2_GYR_ODR_100HZ;
        config[GYRO].cfg.gyr.range = BMI2_GYR_RANGE_2000;
        config[GYRO].cfg.gyr.ois_range = BMI2_GYR_OIS_2000;
    
        /* Configurations for aux. */
        config[AUX].cfg.aux.odr = BMI2_AUX_ODR_100HZ;
        config[AUX].cfg.aux.aux_en = BMI2_ENABLE;
        config[AUX].cfg.aux.i2c_device_addr = BMM150_DEFAULT_I2C_ADDRESS;
        config[AUX].cfg.aux.fcu_write_en = BMI2_ENABLE;
        config[AUX].cfg.aux.man_rd_burst = BMI2_AUX_READ_LEN_3;
        config[AUX].cfg.aux.read_addr = BMM150_REG_DATA_X_LSB;
    
        /* Set new configurations for accel, gyro and aux. */
        rslt = bmi270_set_sensor_config(config, 3, &aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("Set_bmi270_sensorconfig done");
        }
       //bmi2_error_codes_print_result(rslt);
    
        /* NOTE:
         * Accel and gyro enable must be done after setting configurations
         */
        rslt = bmi270_sensor_enable(sensor_list, 3, &aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("Sensor Enabled");
        }
        //bmi2_error_codes_print_result(rslt);
    
        /* Initialize bmm150. */
        rslt = bmm150_init(&aux_bmm150_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("bmm150_init done");
        }
        //bmm150_error_codes_print_result(rslt);
    
        /* Set the power mode to normal mode. */
        settings.pwr_mode = BMM150_POWERMODE_NORMAL;
        rslt = bmm150_set_op_mode(&settings, &aux_bmm150_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("Set_bmi270_sensorconfig done");
        }
    
        //bmm150_error_codes_print_result(rslt);
    
        rslt = bmi270_get_sensor_config(config, 3, &aux_bmi2_dev);
        //bmi2_error_codes_print_result(rslt);
    
        /* Disable manual mode so that the data mode is enabled. */
        config[AUX].cfg.aux.manual_en = BMI2_DISABLE;
    
        /* Set the aux configurations. */
        rslt = bmi270_set_sensor_config(config, 3, &aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("Set_bmi270_sensorconfig done");
        }
        //bmi2_error_codes_print_result(rslt);
    
        /* Map data ready interrupt to interrupt pin. */
        rslt = bmi2_map_data_int(BMI2_DRDY_INT, BMI2_INT1, &aux_bmi2_dev);
        if (rslt == BMI2_OK)
        {
          Serial.println("Set bmi270_Map done");
          Serial.println("MAGNETOMETER, ACCEL, AND GYRO DATA IN DATA MODE");
        }
        if (aux_bmm150_dev.chip_id == BMM150_CHIP_ID)
        {
           // printf("\nValid BMM150 (Aux) sensor - Chip ID : 0x%x\n", aux_bmm150_dev.chip_id);
            Serial.println("Valid BMM150 (Aux) sensor - Chip ID :");
            Serial.println(aux_bmm150_dev.chip_id);
        }
        else
        {
           // printf("\nInvalid BMM150 (Aux) sensor - Chip ID : 0x%x\n", aux_bmm150_dev.chip_id);
            Serial.print("Invalid BMM150 (Aux) sensor - Chip ID: ");
            Serial.print(aux_bmm150_dev.chip_id);
        }
    
    #ifdef BMM150_USE_FIXED_POINT
        //printf("Magnetometer data contains fraction part (last 4 bits) and decimal part\n\n");
        Serial.println("Magnetometer data contains fraction part (last 4 bits) and decimal part");
    #endif
    }
    
    void loop() {
    //        while (1)
    //        {
                /* Delay has been added to get aux, accel and gyro data at the interval of every 0.05 second. */
                aux_bmi2_dev.delay_us(50000, aux_bmi2_dev.intf_ptr);
    
                /* To get the data ready interrupt status of accel, gyro and aux */
                rslt = bmi2_get_int_status(&int_status, &aux_bmi2_dev);
                //bmi2_error_codes_print_result(rslt);
    
                /* To check the data ready interrupt status and print the status for 20 samples. */
                if ((int_status & BMI2_ACC_DRDY_INT_MASK) && (int_status & BMI2_GYR_DRDY_INT_MASK) &&
                    (int_status & BMI2_AUX_DRDY_INT_MASK))
                {
                    rslt = bmi2_get_sensor_data(&sensor_data, &aux_bmi2_dev);
                    //bmi2_error_codes_print_result(rslt);
    
                    if (rslt == BMI2_OK)
                    {
                        //printf("\nData set : %d", count);
    
                        /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */
                        x = lsb_to_mps2(sensor_data.acc.x, 2, aux_bmi2_dev.resolution);
                        y = lsb_to_mps2(sensor_data.acc.y, 2, aux_bmi2_dev.resolution);
                        z = lsb_to_mps2(sensor_data.acc.z, 2, aux_bmi2_dev.resolution);
    
                        Serial.print("Accel x = ");
                        Serial.print(x);//sensor_data.sens_data.acc.x);
                        Serial.print("\t");
                        Serial.print("Accel y = ");
                        Serial.print(y);//sensor_data.sens_data.acc.y);
                        Serial.print("\t");
                        Serial.print("Accel z = ");
                        Serial.print(z);//sensor_data.sens_data.acc.z);
                        Serial.print("\t");
    
                        /* Print the data in m/s2. */
                       // printf("\nAcc_ms2_X = %4.2f\t Acc_ms2_Y = %4.2f\t Acc_ms2_Z = %4.2f\n", x, y, z);
    
    
                        /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */
                        x = lsb_to_dps(sensor_data.gyr.x, 2000, aux_bmi2_dev.resolution);
                        y = lsb_to_dps(sensor_data.gyr.y, 2000, aux_bmi2_dev.resolution);
                        z = lsb_to_dps(sensor_data.gyr.z, 2000, aux_bmi2_dev.resolution);
    
                        Serial.print("Gyro x = ");
                        Serial.print(x);//sensor_data.sens_data.gyr.x);
                        Serial.print("\t");
                        Serial.print("Gyro y = ");
                        Serial.print(y);//sensor_data.sens_data.gyr.y);
                        Serial.print("\t");
                        Serial.print("Gyro z = ");
                        Serial.print(z);//sensor_data.sens_data.gyr.z);
                        Serial.print("\t");
    
                        /* Print the data in dps. */
                       // printf("\nGyro_DPS_X = %4.2f\t Gyro_DPS_Y = %4.2f\t Gyro_DPS_Z = %4.2f\n", x, y, z);
     
    
                        /* Compensating the raw auxiliary data available from the BMM150 API. */
                        bmm150_aux_mag_data(sensor_data.aux_data, &mag_data, &aux_bmm150_dev);
                        //bmm150_error_codes_print_result(rslt);
    //                    printf("\nMag_uT_X = %ld\t  Mag_uT_Y = %ld\t  Mag_uT_Z = %ld\n", (long unsigned int)mag_data.x,
    //                           (long unsigned int)mag_data.y, (long unsigned int)mag_data.z);
                        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");
    
    //                }
    
    //                count++;
    //                limit--;
    //
    //                if (limit == 0)
    //                {
    //                    break;
    //                }
                }
            }
        
        //bmi2_coines_deinit();
    
        //return rslt;
    }
    
    /*!
     * @brief This function reads the data from auxiliary sensor in data mode.
     */
    static int8_t aux_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr)
    {
        int8_t rslt;
    
        rslt = bmi2_read_aux_man_mode(reg_addr, reg_data, length, &aux_bmi2_dev);
    
        return rslt;
    }
    
    /*!
     * @brief This function writes the data to auxiliary sensor in data mode.
     */
    static int8_t aux_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr)
    {
        int8_t rslt;
    
        rslt = bmi2_write_aux_man_mode(reg_addr, reg_data, length, &aux_bmi2_dev);
    
        return rslt;
    }
    
    /*!
     * Delay function map to COINES platform
     */
    static void aux_delay_us(uint32_t period, void *intf_ptr)
    {
        ;//coines_delay_usec(period);
    }
    
    /*!
     * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at
     * range 2G, 4G, 8G or 16G.
     */
    static float lsb_to_mps2(int16_t val, float g_range, uint8_t bit_width)
    {
        float half_scale = ((float)(1 << bit_width) / 2.0f);
    
        return (GRAVITY_EARTH * val * g_range) / half_scale;
    }
    
    /*!
     * @brief This function converts lsb to degree per second for 16 bit gyro at
     * range 125, 250, 500, 1000 or 2000dps.
     */
    static float lsb_to_dps(int16_t val, float dps, uint8_t bit_width)
    {
        float half_scale = ((float)(1 << bit_width) / 2.0f);
    
        return (dps / ((half_scale))) * (val);
    }

     

    Tags (2)
    BSTRobin
    Community Moderator

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

    Hi vamshi,

    You could step run your code. After you call bmm150_init() function, could you get BMM150 chip ID?
    If no, you need to check whether your bmm150 is correctly connected to the bmi270 through aux?

    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