firmware/src/modules/Telemetry/Sensor/BME680Sensor.cpp
Markus a71b47b5bb
Some checks are pending
CI / setup (all) (push) Waiting to run
CI / setup (check) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker (alpine, native, linux/amd64) (push) Waiting to run
CI / docker (alpine, native, linux/arm64) (push) Waiting to run
CI / docker (alpine, native-tft, linux/amd64) (push) Waiting to run
CI / docker (debian, native, linux/amd64) (push) Waiting to run
CI / docker (debian, native, linux/arm/v7) (push) Waiting to run
CI / docker (debian, native, linux/arm64) (push) Waiting to run
CI / docker (debian, native-tft, linux/amd64) (push) Waiting to run
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (rp2350) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
rework sensor instantiation to saves memory by removing the static allocation (#8054)
* rework I2C sensor init

the goal is to only instantiate sensors that are pressend to save memory.
side effacts:
 - easyer sensor integration (less C&P code)
 - nodeTelemetrySensorsMap can be removed when all devices are migrated

* add missing ifdef

* refactor a bunch of more sensors

RAM -816
Flash -916

* fix build for t1000

* refactor more sensors

RAM -192
Flash -60

* improve error handling

Flash -112

* fix build

* fix build

* fix IndicatorSensor

* fix tracker-t1000-e build

not sure what magic is used but it works

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/modules/Telemetry/Sensor/DFRobotGravitySensor.h

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 11:09:33 -05:00

149 lines
5.1 KiB
C++

#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<bsec2.h>)
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BME680Sensor.h"
#include "FSCommon.h"
#include "SPILock.h"
#include "TelemetrySensor.h"
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
int32_t BME680Sensor::runOnce()
{
if (!bme680.run()) {
checkStatus("runTrigger");
}
return 35;
}
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
status = 0;
if (!bme680.begin(dev->address.address, *bus))
checkStatus("begin");
if (bme680.status == BSEC_OK) {
status = 1;
if (!bme680.setConfig(bsec_config)) {
checkStatus("setConfig");
status = 0;
}
loadState();
if (!bme680.updateSubscription(sensorList, ARRAY_LEN(sensorList), BSEC_SAMPLE_RATE_LP)) {
checkStatus("updateSubscription");
status = 0;
}
LOG_INFO("Init sensor: %s with the BSEC Library version %d.%d.%d.%d ", sensorName, bme680.version.major,
bme680.version.minor, bme680.version.major_bugfix, bme680.version.minor_bugfix);
}
if (status == 0)
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status);
initI2CSensor();
return status;
}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
return false;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_gas_resistance = true;
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal;
measurement->variant.environment_metrics.relative_humidity =
bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal;
measurement->variant.environment_metrics.barometric_pressure = bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal;
measurement->variant.environment_metrics.gas_resistance = bme680.getData(BSEC_OUTPUT_RAW_GAS).signal / 1000.0;
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal;
updateState();
return true;
}
void BME680Sensor::loadState()
{
#ifdef FSCom
spiLock->lock();
auto file = FSCom.open(bsecConfigFileName, FILE_O_READ);
if (file) {
file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.close();
bme680.setState(bsecState);
LOG_INFO("%s state read from %s", sensorName, bsecConfigFileName);
} else {
LOG_INFO("No %s state found (File: %s)", sensorName, bsecConfigFileName);
}
spiLock->unlock();
#else
LOG_ERROR("ERROR: Filesystem not implemented");
#endif
}
void BME680Sensor::updateState()
{
#ifdef FSCom
spiLock->lock();
bool update = false;
if (stateUpdateCounter == 0) {
/* First state update when IAQ accuracy is >= 3 */
accuracy = bme680.getData(BSEC_OUTPUT_IAQ).accuracy;
if (accuracy >= 2) {
LOG_DEBUG("%s state update IAQ accuracy %u >= 2", sensorName, accuracy);
update = true;
stateUpdateCounter++;
} else {
LOG_DEBUG("%s not updated, IAQ accuracy is %u < 2", sensorName, accuracy);
}
} else {
/* Update every STATE_SAVE_PERIOD minutes */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
LOG_DEBUG("%s state update every %d minutes", sensorName, STATE_SAVE_PERIOD / 60000);
update = true;
stateUpdateCounter++;
}
}
if (update) {
bme680.getState(bsecState);
if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName)) {
LOG_WARN("Can't remove old state file");
}
auto file = FSCom.open(bsecConfigFileName, FILE_O_WRITE);
if (file) {
LOG_INFO("%s state write to %s", sensorName, bsecConfigFileName);
file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.flush();
file.close();
} else {
LOG_INFO("Can't write %s state (File: %s)", sensorName, bsecConfigFileName);
}
}
spiLock->unlock();
#else
LOG_ERROR("ERROR: Filesystem not implemented");
#endif
}
void BME680Sensor::checkStatus(const char *functionName)
{
if (bme680.status < BSEC_OK)
LOG_ERROR("%s BSEC2 code: %d", functionName, bme680.status);
else if (bme680.status > BSEC_OK)
LOG_WARN("%s BSEC2 code: %d", functionName, bme680.status);
if (bme680.sensor.status < BME68X_OK)
LOG_ERROR("%s BME68X code: %d", functionName, bme680.sensor.status);
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
}
#endif