mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-06-03 01:54:42 +00:00
Merge pull request #2634 from NickDunklee/bme680-fixes-consolidation
feat: Integrate BME680 Bosch BSEC support for RAK4631
This commit is contained in:
@@ -12,6 +12,31 @@
|
||||
// Sensor library includes and static driver instances
|
||||
// ============================================================
|
||||
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
#ifndef TELEM_BME680_ADDRESS
|
||||
#define TELEM_BME680_ADDRESS 0x76
|
||||
#endif
|
||||
#define TELEM_BME680_SEALEVELPRESSURE_HPA (1013.25)
|
||||
#include <bsec.h>
|
||||
#include <Adafruit_LittleFS.h>
|
||||
#include <InternalFileSystem.h>
|
||||
static const uint8_t bsec_config_iaq[] = {
|
||||
#include "config/generic_33v_3s_28d/bsec_iaq.txt" // 3.3v, LP, 28 day background calibration window
|
||||
};
|
||||
static Bsec bsec_iaq;
|
||||
static float bsec_temperature = 0;
|
||||
static float bsec_humidity = 0;
|
||||
static float bsec_pressure_hpa = 0;
|
||||
static float bsec_iaq_val = 0;
|
||||
static uint8_t bsec_accuracy = 0;
|
||||
static bool bsec_active = false;
|
||||
static bool bsec_data_ready = false;
|
||||
static bool bsec_first_save_done = false;
|
||||
static uint32_t bsec_last_save_ms = 0;
|
||||
#define BSEC_STATE_FILE "/bsec_state.bin"
|
||||
#define BSEC_SAVE_INTERVAL_MS (8UL * 60 * 60 * 1000) // 8 hour state-save interval
|
||||
#endif
|
||||
|
||||
#ifdef ENV_INCLUDE_BME680
|
||||
#ifndef TELEM_BME680_ADDRESS
|
||||
#define TELEM_BME680_ADDRESS 0x76
|
||||
@@ -235,9 +260,10 @@ static void query_bme680(uint8_t ch, uint8_t, CayenneLPP& lpp) {
|
||||
if (BME680.performReading()) {
|
||||
lpp.addTemperature(ch, BME680.temperature);
|
||||
lpp.addRelativeHumidity(ch, BME680.humidity);
|
||||
lpp.addBarometricPressure(ch, BME680.pressure / 100);
|
||||
lpp.addAltitude(ch, 44330.0 * (1.0 - pow((BME680.pressure / 100) / TELEM_BME680_SEALEVELPRESSURE_HPA, 0.1903)));
|
||||
lpp.addAnalogInput(ch, BME680.gas_resistance);
|
||||
const float pressure_hpa = BME680.pressure / 100.0f;
|
||||
lpp.addBarometricPressure(ch, pressure_hpa);
|
||||
lpp.addAltitude(ch, 44330.0f * (1.0f - powf(pressure_hpa / (float)TELEM_BME680_SEALEVELPRESSURE_HPA, 0.1903f)));
|
||||
lpp.addGenericSensor(ch, BME680.gas_resistance);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -449,6 +475,62 @@ static void query_rak12035(uint8_t ch, uint8_t sub_ch, CayenneLPP& lpp) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
static void bsec_load_state() {
|
||||
using namespace Adafruit_LittleFS_Namespace;
|
||||
File f = InternalFS.open(BSEC_STATE_FILE, FILE_O_READ);
|
||||
if (!f) return;
|
||||
uint8_t state[BSEC_MAX_STATE_BLOB_SIZE];
|
||||
f.read(state, BSEC_MAX_STATE_BLOB_SIZE);
|
||||
f.close();
|
||||
bsec_iaq.setState(state);
|
||||
}
|
||||
|
||||
static void bsec_save_state() {
|
||||
using namespace Adafruit_LittleFS_Namespace;
|
||||
uint8_t state[BSEC_MAX_STATE_BLOB_SIZE];
|
||||
bsec_iaq.getState(state);
|
||||
InternalFS.remove(BSEC_STATE_FILE);
|
||||
File f = InternalFS.open(BSEC_STATE_FILE, FILE_O_WRITE);
|
||||
if (!f) return;
|
||||
f.write(state, BSEC_MAX_STATE_BLOB_SIZE);
|
||||
f.close();
|
||||
}
|
||||
|
||||
static uint8_t init_bme680_bsec(TwoWire* wire, uint8_t addr) {
|
||||
bsec_iaq.begin(addr, *wire);
|
||||
if (bsec_iaq.bsecStatus != BSEC_OK) return 0;
|
||||
|
||||
bsec_iaq.setConfig(bsec_config_iaq);
|
||||
if (bsec_iaq.bsecStatus != BSEC_OK) return 0;
|
||||
|
||||
bsec_virtual_sensor_t outputs[] = {
|
||||
BSEC_OUTPUT_IAQ,
|
||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
|
||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
||||
BSEC_OUTPUT_RAW_PRESSURE,
|
||||
BSEC_OUTPUT_STABILIZATION_STATUS,
|
||||
BSEC_OUTPUT_RUN_IN_STATUS,
|
||||
};
|
||||
bsec_iaq.updateSubscription(outputs, 6, BSEC_SAMPLE_RATE_LP);
|
||||
if (bsec_iaq.bsecStatus != BSEC_OK) return 0;
|
||||
|
||||
bsec_load_state();
|
||||
bsec_active = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void query_bme680_bsec(uint8_t ch, uint8_t, CayenneLPP& lpp) {
|
||||
if (!bsec_data_ready) return;
|
||||
lpp.addTemperature(ch, bsec_temperature);
|
||||
lpp.addRelativeHumidity(ch, bsec_humidity);
|
||||
lpp.addBarometricPressure(ch, bsec_pressure_hpa);
|
||||
lpp.addAltitude(ch, 44330.0f * (1.0f - powf(bsec_pressure_hpa / (float)TELEM_BME680_SEALEVELPRESSURE_HPA, 0.1903f)));
|
||||
lpp.addGenericSensor(ch, (uint16_t)bsec_iaq_val);
|
||||
lpp.addAnalogInput(ch, (float)bsec_accuracy);
|
||||
}
|
||||
#endif
|
||||
|
||||
// ============================================================
|
||||
// Sensor descriptor table
|
||||
//
|
||||
@@ -476,6 +558,9 @@ static const SensorDef SENSOR_TABLE[] = {
|
||||
#ifdef ENV_INCLUDE_BME680
|
||||
{ TELEM_BME680_ADDRESS, "BME680", init_bme680, query_bme680 },
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
{ TELEM_BME680_ADDRESS, "BME680+BSEC", init_bme680_bsec, query_bme680_bsec },
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME280
|
||||
{ TELEM_BME280_ADDRESS, "BME280", init_bme280, query_bme280 },
|
||||
#endif
|
||||
@@ -798,11 +883,13 @@ void EnvironmentSensorManager::stop_gps() {
|
||||
MESH_DEBUG_PRINTLN("Stop GPS is N/A on this board. Actual GPS state unchanged");
|
||||
#endif
|
||||
}
|
||||
#endif // ENV_INCLUDE_GPS
|
||||
|
||||
#if ENV_INCLUDE_GPS || defined(ENV_INCLUDE_BME680_BSEC)
|
||||
void EnvironmentSensorManager::loop() {
|
||||
static long next_gps_update = 0;
|
||||
|
||||
#if ENV_INCLUDE_GPS
|
||||
static long next_gps_update = 0;
|
||||
if (gps_active) {
|
||||
_location->loop();
|
||||
}
|
||||
@@ -830,5 +917,27 @@ void EnvironmentSensorManager::loop() {
|
||||
next_gps_update = millis() + (gps_update_interval_sec * 1000);
|
||||
}
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
if (bsec_active && bsec_iaq.run()) {
|
||||
uint8_t prev_accuracy = bsec_accuracy;
|
||||
bsec_temperature = bsec_iaq.temperature;
|
||||
bsec_humidity = bsec_iaq.humidity;
|
||||
bsec_pressure_hpa = bsec_iaq.pressure / 100.0f;
|
||||
bsec_iaq_val = bsec_iaq.iaq;
|
||||
bsec_accuracy = bsec_iaq.iaqAccuracy;
|
||||
bsec_data_ready = true;
|
||||
|
||||
if (bsec_accuracy == 3) {
|
||||
if (!bsec_first_save_done) {
|
||||
bsec_save_state();
|
||||
bsec_last_save_ms = millis();
|
||||
bsec_first_save_done = true;
|
||||
} else if ((millis() - bsec_last_save_ms) >= BSEC_SAVE_INTERVAL_MS) {
|
||||
bsec_save_state();
|
||||
bsec_last_save_ms = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ENV_INCLUDE_BME680_BSEC
|
||||
}
|
||||
#endif
|
||||
#endif // ENV_INCLUDE_GPS || ENV_INCLUDE_BME680_BSEC
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
#endif
|
||||
bool begin() override;
|
||||
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
|
||||
#if ENV_INCLUDE_GPS
|
||||
#if ENV_INCLUDE_GPS || defined(ENV_INCLUDE_BME680_BSEC)
|
||||
void loop() override;
|
||||
#endif
|
||||
int getNumSettings() const override;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
Import('env')
|
||||
import os
|
||||
|
||||
# Bosch has a goof in their PlatformIO packaging making linking fail.
|
||||
# The BSEC library's extra_script.py selects cortex-m4/libalgobsec.a (soft-float ABI).
|
||||
# nRF52840 compiles with -mfloat-abi=hard, requiring the fpv4-sp-d16-hard blob.
|
||||
# Workaround to prepend the hard-float path so the linker finds it before the
|
||||
# soft-float one.
|
||||
bsec_hard = os.path.join(
|
||||
env.subst('$PROJECT_DIR'),
|
||||
'.pio', 'libdeps', env.subst('$PIOENV'),
|
||||
'BSEC Software Library', 'src',
|
||||
'cortex-m4', 'fpv4-sp-d16-hard'
|
||||
)
|
||||
env.Prepend(LIBPATH=[bsec_hard])
|
||||
@@ -2,6 +2,8 @@
|
||||
extends = nrf52_base
|
||||
board = rak4631
|
||||
board_check = true
|
||||
extra_scripts = ${nrf52_base.extra_scripts}
|
||||
post:variants/rak4631/fix_bsec_lib.py
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
${sensor_base.build_flags}
|
||||
-I variants/rak4631
|
||||
@@ -21,6 +23,8 @@ build_flags = ${nrf52_base.build_flags}
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
-D ENV_INCLUDE_RAK12035=1
|
||||
-UENV_INCLUDE_BME680
|
||||
-D ENV_INCLUDE_BME680_BSEC=1
|
||||
build_src_filter = ${nrf52_base.build_src_filter}
|
||||
+<../variants/rak4631>
|
||||
+<helpers/sensors>
|
||||
@@ -31,6 +35,7 @@ lib_deps =
|
||||
${sensor_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.27
|
||||
boschsensortec/BSEC Software Library @ ^1.8.1492
|
||||
|
||||
[env:RAK_4631_repeater]
|
||||
extends = rak4631
|
||||
|
||||
Reference in New Issue
Block a user