mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-14 04:07:08 +01:00
Remove dependency from Sparkfun BME280 library
This commit is contained in:
@@ -66,6 +66,13 @@ unsigned char i2cFindAndLock(size_t size, unsigned char * addresses);
|
||||
bool i2cGetLock(unsigned char address);
|
||||
bool i2cReleaseLock(unsigned char address);
|
||||
|
||||
void i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value);
|
||||
uint8_t i2c_read_uint8(uint8_t address, uint8_t reg);
|
||||
uint16_t i2c_read_uint16(uint8_t address, uint8_t reg);
|
||||
uint16_t i2c_read_uint16_le(uint8_t address, uint8_t reg);
|
||||
int16_t i2c_read_int16(uint8_t address, uint8_t reg);
|
||||
int16_t i2c_read_int16_le(uint8_t address, uint8_t reg);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPIO
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -141,7 +141,11 @@
|
||||
#define BMX280_ADDRESS 0x00 // 0x00 means auto
|
||||
#endif
|
||||
|
||||
#define BMX280_MODE 1 // 1 for forced mode, 3 for normal mode
|
||||
#define BMX280_MODE 1 // 0 for sleep mode, 1 or 2 for forced mode, 3 for normal mode
|
||||
#define BMX280_STANDBY 0 // 0 for 0.5ms, 1 for 62.5ms, 2 for 125ms
|
||||
// 3 for 250ms, 4 for 500ms, 5 for 1000ms
|
||||
// 6 for 10ms, 7 for 20ms
|
||||
#define BMX280_FILTER 0 // 0 for OFF, 1 for 2 values, 2 for 4 values, 3 for 8 values and 4 for 16 values
|
||||
#define BMX280_TEMPERATURE 1 // Oversampling for temperature (set to 0 to disable magnitude)
|
||||
#define BMX280_HUMIDITY 1 // Oversampling for humidity (set to 0 to disable magnitude, only for BME280)
|
||||
#define BMX280_PRESSURE 1 // Oversampling for pressure (set to 0 to disable magnitude)
|
||||
|
||||
@@ -104,6 +104,52 @@ int _i2cClearbus(int sda, int scl) {
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// I2C API
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value) {
|
||||
Wire.beginTransmission((uint8_t) address);
|
||||
Wire.write((uint8_t) reg);
|
||||
Wire.write((uint8_t) value);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
uint8_t i2c_read_uint8(uint8_t address, uint8_t reg) {
|
||||
uint8_t value;
|
||||
Wire.beginTransmission((uint8_t) address);
|
||||
Wire.write((uint8_t) reg);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((uint8_t)address, (uint8_t) 1);
|
||||
value = Wire.read();
|
||||
Wire.endTransmission();
|
||||
return value;
|
||||
};
|
||||
|
||||
uint16_t i2c_read_uint16(uint8_t address, uint8_t reg) {
|
||||
uint16_t value;
|
||||
Wire.beginTransmission((uint8_t) address);
|
||||
Wire.write((uint8_t) reg);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((uint8_t) address, (uint8_t) 2);
|
||||
value = (Wire.read() << 8) | Wire.read();
|
||||
Wire.endTransmission();
|
||||
return value;
|
||||
};
|
||||
|
||||
uint16_t i2c_read_uint16_le(uint8_t address, uint8_t reg) {
|
||||
uint16_t temp = i2c_read_uint16(address, reg);
|
||||
return (temp >> 8) | (temp << 8);
|
||||
};
|
||||
|
||||
int16_t i2c_read_int16(uint8_t address, uint8_t reg) {
|
||||
return (int16_t) i2c_read_uint16(address, reg);
|
||||
};
|
||||
|
||||
int16_t i2c_read_int16_le(uint8_t address, uint8_t reg) {
|
||||
return (int16_t) i2c_read_uint16_le(address, reg);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utils
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// BME280/BMP280 Sensor over I2C
|
||||
// Uses SparkFun BME280 library
|
||||
// Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -10,10 +9,43 @@
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "I2CSensor.h"
|
||||
#include <SparkFunBME280.h>
|
||||
|
||||
#define BMX280_CHIP_BMP280 0x58
|
||||
#define BMX280_CHIP_BME280 0x60
|
||||
#define BMX280_CHIP_BMP280 0x58
|
||||
#define BMX280_CHIP_BME280 0x60
|
||||
|
||||
#define BMX280_REGISTER_DIG_T1 0x88
|
||||
#define BMX280_REGISTER_DIG_T2 0x8A
|
||||
#define BMX280_REGISTER_DIG_T3 0x8C
|
||||
|
||||
#define BMX280_REGISTER_DIG_P1 0x8E
|
||||
#define BMX280_REGISTER_DIG_P2 0x90
|
||||
#define BMX280_REGISTER_DIG_P3 0x92
|
||||
#define BMX280_REGISTER_DIG_P4 0x94
|
||||
#define BMX280_REGISTER_DIG_P5 0x96
|
||||
#define BMX280_REGISTER_DIG_P6 0x98
|
||||
#define BMX280_REGISTER_DIG_P7 0x9A
|
||||
#define BMX280_REGISTER_DIG_P8 0x9C
|
||||
#define BMX280_REGISTER_DIG_P9 0x9E
|
||||
|
||||
#define BMX280_REGISTER_DIG_H1 0xA1
|
||||
#define BMX280_REGISTER_DIG_H2 0xE1
|
||||
#define BMX280_REGISTER_DIG_H3 0xE3
|
||||
#define BMX280_REGISTER_DIG_H4 0xE4
|
||||
#define BMX280_REGISTER_DIG_H5 0xE5
|
||||
#define BMX280_REGISTER_DIG_H6 0xE7
|
||||
|
||||
#define BMX280_REGISTER_CHIPID 0xD0
|
||||
#define BMX280_REGISTER_VERSION 0xD1
|
||||
#define BMX280_REGISTER_SOFTRESET 0xE0
|
||||
|
||||
#define BMX280_REGISTER_CAL26 0xE1
|
||||
|
||||
#define BMX280_REGISTER_CONTROLHUMID 0xF2
|
||||
#define BMX280_REGISTER_CONTROL 0xF4
|
||||
#define BMX280_REGISTER_CONFIG 0xF5
|
||||
#define BMX280_REGISTER_PRESSUREDATA 0xF7
|
||||
#define BMX280_REGISTER_TEMPDATA 0xFA
|
||||
#define BMX280_REGISTER_HUMIDDATA 0xFD
|
||||
|
||||
class BMX280Sensor : public I2CSensor {
|
||||
|
||||
@@ -27,11 +59,6 @@ class BMX280Sensor : public I2CSensor {
|
||||
|
||||
BMX280Sensor(): I2CSensor() {
|
||||
_sensor_id = SENSOR_BMX280_ID;
|
||||
_bme = new BME280();
|
||||
}
|
||||
|
||||
~BMX280Sensor() {
|
||||
delete _bme;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@@ -91,8 +118,9 @@ class BMX280Sensor : public I2CSensor {
|
||||
}
|
||||
|
||||
#if BMX280_MODE == 1
|
||||
forceRead();
|
||||
_forceRead();
|
||||
#endif
|
||||
_read();
|
||||
|
||||
}
|
||||
|
||||
@@ -103,19 +131,20 @@ class BMX280Sensor : public I2CSensor {
|
||||
_error = SENSOR_ERROR_OK;
|
||||
unsigned char i = 0;
|
||||
#if BMX280_TEMPERATURE > 0
|
||||
if (index == i++) return _bme->readTempC();
|
||||
if (index == i++) return _temperature;
|
||||
#endif
|
||||
#if BMX280_PRESSURE > 0
|
||||
if (index == i++) return _bme->readFloatPressure() / 100;
|
||||
if (index == i++) return _pressure / 100;
|
||||
#endif
|
||||
#if BMX280_HUMIDITY > 0
|
||||
if (_chip == BMX280_CHIP_BME280) {
|
||||
if (index == i) return _bme->readFloatHumidity();
|
||||
if (index == i) return _humidity;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_error = SENSOR_ERROR_OUT_OF_RANGE;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// Load the configuration manifest
|
||||
@@ -161,23 +190,11 @@ class BMX280Sensor : public I2CSensor {
|
||||
|
||||
void _init() {
|
||||
|
||||
_bme->settings.commInterface = I2C_MODE;
|
||||
_bme->settings.I2CAddress = _address;
|
||||
_bme->settings.runMode = BMX280_MODE;
|
||||
_bme->settings.tStandby = 0;
|
||||
_bme->settings.filter = 0;
|
||||
_bme->settings.tempOverSample = BMX280_TEMPERATURE;
|
||||
_bme->settings.pressOverSample = BMX280_PRESSURE;
|
||||
_bme->settings.humidOverSample = BMX280_HUMIDITY;
|
||||
|
||||
// Fix when not measuring temperature, t_fine should have a sensible value
|
||||
if (BMX280_TEMPERATURE == 0) _bme->t_fine = 100000; // aprox 20ºC
|
||||
|
||||
// Make sure sensor had enough time to turn on. BMX280 requires 2ms to start up
|
||||
delay(10);
|
||||
|
||||
// Check sensor correctly initialized
|
||||
_chip = _bme->begin();
|
||||
_chip = i2c_read_uint8(_address, BMX280_REGISTER_CHIPID);
|
||||
if ((_chip != BMX280_CHIP_BME280) && (_chip != BMX280_CHIP_BMP280)) {
|
||||
_chip = 0;
|
||||
i2cReleaseLock(_address);
|
||||
@@ -194,11 +211,51 @@ class BMX280Sensor : public I2CSensor {
|
||||
if (_chip == BMX280_CHIP_BME280) ++_count;
|
||||
#endif
|
||||
|
||||
_measurement_delay = measurementTime();
|
||||
_readCoefficients();
|
||||
|
||||
unsigned char data = 0;
|
||||
i2c_write_uint8(_address, BMX280_REGISTER_CONTROL, data);
|
||||
|
||||
data = (BMX280_STANDBY << 0x5) & 0xE0;
|
||||
data |= (BMX280_FILTER << 0x02) & 0x1C;
|
||||
i2c_write_uint8(_address, BMX280_REGISTER_CONFIG, data);
|
||||
|
||||
data = (BMX280_HUMIDITY) & 0x07;
|
||||
i2c_write_uint8(_address, BMX280_REGISTER_CONTROLHUMID, data);
|
||||
|
||||
data = (BMX280_TEMPERATURE << 5) & 0xE0;
|
||||
data |= (BMX280_PRESSURE << 2) & 0x1C;
|
||||
data |= (BMX280_MODE) & 0x03;
|
||||
i2c_write_uint8(_address, BMX280_REGISTER_CONTROL, data);
|
||||
|
||||
_measurement_delay = _measurementTime();
|
||||
|
||||
}
|
||||
|
||||
unsigned long measurementTime() {
|
||||
void _readCoefficients() {
|
||||
_bmx280_calib.dig_T1 = i2c_read_uint16_le(_address, BMX280_REGISTER_DIG_T1);
|
||||
_bmx280_calib.dig_T2 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_T2);
|
||||
_bmx280_calib.dig_T3 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_T3);
|
||||
|
||||
_bmx280_calib.dig_P1 = i2c_read_uint16_le(_address, BMX280_REGISTER_DIG_P1);
|
||||
_bmx280_calib.dig_P2 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P2);
|
||||
_bmx280_calib.dig_P3 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P3);
|
||||
_bmx280_calib.dig_P4 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P4);
|
||||
_bmx280_calib.dig_P5 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P5);
|
||||
_bmx280_calib.dig_P6 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P6);
|
||||
_bmx280_calib.dig_P7 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P7);
|
||||
_bmx280_calib.dig_P8 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P8);
|
||||
_bmx280_calib.dig_P9 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_P9);
|
||||
|
||||
_bmx280_calib.dig_H1 = i2c_read_uint8(_address, BMX280_REGISTER_DIG_H1);
|
||||
_bmx280_calib.dig_H2 = i2c_read_int16_le(_address, BMX280_REGISTER_DIG_H2);
|
||||
_bmx280_calib.dig_H3 = i2c_read_uint8(_address, BMX280_REGISTER_DIG_H3);
|
||||
_bmx280_calib.dig_H4 = (i2c_read_uint8(_address, BMX280_REGISTER_DIG_H4) << 4) | (i2c_read_uint8(_address, BMX280_REGISTER_DIG_H4+1) & 0xF);
|
||||
_bmx280_calib.dig_H5 = (i2c_read_uint8(_address, BMX280_REGISTER_DIG_H5+1) << 4) | (i2c_read_uint8(_address, BMX280_REGISTER_DIG_H5) >> 4);
|
||||
_bmx280_calib.dig_H6 = (int8_t) i2c_read_uint8(_address, BMX280_REGISTER_DIG_H6);
|
||||
}
|
||||
|
||||
unsigned long _measurementTime() {
|
||||
|
||||
// Measurement Time (as per BMX280 datasheet section 9.1)
|
||||
// T_max(ms) = 1.25
|
||||
@@ -224,23 +281,135 @@ class BMX280Sensor : public I2CSensor {
|
||||
|
||||
}
|
||||
|
||||
void forceRead() {
|
||||
void _forceRead() {
|
||||
|
||||
// We set the sensor in "forced mode" to force a reading.
|
||||
// After the reading the sensor will go back to sleep mode.
|
||||
uint8_t value = _bme->readRegister(BME280_CTRL_MEAS_REG);
|
||||
uint8_t value = i2c_read_uint8(_address, BMX280_REGISTER_CONTROL);
|
||||
value = (value & 0xFC) + 0x01;
|
||||
_bme->writeRegister(BME280_CTRL_MEAS_REG, value);
|
||||
i2c_write_uint8(_address, BMX280_REGISTER_CONTROL, value);
|
||||
|
||||
delay(_measurement_delay);
|
||||
|
||||
}
|
||||
|
||||
void _read() {
|
||||
|
||||
#if BMX280_TEMPERATURE > 0
|
||||
int32_t adc_T = i2c_read_uint16(_address, BMX280_REGISTER_TEMPDATA);
|
||||
adc_T <<= 8;
|
||||
adc_T |= i2c_read_uint8(_address, BMX280_REGISTER_TEMPDATA+2);
|
||||
adc_T >>= 4;
|
||||
|
||||
int32_t var1t = ((((adc_T>>3) -
|
||||
((int32_t)_bmx280_calib.dig_T1 <<1))) *
|
||||
((int32_t)_bmx280_calib.dig_T2)) >> 11;
|
||||
|
||||
int32_t var2t = (((((adc_T>>4) -
|
||||
((int32_t)_bmx280_calib.dig_T1)) *
|
||||
((adc_T>>4) - ((int32_t)_bmx280_calib.dig_T1))) >> 12) *
|
||||
((int32_t)_bmx280_calib.dig_T3)) >> 14;
|
||||
|
||||
int32_t t_fine = var1t + var2t;
|
||||
|
||||
double T = (t_fine * 5 + 128) >> 8;
|
||||
_temperature = T / 100;
|
||||
#else
|
||||
int32_t t_fine = 102374; // ~20ºC
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
#if BMX280_PRESSURE > 0
|
||||
int64_t var1, var2, p;
|
||||
|
||||
int32_t adc_P = i2c_read_uint16(_address, BMX280_REGISTER_PRESSUREDATA);
|
||||
adc_P <<= 8;
|
||||
adc_P |= i2c_read_uint8(_address, BMX280_REGISTER_PRESSUREDATA+2);
|
||||
adc_P >>= 4;
|
||||
|
||||
var1 = ((int64_t)t_fine) - 128000;
|
||||
var2 = var1 * var1 * (int64_t)_bmx280_calib.dig_P6;
|
||||
var2 = var2 + ((var1*(int64_t)_bmx280_calib.dig_P5)<<17);
|
||||
var2 = var2 + (((int64_t)_bmx280_calib.dig_P4)<<35);
|
||||
var1 = ((var1 * var1 * (int64_t)_bmx280_calib.dig_P3)>>8) +
|
||||
((var1 * (int64_t)_bmx280_calib.dig_P2)<<12);
|
||||
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)_bmx280_calib.dig_P1)>>33;
|
||||
if (var1 == 0) return; // avoid exception caused by division by zero
|
||||
|
||||
p = 1048576 - adc_P;
|
||||
p = (((p<<31) - var2)*3125) / var1;
|
||||
var1 = (((int64_t)_bmx280_calib.dig_P9) * (p>>13) * (p>>13)) >> 25;
|
||||
var2 = (((int64_t)_bmx280_calib.dig_P8) * p) >> 19;
|
||||
|
||||
p = ((p + var1 + var2) >> 8) + (((int64_t)_bmx280_calib.dig_P7)<<4);
|
||||
_pressure = (double) p / 256;
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
#if BMX280_HUMIDITY > 0
|
||||
if (_chip == BMX280_CHIP_BME280) {
|
||||
|
||||
int32_t adc_H = i2c_read_uint16(_address, BMX280_REGISTER_HUMIDDATA);
|
||||
|
||||
int32_t v_x1_u32r;
|
||||
|
||||
v_x1_u32r = (t_fine - ((int32_t)76800));
|
||||
|
||||
v_x1_u32r = (((((adc_H << 14) - (((int32_t)_bmx280_calib.dig_H4) << 20) -
|
||||
(((int32_t)_bmx280_calib.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
|
||||
(((((((v_x1_u32r * ((int32_t)_bmx280_calib.dig_H6)) >> 10) *
|
||||
(((v_x1_u32r * ((int32_t)_bmx280_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) +
|
||||
((int32_t)2097152)) * ((int32_t)_bmx280_calib.dig_H2) + 8192) >> 14));
|
||||
|
||||
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
|
||||
((int32_t)_bmx280_calib.dig_H1)) >> 4));
|
||||
|
||||
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
|
||||
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
|
||||
double h = (v_x1_u32r >> 12);
|
||||
_humidity = h / 1024.0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
BME280 * _bme = NULL;
|
||||
unsigned char _chip;
|
||||
unsigned long _measurement_delay;
|
||||
double _temperature = 0;
|
||||
double _pressure = 0;
|
||||
double _humidity = 0;
|
||||
|
||||
typedef struct {
|
||||
|
||||
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;
|
||||
|
||||
uint8_t dig_H1;
|
||||
int16_t dig_H2;
|
||||
uint8_t dig_H3;
|
||||
int16_t dig_H4;
|
||||
int16_t dig_H5;
|
||||
int8_t dig_H6;
|
||||
|
||||
} bmx280_calib_t;
|
||||
|
||||
bmx280_calib_t _bmx280_calib;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ lib_deps =
|
||||
OneWire
|
||||
Brzo I2C
|
||||
https://github.com/krosk93/espsoftwareserial#a770677
|
||||
SparkFun BME280
|
||||
PMS Library
|
||||
https://github.com/madpilot/mDNSResolver#4cfcda1
|
||||
https://bitbucket.org/xoseperez/justwifi.git#1.1.6
|
||||
|
||||
Reference in New Issue
Block a user