From 634e2cdf52eb0780043435fb54b1c76514447e84 Mon Sep 17 00:00:00 2001 From: Fisch Date: Sun, 13 Nov 2022 14:19:12 +0100 Subject: [PATCH] add sht31 humidity sensor to outdoor station --- include/sensor_sht31.cpp | 130 +++++++++++++++++++++++++++++++++++++++ include/sensor_sht31.h | 46 ++++++++++++++ platformio.ini | 13 +++- src/main.cpp | 41 ++++++++++++ 4 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 include/sensor_sht31.cpp create mode 100644 include/sensor_sht31.h diff --git a/include/sensor_sht31.cpp b/include/sensor_sht31.cpp new file mode 100644 index 0000000..f36a992 --- /dev/null +++ b/include/sensor_sht31.cpp @@ -0,0 +1,130 @@ +//Connect SCL to D1, SDA to D2, GND and 3v3 +#include "sensor_sht31.h" + + + +Sensor_SHT31::Sensor_SHT31() +{ + sht31 = new Adafruit_SHT31(); +} + +void Sensor_SHT31::init() //Things to be done during setup() +{ + Serial.println("initializing sht31"); + if (!sht31->begin(0x44)){ + Serial.println("#ERROR: SHT31 init fail\n"); + }else{ + init_ok=true; //stays false if init failed, sensor will not be read in loop + } +} + +//Also called during setup() +void Sensor_SHT31::setSettings_Temperature(float minchange, unsigned long senddelaymax, unsigned long readdelay) +{ + data_temperature.minchange=minchange; + data_temperature.senddelaymax=senddelaymax; + data_temperature.readdelay=readdelay; +} + +//Also called during setup() +void Sensor_SHT31::setSettings_Humidity(float minchange, unsigned long senddelaymax, unsigned long readdelay) +{ + data_humidity.minchange=minchange; + data_humidity.senddelaymax=senddelaymax; + data_humidity.readdelay=readdelay; +} + +//Called during setup +void Sensor_SHT31::advertise(HomieNode& p_sensorNode) +{ + sensorNode = &p_sensorNode; + sensorNode->advertise("temperature_sht"); + sensorNode->advertise("humidity_sht"); + sensorNode->advertise("sht_heater"); +} + +void Sensor_SHT31::sensorloop() +{ + if (init_ok) { + loop_SHT31_temperature(); + loop_SHT31_humidity(); + } +} + +void Sensor_SHT31::loop_SHT31_temperature() +{ + sensordata &d=data_temperature; + bool _changed=false; + + if (millis() >= (d.lastreadtime+d.readdelay)) { + d.value = sht31->readTemperature(); + if (fabs(d.lastsentvalue-d.value)>=d.minchange){ + _changed=true; + } + d.lastreadtime=millis(); + } + + if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { + Serial.print("Sending SHT31_temperature. reason="); + if (_changed) Serial.println("change"); else Serial.println("time"); + + + if (!(isnan(d.value) == 1)){ //success + sensorNode->setProperty("temperature_sht").send(String(d.value)); + Homie.getLogger() << "temperature_sht " << ": " << d.value << endl; + d.lastsentvalue=d.value; + } + + d.lastsent=millis(); + } +} + +void Sensor_SHT31::loop_SHT31_humidity() +{ + sensordata &d=data_humidity; + bool _changed=false; + + if (millis() >= (d.lastreadtime+d.readdelay)) { + d.value = sht31->readHumidity(); + checkHeater(d.value); + if (fabs(d.lastsentvalue-d.value)>=d.minchange){ + _changed=true; + } + d.lastreadtime=millis(); + } + + if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { + Serial.print("Sending SHT31_humidity. reason="); + if (_changed) Serial.println("change"); else Serial.println("time"); + + if (!(isnan(d.value) == 1)){ //success + Homie.getLogger() << "humidity_sht " << ": " << d.value << endl; + sensorNode->setProperty("humidity_sht").send(String(d.value)); + d.lastsentvalue=d.value; + } + d.lastsent=millis(); + } +} + +void Sensor_SHT31::checkHeater(float humidity) { + + bool heaterstatus=sht31->isHeaterEnabled(); + if (isnan(humidity)==1) { //if sensor cant be read. turn heater on to prevent condensation just in case + sht31->heater(true); + Serial.println("checkHeater humidity isnan. turned heater on"); + }else{ + if (!heaterstatus && humidity>=SHT31_HUMIDITY_HEATERON) {//heater was off and humidity is too high + sht31->heater(true); + Serial.println("checkHeater humidity too high. turned heater on"); + }else if(heaterstatus && humidity<=SHT31_HUMIDITY_HEATEROFF) { //heater was on and humidity is low enough + sht31->heater(false); + Serial.println("checkHeater humidity low enough. turned heater off"); + } + } + heaterstatus=sht31->isHeaterEnabled(); + if (heaterstatus!=last_sent_heaterstatus || millis()<30000) { //changed or just booted + sensorNode->setProperty("sht_heater").send(String(heaterstatus)); + last_sent_heaterstatus=heaterstatus; + } + +} \ No newline at end of file diff --git a/include/sensor_sht31.h b/include/sensor_sht31.h new file mode 100644 index 0000000..22903a5 --- /dev/null +++ b/include/sensor_sht31.h @@ -0,0 +1,46 @@ +#ifndef Sensor_SHT31_H +#define Sensor_SHT31_H + +#include "sensordata.h" +#include + +#include +#include "Adafruit_SHT31.h" + +#define SHT31_HUMIDITY_HEATERON 95 +#define SHT31_HUMIDITY_HEATEROFF 85 + +class Sensor_SHT31 +{ + +private: + Adafruit_SHT31 *sht31; + + HomieNode *sensorNode; //reference to HomieNode + + struct sensordata data_temperature; //struct values are changed in setup() + struct sensordata data_humidity; //struct values are changed in setup() + + bool init_ok; + + bool last_sent_heaterstatus; + + +public: + Sensor_SHT31(); + + void loop_SHT31_temperature(); + void loop_SHT31_humidity(); + + void init(); + void setSettings_Temperature(float minchange, unsigned long senddelaymax, unsigned long readdelay); + void setSettings_Humidity(float minchange, unsigned long senddelaymax, unsigned long readdelay); + void advertise(HomieNode& p_sensorNode); + void sensorloop(); + + void checkHeater(float humidity); + +}; + +#endif + diff --git a/platformio.ini b/platformio.ini index caace1f..cb9f650 100644 --- a/platformio.ini +++ b/platformio.ini @@ -43,9 +43,14 @@ build_flags = -D SENSOR_TCS34725_COLORTEMP_minchange=100 -D SENSOR_TCS34725_LUXFACTOR=0.3 #measured with luxmeter. with half tennis ball was 1.7ev less. 1/2^1.7=0,3078 - -D SENSOR_HS1101 - -D SENSOR_HS1101_PIN=D5 - -D SENSOR_HS1101_humidity_minchange=10 + #-D SENSOR_HS1101 + #-D SENSOR_HS1101_PIN=D5 + #-D SENSOR_HS1101_humidity_minchange=10 + + -D SENSOR_SHT31 + -D SENSOR_SHT31_humidity_minchange=5 + -D SENSOR_SHT31_temperature_minchange=0.5 + -D SENSOR_ML8511 -D SENSOR_ML8511_PIN=A0 @@ -72,6 +77,8 @@ lib_deps = https://github.com/adafruit/Adafruit_TCS34725#1.3.5 ArduinoJson@6.16.1 #dependency of homie. using older version because of "ambiguous overload for operator|" error Homie@3.0.0 + adafruit/Adafruit SHT31 Library@^2.2.0 + SPI #Test diff --git a/src/main.cpp b/src/main.cpp index 95c432b..55faf5e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -108,6 +108,33 @@ HomieNode sensorNode("sensors", "Sensors","sensors"); //id, name, type #endif + +#ifdef SENSOR_SHT31 + #include "sensor_sht31.cpp" + Sensor_SHT31 sensor_sht31; + + #ifndef SENSOR_SHT31_temperature_minchange + #define SENSOR_SHT31_temperature_minchange 0.2 + #endif + #ifndef SENSOR_SHT31_temperature_senddelaymax + #define SENSOR_SHT31_temperature_senddelaymax 300000 + #endif + #ifndef SENSOR_SHT31_temperature_readdelay + #define SENSOR_SHT31_temperature_readdelay 10000 + #endif + + #ifndef SENSOR_SHT31_humidity_minchange + #define SENSOR_SHT31_humidity_minchange 2.0 + #endif + #ifndef SENSOR_SHT31_humidity_senddelaymax + #define SENSOR_SHT31_humidity_senddelaymax 10*60*1000 + #endif + #ifndef SENSOR_SHT31_humidity_readdelay + #define SENSOR_SHT31_humidity_readdelay 10000 + #endif + +#endif + #ifdef SENSOR_HS1101 #include "sensor_hs1101.cpp" Sensor_HS1101 sensor_hs1101(SENSOR_HS1101_PIN); @@ -427,6 +454,12 @@ void setup() { sensor_htu21d.setSettings_Humidity(SENSOR_HTU21D_humidity_minchange,SENSOR_HTU21D_humidity_senddelaymax,SENSOR_HTU21D_humidity_readdelay); #endif + #ifdef SENSOR_SHT31 + sensor_sht31.init(); + sensor_sht31.setSettings_Temperature(SENSOR_SHT31_temperature_minchange,SENSOR_SHT31_temperature_senddelaymax,SENSOR_SHT31_temperature_readdelay); + sensor_sht31.setSettings_Humidity(SENSOR_SHT31_humidity_minchange,SENSOR_SHT31_humidity_senddelaymax,SENSOR_SHT31_humidity_readdelay); + #endif + #ifdef SENSOR_HS1101 @@ -528,6 +561,10 @@ void setup() { sensor_htu21d.advertise(sensorNode); #endif + #ifdef SENSOR_SHT31 + sensor_sht31.advertise(sensorNode); + #endif + #ifdef SENSOR_HS1101 sensor_hs1101.advertise(sensorNode); #endif @@ -609,6 +646,10 @@ void loopHandler() { sensor_htu21d.sensorloop(); #endif + #ifdef SENSOR_SHT31 + sensor_sht31.sensorloop(); + #endif + #ifdef SENSOR_HS1101 sensor_hs1101.sensorloop(); #endif