#include #include #include #include #include #include #include #include #include "time.h" Preferences preferences; // #define DHTPIN 4 // GPIO-Pin, an den der Data-Pin des DHT11 angeschlossen ist // #define DHTTYPE DHT11 // DHT 11 // DHT dht(DHTPIN, DHTTYPE); const char* ntp = "fritz.box"; const int gmt_offset_sec = 3600; const int daylight_offset_sec = 7200; //Variablen für PWM int pwm_freq = 5000; int pwm_resolution = 10; //Variablen PWM fan int fan_pwm_channel = 0; int fan_pwm_pin = 14; //Variable PWM LED1 int led1_pwm_channel = 1; int led1_pwm_pin = 26; //Variabke PWM LED2 int led2_pwm_channel = 2; int led2_pwm_pin = 27; char led1cycle[5] = "led1"; char led2cycle[5] = "led2"; char fancycle[4] = "fan"; //Variable zum Speichern des Status des Schalters bool fan_active = false; bool led1active = false; bool led2active = false; /* Ändern Sie dies auf die Auflösung Ihres Bildschirms */ static const uint16_t screenWidth = 320; static const uint16_t screenHeight = 240; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 }; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; //TFT_eSPI tft = TFT_eSPI( screenWidth, screenHeight ); /* TFT-Instanz */ TFT_eSPI tft = TFT_eSPI(); #if LV_USE_LOG != 0 /* Serielle Debugging-Funktion */ void my_print(const char * buf) { Serial.printf(buf); Serial.flush(); } #endif //WIFI void scanWifi(lv_event_t * e) { lv_dropdown_clear_options(ui_wifinetlist); int n = WiFi.scanNetworks(); if (n == 0) { Serial.println("no networks found"); lv_dropdown_add_option(ui_wifinetlist, "no networks found", n); } else { for (int i = 0; i < n; ++i) { lv_dropdown_add_option(ui_wifinetlist, WiFi.SSID(i).c_str(), i); } } } void setWifi(lv_event_t * e) { char ssid[32]; lv_dropdown_get_selected_str(ui_wifinetlist, ssid, sizeof(ssid)); const char * pw = (const char*)lv_textarea_get_text(ui_wifipw); WiFi.begin(ssid, pw); int8_t counter; while (WiFi.status() != WL_CONNECTED && counter != 21) { lv_label_set_text(ui_wifistatus, "Connecting..."); delay(500); ++counter; } lv_label_set_text(ui_wifistatus, "Connected"); preferences.begin("wifi", false); preferences.putString("ssid", ssid); preferences.putString("pw", pw); preferences.end(); } // FAN AND LIGHT CONTROL void switchEventHandler(lv_event_t * e) { lv_obj_t *obj = (lv_obj_t *)lv_event_get_target(e); char * user_data = (char*)lv_event_get_user_data(e); int light_off_duty_cycle = 1024; int fan_duty_cycle; int led1_duty_cycle; int led2_duty_cycle; if(obj == ui_light1switch) { if (lv_obj_has_state(obj, LV_STATE_CHECKED)) { preferences.begin("g_phase", true); led1_duty_cycle = preferences.getInt(user_data, 860); preferences.end(); led1active = true; turnOn(led1_pwm_pin, led1_duty_cycle, ui_light1statuslbl, ui_lbllightstatus, ui_light1percent); } else { led1active = false; turnOff(led1_pwm_pin, light_off_duty_cycle, ui_light1statuslbl, ui_lbllightstatus, ui_light1percent); } } if(obj == ui_light2switch) { if (lv_obj_has_state(obj, LV_STATE_CHECKED)) { preferences.begin("g_phase", true); led2_duty_cycle = preferences.getInt(user_data, 860); preferences.end(); led2active = true; turnOn(led2_pwm_pin, led2_duty_cycle, ui_light2statuslbl, ui_lbllightstatus, ui_light2percent); } else { led2active = false; turnOff(led2_pwm_pin, light_off_duty_cycle, ui_light2statuslbl, ui_lbllightstatus, ui_light2percent); } } if(obj == ui_switchfanstatus) { if (lv_obj_has_state(obj, LV_STATE_CHECKED)) { preferences.begin("g_phase", true); fan_duty_cycle = preferences.getInt(user_data, 310); preferences.end(); fan_active = true; turnOn(fan_pwm_pin, fan_duty_cycle, ui_lblfanstatus, ui_lblfanspeed, ui_lblfanfanspeed); } else { int off_duty_cycle = 0; fan_active = false; turnOff(fan_pwm_pin, off_duty_cycle, ui_lblfanstatus, ui_lblfanspeed, ui_lblfanfanspeed); } } } void turnOn(int pin, int duty_cycle, lv_obj_t * statuslbl, lv_obj_t * statusmainlbl, lv_obj_t * percent) { ledcWrite(pin, duty_cycle); int percentage; if (statusmainlbl == ui_lblfanspeed) { percentage = round((duty_cycle * 100.0) / 1024.0); lv_label_set_text_fmt(statusmainlbl, "%d%%", percentage); lv_label_set_text_fmt(percent, "%d%%", percentage); } else { percentage = round(100 - (duty_cycle * 100.0) / 1024.0); lv_label_set_text(statusmainlbl, "ON"); lv_label_set_text_fmt(percent, "%d%%", percentage); preferences.begin("g_phase", false); preferences.putBool("light", true); preferences.end(); } lv_label_set_text(statuslbl, "ON"); } void turnOff(int pin, int duty_cycle, lv_obj_t * statuslbl, lv_obj_t * statusmainlbl, lv_obj_t * percent) { ledcWrite(pin, duty_cycle); if (statusmainlbl == ui_lblfanspeed) lv_label_set_text(statusmainlbl, "0%"); lv_label_set_text(statuslbl, "OFF"); lv_label_set_text_fmt(percent, "0%%"); if (led1active == false && led2active == false) { preferences.begin("g_phase", false); preferences.putBool("light", false); preferences.end(); lv_label_set_text(statusmainlbl, "OFF"); } } void dimm(int pin, int duty_cycle, lv_obj_t * percent, lv_obj_t * percent2 = NULL) { int percentage = 0; ledcWrite(pin, duty_cycle); if (percent == ui_lblfanspeed) { percentage = round((duty_cycle * 100.0) / 1024.0); lv_label_set_text_fmt(percent2, "%d%%", percentage); } else { percentage = round(100.0 - (duty_cycle * 100.0) / 1024.0); } lv_label_set_text_fmt(percent, "%d%%", percentage); } static void dimmUpBtnEventHandler(lv_event_t * e) { int fan_duty_cycle = 10; int led1_duty_cycle = -10; int led2_duty_cycle = -10; lv_obj_t *obj = (lv_obj_t *)lv_event_get_target(e); char* user_data = (char*)lv_event_get_user_data(e); if (obj == ui_light1up) { if (led1active) { preferences.begin("g_phase", false); led1_duty_cycle += preferences.getInt(user_data, 860); if (led1_duty_cycle <= 0) led1_duty_cycle = 0; preferences.putInt(user_data, led1_duty_cycle); preferences.end(); dimm(led1_pwm_pin, led1_duty_cycle, ui_light1percent); } } if (obj == ui_light2up) { if (led2active) { preferences.begin("g_phase", false); led2_duty_cycle += preferences.getInt(user_data, 860); if (led2_duty_cycle <= 0) led2_duty_cycle = 0; preferences.putInt(user_data, led2_duty_cycle); preferences.end(); dimm(led2_pwm_pin, led2_duty_cycle, ui_light2percent); } } if (obj == ui_btnfanup) { if (fan_active) { preferences.begin("g_phase", false); fan_duty_cycle += preferences.getInt(user_data, 76); if (fan_duty_cycle >= 1024) fan_duty_cycle = 1024; preferences.putInt(user_data, fan_duty_cycle); preferences.end(); dimm(fan_pwm_pin, fan_duty_cycle, ui_lblfanspeed, ui_lblfanfanspeed); } } } static void dimmDownBtnEventHandler(lv_event_t * e) { lv_obj_t *obj = (lv_obj_t *)lv_event_get_target(e); char* user_data = (char*)lv_event_get_user_data(e); int fan_duty_cycle = -10; int led1_duty_cycle = 10; int led2_duty_cycle = 10; if (obj == ui_light1down) { if (led1active) { preferences.begin("g_phase", false); led1_duty_cycle += preferences.getInt(user_data); if (led1_duty_cycle >= 860) led1_duty_cycle = 860; preferences.putInt(user_data, led1_duty_cycle); preferences.end(); dimm(led1_pwm_pin, led1_duty_cycle, ui_light1percent); } } if (obj == ui_light2down) { if (led2active) { preferences.begin("g_phase", false); led2_duty_cycle += preferences.getInt(user_data); if (led2_duty_cycle >= 860) led2_duty_cycle = 860; preferences.putInt(user_data, led2_duty_cycle); preferences.end(); dimm(led2_pwm_pin, led2_duty_cycle, ui_light2percent); } } if (obj == ui_btnfandown) { if (fan_active) { preferences.begin("g_phase", false); fan_duty_cycle += preferences.getInt(user_data); if (fan_duty_cycle <= 310) fan_duty_cycle = 310; preferences.putInt(user_data, fan_duty_cycle); preferences.end(); dimm(fan_pwm_pin, fan_duty_cycle, ui_lblfanspeed, ui_lblfanfanspeed); } } } /* Display aktualisieren */ void my_disp_flush (lv_display_t *disp, const lv_area_t *area, uint8_t *pixelmap) { uint32_t w = ( area->x2 - area->x1 + 1 ); uint32_t h = ( area->y2 - area->y1 + 1 ); if (LV_COLOR_16_SWAP) { size_t len = lv_area_get_size( area ); lv_draw_sw_rgb565_swap( pixelmap, len ); } tft.startWrite(); tft.setAddrWindow( area->x1, area->y1, w, h ); tft.pushColors( (uint16_t*) pixelmap, w * h, true ); tft.endWrite(); lv_disp_flush_ready( disp ); } /* Touchpad lesen */ void my_touchpad_read (lv_indev_t * indev_driver, lv_indev_data_t * data) { uint16_t touchX = 0, touchY = 0; bool touched = tft.getTouch( &touchX, &touchY, 600 ); if (!touched) { data->state = LV_INDEV_STATE_REL; } else { data->state = LV_INDEV_STATE_PR; // Anpassung der Koordinaten für Rotation(3) data->point.x = touchX; data->point.y = touchY; // Begrenze die Koordinaten auf die Bildschirmauflösung if (data->point.x < 0) data->point.x = 0; if (data->point.y < 0) data->point.y = 0; // Debugging-Ausgaben /* Serial.print("Touch X: "); Serial.print(data->point.x); Serial.print(" | Touch Y: "); Serial.println(data->point.y); */ } } /* Tick-Funktion für LVGL interne Timings */ static uint32_t my_tick_get_cb (void) { return millis(); } //Setup Preferences void initPreferences() { preferences.begin("wifi", false); preferences.putString("ssid", "MeinZuhause"); preferences.putString("pw", "D4n1e7Y4s3m1nUnd7ey7a"); preferences.end(); preferences.begin("g_phase", false); preferences.putBool("light", false); preferences.putInt(led1cycle, 860); preferences.putInt(led2cycle, 860); preferences.putInt(fancycle, 510); preferences.putBool("veggie", false); preferences.putBool("flowering", false); preferences.end(); } struct tm timeinfo; struct tm targettime = {0}; time_t realtime; time_t target_sec; time_t endtime; time_t diff_time; int updateVeggieMode = 5000; bool startup; void setup () { Serial.begin( 115200 ); /* Vorbereitung für mögliches serielles Debugging */ //INIT NEEDED PREFERENCES FILES // initPreferences(); String LVGL_Arduino = "Hello Arduino! "; LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch(); Serial.println( LVGL_Arduino ); Serial.println( "I am LVGL_Arduino" ); lv_init(); #if LV_USE_LOG != 0 lv_log_register_print_cb( my_print ); /* Registrieren der Print-Funktion für Debugging */ #endif tft.begin(); /* TFT initialisieren */ tft.setRotation( 3 ); /* Landscape-Orientierung, gedreht */ // Setzen Sie Ihre Kalibrierungsdaten hier ein uint16_t calData[5] = { 419, 3486, 314, 3434, 1 }; tft.setTouch(calData); // PWM-Kanal konfigurieren ledcAttachChannel(fan_pwm_pin, pwm_freq, pwm_resolution, fan_pwm_channel); ledcAttachChannel(led1_pwm_pin, pwm_freq, pwm_resolution, led1_pwm_channel); ledcAttachChannel(led2_pwm_pin, pwm_freq, pwm_resolution, led2_pwm_channel); static lv_disp_t* disp; disp = lv_display_create( screenWidth, screenHeight ); lv_display_set_buffers( disp, buf, NULL, SCREENBUFFER_SIZE_PIXELS * sizeof(lv_color_t), LV_DISPLAY_RENDER_MODE_PARTIAL ); lv_display_set_flush_cb( disp, my_disp_flush ); static lv_indev_t* indev; indev = lv_indev_create(); lv_indev_set_type( indev, LV_INDEV_TYPE_POINTER ); lv_indev_set_read_cb( indev, my_touchpad_read ); lv_tick_set_cb( my_tick_get_cb ); ui_init(); Serial.println( "Setup abgeschlossen" ); // Verknüpfung Funktionen UI lv_obj_add_event_cb(ui_switchfanstatus, switchEventHandler, LV_EVENT_VALUE_CHANGED, fancycle); // Verknüpfen des Switches lv_obj_add_event_cb(ui_btnfanup, dimmUpBtnEventHandler, LV_EVENT_CLICKED, fancycle); // Up-Button lv_obj_add_event_cb(ui_btnfandown, dimmDownBtnEventHandler, LV_EVENT_CLICKED, fancycle); lv_obj_add_event_cb(ui_light1switch, switchEventHandler, LV_EVENT_VALUE_CHANGED, led1cycle); lv_obj_add_event_cb(ui_light2switch, switchEventHandler, LV_EVENT_VALUE_CHANGED, led2cycle); lv_obj_add_event_cb(ui_light1up, dimmUpBtnEventHandler, LV_EVENT_CLICKED, led1cycle); lv_obj_add_event_cb(ui_light2up, dimmUpBtnEventHandler, LV_EVENT_CLICKED, led2cycle); lv_obj_add_event_cb(ui_light1down, dimmDownBtnEventHandler, LV_EVENT_CLICKED, led1cycle); lv_obj_add_event_cb(ui_light2down, dimmDownBtnEventHandler, LV_EVENT_CLICKED, led2cycle); lv_obj_add_event_cb(ui_wifibtn, scanWifi, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(ui_wifikeyboard, setWifi, LV_EVENT_READY, NULL); lv_obj_add_event_cb(ui_savemode, saveModeSettings, LV_EVENT_CLICKED, NULL); // Setze initial den Lüfter auf "Off" und den Schalter auf unchecked lv_label_set_text(ui_lblfanstatus, "OFF"); lv_label_set_text(ui_lblfanfanspeed, "0%"); lv_label_set_text(ui_lblfanspeed, "0%"); lv_label_set_text(ui_lbllightstatus, "OFF"); lv_label_set_text(ui_light1statuslbl, "OFF"); lv_label_set_text(ui_light2statuslbl, "OFF"); //Speichern der var von DutyCycle led1, led2, fan lv_dropdown_clear_options(ui_wifinetlist); // Standardmäßig den Lüfter auf 50% Duty Cycle setzen lv_obj_add_state(ui_switchfanstatus, LV_STATE_CHECKED); lv_obj_send_event(ui_switchfanstatus, LV_EVENT_VALUE_CHANGED, fancycle); //Setup Wifi preferences.begin("wifi", true); String ssid = preferences.getString("ssid", ""); String pw = preferences.getString("pw", ""); int8_t counter = 0; if (ssid != "" && pw != "") { WiFi.begin(ssid.c_str(), pw.c_str()); //WiFi.begin("MeinZuhause", "D4n1e7Y4s3m1nUnd7ey7a"); while (WiFi.status() != WL_CONNECTED && counter != 20) { lv_label_set_text(ui_wifistatus, "Connecting..."); Serial.println("AHHHHHH die Schleife"); delay(500); if (counter == 19) { ESP.restart(); } ++counter; } lv_label_set_text(ui_wifistatus, "Connected"); } preferences.end(); //Test GrowProgram preferences.begin("g_phase", true); bool light_status = preferences.getBool("light_status", false); int led1 = preferences.getInt(led1cycle, 860); int led2 = preferences.getInt(led2cycle, 860); bool veggie = preferences.getBool("veggie"); bool flowering = preferences.getBool("flowering"); if (veggie) { lv_dropdown_set_selected(ui_growmode, 1); } else if (flowering) { lv_dropdown_set_selected(ui_growmode, 2); } else { lv_dropdown_set_selected(ui_growmode, 0); } preferences.end(); Serial.println("VON SETUP"); Serial.print("MODUS VEGGIE: "); Serial.println(veggie); Serial.print("MODUS FLOWERING: "); Serial.println(flowering); Serial.print("LICHTSTATUS: "); Serial.println(light_status); Serial.print("LED1: "); Serial.println(led1); Serial.print("LED2: "); Serial.println(led2); configTime(gmt_offset_sec, daylight_offset_sec, ntp); printTime(); targettime = timeinfo; startup = true; lv_obj_add_event_cb(ui_growmode, setMode, LV_EVENT_VALUE_CHANGED, NULL); WiFi.disconnect(); } void loop () { lv_timer_handler(); /* Lässt die GUI ihre Arbeit verrichten */ static unsigned int lastUpdate = 0; static unsigned int lastUpdate2 = 0; const unsigned int updateInterval = 1000; //60 sekunden unsigned long currentMillis = millis(); if (currentMillis - lastUpdate >= updateInterval) { printTime(); lastUpdate = currentMillis; } if (currentMillis - lastUpdate2 >= updateVeggieMode) { Serial.print("UPDATE LOOP: "); Serial.println(updateVeggieMode); growMode(); lastUpdate2 = currentMillis; } } void saveModeSettings(lv_event_t * e) { char mode[32]; char start_h[32]; char start_m[32]; char end_h[32]; char end_m[32]; lv_dropdown_get_selected_str(ui_setmode, mode, sizeof(mode)); lv_roller_get_selected_str(ui_starthour, start_h, sizeof(start_h)); lv_roller_get_selected_str(ui_endhour, end_h, sizeof(end_h)); lv_roller_get_selected_str(ui_startmin, start_m, sizeof(start_h)); lv_roller_get_selected_str(ui_endmin, end_m, sizeof(end_h)); int start_hour = atoi(start_h); int start_min = atoi(start_m); int end_hour = atoi(end_h); int end_min = atoi(end_m); preferences.begin("g_phase", false); if (!strncmp(mode, "Veggie", 6)) { preferences.putInt("veggie_start_h", start_hour); preferences.putInt("veggie_start_m", start_min); preferences.putInt("veggie_end_h", end_hour); preferences.putInt("veggie_end_m", end_min); } else if (!strncmp(mode, "Flower", 6)) { preferences.putInt("flower_start_h", start_hour); preferences.putInt("flower_start_m", start_min); preferences.putInt("flower_end_h", end_hour); preferences.putInt("flower_end_m", end_min); } preferences.end(); } void setMode(lv_event_t * e) { char mode[8]; lv_dropdown_get_selected_str(ui_growmode, mode, sizeof(mode)); preferences.begin("g_phase", false); if (!strncmp(mode, "Manuell", 7)) { preferences.putBool("veggie", false); preferences.putBool("flowering", false); } else if (!strncmp(mode, "Veggie", 6)) { preferences.putBool("veggie", true); preferences.putBool("flowering", false); targettime = timeinfo; growMode(); } else { preferences.putBool("veggie", false); preferences.putBool("flowering", true); targettime = timeinfo; growMode(); } preferences.end(); } void modeOn() { lv_obj_add_state(ui_light1switch, LV_STATE_CHECKED); lv_obj_add_state(ui_light2switch, LV_STATE_CHECKED); lv_obj_send_event(ui_light1switch, LV_EVENT_VALUE_CHANGED, led1cycle); lv_obj_send_event(ui_light2switch, LV_EVENT_VALUE_CHANGED, led2cycle); } void modeOff() { lv_obj_remove_state(ui_light1switch, LV_STATE_CHECKED); lv_obj_remove_state(ui_light2switch, LV_STATE_CHECKED); lv_obj_send_event(ui_light1switch, LV_EVENT_VALUE_CHANGED, led1cycle); lv_obj_send_event(ui_light2switch, LV_EVENT_VALUE_CHANGED, led2cycle); } void growMode() { Serial.println("GROWMODE"); preferences.begin("g_phase", true); bool lights = preferences.getBool("light"); bool veggie_state = preferences.getBool("veggie"); bool flower_state = preferences.getBool("flowering"); Serial.print("Veggie: "); Serial.println(veggie_state); Serial.print("Flowering: "); Serial.println(flower_state); Serial.print("Status Licht:"); Serial.println(lights); Serial.println("###################"); preferences.end(); if (veggie_state || flower_state) { preferences.begin("g_phase", true); Serial.println("IF VEGGIE OR FLOWER ACTIVE"); int start_h; int start_m; int end_h; int end_m; Serial.println("###################"); if (veggie_state) { Serial.println("IF VEGGIE"); start_h = preferences.getInt("veggie_start_h"); start_m = preferences.getInt("veggie_start_m"); end_h = preferences.getInt("veggie_end_h"); end_m = preferences.getInt("veggie_end_m"); Serial.println("###################"); } else { Serial.println("IF FLOWER"); start_h = preferences.getInt("flower_start_h"); start_m = preferences.getInt("flower_start_m"); end_h = preferences.getInt("flower_end_h"); end_m = preferences.getInt("flower_end_m"); Serial.println("###################"); } preferences.end(); time_t diff_start = getDiffTime(start_h, start_m); time_t diff_end = getDiffTime(end_h, end_m); if (diff_start < 0 && diff_end < 0 && diff_start < diff_end) { Serial.println("IF DIFFS KLEINER THEN 0"); Serial.println("DIFFSTART IST KLEINER"); modeOff(); targettime.tm_mday += 1; diff_start = getDiffTime(start_h, start_m); updateVeggieMode = (diff_start * 1000) + 1000; Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); Serial.println(&targettime, "Targettime: %A, %B %d %Y %H:%M:%S"); Serial.println(diff_start); Serial.println("###################"); } else if (diff_start < 0 && diff_end < 0 && diff_start > diff_end) { Serial.println("IF DIFFS KLEINER THEN 0"); Serial.println("DIFFSTART IST GRÖßER"); modeOn(); targettime.tm_mday += 1; diff_end = getDiffTime(end_h, end_m); updateVeggieMode = (diff_end *1000) + 1000; Serial.println(diff_end); Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); Serial.println(&targettime, "Targettime: %A, %B %d %Y %H:%M:%S"); Serial.println("###################"); } else if (diff_start > 0 && diff_end > 0 && diff_start > diff_end) { Serial.println("IF DIFFS GRÖßER THEN 0"); Serial.println("DIFFSTART IST GRÖßER"); Serial.print("DIFF START: "); Serial.println(diff_start); Serial.print("DIFF END: "); Serial.println(diff_end); modeOn(); updateVeggieMode = (diff_end* 1000) + 1000; Serial.println(updateVeggieMode); Serial.println("###################"); } else if (diff_start > 0 && diff_end > 0 && diff_start < diff_end) { Serial.println("IF DIFFS GRÖßER THEN 0"); Serial.println("DIFFSTART IST KLEINER"); Serial.print("DIFF START: "); Serial.println(diff_start); Serial.print("DIFF END: "); Serial.println(diff_end); modeOff(); updateVeggieMode = (diff_start* 1000) + 1000; Serial.println(updateVeggieMode); Serial.println("###################"); } else { if (lights) { Serial.println("LIGHTS ARE ON"); diff_time = getDiffTime(end_h, end_m); Serial.println(diff_time); Serial.println(&timeinfo, "Testtime: %A, %B %d %Y %H:%M:%S"); Serial.println(&targettime, "Testtime: %A, %B %d %Y %H:%M:%S"); if (diff_time < 0) { modeOff(); diff_time = getDiffTime(start_h, start_m); updateVeggieMode = (diff_time * 1000) + 1000; } else { updateVeggieMode = (diff_time * 1000) + 1000; modeOn(); Serial.print("UPDATE LIGHTS ON: "); Serial.print(updateVeggieMode); Serial.println("###################"); } } else { Serial.println("LIGHTS OFF: "); diff_time = getDiffTime(start_h, start_m); Serial.println(diff_time); Serial.println(&timeinfo, "Testtime: %A, %B %d %Y %H:%M:%S"); Serial.println(&targettime, "Testtime: %A, %B %d %Y %H:%M:%S"); if (diff_time < 0) { modeOn(); diff_time = getDiffTime(end_h, end_m); updateVeggieMode = (diff_time * 1000) + 1000; } else { modeOff(); updateVeggieMode = (diff_time * 1000) + 1000; Serial.print("UPDATE LIGHTS OFF: "); Serial.print(updateVeggieMode); Serial.println("###################"); } } } } preferences.end(); } time_t getDiffTime(int time_h, int time_m) { targettime.tm_hour = time_h; targettime.tm_min = time_m; targettime.tm_sec = 0; target_sec = mktime(&targettime); realtime = mktime(&timeinfo); diff_time = difftime(target_sec, realtime); return diff_time; } void printTime() { if(!getLocalTime(&timeinfo)) { Serial.println("Failed to obtain time"); return; } char clock[80]; strftime(clock,80,"Uhrzeit: %H:%M:%S",&timeinfo); lv_label_set_text(ui_lblclock, clock); }