Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BMA4xy accelerometer series design guide

     Selecting the right part

    The BMA4xy series of accelerometer contains 2 products: BMA423 and BMA456. Other variants, such as the BMA421, BMA422 and BMA455 are for smartphone applications and are not available through worldwide distribution, therefore not covered in this design guide. Table 1 shows an overview of the features.

    family overviewpng.png
    Table 1: Overview of the products in this family

    Common characterictics
    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
    • Auxialiary 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.


    Differences between products

    The main differences in the BMA4xy product family are in the thickness of the package, and the overall performance of the MEMS element. While BMA423 is a suitable choice for most standard applications, BMA456 offers higher performance and stability in a smaller package. See the complete list of differences in Table 2.

    ParameterBMA423BMA456Units
    Height0,950,65mm
    Digital resolution1216bits
    Zero-g offset (typ.)±80±20mg
    Noise density (typ.)140120µg/√Hz
    TCO (X&Y axis)10,2mg/K
    TCO (Z axis)10,35mg/K
    TCS0,020,005%/K
    Cross Axis Sensitivity20,5%


    Table 2: Differences between BMA4xy product family members

    Available evaluation tools and software

    To best to evaluate the products from the BMA4xy family, we recommend the following combination of evaluation tools:

    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 intial 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:

    DeviceChip ID
    BMA4230x13
    BMA4560x16


    Table 3: Chip IDs of the BMA4xy product family

    Here is some sample code on how to perform this test, based on BMA423, using the COINES software as the host.

    /*!
     * @brief 	This internal API is used to initializes the bma423 and verify the 
     *			communication by reading the chip id.
     *
     * @param[in] void
     *
     * @return void
     *
     */
    static void init_comm_test_bma423(void)
    {
        int8_t rslt;
    	
    #if BMA423_INTERFACE_SPI==1
    	/* BMA423 requires a dummy SPI transaction to switch to SPI mode at power-on */
    	uint8_t dummybyte;
    	bma4_write_regs(COINES_SHUTTLE_PIN_7, &dummybyte, 1, &bma423dev);
    #endif
    	
        rslt = bma423_init(&bma423dev);
        if (rslt == BMA4_OK)
        {
            printf("BMA423 Initialization Success!\n");
            printf("Test #1: Communication. PASSED. Chip ID 0x%x\n", bma423dev.chip_id);
        }
    
        else
        {
    		char err_string[255];
            printf("BMA423 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", BMA423_CHIP_ID, bma423dev.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 intergrated 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 functionnality.

    Here is some sample code on how to perform this self-test, based on BMA423, 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_bma423(void) {
    	
    	uint16_t commrslt; 
    	uint8_t	testrslt;
    
    	commrslt = bma4_perform_accel_selftest(&testrslt, &bma423dev);
    	
    	if ( 0 != commrslt ) 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.

    ParameterBMA423BMA456units
    Offset±80±20mg
    Noise140120µg/√Hz


    Table 4: Typical performance of the BMA4xy product family

    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 BMA423, 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 12 bits') */
    		xval = (((double)sens_data[i].x) * 4. * 2. * 1000) / pow(2,12);
    		yval = (((double)sens_data[i].y) * 4. * 2. * 1000) / pow(2,12);
    		zval = (((double)sens_data[i].z) * 4. * 2. * 1000) / pow(2,12);
    		
    		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, substract the offset from each datapoint. The 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 BMA423, 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,12);
    		yval = (((double)sens_data[i].y) * 4. * 2. * 1000.) / pow(2,12);
    		zval = (((double)sens_data[i].z) * 4. * 2. * 1000.) / pow(2,12);
    		
    		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) */
    	/* BMA423 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
    PreCal.png

    PostCal.png

    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 BMA423, 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 = bma423_init(&bma423dev);
    	
        if (rslt == BMA4_OK) {
            printf("BMA423 Initialization Success!\n");
        } else {	
            coines_exit_error("BMA423 Initialization Failure!\n");
        }
        coines_delay_msec(100);
    	
    	/*! calculates the offset before compensation */
    	bma423_get_offset(&x_off_mg, &y_off_mg, &z_off_mg);
    	
    	printf("Pre-calibration offset : X=%4.1lfmg Y=%4.1lfmg Z=%4.1lfmg\n", x_off_mg, y_off_mg, z_off_mg);
    	
    	
    	/*! performs fast offset compensation */
    	const int32_t target_values[3] = {	X_REST_POSITION_MG * 1000, \
    										Y_REST_POSITION_MG * 1000, \
    										X_REST_POSITION_MG * 1000};
    	commrslt = bma4_perform_accel_foc( target_values, &bma423dev);
    	
    	if ( 0 != commrslt ) coines_exit_error("Unknown communication error. Exiting...\n");
    	
    	
    	/*! calculates the offset after compensation */
    	bma423_get_offset(&x_off_mg, &y_off_mg, &z_off_mg);
    	
    	printf("Post-calibration offset : X=%4.1lfmg Y=%4.1lfmg Z=%4.1lfmg", x_off_mg, y_off_mg, z_off_mg);
    	
    	


    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 BMA423, 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 bma423_update_nvm(void) {
    	uint16_t commrslt;
    	uint8_t data;
    
    	/* unlocks the NVM for writing */
    	data = 0x02;
    	bma4_write_regs(0x6A, &data, 1, &bma423dev);
    	
    	
    	/* makes sure the BMA423 is not executing another command */
    	do {
    		commrslt = bma4_read_regs(BMA4_STATUS_ADDR, &data, 1, &bma423dev);
    		if ( 0 != commrslt ) coines_exit_error("Unknown communication error. Exiting...\n");
    	} while ( 0 == (data&0x10) );
    	
    	
    	/* performs the writing of the NVM */
    	commrslt = bma4_set_command_register( 0xA0,  &bma423dev);
    	if ( 0 != commrslt ) coines_exit_error("Unknown communication error. Exiting...\n");
    	
    	
    	/* wait for the command to be completed */
    	do {
    		commrslt = bma4_read_regs(BMA4_STATUS_ADDR, &data, 1, &bma423dev);
    		if ( 0 != commrslt ) coines_exit_error("Unknown communication error. Exiting...\n");
    	} while ( 0 == (data&0x10) );
    	
    	
    	/* locks the NVM writing */
    	data = 0x00;
    	bma4_write_regs(0x6A, &data, 1, &bma423dev);
    }


    Further reads

    Datasheets:

    Application notes:

    Version history
    Revision #:
    7 of 7
    Last update:
    ‎03-08-2019 09:38 AM
    Updated by:
     
    Labels (1)
    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