diff --git a/src/capacitiveSoilMoistureSensor.cpp b/src/capacitiveSoilMoistureSensor.cpp index 3b67af6..40e5367 100644 --- a/src/capacitiveSoilMoistureSensor.cpp +++ b/src/capacitiveSoilMoistureSensor.cpp @@ -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; + } } \ No newline at end of file diff --git a/src/connections.cpp b/src/connections.cpp index bb0dca5..21071e0 100644 --- a/src/connections.cpp +++ b/src/connections.cpp @@ -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."); } } diff --git a/src/header.h b/src/header.h index 9f8f33a..19655b0 100644 --- a/src/header.h +++ b/src/header.h @@ -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(); diff --git a/src/main.cpp b/src/main.cpp index 9b624f6..27b9bd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,8 @@ void setup() { Serial.println("Setup complete..."); Serial.println(); Serial.println(); + // first read without delay + readSensors(); } void loop() { diff --git a/src/peripherals.cpp b/src/peripherals.cpp index 730aeb9..0ff6898 100644 --- a/src/peripherals.cpp +++ b/src/peripherals.cpp @@ -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); +} \ No newline at end of file