Skip to content

Commit 5fb1eeb

Browse files
committed
BME280 humidity sensing support addition. Aligned with Bosch driver for the sensor
1 parent 8941649 commit 5fb1eeb

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

src/mgos_barometer_bme280.c

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
#include "mgos_barometer_bme280.h"
1818
#include "mgos_i2c.h"
1919

20+
#define BME280_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)
21+
2022
// Datasheet:
2123
// https://cdn-shop.adafruit.com/datasheets/BST-BME280_DS001-10.pdf
2224
//
23-
// TODO(pim): Add humidity sensing
25+
2426

2527
bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
2628
int val;
@@ -33,6 +35,9 @@ bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
3335
return false;
3436
}
3537

38+
LOG(LL_DEBUG, ("Detecting BMx280 %d, reg b is: %d", dev->i2caddr, val));
39+
40+
3641
if (val == 0x56 || val == 0x57) {
3742
LOG(LL_INFO, ("Preproduction version of BMP280 detected (0x%02x)", val));
3843
return true;
@@ -74,19 +79,51 @@ bool mgos_barometer_bme280_create(struct mgos_barometer *dev) {
7479
return false;
7580
}
7681

82+
if( dev->capabilities && MGOS_BAROMETER_CAP_HYGROMETER ) {
83+
uint8_t reg_data[ 7 ];
84+
int16_t dig_h4_lsb;
85+
int16_t dig_h4_msb;
86+
int16_t dig_h5_lsb;
87+
int16_t dig_h5_msb;
88+
89+
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_HUMIDITY_CALIB_ADDR, 7, reg_data)) {
90+
free(dev->user_data);
91+
return false;
92+
}
93+
94+
bme280_data->calib.dig_H2 = (int16_t)BME280_CONCAT_BYTES(reg_data[1], reg_data[0]);
95+
bme280_data->calib.dig_H3 = reg_data[2];
96+
dig_h4_msb = (int16_t)(int8_t)reg_data[3] * 16;
97+
dig_h4_lsb = (int16_t)(reg_data[4] & 0x0F);
98+
bme280_data->calib.dig_H4 = dig_h4_msb | dig_h4_lsb;
99+
dig_h5_msb = (int16_t)(int8_t)reg_data[5] * 16;
100+
dig_h5_lsb = (int16_t)(reg_data[4] >> 4);
101+
bme280_data->calib.dig_H5 = dig_h5_msb | dig_h5_lsb;
102+
bme280_data->calib.dig_H6 = (int8_t)reg_data[6];
103+
}
104+
77105
// SPI | 0.5ms period | 16X IIR filter
78106
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CONFIG, 0x00 | BME280_STANDBY_500us << 2 | BME280_FILTER_16X << 5)) {
79107
free(dev->user_data);
80108
return false;
81109
}
82110
mgos_usleep(10000);
83111

112+
113+
// Humidity OS
114+
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CTRL_HUM, BME280_OVERSAMP_2X)) {
115+
free(dev->user_data);
116+
return false;
117+
}
118+
mgos_usleep(5000);
119+
84120
// Mode | Pressure OS | Temp OS
85121
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)) {
86122
free(dev->user_data);
87123
return false;
88124
}
89125

126+
90127
dev->capabilities |= MGOS_BAROMETER_CAP_BAROMETER;
91128
dev->capabilities |= MGOS_BAROMETER_CAP_THERMOMETER;
92129

@@ -116,17 +153,19 @@ bool mgos_barometer_bme280_read(struct mgos_barometer *dev) {
116153
}
117154

118155
// read data from sensor
119-
uint8_t data[6];
120-
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_PRESSURE_MSB, 6, data)) {
156+
uint8_t data[8];
157+
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_PRESSURE_MSB, 8, data)) {
121158
return false;
122159
}
123-
int32_t Padc, Tadc;
124-
Padc = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
125-
Tadc = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
126-
// LOG(LL_DEBUG, ("Padc=%d Tadc=%d", Padc, Tadc));
160+
uint32_t Padc, Tadc, Hadc;
161+
Padc = (uint32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
162+
Tadc = (uint32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
163+
Hadc = (data[6]) << 8 | data[7];
127164

128165
// Convert data (from datasheet, section 8.1)
129-
double var1, var2, T, P;
166+
double var1, var2, var3, var4, var5, var6, T, P, H;
167+
double H_min = 1.0;
168+
double H_max = 100.0;
130169
int32_t t_fine;
131170

132171
// Compensation for temperature -- double precision
@@ -155,7 +194,27 @@ bool mgos_barometer_bme280_read(struct mgos_barometer *dev) {
155194
}
156195
dev->pressure = (float)P;
157196

158-
// LOG(LL_DEBUG, ("P=%.2f T=%.2f", dev->pressure, dev->temperature));
197+
H = 0.0;
198+
if( dev->capabilities && MGOS_BAROMETER_CAP_HYGROMETER ) {
199+
// Compensation for humidity
200+
var1 = ((double)t_fine) - 76800.0;
201+
var2 = (((double)bme280_data->calib.dig_H4) * 64.0 + (((double) bme280_data->calib.dig_H5) / 16384.0) * var1);
202+
var3 = Hadc - var2;
203+
var4 = ((double)bme280_data->calib.dig_H2) / 65536.0;
204+
var5 = (1.0 + (((double) bme280_data->calib.dig_H3) / 67108864.0) * var1);
205+
var6 = 1.0 + (((double) bme280_data->calib.dig_H6) / 67108864.0) * var1 * var5;
206+
var6 = var3 * var4 * (var5 * var6);
207+
H = var6 * (1.0 - ((double) bme280_data->calib.dig_H1) * var6 / 524288.0);
208+
209+
if (H > H_max)
210+
H = H_max;
211+
else if (H < H_min)
212+
H = H_min;
213+
}
214+
215+
dev->humidity = (float)H;
216+
217+
LOG(LL_DEBUG, ("P=%.2f T=%.2f H=%.2f", dev->pressure, dev->temperature, dev->humidity));
159218

160219
return true;
161220
}

src/mgos_barometer_bme280.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
// DevID: 0x56/0x57 are samples of BMP280; 0x58 is mass production BMP280; 0x60 is BME280
2323
#define BME280_REG_DEVID (0xD0) /* Chip ID Register */
2424
#define BME280_REG_RESET (0xE0) /* Softreset Register */
25+
#define BME280_REG_CTRL_HUM (0xF2) /* Humidity oversampling */
2526
#define BME280_REG_STATUS (0xF3) /* Status Register */
2627
#define BME280_REG_CTRL_MEAS (0xF4) /* Ctrl Measure Register */
2728
#define BME280_REG_CONFIG (0xF5) /* Configuration Register */
@@ -38,6 +39,7 @@
3839
#define BME280_MODE_NORMAL (0x03)
3940

4041
#define BME280_REG_TEMPERATURE_CALIB_DIG_T1_LSB (0x88)
42+
#define BME280_REG_HUMIDITY_CALIB_ADDR (0xE1)
4143

4244
#define BME280_OVERSAMP_SKIPPED (0x00)
4345
#define BME280_OVERSAMP_1X (0x01)

0 commit comments

Comments
 (0)