diff --git a/esp32/include/ControllerConfiguration.h b/esp32/include/ControllerConfiguration.h index 980599e..ebb7111 100644 --- a/esp32/include/ControllerConfiguration.h +++ b/esp32/include/ControllerConfiguration.h @@ -80,8 +80,8 @@ */ #define FIRMWARE_VERSION "sw 1.3 hw 0.10" -#define MOIST_SENSOR_MAX_ADC 1200 //swamp earth - 50 margin -#define MOIST_SENSOR_MIN_ADC 1800 //dry earth + 1500 margin +#define MOIST_SENSOR_MAX_ADC 2800 //swamp earth - 50 margin +#define MOIST_SENSOR_MIN_ADC 1200 //dry earth + 1500 margin #define SOLAR_VOLT_FACTOR 11 #define BATTSENSOR_INDEX_SOLAR 0 diff --git a/esp32/include/HomieConfiguration.h b/esp32/include/HomieConfiguration.h index 704295d..cd2b465 100644 --- a/esp32/include/HomieConfiguration.h +++ b/esp32/include/HomieConfiguration.h @@ -18,6 +18,7 @@ #define MAX_PLANTS 7 + /** * @name Homie Attributes * generated Information @@ -88,7 +89,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 threshold"); \ + HomieSetting mSensorDry##plant = HomieSetting("dry" strplant, "Plant " strplant "- Moist sensor dry %"); \ 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"); \ diff --git a/esp32/include/HomieTypes.h b/esp32/include/HomieTypes.h index fffc43b..5e58d13 100644 --- a/esp32/include/HomieTypes.h +++ b/esp32/include/HomieTypes.h @@ -13,12 +13,12 @@ #include -#define DEACTIVATED_PLANT 5000 -#define MISSING_SENSOR 5001 +#define DEACTIVATED_PLANT -1 +#define MISSING_SENSOR -2 typedef struct PlantSettings_t { - HomieSetting *pSensorDry; + HomieSetting *pSensorDry; HomieSetting *pPumpAllowedHourRangeStart; HomieSetting *pPumpAllowedHourRangeEnd; HomieSetting *pPumpOnlyWhenLowLight; diff --git a/esp32/include/MathUtils.h b/esp32/include/MathUtils.h new file mode 100644 index 0000000..0729ed6 --- /dev/null +++ b/esp32/include/MathUtils.h @@ -0,0 +1,7 @@ +#ifndef MATHUTILS_H +#define MATHUTILS_H + + +bool equalish(double x, double y); + +#endif \ No newline at end of file diff --git a/esp32/include/PlantCtrl.h b/esp32/include/PlantCtrl.h index 37adab4..09fcc77 100644 --- a/esp32/include/PlantCtrl.h +++ b/esp32/include/PlantCtrl.h @@ -13,7 +13,9 @@ #define PLANT_CTRL_H #include "HomieTypes.h" +#include "ControllerConfiguration.h" #include "RunningMedian.h" +#include "MathUtils.h" class Plant { @@ -62,14 +64,15 @@ public: */ bool isPumpRequired() { - bool isDry = getCurrentMoisture() > getSettingsMoisture(); + bool isDry = getCurrentMoisture() > getSetting2Moisture(); bool isActive = isPumpTriggerActive(); return isDry && isActive; } bool isPumpTriggerActive() { - return this->mSetting->pSensorDry->get() != DEACTIVATED_PLANT; + long current = this->mSetting->pSensorDry->get(); + return !equalish(current,DEACTIVATED_PLANT); } float getCurrentMoisture() @@ -79,11 +82,13 @@ public: } return this->moistureRaw.getMedian(); } - long getSettingsMoisture() + + long getSetting2Moisture() { if (this->mSetting->pSensorDry != NULL) { - return this->mSetting->pSensorDry->get(); + float percent = (this->mSetting->pSensorDry->get()); + return MOIST_SENSOR_MIN_ADC + ((MOIST_SENSOR_MAX_ADC - MOIST_SENSOR_MIN_ADC) * percent); } else { diff --git a/esp32/src/MathUtil.cpp b/esp32/src/MathUtil.cpp new file mode 100644 index 0000000..e3e0784 --- /dev/null +++ b/esp32/src/MathUtil.cpp @@ -0,0 +1,7 @@ + +#include "MathUtils.h" +#include +bool equalish(double x, double y) +{ + return (abs(x - y) < 0.5); +} \ No newline at end of file diff --git a/esp32/src/PlantCtrl.cpp b/esp32/src/PlantCtrl.cpp index 5b0da87..6fb2e62 100644 --- a/esp32/src/PlantCtrl.cpp +++ b/esp32/src/PlantCtrl.cpp @@ -13,6 +13,12 @@ #include "PlantCtrl.h" #include "ControllerConfiguration.h" #include "TimeUtils.h" +#include "MathUtils.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) { @@ -27,8 +33,8 @@ void Plant::init(void) { /* Initialize Home Settings validator */ this->mSetting->pSensorDry->setDefaultValue(DEACTIVATED_PLANT); - this->mSetting->pSensorDry->setValidator([](long candidate) { - return (((candidate >= 0) && (candidate <= 4095)) || candidate == DEACTIVATED_PLANT); + this->mSetting->pSensorDry->setValidator([](double candidate) { + return (((candidate >= 0.0) && (candidate <= 100.0)) || equalish(candidate,DEACTIVATED_PLANT)); }); this->mSetting->pPumpAllowedHourRangeStart->setDefaultValue(8); // start at 8:00 this->mSetting->pPumpAllowedHourRangeStart->setValidator([](long candidate) { @@ -63,6 +69,7 @@ void Plant::clearMoisture(void){ void Plant::addSenseValue(void) { int raw = analogRead(this->mPinSensor); + Serial << "plant bla " << raw << endl; if(raw < MOIST_SENSOR_MAX_ADC && raw > MOIST_SENSOR_MIN_ADC){ this->moistureRaw.add(raw); } @@ -73,6 +80,25 @@ void Plant::postMQTTconnection(void) const String OFF = String("OFF"); this->mConnected = true; this->mPlant->setProperty("switch").send(OFF); + + long raw = getCurrentMoisture(); + double pct = 100 - mapf(raw, MOIST_SENSOR_MIN_ADC, MOIST_SENSOR_MAX_ADC, 0, 100); + if (equalish(raw, MISSING_SENSOR)) + { + pct = 0; + } + if (pct < 0) + { + pct = 0; + } + if (pct > 100) + { + pct = 100; + } + + this->mPlant->setProperty("moist").send(String(round(pct*10)/10)); + this->mPlant->setProperty("moistraw").send(String(raw)); + } void Plant::deactivatePump(void) diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index 57d1662..a85835f 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -260,7 +260,7 @@ void readOneWireSensors() void readPowerSwitchedSensors() { digitalWrite(OUTPUT_ENABLE_SENSOR, HIGH); - delay(10); + delay(500); for (int i = 0; i < MAX_PLANTS; i++) { mPlants[i].clearMoisture(); @@ -272,7 +272,7 @@ void readPowerSwitchedSensors() { mPlants[i].addSenseValue(); } - delay(2); + delay(20); } waterRawSensor.clear(); @@ -372,10 +372,6 @@ void onHomieEvent(const HomieEvent &event) configTime(0, 0, ntpServer.get()); - for (int i = 0; i < MAX_PLANTS; i++) - { - mPlants[i].postMQTTconnection(); - } { getTopic(TEST_TOPIC, testopic) Homie.getMqttClient() @@ -436,7 +432,7 @@ int determineNextPump() log(LOG_LEVEL_DEBUG, String(String(i) + " No pump required: due to light"), LOG_DEBUG_CODE); continue; } - if (plant.getCurrentMoisture() == MISSING_SENSOR) + if (equalish(plant.getCurrentMoisture(),MISSING_SENSOR)) { plant.publishState("nosensor"); log(LOG_LEVEL_ERROR, String(String(i) + " No pump possible: missing sensor"), LOG_MISSING_PUMP); @@ -599,8 +595,7 @@ void setup() // Set default values //in seconds - deepSleepTime.setDefaultValue(600).setValidator([](long candidate) - { return (candidate > 0) && (candidate < (60 * 60 * 2) /** 2h max sleep */); }); + deepSleepTime.setDefaultValue(600).setValidator([](long candidate) { return (candidate > 0) && (candidate < (60 * 60 * 2) /** 2h max sleep */); }); deepSleepNightTime.setDefaultValue(600); wateringDeepSleep.setDefaultValue(5); ntpServer.setDefaultValue("pool.ntp.org"); @@ -764,29 +759,16 @@ void plantcontrol() Serial << "Plant" << lastPumpRunning << ": Water diff " << waterDiff << " mm" << endl; } - readOneWireSensors(); - - for (int i = 0; i < MAX_PLANTS; i++) + if (mAliveWasRead) { - long raw = mPlants[i].getCurrentMoisture(); - long pct = 100 - map(raw, MOIST_SENSOR_MIN_ADC, MOIST_SENSOR_MAX_ADC, 0, 100); - if (raw == MISSING_SENSOR) + for (int i = 0; i < MAX_PLANTS; i++) { - pct = 0; + mPlants[i].postMQTTconnection(); } - if (pct < 0) - { - pct = 0; - } - if (pct > 100) - { - pct = 100; - } - - mPlants[i].setProperty("moist").send(String(pct)); - mPlants[i].setProperty("moistraw").send(String(raw)); } + readOneWireSensors(); + Serial << "W : " << waterRawSensor.getAverage() << " cm (" << String(waterLevelMax.get() - waterRawSensor.getAverage()) << "%)" << endl; lastWaterValue = waterRawSensor.getAverage();