added timed light function
This commit is contained in:
parent
e927fc8c70
commit
f99f72b65a
@ -69,8 +69,12 @@
|
||||
#define SENSOR_TANK_ECHO GPIO_NUM_16 /**< GPIO 16 - echo feedback of water sensor */
|
||||
#define SENSOR_TANK_TRG GPIO_NUM_17 /**< GPIO 17 - trigger for water sensor */
|
||||
#define BUTTON GPIO_NUM_0 /**< GPIO 0 - Fix button of NodeMCU */
|
||||
#define CUSTOM1_PIN3 GPIO_NUM_2 /**< GPIO 2 - Custom GPIO controlling a MOSFET, connected to GND */
|
||||
#define CUSTOM1_PIN2 GPIO_NUM_12 /**< GPIO 4 - custom GPIO directly connected to GPIO header */
|
||||
|
||||
#define CUSTOM1_PIN1 GPIO_NUM_34 /** direct gpio */
|
||||
#define CUSTOM1_PIN3 GPIO_NUM_35 /** direct gpio */
|
||||
#define CUSTOM1_PIN5 GPIO_NUM_2 /** mosfet controlled */
|
||||
#define CUSTOM1_PIN7 GPIO_NUM_12 /** mosfet controlled */
|
||||
|
||||
#define I2C1_SDA GPIO_NUM_34 /**< GPIO 34 - I2C */
|
||||
#define I2C1_SCL GPIO_NUM_35 /**< GPIO 35 - I2C */
|
||||
/* @} */
|
||||
@ -80,6 +84,8 @@
|
||||
*/
|
||||
#define FIRMWARE_VERSION "sw 1.3 hw 0.10"
|
||||
|
||||
#define TIMED_LIGHT_PIN CUSTOM1_PIN5
|
||||
|
||||
#define MOIST_SENSOR_MAX_FRQ 60000 // 60kHz (500Hz margin)
|
||||
#define MOIST_SENSOR_MIN_FRQ 1000 // 1kHz (500Hz margin)
|
||||
|
||||
|
@ -51,6 +51,11 @@ HomieNode plant4("plant4", "Plant 4", "Plant"); /**< dynamic Homie information f
|
||||
HomieNode plant5("plant5", "Plant 5", "Plant"); /**< dynamic Homie information for sixth plant */
|
||||
HomieNode plant6("plant6", "Plant 6", "Plant"); /**< dynamic Homie information for seventh plant */
|
||||
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
HomieNode timedLightNode("timedLight", "TimedLight", "Status");
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
|
||||
HomieNode sensorLipo("lipo", "Battery Status", "Lipo");
|
||||
HomieNode sensorSolar("solar", "Solar Status", "Solarpanel");
|
||||
HomieNode sensorWater("water", "WaterSensor", "Water");
|
||||
@ -78,6 +83,14 @@ HomieSetting<const char *> lipoSensorAddr("lipoDSAddr", "1wire address for lipo
|
||||
HomieSetting<const char *> waterSensorAddr("tankDSAddr", "1wire address for water temperature sensor");
|
||||
HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as default)");
|
||||
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
HomieSetting<double> timedLightVoltageCutoff("LightVoltageCutoff", "voltage at wich to disable light");
|
||||
HomieSetting<long> timedLightStart("LightStart", "hour to start light");
|
||||
HomieSetting<long> timedLightEnd("LightEnd", "hour to end light");
|
||||
HomieSetting<bool> timedLightOnlyWhenDark("LightOnlyDark", "only enable light, if solar is low");
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "RunningMedian.h"
|
||||
#include "MathUtils.h"
|
||||
|
||||
#define MOISTURE_MEASUREMENT_DURATION 500 /** ms */
|
||||
#define MOISTURE_MEASUREMENT_DURATION 400 /** ms */
|
||||
|
||||
|
||||
class Plant
|
||||
|
@ -57,9 +57,10 @@
|
||||
******************************************************************************/
|
||||
|
||||
void log(int level, String message, int code);
|
||||
int determineNextPump();
|
||||
int determineNextPump(bool lowLight);
|
||||
void plantcontrol();
|
||||
void readPowerSwitchedSensors();
|
||||
bool determineTimedLightState(bool lowLight);
|
||||
|
||||
/******************************************************************************
|
||||
* NON VOLATILE VARIABLES in DEEP SLEEP
|
||||
@ -67,6 +68,10 @@ void readPowerSwitchedSensors();
|
||||
|
||||
RTC_DATA_ATTR int lastPumpRunning = -1; /**< store last successfully waterd plant */
|
||||
RTC_DATA_ATTR long lastWaterValue = 0; /**< to calculate the used water per plant */
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
RTC_DATA_ATTR bool timedLightOn = false; /**< allow fast recovery after poweron */
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
|
||||
RTC_DATA_ATTR long rtcLastWateringPlant[MAX_PLANTS] = {0};
|
||||
RTC_DATA_ATTR long consecutiveWateringPlant[MAX_PLANTS] = {0};
|
||||
@ -133,19 +138,21 @@ void espDeepSleepFor(long seconds, bool activatePump)
|
||||
}
|
||||
}
|
||||
|
||||
//allo hold for all digital pins
|
||||
gpio_deep_sleep_hold_en();
|
||||
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
|
||||
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)
|
||||
{
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
|
||||
gpio_deep_sleep_hold_en();
|
||||
|
||||
gpio_hold_en(OUTPUT_ENABLE_PUMP); //pump pwr
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_hold_dis(OUTPUT_ENABLE_PUMP); //pump pwr
|
||||
gpio_deep_sleep_hold_dis();
|
||||
digitalWrite(OUTPUT_ENABLE_PUMP, LOW);
|
||||
digitalWrite(OUTPUT_ENABLE_SENSOR, LOW);
|
||||
for (int i = 0; i < MAX_PLANTS; i++)
|
||||
@ -160,7 +167,10 @@ void espDeepSleepFor(long seconds, bool activatePump)
|
||||
gpio_hold_en(OUTPUT_PUMP4);
|
||||
gpio_hold_en(OUTPUT_PUMP5);
|
||||
gpio_hold_en(OUTPUT_PUMP6);
|
||||
//FIXME fix for outher outputs
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
gpio_hold_en(TIMED_LIGHT_PIN);
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
|
||||
esp_sleep_enable_timer_wakeup((seconds * 1000U * 1000U));
|
||||
if (mAliveWasRead)
|
||||
@ -410,9 +420,8 @@ void onHomieEvent(const HomieEvent &event)
|
||||
}
|
||||
}
|
||||
|
||||
int determineNextPump()
|
||||
int determineNextPump(bool isLowLight)
|
||||
{
|
||||
bool isLowLight = (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE);
|
||||
int pumpToUse = -1;
|
||||
for (int i = 0; i < MAX_PLANTS; i++)
|
||||
{
|
||||
@ -601,6 +610,13 @@ void setup()
|
||||
WiFi.mode(WIFI_OFF);
|
||||
Serial.flush();
|
||||
|
||||
//restore state before releasing pin, to prevent flickering
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
pinMode(TIMED_LIGHT_PIN, OUTPUT);
|
||||
digitalWrite(TIMED_LIGHT_PIN, timedLightOn);
|
||||
gpio_hold_dis(TIMED_LIGHT_PIN);
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
gpio_hold_dis(OUTPUT_PUMP0);
|
||||
gpio_hold_dis(OUTPUT_PUMP1);
|
||||
gpio_hold_dis(OUTPUT_PUMP2);
|
||||
@ -683,9 +699,20 @@ void setup()
|
||||
waterLevelVol.setDefaultValue(5000); /* 5l in ml */
|
||||
lipoSensorAddr.setDefaultValue("");
|
||||
waterSensorAddr.setDefaultValue("");
|
||||
pumpIneffectiveWarning.setDefaultValue(600).setValidator([](long candidate)
|
||||
pumpIneffectiveWarning.setDefaultValue(5).setValidator([](long candidate)
|
||||
{ return (candidate > 0) && (candidate < (20)); });
|
||||
pumpIneffectiveWarning.setDefaultValue(5);
|
||||
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
timedLightStart.setDefaultValue(18).setValidator([](long candidate)
|
||||
{ return (candidate > 0) && (candidate < (25)); });
|
||||
timedLightEnd.setDefaultValue(23).setValidator([](long candidate)
|
||||
{ return (candidate > 0) && (candidate < (22)); });
|
||||
timedLightOnlyWhenDark.setDefaultValue(true);
|
||||
timedLightVoltageCutoff.setDefaultValue(3.8).setValidator([](double candidate)
|
||||
{ return (candidate > 3.3) && (candidate < (4.2)); });
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
|
||||
Homie.setLoopFunction(homieLoop);
|
||||
Homie.onEvent(onHomieEvent);
|
||||
|
||||
@ -891,9 +918,10 @@ void plantcontrol()
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
bool isLowLight = (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE);
|
||||
bool hasWater = true; //FIXMEmWaterGone > waterLevelMin.get();
|
||||
//FIXME no water warning message
|
||||
lastPumpRunning = determineNextPump();
|
||||
lastPumpRunning = determineNextPump(isLowLight);
|
||||
if (lastPumpRunning != -1 && !hasWater)
|
||||
{
|
||||
log(LOG_LEVEL_ERROR, LOG_PUMP_BUTNOTANK_MESSAGE, LOG_PUMP_BUTNOTANK_CODE);
|
||||
@ -917,6 +945,13 @@ void plantcontrol()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TIMED_LIGHT_PIN)
|
||||
bool shouldLight = determineTimedLightState(isLowLight);
|
||||
timedLightOn = shouldLight;
|
||||
digitalWrite(TIMED_LIGHT_PIN, shouldLight);
|
||||
#endif // TIMED_LIGHT_PIN
|
||||
|
||||
|
||||
/* Always handle one of the deep sleep duration */
|
||||
if (lastPumpRunning == -1 || !hasWater)
|
||||
{
|
||||
@ -939,6 +974,42 @@ void plantcontrol()
|
||||
|
||||
/** @}*/
|
||||
|
||||
|
||||
bool determineTimedLightState(bool lowLight){
|
||||
bool onlyAllowedWhenDark = timedLightOnlyWhenDark.get();
|
||||
long hoursStart = timedLightStart.get();
|
||||
long hoursEnd = timedLightEnd.get();
|
||||
|
||||
//ntp missing
|
||||
if(getCurrentTime() < 10000){
|
||||
timedLightNode.setProperty("state").send(String("Off, missing ntp"));
|
||||
return false;
|
||||
}
|
||||
if(onlyAllowedWhenDark && !lowLight){
|
||||
timedLightNode.setProperty("state").send(String("Off, not dark"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((hoursStart > hoursEnd) &&
|
||||
(getCurrentHour() >= hoursStart || getCurrentHour() <= hoursEnd)) ||
|
||||
/* Handle e.g. start = 8, end = 21 */
|
||||
((hoursStart < hoursEnd) &&
|
||||
(getCurrentHour() >= hoursStart && getCurrentHour() <= hoursEnd)))
|
||||
{
|
||||
if(battery.getVoltage(BATTSENSOR_INDEX_BATTERY) >= timedLightVoltageCutoff.get() ){
|
||||
timedLightNode.setProperty("state").send(String("On"));
|
||||
return true;
|
||||
}else {
|
||||
timedLightNode.setProperty("state").send(String("Off, due to missing voltage"));
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
timedLightNode.setProperty("state").send(String("Off, outside worktime"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void log(int level, String message, int statusCode)
|
||||
{
|
||||
String buffer;
|
||||
|
Loading…
Reference in New Issue
Block a user