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.
... View more