diff --git a/esp32/include/ControllerConfiguration.h b/esp32/include/ControllerConfiguration.h index 3b036df..0085256 100644 --- a/esp32/include/ControllerConfiguration.h +++ b/esp32/include/ControllerConfiguration.h @@ -46,7 +46,6 @@ #define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */ #define MAX_PLANTS 7 -#define EMPTY_LIPO_MULTIPL 3 /**< Multiplier to increase time for sleeping when lipo is empty */ #define MINIMUM_LIPO_VOLT 3.6f /**< Minimum voltage of the Lipo, that must be present */ #define NO_LIPO_VOLT 2.0f /**< No Lipo connected */ #define MINIMUM_SOLAR_VOLT 4.0f /**< Minimum voltage of the sun, to detect daylight */ @@ -59,6 +58,7 @@ #define MAX_CONFIG_SETTING_ITEMS 50 /**< Parameter, that can be configured in Homie */ -#define PANIK_MODE_DEEPSLEEP 18000000000U /**< 5 hours in usecond */ +#define PANIK_MODE_DEEPSLEEP (60*60*5U) /**< 5 hours in usecond */ +#define PANIK_MODE_DEEPSLEEP_US (PANIK_MODE_DEEPSLEEP*1000*1000) #endif diff --git a/esp32/include/HomieConfiguration.h b/esp32/include/HomieConfiguration.h index 510dd47..9146754 100644 --- a/esp32/include/HomieConfiguration.h +++ b/esp32/include/HomieConfiguration.h @@ -37,7 +37,6 @@ HomieNode stayAlive("stay", "alive", "alive"); /** *********************************** Settings ******************************* */ - HomieSetting deepSleepTime("deepsleep", "time in milliseconds to sleep (0 deactivats it)"); HomieSetting deepSleepNightTime("nightsleep", "time in milliseconds to sleep (0 uses same setting: deepsleep at night, too)"); HomieSetting wateringDeepSleep("pumpdeepsleep", "time seconds to sleep, while a pump is running"); diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index fcc60ad..1162215 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -29,6 +29,7 @@ const unsigned long TEMPREADCYCLE = 30000; /**< Check temperature all half minut /********************* non volatile enable after deepsleep *******************************/ +RTC_DATA_ATTR long gotoMode2AfterThisTimestamp = 0; RTC_DATA_ATTR long rtcDeepSleepTime = 0; /**< Time, when the microcontroller shall be up again */ RTC_DATA_ATTR long rtcLastActive0 = 0; RTC_DATA_ATTR long rtcMoistureTrigger0 = 0; /**= (MIN_TIME_RUNNING * MS_TO_S)) && (deepSleepTime.get() > 0)) { - Serial << "No W" << endl; - /* in 500 microseconds */ - wait4sleep.in(500, prepareSleep); - return; - } - } sensorLipo.setProperty("percent").send( String(100 * lipoRawSensor.getAverage() / 4095) ); sensorLipo.setProperty("volt").send( String(ADC_5V_TO_3V3(lipoRawSensor.getAverage())) ); @@ -157,20 +166,37 @@ void mode2MQTT(){ bool lipoTempWarning = abs(temp[0] - temp[1]) > 5; if(lipoTempWarning){ - wait4sleep.in(500, prepareSleep); + Serial.println("Lipo temp incorrect, panic mode deepsleep"); + espDeepSleepFor(PANIK_MODE_DEEPSLEEP); return; } - digitalWrite(OUTPUT_PUMP, LOW); - for(int i=0; i < MAX_PLANTS; i++) { - digitalWrite(mPlants[i].mPinPump, LOW); - } + bool hasWater = mWaterGone > waterLevelMin.get(); + //FIXME no water warning message lastPumpRunning = determineNextPump(); - if(lastPumpRunning != -1){ + if(lastPumpRunning != -1 && hasWater){ setLastActivationForPump(lastPumpRunning, getCurrentTime()); digitalWrite(mPlants[lastPumpRunning].mPinPump, HIGH); } + float solarValue = solarRawSensor.getMedian(); + if(lastPumpRunning == -1 || !hasWater){ + if((ADC_5V_TO_3V3(solarValue) < SOLAR_CHARGE_MIN_VOLTAGE)){ + gotoMode2AfterThisTimestamp = getCurrentTime()+deepSleepNightTime.get(); + Serial.println("No pumps to activate and low light, deepSleepNight"); + espDeepSleepFor(deepSleepNightTime.get()); + }else { + gotoMode2AfterThisTimestamp = getCurrentTime()+deepSleepTime.get(); + Serial.println("No pumps to activate, deepSleep"); + espDeepSleepFor(deepSleepTime.get()); + } + + }else { + gotoMode2AfterThisTimestamp = 0; + Serial.println("Running pump, watering deepsleep"); + espDeepSleepFor(wateringDeepSleep.get()); + } + } void setMoistureTrigger(int plantId, long value){ @@ -316,6 +342,8 @@ void onHomieEvent(const HomieEvent& event) { //wait for rtc sync? rtcDeepSleepTime = deepSleepTime.get(); Serial << rtcDeepSleepTime << " ms ds" << endl; + + //saveguard, should be overriden in mode2MQTT normally esp_sleep_enable_timer_wakeup( (rtcDeepSleepTime * 1000U) ); mode2MQTT(); @@ -341,6 +369,8 @@ void onHomieEvent(const HomieEvent& event) { case HomieEventType::OTA_SUCCESSFUL: digitalWrite(OUTPUT_SENSOR, LOW); break; + default: + break; } } @@ -358,7 +388,7 @@ int determineNextPump(){ long lastActivation = getLastActivationForPump(i); long sinceLastActivation = getCurrentTime()-lastActivation; //this pump is in cooldown skip it and disable low power mode trigger for it - if(mPlants[i].mSetting->pPumpCooldownInHours->get() > sinceLastActivation / 3600 / 1000){ + if(mPlants[i].mSetting->pPumpCooldownInHours->get() > sinceLastActivation / 3600){ setMoistureTrigger(i, DEACTIVATED_PLANT); continue; } @@ -480,9 +510,12 @@ void systemInit(){ Homie_setFirmware("PlantControl", FIRMWARE_VERSION); // Set default values - deepSleepTime.setDefaultValue(30000); /* 30 seconds in milliseconds */ - deepSleepNightTime.setDefaultValue(0); - wateringDeepSleep.setDefaultValue(60000); /* 1 minute in milliseconds */ + + //in seconds + deepSleepTime.setDefaultValue(10); + deepSleepNightTime.setDefaultValue(30); + wateringDeepSleep.setDefaultValue(5); + waterLevelMax.setDefaultValue(1000); /* 100cm in mm */ waterLevelMin.setDefaultValue(50); /* 5cm in mm */ waterLevelWarn.setDefaultValue(500); /* 50cm in mm */ @@ -560,10 +593,11 @@ void systemInit(){ bool mode1(){ Serial.println("m1"); + Serial << getCurrentTime() << " curtime" << endl; - struct timeval tv_now; - gettimeofday(&tv_now, NULL); - Serial << tv_now.tv_sec << " curtime" << endl; + if(rtcDeepSleepTime > 0){ + esp_sleep_enable_timer_wakeup( (rtcDeepSleepTime * 1000U) ); + } readSensors(); //queue sensor values for @@ -612,7 +646,16 @@ bool mode1(){ } //check how long it was already in mode1 if to long goto mode2 - //TODO evaluate if something is to do + long cTime = getCurrentTime(); + if(cTime < 100000){ + Serial.println("Starting mode 2 due to missing ntp"); + //missing ntp time boot to mode3 + return true; + } + if(gotoMode2AfterThisTimestamp < cTime){ + Serial.println("Starting mode 2 after specified mode1 time"); + return true; + } return false; } @@ -667,19 +710,11 @@ void setup() { // Big TODO use here the settings in RTC_Memory //Panik mode, the Lipo is empty, sleep a long long time: - if ( SOLAR_VOLT(solarRawSensor.getAverage()) < MINIMUM_SOLAR_VOLT) { - Serial << deepSleepNightTime.get() << "ms ds " << SOLAR_VOLT(solarRawSensor.getAverage()) << "V" << endl; - esp_sleep_enable_timer_wakeup(PANIK_MODE_DEEPSLEEP); - } - - if (mConfigured && - (ADC_5V_TO_3V3(lipoRawSensor.getAverage()) < MINIMUM_LIPO_VOLT) && - (ADC_5V_TO_3V3(lipoRawSensor.getAverage()) > NO_LIPO_VOLT) && - (deepSleepTime.get()) ) { - long sleepEmptyLipo = (deepSleepTime.get() * EMPTY_LIPO_MULTIPL); - Serial << sleepEmptyLipo << " ms lipo " << ADC_5V_TO_3V3(lipoRawSensor.getAverage()) << "V" << endl; - esp_sleep_enable_timer_wakeup(sleepEmptyLipo * 1000U); - mDeepSleep = true; + if ((ADC_5V_TO_3V3(lipoRawSensor.getAverage()) < MINIMUM_LIPO_VOLT) && + (ADC_5V_TO_3V3(lipoRawSensor.getAverage()) > NO_LIPO_VOLT)) { + Serial << PANIK_MODE_DEEPSLEEP << " s lipo " << ADC_5V_TO_3V3(lipoRawSensor.getAverage()) << "V" << endl; + esp_sleep_enable_timer_wakeup(PANIK_MODE_DEEPSLEEP_US); + esp_deep_sleep_start(); } if(mode1()){