Add partial BMP280/BME280 driver
This commit is contained in:
@ -5,15 +5,57 @@
|
||||
// https://cdn-shop.adafruit.com/datasheets/MPL115A2.pdf
|
||||
|
||||
bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
|
||||
int val;
|
||||
|
||||
if (!dev) return false;
|
||||
return false;
|
||||
|
||||
if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, BME280_REG_DEVID)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val == 0x56 || val == 0x57) {
|
||||
LOG(LL_INFO, ("Preproduction version of BMP280 detected (0x%02x)", val));
|
||||
return true;
|
||||
}
|
||||
if (val == 0x58) // Mass production BMP280
|
||||
return true;
|
||||
|
||||
if (val == 0x60) // Mass production BME280
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mgos_barometer_bme280_create(struct mgos_barometer *dev) {
|
||||
struct mgos_barometer_bme280_data *bme280_data;
|
||||
|
||||
if (!dev) return false;
|
||||
return false;
|
||||
|
||||
bme280_data=calloc(1, sizeof(struct mgos_barometer_bme280_data));
|
||||
if (!bme280_data) return false;
|
||||
dev->user_data=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;
|
||||
|
||||
// Mode | Pressure OS | Temp OS
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CTRL_MEAS, BME280_MODE_SLEEP | BME280_OVERSAMP_1X << 2 | BME280_OVERSAMP_1X << 5))
|
||||
return false;
|
||||
mgos_usleep(10000);
|
||||
|
||||
// SPI | 250ms period | no filter
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CONFIG, 0x00 | 0x04 << 2 | 0x00 << 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_1X << 2 | BME280_OVERSAMP_1X << 5))
|
||||
return false;
|
||||
|
||||
dev->has_barometer=true;
|
||||
dev->has_thermometer=true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mgos_barometer_bme280_destroy(struct mgos_barometer *dev) {
|
||||
@ -32,6 +74,48 @@ bool mgos_barometer_bme280_read(struct mgos_barometer *dev) {
|
||||
bme280_data=(struct mgos_barometer_bme280_data *) dev->user_data;
|
||||
if (!bme280_data) return false;
|
||||
|
||||
return false;
|
||||
// Forced Mode | 8x OS Pressure | 1x OS Temp
|
||||
// 0x01 | 0x04 << 2 | 0x01 << 5
|
||||
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CTRL_MEAS, 0x01 | 0x04 << 2 | 0x01 << 5))
|
||||
return false;
|
||||
mgos_usleep(10000);
|
||||
|
||||
// read data from sensor
|
||||
uint8_t data[6];
|
||||
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;
|
||||
|
||||
// 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;
|
||||
} 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);
|
||||
}
|
||||
dev->pressure=((float)P/256.0)*1000;
|
||||
// LOG(LL_DEBUG, ("P=%.2f T=%.2f", dev->pressure, dev->temperature));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,71 @@
|
||||
#include "mgos.h"
|
||||
#include "mgos_barometer_internal.h"
|
||||
|
||||
// DevID: 0x56/0x57 are samples of BMP280; 0x58 is mass production BMP280; 0x60 is BME280
|
||||
#define BME280_REG_DEVID (0xD0) /* Chip ID Register */
|
||||
#define BME280_REG_RESET (0xE0) /* Softreset Register */
|
||||
#define BME280_REG_STATUS (0xF3) /* Status Register */
|
||||
#define BME280_REG_CTRL_MEAS (0xF4) /* Ctrl Measure Register */
|
||||
#define BME280_REG_CONFIG (0xF5) /* Configuration Register */
|
||||
#define BME280_REG_PRESSURE_MSB (0xF7) /* Pressure MSB Register */
|
||||
#define BME280_REG_PRESSURE_LSB (0xF8) /* Pressure LSB Register */
|
||||
#define BME280_REG_PRESSURE_XLSB (0xF9) /* Pressure XLSB Register */
|
||||
#define BME280_REG_TEMPERATURE_MSB (0xFA) /* Temperature MSB Reg */
|
||||
#define BME280_REG_TEMPERATURE_LSB (0xFB) /* Temperature LSB Reg */
|
||||
#define BME280_REG_TEMPERATURE_XLSB (0xFC) /* Temperature XLSB Reg */
|
||||
#define BME280_REG_HUMIDITY_MSB (0xFD) /* Humidity MSB Reg (BME280 only)*/
|
||||
#define BME280_REG_HUMIDITY_LSB (0xFE) /* Humidity LSB Reg (BME280 only)*/
|
||||
#define BME280_MODE_SLEEP (0x00)
|
||||
#define BME280_MODE_FORCED (0x01)
|
||||
#define BME280_MODE_NORMAL (0x03)
|
||||
|
||||
#define BME280_REG_TEMPERATURE_CALIB_DIG_T1_LSB (0x88)
|
||||
|
||||
#define BME280_OVERSAMP_NONE (0x00)
|
||||
#define BME280_OVERSAMP_1X (0x01)
|
||||
#define BME280_OVERSAMP_2X (0x02)
|
||||
#define BME280_OVERSAMP_4X (0x03)
|
||||
#define BME280_OVERSAMP_8X (0x04)
|
||||
#define BME280_OVERSAMP_16X (0x05)
|
||||
|
||||
#define BME280_STANDBY_500us (0x00)
|
||||
#define BME280_STANDBY_62ms (0x01)
|
||||
#define BME280_STANDBY_125ms (0x02)
|
||||
#define BME280_STANDBY_250ms (0x03)
|
||||
#define BME280_STANDBY_500ms (0x04)
|
||||
#define BME280_STANDBY_1000ms (0x05)
|
||||
// Note: Datasheet defines 110 == 10ms, 111 == 20ms, but BME280 and BMP280
|
||||
// implement this differently.
|
||||
|
||||
|
||||
struct mgos_barometer_bme280_calib_data {
|
||||
// Calibration data:
|
||||
uint16_t dig_T1;
|
||||
int16_t dig_T2;
|
||||
int16_t dig_T3;
|
||||
uint16_t dig_P1;
|
||||
int16_t dig_P2;
|
||||
int16_t dig_P3;
|
||||
int16_t dig_P4;
|
||||
int16_t dig_P5;
|
||||
int16_t dig_P6;
|
||||
int16_t dig_P7;
|
||||
int16_t dig_P8;
|
||||
int16_t dig_P9;
|
||||
|
||||
// Additional calibration data for BME280
|
||||
uint8_t dig_H1;
|
||||
int16_t dig_H2;
|
||||
uint8_t dig_H3;
|
||||
int16_t dig_H4; // Note: this is 0xE4 / 0xE5[3:0]
|
||||
int16_t dig_H5; // Note: this is 0xE5[7:4] / 0xE6
|
||||
int8_t dig_H6;
|
||||
};
|
||||
|
||||
struct mgos_barometer_bme280_data {
|
||||
float a0, b1, b2, c12;
|
||||
struct mgos_barometer_bme280_calib_data calib;
|
||||
|
||||
float humidity;
|
||||
};
|
||||
|
||||
bool mgos_barometer_bme280_detect(struct mgos_barometer *dev);
|
||||
|
Reference in New Issue
Block a user