#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; ESP32Time rtc(3600); //Variablen für PWM int pwm_freq = 5000; int pwm_resolution = 8; int pwm_light_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 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); Serial.println(ssid); Serial.println(pw); WiFi.begin(ssid, pw); int8_t counter; while (WiFi.status() != WL_CONNECTED && counter != 10) { lv_label_set_text(ui_wifistatus, "Connecting..."); // Serial.println("AHHHHHH die Schleife"); delay(500); ++counter; } lv_label_set_text(ui_wifistatus, "Connected"); preferences.begin("wifi", false); preferences.putString("ssid", ssid); preferences.putString("pw", pw); preferences.end(); } 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); preferences.begin("dutycycles", false); 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)) { led1_duty_cycle = preferences.getInt(user_data, 860); 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)) { led2_duty_cycle = preferences.getInt(user_data, 860); 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)) { fan_duty_cycle = preferences.getInt(user_data, 76); 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); } } preferences.end(); } 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) / 255.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); } 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) { 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) / 255.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 = 3; 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); preferences.begin("dutycycles", false); Serial.println(user_data); if (obj == ui_light1up) { if (led1active) { led1_duty_cycle += preferences.getInt(user_data, 860); if (led1_duty_cycle <= 0) led1_duty_cycle = 0; Serial.println(led1_duty_cycle); preferences.putInt(user_data, led1_duty_cycle); dimm(led1_pwm_pin, led1_duty_cycle, ui_light1percent); } } if (obj == ui_light2up) { if (led2active) { led2_duty_cycle += preferences.getInt(user_data, 860); if (led2_duty_cycle <= 0) led2_duty_cycle = 0; Serial.println(led2_duty_cycle); preferences.putInt(user_data, led2_duty_cycle); dimm(led2_pwm_pin, led2_duty_cycle, ui_light2percent); } } if (obj == ui_btnfanup) { if (fan_active) { fan_duty_cycle += preferences.getInt(user_data, 76); if (fan_duty_cycle >= 255) fan_duty_cycle = 255; Serial.println(fan_duty_cycle); preferences.putInt(user_data, fan_duty_cycle); dimm(fan_pwm_pin, fan_duty_cycle, ui_lblfanspeed, ui_lblfanfanspeed); } } preferences.end(); } 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 = -3; int led1_duty_cycle = 10; int led2_duty_cycle = 10; preferences.begin("dutycycles", false); Serial.println(user_data); if (obj == ui_light1down) { if (led1active) { led1_duty_cycle += preferences.getInt(user_data); if (led1_duty_cycle >= 860) led1_duty_cycle = 860; Serial.println(led1_duty_cycle); preferences.putInt(user_data, led1_duty_cycle); dimm(led1_pwm_pin, led1_duty_cycle, ui_light1percent); } } if (obj == ui_light2down) { if (led2active) { led2_duty_cycle += preferences.getInt(user_data); if (led2_duty_cycle >= 860) led2_duty_cycle = 860; Serial.println(led2_duty_cycle); preferences.putInt(user_data, led2_duty_cycle); dimm(led2_pwm_pin, led2_duty_cycle, ui_light2percent); } } if (obj == ui_btnfandown) { if (fan_active) { fan_duty_cycle += preferences.getInt(user_data); if (fan_duty_cycle <= 64) fan_duty_cycle = 64; preferences.putInt(user_data, fan_duty_cycle); dimm(fan_pwm_pin, fan_duty_cycle, ui_lblfanspeed, ui_lblfanfanspeed); } } preferences.end(); } /* 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(); } struct tm timeinfo; struct tm targettime = {0}; time_t realtime; time_t target_sec; time_t endtime; void setup () { Serial.begin( 115200 ); /* Vorbereitung für mögliches serielles Debugging */ 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_light_resolution, led1_pwm_channel); ledcAttachChannel(led2_pwm_pin, pwm_freq, pwm_light_resolution, led2_pwm_channel); // Standardmäßig den Lüfter auf 0% Duty Cycle setzen ledcWrite(fan_pwm_pin, 76); ledcWrite(led1_pwm_pin, 255); ledcWrite(led2_pwm_pin, 255); 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" ); // DHT11-Sensor initialisieren // dht.begin(); // 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); preferences.begin("wifi", false); 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(); int target_h; int target_m; bool lights; preferences.begin("g_phase", false); bool veggie = preferences.getBool("veggie"); bool flowering = preferences.getBool("flowering"); bool veggie_lights_on = preferences.getBool("veggie_on"); bool veggie_lights_off = preferences.getBool("veggie_off"); bool flower_lights_on = preferences.getBool("flower_on"); bool flower_lights_off = preferences.getBool("flower_off"); if (veggie) { lv_dropdown_set_selected(ui_growmode, 1); if (veggie_lights_off) { target_h = preferences.getInt("veggie_start_h"); target_m = preferences.getInt("veggie_start_m"); lights = true; } else { target_h = preferences.getInt("veggie_end_h"); target_m = preferences.getInt("veggie_end_m"); lights = false; } } else if (flowering) { lv_dropdown_set_selected(ui_growmode, 2); } else { lv_dropdown_set_selected(ui_growmode, 0); } int start_flower_h = preferences.getInt("flower_start_h"); int start_flower_m = preferences.getInt("flower_start_m"); int end_flower_h = preferences.getInt("flower_end_h"); int end_flower_m = preferences.getInt("flower_end_m"); preferences.end(); Serial.print("Starttime Flower: "); Serial.print(start_flower_h); Serial.print(":"); Serial.println(start_flower_m); Serial.print("Endtime: "); Serial.print(end_flower_h); Serial.print(":"); Serial.println(end_flower_m); configTime(gmt_offset_sec, daylight_offset_sec, ntp); if(!getLocalTime(&timeinfo)) { Serial.println("Failed to obtain time"); return; } realtime = mktime(&timeinfo); targettime = timeinfo; targettime.tm_hour = target_h; targettime.tm_min = target_m; targettime.tm_sec = 0; target_sec = mktime(&targettime); if (realtime >= target_sec) { } Serial.println(&timeinfo, "Testtime: %A, %B %d %Y %H:%M:%S"); Serial.println(&targettime, "Testtime: %A, %B %d %Y %H:%M:%S"); 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 long lastUpdate = 0; const unsigned long updateInterval = 60000; //60 sekunden static unsigned long lastUpdate2 = 0; const unsigned long updateInterval2 = 1000; unsigned long currentMillis = millis(); if (currentMillis - lastUpdate2 >= updateInterval2) { printTime(); realtime = mktime(&timeinfo); //onTime(); lastUpdate2 = currentMillis; } if (currentMillis - lastUpdate >= updateInterval) { // if (realtime >= testtime2) // { // } lastUpdate = currentMillis; } } void onTime() { // testtime.tm_min += 5; // int seconds = 60 * 5; // testtime2 = mktime(&testtime); // testtime2 += seconds; // struct tm * test = gmtime(&testtime2); // Serial.println(test, "Test: ,%A, %B %d %Y %H:%M:%S"); } 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_startmin, start_m, sizeof(start_h)); lv_roller_get_selected_str(ui_endhour, end_h, sizeof(end_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); } else { preferences.putBool("veggie", false); preferences.putBool("flowering", true); } preferences.end(); } void veggie() { } void flowering() { } void printTime() { struct tm timeinfo; 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); }