Helligkeit/src/patrix/bme680.h
2025-02-16 20:25:36 +01:00

77 lines
2.3 KiB
C++

#ifndef BME680_H
#define BME680_H
#include "Adafruit_BME680.h"
#include "mqtt.h"
class BME680 {
Adafruit_BME680 bme; // NOLINT(*-interfaces-global-init)
unsigned long last = 0UL;
public:
const String name;
unsigned long intervalMs;
explicit BME680(String name, const unsigned long interval_ms = 5000) : name(std::move(name)), intervalMs(interval_ms) {
//
}
void setup() {
if (bme.begin()) {
Log.printf("BME680 \"%s\": Initialized.\n", name.c_str());
} else {
Log.printf("BME680 \"%s\": Failed to initialize.\n", name.c_str());
}
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150);
}
void loop() {
const auto now = max(1UL, millis());
if (last == 0 || now - last >= intervalMs) {
if (bme.beginReading() == 0) {
Log.printf("BME680 \"%s\": Failed to request reading.\n", name.c_str());
setup();
}
last = now;
}
if (bme.remainingReadingMillis() == 0) {
if (bme.endReading()) {
const auto humidityAbsolute = calculateHumidityAbsolute(bme.temperature, bme.humidity);
mqttPublishValue(name + "/temperature", bme.temperature, "TEMPERATURE_C");
mqttPublishValue(name + "/pressure", bme.pressure / 100.0, "PRESSURE_HPA");
mqttPublishValue(name + "/humidity/relative", bme.humidity, "HUMIDITY_RELATIVE_PERCENT");
mqttPublishValue(name + "/humidity/absolute", humidityAbsolute, "HUMIDITY_ABSOLUTE_MGL");
mqttPublishValue(name + "/gas", bme.gas_resistance, "RESISTANCE_OHMS");
mqttPublishValue(name + "/altitude", bme.readAltitude(1013.25), "ALTITUDE_M");
} else {
Log.printf("BME680 \"%s\": Failed to complete reading\n", name.c_str());
setup();
}
}
}
static double calculateHumidityAbsolute(const double temperature, const double humidityRelative) {
constexpr auto A = 6.112;
constexpr auto m = 17.67;
constexpr auto Tn = 243.5;
constexpr auto Mw = 18.01534;
constexpr auto R = 8.314462618;
const auto Tk = temperature + 273.15;
const auto P_sat = A * exp((m * temperature) / (temperature + Tn));
const auto P_act = P_sat * (humidityRelative / 100.0);
return (P_act * Mw) / (R * Tk);
}
};
#endif