removed mode1, reduced redundant bus resets, removed multiple deep sleep paths

This commit is contained in:
Empire 2021-02-26 09:33:16 +01:00
parent fcdcfe2720
commit 552c27632b
2 changed files with 101 additions and 381 deletions

View File

@ -82,13 +82,12 @@
#define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */ #define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */
#define MAX_PLANTS 7 #define MAX_PLANTS 7
#define MINIMUM_LIPO_VOLT 3.6f /**< Minimum voltage of the Lipo, that must be present */ #define MINIMUM_LIPO_VOLT 3.2f /**< Minimum voltage of the Lipo, that must be present */
#define NO_LIPO_VOLT 2.0f /**< No Lipo connected */ #define NO_LIPO_VOLT 2.0f /**< No Lipo connected */
#define MINIMUM_SOLAR_VOLT 4.0f /**< Minimum voltage of the sun, to detect daylight */ #define MINIMUM_SOLAR_VOLT 4.0f /**< Minimum voltage of the sun, to detect daylight */
#define SOLAR_CHARGE_MIN_VOLTAGE 7 /**< Sun is rising (morning detected) */ #define SOLAR_CHARGE_MIN_VOLTAGE 7 /**< Sun is rising (morning detected) */
#define SOLAR_CHARGE_MAX_VOLTAGE 9 /**< Sun is shining (noon) */ #define SOLAR_CHARGE_MAX_VOLTAGE 9 /**< Sun is shining (noon) */
#define VOLT_MAX_BATT 4.2f #define VOLT_MAX_BATT 4.2f
#define VOLT_MAX_SOLAR 20.0f
#define MAX_CONFIG_SETTING_ITEMS 50 /**< Parameter, that can be configured in Homie */ #define MAX_CONFIG_SETTING_ITEMS 50 /**< Parameter, that can be configured in Homie */

View File

@ -31,61 +31,38 @@
* DEFINES * DEFINES
******************************************************************************/ ******************************************************************************/
#define AMOUNT_SENOR_QUERYS 8 #define AMOUNT_SENOR_QUERYS 8
#define SENSOR_QUERY_SHIFTS 3
#define SOLAR4SENSORS 6.0f
#define TEMP_INIT_VALUE -999.0f
#define TEMP_MAX_VALUE 85.0f
#define HalfHour 60
/******************************************************************************
* TYPE DEFS
******************************************************************************/
typedef struct
{
long lastActive; /**< Timestamp, a pump was activated */
long moistTrigger; /**< Trigger value of the moist sensor */
long moisture; /**< last measured moist value */
} rtc_plant_t;
/****************************************************************************** /******************************************************************************
* FUNCTION PROTOTYPES * FUNCTION PROTOTYPES
******************************************************************************/ ******************************************************************************/
int determineNextPump(); int determineNextPump();
void setLastActivationForPump(int pumpId, long time); //void setLastActivationForPump(int pumpId, long time);
int readTemp(); int readTemp();
/****************************************************************************** /******************************************************************************
* NON VOLATILE VARIABLES in DEEP SLEEP * NON VOLATILE VARIABLES in DEEP SLEEP
******************************************************************************/ ******************************************************************************/
RTC_DATA_ATTR rtc_plant_t rtcPlant[MAX_PLANTS]; //only relevant if mode2 did start pumping before
RTC_DATA_ATTR long gotoMode2AfterThisTimestamp = 0;
RTC_DATA_ATTR long rtcDeepSleepTime = 0; /**< Time, when the microcontroller shall be up again */
RTC_DATA_ATTR int lastPumpRunning = 0; RTC_DATA_ATTR int lastPumpRunning = 0;
RTC_DATA_ATTR long lastWaterValue = 0; RTC_DATA_ATTR long lastWaterValue = 0;
RTC_DATA_ATTR float rtcLastLipoTemp = 0.0f;
RTC_DATA_ATTR float rtcLastWaterTemp = 0.0f;
RTC_DATA_ATTR float rtcLastBatteryVoltage = 0.0f;
RTC_DATA_ATTR float rtcLastSolarVoltage = 0.0f;
RTC_DATA_ATTR int gBootCount = 0; RTC_DATA_ATTR int gBootCount = 0;
RTC_DATA_ATTR int gCurrentPlant = 0; /**< Value Range: 1 ... 7 (0: no plant needs water) */
RTC_DATA_ATTR int rtcLipoTempIndex = 0; //FIXME use -1 and configure properly //FIXME use -1 and configure properly
RTC_DATA_ATTR int rtcLipoTempIndex = 0;
RTC_DATA_ATTR int rtcWaterTempIndex = -1; RTC_DATA_ATTR int rtcWaterTempIndex = -1;
/****************************************************************************** /******************************************************************************
* LOCAL VARIABLES * LOCAL VARIABLES
******************************************************************************/ ******************************************************************************/
const unsigned long TEMPREADCYCLE = 30000; /**< Check temperature all half minutes */
int wakeUpReason = WAKEUP_REASON_UNDEFINED;
bool volatile mode3Active = false; /**< Controller must not sleep */ bool volatile mode3Active = false; /**< Controller must not sleep */
bool volatile mDeepsleep = false; bool volatile mDeepsleep = false;
int readCounter = 0; int readCounter = 0;
bool mConfigured = false; bool mConfigured = false;
long nextBlink = 0; /**< Time needed in main loop to support expected blink code */ long nextBlink = 0; /**< Time needed in main loop to support expected blink code */
RunningMedian waterRawSensor = RunningMedian(5); RunningMedian waterRawSensor = RunningMedian(5);
float mTempLipo = 0.0f; float mTempLipo = 0.0f;
@ -98,7 +75,7 @@ float mChipTemp = 0.0f;
OneWire oneWire(SENSOR_DS18B20); OneWire oneWire(SENSOR_DS18B20);
DallasTemperature sensors(&oneWire); DallasTemperature sensors(&oneWire);
DS2438 battery(&oneWire,0.1f); DS2438 battery(&oneWire, 0.1f);
Plant mPlants[MAX_PLANTS] = { Plant mPlants[MAX_PLANTS] = {
Plant(SENSOR_PLANT0, OUTPUT_PUMP0, 0, &plant0, &mSetting0), Plant(SENSOR_PLANT0, OUTPUT_PUMP0, 0, &plant0, &mSetting0),
@ -112,35 +89,6 @@ Plant mPlants[MAX_PLANTS] = {
/****************************************************************************** /******************************************************************************
* LOCAL FUNCTIONS * LOCAL FUNCTIONS
******************************************************************************/ ******************************************************************************/
void setMoistureTrigger(int plantId, long value)
{
if ((plantId >= 0) && (plantId < MAX_PLANTS))
{
rtcPlant[plantId].moistTrigger = value;
}
}
void setLastMoisture(int plantId, long value)
{
if ((plantId >= 0) && (plantId < MAX_PLANTS))
{
rtcPlant[plantId].moisture = value;
}
}
long getLastMoisture(int plantId)
{
if ((plantId >= 0) && (plantId < MAX_PLANTS))
{
return rtcPlant[plantId].moisture;
}
else
{
return -1;
}
}
long getDistance() long getDistance()
{ {
byte startByte, h_data, l_data, sum; byte startByte, h_data, l_data, sum;
@ -170,49 +118,6 @@ long getDistance()
} }
} }
/**
* @brief Read Voltage and Temperatur
* Read the battery voltage and the current voltage, provided by the solar panel
*/
void readSystemSensors()
{
int timeoutTemp = millis() + TEMPERATUR_TIMEOUT;
int sensorCount = 0;
/* Required to read the temperature at least once */
while (sensorCount == 0 && millis() < timeoutTemp)
{
sensors.begin();
battery.begin();
sensorCount = sensors.getDS18Count();
Serial << "Waitloop: One wire count: " << sensorCount << endl;
delay(200);
}
Serial << "One wire count: " << sensorCount << endl;
/* Measure temperature */
if (sensorCount > 0)
{
sensors.requestTemperatures();
}
for (int i = 0; i < sensorCount; i++)
{
Serial << "OneWire sensor " << i << " has value " << sensors.getTempCByIndex(i) << endl;
}
// Update battery chip data
battery.update();
mSolarVoltage = battery.getVoltage(BATTSENSOR_INDEX_SOLAR) * SOLAR_VOLT_FACTOR;
mBatteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY);
mChipTemp = battery.getTemperature();
rtcLastBatteryVoltage = mBatteryVoltage;
rtcLastSolarVoltage = mSolarVoltage;
rtcLastLipoTemp = mTempLipo;
rtcLastWaterTemp = mTempWater;
}
long getCurrentTime() long getCurrentTime()
{ {
struct timeval tv_now; struct timeval tv_now;
@ -242,16 +147,17 @@ void espDeepSleepFor(long seconds, bool activatePump = false)
} }
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON); esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON);
if (activatePump) if (activatePump)
{ {
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
gpio_deep_sleep_hold_en(); gpio_deep_sleep_hold_en();
gpio_hold_en(GPIO_NUM_13); //pump pwr gpio_hold_en(GPIO_NUM_13); //pump pwr
} }
else else
{ {
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
gpio_hold_dis(GPIO_NUM_13); //pump pwr gpio_hold_dis(GPIO_NUM_13); //pump pwr
gpio_deep_sleep_hold_dis(); gpio_deep_sleep_hold_dis();
digitalWrite(OUTPUT_PUMP, LOW); digitalWrite(OUTPUT_PUMP, LOW);
@ -268,28 +174,21 @@ void espDeepSleepFor(long seconds, bool activatePump = false)
Serial.print(seconds); Serial.print(seconds);
Serial.println(" seconds"); Serial.println(" seconds");
esp_sleep_enable_timer_wakeup((seconds * 1000U * 1000U)); esp_sleep_enable_timer_wakeup((seconds * 1000U * 1000U));
mDeepsleep = true; mDeepsleep = true;
} }
void mode2MQTT() void mode2MQTT()
{ {
readSystemSensors();
digitalWrite(OUTPUT_PUMP, LOW); digitalWrite(OUTPUT_PUMP, LOW);
for (int i = 0; i < MAX_PLANTS; i++) for (int i = 0; i < MAX_PLANTS; i++)
{ {
mPlants[i].deactivatePump(); mPlants[i].deactivatePump();
} }
if (deepSleepTime.get())
{
Serial << "deepsleep time is configured to " << deepSleepTime.get() << endl;
}
/* Publish default values */
if (lastPumpRunning != -1) if (lastPumpRunning != -1)
{ {
long waterDiff = waterRawSensor.getAverage() - lastWaterValue; //long waterDiff = waterRawSensor.getAverage() - lastWaterValue;
//TODO attribute used water in ml to plantid //TODO attribute used water in ml to plantid
} }
for (int i = 0; i < MAX_PLANTS; i++) for (int i = 0; i < MAX_PLANTS; i++)
@ -318,18 +217,16 @@ void mode2MQTT()
sensorLipo.setProperty("percent").send(String(100 * mBatteryVoltage / VOLT_MAX_BATT)); sensorLipo.setProperty("percent").send(String(100 * mBatteryVoltage / VOLT_MAX_BATT));
sensorLipo.setProperty("volt").send(String(mBatteryVoltage)); sensorLipo.setProperty("volt").send(String(mBatteryVoltage));
sensorLipo.setProperty("current").send(String(battery.getCurrent()));
sensorLipo.setProperty("Ah").send(String(battery.getAh())); sensorLipo.setProperty("Ah").send(String(battery.getAh()));
sensorLipo.setProperty("ICA").send(String(battery.getICA())); sensorLipo.setProperty("ICA").send(String(battery.getICA()));
sensorLipo.setProperty("DCA").send(String(battery.getDCA())); sensorLipo.setProperty("DCA").send(String(battery.getDCA()));
sensorLipo.setProperty("CCA").send(String(battery.getCCA())); sensorLipo.setProperty("CCA").send(String(battery.getCCA()));
sensorSolar.setProperty("percent").send(String(100 * mSolarVoltage / VOLT_MAX_SOLAR));
sensorSolar.setProperty("volt").send(String(mSolarVoltage)); sensorSolar.setProperty("volt").send(String(mSolarVoltage));
startupReason.setProperty("startupReason").send(String(wakeUpReason));
rtcLipoTempIndex = lipoSensorIndex.get(); rtcLipoTempIndex = lipoSensorIndex.get();
rtcWaterTempIndex = waterSensorIndex.get(); rtcWaterTempIndex = waterSensorIndex.get();
sensorTemp.setProperty(TEMPERATUR_SENSOR_LIPO).send(String(mTempLipo)); sensorTemp.setProperty(TEMPERATUR_SENSOR_LIPO).send(String(mTempLipo));
Serial << "Lipo Temperatur " << mTempLipo << " °C " << endl; Serial << "Lipo Temperatur " << mTempLipo << " °C " << endl;
@ -339,11 +236,6 @@ void mode2MQTT()
sensorTemp.setProperty(TEMPERATUR_SENSOR_CHIP).send(String(mChipTemp)); sensorTemp.setProperty(TEMPERATUR_SENSOR_CHIP).send(String(mChipTemp));
Serial << "Chip Temperatur " << mChipTemp << " °C " << endl; Serial << "Chip Temperatur " << mChipTemp << " °C " << endl;
for (int i = 0; i < MAX_PLANTS; i++)
{
setMoistureTrigger(i, mPlants[i].mSetting->pSensorDry->get());
}
bool hasWater = true; //FIXMEmWaterGone > waterLevelMin.get(); bool hasWater = true; //FIXMEmWaterGone > waterLevelMin.get();
//FIXME no water warning message //FIXME no water warning message
lastPumpRunning = determineNextPump(); lastPumpRunning = determineNextPump();
@ -360,68 +252,32 @@ void mode2MQTT()
else else
{ {
digitalWrite(OUTPUT_PUMP, HIGH); digitalWrite(OUTPUT_PUMP, HIGH);
setLastActivationForPump(lastPumpRunning, getCurrentTime()); //TODO setLastActivationForPump(lastPumpRunning, getCurrentTime());
mPlants[lastPumpRunning].activatePump(); mPlants[lastPumpRunning].activatePump();
} }
} }
if (lastPumpRunning == -1 || !hasWater) if (lastPumpRunning == -1 || !hasWater)
{ {
if (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE) if (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE)
{ {
gotoMode2AfterThisTimestamp = getCurrentTime() + maxTimeBetweenMQTTUpdates.get();
Serial.print(mSolarVoltage); Serial.print(mSolarVoltage);
Serial.println("V! No pumps to activate and low light, deepSleepNight"); Serial.println("V! No pumps to activate and low light, deepSleepNight");
espDeepSleepFor(deepSleepNightTime.get()); espDeepSleepFor(deepSleepNightTime.get());
rtcDeepSleepTime = deepSleepNightTime.get();
} }
else else
{ {
gotoMode2AfterThisTimestamp = getCurrentTime() + maxTimeBetweenMQTTUpdates.get();
Serial.println("No pumps to activate, deepSleep"); Serial.println("No pumps to activate, deepSleep");
espDeepSleepFor(deepSleepTime.get()); espDeepSleepFor(deepSleepTime.get());
rtcDeepSleepTime = deepSleepTime.get();
} }
} }
else else
{ {
gotoMode2AfterThisTimestamp = 0;
Serial.println("Running pump, watering deepsleep"); Serial.println("Running pump, watering deepsleep");
espDeepSleepFor(wateringDeepSleep.get(), true); espDeepSleepFor(wateringDeepSleep.get(), true);
} }
} }
long getMoistureTrigger(int plantId)
{
if ((plantId >= 0) && (plantId < MAX_PLANTS))
{
return rtcPlant[plantId].moistTrigger;
}
else
{
return -1;
}
}
void setLastActivationForPump(int plantId, long value)
{
if ((plantId >= 0) && (plantId < MAX_PLANTS))
{
rtcPlant[plantId].lastActive = value;
}
}
long getLastActivationForPump(int plantId)
{
if ((plantId >= 0) && (plantId < MAX_PLANTS))
{
return rtcPlant[plantId].lastActive;
}
else
{
return -1;
}
}
/** /**
* @brief Read ultra sensor JSN-SR04T-2.0 * @brief Read ultra sensor JSN-SR04T-2.0
* Read the distance of the water level. * Read the distance of the water level.
@ -448,70 +304,57 @@ void readDistance()
} }
} }
/**
* @brief read all temperatur sensors
*
* @return int
* <code>0</code> device can sleep, no change in the temperatures
* <code>1</code> something changed and the temperatures shall be published via MQTT
*/
int readTemp() {
int readAgain = TEMP_SENSOR_MEASURE_SERIES;
int sensorCount = sensors.getDS18Count();
int leaveMode1 = 0;
while (readAgain > 0)
{
sensors.requestTemperatures();
if (sensorCount > 0)
{
if (rtcLipoTempIndex != -1)
{
mTempLipo = sensors.getTempCByIndex(rtcLipoTempIndex);
}
else
{
Serial << "missing lipotemp, proceed to mode2: " << endl;
leaveMode1 = 1;
readAgain = 0;
wakeUpReason = WAKEUP_REASON_RTC_MISSING;
}
} else {
Serial << "No Sensors detected" << endl;
return 1;
}
if (sensorCount > 1 && rtcWaterTempIndex != -1)
{
mTempWater = sensors.getTempCByIndex(rtcWaterTempIndex);
//Serial << "waterTempCurrent: " << temp2Raw << endl;
}
readAgain--;
delay(50);
}
return leaveMode1;
}
/** /**
* @brief Sensors, that are connected to GPIOs, mandatory for WIFI. * @brief Sensors, that are connected to GPIOs, mandatory for WIFI.
* These sensors (ADC2) can only be read when no Wifi is used. * These sensors (ADC2) can only be read when no Wifi is used.
*/ */
bool readSensors() void readSensors()
{ {
bool leaveMode1 = false;
Serial << "Read Sensors" << endl; Serial << "Read Sensors" << endl;
/* activate all sensors */
readSystemSensors();
/* activate all sensors */
pinMode(OUTPUT_SENSOR, OUTPUT);
digitalWrite(OUTPUT_SENSOR, HIGH); digitalWrite(OUTPUT_SENSOR, HIGH);
delay(20);
sensors.begin();
/* wait before reading something */ /* wait before reading something */
delay(20);
int timeoutTemp = millis() + TEMPERATUR_TIMEOUT;
int sensorCount = 0;
/* Required to read the temperature at least once */
while ((sensorCount == 0 || !battery.isFound()) && millis() < timeoutTemp)
{
sensors.begin();
battery.begin();
sensorCount = sensors.getDS18Count();
delay(50);
}
Serial << "One wire count: " << sensorCount << " found in " << (millis() - timeoutTemp) << "ms" << endl;
/* Measure temperature */
if (sensorCount > 0)
{
sensors.requestTemperatures();
}
for (int i = 0; i < sensorCount; i++) {
float temp = sensors.getTempCByIndex(i);
Serial << "OneWire sensor " << i << " has value " << temp << endl;
if (rtcWaterTempIndex != -1 && rtcWaterTempIndex == i) {
mTempWater = temp;
}
if (rtcLipoTempIndex != -1 && rtcLipoTempIndex == i) {
mTempLipo = temp;
}
}
// Update battery chip data
battery.update();
mSolarVoltage = battery.getVoltage(BATTSENSOR_INDEX_SOLAR) * SOLAR_VOLT_FACTOR;
mBatteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY);
mChipTemp = battery.getTemperature();
// if(mBatteryVoltage < MINIMUM_LIPO_VOLT){
// Serial.println("Low lipo voltage, abort high level processing");
// }
for (int readCnt = 0; readCnt < AMOUNT_SENOR_QUERYS; readCnt++) for (int readCnt = 0; readCnt < AMOUNT_SENOR_QUERYS; readCnt++)
{ {
for (int i = 0; i < MAX_PLANTS; i++) for (int i = 0; i < MAX_PLANTS; i++)
@ -521,52 +364,12 @@ bool readSensors()
delay(10); delay(10);
} }
for (int i = 0; i < MAX_PLANTS; i++)
{
long current = mPlants[i].getCurrentMoisture();
long delta = abs(getLastMoisture(i) - current);
bool tmp = (delta > MOIST_DELTA_TRIGGER_ADC);
setLastMoisture(i, current);
if (tmp)
{
wakeUpReason = WAKEUP_REASON_MOIST_CHANGE + i;
leaveMode1 = true;
Serial.printf("Mode2 start due to moist delta in plant %d with %ld \r\n", i, delta);
}
}
if (abs(mBatteryVoltage - rtcLastBatteryVoltage) > LIPO_DELTA_VOLT_ADC)
{
wakeUpReason = WAKEUP_REASON_BATTERY_CHANGE;
leaveMode1 = true;
}
if (abs(mSolarVoltage - rtcLastSolarVoltage) > SOLAR_DELTA_VOLT_ADC)
{
wakeUpReason = WAKEUP_REASON_SOLAR_CHANGE;
leaveMode1 = true;
}
/* Read the distance and give the temperature sensors some time */ /* Read the distance and give the temperature sensors some time */
readDistance(); readDistance();
Serial << "Distance sensor " << waterRawSensor.getAverage() << " cm" << endl; Serial << "Distance sensor " << waterRawSensor.getAverage() << " cm" << endl;
// check if chip needs to start into full operational mode
leaveMode1 |= readTemp();
if (abs(mTempWater - rtcLastLipoTemp) > TEMPERATURE_DELTA_TRIGGER_IN_C)
{
leaveMode1 = true;
wakeUpReason = WAKEUP_REASON_TEMP1_CHANGE;
}
if (abs(mTempWater - rtcLastWaterTemp) > TEMPERATURE_DELTA_TRIGGER_IN_C)
{
wakeUpReason = WAKEUP_REASON_TEMP2_CHANGE;
leaveMode1 = true;
}
/* deactivate the sensors */ /* deactivate the sensors */
digitalWrite(OUTPUT_SENSOR, LOW); digitalWrite(OUTPUT_SENSOR, LOW);
return leaveMode1;
} }
void onHomieEvent(const HomieEvent &event) void onHomieEvent(const HomieEvent &event)
@ -579,8 +382,7 @@ void onHomieEvent(const HomieEvent &event)
case HomieEventType::MQTT_READY: case HomieEventType::MQTT_READY:
Serial.printf("NTP Setup with server %s\r\n", ntpServer.get()); Serial.printf("NTP Setup with server %s\r\n", ntpServer.get());
configTime(0, 0, ntpServer.get()); configTime(0, 0, ntpServer.get());
//wait for rtc sync?
rtcDeepSleepTime = deepSleepTime.get();
Serial << "Setup plants" << endl; Serial << "Setup plants" << endl;
for (int i = 0; i < MAX_PLANTS; i++) for (int i = 0; i < MAX_PLANTS; i++)
{ {
@ -589,10 +391,6 @@ void onHomieEvent(const HomieEvent &event)
mode2MQTT(); mode2MQTT();
break; break;
case HomieEventType::READY_TO_SLEEP:
Homie.getLogger() << "rtsleep" << endl;
esp_deep_sleep_start();
break;
case HomieEventType::OTA_STARTED: case HomieEventType::OTA_STARTED:
Homie.getLogger() << "OTA started" << endl; Homie.getLogger() << "OTA started" << endl;
digitalWrite(OUTPUT_SENSOR, HIGH); digitalWrite(OUTPUT_SENSOR, HIGH);
@ -626,15 +424,12 @@ int determineNextPump()
for (int i = 0; i < MAX_PLANTS; i++) for (int i = 0; i < MAX_PLANTS; i++)
{ {
Plant plant = mPlants[i]; Plant plant = mPlants[i];
long lastActivation = getLastActivationForPump(i); //TODO skip pump last used here!
long sinceLastActivation = getCurrentTime() - lastActivation; //if (plant.isInCooldown(sinceLastActivation))
//this pump is in cooldown skip it and disable low power mode trigger for it //{
if (plant.isInCooldown(sinceLastActivation)) // Serial.printf("%d Skipping due to cooldown %ld / %ld \r\n", i, sinceLastActivation, plant.getCooldownInSeconds());
{ //continue;
Serial.printf("%d Skipping due to cooldown %ld / %ld \r\n", i, sinceLastActivation, plant.getCooldownInSeconds()); //}
setMoistureTrigger(i, DEACTIVATED_PLANT);
continue;
}
//skip as it is not low light //skip as it is not low light
if (!isLowLight && plant.isAllowedOnlyAtLowLight()) if (!isLowLight && plant.isAllowedOnlyAtLowLight())
{ {
@ -701,8 +496,8 @@ void systemInit()
//in seconds //in seconds
maxTimeBetweenMQTTUpdates.setDefaultValue(120); maxTimeBetweenMQTTUpdates.setDefaultValue(700);
deepSleepTime.setDefaultValue(60); deepSleepTime.setDefaultValue(600);
deepSleepNightTime.setDefaultValue(600); deepSleepNightTime.setDefaultValue(600);
wateringDeepSleep.setDefaultValue(5); wateringDeepSleep.setDefaultValue(5);
ntpServer.setDefaultValue("pool.ntp.org"); ntpServer.setDefaultValue("pool.ntp.org");
@ -761,74 +556,6 @@ void systemInit()
stayAlive.advertise("alive").setName("Alive").setDatatype(NUMBER_TYPE).settable(aliveHandler); stayAlive.advertise("alive").setName("Alive").setDatatype(NUMBER_TYPE).settable(aliveHandler);
} }
bool mode1()
{
Serial.println("==== Mode 1 ====");
Serial << getCurrentTime() << " curtime" << endl;
bool deltaTrigger = readSensors();
//queue sensor values for
if (deltaTrigger)
{
Serial.println("1 delta triggered, going to mode2");
return true;
}
if (rtcDeepSleepTime == 0)
{
wakeUpReason = WAKEUP_REASON_RTC_MISSING;
Serial.println("1 missing rtc value, going to mode2");
return true;
}
for (int i = 0; i < MAX_PLANTS; i++)
{
long trigger = getMoistureTrigger(i);
if (trigger == 0)
{
wakeUpReason = WAKEUP_REASON_RTC_MISSING;
Serial << "Missing rtc trigger " << i << endl;
return true;
}
if (trigger == DEACTIVATED_PLANT)
{
continue;
}
long raw = mPlants[i].getCurrentMoisture();
if (raw == MISSING_SENSOR)
{
continue;
}
if (raw > trigger)
{
Serial << "plant " << i << " dry " << raw << " / " << trigger << " starting mode 2" << endl;
wakeUpReason = WAKEUP_REASON_PLANT_DRY + i;
return true;
}
}
//check how long it was already in mode1 if to long goto mode2
long cTime = getCurrentTime();
if (cTime < 100000)
{
Serial.println("Starting mode 2 due to missing ntp");
//missing ntp time boot to mode3
wakeUpReason = WAKEUP_REASON_TIME_UNSET;
return true;
}
if (gotoMode2AfterThisTimestamp < cTime)
{
wakeUpReason = WAKEUP_REASON_MODE2_WAKEUP_TIMER;
Serial.println("Starting mode 2 after specified mode1 time");
return true;
}
else
{
Serial << "Mode2 Timer " << gotoMode2AfterThisTimestamp << " curtime " << cTime << endl;
}
return false;
}
void mode2() void mode2()
{ {
Serial.println("==== Mode 2 ===="); Serial.println("==== Mode 2 ====");
@ -849,7 +576,6 @@ void mode2()
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.setTimeout(1000); // Set timeout of 1 second
Serial << endl Serial << endl
<< endl; << endl;
/* Intialize Plant */ /* Intialize Plant */
@ -858,11 +584,14 @@ void setup()
mPlants[i].init(); mPlants[i].init();
} }
/* read button */ // read button
pinMode(BUTTON, INPUT); pinMode(BUTTON, INPUT);
/* Power pins */ // Power pins
pinMode(OUTPUT_PUMP, OUTPUT); pinMode(OUTPUT_PUMP, OUTPUT);
pinMode(OUTPUT_SENSOR, OUTPUT);
// Individual Pump pins
/* Disable Wifi and bluetooth */ /* Disable Wifi and bluetooth */
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
@ -873,30 +602,23 @@ void setup()
Serial << "Limits.hpp" << endl; Serial << "Limits.hpp" << endl;
} }
readSensors();
// Big TODO use here the settings in RTC_Memory // Big TODO use here the settings in RTC_Memory
//Panik mode, the Lipo is empty, sleep a long long time: //Panik mode, the Lipo is empty, sleep a long long time:
if ((mBatteryVoltage < MINIMUM_LIPO_VOLT) && // if ((mBatteryVoltage < MINIMUM_LIPO_VOLT) &&
(mBatteryVoltage > NO_LIPO_VOLT)) // (mBatteryVoltage > NO_LIPO_VOLT))
{ // {
Serial << PANIK_MODE_DEEPSLEEP << " s lipo " << mBatteryVoltage << "V" << endl; // Serial << PANIK_MODE_DEEPSLEEP << " s lipo " << mBatteryVoltage << "V" << endl;
esp_sleep_enable_timer_wakeup(PANIK_MODE_DEEPSLEEP_US); // esp_sleep_enable_timer_wakeup(PANIK_MODE_DEEPSLEEP_US);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); // esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF); // esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON); // esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF); // esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF);
esp_deep_sleep_start(); // esp_deep_sleep_start();
} // }
mode2();
if (mode1())
{
mode2();
}
else
{
Serial.println("nop");
espDeepSleepFor(rtcDeepSleepTime);
}
} }
/** /**
@ -905,7 +627,16 @@ void setup()
*/ */
void loop() void loop()
{ {
if (!mDeepsleep || mode3Active) /* Toggel Senor LED to visualize mode 3 */
if (mode3Active)
{
if (nextBlink < millis())
{
nextBlink = millis() + 500;
digitalWrite(OUTPUT_SENSOR, !digitalRead(OUTPUT_SENSOR));
}
}
else if (!mDeepsleep)
{ {
Homie.loop(); Homie.loop();
} }
@ -918,19 +649,9 @@ void loop()
if (millis() > 30000 && !mode3Active) if (millis() > 30000 && !mode3Active)
{ {
Serial << (millis() / 1000) << "not terminated watchdog putting to sleep" << endl; Serial << (millis() / 1000) << "not terminated watchdog reset" << endl;
Serial.flush(); Serial.flush();
espDeepSleepFor(rtcDeepSleepTime); esp_restart();
}
/* Toggel Senor LED to visualize mode 3 */
if (mode3Active)
{
if (nextBlink < millis())
{
nextBlink = millis() + 500;
digitalWrite(OUTPUT_SENSOR, !digitalRead(OUTPUT_SENSOR));
}
} }
} }