diff --git a/platformio.ini b/platformio.ini index f99a3e4..2ce78cc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,6 +10,8 @@ lib_deps = SPI https://github.com/adafruit/Adafruit_TSL2561 https://github.com/knolleary/pubsubclient https://github.com/adafruit/Adafruit_BME680 + https://github.com/adafruit/Adafruit_BMP280 + https://github.com/adafruit/Adafruit_AHTX0 https://github.com/phassel/ArduPID/ https://github.com/me-no-dev/ESPAsyncWebServer https://github.com/wayoda/LedControl diff --git a/src/Greenhouse.cpp b/src/Greenhouse.cpp index 370856c..95f7bdd 100644 --- a/src/Greenhouse.cpp +++ b/src/Greenhouse.cpp @@ -1,19 +1,20 @@ #ifdef NODE_GREENHOUSE #include "patrix/tsl2561.h" -#include "patrix/DHT22.h" +#include "patrix/bmp280_aht20.h" -TSL2561 greenhouseTSL("greenhouse"); +TSL2561 greenhouse_TSL2561("greenhouse"); -DHT22Sensor greenhouseDHT22("greenhouse", D5); +BMP280_AHT20 greenhouse_BMP280_AHT20("greenhouse"); void patrixSetup() { - greenhouseTSL.setup(); + greenhouse_TSL2561.setup(); + greenhouse_BMP280_AHT20.setup(); } void patrixLoop() { - greenhouseTSL.loop(); - greenhouseDHT22.loop(); + greenhouse_TSL2561.loop(); + greenhouse_BMP280_AHT20.loop(); } -#endif \ No newline at end of file +#endif diff --git a/src/patrix/bmp280_aht20.h b/src/patrix/bmp280_aht20.h new file mode 100644 index 0000000..c208fd4 --- /dev/null +++ b/src/patrix/bmp280_aht20.h @@ -0,0 +1,105 @@ +#ifndef BMP280_H +#define BMP280_H + +#include "Adafruit_BMP280.h" +#include "Adafruit_AHTX0.h" +#include "mqtt.h" + +class BMP280_AHT20 { + + Adafruit_BMP280 sensor; + + Adafruit_AHTX0 aht20; + + unsigned long last = 0UL; + +public: + + const String name; + + unsigned long intervalMs; + + explicit BMP280_AHT20(String name, const unsigned long interval_ms = 5000) : name(std::move(name)), intervalMs(interval_ms) { + // + } + + void setup() { + bmp280Setup(); + aht20Setup(); + } + + void bmp280Setup() { + if (sensor.begin()) { + Log.info("BMP280 \"%s\": Initialized.", name.c_str()); + sensor.setSampling( + Adafruit_BMP280::MODE_NORMAL, + Adafruit_BMP280::SAMPLING_X16, + Adafruit_BMP280::SAMPLING_X16, + Adafruit_BMP280::FILTER_X16, + Adafruit_BMP280::STANDBY_MS_500 + ); + } else { + Log.error("BMP280 \"%s\": Failed to initialize.", name.c_str()); + } + } + + void aht20Setup() { + if (aht20.begin()) { + Log.info("AHT20 \"%s\": Initialized.", name.c_str()); + } else { + Log.error("AHT20 \"%s\": Failed to initialize.", name.c_str()); + } + } + + void loop() { + const auto now = max(1UL, millis()); + if (last != 0 && now - last < intervalMs) { + return; + } + + last = now; + bmp280Read(); + aht20Read(); + } + + void bmp280Read() { + const auto pressure = sensor.readPressure(); + if (isnan(pressure)) { + Log.error("BMP280 \"%s\": Failed to read", name.c_str()); + bmp280Setup(); + return; + } + + mqttPublishValue(name + "/pressure", pressure / 100.0, "PRESSURE_HPA"); + } + + void aht20Read() { + sensors_event_t temperature{}; + sensors_event_t relative{}; + if (!aht20.getEvent(&relative, &temperature)) { + Log.error("AHT20 \"%s\": Failed to read", name.c_str()); + aht20Setup(); + return; + } + + const auto absolute = calculateHumidityAbsolute(temperature.temperature, relative.relative_humidity); + mqttPublishValue(name + "/temperature", temperature.temperature, "TEMPERATURE_C"); + mqttPublishValue(name + "/relative", relative.relative_humidity, "HUMIDITY_RELATIVE_PERCENT"); + mqttPublishValue(name + "/absolute", absolute, "HUMIDITY_ABSOLUTE_GM3"); + } + + 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