From d0320beaa7a3176aa5f65fd031e0146fd47e2054 Mon Sep 17 00:00:00 2001 From: c3ma Date: Sat, 12 Feb 2022 05:26:54 +0100 Subject: [PATCH] allow sensor type selection per plant, changed calculations to use PCT values, due to different raw value meaning --- esp32/include/ControllerConfiguration.h | 3 + esp32/include/HomieConfiguration.h | 3 +- esp32/include/HomieTypes.h | 5 + esp32/include/LogDefines.h | 3 + esp32/include/MathUtils.h | 1 + esp32/include/PlantCtrl.h | 100 +++++++++++++------- esp32/src/MathUtil.cpp | 7 +- esp32/src/PlantCtrl.cpp | 120 +++++++++++++++--------- esp32/src/main.cpp | 83 ++++++++++------ 9 files changed, 217 insertions(+), 108 deletions(-) diff --git a/esp32/include/ControllerConfiguration.h b/esp32/include/ControllerConfiguration.h index dabb967..8a335dd 100644 --- a/esp32/include/ControllerConfiguration.h +++ b/esp32/include/ControllerConfiguration.h @@ -93,6 +93,9 @@ #define MOIST_SENSOR_MAX_FRQ 10000 // 10kHz (as never more then 3000 was measured) #define MOIST_SENSOR_MIN_FRQ 1000 // 1kHz (500Hz margin) +#define ANALOG_SENSOR_MAX_MV 1000 +#define ANALOG_SENSOR_MIN_MV 100 + #define SOLAR_VOLT_FACTOR 11 #define BATTSENSOR_INDEX_SOLAR 0 #define BATTSENSOR_INDEX_BATTERY 1 diff --git a/esp32/include/HomieConfiguration.h b/esp32/include/HomieConfiguration.h index 124d166..14028b5 100644 --- a/esp32/include/HomieConfiguration.h +++ b/esp32/include/HomieConfiguration.h @@ -101,6 +101,7 @@ HomieSetting ntpServer("ntpServer", "NTP server (pool.ntp.org as d #define GENERATE_PLANT(plant, strplant) \ HomieSetting mSensorDry##plant = HomieSetting("dry" strplant, "Plant " strplant "- Moist sensor dry %"); \ + HomieSetting pSensorType##plant = HomieSetting("sensoryType" strplant, "sensor" strplant " - sensortype"); \ HomieSetting mPumpAllowedHourRangeStart##plant = HomieSetting("hourstart" strplant, "Plant" strplant " - Range pump allowed hour start (0-23)"); \ HomieSetting mPumpAllowedHourRangeEnd##plant = HomieSetting("hourend" strplant, "Plant" strplant " - Range pump allowed hour end (0-23)"); \ HomieSetting mPumpOnlyWhenLowLight##plant = HomieSetting("lowLight" strplant, "Plant" strplant " - Enable the Pump only, when there is no sunlight"); \ @@ -108,7 +109,7 @@ HomieSetting ntpServer("ntpServer", "NTP server (pool.ntp.org as d HomieSetting pPumpDuration##plant = HomieSetting("pumpDuration" strplant, "Plant" strplant " - time seconds to water when pump is active"); \ HomieSetting pPumpMl##plant = HomieSetting("pumpAmount" strplant, "Plant" strplant " - ml (if using flowmeter) to water when pump is active"); \ HomieSetting pPowerLevel##plant = HomieSetting("powerLevel" strplant, "Plant" strplant " - pwm duty cycle in percent"); \ - PlantSettings_t mSetting##plant = {&mSensorDry##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInMinutes##plant, &pPumpDuration##plant, &pPowerLevel##plant, &pPumpMl##plant}; \ + PlantSettings_t mSetting##plant = {&mSensorDry##plant, &pSensorType##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInMinutes##plant, &pPumpDuration##plant, &pPowerLevel##plant, &pPumpMl##plant}; \ /**< Generate all settings for one plant \ * \ * Feature to start pumping only at morning: @link{SOLAR_CHARGE_MIN_VOLTAGE} and @link{SOLAR_CHARGE_MAX_VOLTAGE} \ diff --git a/esp32/include/HomieTypes.h b/esp32/include/HomieTypes.h index 1d4d04e..b3f064d 100644 --- a/esp32/include/HomieTypes.h +++ b/esp32/include/HomieTypes.h @@ -13,6 +13,10 @@ #include +#define SENSOR_NONE 0 +#define SENSOR_CAPACITIVE_FREQUENCY_MOD 1 +#define SENSOR_ANALOG_RESISTANCE_PROBE 2 + //plant pump is deactivated, but sensor values are still recorded and published #define DEACTIVATED_PLANT -1 //special value to indicate a missing sensor when the plant is not deactivated but no valid sensor value was read @@ -23,6 +27,7 @@ typedef struct PlantSettings_t { HomieSetting *pSensorDry; + HomieSetting *pSensorMode; HomieSetting *pPumpAllowedHourRangeStart; HomieSetting *pPumpAllowedHourRangeEnd; HomieSetting *pPumpOnlyWhenLowLight; diff --git a/esp32/include/LogDefines.h b/esp32/include/LogDefines.h index e1fcced..c5db217 100644 --- a/esp32/include/LogDefines.h +++ b/esp32/include/LogDefines.h @@ -21,6 +21,9 @@ #define LOG_HARDWARECOUNTER_ERROR_MESSAGE "PCNR returned error" #define LOG_HARDWARECOUNTER_ERROR_CODE -4 +#define LOG_SENSORMODE_UNKNOWN "Unknown sensor mode requested" +#define LOG_SENSORMODE_UNKNOWN_CODE -5 + #define LOG_PUMP_AND_DOWNLOADMODE "Download mode, ignoring pump request" #define LOG_PUMP_AND_DOWNLOADMODE_CODE 2 diff --git a/esp32/include/MathUtils.h b/esp32/include/MathUtils.h index 0729ed6..2713d6c 100644 --- a/esp32/include/MathUtils.h +++ b/esp32/include/MathUtils.h @@ -3,5 +3,6 @@ bool equalish(double x, double y); +double mapf(double x, double in_min, double in_max, double out_min, double out_max); #endif \ No newline at end of file diff --git a/esp32/include/PlantCtrl.h b/esp32/include/PlantCtrl.h index 49aee02..17fab9e 100644 --- a/esp32/include/PlantCtrl.h +++ b/esp32/include/PlantCtrl.h @@ -17,19 +17,21 @@ #include "ControllerConfiguration.h" #include "RunningMedian.h" #include "MathUtils.h" +#include "MQTTUtils.h" +#include "LogDefines.h" -#define MOISTURE_MEASUREMENT_DURATION 400 /** ms */ +#define ANALOG_REREADS 5 +#define MOISTURE_MEASUREMENT_DURATION 400 /** ms */ #define PWM_FREQ 50000 #define PWM_BITS 8 - class Plant { private: HomieNode *mPlant = NULL; HomieInternals::PropertyInterface mPump; - int32_t mMoisture_freq = 0; + RunningMedian mMoisture_raw = RunningMedian(ANALOG_REREADS); int mPinSensor = 0; /**< Pin of the moist sensor */ int mPinPump = 0; /**< Pin of the pump */ bool mConnected = false; @@ -52,10 +54,9 @@ public: void advertise(void); - /** - * @brief Measure a new analog moister value - * - */ + //for sensor that might take any time + void blockingMoistureMeasurement(void); + //for sensor that need a start and a end in defined timing void startMoistureMeasurement(void); void stopMoistureMeasurement(void); @@ -63,10 +64,15 @@ public: void activatePump(void); - - bool isHydroponic(){ + bool isHydroponic() + { long current = this->mSetting->pSensorDry->get(); - return equalish(current,HYDROPONIC_MODE); + return equalish(current, HYDROPONIC_MODE); + } + + long isSensorMode(int sensorMode) + { + return this->mSetting->pSensorMode->get() == sensorMode; } /** @@ -77,36 +83,27 @@ public: */ bool isPumpRequired() { - if(isHydroponic()){ + if (isHydroponic()) + { //hydroponic only uses timer based controll return true; } - bool isDry = getCurrentMoisture() > getSetting2Moisture(); + bool isDry = getCurrentMoisturePCT() < getTargetMoisturePCT(); bool isActive = isPumpTriggerActive(); return isDry && isActive; - } + } bool isPumpTriggerActive() { long current = this->mSetting->pSensorDry->get(); - return !equalish(current,DEACTIVATED_PLANT); + return !equalish(current, DEACTIVATED_PLANT); } - float getCurrentMoisture() - { - if(mMoisture_freq < MOIST_SENSOR_MIN_FRQ){ - return MISSING_SENSOR; - } - return mMoisture_freq; - } - - long getSetting2Moisture() + float getTargetMoisturePCT() { - if (this->mSetting->pSensorDry != NULL) + if (isPumpTriggerActive()) { - //1 is totally wet, 0 is try, 0 is MOIST_SENSOR_MAX_FRQ, 1 is MOIST_SENSOR_MIN_FRQ - float factor = (this->mSetting->pSensorDry->get()); - return map(factor,0,100,MOIST_SENSOR_MAX_FRQ,MOIST_SENSOR_MIN_FRQ); + return this->mSetting->pSensorDry->get(); } else { @@ -114,6 +111,38 @@ public: } } + float getCurrentMoisturePCT() + { + if (isSensorMode(SENSOR_NONE)) + { + return DEACTIVATED_PLANT; + } + if (isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)) + { + return mapf(mMoisture_raw.getMedian(), MOIST_SENSOR_MAX_FRQ, MOIST_SENSOR_MIN_FRQ, 0, 100); + } + else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE)) + { + return mapf(mMoisture_raw.getMedian(), ANALOG_SENSOR_MAX_MV, ANALOG_SENSOR_MIN_MV, 0, 100); + } else { + log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE); + return DEACTIVATED_PLANT; + } + } + + float getCurrentMoistureRaw() + { + if (isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)) + { + if (mMoisture_raw.getMedian() < MOIST_SENSOR_MIN_FRQ) + { + return MISSING_SENSOR; + } + } + + return mMoisture_raw.getMedian(); + } + HomieInternals::SendingPromise &setProperty(const String &property) const { return mPlant->setProperty(property); @@ -121,7 +150,8 @@ public: void init(void); - long getCooldownInSeconds() { + long getCooldownInSeconds() + { return this->mSetting->pPumpCooldownInSeconds->get(); } @@ -130,7 +160,8 @@ public: * * @return hour */ - int getHoursStart() { + int getHoursStart() + { return this->mSetting->pPumpAllowedHourRangeStart->get(); } @@ -139,13 +170,15 @@ public: * * @return hour */ - int getHoursEnd() { + int getHoursEnd() + { return this->mSetting->pPumpAllowedHourRangeEnd->get(); } bool isAllowedOnlyAtLowLight(void) { - if(this->isHydroponic()){ + if (this->isHydroponic()) + { return false; } return this->mSetting->pPumpOnlyWhenLowLight->get(); @@ -153,11 +186,12 @@ public: void publishState(String state); - bool switchHandler(const HomieRange& range, const String& value); + bool switchHandler(const HomieRange &range, const String &value); void setSwitchHandler(HomieInternals::PropertyInputHandler f); - long getPumpDuration() { + long getPumpDuration() + { return this->mSetting->pPumpDuration->get(); } }; diff --git a/esp32/src/MathUtil.cpp b/esp32/src/MathUtil.cpp index e3e0784..6b4cb84 100644 --- a/esp32/src/MathUtil.cpp +++ b/esp32/src/MathUtil.cpp @@ -4,4 +4,9 @@ bool equalish(double x, double y) { return (abs(x - y) < 0.5); -} \ No newline at end of file +} + +double mapf(double x, double in_min, double in_max, double out_min, double out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} diff --git a/esp32/src/PlantCtrl.cpp b/esp32/src/PlantCtrl.cpp index c2c2340..0409230 100644 --- a/esp32/src/PlantCtrl.cpp +++ b/esp32/src/PlantCtrl.cpp @@ -9,18 +9,11 @@ * */ - #include "PlantCtrl.h" #include "ControllerConfiguration.h" #include "TimeUtils.h" -#include "MathUtils.h" #include "driver/pcnt.h" -double mapf(double x, double in_min, double in_max, double out_min, double out_max) -{ - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - Plant::Plant(int pinSensor, int pinPump, int plantId, HomieNode *plant, PlantSettings_t *setting) { this->mPinSensor = pinSensor; @@ -37,6 +30,12 @@ void Plant::init(void) this->mSetting->pSensorDry->setValidator([](long candidate) { return (((candidate >= 0.0) && (candidate <= 100.0)) || equalish(candidate,DEACTIVATED_PLANT) || equalish(candidate,HYDROPONIC_MODE)); }); + + this->mSetting->pSensorMode->setDefaultValue(SENSOR_NONE); + this->mSetting->pSensorMode->setValidator([](long candidate) { + return candidate == SENSOR_NONE || candidate == SENSOR_CAPACITIVE_FREQUENCY_MOD || candidate == SENSOR_ANALOG_RESISTANCE_PROBE; + }); + this->mSetting->pPumpAllowedHourRangeStart->setDefaultValue(8); // start at 8:00 this->mSetting->pPumpAllowedHourRangeStart->setValidator([](long candidate) { return ((candidate >= 0) && (candidate <= 23)); @@ -76,47 +75,82 @@ void Plant::init(void) Serial.flush(); pinMode(this->mPinSensor, INPUT); - pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); - pcnt_config_t pcnt_config = { }; // Instancia PCNT config - - pcnt_config.pulse_gpio_num = this->mPinSensor; // Configura GPIO para entrada dos pulsos - pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED; // Configura GPIO para controle da contagem - pcnt_config.unit = unit; // Unidade de contagem PCNT - 0 - pcnt_config.channel = PCNT_CHANNEL_0; // Canal de contagem PCNT - 0 - pcnt_config.counter_h_lim = INT16_MAX; // Limite maximo de contagem - 20000 - pcnt_config.pos_mode = PCNT_COUNT_INC; // Incrementa contagem na subida do pulso - pcnt_config.neg_mode = PCNT_COUNT_DIS; // Incrementa contagem na descida do pulso - pcnt_config.lctrl_mode = PCNT_MODE_KEEP; // PCNT - modo lctrl desabilitado - pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // PCNT - modo hctrl - se HIGH conta incrementando - pcnt_unit_config(&pcnt_config); // Configura o contador PCNT + if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)){ - pcnt_counter_pause(unit); // Pausa o contador PCNT - pcnt_counter_clear(unit); // Zera o contador PCNT + pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); + pcnt_config_t pcnt_config = { }; // Instancia PCNT config - Serial.println("Setup Counter " + String(mPinPump) + "=" + String(LOW)); + pcnt_config.pulse_gpio_num = this->mPinSensor; // Configura GPIO para entrada dos pulsos + pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED; // Configura GPIO para controle da contagem + pcnt_config.unit = unit; // Unidade de contagem PCNT - 0 + pcnt_config.channel = PCNT_CHANNEL_0; // Canal de contagem PCNT - 0 + pcnt_config.counter_h_lim = INT16_MAX; // Limite maximo de contagem - 20000 + pcnt_config.pos_mode = PCNT_COUNT_INC; // Incrementa contagem na subida do pulso + pcnt_config.neg_mode = PCNT_COUNT_DIS; // Incrementa contagem na descida do pulso + pcnt_config.lctrl_mode = PCNT_MODE_KEEP; // PCNT - modo lctrl desabilitado + pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // PCNT - modo hctrl - se HIGH conta incrementando + pcnt_unit_config(&pcnt_config); // Configura o contador PCNT + + + pcnt_counter_pause(unit); // Pausa o contador PCNT + pcnt_counter_clear(unit); // Zera o contador PCNT + + Serial.println("Setup Counter " + String(mPinPump) + "=" + String(LOW)); + } else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE)){ + adcAttachPin(this->mPinSensor); + } else if (isSensorMode(SENSOR_NONE)){ + //nothing to do here + } else { + log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE); + } + } +void Plant::blockingMoistureMeasurement(void) { + if(isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE)){ + for(int i = 0;imMoisture_raw.add(analogReadMilliVolts(this->mPinSensor)); + delay(5); + } + }else if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD) || isSensorMode(SENSOR_NONE)){ + //nothing to do here + } else { + log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE); + } +} + + void Plant::startMoistureMeasurement(void) { - pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); - pcnt_counter_resume(unit); + if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)){ + pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); + pcnt_counter_resume(unit); + } else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE) || isSensorMode(SENSOR_NONE)){ + //nothing to do here + } else { + log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE); + } } void Plant::stopMoistureMeasurement(void) { - int16_t pulses; - pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); - pcnt_counter_pause(unit); - esp_err_t result = pcnt_get_counter_value(unit, &pulses); - pcnt_counter_clear(unit); - - - if(result != ESP_OK){ - //FIXME log(LOG_LEVEL_ERROR, LOG_HARDWARECOUNTER_ERROR_MESSAGE, LOG_HARDWARECOUNTER_ERROR_CODE); - this -> mMoisture_freq = -1; - } else { - this->mMoisture_freq = pulses * (1000 / MOISTURE_MEASUREMENT_DURATION); + if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)){ + int16_t pulses; + pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); + pcnt_counter_pause(unit); + esp_err_t result = pcnt_get_counter_value(unit, &pulses); + pcnt_counter_clear(unit); + if(result != ESP_OK){ + log(LOG_LEVEL_ERROR, LOG_HARDWARECOUNTER_ERROR_MESSAGE, LOG_HARDWARECOUNTER_ERROR_CODE); + this-> mMoisture_raw.clear(); + this -> mMoisture_raw.add(-1); + } else { + this->mMoisture_raw.add(pulses * (1000 / MOISTURE_MEASUREMENT_DURATION)); + } + }else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE) || isSensorMode(SENSOR_NONE)){ + //nothing to do here + } else { + log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE); } - } void Plant::postMQTTconnection(void) @@ -125,8 +159,10 @@ void Plant::postMQTTconnection(void) this->mConnected = true; this->mPlant->setProperty("switch").send(OFF); - long raw = getCurrentMoisture(); - double pct = mapf(raw, MOIST_SENSOR_MIN_FRQ, MOIST_SENSOR_MAX_FRQ, 100, 0); + float pct = getCurrentMoisturePCT(); + float raw = getCurrentMoistureRaw(); + Serial.println(pct); + Serial.println(".................."); if (equalish(raw, MISSING_SENSOR)) { pct = 0; @@ -140,9 +176,9 @@ void Plant::postMQTTconnection(void) pct = 100; } - this->mPlant->setProperty("moist").send(String(round(pct*10)/10)); + this->mPlant->setProperty("moist").send(String(pct)); this->mPlant->setProperty("moistraw").send(String(raw)); - this->mPlant->setProperty("moisttrigger").send(String(getSetting2Moisture())); + this->mPlant->setProperty("moisttrigger").send(String(getTargetMoisturePCT())); } void Plant::deactivatePump(void) diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index 823d8f2..aaf3193 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -209,7 +209,7 @@ void readOneWireSensors() continue; } - char buf[(sizeof(ds18b20Address) * 2)+1]; /* additional byte for trailing terminator */ + char buf[(sizeof(ds18b20Address) * 2) + 1]; /* additional byte for trailing terminator */ snprintf(buf, sizeof(buf), "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X", ds18b20Address[0], ds18b20Address[1], @@ -269,7 +269,27 @@ void readPowerSwitchedSensors() for (int i = 0; i < MAX_PLANTS; i++) { - Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoisture() << " hz" << endl; + mPlants[i].blockingMoistureMeasurement(); + } + + for (int i = 0; i < MAX_PLANTS; i++) + { + if (mPlants[i].isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)) + { + Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " hz" << endl; + } + else if (mPlants[i].isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE)) + { + Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " mV" << endl; + } + else if (mPlants[i].isSensorMode(SENSOR_NONE)) + { + Serial << "Plant " << i << " measurement: no sensor configured" << endl; + } + else + { + log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE); + } } waterRawSensor.clear(); @@ -408,7 +428,7 @@ int determineNextPump(bool isLowLight) } if (!plant.isHydroponic()) { - if (equalish(plant.getCurrentMoisture(), MISSING_SENSOR)) + if (equalish(plant.getCurrentMoistureRaw(), MISSING_SENSOR)) { plant.publishState("nosensor"); log(LOG_LEVEL_ERROR, String(String(i) + " No pump possible: missing sensor"), LOG_MISSING_PUMP); @@ -631,7 +651,7 @@ void pumpActiveLoop() #endif long pumpStarted = pumpTarget - (mPlants[pumpToRun].getPumpDuration() * 1000); - long duration = millis()-pumpStarted; + long duration = millis() - pumpStarted; if (millis() > pumpTarget) { mPlants[pumpToRun].setProperty("watertime").send(String(duration)); @@ -704,33 +724,7 @@ void safeSetup() return; } - /************************* Start One-Wire bus ***************/ - int tempInitStartTime = millis(); - uint8_t sensorCount = 0U; - - /* Required to read the temperature at least once */ - while ((sensorCount == 0 || !battery.isFound()) && millis() < tempInitStartTime + TEMPERATUR_TIMEOUT) - { - sensors.begin(); - battery.begin(); - sensorCount = sensors.getDS18Count(); - delay(50); - } - - Serial << "DS18S20 count: " << sensorCount << " found in " << (millis() - tempInitStartTime) << " ms" << endl; - Serial.flush(); - /* Measure temperature TODO idea: move this into setup */ - if (sensorCount > 0) - { - //sensors.setResolution(DS18B20_RESOLUTION); - sensors.requestTemperatures(); - } - Serial << "Reading sensors start" << endl; - Serial.flush(); - readPowerSwitchedSensors(); - Serial << "Reading sensors end" << endl; - Serial.flush(); - /************************* Start Homie Framework ***************/ + /************************* Start Homie Framework ***************/ Homie_setFirmware("PlantControl", FIRMWARE_VERSION); Homie.disableLedFeedback(); Homie_setBrand("PlantControl"); @@ -766,9 +760,36 @@ void safeSetup() Homie.setup(); + /************************* Start One-Wire bus ***************/ + int tempInitStartTime = millis(); + uint8_t sensorCount = 0U; + + /* Required to read the temperature at least once */ + while ((sensorCount == 0 || !battery.isFound()) && millis() < tempInitStartTime + TEMPERATUR_TIMEOUT) + { + sensors.begin(); + battery.begin(); + sensorCount = sensors.getDS18Count(); + delay(50); + } + + Serial << "DS18S20 count: " << sensorCount << " found in " << (millis() - tempInitStartTime) << " ms" << endl; + Serial.flush(); + /* Measure temperature TODO idea: move this into setup */ + if (sensorCount > 0) + { + //sensors.setResolution(DS18B20_RESOLUTION); + sensors.requestTemperatures(); + } + mConfigured = Homie.isConfigured(); if (mConfigured) { + Serial << "Reading sensors start" << endl; + Serial.flush(); + readPowerSwitchedSensors(); + Serial << "Reading sensors end" << endl; + Serial.flush(); for (int i = 0; i < MAX_PLANTS; i++) { mPlants[i].advertise();