Merge branch 'bme680_bsec' into 'master'
Bme680 bsec See merge request Mathieu/Domotique!2
This commit is contained in:
commit
1cd02f0fbc
@ -7,6 +7,7 @@ before_script:
|
||||
- arduino --install-library "Adafruit BME680 Library" || true
|
||||
- arduino --install-library "Adafruit Unified Sensor" || true
|
||||
- arduino --install-library "DHT sensor library" || true
|
||||
- arduino --install-library "BSEC Software Library" || true
|
||||
- arduino --board esp8266:esp8266:generic --save-prefs
|
||||
- arduino --pref "compiler.warning_level=all" --save-prefs
|
||||
|
||||
|
@ -44,3 +44,4 @@ Quick cmdline to install deps:
|
||||
arduino --install-library "Adafruit BME680 Library"
|
||||
arduino --install-library "Adafruit Unified Sensor"
|
||||
arduino --install-library "DHT sensor library"
|
||||
arduino --install-library "BSEC Software Library" # Then you have to follow the instruction in the README.md in the BSEC install folder
|
||||
|
@ -21,7 +21,7 @@ int BME680GetMeasure(float &t, float &p, float &h, float &g, float &a);
|
||||
int BME680Setup();
|
||||
bool BME680IsConnected();
|
||||
|
||||
#else //CONFIG_ENABLE_BMP80
|
||||
#else //CONFIG_ENABLE_BME680
|
||||
int BME680GetMeasure(float &, float &, float&, float &, float &){return -1;};
|
||||
int BME680Setup(){SKETCH_DEBUG_PRINTLN("BME680 is disabled at build time"); return -1;};
|
||||
bool BME680IsConnected(){return false;};
|
||||
|
16
WifiControlSensor/BME680_BSEC.h
Normal file
16
WifiControlSensor/BME680_BSEC.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#ifdef CONFIG_BME680_BSEC_ENABLE
|
||||
int BME680BSECGetMeasure(float &t, float &p, float &h, float &iaq, float &iaqAcc);
|
||||
int BME680BSECSetup();
|
||||
bool BME680BSECIsConnected();
|
||||
#else // CONFIG_ENABLE_BME680_BSEC
|
||||
#define BSEC_MAX_STATE_BLOB_SIZE 0
|
||||
int BME680BSECGetMeasure(float &, float &, float &, float &, float &) {
|
||||
return -1;
|
||||
};
|
||||
int BME680BSECSetup() {
|
||||
SKETCH_DEBUG_PRINTLN("BME680 BSEC is disabled at build time");
|
||||
return -1;
|
||||
};
|
||||
bool BME680BSECIsConnected() { return false; };
|
||||
#endif
|
153
WifiControlSensor/BME680_BSEC.ino
Normal file
153
WifiControlSensor/BME680_BSEC.ino
Normal file
@ -0,0 +1,153 @@
|
||||
#ifdef CONFIG_BME680_BSEC_ENABLE
|
||||
#include "BME680_BSEC.h"
|
||||
|
||||
#include "bsec.h"
|
||||
/* Configure the BSEC library with information about the sensor
|
||||
18v/33v = Voltage at Vdd. 1.8V or 3.3V
|
||||
3s/300s = BSEC operating mode, BSEC_SAMPLE_RATE_LP or BSEC_SAMPLE_RATE_ULP
|
||||
4d/28d = Operating age of the sensor in days
|
||||
generic_18v_3s_4d
|
||||
generic_18v_3s_28d
|
||||
generic_18v_300s_4d
|
||||
generic_18v_300s_28d
|
||||
generic_33v_3s_4d
|
||||
generic_33v_3s_28d
|
||||
generic_33v_300s_4d
|
||||
generic_33v_300s_28d
|
||||
*/
|
||||
const uint8_t bsec_config_iaq[] = {
|
||||
#if CONFIG_SAMPLING_PERIODE_MS == 3000
|
||||
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
|
||||
#elif CONFIG_SAMPLING_PERIODE_MS == 300000
|
||||
#include "config/generic_33v_300s_4d/bsec_iaq.txt"
|
||||
#else
|
||||
#error "Unsupport CONFIG_SAMPLING_PERIODE_MS (3000 and 300000 are supported)"
|
||||
#endif
|
||||
};
|
||||
|
||||
#define STATE_SAVE_PERIOD \
|
||||
UINT32_C(360 * 60 * 1000) // 360 minutes - 4 times a day
|
||||
uint16_t stateUpdateCounter = 0;
|
||||
Bsec iaqSensor;
|
||||
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
|
||||
|
||||
// Helper function definitions
|
||||
int checkIaqSensorStatus(void) {
|
||||
if (iaqSensor.status != BSEC_OK) {
|
||||
if (iaqSensor.status < BSEC_OK) {
|
||||
SKETCH_DEBUG_PRINTLN("BSEC error code : " + String(iaqSensor.status));
|
||||
|
||||
return -2;
|
||||
} else {
|
||||
SKETCH_DEBUG_PRINTLN("BSEC warning code : " + String(iaqSensor.status));
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (iaqSensor.bme680Status != BME680_OK) {
|
||||
if (iaqSensor.bme680Status < BME680_OK) {
|
||||
SKETCH_DEBUG_PRINTLN("BME680 error code : " + String(iaqSensor.bme680Status));
|
||||
|
||||
return -2;
|
||||
} else {
|
||||
SKETCH_DEBUG_PRINTLN("BME680 warning code : " + String(iaqSensor.bme680Status));
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
iaqSensor.status = BSEC_OK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void updateState(void)
|
||||
{
|
||||
bool update = false;
|
||||
/* Set a trigger to save the state. Here, the state is saved every STATE_SAVE_PERIOD with the
|
||||
* first state being saved once the algorithm achieves full calibration, i.e. iaqAccuracy = 3
|
||||
*/
|
||||
if (stateUpdateCounter == 0) {
|
||||
if (iaqSensor.iaqAccuracy >= 3) {
|
||||
update = true;
|
||||
stateUpdateCounter++;
|
||||
}
|
||||
} else {
|
||||
/* Update every STATE_SAVE_PERIOD milliseconds */
|
||||
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
|
||||
update = true;
|
||||
stateUpdateCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (update) {
|
||||
iaqSensor.getState(bsecState);
|
||||
checkIaqSensorStatus();
|
||||
|
||||
SKETCH_DEBUG_PRINTLN("Writing state to EEPROM");
|
||||
|
||||
EepromSaveBME680State(bsecState);
|
||||
}
|
||||
}
|
||||
|
||||
int BME680BSECGetMeasure(float &t, float &p, float &h, float &iaq, float &iaqAcc)
|
||||
{
|
||||
if (iaqSensor.run()) { // If new data is available
|
||||
t = iaqSensor.temperature;
|
||||
p = iaqSensor.pressure;
|
||||
h = iaqSensor.humidity;
|
||||
iaq = iaqSensor.iaq;
|
||||
iaqAcc = iaqSensor.iaqAccuracy;
|
||||
updateState();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BME680BSECSetup()
|
||||
{
|
||||
Wire.begin();
|
||||
iaqSensor.begin(CONFIG_BME680_BSEC_I2C_ADDR, Wire);
|
||||
|
||||
SKETCH_DEBUG_PRINTLN("\nBSEC library version " + String(iaqSensor.version.major) + "." +
|
||||
String(iaqSensor.version.minor) + "." + String(iaqSensor.version.major_bugfix) +
|
||||
"." + String(iaqSensor.version.minor_bugfix));
|
||||
|
||||
if (checkIaqSensorStatus())
|
||||
return -1;
|
||||
|
||||
iaqSensor.setConfig(bsec_config_iaq);
|
||||
|
||||
if (checkIaqSensorStatus())
|
||||
return -1;
|
||||
|
||||
if (!EepromLoadBME680State(bsecState))
|
||||
iaqSensor.setState(bsecState);
|
||||
|
||||
if (checkIaqSensorStatus())
|
||||
return -1;
|
||||
|
||||
bsec_virtual_sensor_t sensorList[7] = {
|
||||
BSEC_OUTPUT_RAW_TEMPERATURE,
|
||||
BSEC_OUTPUT_RAW_PRESSURE,
|
||||
BSEC_OUTPUT_RAW_HUMIDITY,
|
||||
BSEC_OUTPUT_RAW_GAS,
|
||||
BSEC_OUTPUT_IAQ,
|
||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
|
||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
||||
};
|
||||
|
||||
iaqSensor.updateSubscription(sensorList, 7, BSEC_SAMPLE_RATE_LP);
|
||||
if (checkIaqSensorStatus())
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool BME680BSECIsConnected()
|
||||
{
|
||||
if (checkIaqSensorStatus())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
@ -23,3 +23,5 @@ typedef struct productConfig_t {
|
||||
int EepromSaveConfig(productConfig &config);
|
||||
int EepromSaveBootMode(uint8_t bootMode);
|
||||
void EepromReadConfig(productConfig &config);
|
||||
int EepromSaveBME680State(uint8_t *bsecState);
|
||||
int EepromLoadBME680State(uint8_t *bsecState);
|
||||
|
@ -6,6 +6,12 @@
|
||||
*/
|
||||
#include "EEPROM.h"
|
||||
|
||||
#define BME680_BSEC_EEPROM_ORIG (CONFIG_EEPROM_SIZE)
|
||||
|
||||
#if (CONFIG_EEPROM_SIZE + BSEC_MAX_STATE_BLOB_SIZE) >= SPI_FLASH_SEC_SIZE
|
||||
#error "CONFIG_EEPROM_SIZE too big"
|
||||
#endif
|
||||
|
||||
char eeprom[CONFIG_EEPROM_SIZE];
|
||||
|
||||
int EepromSaveConfig(productConfig &config) {
|
||||
@ -54,7 +60,6 @@ void readConfElement(char** element, int &i) {
|
||||
SKETCH_DEBUG_PRINTLN("Looks like there is a configuration issue (too long)");
|
||||
**element = '\0';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EepromReadConfig(productConfig &config) {
|
||||
@ -101,3 +106,42 @@ void EepromReadConfig(productConfig &config) {
|
||||
readConfElement(&config.bssid, i);
|
||||
|
||||
}
|
||||
|
||||
int EepromSaveBME680State(uint8_t *bsecState)
|
||||
{
|
||||
for (uint16_t i = BME680_BSEC_EEPROM_ORIG;
|
||||
i < BME680_BSEC_EEPROM_ORIG + BSEC_MAX_STATE_BLOB_SIZE; i++) {
|
||||
EEPROM.write(i + 1, bsecState[i]);
|
||||
}
|
||||
|
||||
EEPROM.write(BME680_BSEC_EEPROM_ORIG, BSEC_MAX_STATE_BLOB_SIZE);
|
||||
EEPROM.commit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EepromLoadBME680State(uint8_t *bsecState)
|
||||
{
|
||||
if (EEPROM.read(BME680_BSEC_EEPROM_ORIG) == BSEC_MAX_STATE_BLOB_SIZE) {
|
||||
// Existing state in EEPROM
|
||||
SKETCH_DEBUG_PRINTLN("Reading BME680 state from EEPROM");
|
||||
|
||||
for (uint16_t i = BME680_BSEC_EEPROM_ORIG;
|
||||
i < BME680_BSEC_EEPROM_ORIG + BSEC_MAX_STATE_BLOB_SIZE; i++) {
|
||||
bsecState[i] = EEPROM.read(i + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
// Erase the EEPROM with zeroes
|
||||
SKETCH_DEBUG_PRINTLN("Erasing EEPROM for BME680 state");
|
||||
|
||||
for (uint16_t i = BME680_BSEC_EEPROM_ORIG;
|
||||
i < BME680_BSEC_EEPROM_ORIG + BSEC_MAX_STATE_BLOB_SIZE + 1; i++)
|
||||
EEPROM.write(i, 0);
|
||||
|
||||
EEPROM.commit();
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
#define BME680_HUMIDITY_FEED_FORMAT "/feeds/%s/%s/bme680/humidity"
|
||||
#define BME680_GAZ_FEED_FORMAT "/feeds/%s/%s/bme680/gaz"
|
||||
#define BME680_ALT_FEED_FORMAT "/feeds/%s/%s/bme680/alt"
|
||||
#define BME680_IAQ_FEED_FORMAT "/feeds/%s/%s/bme680/iaq"
|
||||
#define BME680_IAQ_ACC_FEED_FORMAT "/feeds/%s/%s/bme680/iaqAcc"
|
||||
#ifndef CONFIG_DISABLE_MQTT
|
||||
#include "Adafruit_MQTT.h"
|
||||
|
||||
|
@ -40,6 +40,9 @@ void WebHandleRoot() {
|
||||
#ifdef CONFIG_ENABLE_BME680
|
||||
"" + (BME680IsConnected() ? "<h6>BME680</h6>Temperature " + String(bme680T, 2) + "C<br/> Pressure " + String(bme680P, 2) + "hPa<br/> Humidity " + String(bme680H, 2) + "%<br/> Gaz " + String(bme680G, 2) + "kOhm<br/>" : "BME680 Disconnected" ) + ""
|
||||
#endif
|
||||
#ifdef CONFIG_BME680_BSEC_ENABLE
|
||||
"" + (BME680BSECIsConnected() ? "<h6>BME680 BSEC</h6>Temperature " + String(bme680BSECT, 2) + "C<br/> Pressure " + String(bme680BSECP, 2) + "hPa<br/> Humidity " + String(bme680BSECH, 2) + "%<br/> Indoor Air Quality " + String(bme680BSECIaq, 2) + "/500<br/> IAQ Accuraccy" + String(bme680BSECIaqAcc) + "/3<br/>": "BME680 Disconnected" ) + ""
|
||||
#endif
|
||||
#ifdef CONFIG_ENABLE_DRY_SENSOR
|
||||
"Dryness " + String((dryness * 100) / 1024) + "%<br/>"
|
||||
#endif
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "debug_sketch.h"
|
||||
#include "BMP180.h"
|
||||
#include "BME680.h"
|
||||
#include "BME680_BSEC.h"
|
||||
#include "sensor_DHT.h"
|
||||
#include "dry_sensor.h"
|
||||
#include "MQTT.h"
|
||||
@ -63,6 +64,7 @@ extern "C" {
|
||||
double temp, pressure;
|
||||
float dhtTemp, dhtHumidity;
|
||||
float bme680T, bme680P, bme680H, bme680G, bme680A;
|
||||
float bme680BSECT, bme680BSECP, bme680BSECH, bme680BSECIaq, bme680BSECIaqAcc;
|
||||
int dryness;
|
||||
uint8_t mode;
|
||||
int reconfig = 0;
|
||||
@ -142,7 +144,7 @@ void WifiSetup(productConfig conf) {
|
||||
reconfig = 0;
|
||||
return;
|
||||
}
|
||||
if (connectionTry == 20) {
|
||||
if (connectionTry == 60) {
|
||||
SKETCH_DEBUG_PRINTLN("Cannot connect to wifi. Try without BSSID and channel");
|
||||
WiFi.begin(conf.ssid, conf.password);
|
||||
}
|
||||
@ -278,6 +280,9 @@ void setup() {
|
||||
if(!BME680Setup()){
|
||||
SKETCH_DEBUG_PRINTLN("BME680 init success");
|
||||
}
|
||||
if(!BME680BSECSetup()){
|
||||
SKETCH_DEBUG_PRINTLN("BME680 with BSEC init success");
|
||||
}
|
||||
WebSetupServer(mode);
|
||||
}
|
||||
#ifdef CONFIG_ENABLE_POWER_SAVE
|
||||
@ -312,7 +317,7 @@ void loop() {
|
||||
}
|
||||
if (!DryGetMeasure(dryness)) {
|
||||
SKETCH_DEBUG_PRINTF("Current dryness %d %%\n", (dryness * 100) / 1024);
|
||||
batchInfo.push_back({dryness, DRY_FEED_FORMAT, 0, 0});
|
||||
batchInfo.push_back({(float)dryness, DRY_FEED_FORMAT, 0, 0});
|
||||
}
|
||||
if (!BME680GetMeasure(bme680T, bme680P, bme680H, bme680G, bme680A)) {
|
||||
SKETCH_DEBUG_PRINT("Current T°C: ");
|
||||
@ -332,6 +337,25 @@ void loop() {
|
||||
batchInfo.push_back({bme680A, BME680_ALT_FEED_FORMAT, 0, 0});
|
||||
}
|
||||
|
||||
if (!BME680BSECGetMeasure(bme680BSECT, bme680BSECP, bme680BSECH, bme680BSECIaq,
|
||||
bme680BSECIaqAcc)) {
|
||||
SKETCH_DEBUG_PRINT("Current T°C: ");
|
||||
SKETCH_DEBUG_PRINT(bme680BSECT);
|
||||
SKETCH_DEBUG_PRINT(" Pressure hPa: ");
|
||||
SKETCH_DEBUG_PRINT(bme680BSECP);
|
||||
SKETCH_DEBUG_PRINT(" Humidity %: ");
|
||||
SKETCH_DEBUG_PRINT(bme680BSECH);
|
||||
SKETCH_DEBUG_PRINT(" Indoor Air Quality: ");
|
||||
SKETCH_DEBUG_PRINT(bme680BSECIaq);
|
||||
SKETCH_DEBUG_PRINT(" IAQ Accuracy: ");
|
||||
SKETCH_DEBUG_PRINTLN(bme680BSECIaqAcc);
|
||||
batchInfo.push_back({bme680BSECT, BME680_TEMPERATURE_FEED_FORMAT, 0, 0});
|
||||
batchInfo.push_back({bme680BSECP, BME680_PRESSURE_FEED_FORMAT, 0, 0});
|
||||
batchInfo.push_back({bme680BSECH, BME680_HUMIDITY_FEED_FORMAT, 0, 0});
|
||||
batchInfo.push_back({bme680BSECIaq, BME680_IAQ_FEED_FORMAT, 0, 0});
|
||||
batchInfo.push_back({bme680BSECIaqAcc, BME680_IAQ_ACC_FEED_FORMAT, 0, 0});
|
||||
}
|
||||
|
||||
if (mode == BOOTMODE_NORMAL)
|
||||
MqttBatchPublish(batchInfo, conf.mqttUser, conf.host);
|
||||
nbCycle = 0;
|
||||
|
@ -13,6 +13,14 @@
|
||||
#define CONFIG_SAMPLING_PERIODE_MS 60000
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ENABLE_BME680) && defined(CONFIG_BME680_BSEC_ENABLE)
|
||||
#error "BME680 and BME680 BSEC cannot be enabled together"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BME680_BSEC_I2C_ADDR
|
||||
#define CONFIG_BME680_BSEC_I2C_ADDR 0x76
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ENABLE_BMP180) && !defined(CONFIG_BMP180_SDA)
|
||||
#error "When enabling BMP180, you should configure SDA pin"
|
||||
#elif !defined(CONFIG_ENABLE_BMP180)
|
||||
|
@ -14,16 +14,22 @@
|
||||
|
||||
// Enable the temperature, pressure, humidity and gaz Sensor BME680 on standard i2c esp8266 pins
|
||||
// It use default i2c pin GPIO4(D2): SDA, GPIO5(D1):SCL
|
||||
#define CONFIG_ENABLE_BME680
|
||||
// Should be powered by 3.3v and sampled every 3sec or 300s (Or you should adapt bsec_config_iaq in BME680_BSEC.ino )
|
||||
#define CONFIG_BME680_BSEC_ENABLE
|
||||
#define CONFIG_BME680_BSEC_I2C_ADDR 0x77
|
||||
|
||||
// Enable the temperature, pressure, humidity and gaz Sensor BME680 on standard i2c esp8266 pins
|
||||
// It use default i2c pin GPIO4(D2): SDA, GPIO5(D1):SCL
|
||||
//#define CONFIG_ENABLE_BME680
|
||||
// Enable the temperatue and pressure Sensor BMP180
|
||||
// (CONFIG_BMP180_SDA and CONFIG_BMP180_SDA should be defined as well)
|
||||
#define CONFIG_ENABLE_BMP180
|
||||
#define CONFIG_BMP180_SDA SDA //D2
|
||||
#define CONFIG_BMP180_SCL SCL //D1
|
||||
|
||||
#define CONFIG_ENABLE_DHT
|
||||
#define CONFIG_DHT_PIN 2
|
||||
#define CONFIG_DHT_TYPE DHT22
|
||||
//#define CONFIG_ENABLE_BMP180
|
||||
//#define CONFIG_BMP180_SDA SDA //D2
|
||||
//#define CONFIG_BMP180_SCL SCL //D1
|
||||
//
|
||||
//#define CONFIG_ENABLE_DHT
|
||||
//#define CONFIG_DHT_PIN 2
|
||||
//#define CONFIG_DHT_TYPE DHT22
|
||||
|
||||
//#define CONFIG_ENABLE_DRY_SENSOR
|
||||
//If the dry sensor is powered by a GPIO, this GPIO could be defined here
|
||||
@ -47,7 +53,7 @@
|
||||
//#define CONFIG_WEB_DELAY_MS 100
|
||||
|
||||
// Get sensors value every X ms
|
||||
#define CONFIG_SAMPLING_PERIODE_MS 300000
|
||||
#define CONFIG_SAMPLING_PERIODE_MS 3000
|
||||
|
||||
// Name of the SSID when in AP mode for configuration
|
||||
#define CONFIG_SSID_NAME "ESPConfiguratorBureau"
|
||||
|
Loading…
Reference in New Issue
Block a user