77 lines
2.3 KiB
C++
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
|