BME680
This commit is contained in:
parent
0660bb1726
commit
d03369e7ef
@ -4,6 +4,7 @@ board = esp12e
|
||||
framework = arduino
|
||||
lib_deps = https://github.com/adafruit/Adafruit_TSL2561
|
||||
https://github.com/knolleary/pubsubclient
|
||||
https://github.com/adafruit/Adafruit_BME680
|
||||
build_flags = -DHOSTNAME=\"Greenhouse\"
|
||||
monitor_speed = 115200
|
||||
upload_protocol = espota
|
||||
|
||||
75
src/bme680.h
Normal file
75
src/bme680.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef BME680_H
|
||||
#define BME680_H
|
||||
|
||||
#include <Adafruit_BME680.h>
|
||||
#include <mqtt.h>
|
||||
|
||||
class BME680 {
|
||||
|
||||
Adafruit_BME680 bme; // NOLINT(*-interfaces-global-init)
|
||||
|
||||
public:
|
||||
|
||||
const char *name;
|
||||
|
||||
unsigned long intervalMs;
|
||||
|
||||
explicit BME680(const char *name, const unsigned long interval_ms = 5000) : name(name), intervalMs(interval_ms) {
|
||||
//
|
||||
}
|
||||
|
||||
void setup() {
|
||||
if (bme.begin()) {
|
||||
Log.printf("BME680: Initialized.\n");
|
||||
} else {
|
||||
Log.printf("BME680: Failed to initialize.\n");
|
||||
}
|
||||
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());
|
||||
static auto last = 0UL;
|
||||
if (last == 0 || now - last >= intervalMs) {
|
||||
if (bme.beginReading() == 0) {
|
||||
Log.print("BME680: Failed to request reading.\n");
|
||||
setup();
|
||||
}
|
||||
last = now;
|
||||
}
|
||||
if (bme.remainingReadingMillis() == 0) {
|
||||
if (bme.endReading()) {
|
||||
const auto humidityAbsolute = calculateHumidityAbsolute(bme.temperature, bme.humidity);
|
||||
mqttPublish("garden/temperature", bme.temperature, "\xB0""C");
|
||||
mqttPublish("garden/pressure", bme.pressure / 100.0, "hPa");
|
||||
mqttPublish("garden/humidity/relative", bme.humidity, "%");
|
||||
mqttPublish("garden/humidity/absolute", humidityAbsolute, "mg/L");
|
||||
mqttPublish("garden/gas", bme.gas_resistance / 1000.0, "KOhms");
|
||||
mqttPublish("garden/altitude", bme.readAltitude(1013.25), "m");
|
||||
} else {
|
||||
Log.printf("Failed to complete reading\n");
|
||||
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
|
||||
13
src/main.cpp
13
src/main.cpp
@ -1,16 +1,25 @@
|
||||
#include <bme680.h>
|
||||
#include "mqtt.h"
|
||||
#include "tsl2561.h"
|
||||
#include "wifi.h"
|
||||
|
||||
BME680 garden("garden");
|
||||
|
||||
BME680 greenhouse("greenhouse");
|
||||
|
||||
void setup() {
|
||||
delay(500);
|
||||
Log.printf("\n\n\nStartup\n");
|
||||
wifiConnect();
|
||||
sensorSetup();
|
||||
tsl2561Setup();
|
||||
garden.setup();
|
||||
greenhouse.setup();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wifiLoop();
|
||||
sensorLoop();
|
||||
mqttLoop();
|
||||
tsl2561Loop();
|
||||
garden.loop();
|
||||
greenhouse.loop();
|
||||
}
|
||||
35
src/mqtt.cpp
35
src/mqtt.cpp
@ -65,30 +65,37 @@ void mqttLoop() {
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const int32_t value, const char *unit) {
|
||||
if (!isTimeSet()) {
|
||||
return;
|
||||
}
|
||||
char buffer[200];
|
||||
snprintf(buffer, sizeof buffer, R"({"timestamp": %lld, "value": %d, "unit": "%s"})", time(nullptr), value, unit);
|
||||
mqttPublish(topic, buffer);
|
||||
mqttPublish(topic, String(value), unit);
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const int64_t value, const char *unit) {
|
||||
mqttPublish(topic, String(value), unit);
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const uint32_t value, const char *unit) {
|
||||
if (!isTimeSet()) {
|
||||
return;
|
||||
}
|
||||
char buffer[200];
|
||||
snprintf(buffer, sizeof buffer, R"({"timestamp": %lld, "value": %d, "unit": "%s"})", time(nullptr), value, unit);
|
||||
mqttPublish(topic, buffer);
|
||||
mqttPublish(topic, String(value), unit);
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const uint64_t value, const char *unit) {
|
||||
mqttPublish(topic, String(value), unit);
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const float value, const char *unit) {
|
||||
mqttPublish(topic, String(value), unit);
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const double value, const char *unit) {
|
||||
mqttPublish(topic, String(value), unit);
|
||||
}
|
||||
|
||||
bool mqttPublish(const char *topic, const String& value, const char *unit) {
|
||||
if (!isTimeSet()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
char buffer[200];
|
||||
snprintf(buffer, sizeof buffer, R"({"timestamp": %lld, "value": %s, "unit": "%s"})", time(nullptr), isnan(value) ? "null" : String(value).c_str(), unit);
|
||||
snprintf(buffer, sizeof buffer, R"({"timestamp": %lld, "value": %s, "unit": "%s"})", time(nullptr), value.c_str(), unit);
|
||||
mqttPublish(topic, buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
void mqttPublish(const char *topic, const char *payload) {
|
||||
|
||||
@ -13,10 +13,18 @@ void mqttLoop();
|
||||
|
||||
void mqttPublish(const char *topic, int32_t value, const char *unit);
|
||||
|
||||
void mqttPublish(const char *topic, int64_t value, const char *unit);
|
||||
|
||||
void mqttPublish(const char *topic, uint32_t value, const char *unit);
|
||||
|
||||
void mqttPublish(const char *topic, uint64_t value, const char *unit);
|
||||
|
||||
void mqttPublish(const char *topic, float value, const char *unit);
|
||||
|
||||
void mqttPublish(const char *topic, double value, const char *unit);
|
||||
|
||||
bool mqttPublish(const char *topic, const String& value, const char *unit);
|
||||
|
||||
void mqttPublish(const char *topic, const char *payload);
|
||||
|
||||
class LogClass final : public Stream {
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
auto tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT);
|
||||
|
||||
void sensorSetup() {
|
||||
void tsl2561Setup() {
|
||||
if (tsl.begin()) {
|
||||
Log.printf("TSL2561: Initialized.\n");
|
||||
} else {
|
||||
@ -26,13 +26,13 @@ void sensorRead() {
|
||||
const auto illuminance = tsl.calculateLux(broadband, ir);
|
||||
if (illuminance == 65536) {
|
||||
Log.printf("TSL2561: Failed to read.\n");
|
||||
sensorSetup();
|
||||
tsl2561Setup();
|
||||
} else {
|
||||
mqttPublish("garden/illuminance", illuminance, "lux");
|
||||
}
|
||||
}
|
||||
|
||||
void sensorLoop() {
|
||||
void tsl2561Loop() {
|
||||
const auto now = millis();
|
||||
static unsigned long last = 0;
|
||||
if (last == 0 || now - last >= TSL2561_INTERVAL_MS) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
#ifndef TSL2561_H
|
||||
#define TSL2561_H
|
||||
|
||||
void sensorSetup();
|
||||
void tsl2561Setup();
|
||||
|
||||
void sensorLoop();
|
||||
void tsl2561Loop();
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user