Improve driver
- switch to continuous measurement - switch to double precision compensation formulas (datasheet section 8.1) - uncrustify Output of BMP280 and MPL3115 are now quite similar: INFO src/main.c i2c_scanner | I2C Address 0x60 true INFO src/main.c i2c_scanner | I2C Address 0x76 true DEBUG src/mgos_barometer.c mgos_barometer_create_i2c | Successfully detected mgos_barometer_type 2 at I2C 0x60 DEBUG src/mgos_barometer.c mgos_barometer_create_i2c | Successfully created mgos_barometer_type 2 at I2C 0x60 DEBUG src/mgos_barometer.c mgos_barometer_create_i2c | Successfully detected mgos_barometer_type 3 at I2C 0x76 DEBUG src/mgos_barometer.c mgos_barometer_create_i2c | Successfully created mgos_barometer_type 3 at I2C 0x76 INFO src/main.c do_baro | Pressure 96623.25Pa INFO src/main.c do_baro | Temperature 16.75C INFO src/main.c do_baro | Pressure 96629.70Pa INFO src/main.c do_baro | Temperature 18.45C INFO src/main.c do_baro | Pressure 96620.50Pa INFO src/main.c do_baro | Temperature 16.75C INFO src/main.c do_baro | Pressure 96633.49Pa INFO src/main.c do_baro | Temperature 18.43C
This commit is contained in:
@ -7,7 +7,9 @@
|
||||
bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
|
||||
int val;
|
||||
|
||||
if (!dev) return false;
|
||||
if (!dev) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, BME280_REG_DEVID)) < 0) {
|
||||
return false;
|
||||
@ -17,11 +19,12 @@ bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
|
||||
LOG(LL_INFO, ("Preproduction version of BMP280 detected (0x%02x)", val));
|
||||
return true;
|
||||
}
|
||||
if (val == 0x58) // Mass production BMP280
|
||||
if (val == 0x58) { // Mass production BMP280
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val == 0x60) { // Mass production BME280
|
||||
dev->capabilities|=MGOS_BAROMETER_CAP_HYGROMETER;
|
||||
dev->capabilities |= MGOS_BAROMETER_CAP_HYGROMETER;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -31,41 +34,51 @@ bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
|
||||
bool mgos_barometer_bme280_create(struct mgos_barometer *dev) {
|
||||
struct mgos_barometer_bme280_data *bme280_data;
|
||||
|
||||
if (!dev) return false;
|
||||
if (!dev) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bme280_data=calloc(1, sizeof(struct mgos_barometer_bme280_data));
|
||||
if (!bme280_data) return false;
|
||||
dev->user_data=bme280_data;
|
||||
bme280_data = calloc(1, sizeof(struct mgos_barometer_bme280_data));
|
||||
if (!bme280_data) {
|
||||
return false;
|
||||
}
|
||||
dev->user_data = bme280_data;
|
||||
|
||||
// Reset device
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_RESET, 0xB6))
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_RESET, 0xB6)) {
|
||||
return false;
|
||||
}
|
||||
mgos_usleep(10000);
|
||||
|
||||
// Read calibration data
|
||||
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_TEMPERATURE_CALIB_DIG_T1_LSB, 24, (uint8_t *)bme280_data))
|
||||
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_TEMPERATURE_CALIB_DIG_T1_LSB, 24, (uint8_t *)bme280_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// SPI | 0.5ms period | 16X IIR filter
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CONFIG, 0x00 | BME280_STANDBY_500us << 2 | BME280_FILTER_16X << 5))
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CONFIG, 0x00 | BME280_STANDBY_500us << 2 | BME280_FILTER_16X << 5)) {
|
||||
return false;
|
||||
}
|
||||
mgos_usleep(10000);
|
||||
|
||||
// Mode | Pressure OS | Temp OS
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CTRL_MEAS, BME280_MODE_NORMAL | BME280_OVERSAMP_16X << 2 | BME280_OVERSAMP_2X << 5))
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CTRL_MEAS, BME280_MODE_NORMAL | BME280_OVERSAMP_16X << 2 | BME280_OVERSAMP_2X << 5)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dev->capabilities|=MGOS_BAROMETER_CAP_BAROMETER;
|
||||
dev->capabilities|=MGOS_BAROMETER_CAP_THERMOMETER;
|
||||
dev->capabilities |= MGOS_BAROMETER_CAP_BAROMETER;
|
||||
dev->capabilities |= MGOS_BAROMETER_CAP_THERMOMETER;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mgos_barometer_bme280_destroy(struct mgos_barometer *dev) {
|
||||
if (!dev) return false;
|
||||
if (!dev) {
|
||||
return false;
|
||||
}
|
||||
if (dev->user_data) {
|
||||
free(dev->user_data);
|
||||
dev->user_data=NULL;
|
||||
dev->user_data = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -73,46 +86,55 @@ bool mgos_barometer_bme280_destroy(struct mgos_barometer *dev) {
|
||||
bool mgos_barometer_bme280_read(struct mgos_barometer *dev) {
|
||||
struct mgos_barometer_bme280_data *bme280_data;
|
||||
|
||||
if (!dev) return false;
|
||||
bme280_data=(struct mgos_barometer_bme280_data *) dev->user_data;
|
||||
if (!bme280_data) return false;
|
||||
if (!dev) {
|
||||
return false;
|
||||
}
|
||||
bme280_data = (struct mgos_barometer_bme280_data *)dev->user_data;
|
||||
if (!bme280_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// read data from sensor
|
||||
uint8_t data[6];
|
||||
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_PRESSURE_MSB, 6, data))
|
||||
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_PRESSURE_MSB, 6, data)) {
|
||||
return false;
|
||||
}
|
||||
int32_t Padc, Tadc;
|
||||
Padc = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
|
||||
Tadc = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
|
||||
// LOG(LL_DEBUG, ("Padc=%d Tadc=%d", Padc, Tadc));
|
||||
|
||||
int32_t var1, var2, T, t_fine, P;
|
||||
// Temp conversion:
|
||||
var1 = ((((Tadc >> 3) - ((int32_t)bme280_data->calib.dig_T1 << 1))) * ((int32_t)bme280_data->calib.dig_T2)) >> 11;
|
||||
var2 = (((((Tadc >> 4) - ((int32_t)bme280_data->calib.dig_T1)) * ((Tadc >> 4) - ((int32_t)bme280_data->calib.dig_T1))) >> 12) * ((int32_t)bme280_data->calib.dig_T3)) >> 14;
|
||||
t_fine = var1 + var2;
|
||||
T = (t_fine * 5 + 128) >> 8; // in hundredth of degrees C; 5123 means 51.23C
|
||||
dev->temperature=(float)T/100.0;
|
||||
// Convert data (from datasheet, section 8.1)
|
||||
double var1, var2, T, P;
|
||||
int32_t t_fine;
|
||||
|
||||
// Pressure conversion:
|
||||
var1 = ((int64_t)t_fine) - 128000;
|
||||
var2 = var1 * var1 * (int64_t)bme280_data->calib.dig_P6;
|
||||
var2 = var2 + ((var1*(int64_t)bme280_data->calib.dig_P5) << 17);
|
||||
var2 = var2 + (((int64_t)bme280_data->calib.dig_P4) << 35);
|
||||
var1 = ((var1 * var1 * (int64_t)bme280_data->calib.dig_P3) >> 8) + ((var1 * (int64_t)bme280_data->calib.dig_P2) << 12);
|
||||
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)bme280_data->calib.dig_P1) >> 33;
|
||||
if (var1 == 0) {
|
||||
P=0;
|
||||
// Compensation for temperature -- double precision
|
||||
var1 = (((double)Tadc) / 16384.0 - ((double)bme280_data->calib.dig_T1) / 1024.0) * ((double)bme280_data->calib.dig_T2);
|
||||
var2 = ((((double)Tadc) / 131072.0 - ((double)bme280_data->calib.dig_T1) / 8192.0) *
|
||||
(((double)Tadc) / 131072.0 - ((double)bme280_data->calib.dig_T1) / 8192.0)) * ((double)bme280_data->calib.dig_T3);
|
||||
t_fine = (int32_t)(var1 + var2);
|
||||
T = (var1 + var2) / 5120.0;
|
||||
dev->temperature = (float)T;
|
||||
|
||||
// Compensation for pressure -- double precision
|
||||
var1 = ((double)t_fine / 2.0) - 64000.0;
|
||||
var2 = var1 * var1 * ((double)bme280_data->calib.dig_P6) / 32768.0;
|
||||
var2 = var2 + var1 * ((double)bme280_data->calib.dig_P5) * 2.0;
|
||||
var2 = (var2 / 4.0) + (((double)bme280_data->calib.dig_P4) * 65536.0);
|
||||
var1 = (((double)bme280_data->calib.dig_P3) * var1 * var1 / 524288.0 + ((double)bme280_data->calib.dig_P2) * var1) / 524288.0;
|
||||
var1 = (1.0 + var1 / 32768.0) * ((double)bme280_data->calib.dig_P1);
|
||||
if (var1 == 0.0) {
|
||||
P = 0.0;
|
||||
} else {
|
||||
P = 1048576 - Padc;
|
||||
P = (((P << 31) - var2) * 3125) / var1;
|
||||
var1 = (((int64_t)bme280_data->calib.dig_P9) * (P >> 13) * (P >> 13)) >> 25;
|
||||
var2 = (((int64_t)bme280_data->calib.dig_P8) * P) >> 19;
|
||||
P = ((P + var1 + var2) >> 8) + (((int64_t)bme280_data->calib.dig_P7) << 4);
|
||||
P = 1048576.0 - (double)Padc;
|
||||
P = (P - (var2 / 4096.0)) * 6250.0 / var1;
|
||||
var1 = ((double)bme280_data->calib.dig_P9) * P * P / 2147483648.0;
|
||||
var2 = P * ((double)bme280_data->calib.dig_P8) / 32768.0;
|
||||
P = P + (var1 + var2 + ((double)bme280_data->calib.dig_P7)) / 16.0;
|
||||
}
|
||||
dev->pressure=((float)P/256.0)*100;
|
||||
dev->pressure = (float)P;
|
||||
|
||||
// LOG(LL_DEBUG, ("P=%.2f T=%.2f", dev->pressure, dev->temperature));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user