Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    Sort by:
    ‎08-02-2023 02:43 PM
    This design guide describes the main features of the BME680, available evaluation tools and software, reference design, layout recommendations, and gives instructions on how to test the sensor’s functionality using sample codes.
    View full article
    ‎06-19-2023 10:55 PM
    The last few years have seen a remarkable increase in the number of use cases involving barometric pressure sensors in consumer electronics devices such as smartphones, tablets, wearable devices, and various home appliances. Barometric pressure sensors have been used for ambient air pressure measurement for several decades, however, recent developments and improvements in both these sensors and the devices in which they are installed have paved the way to superior performance and lower costs. The barometric pressure sensor has found its place across a wide range of products, no longer limited to traditional "weather stations". Today’s barometric pressure sensors are so incredibly accurate that they can determine altitude to within just a few centimeters. This, coupled with low-cost manufacture, has made these sensors the mainstays for motion tracking, enabling what had previously been solely the realm of science fiction. This paper will describe the two primary types of technologies used for pressure sensors, capacitive and piezoresistive, and subsequently, focus on several applications and key requirements.
    View full article
    ‎01-31-2023 03:42 PM
    The BME688 is the first gas sensor with Artificial Intelligence (AI) with integrated high-linearity and high-accuracy pressure, humidity and temperature sensors. The BME688 can detect gases by measuring their unique electrical fingerprint and therefore distinguish different gas compositions. However, the sensor has to be teached about these different gases first. That means, we have to train the sensor using Machine Learning.  And that’s where the BME AI Studio comes in, it lets the user explore, verify and validate the specific use case based on their application. In these series of short videos we take you through a step by step approach to realize these use case detection. It showcase all the key steps from how to configure the board, data collection, algorithm training and finally deployment of algorithm. The video series features a “quick start” video in the beginning that gives a quick overview of the all the steps involved  and additional videos about each step. The videos have been split in to smaller modular videos that gives an overview of all the key steps, it can be viewed as a playlist (one after the other) or the user can go to a specific video to know more about it. We hope that you will enjoy watching it.   
    View full article
    100% helpful (1/1)
    ‎08-10-2022 04:52 PM
    The Arduino Nicla Sense ME board featuring a rich set of Bosch Sensortec sensors is a robust and versatile development board that enables users to develop smart sensing applications. This series of tutorial videos aim to help users to get started and familiar with the board and quickly explore some of the functionalities and resources around it.  
    View full article
    ‎05-06-2022 04:05 PM
    The Self-Learning AI Software can recognize and track more than fifteen pre-learned fitness exercises and has the ability to learn new movements and fitness exercises created by you! Please find attached the ZIP file with the following contents: Never Skip Leg Day This session includes exercises where the sensor is mounted on the ankle and the focus will be on building leg strength. PDF document with all instructions Generated patterns Raw sample data Outdoor Bodyweight Workout This session includes exercises where the sensor is mounted on the arm. This workout is great for strengthening your core, arms and legs muscles. PDF document with all instructions Generated patterns Raw sample data Outdoor Core Workout This session includes exercises where the sensor is mounted on the ankle. This workout is great for strengthening your core. PDF document with all instructions Generated patterns Raw sample data Waist Tracking This session includes exercises where the sensor is mounted on the waist and the arm. PDF document with all instructions Generated patterns Raw sample data The self-learning AI firmware is available on our Nicla Sense ME board here. For more information about the list of virtual sensors, see the Nicla Sense ME Board examples.
    View full article
    ‎04-27-2022 09:44 AM
    Selecting the right part BMA456 is 16bit, digital, triaxial acceleration sensor with intelligent on-chip motion triggered interrupt features optimized for wearable and hearable applications. BMA456 support different advanced features via different configure file. Table 1 shows an overview of the features. Parameter BMA456 Digital resolution 16bit Range and sensitivity +/-2g: 16384LSB/g +/-4g: 8192LSB/g +/-8g: 4096LSB/g +/-4g: 2048LSB/g Zero-g offset(typ.) +/-20mg Noise density(typ.) 120µg/√Hz Bandwidths 5Hz …684Hz Interfaces SPI & I2C, 2 x digital interrupt pins Supply voltage VDD: 1.62 to 3.6V VDDIO: 1.2 to 3.6V LGA package(mm3) 2.0 x 2.0 x 0.65 Feature/Interrupts Step Counter/Step detector (optimized for wearables) Activity recognition: running, walking, still Tilt on wrist Tab/Double Tab Any-motion/No-motion High-g/ low-g Table 1: Overview BMA456 features Common characteristics The main characteristics of this product family are: Key features: 2.0 x 2.0 mm² size Pin to pin compatibility with all other 2.0 x 2.0 accelerometers from Bosch Sensortec SPI or I²C interface Configurable range from ±2G to ±16g Configurable output data rate up to 1.6kHz Integrated 1kB FIFO Auxiliary I²C interface for connecting external magnetometer, including data synchronization Built-in smart interrupt controller, with features such as step-counter which offers high performance for all wearing positions, including wrist-worn. BMA456 parameters BMA456 offers higher performance and stability in a smaller package. See the complete description in Table 2. Parameter BMA456 Units Height 0,65 mm Digital resolution 16 bits Zero-g offset (typ.) ±20 mg Noise density (typ.) 120 µg/√Hz TCO (X&Y axis) 0.2 mg/K TCO (Z axis) 0.35 mg/K TCS 0.005 %/K Cross Axis Sensitivity 0.5 % Table 2: BMA456 parameter value Available evaluation tools and software To best to evaluate the products from the BMA456 family, we recommend the following combination of evaluation tools: COINES Desktop software Application board 3.0 Sensor Shuttle board BMA456 Shuttle board. Layout recommendations Because the BMA4xy sensor family contains tiny mechanical structure inside the package, care must be taken during the layout phase to ensure the best performance. The complete handling and soldering guide can be found on the Bosch Sensortec's website. First power-on After powering the sensor for the first time, the initial specs would be to test for communication with the device. This can be done simply by reading the chip identification code in the register 0x00. See below for the expected values: Device Chip ID BMA456 0x16 Table 3: Chip IDs of the BMA4xy product family Here is some sample code on how to perform this test, based on BMA456, using the COINES software as the host. /*!  * @brief This internal API is used to initializes the bma456 and verify the  *communication by reading the chip id.  *  * @param[in] void  * @return void  *  */ static void init_comm_test_bma456(void) {     int8_t rslt;                    struct bma4_dev bma456dev = { 0 };       rslt = bma4_interface_init(&bma456dev, BMA4_I2C_INTF, BMA45X_VARIANT);     rslt = bma456_init(&bma456devbma425dev);     if (rslt == BMA4_OK)     {         printf("BMA456 Initialization Success!\n");         printf("Test #1: Communication. PASSED. Chip ID 0x%x\n", bma456dev.chip_id);     }       else     {         char err_string[255];         printf("BMA456 Initialization Failure!\n");                                        if (BMA4_E_INVALID_SENSOR == rslt)         {              sprintf(err_string, "Test #1: Communication. FAILED. Expected Chip ID: 0x%x. Received 0x%x\n",\                             BMA456_CHIP_ID, bma456dev.chip_id);         }         else         {              sprintf(err_string, "Test #1: Communication. FAILED. No response from the sensor.");         }                                        coines_exit_error(err_string);     }     coines_delay_msec(100); } How to test the sensor's functionality The BMA4xy series of accelerometers feature a fully integrated and motionless self-test procedure on the ASIC itself. When the self-test is triggered, the accelerometer uses electric fields to physically move the electrodes in all directions, senses the deflection and compares it with the expected output. Therefore, the built-in self-test features is the recommended way to test the sensor's functionality. Here is some sample code on how to perform this self-test, based on BMA456, using the COINES software as the host. /*!  * @brief This internal API is used to test if the sensor is working by triggering the self-test.  *  * @param[in] void  * @return void  *  */ static void function_test_bma456(void) {     uint16_t rslt;     uint8_t testrslt;       rslt = bma4_perform_accel_selftest(&testrslt, &bma456dev);                    if ( 0 != rslt ) coines_exit_error("Test #2: Functionnality. FAILED. Unknown communication error\n");                if ( BMA4_SELFTEST_PASS == testrslt ) {         printf("Test #2: Functionnality. PASSED. Sensor self-test successful\n");     } else {         printf("Test #2: Functionnality. FAILED. Sensor self-test failed\n");     }                } How to test the sensor's performance There are 2 performance parameters that can easily be tested with the device motionless: offset and noise. See below for the typical values of the sensors. Note: Typical values are defined as ±1σ, which means that we expect 68.3% of sensors to fall within these values. Min/Max values are defined as ±3σ, which means 99.7% of sensors shall be within these values. Parameter BMA456 units Offset ±20 mg Noise 120 µg/√Hz Table 4: Typical performance of BMA456 For the offset, the test procedure is quite simple. With the device in a known position, such as a flat surface, calculate the average value for each axis, and substract the expected output (e.g. 0G, 0G, +1G) from the data. The result is the offset of the sensor. Here is some sample code on how to perform this test, based on BMA456, using the COINES software as the host. /*! Average value calculation */ double x_avg_mg=0; double y_avg_mg=0; double z_avg_mg=0; for (int i=0; i<1000; ++i) {     double xval, yval, zval;     /* ( 'datapoint' * '4G' * '2' * '1000mg') / ('scaling factor for 16 bits') */     xval = (((double)sens_data[i].x) * 4. * 2. * 1000) / pow(2,16);     yval = (((double)sens_data[i].y) * 4. * 2. * 1000) / pow(2,16);     zval = (((double)sens_data[i].z) * 4. * 2. * 1000) / pow(2,16);                                    x_avg_mg += xval / 1000.;     y_avg_mg += yval / 1000.;     z_avg_mg += zval / 1000.; }                /*! Offset Calculation */ double x_off_mg=x_avg_mg - X_REST_POSITION_MG; double y_off_mg=y_avg_mg - Y_REST_POSITION_MG; double z_off_mg=z_avg_mg - Z_REST_POSITION_MG;                if( OFFSET_THRESHOLD_MG > x_off_mg && OFFSET_THRESHOLD_MG > y_off_mg && \                                OFFSET_THRESHOLD_MG > z_off_mg ) {     printf("Test #3: Performance. Offset. PASSED: X=%4.1lfmg Y=%4.1lfmg Z=%4.1lfmg Threshold <\        %4.1lf\n",       x_off_mg, y_off_mg, z_off_mg, OFFSET_THRESHOLD_MG); } else {     printf("Test #3: Performance. Offset. FAILED: X=%4.1lfmg Y=%4.1lfmg Z=%4.1lfmg Threshold <\ %4.1lf\n", x_off_mg, y_off_mg, z_off_mg, OFFSET_THRESHOLD_MG); } The noise calculation is a bit more complicated. First, subtract the offset from each datapoint. The RMS value can be calculated as the square root of the arithmetic mean of the squares of the noise values.  x_rms = sqrt[1/n( x_1^2 + x_2^2 + .... + x_n^2)] Since the noise value is affected by the bandwidth of the digital filter, we need to convert it back to noise density with the following formula. Note: this applied only to a second order filter noise_density = noise_RMS/[sqrt(1.22 x bandwidth)] Here is some sample code on how to perform this test, based on BMA456, using the COINES software as the host. /*! RMS Noise Calculation */ double x_rms_noise_mg=0; double y_rms_noise_mg=0; double z_rms_noise_mg=0; for (int i=0; i<1000; ++i) {     double xval, yval, zval;     /* ( 'datapoint' * '4G' * '2' * '1000mg') / ('scaling factor for 12 bits') */     xval = (((double)sens_data[i].x) * 4. * 2. * 1000.) / pow(2,16);     yval = (((double)sens_data[i].y) * 4. * 2. * 1000.) / pow(2,16);     zval = (((double)sens_data[i].z) * 4. * 2. * 1000.) / pow(2,16);                                    x_rms_noise_mg += pow(xval - x_avg_mg,2) / 1000.;     y_rms_noise_mg += pow(yval - y_avg_mg,2) / 1000.;     z_rms_noise_mg += pow(zval - z_avg_mg,2) / 1000.; }                /* rms noise is the square root of the arithmetic mean of the squares of the noise values */ x_rms_noise_mg = sqrt(x_rms_noise_mg); y_rms_noise_mg = sqrt(y_rms_noise_mg); z_rms_noise_mg = sqrt(z_rms_noise_mg);                /*! RMS Noise to RMS noise density convertion */ /* noise density = RMS noise  / sqrt ( 1.22 * bandwidth) */ /* BMA456 has 40.5Hz bandwidth at 100Hz normal mode */   double x_noise_dens_ug = 1000 * x_rms_noise_mg / sqrt(1.22 * 40.5); double y_noise_dens_ug = 1000 * y_rms_noise_mg / sqrt(1.22 * 40.5); double z_noise_dens_ug = 1000 * z_rms_noise_mg / sqrt(1.22 * 40.5);   if( NOISE_THRESHOLD_MG > x_noise_dens_ug &&                                NOISE_THRESHOLD_MG > y_noise_dens_ug &&                                NOISE_THRESHOLD_MG > z_noise_dens_ug ) {     printf("Test #3: Performance. Noise. PASSED: X=%4.1lfug/sqrt(Hz) Y=%4.1lfug/sqrt(Hz) \ Z=%4.1lfug/sqrt(Hz) Threshold < %4.1lf\n", x_noise_dens_ug, y_noise_dens_ug, z_noise_dens_ug,\ NOISE_THRESHOLD_MG); } else {     printf("Test #3: Performance. Noise. FAILED: X=%4.1lfug/sqrt(Hz) Y=%4.1lfug/sqrt(Hz) \   Z=%4.1lfug/sqrt(Hz) Threshold < %4.1lf\n", x_noise_dens_ug, y_noise_dens_ug,\ z_noise_dens_ug,NOISE_THRESHOLD_MG);   } Calibrating the sensor The first question to ask concerning calibration is whether it is required for the intended application. Accelerometer calibration mainly consists of calibrating the accelerometer's offset. The main impact for this is in tilt-sensing application, where the offset will induce an error in the measurement of the horizon. The accelerometer comes from the factory pre-trimmed, but the soldering process and PCB bending due to assembly can vary the offset, therefore it is preferable to calibrate the accelerometer after assembling the device into the device housing. Pre- and post-calibration accuracy     Sample code The calibration procedure is outlined in the inline calibration application note. Here is some sample code on how to perform this calibration, based on BMA456, using the COINES software as the host. Note : Although the concept is the same, the BMA4xy family of accelerometers does not include a built-in offset calculation on the ASIC. Since the offset are calculated inside of the Sensor API itself, it allows for a much more flexible target position.  rslt = bma456_init(&bma456dev); if (rslt == BMA4_OK) {     printf("BMA456 Initialization Success!\n"); } else {                  coines_exit_error("BMA456 Initialization Failure!\n"); } coines_delay_msec(100); rslt = bma456_write_config_file(&bma456dev); /* Enable the accelerometer */ rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma456dev); /* Set the accel configurations */ struct bma4_accel_config accel_conf = { 0 }; accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ; accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; accel_conf.perf_mode = BMA4_CIC_AVG_MODE; accel_conf.range = BMA4_ACCEL_RANGE_8G; rslt = bma4_set_accel_config(&accel_conf, &bma456dev); dev.delay_us(20000, dev.intf_ptr);                         if (rslt == BMA4_OK) {     /* Set accel foc axis and it's sign (x, y, z, sign)*/ struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 };       rslt = bma4_perform_accel_foc( &g_value_foc, &bma456dev);                          if (rslt == BMA4_OK) {         printf("BMA456 perform FOC successful!\n");         /* Delay after performing Accel FOC */         dev->delay_us(30000, bma456dev ->intf_ptr);         /*! calculates the offset after compensation */         rslt = bma4_read_regs(BMA4_OFFSET_0_ADDR, data_array, 3, & bma456dev);         printf("Post-calibration offset : X=%4.1lfmg Y=%4.1lfmg Z=%4.1lfmg", data_array[0],\                data_array[1], data_array[3]);     } else {                  coines_exit_error("Unknown communication error. Exiting...\n");     } } Once the offsets are determined, they can be written into the NVM so that the sensor automatically compensates for the soldering offset even after physically removing the power. Here is some sample code on how to save calibration data to NVM, based on BMA456, using the COINES software as the host. /*!  * @brief This internal API is used to update the nvm content  *  * @param[in] void  * @return void  *  */ static void bma456_update_nvm(void) {     uint16_t rslt;     uint8_t data;       /* unlocks the NVM for writing */     data = 0x02;     bma4_write_regs(0x6A, &data, 1, &bma456dev);                    /* makes sure the BMA456 is not executing another command */ do {         rslt = bma4_read_regs(BMA4_STATUS_ADDR, &data, 1, &bma456dev);         if ( 0 != rslt ) coines_exit_error("Unknown communication error. Exiting...\n");     } while ( 0 == (data&0x10) );                    /* performs the writing of the NVM */     rslt = bma4_set_command_register( 0xA0,  &bma456dev);     if ( 0 != rslt ) coines_exit_error("Unknown communication error. Exiting...\n");                        /* wait for the command to be completed */ do {         rslt = bma4_read_regs(BMA4_STATUS_ADDR, &data, 1, &bma456dev);         if ( 0 != rslt ) coines_exit_error("Unknown communication error. Exiting...\n");     } while ( 0 == (data&0x10) );                    /* locks the NVM writing */     data = 0x00;     bma4_write_regs(0x6A, &data, 1, &bma456dev); }   Further reads Datasheets: BMA456 Datasheet Application notes: Inline calibration of accelerometers Handling, soldering and mounting instructions, Accelerometers HSMI  
    View full article
    100% helpful (1/1)
    ‎05-31-2021 12:16 PM
    Frequently Asked Questions (FAQs) about the BMP384 sensor
    View full article
    100% helpful (7/7)
    ‎05-31-2021 12:09 PM
    Frequently Asked Questions (FAQs) about the BME688 sensor
    View full article
    100% helpful (1/1)
    ‎05-31-2021 12:09 PM
    Frequently Asked Questions (FAQs) about the BHI260AP sensor
    View full article
    ‎04-01-2021 10:22 AM
    Please find attached the two white papers for our BHI260AP self-learning AI sensor: White paper: Me, myself and AI How the new self-learning AI sensor pesonalizes your home workout Fitness tracking is presently experiencing a huge upswing in popularity. The market for fitness trackers and step counters has surged by 65% year-on-year [1], with just the Fitbit platform alone claiming nearly 30 million active users [2]. Current activity tracking devices have demonstrated the huge market potential of this segment and have laid the groundwork for next-generation AI-enabled devices to take centre stage as individual fitness tracking goes mainstream. White paper: Swim like a fish with Artificial Intelligence Combining AI and sensors to create a new generation of intelligent wearables Artificial intelligence (AI) is rapidly becoming a natural and integral part of our everyday lives – working silently and unnoticed in the background. AI makes sense of the multitude of data streaming in from various sensors to deliver detailed and precise insights, which have the potential to increase the utility of virtually all electronic devices on the market today. This defining technology can accurately determine whether the user of a device is walking, running, sitting, sleeping – or even swimming in real-time. This article explores how sensors synergize with AI in wearables to deliver valuable information to users – even in demanding environments like swimming pools.
    View full article
    100% helpful (4/4)
    ‎06-19-2020 11:54 AM
    step by step how to use python scripts with our Bosch Sensortec APP 2.0
    View full article
    ‎06-15-2020 05:05 AM
    For customer usage, you need to download the sensor driver package from the website to communicate with sensor after connecting the BMP388 chip to your developing board.  You can find the information from the following link https://github.com/BoschSensortec/BMP3-Sensor-API. The procedure of using BMP388 sensor API is presented in the following flow chart: The detailed example code for integration of API could be found in: https://github.com/BoschSensortec/BMP3-Sensor-API/blob/master/README.md Following steps need to be considered to ensure the API/sensor configured correctly. For reading the data information from API, the following example can follow 1.The following static function should be added into your own project static int64_t compensate_temperature static uint64_t compensate_pressure static double bmp3_pow static void parse_calib_data static double compensate_temperature_d static double compensate_pressure_d 2.Define the main function to print the data, the structure for BMP3 and put the trimming data into the correct position as follow. One example shown below calib_data->reg_calib_data.par_t1 = (int16_t)27402; calib_data->reg_calib_data.par_t2 = (int16_t)18868; calib_data->reg_calib_data.par_t3 = (int8_t)-10; calib_data->reg_calib_data.par_p1 = (int16_t)-244; calib_data->reg_calib_data.par_p2 = (int16_t)-3254; calib_data->reg_calib_data.par_p3 = (int8_t)35; calib_data->reg_calib_data.par_p4 = (int8_t)0; calib_data->reg_calib_data.par_p5 = (int16_t)25879; calib_data->reg_calib_data.par_p6 = (int16_t)31477; calib_data->reg_calib_data.par_p7 = (int8_t)-13; calib_data->reg_calib_data.par_p8 = (int8_t)-10; calib_data->reg_calib_data.par_p9 = (int16_t)16342; calib_data->reg_calib_data.par_p10 = (int8_t)29; calib_data->reg_calib_data.par_p11 = (int8_t)-60; 3.Give the correct default value to the uncompensated temperature and pressure, define the version to temperature and pressure. uncomp_data->pressure = 8241776; uncomp_data->temperature = 8329880; double temp = compensate_temperature_d(uncomp_data, calib_data); double press = compensate_pressure_d(uncomp_data, calib_data); double tempurature = temp; double pressure = press; 4.Print out the final value printf("Temperature\t Pressure\t\n"); printf("%0.2f\t\t %0.2f\t\t\n", tempurature, pressure); system("pause");  
    View full article
    ‎06-15-2020 04:52 AM
    General Description The BME280 is a combined digital humidity, pressure and temperature sensor based on proven sensing principles. The API can be downloaded from Github. The BSEC can be downloaded from the Bosch Sensortec website. Sensor Data The humidity sensor data is expressed as a percentage (10% - 90% at 0°C-65°C). The pressure sensor data is in hPa (300hPa - 1100hPa at 0°C-65°C). The temperature sensor data is in °C (-40°C - 85°C). The function bme280_get_sensor_data in the API is used to get the sensor data. Accuracy The accuracy represents how accurate the sensor can be under certain condition. Table 1 lists the accuracy of humidity sensor, pressure sensor, and temperature sensor. Pressure Sensor Drift The pressure sensor drift represents the error in the measured value. Basically, there are two drifts on the pressure part in the BME280, i.e. solder drift and long-term drift. Pressure Sensor TCO The TCO (offset temperature coefficient) is the change in the pressure signal caused by a change in the temperature. For the pressure sensor, the TCO is ±1.5 Pa/K, equivalent to ±12.6 cm at 1 °C temperature change, which means the pressure sensor data changes within ±1.5 Pa, with 1 °C temperature change at constant pressure. Working Mode The BME280 can be operated in three working modes: sleep mode, normal mode, and force mode, which can be selected using the mode [1:0] setting (in register 0xF4 [1:0], sleep mode -> b11, force mode -> b10 and b01, normal mode -> b11). The function bme280_set_sensor_mode in the API can also used to set power mode. During the measurement cycle, the BME280 measures temperature, pressure and humidity, with optional oversampling. After the measurement cycle, the pressure and temperature data can be passed through an optional IIR filter, which removes short-term fluctuations in pressure (e.g. caused by slamming a door). For humidity, such a filter is not needed and has not been implemented. Humidity/Pressure/Temperature OSR Oversampling can be enabled during the measurement, which can reduce noise but also consumes more power. Different sensors have different OSRs (oversampling rate). The osrs_h<2:0> settings are explained as follows: b000-> skip humidity data/no humidity b001-> oversamplingx1 b010-> oversamplingx2 b011-> oversamplingx4 b100-> oversamplingx8 b101, and other settings -> oversamplingx16  The osrs_p<4:2> settings are explained as follows: b000-> skip humidity data/no humidity b001-> oversamplingx1 b010-> oversamplingx2 b011-> oversamplingx4 b100-> oversamplingx8 b101, and other settings-> oversamplingx16 The osrs_t<7:5> settings are explained as follows: b000-> skip humidity data/no humidity b001-> oversamplingx1 b010-> oversamplingx2 b011-> oversamplingx4 b100-> oversamplingx8 b101, and other settings-> oversamplingx16   The function bme280_set_sensor_settings in the API can also be used to set the OSR for any sensor. See below for the example.   ... int8_t rslt; uint8_t settings_sel; dev->settings.osr_h = BME280_OVERSAMPLING_1X; dev->settings.osr_p = BME280_OVERSAMPLING_16X; dev->settings.osr_t = BME280_OVERSAMPLING_2X; ... settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL; rslt = bme280_set_sensor_settings(settings_sel, dev); .... return rslt; ... Signal Filter The environmental pressure is subject to many short-term changes caused by, for example, door or window slamming, wind blowing into the sensor, etc. The BME280 features an internal IIR filter which can suppress these disturbances in the output data without causing additional interface traffic and processor workload. By setting the filter coefficient (c), the bandwidth of the temperature and pressure output signals can be effectively reduced and the resolution of the pressure and temperature output data can be increased to 20 bits. The output of the next measurement step is filtered using the following formula:  Where, data_filter_old is the data coming from the current filter memory. data_ADC is the data coming from current ADC acquisition. data_filtered is the new value of filter memory and the value that will be sent to the output registers.   The filter<4:2> settings are explained as follows: b000-> Filter off b001-> filter coefficient 2 b010-> filter coefficient 4 b011-> filter coefficient 8 b100, and other settings-> filter coefficient 16   The function bme280_set_sensor_settings in the API can also be used to set filter. See below for the example. ... int8_t rslt; uint8_t settings_sel; ... dev->settings.filter = BME280_FILTER_COEFF_16; ... settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL; ... rslt = bme280_set_sensor_settings(settings_sel, dev); ... return rslt; ​
    View full article
    100% helpful (2/2)
    ‎11-12-2019 08:33 AM
    Introduction This document is meant as a reference guide on how to design using Bosch Sensortec’s BHy1. BHy1 family includes two parts, one is BHA250 series, the other is BHI160 series. Selecting the right part The BHA250 contains part number: BHA250 and BHA250B. The BHA250/BHA250B is sensor hub which integrated Accelerometer. Figure1 shows the BHA250 laser marking.                                                                                              Fig1 The BHI160 contains part number: BHI160and BHI160B. The BHI160/ BHI160B is smart sensor which integrated IMU(ACC+Gyro). Figure2 shows the laser marking.                                                                                                  Fig2 Common Characteristics Key features 1xI2C(3.4MHz) Host Interface; 1xI2C(1MHz) Aux Interface; up to 3 GPIOs 32-bit Floating-point; 96 KB ROM; 48 KB RAM Max ODR is 200Hz  Difference between products                                                 Table 1: Difference on BHA250 and BHI160                                           Table 2: Accelerometer Parameter on BHA250 and BHI160                                                        Table 3: BHI160 Gyroscope Parameter  Available evaluation tools and software To best to evaluate the products from the BHy1 family is the following combination of evaluation tools: COINES Desktop software Application board 2.0 Sensor Shuttle board BHI160/BHI160B Shuttle board BHI250/BHA250B Shuttle board Reference design See Figure 3 for BHA250 schematic of a typical use-case.                                                                      Figure3  BHA250/BHA250B typical schematic Bill of materials: Note: R3 and R4 are mandatory, even if no external sensor is attached. Layout recommendations Landing Pattern                                          Figure5: BHA250/BHA250B Landing Pattern                                                       Figure6: BHI160/BHI160B Landing Pattern  Typical Layout                                                       Figure7: BHA250/BHA250B Layout                                                            Figure8: BHI160/BHI160B Layout Manufacturing notes BHy1 on COINES COINES setup       Platform: Windows gcc: "C:\DiaSemi\SmartSnippetsStudio\Tools\mingw64_targeting32\bin\gcc.exe C:\TDM-GCC-64\bin\gcc.exe". [ MKDIR ] build [ CC ] bhy_activity_recognition.c [ CC ] ../../../../sensorAPI/bhy/src/BHy_support.c [ CC ] ../../../../sensorAPI/bhy/src/bhy_uc_driver.c [ CC ] ../../../../sensorAPI/bhy/src/bhy.c [ CC ] ../../../../sensorAPI/bhy/AppBoard_usb_driver/AppBoard_usb_driver.c [ MAKE ] coinesAPI [ MKDIR ] build [ CC ] coines.c [ CC ] comm_intf/comm_intf.c [ CC ] comm_intf/comm_ringbuffer.c [ CC ] comm_driver/usb.c [ CC ] comm_driver/legacy_usb/legacy_usb_support.c [ AR ] libcoines [ LD ] bhy_activity_recognition.exe Operation finished successfully Running on BHy1 shuttle board Connect with APP2.0 board (BHy1 Shuttle board) and compile the sample code (..\..\examples\c\bhy\rotation_vector), Click  to run and get the output on the console. Running example 'bhy_rotation_vector.exe' ... uploading RAM patch... W: 1.000 X: 0.000 Y: 0.000 Z: 0.000 W: 1.000 X:-0.000 Y: 0.000 Z: 0.000 W: 1.000 X:-0.000 Y: 0.000 Z: 0.000 W: 0.999 X: 0.005 Y: 0.018 Z: 0.000 W: 0.999 X: 0.005 Y: 0.018 Z: 0.000 W: 0.999 X: 0.005 Y: 0.018 Z: 0.000 W: 0.999 X: 0.005 Y: 0.018 Z: 0.000 BHy1 example code on COINES Activity recognition example Data parsing for activity recognition is available in COINES. The user can open the “bhy_activity_recognition.c” in COINES, compile and run. The output will be shown in the COINES console. The code is shown as below.     /* @brief This API is used for parsing the activity recognition data from BHY * * @param[in] sensor_data: bhy data * @param[in] sensor_id: bhy id * * @return void * */ void sensors_callback(bhy_data_generic_t * sensor_data, bhy_virtual_sensor_t sensor_id) { float temp; u8 index; /* Since a timestamp is always sent before every new data, and that the callbacks */ /* are called while the parsing is done, then the system timestamp is always equal */ /* to the sample timestamp. (in callback mode only) */ temp = g_system_timestamp / 3200000.; for (index = 6; index <= 8; index++) { outBuffer[index] = floorf(temp) + '0'; temp = (temp - floorf(temp)) * 10; } for (index = 10; index <= 12; index++) { outBuffer[index] = floorf(temp) + '0'; temp = (temp - floorf(temp)) * 10; } /* if there are no changes then it will read X */ outBuffer[22] = 'X'; outBuffer[35] = 'X'; outBuffer[48] = 'X'; outBuffer[61] = 'X'; outBuffer[74] = 'X'; outBuffer[87] = 'X'; /* '0' means "end of activity and '1' means start of activity */ if (sensor_data->data_scalar_u16.data & 0b0000000000000001) outBuffer[22] = '0'; if (sensor_data->data_scalar_u16.data & 0b0000000000000010) outBuffer[35] = '0'; if (sensor_data->data_scalar_u16.data & 0b0000000000000100) outBuffer[48] = '0'; if (sensor_data->data_scalar_u16.data & 0b0000000000001000) outBuffer[61] = '0'; if (sensor_data->data_scalar_u16.data & 0b0000000000010000) outBuffer[74] = '0'; if (sensor_data->data_scalar_u16.data & 0b0000000000100000) outBuffer[87] = '0'; if (sensor_data->data_scalar_u16.data & 0b0000000100000000) outBuffer[22] = '1'; if (sensor_data->data_scalar_u16.data & 0b0000001000000000) outBuffer[35] = '1'; if (sensor_data->data_scalar_u16.data & 0b0000010000000000) outBuffer[48] = '1'; if (sensor_data->data_scalar_u16.data & 0b0000100000000000) outBuffer[61] = '1'; if (sensor_data->data_scalar_u16.data & 0b0001000000000000) outBuffer[74] = '1'; if (sensor_data->data_scalar_u16.data & 0b0010000000000000) outBuffer[87] = '1'; fprintf(stderr, "%s", outBuffer); /* activity recognition is not time critical, so let's wait a little bit */ mdelay(200); }      Gesture recognition example Data parsing for gesture recognition is available in COINES. The user can open the “bhy_gesture_recognition.c” in COINES, compile and run. The output will be shown in COINES console. In the example code, three gestures are enabled, which are “Glance, Pickup and Significant Motion”. The code is shown as below.     /* @brief This API is used for parsing the activity recognition data from BHY * * @param[in] sensor_data: bhy data * @param[in] sensor_id: bhy id * * @return void * */ void sensors_callback(bhy_data_generic_t * sensor_data, bhy_virtual_sensor_t sensor_id) { float temp; u8 index; /* Since a timestamp is always sent before every new data, and that the callbacks */ /* are called while the parsing is done, then the system timestamp is always equal */ /* to the sample timestamp. (in callback mode only) */ temp = g_system_timestamp / 3200000.; for (index = 6; index <= 8; index++) { outBuffer[index] = floorf(temp) + '0'; temp = (temp - floorf(temp)) * 10; } for (index = 10; index <= 12; index++) { outBuffer[index] = floorf(temp) + '0'; temp = (temp - floorf(temp)) * 10; } sensor_id &= 0x1F; /* gesture recognition sensors are always one-shot, so you need to */ /* re-enable them every time if you want to catch every event */ bhy_enable_virtual_sensor(sensor_id, VS_WAKEUP, 1, 0, VS_FLUSH_NONE, 0, 0); switch (sensor_id) { case VS_TYPE_GLANCE: strcpy(&outBuffer[24], "Glance \r\n"); break; case VS_TYPE_PICKUP: strcpy(&outBuffer[24], "Pickup \r\n"); break; case VS_TYPE_SIGNIFICANT_MOTION: strcpy(&outBuffer[24], "Sig motion\r\n"); break; default: strcpy(&outBuffer[24], "Unknown \r\n"); break; } fprintf(stderr, "%s", outBuffer); fflush(stderr); }     Gravity vector example Data parsing for gravity vector is available in COINES. The user can open the “bhy_gravity_vector.c” in COINES, compile and run. The output will be shown in COINES console. The code is shown as below.     /* @brief This API is used for parsing the activity recognition data from BHY * * @param[in] sensor_data: bhy data * @param[in] sensor_id: bhy id * * @return void * */ void sensors_callback(bhy_data_generic_t * sensor_data, bhy_virtual_sensor_t sensor_id) { float temp; u8 index; temp = sensor_data->data_vector.x / 8192.; outBuffer[3] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[4] = floorf(temp) + '0'; for (index = 6; index <= 8; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } temp = sensor_data->data_vector.y / 8192.; outBuffer[13] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[14] = floorf(temp) + '0'; for (index = 16; index <= 18; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } temp = sensor_data->data_vector.z / 8192.; outBuffer[23] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[24] = floorf(temp) + '0'; for (index = 26; index <= 28; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } fprintf(stderr, "%s", outBuffer); fflush(stderr); }     Rotation vector example Data parsing for Rotation Vector is available in COINES. The user can open the “bhy_rotation_vector.c” in COINES, compile and run. The output will be shown in COINES console. The code is shown as below.     /* @brief This API is used for parsing the activity recognition data from BHY * * @param[in] sensor_data: bhy data * @param[in] sensor_id: bhy id * * @return void * */ void sensors_callback(bhy_data_generic_t * sensor_data, bhy_virtual_sensor_t sensor_id) { float temp; u8 index; temp = sensor_data->data_quaternion.w / 16384.; outBuffer[3] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[4] = floorf(temp) + '0'; for (index = 6; index <= 8; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } temp = sensor_data->data_quaternion.x / 16384.; outBuffer[13] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[14] = floorf(temp) + '0'; for (index = 16; index <= 18; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } temp = sensor_data->data_quaternion.y / 16384.; outBuffer[23] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[24] = floorf(temp) + '0'; for (index = 26; index <= 28; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } temp = sensor_data->data_quaternion.z / 16384.; outBuffer[33] = temp < 0 ? '-' : ' '; temp = temp < 0 ? -temp : temp; outBuffer[34] = floorf(temp) + '0'; for (index = 36; index <= 38; index++) { temp = (temp - floorf(temp)) * 10; outBuffer[index] = floorf(temp) + '0'; } fprintf(stderr, "%s", outBuffer); fflush(stderr); }      Create customer example Customer can create their own case based on the sensor they used in the folder “examples”, for example, BHI160 Shuttle board, we can create a new folder “acc_gyro data output” Create the file and copy “Makefile” from other bhy example(like gravity_vector) Modify the Makefile                                           #CCE_Board_Definitions:BHI160;BHI160B;BHA250;BHA250B COINES_INSTALL_PATH ?= ../../../.. EXAMPLE_FILE ?= acc_gyro data output.c SHUTTLE_BOARD ?= BHI160 CFLAGS += -DBST_APPBOARD_VIA_USB -D$(SHUTTLE_BOARD) include $(COINES_INSTALL_PATH)/examples/c/examples.mk Now, you can make, compile and run your own code via COINES. Further reads BHA250/BHA250B Datasheet BHI160/BHI160B Datasheet BHy1 Handling, Soldering & Mounting Instructions BHy1 MCU Driver Porting Guide BHy1 Interfacing reference code from generic driver                                 
    View full article
    ‎10-14-2019 03:27 PM
    BME680 is as combined digital gas, humidity, pressure and temperature sensor based on proven sensing principles. API Link: https://github.com/BoschSensortec/BME680_driver BSEC Link: https://www.bosch-sensortec.com/bst/products/all_products/bme680 Sensor data type Gas sensor data is gas sensor resistance. Humidity sensor data is in type of percentage (10%-90%, in 0°C-65°C). Pressure sensor data is in type of hPa (300hPa-1100hPa, in 0°C-65°C). Temperature sensor data is in type of °C (-40°C-85°C). Use function bme680_get_sensor_data in API to get sensor data. Use BSEC software Library, put gas/humidity/pressure/temperature sensor data as inputs into BSEC, you can also get IAQ(Indoor Air Quality) from outputs. Measurement preiod The BME680 measurement period consists of a temperature, pressure and humidity measurement with selectable oversampling. Moreover, it contains a heating phase for the gas sensor hot plate as well as a measurement of the gas sensor resistance. After the measurement period, the pressure and temperature data can be passed through an optional IIR filter, which removes short-term fluctuations in pressure (e.g. caused by slamming a door). For humidity and gas, such a filter is not needed and has not been implemented Gas resistance sensitivity The sensitivity of BME680 to certain target gas is gas_resistance/gas_resistance_base. The sensitivity equaling to 1 means BME680 is not sensitivity in this concentration of the target gas, while the less value in sensitivity, the more sensitive BME680 to the target gas.  Data Interrupt There is new data interrupt in BME680, below table shows how to enable this feature.  Pressure sensor drift Used to represent errors in measured values. Basically, two drifts will appear on the pressure part in BME680: one is solder drifts and the other is long term drift.  Pressure sensor offset temperature coefficient (TCO) TCO is the change in the pressure signal introduced by a change of the temperature. For pressure sensor, TCO is ±1.5 Pa/K, equiv. to ±12.6 cm at 1 °C temperature change, which means pressure sensor data will change within ±1.5 Pa with 1 °C temperature change at constant pressure. Accuracy of temperature/pressure/humidity This feature is used to represent how much accuracy can be achieved on certain condition. Humidity sensor: ±3 % relative humidity, on condition: 20-80 %r.H., 25°C, including hysteresis Pressure sensor: 0.12 hPa, on condition: 25°C-40°C, 700-1100hPa, at constat humidity Temperature Sensor: ±1°C, on condition: 25°C ±0.5°C, on condition: 0…65°C OSR / Oversampling of humidity/pressure/temperature There are several oversampling options for different sensors. It is possible to reduce noise, but the power consumption will be higher. Humidity sensor OSR  As for how to set osrs_h<2:0>, b000->skip humidity data/no humidity, b001->oversamplingx1, b010->oversamplingx2, b011->oversamplingx4, b100->oversamplingx8, b101/Others->oversamplingx16. Pressure sensor OSR  As for how to set osrs_p<4:2>, b000->skip humidity data/no humidity, b001->oversamplingx1, b010->oversamplingx2, b011->oversamplingx4, b100->oversamplingx8, b101/Others->oversamplingx16. Temperature sensor OSR  As for how to set osrs_t<7:5>, b000->skip humidity data/no humidity, b001->oversamplingx1, b010->oversamplingx2, b011->oversamplingx4, b100->oversamplingx8, b101/Others->oversamplingx16. You can use function bme680_set_sensor_settings in API to set OSR of any sensor. Signal filter The environmental pressure is subject to many short-term changes, caused e.g. by slamming of a door or window, or wind blowing into the sensor. To suppress these disturbances in the output data without causing additional interface traffic and processor work load, the BME680 features an internal IIR filter. Via setting filter coefficient(c), it effectively reduces the bandwidth of the temperature and pressure output signals and increases the resolution of the pressure and temperature output data to 20 bit(Pressure and Temperature OSR must be non-zero). When c is bigger, response time will be longer.  As for how to set filter<4:2>, b000->filter coefficient 0, b001-> filter coefficient 1, b010-> filter coefficient 3, b011-> filter coefficient 7, b100-> filter coefficient 15, b101-> filter coefficient 31,  b110-> filter coefficient 63, b111-> filter coefficient 127. You can use function bme680_set_sensor_settings in API to set filter.    
    View full article
    ‎08-15-2019 11:12 AM
    Introduction This document is intended as a reference guide on how to design using Bosch Sensortec’s BMI08x series IMU. It describes the main features of the BMI08x family, available evaluation tools and software, reference design, layout recommendations, and gives instructions on how to test the BMI08x family’s functionality using sample codes, and how to demonstrate and evaluate it with COINES. Selecting the right part The BMI08x family has two products: BMI085 and BMI088, which are ideally suited for high-performance consumer applications. The BMI085 is designed for virtual augmented and mixed reality applications, high-end gaming, platform stabilization applications such as image stabilization, as well as indoor navigation and dead reckoning, such as robotics applications. The BMI088 is designed for applications in harsh vibration environments such as drones and robotics. The IMU is designed to effectively suppress vibration above several hundred Hz, which may occasionally occur due to resonance on the PCB or the structure of the total system. Table 1 shows an overview of the features.                                                                           Table 1: Overview of the features Key features This section describes the key features of the BMI08x family. Good stability of TCO, TCS, bias and stress Low latency BMI088 has vibration robustness and suppression BMI085 has integrated accelerometer and gyroscope data synchronization function  Differences between products The main differences between the BMI08x family products are the accelerometer part and the overall performance of the MEMS element.                                                                                                                                       Table 2: Main differences Available evaluation tools and software To best evaluate the BMI08x family, the following combination of evaluation tools is recommended: COINES Desktop software (Windows version &Linux version & MacOS) Development Desktop Software Application board 2.0 Sensor shuttle board BMI085 shuttle board BMI088 shuttle board Hardware reference design Figure 1 and Figure 2 show the I2C and SPI reference designs for BMI085 and BMI088                                                                                       Figure 1: I2C connection                                                                       Figure 2: SPI connection Bill of materials Table 3 lists the bill of necessary materials.                                                                                                                                     Table 3: Bill of materials Layout recommendations Because the BMI08x sensor family contains tiny mechanical structures inside the package, care must be taken during the layout phase to ensure optimum performance. The complete handing and soldering guide can be found on the Bosch Sensortec’s website. The typical manufacturing procedures for the BMI08x IMU are described in the following sections. Recommended layout rules The recommended layout rules are as follows: PCB land width = LGA solder pin width PCB land length = LGA solder pin length + 0.1mm on each side Solder mask opening width = PCB land width + 0.05mm on each side Solder mask opening length = PCB land     Landing Pattern The BMI08x family has the same landing pattern. The following dimensioning is recommended.                                            Figure 3: Recommended landing pattern (top view, in mm) Typical Layout Figure 4 shows the typical layout.                                                                                      Figure 4: Typical layout  Manufacturing notes Table 4 lists the recommendations for the manufacture.                                                                           Table 4: Manufacture recommendations First power-on This chapter describes how to test the BMI08x family’s functionality and performance after powering it on for the first time. To properly initialize the device, the user must decide which interface to use (I2C or SPI) during hardware design. With the PS pin, the user can determine which interface the sensor should listen to. The gyroscope part of the BMI08x initializes its I/O pins according to the selection given by the PS pin. The accelerometer part starts and remains in I2C mode. When a rising edge is detected on the CSB1 pin (chip select of the accelerometer), the accelerometer part switches to SPI mode and remains until the next power-up reset. To switch the accelerometer to SPI mode, the user can perform a dummy SPI read operation during the initialization phase. After the power-on reset, the gyroscope enters normal mode, while the accelerometer enters suspend mode. To switch the accelerometer to normal mode, do the following: Power up the sensor. Wait for 1ms Enter normal mode by writing ‘4’ to ACC_PWR_CTRL. Wait for 50ms. The accelerometer enters normal mode. Below are some example codes for performing tests based on BMI08x shuttle board and API, using the COINES software as the host. To test the BMI08x family’s functionality, do the following: 1) Initialize the sensor driver API interface (based on GenAPI and COINES as example) /*! * @brief this internal API is used to set the sensor driver interface to * read/write the data. * * @param[in] void * * @return void * */ static void init_bmi08x_sensor_driver_interface(void) { #if BMI08x_INTERFACE_I2C==1 /* I2C setup */ /* link read/write/delay function of host system to appropriate * bmi08x function call prototypes */ bmi08xdev.write = coines_write_i2c; bmi08xdev.read = coines_read_i2c; bmi08xdev.delay_ms = coines_delay_msec; /* set correct i2c address */ bmi08xdev.accel_id = (unsigned char) BMI08x_ACCEL_DEV_ADDR; bmi08xdev.gyro_id = (unsigned char) BMI08x_GYRO_DEV_ADDR; bmi08xdev.intf = BMI08X_I2C_INTF; #endif #if BMI08x_INTERFACE_SPI==1 /* SPI setup */ /* link read/write/delay function of host system to appropriate * bmi08x function call prototypes */ bmi08xdev.write = coines_write_spi; bmi08xdev.read = coines_read_spi; bmi08xdev.delay_ms = coines_delay_msec; bmi08xdev.intf = BMI08X_SPI_INTF; bmi08xdev.accel_id = COINES_SHUTTLE_PIN_8; bmi08xdev.gyro_id = COINES_SHUTTLE_PIN_14; #endif } 2)  Set up the communication between Bosch Sensortec application board 2.0 and PC, and get the board hardware and software information. struct coines_board_info board_info; int16_t rslt; rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); if (rslt < 0) { printf("\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); exit(rslt); } rslt = coines_get_board_info(&board_info); if (rslt == COINES_SUCCESS) { if ((board_info.shuttle_id != BMI085_SHUTTLE_ID) && (board_info.shuttle_id != BMI088_SHUTTLE_ID)) { printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); exit(COINES_E_FAILURE); } } 3)Initialize the sensor interface, protocol, and power on VDD and VDDIO. /*********************************************************************/ /* functions */ /*! * @brief This internal API is used to initialize the sensor interface depending * on selection either SPI or I2C. * * @param[in] void * * @return void * */ static void init_sensor_interface(void) { /* Switch VDD for sensor off */ coines_set_shuttleboard_vdd_vddio_config(0, 0); coines_delay_msec(10); #if BMI08x_INTERFACE_I2C==1 /* set the sensor interface as I2C with 400kHz speed*/ coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); coines_delay_msec(10); /* PS pin is made high for selecting I2C protocol*/ coines_set_pin_config(COINES_SHUTTLE_PIN_9, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); #endif #if BMI08x_INTERFACE_SPI==1 /* CS pin is made high for selecting SPI protocol*/ coines_set_pin_config(COINES_SHUTTLE_PIN_8, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); /* CS pin is made high for selecting SPI protocol*/ coines_set_pin_config(COINES_SHUTTLE_PIN_14, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); /* PS pin is made low for selecting SPI protocol*/ coines_set_pin_config(COINES_SHUTTLE_PIN_9, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); coines_delay_msec(10); coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); #endif coines_delay_msec(10); /* Switch VDD for sensor on */ coines_set_shuttleboard_vdd_vddio_config(3300, 3300); } 4) After a delay of approximately 200ms, call the BMI08x API to initialize the BMI08x, including its power mode, ODR, bandwidth, range. /*! * @brief This internal API is used to initialize the bmi08x sensor * settings like power mode and OSRS settings. * * @param[in] void * * @return void * */ static void init_bmi08x(void) { if (bmi08a_init(&bmi08xdev) == BMI08X_OK && bmi08g_init(&bmi08xdev) == BMI08X_OK) { printf("BMI08x initialization success !\n"); printf("Accel chip ID - 0x%x\n", bmi08xdev.accel_chip_id); printf("Gyro chip ID - 0x%x\n", bmi08xdev.gyro_chip_id); } else { printf("BMI08x initialization failure !\n"); exit(COINES_E_FAILURE); } bmi08xdev.accel_cfg.odr = BMI08X_ACCEL_ODR_1600_HZ; #if BMI08X_FEATURE_BMI085 == 1 bmi08xdev.accel_cfg.range = BMI085_ACCEL_RANGE_16G; #elif BMI08X_FEATURE_BMI088 == 1 bmi08xdev.accel_cfg.range = BMI088_ACCEL_RANGE_24G; #endif bmi08xdev.accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE; //user_accel_power_modes[user_bmi088_accel_low_power]; bmi08xdev.accel_cfg.bw = BMI08X_ACCEL_BW_NORMAL; /* Bandwidth and OSR are same */ bmi08a_set_power_mode(&bmi08xdev); coines_delay_msec(10); bmi08a_set_meas_conf(&bmi08xdev); coines_delay_msec(10); bmi08xdev.gyro_cfg.odr = BMI08X_GYRO_BW_230_ODR_2000_HZ; bmi08xdev.gyro_cfg.range = BMI08X_GYRO_RANGE_250_DPS; bmi08xdev.gyro_cfg.bw = BMI08X_GYRO_BW_230_ODR_2000_HZ; bmi08xdev.gyro_cfg.power = BMI08X_GYRO_PM_NORMAL; bmi08g_set_power_mode(&bmi08xdev); coines_delay_msec(10); bmi08g_set_meas_conf(&bmi08xdev); coines_delay_msec(10); } 5. Call the BMI08x API to read Acc and Gyro data in a while loop. int times_to_read = 0; while (times_to_read < 10) { bmi08a_get_data(&bmi08x_accel, &bmi08xdev); printf("ax:%d ay:%d az:%d\n", bmi08x_accel.x, bmi08x_accel.y, bmi08x_accel.z); bmi08g_get_data(&bmi08x_gyro, &bmi08xdev); printf("gx:%d gy:%d gz:%d\n", bmi08x_gyro.x, bmi08x_gyro.y, bmi08x_gyro.z); fflush(stdout); coines_delay_msec(10); times_to_read = times_to_read + 1; } coines_close_comm_intf(COINES_COMM_INTF_USB); Calibration Both accelerometer part and gyroscope part of the BMI08x are pre-trimmed at the factory. However, the soldering process and PCB bending due to assembly can result in offset changing; therefore, it is recommended to calibrate the sensor after assembling the device into the device housing. The acceleration sensor offset consists of two parts: the static “unwanted” offset mainly due to soldering drift, and the offset generated when an acceleration is applied to the sensor. The latter depends on the applied acceleration and its magnitude if defined by the sensor’s sensitivity. However, the sensitivity has a certain tolerance (typ. <1%). This means that in order to compensate for the static offset, the sensor must be oriented in such a way that no external acceleration is applied to the sensing axis. As gravity also causes a sensor signal, the sensing axis must be oriented perpendicular to the gravity field. The compensation process described below focuses on the x/y-axis. The z-axis can also be compensated in the same way, but the user has to consider the applied gravity. Alternatively, the process can be repeated after turning the device, with the z-axis perpendicular to the gravity vector. Place your sensor (the system with the sensor inside) on a well-defined surface, for example, a horizontal table. The expected sensor output for the x/y-axis should be 0 mg. Set the sensor to the lowest g-range (BMI085 to 2G, BMI088 to 3G) Measure the sensor output to ensure the sensor is fully at rest, without vibrations, inclinations, big temperature changes or strong VDD fluctuations. It is advisable to take several values and generate the average over the values (e.g. 1000 values). Consider the resolution of BMI085 and BMI088, and save the offset in LSB or mg. Subtract the offset from the future accelerometer sensor data. The gyroscope part of the BMI08x has outstanding offset performance and very high offset stability. However, small offsets may still occur and change over the operation time (mainly due to changes in the operation temperature). As the needs vary from application to application, the application should take care of the offset compensation. To do this, the application has to ensure that the gyroscope is fully at rest when compensating for the offset. Only at rest the static offset can be separated from any motion-based offset. This can be achieved for example by monitoring the accelerometer signals of all axes and checking the noise of each axis. If the noise is below certain threshold (application specific), the application can assume that the sensor is at rest. While monitoring, the device remains at rest and the host can read sensor values, for example, for ten seconds. The average of the gathered values per axis shows the residual offset and can be subtracted from any future the sensor data. Example code The code below shows how to read the BMI08x sensor data via BMI08x API and COINES system. /*! * @brief This internal API is used to read sensor data * * @param[in] void * * @return void * */ void read_sensor_data(void) { int16_t rslt; int counter = 0; uint8_t lsb, msb; int16_t ax, ay, az, gx, gy, gz; uint32_t valid_sample_count = 0; int idx = 0; int buffer_index = 0; while (counter < 1000) { memset(&bmi08x_accel_stream_buffer[0], 0, COINES_STREAM_RSP_BUF_SIZE); rslt = coines_read_stream_sensor_data(1, 1, &bmi08x_accel_stream_buffer[0], &valid_sample_count); if (rslt == COINES_SUCCESS) { buffer_index = 0; for (idx = 0; idx < valid_sample_count; idx++) { #if BMI08x_INTERFACE_SPI==1 buffer_index++; //dummy byte; ignore for spi #endif lsb = bmi08x_accel_stream_buffer[buffer_index++]; msb = bmi08x_accel_stream_buffer[buffer_index++]; ax = (msb << 😎 | lsb; lsb = bmi08x_accel_stream_buffer[buffer_index++]; msb = bmi08x_accel_stream_buffer[buffer_index++]; ay = (msb << 😎 | lsb; lsb = bmi08x_accel_stream_buffer[buffer_index++]; msb = bmi08x_accel_stream_buffer[buffer_index++]; az = (msb << 😎 | lsb; printf("ax: %-5d \t ay: %-5d \t az: %-5d\n", ax, ay, az); fflush(stdout); } } memset(&bmi08x_gyro_stream_buffer[0], 0, COINES_STREAM_RSP_BUF_SIZE); rslt = coines_read_stream_sensor_data(2, 1, &bmi08x_gyro_stream_buffer[0], &valid_sample_count); if (rslt == COINES_SUCCESS) { buffer_index = 0; for (idx = 0; idx < valid_sample_count; idx++) { lsb = bmi08x_gyro_stream_buffer[buffer_index++]; msb = bmi08x_gyro_stream_buffer[buffer_index++]; gx = (msb << 😎 | lsb; lsb = bmi08x_gyro_stream_buffer[buffer_index++]; msb = bmi08x_gyro_stream_buffer[buffer_index++]; gy = (msb << 😎 | lsb; lsb = bmi08x_gyro_stream_buffer[buffer_index++]; msb = bmi08x_gyro_stream_buffer[buffer_index++]; gz = (msb << 😎 | lsb; printf("gx: %-5d \t gy: %-5d \t gz: %-5d\n", gx, gy, gz); fflush(stdout); } } coines_delay_msec(1); counter++; } }  Further reads Datasheets: BMI085 Datasheet BMI088 Datasheet  Application notes: FIFO usage Handing soldering and mounting instructions: Handling, soldering & mounting instruction
    View full article
    ‎08-14-2019 10:25 AM
     Selecting the right part The BMP series of pressure sensor contains 2 products: BMP280 and BMP388. Table 1 shows an overview of the features.                                                     Table 1: Overview of the products in this family Key features LGA with metal lid package SPI or I2C interface Built-in IIR filter.  Differences between products The main differences in the BMP product family are in the thickness of the package, and the overall performance of the MEMS element. BMP388 offers higher performance in a smaller package compared to BMP280. See the complete list of differences in Table 2.                                                                                             Table 2: Differences between BMP product family members Available evaluation tools and software To best to evaluate the products from the BMP family, we recommend the following combination of evaluation tools: COINES Desktop software (Windows version &Linux version & MacOS) Development Desktop Software Application board 2.0 BMP280 shuttle board BMP388 shuttle board Reference design Figure 1 shows a complete schematic of a typical use case.                                                                                           BMP280                                                                                        BMP388                                                        Figure 1: Exemplary Reference design   Bill of materials                                             Table 3: Bill of materials Layout recommendations Because the BMP sensor family contains tiny mechanical structure inside the package, care must be taken during the layout phase to ensure the best performance. The complete handling and soldering guide can be found on the Bosch Sensortec’s website. BMP28x Handling, soldering & mounting instructions BMP380 Handling,soldering & mounting instructions In addition to the attached guidelines, see below for the typical manufacturing procedure for the BMP388 pressure sensor. Landing Pattern                                                                                          BMP280                                                                                      BMP388                                                          Figure 2: Recommended landing pattern Typical Layout                                                                                                   BMP280                                                                                           BMP388                                                                          Figure 3: Typical layout Manufacturing notes                                                               Table 4: Manufacture recommendation First power-on After powering on the sensor for the first time, the initial specs would be tested for communication with the device. This can be done simply by reading the chip identification code in the register 0xD0 (BMP280) 0x00 (BMP388). See below for the expected values:                                                          Table 5: Chip IDs of the BMP product family Here is some sample code on how to perform this test, based on the BMP388 , using the COINES software as the host. /*! * @brief This internal API is used to check the bmp388 sensor chip ID * * @param[in] void * * @return void * */ static void init_bmp3(void) { int8_t rslt; rslt = bmp3_init(&bmp3Dev); if (rslt == BMP3_OK) { printf("BMP3 Initialization Success!\n"); printf("Chip ID 0x%X\n", bmp3Dev.chip_id); } else { printf("Chip Initialization failure !\n"); exit(COINES_E_FAILURE); } } How to read sensor data  Here is some sample code on how to read sensor data, based on the BMP388, using the COINES software as the host /*! * @brief This internal API is used to read the streaming data in a while loop and * print in console. * * @param[in] void * * @return void */ static void read_sensor_data(void) { int times_to_read = 0; while (times_to_read < 200) { bmp3_get_sensor_data(BMP3_ALL, &bmp3_comp_data, &bmp3Dev); printf("T: %.2f, P: %.2f \n", (bmp3_comp_data.temperature / 100.), (bmp3_comp_data.pressure / 100.)); fflush(stdout); coines_delay_msec(10); times_to_read = times_to_read + 1; } }  Sample code The complete sample code shown above can be compiled and executed from the COINES installation directory (by default, C:/COINES under Windows), from the following subfolder: \examples\c\bmp3 Usage The COINES installation provides sample code on how to turn on the sensor, configure it and read out the pressure data. COINES\v1.0\examples\c\bmp3 Sample code /*! * @brief Main Function where the execution getting started to test the code. * * @param[in] argc * @param[in] argv * * @return status * */ int main(int argc, char *argv[]) { int16_t rslt; struct coines_board_info board_info; init_bmp3_sensor_driver_interface(); rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); if (rslt < 0) { printf("\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); exit(rslt); } rslt = coines_get_board_info(&board_info); if (rslt == COINES_SUCCESS) { if (board_info.shuttle_id != BMP3_SHUTTLE_ID) { printf("! Warning invalid sensor shuttle. This application will not support this sensor \r\n" "1.Check the sensor shuttle \r\n" "2.Reset the board \r\n"); exit(COINES_E_FAILURE); } } init_sensor_interface(); /* after sensor init introduce 200 msec sleep */ coines_delay_msec(200); init_bmp3(); read_sensor_data(); coines_close_comm_intf(COINES_COMM_INTF_USB); return EXIT_SUCCESS; Further reads Datasheets: BMP280 Datasheet BMP388 Datasheet Application notes: BMP388 self-test Handling, soldering and mounting instructions BMP280 HSMI BMP388 HSMI
    View full article
    100% helpful (1/1)
    ‎08-14-2019 10:20 AM
     Introduction This document is meant as a reference guide on how to design using Bosch Sensortec’s BMA400 accelerometer.  Selecting the right part The BMA400 is the first ultra-low power accelerometer with anti-aliasing performance, so strictly speaking, currently there is no compatible sensors in Bosch SensorTec products. However, a comparison between BMA400 & BMA4xy series is helpful for user to understand BMA400’s performance better. Table 1 shows an overview of the features.                                                                                  Table 1 sensor main features   Common characteristics The main characteristics of this product family are:   Key features LGA package (12 pins), 2mm x 2mm x 0.95mm Ultra-low power consumption:      3.5uA @800Hz to 14uA@800Hz (configurable in normal mode) 0.8uA @25Hz to 1.2uA @25Hz (configurable in low power mode) Anti-aliasing: consecutive sampling in normal mode (not duty-cycling) Configurable Acceleration ranges ±2g/±4g/±8g/±16g Configurable output data rate: 12.5Hz to 800Hz (normal mode) 1 KB FIFO Auto-low power/Auto wakeup Activity/In-activity Step Counter (overall device current consumption 4µA) Activity Recognition (Walking, Running, Standing still) Orientation detection Tap/double tap   Free-fall detection Wearables, position Differences between products BMA400 is the only one product with ultra-low power feature from Bosch Sensor tech. The key parameters are listed in Table 2.                                                                     Table 2 Key parameters of BMA400 Available evaluation tools and software To best to evaluate the products from the BMA400 family is the following combination of evaluation tools: COINES Desktop software, BST_download_page -> ‘Software’ Tap -> ‘Communication with Inertial and Environmental Sensors (COINES)’ Application board 2.0 https://ae-bst.resource.bosch.com/media/_tech/media/shuttleboard_flyer/Applicationboard-2-0_Flyer.pdf Sensor Shuttle board BMA400 Shuttle board Reference design See Figure 1 for a complete schematic of a typical use-case. Note: SPI is highly recommended because of the low current consumption. Since if I2C interface is applied, the pull-up resistors will consume significantly high current comparing to BMA400 ultra-low power consumption. The VDDIO of MCU and BMA400 should be connected to same power source (level). GPIO1 & GPIO2 of MCU should be configured as input if connected to INT1/INT2 of BMA400. In case I2C interface is used (even not recommended), connect CSB to VDDIO to prevent unwanted level jumps on CSB pin, which might bring BMA400 from I2C mode to SPI mode, especially during ESD test. Table 3 shows the bill of materials.                                                               Table 3 BMA400 relevant Bill of materials  Layout recommendations Because the BMA400 sensor family contains tiny mechanical structure inside the package, care must be taken during the layout phase to ensure the best performance. The complete handling and soldering guide can be found on the Bosch Sensortec’s website. BST_BMA400 -> ‘downloads’ -> ‘Handling & Soldering instructions’ In addition to the attached guidelines, see below for the typical integration & manufacturing procedure for the BMA400 accelerometer.    Landing Pattern                                                                 Figure 2 Landing pattern      Typical Layout Figure 3 Typical layout Note: No via under sensor. On top layer, where sensor is mounted, no copper under sensor; while on the 2 nd layer (bottom layer of 2-layers PCB), ground copper is welcomed to prevent EMI interference. Traces should be fanned out to the outside of sensor, not inside. In the area of sensor, no trace should be on the 2 nd layer (bottom layer of 2-layers PCB); When there is ground copper on the 2 nd layer, traces can be on 3 rd ( and 4 th /5 th …) layers; But keep high frequency or high current signals away from sensor area, from top to bottom. Manufacturing notes                                                                              Table 4 Manufacturing parameters First power-on After powering the sensor for the first time, the initial specs would be to test for communication with the device. This can be done simply by reading the chip identification code in the register 0x00. See below for the expected values:                                                                   Table 5 Chip ID of the BMA400 product To properly initialize the device, the user must decide which interface to use (I2C or SPI) during hardware design. After power up, BMA400 is by default in I2C mode, until detect a rising edge on CSB pin, then BMA400 will switch to SPI mode until next soft rest or power on reset. Therefore, once BMA400 is connected to SPI interface from host, firstly a rising edge on CSB pin should be triggered, which can be implemented, for example, by a read from CHIPID register. For I2C connect, pulling the CSB pin to VDDIO directly or through a resistor will prevent BMA400 switches to SPI mode during running or ESD. For SPI read, the first byte got from BMA400 is always a dummy byte, which should be skipped. The valuable information start from the second byte. Here is some sample code on how to perform a CHIPID reading, using the COINES software (check Chapter 2.3 for detailed information) as the host. * @brief This internal API is used to initializes the bma400 sensor with default * settings like power mode and OSRS settings * * @param[in] void * * @return void * */ static void init_bma400(void) { int8_t rslt; rslt = bma400_init(&bma400dev); if (rslt == BMA400_OK) { printf("BMA400 Initialization Success!\n"); printf("Chip ID 0x%x\n", bma400dev.chip_id); } else { print_rslt(rslt); exit(COINES_E_FAILURE); } coines_delay_msec(100); } /********************** Global function definitions ************************/ /*! * @brief This API is the entry point, Call this API before using other APIs. * This API reads the chip-id of the sensor which is the first step to * verify the sensor and updates the trim parameters of the sensor. */ int8_t bma400_init(struct bma400_dev *dev) { int8_t rslt; uint8_t chip_id = 0; /* Check for null pointer in the device structure*/ rslt = null_ptr_check(dev); /* Proceed if null check is fine */ if (rslt == BMA400_OK) { /* Initial power-up time */ dev->delay_ms(5); /* Assigning dummy byte value */ if (dev->intf == BMA400_SPI_INTF) { /* Dummy Byte availability */ dev->dummy_byte = 1; /* Dummy read of Chip-ID in SPI mode */ rslt = bma400_get_regs(BMA400_CHIP_ID_ADDR, &chip_id, 1, dev); } else { dev->dummy_byte = 0; } if (rslt == BMA400_OK) { /* Chip ID of the sensor is read */ rslt = bma400_get_regs(BMA400_CHIP_ID_ADDR, &chip_id, 1, dev); /* Proceed if everything is fine until now */ if (rslt == BMA400_OK) { /* Check for chip id validity */ if (chip_id == BMA400_CHIP_ID) { /* Store the chip ID in dev structure */ dev->chip_id = chip_id; } else { rslt = BMA400_E_DEV_NOT_FOUND; } } } } return rslt; } How to test the sensor’s functionality The BMA400 accelerometer features a fully integrated and motionless self-test procedure on the ASIC itself. When the self-test is triggered, the accelerometer uses electric fields to physically move the electrodes in all directions, senses the deflection and compares it with the expected output. Therefore, the built-in self-test features is the recommended way to test the sensor’s functionality. Here are some sample codes on how to perform this self-test, based on BMA400, using the COINES software as the host. Codes from COINS(caller): /*! * @brief This internal API is used to perform the self test * * @param[in] bma400dev: device structure * * @return void * */ static void perform_self_test(struct bma400_dev *bma400dev) { int8_t rslt; /* Doing soft reset */ rslt = bma400_soft_reset(bma400dev); print_rslt(rslt); printf("Running self test...\r\n"); coines_delay_msec(500); rslt = bma400_perform_self_test(bma400dev); print_rslt(rslt); if (rslt == BMA400_OK) { printf("Self test passed!\r\n"); } fflush(stdout); }  Codes from BMA400 API: /*! * @brief This is used to perform self test of accelerometer in BMA400 */ int8_t bma400_perform_self_test(const struct bma400_dev *dev) { int8_t rslt; int8_t self_test_rslt = 0; struct bma400_sensor_data accel_pos, accel_neg; /* Check for null pointer in the device structure */ rslt = null_ptr_check(dev); /* Proceed if null check is fine */ if (rslt == BMA400_OK) { /* pre-requisites for self test*/ rslt = enable_self_test(dev); if (rslt == BMA400_OK) { rslt = positive_excited_accel(&accel_pos, dev); if (rslt == BMA400_OK) { rslt = negative_excited_accel(&accel_neg, dev); if (rslt == BMA400_OK) { /* Validate the self test result */ rslt = validate_accel_self_test(&accel_pos, &accel_neg); } } } } /* Check to ensure bus error does not occur */ if (rslt >= BMA400_OK) { /* Store the status of self test result */ self_test_rslt = rslt; /* Perform soft reset */ rslt = bma400_soft_reset(dev); } /* Check to ensure bus operations are success */ if (rslt == BMA400_OK) { /* Restore self_test_rslt as return value */ rslt = self_test_rslt; } return rslt; } How to test the sensor’s performance There are two performance parameters that can easily be tested with the device motionless: offset and noise. See below for the typical values of the sensors. Note: Typical values are defined as ±1σ, which means that we expect 68.3% of sensors to fall within these values. Min/Max values are defined as ±3σ, which means 99.7% of sensors shall be within these values. For the offset, the test procedure is quite simple. With the device in a known position, such as a flat surface, calculate the average value for each axis, and subtract the expected output (e.g. 0G, 0G, +1G) from the data. The result is the offset of the sensor. Here is some sample code on how to perform this test, based on BMA400, using the COINES software as the host. Missed BMA400 offset calculation examples: /*! * @brief This internal API is used to measure the sensor offset * * @param[out] x_off_mg, y_off_mg, z_off_mg * * @return void * */ static void bma423_get_offset(double *x_off_mg, double *y_off_mg, double *z_off_mg) { uint16_t commrslt; /* Declare an accelerometer configuration structure */ struct bma4_accel_config accel_conf; /* Declare a data buffer for the sensor data structure */ struct bma4_accel sens_data[20]; /* Enable the accelerometer */ The noise calculation is a bit more complicated. First, subtract the offset from each data point. The RMS value can be calculated as the square root of the arithmetic mean of the squares of the noise values. Since the noise value is affected by the bandwidth of the digital filter, we need to convert it back to noise density with the following formula. Note: this applied only to a second order filter. Here is some sample code on how to perform this test, based on BMI160, using the COINES software as the host. Calibrating the sensor The first question to ask concerning calibration is whether it is required for the intended application. Accelerometer calibration mainly consists of calibrating the accelerometer’s offset. The main impact for this is in tilt-sensing application, where the offset will induce an error in the measurement of the horizon. The accelerometer comes from the factory pre-trimmed, but the soldering process and PCB bending due to assembly can vary the offset, therefore it is preferable to calibrate the accelerometer after assembling the device into the device housing. Therefore, it is recommended to calibrate the sensor after assembling the device into the device housing. The acceleration sensor offset consists of two parts: the static “unwanted” offset mainly due to soldering drift, and the offset generated when an acceleration is applied to the sensor. The latter depends on the applied acceleration and its magnitude if defined by the sensor’s sensitivity. However, the sensitivity has a certain tolerance (typ. <1%). This means that in order to compensate for the static offset, the sensor must be oriented in such a way that no external acceleration is applied to the sensing axis. As gravity also causes a sensor signal, the sensing axis must be oriented perpendicular to the gravity field. The compensation process described below focuses on the x/y-axis. The z-axis can also be compensated in the same way, but the user has to consider the applied gravity. Alternatively, the process can be repeated after turning the device, with the z-axis perpendicular to the gravity vector. Place your sensor (the system with the sensor inside) on a well-defined surface, for example, a horizontal table. The expected sensor output for the x/y-axis should be 0 mg. Set the sensor to the lowest g-range (2G) Measure the sensor output to ensure the sensor is fully at rest, without vibrations, inclinations, big temperature changes or strong VDD fluctuations. It is advisable to take several values and generate the average over the values (e.g. 1000 values). Consider the resolution of BMA400, and save the offset in LSB or mg. The offset subtracted from the future accelerometer sensor data.  Usage The COINES installation provides sample code on how to turn on the sensor, configure it and read out the acceleration data.   Sample code The main function shows the initialization process of BMA400 based on COINS software & APP2.0 board. /*! * @brief Main Function where the execution getting started to test the code. * * @param[in] argc * @param[in] argv * * @return status * */ int main(int argc, char const *argv[]) { struct coines_board_info board_info; struct bma400_sensor_data data; struct bma400_dev bma; int8_t rslt; uint8_t n_samples = 200; float t, x, y, z; init_bma400_sensor_driver_interface(&bma); rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); if (rslt < 0) { printf("\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); exit(rslt); } /* Check if the right board is connected (implicitly check if board was reset) */ rslt = coines_get_board_info(&board_info); if (rslt == COINES_SUCCESS) { if(board_info.shuttle_id != BMA400_SHUTTLE_ID) { printf("Invalid sensor shuttle ID (not a BMA400 shuttle)\n(sometimes board power off-power on helps.)\n"); fflush(stdout); exit(COINES_E_FAILURE); } } init_sensor_interface(); /* after sensor init introduce 200 msec sleep */ coines_delay_msec(200); init_bma400(&bma); rslt = bma400_soft_reset(&bma); print_rslt(rslt); rslt = set_sensor_config(&bma); if(rslt != BMA400_OK) { printf("Error setting bma400 config.\n"); fflush(stdout); exit(rslt); } while (n_samples && (rslt == BMA400_OK)) { bma.delay_ms(10); /* Wait for 10ms as ODR is set to 100Hz */ rslt = bma400_get_accel_data(BMA400_DATA_SENSOR_TIME, &data, &bma); print_rslt(rslt); /* 12-bit accelerometer at range 2G */ x = lsb_to_ms2(data.x, 2, 12); y = lsb_to_ms2(data.y, 2, 12); z = lsb_to_ms2(data.z, 2, 12); t = sensor_ticks_to_s(data.sensortime); printf("t[s]:%.4f\tdata[m/s2]: ax:%.4f\tay:%.4f\taz:%.4f\n", t, x, y, z); fflush(stdout); n_samples--; } return 0; } Below function described how to coinfigure the BMA400: /*! * @brief This internal API is used to configure the sensor * * @param[in] bma400dev: bma400 device structure * * @return Results of API execution status. * @retval 0 -> Success * @retval Any non zero value -> Fail * */ static int8_t set_sensor_config(struct bma400_dev *bma400dev) { int8_t rslt; struct bma400_sensor_conf conf; /* Select the type of configuration to be modified */ conf.type = BMA400_ACCEL; /* Get the accelerometer configurations which are set in the sensor */ rslt = bma400_get_sensor_conf(&conf, 1, bma400dev); print_rslt(rslt); /* Modify the desired configurations as per macros * available in bma400_defs.h file */ conf.param.accel.odr = BMA400_ODR_100HZ; conf.param.accel.range = BMA400_2G_RANGE; conf.param.accel.data_src=BMA400_DATA_SRC_ACCEL_FILT_1; /* Set the desired configurations to the sensor */ rslt = bma400_set_sensor_conf(&conf, 1, bma400dev); print_rslt(rslt); rslt = bma400_set_power_mode(BMA400_LOW_POWER_MODE, bma400dev); print_rslt(rslt); return rslt; } Below codes come from BMA400 API, which describe how to read and set BMA400 sensor configuration, and how to read sensor data. /*! * @brief This API is used to get the accel data along with the sensor-time */ int8_t bma400_get_accel_data(uint8_t data_sel, struct bma400_sensor_data *accel, const struct bma400_dev *dev) { int8_t rslt; /* Check for null pointer in the device structure*/ rslt = null_ptr_check(dev); /* Proceed if null check is fine */ if ((rslt == BMA400_OK) || (accel != NULL)) { /* Read and store the accel data */ rslt = get_accel_data(data_sel, accel, dev); } else { rslt = BMA400_E_NULL_PTR; } return rslt; } /*! * @brief This API is used to set the sensor settings like sensor * configurations and interrupt configurations */ int8_t bma400_set_sensor_conf(const struct bma400_sensor_conf *conf, uint16_t n_sett, const struct bma400_dev *dev) { int8_t rslt; uint16_t idx = 0; uint8_t data_array[3] = { 0 }; /* Check for null pointer in the device structure*/ rslt = null_ptr_check(dev); /* Proceed if null check is fine */ if (rslt == BMA400_OK) { /* Read the interrupt pin mapping configurations */ rslt = bma400_get_regs(BMA400_INT_MAP_ADDR, data_array, 3, dev); if (rslt == BMA400_OK) { for (idx = 0; idx < n_sett; idx++) { switch (conf[idx].type) { case BMA400_ACCEL: /* Setting Accel configurations */ rslt = set_accel_conf(&conf[idx].param.accel, dev); if (rslt == BMA400_OK) { /* Int pin mapping settings */ map_int_pin(data_array, BMA400_DATA_READY_INT_MAP, conf[idx].param.accel.int_chan); } break; case BMA400_TAP_INT: /* Setting TAP configurations */ rslt = set_tap_conf(&conf[idx].param.tap, dev); if (rslt == BMA400_OK) { /* Int pin mapping settings */ map_int_pin(data_array, BMA400_TAP_INT_MAP, conf[idx].param.tap.int_chan); } break; case BMA400_ACTIVITY_CHANGE_INT: /* Setting activity change config */ rslt = set_activity_change_conf(&conf[idx].param.act_ch, dev); if (rslt == BMA400_OK) { /* Int pin mapping settings */ map_int_pin(data_array, BMA400_ACT_CH_INT_MAP, conf[idx].param.act_ch.int_chan); } break; case BMA400_GEN1_INT: /* Setting Generic int 1 config */ rslt = set_gen1_int(&conf[idx].param.gen_int, dev); if (rslt == BMA400_OK) { /* Int pin mapping settings */ map_int_pin(data_array, BMA400_GEN1_INT_MAP, conf[idx].param.gen_int.int_chan); } break; case BMA400_GEN2_INT: /* Setting Generic int 2 config */ rslt = set_gen2_int(&conf[idx].param.gen_int, dev); if (rslt == BMA400_OK) { /* Int pin mapping settings */ map_int_pin(data_array, BMA400_GEN2_INT_MAP, conf[idx].param.gen_int.int_chan); } break; case BMA400_ORIENT_CHANGE_INT: /* Setting orient int config */ rslt = set_orient_int(&conf[idx].param.orient, dev); if (rslt == BMA400_OK) { /* Int pin mapping settings */ map_int_pin(data_array, BMA400_ORIENT_CH_INT_MAP, conf[idx].param.orient.int_chan); } break; case BMA400_STEP_COUNTER_INT: /* Int pin mapping settings */ map_int_pin(data_array, BMA400_STEP_INT_MAP, conf[idx].param.step_cnt.int_chan); break; } } if (rslt == BMA400_OK) { /* Set the interrupt pin mapping configurations */ rslt = bma400_set_regs(BMA400_INT_MAP_ADDR, data_array, 3, dev); } } } return rslt; } /*! * @brief This API is used to get the sensor settings like sensor * configurations and interrupt configurations and store * them in the corresponding structure instance */ int8_t bma400_get_sensor_conf(struct bma400_sensor_conf *conf, uint16_t n_sett, const struct bma400_dev *dev) { int8_t rslt = BMA400_OK; uint16_t idx = 0; uint8_t data_array[3] = { 0 }; if (conf == NULL) { rslt = BMA400_E_NULL_PTR; } if (rslt == BMA400_OK) { /* Read the interrupt pin mapping configurations */ rslt = bma400_get_regs(BMA400_INT_MAP_ADDR, data_array, 3, dev); } for (idx = 0; (idx < n_sett) && (rslt == BMA400_OK); idx++) { switch (conf[idx].type) { case BMA400_ACCEL: /* Accel configuration settings */ rslt = get_accel_conf(&conf[idx].param.accel, dev); if (rslt == BMA400_OK) { /* Get the INT pin mapping */ get_int_pin_map(data_array, BMA400_DATA_READY_INT_MAP, &conf[idx].param.accel.int_chan); } break; case BMA400_TAP_INT: /* TAP configuration settings */ rslt = get_tap_conf(&conf[idx].param.tap, dev); if (rslt == BMA400_OK) { /* Get the INT pin mapping */ get_int_pin_map(data_array, BMA400_TAP_INT_MAP, &conf[idx].param.tap.int_chan); } break; case BMA400_ACTIVITY_CHANGE_INT: /* Activity change configurations */ rslt = get_activity_change_conf(&conf[idx].param.act_ch, dev); if (rslt == BMA400_OK) { /* Get the INT pin mapping */ get_int_pin_map(data_array, BMA400_ACT_CH_INT_MAP, &conf[idx].param.act_ch.int_chan); } break; case BMA400_GEN1_INT: /* Generic int1 configurations */ rslt = get_gen1_int(&conf[idx].param.gen_int, dev); if (rslt == BMA400_OK) { /* Get the INT pin mapping */ get_int_pin_map(data_array, BMA400_GEN1_INT_MAP, &conf[idx].param.gen_int.int_chan); } break; case BMA400_GEN2_INT: /* Generic int2 configurations */ rslt = get_gen2_int(&conf[idx].param.gen_int, dev); if (rslt == BMA400_OK) { /* Get the INT pin mapping */ get_int_pin_map(data_array, BMA400_GEN2_INT_MAP, &conf[idx].param.gen_int.int_chan); } break; case BMA400_ORIENT_CHANGE_INT: /* Orient int configurations */ rslt = get_orient_int(&conf[idx].param.orient, dev); if (rslt == BMA400_OK) { /* Get the INT pin mapping */ get_int_pin_map(data_array, BMA400_ORIENT_CH_INT_MAP, &conf[idx].param.orient.int_chan); } break; case BMA400_STEP_COUNTER_INT: /* Get int pin mapping settings */ get_int_pin_map(data_array, BMA400_STEP_INT_MAP, &conf[idx].param.step_cnt.int_chan); break; default: rslt = BMA400_E_INVALID_CONFIG; } } return rslt; } Further reads Datasheets: BMA400 datasheet -> ‘Download’ -> ‘BST-BMA400-DSxxx’, like BST-BMA400-DS000 Application notes: BMA400 Evaluation Guide Handing soldering and mounting instructions Handling, soldering & mounting instruction                                                                                                                                                                                                                                                                                                                  
    View full article
    0% helpful (0/1)
    ‎08-14-2019 10:04 AM
     Introduction This document is meant as a reference guide on how to design using Bosch Sensortec’s BME280 series of humidity sensor. Selecting the right part The BME280 series of humidity sensor contains 1 products: BME280. Table 1 shows an overview of the features.                                                                Table 1: Overview of the products in this family  Common characteristics The main characteristics of this product family are:  Key features The BME280 is an integrated environmental sensor developed specifically for mobile applications where size and low power consumption are key design constraints. The unit combines individual high linearity, high accuracy sensors for pressure, humidity and temperature in an 8-pin metal-lid 2.5 x 2.5 x 0.93 mm³ LGA package, designed for low current consumption (3.6 μA @1Hz), long term stability and high EMC robustness. The humidity sensor features an extremely fast response time which supports performance requirements for emerging applications such as context awareness, and high accuracy over a wide temperature range. The pressure sensor is an absolute barometric pressure sensor with features exceptionally high accuracy and resolution at very low noise. The integrated temperature sensor has been optimized for very low noise and high resolution. It is primarily used for temperature compensation of the pressure and humidity sensors, and can also be used for estimating ambient temperature. The BME280 supports a full suite of operating modes which provide the flexibility to optimize the device for power consumption, resolution and filter performance.  Available evaluation tools and software To best to evaluate the products from the BME280 family, we recommend the following combination of evaluation tools: COINES Desktop software Installer for Windows based systems: https://ae-bst.resource.bosch.com/media/_tech/media/coines/COINES_Installers_v1.1_Windows.zip Installer for Linux based systems: https://ae-bst.resource.bosch.com/media/_tech/media/coines/COINES_Installers_v1.1_Linux.zip Application board 2.0 Without bluetooth. Ordering code 0330.AB0.011 With bluetooth. Ordering code 0330.AB0.111 https://www.bosch-sensortec.com/bst/support_tools/application_boards/overview_application_boards Sensor Shuttle board BME280 Shuttle board. Ordering code 0330.SB4.185  Reference design See Figure 1 for a complete schematic of a typical BME280 use-case.                                                         Fig. 1: Mockup Reference design    Bill of materials                                              Table 3: Bill of materials  Layout recommendations Because the BME280 sensor family contains tiny mechanical structure inside the package, care must be taken during the layout phase to ensure the best performance. The complete handling and soldering guide can be found on the Bosch Sensortec’s website. In addition to the attached guidelines, see below for the typical manufacturing procedure for the BME280 humidity sensor.       Landing Pattern                                                                  Fig. 2: Recommended landing pattern Note: red areas demark exposed PCB metal pads. In case of a solder mask defined (SMD) PCB process, the land dimensions should be defined by solder mask openings. The underlying metal pads are larger than these openings. In case of a non solder mask defined (NSMD) PCB process, the land dimensions should be defined in the metal layer. The mask openings are larger than these metal pads.  Typical Layout                                                                              Figure 3: Typical layout Manufacturing notes                                                             Table 4: Manufacture recommendation   First power-on After powering the sensor for the first time, the initial specs would be to test for communication with the device. This can be done simply by reading the chip identification code in the register 0xD0. See below for the expected values                                                         Table 5: Chip IDs of the BME280 product family Here is some sample code on how to perform this test, using the COINES software as the host. /*! * @brief This internal API is used to initializes the bme280 sensor with default * settings like power mode and OSRS settings * * @param[in] void * * @return void * */ static void init_bme280(void) { int8_t rslt; rslt = bme280_init(&bme280Dev); if (rslt == BME280_OK) { printf("BME280 Initialization Success!\n"); printf("Chip ID 0x%x\n", bme280Dev.chip_id); } else { printf("Chip Initialization failure !\n"); exit(COINES_E_FAILURE); } coines_delay_msec(100); bme280_set_sensor_mode(BME280_NORMAL_MODE, &bme280Dev); } How to read sensor data  Here is some sample code on how to read sensor data, using the COINES software as the host. /*! * @brief This internal API is used to read the streaming data in a while loop and * print in console. * * @param[in] void * * @return void */ static void read_sensor_data(void) { int times_to_read = 0; while (times_to_read < 200) { bme280_get_sensor_data(BME280_ALL, &bme280_comp_data, &bme280Dev); printf("T: %.2f, H: %.2f, P: %.2f \n", (bme280_comp_data.temperature / 100.), (bme280_comp_data.humidity / 1000.), (bme280_comp_data.pressure / 100.)); fflush(stdout); coines_delay_msec(10); times_to_read = times_to_read + 1; } } Sample code The complete sample code shown above can be compiled and executed from the COINES installation directory (by default, C:/COINES under Windows), from the following subfolder: \examples\c\bme280 Usage The COINES installation provides sample code on how to turn on the sensor, configure it and read out data. COINES\v1.0\ examples\c\bme280 Sample code /*! * @brief Main Function where the execution getting started to test the code. * * @param[in] argc * @param[in] argv * * @return status * */ int main(int argc, char *argv[]) { int16_t rslt; struct coines_board_info board_info; init_bme280_sensor_driver_interface(); rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); if (rslt < 0) { printf("\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); exit(rslt); } rslt = coines_get_board_info(&board_info); if (rslt == COINES_SUCCESS) { if (board_info.shuttle_id != BME280_SHUTTLE_ID) { printf("! Warning invalid sensor shuttle. This application will not support this sensor \r\n" "1.Check the sensor shuttle \r\n" "2.Reset the board \r\n"); exit(COINES_E_FAILURE); } } init_sensor_interface(); /* after sensor init introduce 200 msec sleep */ coines_delay_msec(200); init_bme280(); read_sensor_data(); coines_close_comm_intf(COINES_COMM_INTF_USB); return EXIT_SUCCESS; } Further reads Datasheets: BME280 Datasheet https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280-DS002.pdf Handling, soldering  and mounting instructions: BME280 HSMI https://ae-bst.resource.bosch.com/media/_tech/media/application_notes/BST-BME280-HS006.pdf                                          
    View full article
    100% helpful (1/1)
    ‎08-14-2019 09:55 AM
     Introduction This document is intended as a reference guide on how to design using Bosch Sensortec’s BMI160 series IMU (inertial measurement unit) Selecting the right part The BMI16x family has two products: BMI160 and BMG250. Table 1 gives an overview of these two products. As the BMM150 can be connected to the secondary interface of BMI160 and BMI120 for 9-axis applications, it is also introduced below.                                                          Table 1: Overview of the products in the BMI16x family     Common characteristics The main characteristics of the BMI16x family are: Highly integrated, low power IMU 16-bit digital, tri-axial accelerometer 16-bit digital, tri-axial gyroscope   Key features 3.0x2.5mm 2 size Pin-to-pin compatibility with products in this family itself and in the BMI2XY family SPI or I 2 C interface Configurable range from ±2g to ±16g for accelerometer and ±125dps to ±2000dps for gyroscope Configurable output data rate up to 1.6kHZ for accelerometer and 6.4kHZ for gyroscope Integrated 1KB FIFO Auxiliary I2C interface for connecting external magnetometer, including data synchronization Built-in smart interrupt controller, with features such as step counter, any motion, no motion, etc    Differences among products The main differences among the BMI160 product family are in the function and overall performance. The BMI160 is the right choice for most standard applications. The BMG250 is a standalone gyroscope for applications where only a gyroscope is required, e.g. OIS etc. See Table 2 for their differences. Table 2: Differences between products in the BMI16x family   Available evaluation tools and software To best evaluate the products from the BMI160 family, the following combination of evaluation tools are recommended: COINES Desktop software (Windows version, Linux version) Application board 2.0 Without Bluetooth With Bluetooth https://www.bosch-sensortec.com/bst/support_tools/application_boards/overview_application_boards Sensor shuttle board BMI160 shuttle board BMG250 shuttle board BMM150 shuttle board  Reference design Figure 1 shows a mockup reference design of the BMI16x family.                                                         Figure 1: Mockup reference design Bill of materials Table 3 lists the bill of necessary materials.                                                                               Table 3: Bill of materials  Layout recommendations Because the BMI160 family contains tiny mechanical structures inside the package, care must be taken during the layout phase to ensure optimum performance. The complete handling and soldering guide can be found on the Bosch Sensortec’s website. The typical manufacturing procedures for the BMI160 accelerometers are described in the following sections. Landing pattern Figure 2 shows the landing pattern of the BMI160 family.                                                                     Figure 2: Landing pattern (in mm) Typical layout Figure 3 shows the typical layout.                                                                      Figure 3: Typical layout (in mm) Manufacturing notes Table 4 lists the recommendations for the manufacture.                                                          Table 4: Manufacture recommendations First power-on After powering on the sensor for the first time, the initial specs would be tested for communication with the device. This can be done by simply reading the chip identification code in the register 0x00. See Table 5 for the chip IDs.                                                            Table 5: Chip IDs of the BMI160 product family Below is some example code on how to perform this test based on the BMI160, using the COINES software as the host. static void init_bmi160(void) { int8_t rslt; rslt = bmi160_init(&bmi160dev); if (rslt == BMI160_OK) { printf("BMI160 initialization success !\n"); printf("Chip ID 0x%X\n", bmi160dev.chip_id); } else { printf("BMI160 initialization failure !\n"); exit(COINES_E_FAILURE); } } /*! * @brief Main Function where the execution getting started to test the code. * * @param[in] argc * @param[in] argv * * @return status * */ int main(int argc, char *argv[]) { struct coines_board_info board_info; int16_t rslt; init_bmi160_sensor_driver_interface(); rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); if (rslt < 0) { printf("\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); exit(rslt); } rslt = coines_get_board_info(&board_info); if (rslt == COINES_SUCCESS) { if (board_info.shuttle_id != BMI160_SHUTTLE_ID) { printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); exit(COINES_E_FAILURE); } } init_sensor_interface(); /* after sensor init introduce 200 msec sleep */ coines_delay_msec(200); init_bmi160();hz coines_close_comm_intf(COINES_COMM_INTF_USB); return EXIT_SUCCESS; } Testing sensor functionality The BMI160 series IMU features a fully integrated and motionless self-test procedure on the ASIC itself. When the self-test is triggered, the accelerometer uses electric fields to physically move the electrodes in all directions, senses the deflection and compares it with the expected output. The gyroscope checks the sensor drive amplitude, frequency and stability of the drive control loop. Therefore, it is recommended to test the BMI160’s functionality using the built-in self-test feature. Here is some sample code on how to perform this self-test, based on BMI160, using the COINES software as the host. Testing sensor performance The BMI160 family’s performance parameters, e.g. offset and noise, can be easily tested with the device motionless. See below for the typical values of the BMI160 family.                                      Table 6: Typical performance of the BMI160 product family Note: Typical values are defined as ± 1σ, which means that 68.3% of sensors are expected to fall within these values. Min/Max values are defined as ± 3σ, which means 99.7% of sensors shall be within these values. The offset testing procedure is quite simple. This can be done by putting the device in a known position, e.g. on a flat surface, calculate the average value for each axis, and subtract the expected output (e.g. 0G, 0G, +1G) from the value. The result is the offset of the sensor. The example code on how to perform this test will be provided when available. The noise calculation is a bit more complicated. First, subtract the offset from each data point. The RMS value can be calculated as the square root of the arithmetic mean of the squares of the noise values. Since the noise value is affected by the bandwidth of the digital filter, it needs to be converted back to noise density using the following formula. Note that this applies to a second order filter only. The example code on how to perform noise calculation will be provided when available.  Example Code The complete example code can be compiled and executed from the following subfolder:  /examples/c/bmi160/ under the COINES installation directory (C:/COINES on Windows by default). Calibration The BMI16x family has been pre-trimmed at the factory, but the offset may vary due to the soldering process and PCB bending during assembly. Therefore, it is preferred to calibrate the accelerometer and the gyroscope after assembling the device into its housing. The BMI16x family calibration includes accelerometer offset calibration and gyroscope offset calibration Example code The calibration procedures can be found in the BMI160 Datasheet. Once the offsets are determined, they can be written into the NVM (non-volatile memory) so that the sensor automatically compensates for the soldering offset even after physically diconnecting the power. The example code on how to perform calibration and save calibration data to NVM will be provided when available. The complete example code can be compiled and executed from the subfolder: /examples/c/bmi160/ under the COINES installation directory (by default, C:/COINES on Windows). Usage The COINES installation provides sample code on how to turn on the sensor, configure it and read out the IMU data.  Example code Below is some example code on how to evaluate basic communication based on the BMI160, using the COINES software as the host. int main(int argc, char *argv[]) { struct coines_board_info board_info; int16_t rslt; init_bmi160_sensor_driver_interface(); rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); if (rslt < 0) { printf("\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); exit(rslt); } rslt = coines_get_board_info(&board_info); if (rslt == COINES_SUCCESS) { if (board_info.shuttle_id != BMI160_SHUTTLE_ID) { printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); exit(COINES_E_FAILURE); } } init_sensor_interface(); /* after sensor init introduce 200 msec sleep */ coines_delay_msec(200); init_bmi160();hz coines_close_comm_intf(COINES_COMM_INTF_USB); return EXIT_SUCCESS; } Further reads Datasheets: BMI160 BMM150 BMG250 Handling, soldering and mounting instructions: BMI160 HSMI      
    View full article
    Top Contributors
    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