diff --git a/src/capacitiveSoilMoistureSensor.cpp b/src/capacitiveSoilMoistureSensor.cpp index 40e5367..776046d 100644 --- a/src/capacitiveSoilMoistureSensor.cpp +++ b/src/capacitiveSoilMoistureSensor.cpp @@ -1,8 +1,7 @@ /* Code for the Capacitive Soil Moisture Sensor */ - -#include +#include const int numReadings = 20; @@ -10,12 +9,10 @@ void setupCapacitiveSoilMoistureSensor() { // pinMode(PIN_MS, INPUT); } -int readCapacitiveSoilMoistureSensor() -{ - int total = 0; // the running total +int readCapacitiveSoilMoistureSensor() { + int total = 0; // the running total // read from the sensor: - for (int readIndex = 0; readIndex < numReadings; readIndex++) - { + for (int readIndex = 0; readIndex < numReadings; readIndex++) { total = total + analogRead(PIN_MS); delay(2); } diff --git a/src/capacitiveSoilMoistureSensor.h b/src/capacitiveSoilMoistureSensor.h new file mode 100644 index 0000000..573661d --- /dev/null +++ b/src/capacitiveSoilMoistureSensor.h @@ -0,0 +1,2 @@ +void setupCapacitiveSoilMoistureSensor(); +int readCapacitiveSoilMoistureSensor(); \ No newline at end of file diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..716844a --- /dev/null +++ b/src/common.h @@ -0,0 +1,46 @@ +#include + +// PUBLISH FREQUENCY (MS) +#define FREQUENCY 20000 + +// fix for core panic during wifi initialization +// #define configMINIMAL_STACK_SIZE 4096 +// #define CONFIG_TIMER_TASK_STACK_SIZE 8192 + +// BH1750 lightsensor +#define MIN_LIGHT 0 +#define MAX_LIGHT 54612 + +// DHT11 +#define PIN_DHT11 14 + +// MQ-135 +#define PIN_MQ135_A 12 +#define PIN_MQ135_D 13 + +// MOISTURE SENSOR // A7 +#define PIN_MS 35 +#define VALUE_WATER 1650 +#define VALUE_AIR 3500 + +// Ventil +#define PIN_VALVE 32 +#define MAX_VALVE_TIMEOUT 5000 + +// STATUS LED +#define PIN_LED_R 2 +#define PIN_LED_G 0 +#define PIN_LED_B 4 + +// LIGHT LED +#define LIGHT_LED_PIN_R 27 +#define LIGHT_LED_PIN_G 26 +#define LIGHT_LED_PIN_B 25 +#define MAX_LIGHT_TIMEOUT (FREQUENCY - 5) + +// MQTT +#define MQTT_HOST "mqtt.timovolkmann.de" +#define MQTT_PORT 1883 +#define MQTT_TOPIC_BASE_SUB "smartgarden/commands" +#define MQTT_TOPIC_BASE_PUB "smartgarden/updates" +#define MQTT_PATH_SUB MQTT_TOPIC_BASE_SUB "/#" diff --git a/src/connections.cpp b/src/connections.cpp index c702145..2f7d557 100644 --- a/src/connections.cpp +++ b/src/connections.cpp @@ -1,17 +1,19 @@ #include -// #include +#include #include -#include +#include +#include +#include +#include +#include extern "C" { -#include "freertos/FreeRTOS.h" -#include "freertos/timers.h" + #include "freertos/FreeRTOS.h" + #include "freertos/timers.h" } -// #define MQTT_VALVE_COMMAND(device_id) (MQTT_TOPIC_BASE_SUB "/" device_id "/valve") -// #define MQTT_SOIL_PROPERTIES(device_id) (MQTT_TOPIC_BASE_SUB "/" device_id "/soil") -// #define MQTT_LIGHT_PROPERTIES(device_id) (MQTT_TOPIC_BASE_SUB "/" device_id "/light") -// #define MQTT_AUTO_PROPERTIES(device_id) (MQTT_TOPIC_BASE_SUB "/" device_id "/automatic") +#include + char MQTT_VALVE_COMMAND[72]; char MQTT_SOIL_PROPERTIES[72]; char MQTT_LIGHT_PROPERTIES[72]; @@ -77,13 +79,6 @@ void connectMQTT() { 2, &mqttTask, 1); - // xTaskCreate( - // mqttLoop, /* Task function. */ - // "mqttLoop", /* String with name of task. */ - // 8192, /* Stack size in bytes. */ - // NULL, /* Parameter passed as input of the task */ - // 1, /* Priority of the task. */ - // &mqttTask); /* Task handle. */ } void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { diff --git a/src/connections.h b/src/connections.h new file mode 100644 index 0000000..7e035fa --- /dev/null +++ b/src/connections.h @@ -0,0 +1,5 @@ +void connectWiFi(); +void mqttLoop(void *parameter); +void connectMQTT(); +void setupConnections(); +void publishMessage(const char *topic, const char *msg); \ No newline at end of file diff --git a/src/header.h b/src/header.h deleted file mode 100644 index 79820b2..0000000 --- a/src/header.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - Header file for the SmartGarden project -*/ - -#define HEADER_H - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "time.h" - -// fix for core panic during wifi initialization -#define configMINIMAL_STACK_SIZE 4096 -#define CONFIG_TIMER_TASK_STACK_SIZE 8192 - -// BH1750 lightsensor -#define MIN_LIGHT 0 -#define MAX_LIGHT 54612 - -// DHT11 -#define PIN_DHT11 14 - -// MQ-135 -#define PIN_MQ135_A 12 -#define PIN_MQ135_D 13 - -// MOISTURE SENSOR // A7 -#define PIN_MS 35 -#define VALUE_WATER 1650 -#define VALUE_AIR 3500 - -// Ventil -#define PIN_VALVE 32 -#define MAX_VALVE_TIMEOUT 5000 - -// STATUS LED -#define PIN_LED_R 2 -#define PIN_LED_G 0 -#define PIN_LED_B 4 - -// LIGHT LED -#define LIGHT_LED_PIN_R 27 -#define LIGHT_LED_PIN_G 26 -#define LIGHT_LED_PIN_B 25 -#define MAX_LIGHT_TIMEOUT 10000 - -// MQTT -#define MQTT_HOST "mqtt.timovolkmann.de" -#define MQTT_PORT 1883 -#define MQTT_TOPIC_BASE_SUB "smartgarden/commands" -#define MQTT_TOPIC_BASE_PUB "smartgarden/updates" -#define MQTT_PATH_SUB MQTT_TOPIC_BASE_SUB "/#" -// MQTT_DEVICE_ID "/#" - -// PUBLISH FREQUENCY (MS) -#define FREQUENCY 20000 - -// moisture -extern void setupCapacitiveSoilMoistureSensor(); -extern int readCapacitiveSoilMoistureSensor(); - -// light -extern void setupLightSensor(); -extern float readLightSensorValue(); - -// temperature & humidity -extern void setupTemperatureSensor(); -extern float readHumidity(); -extern float readTemperature(); - -// mqtt & wifi -extern void setupConnections(); -extern void publishMessage(const char *topic, const char *msg); - -// RGB PWM LED -extern void setupPWM(); -extern void setValueNM(int NM); -extern void getColorBasedOnValueNM(int valueNM); -extern void triggerLight(); - -// NTP Timestamps -void printTimestamp(); -void setupNTP(); -bool checkForDay(); -int getCurrentHour(); - -// sensors -void readSensors(); -void toggleValve(bool automatic); -void setSoilProperties(int FC, int PWP, int SAT); -void setupStore(); -void setLightProperties(int NM, int minLX); -void restoreLightProps(); -void persistLightProps(int NM, int minLX); -void restoreAutoProps(); -void persistAutoProps(bool light, bool irrigation); -void setAutoProperties(bool light, bool irrigation); - -void initDeviceID(); -String getDeviceID(); -const char *getDeviceIDcharArr(); - -void takeSemaphore(); -void releaseSemaphore(); diff --git a/src/lightChecker.cpp b/src/lightChecker.cpp index 5ecf944..8a8a87d 100644 --- a/src/lightChecker.cpp +++ b/src/lightChecker.cpp @@ -1,4 +1,4 @@ -#include +#include bool lightActive = false; // Colors in Array: purple, blue, green, yellow, orange, red, white @@ -29,10 +29,6 @@ void setupPWM() { ledcAttachPin(LIGHT_LED_PIN_B, ledChannelBlue); } -void setValueNM(int NM) { - getColorBasedOnValueNM(NM); -} - void getColorBasedOnValueNM(int valueNM) { if (valueNM <= 420) { //Purple colorCounter = 0; @@ -56,10 +52,11 @@ void getColorBasedOnValueNM(int valueNM) { Serial.print(valueNM); } +void setValueNM(int NM) { + getColorBasedOnValueNM(NM); +} + bool shutdownLight() { - //digitalWrite(LIGHT_LED_PIN_R, LOW); - //digitalWrite(LIGHT_LED_PIN_G, LOW); - //digitalWrite(LIGHT_LED_PIN_B, LOW); ledcWrite(ledChannelRed, 0); ledcWrite(ledChannelGreen, 0); ledcWrite(ledChannelBlue, 0); @@ -74,7 +71,6 @@ bool activateLight() { } void lightTask(void *parameter) { - takeSemaphore(); unsigned long lightTimeoutTimer = millis(); if (lightActive == false) { lightActive = activateLight(); @@ -82,7 +78,6 @@ void lightTask(void *parameter) { } lightActive = shutdownLight(); } - releaseSemaphore(); vTaskDelete(NULL); } diff --git a/src/lightChecker.h b/src/lightChecker.h new file mode 100644 index 0000000..2057252 --- /dev/null +++ b/src/lightChecker.h @@ -0,0 +1,3 @@ +void setupPWM(); +void setValueNM(int NM); +void triggerLight(); \ No newline at end of file diff --git a/src/lightSensor.cpp b/src/lightSensor.cpp index 78cb5ac..612f761 100644 --- a/src/lightSensor.cpp +++ b/src/lightSensor.cpp @@ -1,4 +1,7 @@ -#include +#include +#include +#include +#include BH1750 lightMeter; diff --git a/src/lightSensor.h b/src/lightSensor.h new file mode 100644 index 0000000..b07a3b6 --- /dev/null +++ b/src/lightSensor.h @@ -0,0 +1,2 @@ +void setupLightSensor(); +float readLightSensorValue(); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 27b9bd7..c6196c5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,9 +2,10 @@ Main file for the SmartGarden project */ -#include - -#include +#include +#include +#include +#include #define TIME_TO_SLEEP 30 volatile int noSleepTasks = 0; @@ -23,13 +24,10 @@ void setup() { digitalWrite(PIN_VALVE, LOW); + setupStore(); + setupSensors(); setupConnections(); - setupLightSensor(); - setupPWM(); - setupTemperatureSensor(); - setupCapacitiveSoilMoistureSensor(); - setupNTP(); // esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * 1000000); Serial.println("Setup complete..."); Serial.println(); @@ -39,22 +37,9 @@ void setup() { } void loop() { - // read sensors + // main loop: read sensors if (millis() - sensorReadTimer >= FREQUENCY) { readSensors(); sensorReadTimer = millis(); - - // if(noSleepTasks == 0) { - // delay(200); - // esp_deep_sleep_start(); - // } } -} - -void takeSemaphore() { - noSleepTasks++; -} - -void releaseSemaphore() { - noSleepTasks--; } \ No newline at end of file diff --git a/src/ntpManager.cpp b/src/ntpManager.cpp index ef5be48..3161ff5 100644 --- a/src/ntpManager.cpp +++ b/src/ntpManager.cpp @@ -1,4 +1,6 @@ -#include +#include +#include +#include const char* ntpServer = "pool.ntp.org"; const long gmtOffset_sec = 3600; diff --git a/src/ntpManager.h b/src/ntpManager.h new file mode 100644 index 0000000..0fb627b --- /dev/null +++ b/src/ntpManager.h @@ -0,0 +1,4 @@ +void setupNTP(); +bool checkForDay(); +int getCurrentHour(); +void printTimestamp(); \ No newline at end of file diff --git a/src/sensors.cpp b/src/sensors.cpp new file mode 100644 index 0000000..71f3e00 --- /dev/null +++ b/src/sensors.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char buffer[128]; +char MQTT_SENSOR_DATA_TOPIC[64]; + +void setupSensors() { + setupLightSensor(); + setupPWM(); + setupTemperatureSensor(); + setupCapacitiveSoilMoistureSensor(); + setupNTP(); + + strcpy(MQTT_SENSOR_DATA_TOPIC, MQTT_TOPIC_BASE_PUB "/"); + strcat(MQTT_SENSOR_DATA_TOPIC, getDeviceIDcharArr()); + strcat(MQTT_SENSOR_DATA_TOPIC, "/data"); + Serial.println("MQTT_SENSOR_DATA_TOPIC:"); + Serial.println(MQTT_SENSOR_DATA_TOPIC); +} + +void readSensors() { + Serial.println(); + StaticJsonDocument<128> doc; + float lxValue = readLightSensorValue(); + Serial.print("Light intensity: "); + Serial.print(lxValue); + Serial.println(" lx"); + doc["brightness"] = lxValue; + if ((lxValue < minimumLightValueLX) && checkForDay()) { + triggerLight(); + } + + int mstValue = readCapacitiveSoilMoistureSensor(); + Serial.print("Soil moisture: "); + Serial.println(mstValue); + + if (automaticIrrigation) { + toggleValve(true); + } + + doc["moisture"] = mstValue; + + float humidityValue = readHumidity(); + Serial.print("Humidity: "); + Serial.println(humidityValue); + + doc["humidity"] = humidityValue; + + float temperatureValue = readTemperature(); + Serial.print("Temperature: "); + Serial.println(temperatureValue); + + doc["temperature"] = temperatureValue; + serializeJson(doc, buffer); + publishMessage(MQTT_SENSOR_DATA_TOPIC, buffer); +} diff --git a/src/sensors.h b/src/sensors.h new file mode 100644 index 0000000..8f52f9e --- /dev/null +++ b/src/sensors.h @@ -0,0 +1,2 @@ +void setupSensors(); +void readSensors(); \ No newline at end of file diff --git a/src/peripherals.cpp b/src/store.cpp similarity index 59% rename from src/peripherals.cpp rename to src/store.cpp index fb661b6..5aa7ac3 100644 --- a/src/peripherals.cpp +++ b/src/store.cpp @@ -1,19 +1,8 @@ -#include #include #include -#include -#include - -#include -//using namespace std; -extern "C" { -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -} - -char MQTT_SENSOR_DATA_TOPIC[64]; - -char buffer[128]; +#include +#include +#include // Feldkapazität des Bodens in Prozent: Standard ist Humus int fieldCapacity = 44; @@ -29,103 +18,7 @@ bool automaticIrrigation = true; // make sure device irrigates until fieldcapacity is reached bool irrigateUntilFC = false; -void readSensors() { - Serial.println(); - StaticJsonDocument<128> doc; - float lxValue = readLightSensorValue(); - Serial.print("Light intensity: "); - Serial.print(lxValue); - Serial.println(" lx"); - doc["brightness"] = lxValue; - if((lxValue < minimumLightValueLX) && checkForDay()) { - triggerLight(); - } - - int mstValue = readCapacitiveSoilMoistureSensor(); - Serial.print("Soil moisture: "); - Serial.println(mstValue); - - if (automaticIrrigation) { - toggleValve(true); - } - - doc["moisture"] = mstValue; - - float humidityValue = readHumidity(); - Serial.print("Humidity: "); - Serial.println(humidityValue); - - doc["humidity"] = humidityValue; - - float temperatureValue = readTemperature(); - Serial.print("Temperature: "); - Serial.println(temperatureValue); - - doc["temperature"] = temperatureValue; - serializeJson(doc, buffer); - publishMessage(MQTT_SENSOR_DATA_TOPIC, buffer); -} - -bool openValve() { - digitalWrite(PIN_VALVE, HIGH); - digitalWrite(PIN_LED_G, LOW); - digitalWrite(PIN_LED_B, HIGH); - return true; -} - -bool closeValve() { - digitalWrite(PIN_VALVE, LOW); - digitalWrite(PIN_LED_G, HIGH); - digitalWrite(PIN_LED_B, LOW); - return false; -} - -void valveTask(void *parameter) { - takeSemaphore(); - bool isAutomatic = (bool) parameter; - Serial.print(isAutomatic); - Serial.println(" Valve task triggered."); - unsigned long valveTimeoutTimer = millis(); - bool valveOpen = false; - int initialSoilMoisture = readCapacitiveSoilMoistureSensor(); - - if (initialSoilMoisture <= permanentWiltingPoint || irrigateUntilFC) { - valveOpen = openValve(); - irrigateUntilFC = true; - } else { - Serial.println("Soil contains enough water. No irrigation needed. "); - } - - while (valveOpen) { - delay(500); - int mstValue = readCapacitiveSoilMoistureSensor(); - - if (mstValue > fieldCapacity) { // && isAutomatic - Serial.println("Field capacity reached. No irrigation needed. "); - valveOpen = closeValve(); - irrigateUntilFC = false; - } - if (millis() - valveTimeoutTimer >= MAX_VALVE_TIMEOUT) { - Serial.println("Irrigation timeout reached. close valve. "); - valveOpen = closeValve(); - } - } - releaseSemaphore(); - vTaskDelete(NULL); -} - -void toggleValve(bool automatic) { - xTaskCreate( - valveTask, /* Task function. */ - "valveTask", /* String with name of task. */ - 2048, /* Stack size in bytes. */ - &automatic, /* Parameter passed as input of the task */ - 3, /* Priority of the task. */ - NULL); /* Task handle. */ -} - void persistSoilProps(int FC, int PWP, int SAT) { - takeSemaphore(); Serial.println("persistSoilProps"); bool f = NVS.setInt("fieldCapacity", FC); bool p = NVS.setInt("permanentWilt", PWP); @@ -137,7 +30,6 @@ void persistSoilProps(int FC, int PWP, int SAT) { else { Serial.println("error occured while trying to persist soil properties"); } - releaseSemaphore(); } void restoreSoilProps() { @@ -163,18 +55,11 @@ void restoreSoilProps() { } void setupStore() { - NVS.begin("store"); initDeviceID(); restoreSoilProps(); restoreLightProps(); restoreAutoProps(); - - strcpy(MQTT_SENSOR_DATA_TOPIC, MQTT_TOPIC_BASE_PUB "/"); - strcat(MQTT_SENSOR_DATA_TOPIC, getDeviceIDcharArr()); - strcat(MQTT_SENSOR_DATA_TOPIC, "/data"); - Serial.println("MQTT_SENSOR_DATA_TOPIC:"); - Serial.println(MQTT_SENSOR_DATA_TOPIC); } void setSoilProperties(int FC, int PWP, int SAT) { @@ -191,7 +76,6 @@ void setSoilProperties(int FC, int PWP, int SAT) { } void persistLightProps(int NM, int minLX) { - takeSemaphore(); Serial.println("persistLightProps"); bool n = NVS.setInt("nanoMeter", NM); bool m = NVS.setInt("minimumLux", minLX); @@ -202,7 +86,6 @@ void persistLightProps(int NM, int minLX) { else { Serial.println("error occured while trying to persist light properties"); } - releaseSemaphore(); } void restoreLightProps() { @@ -227,7 +110,6 @@ void setLightProperties(int NM, int minLX) { } 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)); @@ -238,7 +120,6 @@ void persistAutoProps(bool light, bool irrigation) { } else { Serial.println("error occured while trying to persist auto properties"); } - releaseSemaphore(); } void restoreAutoProps() { diff --git a/src/store.h b/src/store.h new file mode 100644 index 0000000..5830269 --- /dev/null +++ b/src/store.h @@ -0,0 +1,29 @@ +// Feldkapazität des Bodens in Prozent: Standard ist Humus +extern int fieldCapacity; +// PWP des Bodens in Prozent: Standard ist Humus +extern int permanentWiltingPoint; +// Boden vollständig gesättigt bei (Prozent): Standard ist Humus +extern int soilSaturation; +// Helligkeitswert der mindestens vorhanden sein muss +extern int minimumLightValueLX; +// switches for automatic light and irrigation control +extern bool automaticLight; +extern bool automaticIrrigation; +// make sure device irrigates until fieldcapacity is reached +extern bool irrigateUntilFC; +// Device UUID will be set on first boot. +extern String DEVICE_ID; + +void persistSoilProps(int FC, int PWP, int SAT); +void restoreSoilProps(); +void setupStore(); +void setSoilProperties(int FC, int PWP, int SAT); +void persistLightProps(int NM, int minLX); +void restoreLightProps(); +void setLightProperties(int NM, int minLX); +void persistAutoProps(bool light, bool irrigation); +void restoreAutoProps(); +void setAutoProperties(bool light, bool irrigation); +void initDeviceID(); +String getDeviceID(); +const char* getDeviceIDcharArr(); \ No newline at end of file diff --git a/src/temperatureSensor.cpp b/src/temperatureSensor.cpp index 61ba0be..83ffdc1 100644 --- a/src/temperatureSensor.cpp +++ b/src/temperatureSensor.cpp @@ -1,7 +1,9 @@ -#include +#include +#include +#include + #define DHTPIN PIN_DHT11 - #define DHTTYPE DHT11 diff --git a/src/temperatureSensor.h b/src/temperatureSensor.h new file mode 100644 index 0000000..a53a7aa --- /dev/null +++ b/src/temperatureSensor.h @@ -0,0 +1,3 @@ +void setupTemperatureSensor(); +float readHumidity(); +float readTemperature(); \ No newline at end of file diff --git a/src/valve.cpp b/src/valve.cpp new file mode 100644 index 0000000..29c7d07 --- /dev/null +++ b/src/valve.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +extern "C" { + #include "freertos/FreeRTOS.h" + #include "freertos/task.h" +} + +#include + +bool openValve() { + digitalWrite(PIN_VALVE, HIGH); + digitalWrite(PIN_LED_G, LOW); + digitalWrite(PIN_LED_B, HIGH); + return true; +} + +bool closeValve() { + digitalWrite(PIN_VALVE, LOW); + digitalWrite(PIN_LED_G, HIGH); + digitalWrite(PIN_LED_B, LOW); + return false; +} + +void valveTask(void *parameter) { + bool isAutomatic = (bool)parameter; + Serial.print(isAutomatic); + Serial.println(" Valve task triggered."); + unsigned long valveTimeoutTimer = millis(); + bool valveOpen = false; + int initialSoilMoisture = readCapacitiveSoilMoistureSensor(); + + if (initialSoilMoisture <= permanentWiltingPoint || irrigateUntilFC) { + valveOpen = openValve(); + irrigateUntilFC = true; + } else { + Serial.println("Soil contains enough water. No irrigation needed. "); + } + + while (valveOpen) { + delay(500); + int mstValue = readCapacitiveSoilMoistureSensor(); + + if (mstValue > fieldCapacity) { // && isAutomatic + Serial.println("Field capacity reached. No irrigation needed. "); + valveOpen = closeValve(); + irrigateUntilFC = false; + } + if (millis() - valveTimeoutTimer >= MAX_VALVE_TIMEOUT) { + Serial.println("Irrigation timeout reached. close valve. "); + valveOpen = closeValve(); + } + } + vTaskDelete(NULL); +} + +void toggleValve(bool automatic) { + xTaskCreate( + valveTask, /* Task function. */ + "valveTask", /* String with name of task. */ + 2048, /* Stack size in bytes. */ + &automatic, /* Parameter passed as input of the task */ + 3, /* Priority of the task. */ + NULL); /* Task handle. */ +} diff --git a/src/valve.h b/src/valve.h new file mode 100644 index 0000000..5017d35 --- /dev/null +++ b/src/valve.h @@ -0,0 +1 @@ +void toggleValve(bool automatic);