diff --git a/src/connections.cpp b/src/connections.cpp index 1cbce8c..bb0dca5 100644 --- a/src/connections.cpp +++ b/src/connections.cpp @@ -10,6 +10,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" TimerHandle_t mqttReconnectTimer; TimerHandle_t wifiReconnectTimer; @@ -112,6 +113,19 @@ 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(topic); + StaticJsonDocument<1024> doc; + DeserializationError err = deserializeJson(doc, payload); + if (err == DeserializationError::Ok) { + int nm = doc["nm"]; + int minLX = doc["minLX"]; + setLightProperties(nm, minLX); + } else { + Serial.println(err.c_str()); + } + } if (strcmp(topic, MQTT_VALVE_COMMAND) == 0) { Serial.println("toggling valve..."); Serial.println(topic); diff --git a/src/header.h b/src/header.h index d40476f..bacec3d 100644 --- a/src/header.h +++ b/src/header.h @@ -15,11 +15,16 @@ #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 @@ -36,15 +41,27 @@ #define PIN_VALVE 32 #define MAX_VALVE_TIMEOUT 10000 -// LED +// 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 +<<<<<<< HEAD #define MQTT_DEVICE_ID "esp-andy" +||||||| cbf5199 +#define MQTT_DEVICE_ID "esp-timo" +======= +#define MQTT_DEVICE_ID "esp-sebastian" +>>>>>>> 18b5c0bfeceb30e12c570e73ae16fb9bc390c4e1 #define MQTT_TOPIC_BASE_SUB "smartgarden/commands" #define MQTT_TOPIC_BASE_PUB "smartgarden/updates" #define MQTT_PATH_PUB MQTT_TOPIC_BASE_PUB "/" MQTT_DEVICE_ID "/" @@ -71,11 +88,26 @@ extern float readTemperature(); 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(); void setSoilProperties(int FC, int PWP, int SAT); void setupStore(); +void setLightProperties(int NM, int minLX); +void restoreLightProbs(); +void persistLightProps(int NM, int minLX); void takeSemaphore(); -void releaseSemaphore(); \ No newline at end of file +void releaseSemaphore(); diff --git a/src/lightChecker.cpp b/src/lightChecker.cpp new file mode 100644 index 0000000..5ecf944 --- /dev/null +++ b/src/lightChecker.cpp @@ -0,0 +1,97 @@ +#include + +bool lightActive = false; +// Colors in Array: purple, blue, green, yellow, orange, red, white +int colorValueArray[][3] = {{125,0,125}, {0,0,255}, {0,255,0}, {255,255,0}, {255,140,0}, {255,0,0}, {255,255,255}}; +int colorCounter = 6; + +// Setting PWM properties +const int freq = 5000; +const int ledChannelRed = 0; +const int ledChannelGreen = 1; +const int ledChannelBlue= 2; +const int resolution = 8; + +void setupPWM() { + // Set pins as output + pinMode(LIGHT_LED_PIN_R, OUTPUT); + pinMode(LIGHT_LED_PIN_G, OUTPUT); + pinMode(LIGHT_LED_PIN_B, OUTPUT); + + // Configure LED PWM functionalitites + ledcSetup(ledChannelRed, freq, resolution); + ledcSetup(ledChannelGreen, freq, resolution); + ledcSetup(ledChannelBlue, freq, resolution); + + // Attach the channel to the GPIO2 to be controlled + ledcAttachPin(LIGHT_LED_PIN_R, ledChannelRed); + ledcAttachPin(LIGHT_LED_PIN_G, ledChannelGreen); + ledcAttachPin(LIGHT_LED_PIN_B, ledChannelBlue); +} + +void setValueNM(int NM) { + getColorBasedOnValueNM(NM); +} + +void getColorBasedOnValueNM(int valueNM) { + if (valueNM <= 420) { //Purple + colorCounter = 0; + } + else if (valueNM <= 490) { //Blue + colorCounter = 1; + } + else if (valueNM <= 575) { //Green + colorCounter = 2; + } + else if (valueNM <= 585) { //Yellow + colorCounter = 3; + } + else if (valueNM <= 650) { //Orange + colorCounter = 4; + } + else if (valueNM > 650) { // 650 to 750 is red + colorCounter = 5; + } + Serial.println("New color set based on: "); + Serial.print(valueNM); +} + +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); + return false; +} + +bool activateLight() { + ledcWrite(ledChannelRed, colorValueArray[colorCounter][0]); + ledcWrite(ledChannelGreen, colorValueArray[colorCounter][1]); + ledcWrite(ledChannelBlue, colorValueArray[colorCounter][2]); + return true; +} + +void lightTask(void *parameter) { + takeSemaphore(); + unsigned long lightTimeoutTimer = millis(); + if (lightActive == false) { + lightActive = activateLight(); + while (millis() - lightTimeoutTimer <= MAX_LIGHT_TIMEOUT) { + } + lightActive = shutdownLight(); + } + releaseSemaphore(); + vTaskDelete(NULL); +} + +void triggerLight() { + xTaskCreate( + lightTask, /* Task function. */ + "lightTask", /* String with name of task. */ + 2048, /* Stack size in bytes. */ + NULL, /* Parameter passed as input of the task */ + 1, /* Priority of the task. */ + NULL); /* Task handle. */ +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3407490..9b624f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,8 +26,10 @@ void setup() { setupStore(); setupConnections(); setupLightSensor(); + setupPWM(); setupTemperatureSensor(); setupCapacitiveSoilMoistureSensor(); + setupNTP(); // esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * 1000000); Serial.println("Setup complete..."); Serial.println(); diff --git a/src/ntpManager.cpp b/src/ntpManager.cpp new file mode 100644 index 0000000..ef5be48 --- /dev/null +++ b/src/ntpManager.cpp @@ -0,0 +1,41 @@ +#include + +const char* ntpServer = "pool.ntp.org"; +const long gmtOffset_sec = 3600; +const int daylightOffset_sec = 3600; + +// start and end hour of the date +const int dayStart = 8; +const int dayEnd = 20; +struct tm timeinfo; + +void setupNTP() { + if (WiFi.isConnected()) { + Serial.println("WiFi OK. Getting Timestamp"); + configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); + printTimestamp(); + } +} + +bool checkForDay() { + printTimestamp(); + if((getCurrentHour() > dayStart) && (getCurrentHour() < dayEnd)) { + return true; + } + else { + return false; + } +} + +int getCurrentHour() { + int currentHour = timeinfo.tm_hour; + return currentHour; +} + +void printTimestamp() { + if(!getLocalTime(&timeinfo)){ + Serial.println("Failed to obtain time"); + return; + } + Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); +} \ No newline at end of file diff --git a/src/peripherals.cpp b/src/peripherals.cpp index 4e99140..730aeb9 100644 --- a/src/peripherals.cpp +++ b/src/peripherals.cpp @@ -19,6 +19,8 @@ int fieldCapacity = 44; int permanentWiltingPoint = 25; // Boden vollständig gesättigt bei (Prozent): Standard ist Humus int soilSaturation = 69; +// Helligkeitswert der mindestens vorhanden sein muss +int minimumLightValueLX = 50; void readSensors() { StaticJsonDocument<128> doc; @@ -27,6 +29,9 @@ void readSensors() { Serial.print(lxValue); Serial.println(" lx"); doc["brightness"] = lxValue; + if((lxValue < minimumLightValueLX) && checkForDay()) { + triggerLight(); + } //sprintf(buffer, "%f", lxValue); //publishMessage(MQTT_BRIGHTNESS, buffer); @@ -93,7 +98,7 @@ void toggleValve() { xTaskCreate( valveTask, /* Task function. */ "valveTask", /* String with name of task. */ - 2048, /* Stack size in bytes. */ + 2048, /* Stack size in bytes. */ NULL, /* Parameter passed as input of the task */ 1, /* Priority of the task. */ NULL); /* Task handle. */ @@ -137,6 +142,7 @@ void restoreSoilProps() { void setupStore() { NVS.begin("store"); restoreSoilProps(); + restoreLightProbs(); } void setSoilProperties(int FC, int PWP, int SAT) { @@ -152,3 +158,38 @@ void setSoilProperties(int FC, int PWP, int SAT) { Serial.println(soilSaturation); } +void persistLightProps(int NM, int minLX) { + takeSemaphore(); + Serial.println("persistSoilProps"); + bool n = NVS.setInt("nanoMeter", NM); + bool m = NVS.setInt("minimumLux", minLX); + if (n && m) { + Serial.println("Light properties sucessfully stored."); + NVS.commit(); + } + else { + Serial.println("error occured while trying to persist soil properties"); + } + releaseSemaphore(); +} + +void restoreLightProbs() { + Serial.println("restoreLightProps"); + int nm = NVS.getInt("nanoMeter"); + int minLX = NVS.getInt("minimumLux"); + if (nm != 0) { + setValueNM(nm); + } + if (minLX != 0) { + minimumLightValueLX = minLX; + } + Serial.print(minimumLightValueLX); +} + +void setLightProperties(int NM, int minLX) { + setValueNM(NM); + minimumLightValueLX = minLX; + persistLightProps(NM, minLX); + Serial.print("new minimum Light Value LX: "); + Serial.println(minimumLightValueLX); +}