implemented irrigation logic + autotoggle by mqtt

This commit is contained in:
Timo Volkmann 2020-07-16 10:55:17 +02:00
parent decdf72f7d
commit 93561d4273
5 changed files with 116 additions and 40 deletions

View File

@ -20,14 +20,16 @@ int readCapacitiveSoilMoistureSensor()
delay(2);
}
int measurement = total / numReadings;
Serial.print("soil moisture raw: ");
Serial.println(measurement);
// add the reading to the total:
//int measurement = analogRead(PIN_MS);
if (map(measurement, VALUE_AIR, VALUE_WATER, 0, 100) < 0) {
int finalRes = map(measurement, VALUE_AIR, VALUE_WATER, 0, 100);
Serial.print("current soil moisture: ");
Serial.println(finalRes);
if (finalRes < 0) {
return 0;
} else if (map(measurement, VALUE_AIR, VALUE_WATER, 0, 100) > 100) {
} else if (finalRes > 100) {
return 100;
} else {return map(measurement, VALUE_AIR, VALUE_WATER, 0, 100);}
} else {
return finalRes;
}
}

View File

@ -11,6 +11,7 @@ extern "C" {
#define MQTT_VALVE_COMMAND MQTT_TOPIC_BASE_SUB "/" MQTT_DEVICE_ID "/valve"
#define MQTT_SOIL_PROPERTIES MQTT_TOPIC_BASE_SUB "/" MQTT_DEVICE_ID "/soil"
#define MQTT_LIGHT_PROPERTIES MQTT_TOPIC_BASE_SUB "/" MQTT_DEVICE_ID "/light"
#define MQTT_AUTO_PROPERTIES MQTT_TOPIC_BASE_SUB "/" MQTT_DEVICE_ID "/automatic"
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
@ -114,7 +115,7 @@ void onMqttMessage(char *topic, byte *payload, unsigned int payload_length) {
Serial.println();
if (strcmp(topic, MQTT_LIGHT_PROPERTIES) == 0) {
Serial.println("receiving light treshold...");
Serial.println("receiving light treshold...");
Serial.println(topic);
StaticJsonDocument<1024> doc;
DeserializationError err = deserializeJson(doc, payload);
@ -129,7 +130,7 @@ Serial.println("receiving light treshold...");
if (strcmp(topic, MQTT_VALVE_COMMAND) == 0) {
Serial.println("toggling valve...");
Serial.println(topic);
toggleValve();
toggleValve(false);
}
if (strcmp(topic, MQTT_SOIL_PROPERTIES) == 0) {
Serial.println("receiving soil thresholds...");
@ -145,6 +146,19 @@ Serial.println("receiving light treshold...");
Serial.println(err.c_str());
}
}
if (strcmp(topic, MQTT_AUTO_PROPERTIES) == 0) {
Serial.println("receiving auto settings...");
Serial.println(topic);
StaticJsonDocument<1024> doc;
DeserializationError err = deserializeJson(doc, payload);
if (err == DeserializationError::Ok) {
bool ir = doc["irrigation"];
bool li = doc["light"];
setAutoProperties(li, ir);
} else {
Serial.println(err.c_str());
}
}
}
void setupConnections() {
@ -174,8 +188,8 @@ void publishMessage(const char *topic, const char *msg) {
if(mqttClient.connected()) {
mqttClient.publish(topic, msg);
Serial.print(topic);
Serial.println(" successfully sent.\n");
Serial.println(" successfully sent.");
} else {
Serial.println("couldn't send message. waiting for reconnect.\n");
Serial.println("couldn't send message. waiting for reconnect.");
}
}

View File

@ -39,7 +39,7 @@
// Ventil
#define PIN_VALVE 32
#define MAX_VALVE_TIMEOUT 10000
#define MAX_VALVE_TIMEOUT 5000
// STATUS LED
#define PIN_LED_R 2
@ -63,7 +63,7 @@
// MQTT_DEVICE_ID "/#"
// PUBLISH FREQUENCY (MS)
#define FREQUENCY 60000
#define FREQUENCY 20000
// moisture
extern void setupCapacitiveSoilMoistureSensor();
@ -96,12 +96,15 @@ int getCurrentHour();
// sensors
void readSensors();
void toggleValve();
void toggleValve(bool automatic);
void setSoilProperties(int FC, int PWP, int SAT);
void setupStore();
void setLightProperties(int NM, int minLX);
void restoreLightProbs();
void restoreLightProps();
void persistLightProps(int NM, int minLX);
void restoreAutoProps();
void persistAutoProps(bool light, bool irrigation);
void setAutoProperties(bool light, bool irrigation);
void takeSemaphore();
void releaseSemaphore();

View File

@ -34,6 +34,8 @@ void setup() {
Serial.println("Setup complete...");
Serial.println();
Serial.println();
// first read without delay
readSensors();
}
void loop() {

View File

@ -21,8 +21,12 @@ int permanentWiltingPoint = 25;
int soilSaturation = 69;
// Helligkeitswert der mindestens vorhanden sein muss
int minimumLightValueLX = 50;
// switches for automatic light and irrigation control
bool automaticLight = true;
bool automaticIrrigation = true;
void readSensors() {
Serial.println();
StaticJsonDocument<128> doc;
float lxValue = readLightSensorValue();
Serial.print("Light intensity: ");
@ -32,30 +36,33 @@ void readSensors() {
if((lxValue < minimumLightValueLX) && checkForDay()) {
triggerLight();
}
//sprintf(buffer, "%f", lxValue);
//publishMessage(MQTT_BRIGHTNESS, buffer);
int mstValue = readCapacitiveSoilMoistureSensor();
Serial.print("Soil moisture: ");
Serial.println(mstValue);
// sprintf(buffer, "%i", mstValue);
// publishMessage(MQTT_MOISTURE, buffer);
// if (mstValue > fieldCapacity) {
// Serial.println("Field capacity reached. No irrigation needed. ");
// }
// if (mstValue < permanentWiltingPoint) {
// Serial.println("Permanent wilting point reached. Plant needs irrigation. ");
// }
if (automaticIrrigation) {
toggleValve(true);
}
doc["moisture"] = mstValue;
float humidityValue = readHumidity();
Serial.print("Humidity: ");
Serial.println(humidityValue);
// sprintf(buffer, "%f", humidityValue);
// publishMessage(MQTT_HUMIDITY, buffer);
doc["humidity"] = humidityValue;
float temperatureValue = readTemperature();
Serial.print("Temperature: ");
Serial.println(temperatureValue);
// sprintf(buffer, "%f", temperatureValue);
// publishMessage(MQTT_TEMPERATURE, buffer);
doc["temperature"] = temperatureValue;
Serial.print("\n");
serializeJson(doc, buffer);
publishMessage(MQTT_SENSOR_DATA, buffer);
}
@ -76,31 +83,42 @@ bool closeValve() {
void valveTask(void *parameter) {
takeSemaphore();
bool isAutomatic = (bool)parameter;
Serial.println("Valve task triggered.");
unsigned long valveTimeoutTimer = millis();
bool valveOpen = openValve();
bool valveOpen = false;
int initialSoilMoisture = readCapacitiveSoilMoistureSensor();
if (initialSoilMoisture > permanentWiltingPoint) {
Serial.println("Soil contains enough water. No irrigation needed. ");
} else {
valveOpen = openValve();
}
while (valveOpen) {
delay(500);
int mstValue = readCapacitiveSoilMoistureSensor();
if (millis() - valveTimeoutTimer >= MAX_VALVE_TIMEOUT) {
if (mstValue > fieldCapacity) { // && isAutomatic
Serial.println("Field capacity reached. No irrigation needed. ");
valveOpen = closeValve();
}
if (millis() - valveTimeoutTimer >= MAX_VALVE_TIMEOUT) {
Serial.println("Irrigation timeout reached. close valve. ");
valveOpen = closeValve();
}
// if (mstValue > 80) {
// valveOpen = closeValve();
// }
}
releaseSemaphore();
vTaskDelete(NULL);
}
void toggleValve() {
void toggleValve(bool automatic) {
xTaskCreate(
valveTask, /* Task function. */
"valveTask", /* String with name of task. */
2048, /* Stack size in bytes. */
NULL, /* Parameter passed as input of the task */
1, /* Priority of the task. */
&automatic, /* Parameter passed as input of the task */
3, /* Priority of the task. */
NULL); /* Task handle. */
}
@ -134,15 +152,19 @@ void restoreSoilProps() {
if (sat != 0) {
soilSaturation = sat;
}
Serial.print(fieldCapacity);
Serial.print(permanentWiltingPoint);
Serial.print(soilSaturation);
Serial.print("fieldCapacity: ");
Serial.println(fieldCapacity);
Serial.print("permanentWiltingPoint: ");
Serial.println(permanentWiltingPoint);
Serial.print("soilSaturation: ");
Serial.println(soilSaturation);
}
void setupStore() {
NVS.begin("store");
restoreSoilProps();
restoreLightProbs();
restoreLightProps();
restoreAutoProps();
}
void setSoilProperties(int FC, int PWP, int SAT) {
@ -160,7 +182,7 @@ void setSoilProperties(int FC, int PWP, int SAT) {
void persistLightProps(int NM, int minLX) {
takeSemaphore();
Serial.println("persistSoilProps");
Serial.println("persistLightProps");
bool n = NVS.setInt("nanoMeter", NM);
bool m = NVS.setInt("minimumLux", minLX);
if (n && m) {
@ -168,12 +190,12 @@ void persistLightProps(int NM, int minLX) {
NVS.commit();
}
else {
Serial.println("error occured while trying to persist soil properties");
Serial.println("error occured while trying to persist light properties");
}
releaseSemaphore();
}
void restoreLightProbs() {
void restoreLightProps() {
Serial.println("restoreLightProps");
int nm = NVS.getInt("nanoMeter");
int minLX = NVS.getInt("minimumLux");
@ -183,7 +205,7 @@ void restoreLightProbs() {
if (minLX != 0) {
minimumLightValueLX = minLX;
}
Serial.print(minimumLightValueLX);
Serial.println(minimumLightValueLX);
}
void setLightProperties(int NM, int minLX) {
@ -193,3 +215,36 @@ void setLightProperties(int NM, int minLX) {
Serial.print("new minimum Light Value LX: ");
Serial.println(minimumLightValueLX);
}
void persistAutoProps(bool light, bool irrigation) {
takeSemaphore();
Serial.println("persistAutoProps");
// saved in NVS as Integer: 1 = true, 2 = false, 0 = not persisted, use standard settings
bool n = NVS.setInt("automaticLight", (light ? 1 : 2));
bool m = NVS.setInt("automaticIrrigation", (irrigation ? 1 : 2));
if (n && m) {
NVS.commit();
Serial.println("Auto properties sucessfully stored.");
} else {
Serial.println("error occured while trying to persist auto properties");
}
releaseSemaphore();
}
void restoreAutoProps() {
Serial.println("restoreLightProps");
int li = NVS.getInt("automaticLight");
int ir = NVS.getInt("automaticIrrigation");
automaticLight = (bool) (li != 2);
automaticIrrigation = (bool) (ir != 2);
Serial.println(minimumLightValueLX);
}
void setAutoProperties(bool light, bool irrigation) {
automaticLight = light;
automaticIrrigation = irrigation;
persistAutoProps(light, irrigation);
Serial.print("new auto settings: ");
Serial.println(automaticLight);
Serial.println(automaticIrrigation);
}