Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    BMP390L doesn't get the pressure value.

    BMP390L doesn't get the pressure value.

    javierrobledo
    Member

    Hi all,

    I have a problem using the BMP390L. I have configurated it correctly following the datasheet and a example project that I have found on this forum. But always the sensor returns me values around 975-977mbar and my atmospheric pressure is 940-945mbar aprox (35mbar of difference is so much). The MSB of the pressure data (reg 0x06) is always returning me the value 0x00. It is normal?

    The measurement of temperature always returns me 1.5ºC more than real temperature, but I can assume this error.

     

    The compensation coefficientes that I get are those seen in the following image, and I think that they are corrects because they are similar with normal values of calibration.

    calib.PNG

    Furthermore, I have been checking the code of temperature and pressure compensation and the script is OK.

     

    Does someone have any idea about why I can not get the right pressure?

     

    Thank you all!

     

    5 REPLIES 5

    Minhwan
    Community Moderator
    Community Moderator

    Hello, 

     

    Could you share your code? 

    Thanks, 

    I want to make one measurement each second, so I configurated the sensor on "Ultra Low Power". This is the configuration:

     

    ret1 = BMP390L_enable_sensors(st); // Sleep mode. Enable sensors
    ret2 = PAWriteReg_BMP390L(st, 0, 0, (uint8_t)BMP390L_INT_CTRL, (uint32_t)BMP390L_REG_SIZE_BYTES, 0x02); // push-pull. INT rising edge. Drdy disable for pressure and temperature
    ret3 = PAWriteReg_BMP390L(st, 0, 0, (uint8_t)BMP390L_IF_CONF, (uint32_t)BMP390L_REG_SIZE_BYTES, 0x00); // SPI 4-wire configuration
    ret4 = PAWriteReg_BMP390L(st, 0, 0, (uint8_t)BMP390L_OSR, (uint32_t)BMP390L_REG_SIZE_BYTES, 0x00); // Oversamplig x1 
    ret5 = PAWriteReg_BMP390L(st, 0, 0, (uint8_t)BMP390L_ODR, (uint32_t)BMP390L_REG_SIZE_BYTES, 0x02); // 50Hz -> Ts = 20ms (prescaler = 4)
    ret6 = PAWriteReg_BMP390L(st, 0, 0, (uint8_t)BMP390L_CONFIG, (uint32_t)BMP390L_REG_SIZE_BYTES, 0x00); // IRR coefficients = 0
    get_compensation_coefficients(st); // Build CALIB_DATA struct

     

    I confirm that I am writting right on the configuration registers.

    These are the functions for compensation:

     

    void get_compensation_coefficients(struct BMP390L_state *st)
    {	
    		
    	tUint32 tmp;
    	double potencia; // valores del datahseet que corresponden a la división de las potencias
    	uint8_t i, addr;
      uint8_t regs[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    	
    	//	BMP390L_ReadRegs(regs, 0x31-0x45, 21 registros) - modo BURST para evitar latches en la lectura
      addr = 0x31;
      for (i = 0; i < 21; i++) {
         PAReadReg_BMP390L(st, 0, 0, addr, (uint32_t) BMP390L_CALIBRATION_SIZE_BYTES, &tmp.all);
         regs[i] = tmp.ui8.byteLow;
         addr++;
    	}
    	
    	// Appendix datasheet BMP390L
    
    	potencia = pow(2.0, -8.0);
    	calib_data.par_t1 = ((double)(regs[1] << 8 | regs[0]) / potencia);	
    
    	potencia = pow(2.0, 30.0);
    	calib_data.par_t2 = ((double)(regs[3] << 8 | regs[2]) / potencia);  
    
    	potencia =  pow(2.0, 48.0);
    	calib_data.par_t3 = ((double)regs[4] / potencia); 	
    
    	potencia = pow(2.0, 20.0);
    	calib_data.par_p1 = (((double)(regs[6] << 8 | regs[5])-(16384.0)) / potencia);
    
    	potencia = pow(2.0, 29.0);
    	calib_data.par_p2 = (((double)(regs[8] << 8 | regs[7])-(16384.0)) / potencia);
    
    	potencia = pow(2.0, 32.0);
    	calib_data.par_p3 = ((double)regs[9] / potencia);
    
    	potencia = pow(2.0, 37.0);
    	calib_data.par_p4 = ((double)regs[10] / potencia);
    
    	potencia = pow(2.0, -3.0);
    	calib_data.par_p5 = ((double)(regs[12] << 8 | regs[11]) / potencia);
    
    	potencia = pow(2.0, 6.0);
    	calib_data.par_p6 = ((double)(regs[14] << 8 | regs[13]) / potencia);
    
    	potencia = pow(2.0, 8.0);
    	calib_data.par_p7 = ((double)regs[15] / potencia);
    	
    	//potencia = 32768.0;
    	potencia = pow(2.0, 15.0);
    	calib_data.par_p8 = ((double)regs[16] / potencia);
    
    	potencia = pow(2.0, 48.0);
    	calib_data.par_p9 = ((double)(regs[18] << 8 | regs[17]) / potencia);
    
    	potencia = pow(2.0, 48.0);
    	calib_data.par_p10 = ((double)regs[19] / potencia);
    	
    	potencia = pow(2.0, 65.0);
    	calib_data.par_p11 = ((double)regs[20] / potencia);
    
    }
    static double BMP390L_compensate_temperature(uint32_t uncomp_temp, struct BMP390L_calib_data *calib_data)
    {	
        double partial_data1;
        double partial_data2;
    
        partial_data1 = (double)(uncomp_temp - calib_data->par_t1);
        partial_data2 = (double)(partial_data1 * calib_data->par_t2);
    
        // Update the compensated temperature in calib structure since this is
        // needed for pressure calculation 
        calib_data->t_lin = partial_data2 + (partial_data1 * partial_data1) * calib_data->par_t3;
    
        // Returns compensated temperature 
        return calib_data->t_lin;
    		
    }
    static double BMP390L_compensate_pressure(uint32_t uncomp_press, struct BMP390L_calib_data *calib_data)
    {
        /* Variable to store the compensated pressure */
        double comp_press;
    
        /* Temporary variables used for compensation */
        double partial_data1;
        double partial_data2;
        double partial_data3;
        double partial_data4;
        double partial_out1;
        double partial_out2;
    
        partial_data1 = calib_data->par_p6 * calib_data->t_lin;
        partial_data2 = calib_data->par_p7 * pow_bmp3(calib_data->t_lin, 2);
        partial_data3 = calib_data->par_p8 * pow_bmp3(calib_data->t_lin, 3);
        partial_out1 = calib_data->par_p5 + partial_data1 + partial_data2 + partial_data3;
        partial_data1 = calib_data->par_p2 * calib_data->t_lin;
        partial_data2 = calib_data->par_p3 * pow_bmp3(calib_data->t_lin, 2);
        partial_data3 = calib_data->par_p4 * pow_bmp3(calib_data->t_lin, 3);
        partial_out2 = uncomp_press * (calib_data->par_p1 + partial_data1 + partial_data2 + partial_data3);
        partial_data1 = pow_bmp3((double)uncomp_press, 2);
        partial_data2 = calib_data->par_p9 + calib_data->par_p10 * calib_data->t_lin;
        partial_data3 = partial_data1 * partial_data2;
        partial_data4 = partial_data3 + pow_bmp3((double)uncomp_press, 3) * calib_data->par_p11;
        comp_press = partial_out1 + partial_out2 + partial_data4;
    
        return comp_press/100;	// comp_press en pascales ------- hPa=mbar=Pa/100.
    }
    
    double pow_bmp3(double base, uint8_t power)
    {
        double pow_output = 1;
    
        while (power != 0)
        {
            pow_output = (float) base * pow_output;
            power--;
        }
    
        return pow_output;
    }

     

     

    On my main task, after call configuration functions (1st block of functions on this topic), I do the following to get a new value of pressure and temperature:

     

    double PA_Temp, PA_Pressure;
    
    ret1 = BMP390L_new_measurement(&PA_BMP390LStatus); // Forced mode. Pressure and temperature sensors enabled
    TaskWait((uint16_t) 5); // Change Task (wait 25ms to get new measurement, T_adquisition=20ms)
    
    PA_Temp = (double) INVALID_DATA;
    while ((PA_Temp < (double) BMP390L_TEMP_VAL_MIN) || (PA_Temp > (double) BMP390L_TEMP_VAL_MAX))
    { // while
    	PATempRead_BMP390L(&PA_BMP390LStatus, &valTemp);
    	PA_Temp = BMP390L_compensate_temperature(valTemp, &calib_data);
    } // while
    
    PA_Pressure = (double) INVALID_DATA;
    while ((PA_Pressure < (double) BMP390L_VAL_MIN) || (PA_Pressure > (double) BMP390L_VAL_MAX))
    {
    	PARead_BMP390L(&PA_BMP390LStatus, &val);
    	PA_Pressure = BMP390L_compensate_pressure(val, &calib_data);
    }

     

    Here it is, on my fisrt measurement (and always), when I get a wrong value of pressure (with difference of 35mbar) and temperature (difference of 1.5ºC).

     

    If you need more information about my program/script, do not hesitate to contact me.

     

    Thank you all again.

     

     

    Hi again Minhwan,

    I have solved it. I was doing an incorrect cast when I read the data registers of the compensation coefficients.

     

    Thank u very much for your support.

    Hello Javierrobledo, 

     

    Good to hear that you solved the issue. 

    Please let me know if you have any questions. 

    Thanks, 

    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