Browse Source

Remove dependency from Sparkfun BME280 library

softuart
Xose Pérez 6 years ago
parent
commit
bc85600e9c
5 changed files with 259 additions and 34 deletions
  1. +7
    -0
      code/espurna/config/prototypes.h
  2. +5
    -1
      code/espurna/config/sensors.h
  3. +46
    -0
      code/espurna/i2c.ino
  4. +201
    -32
      code/espurna/sensors/BMX280Sensor.h
  5. +0
    -1
      code/platformio.ini

+ 7
- 0
code/espurna/config/prototypes.h View File

@ -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
// -----------------------------------------------------------------------------


+ 5
- 1
code/espurna/config/sensors.h View File

@ -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)


+ 46
- 0
code/espurna/i2c.ino View File

@ -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
// -----------------------------------------------------------------------------


+ 201
- 32
code/espurna/sensors/BMX280Sensor.h View File

@ -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();
}
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() {
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;
};


+ 0
- 1
code/platformio.ini View File

@ -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


Loading…
Cancel
Save