diff --git a/CYD-Klipper/.vscode/settings.json b/CYD-Klipper/.vscode/settings.json index e9997e2..8be69ef 100644 --- a/CYD-Klipper/.vscode/settings.json +++ b/CYD-Klipper/.vscode/settings.json @@ -12,6 +12,8 @@ "algorithm": "cpp", "cstddef": "cpp", "functional": "cpp", - "*.tcc": "cpp" - } + "*.tcc": "cpp", + "cmath": "cpp" + }, + "cmake.configureOnOpen": false } \ No newline at end of file diff --git a/CYD-Klipper/boards/esp32-2432S022C-smartdisplay.json b/CYD-Klipper/boards/esp32-2432S022C-smartdisplay.json new file mode 100644 index 0000000..6359d76 --- /dev/null +++ b/CYD-Klipper/boards/esp32-2432S022C-smartdisplay.json @@ -0,0 +1,126 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": [ + "'-D ARDUINO_ESP32_DEV'", + "'-D ESP32_2432S022C'", + "'-D LCD_WIDTH=240'", + "'-D LCD_HEIGHT=320'", + "'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'", + "'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'", + "'-D BCKL=0'", + "'-D LCD_ST7789_I80'", + "'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'", + "'-D ST7789_I80_BUS_CONFIG_DC=16'", + "'-D ST7789_I80_BUS_CONFIG_WR=4'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D8=15'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D9=13'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D10=12'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D11=14'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D12=27'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D13=25'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D14=33'", + "'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D15=32'", + "'-D ST7789_I80_BUS_CONFIG_BUS_WIDTH=8'", + "'-D ST7789_I80_BUS_CONFIG_MAX_TRANSFER_BYTES=(LVGL_BUFFER_PIXELS * sizeof(lv_color_t))'", + "'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'", + "'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'", + "'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'", + "'-D ST7789_IO_I80_CONFIG_PCLK_HZ=55000000'", + "'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'", + "'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'", + "'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'", + "'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_IDLE_LEVEL=0'", + "'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_CMD_LEVEL=0'", + "'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DUMMY_LEVEL=0'", + "'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DATA_LEVEL=1'", + "'-D ST7789_IO_I80_CONFIG_FLAGS_CS_ACTIVE_HIGH=0'", + "'-D ST7789_IO_I80_CONFIG_FLAGS_REVERSE_COLOR_BITS=0'", + "'-D ST7789_IO_I80_CONFIG_FLAGS_SWAP_COLOR_BYTES=0'", + "'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'", + "'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=0'", + "'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'", + "'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'", + "'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'", + "'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'", + "'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'", + "'-D ST7789_RD_GPIO=2'", + "'-D LCD_SWAP_XY=false'", + "'-D LCD_MIRROR_X=false'", + "'-D LCD_MIRROR_Y=false'", + "'-D BOARD_HAS_TOUCH'", + "'-D TOUCH_CST816S_I2C'", + "'-D CST816S_I2C_HOST=0'", + "'-D CST816S_I2C_CONFIG_SDA_IO_NUM=21'", + "'-D CST816S_I2C_CONFIG_SCL_IO_NUM=22'", + "'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'", + "'-D CST816S_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'", + "'-D CST816S_I2C_CONFIG_MASTER_CLK_SPEED=400000'", + "'-D CST816S_I2C_CONFIG_CLK_FLAGS=0'", + "'-D CST816S_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS'", + "'-D CST816S_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'", + "'-D CST816S_IO_I2C_CONFIG_DC_BIT_OFFSET=0'", + "'-D CST816S_IO_I2C_CONFIG_LCD_CMD_BITS=8'", + "'-D CST816S_IO_I2C_CONFIG_LCD_PARAM_BITS=0'", + "'-D CST816S_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'", + "'-D CST816S_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'", + "'-D CST816S_TOUCH_CONFIG_X_MAX=LCD_WIDTH'", + "'-D CST816S_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'", + "'-D CST816S_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'", + "'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=GPIO_NUM_NC'", + "'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'", + "'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'", + "'-D TOUCH_SWAP_XY=false'", + "'-D TOUCH_SWAP_X=false'", + "'-D TOUCH_SWAP_Y=false'", + "'-D BOARD_HAS_TF'", + "'-D TF_CS=5'", + "'-D TF_SPI_MOSI=23'", + "'-D TF_SPI_SCLK=18'", + "'-D TF_SPI_MISO=19'", + "'-D BOARD_HAS_SPEAK'", + "'-D SPEAK=26'", + + "-DCYD_SCREEN_GAP_PX=8", + "-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35", + "-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35", + "-DCYD_SCREEN_FONT=lv_font_montserrat_14", + "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10", + "-DCYD_SCREEN_SIDEBAR_SIZE_PX=40", + "-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1", + "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1", + "-DCYD_SCREEN_DISABLE_INVERT_COLORS=1" + ], + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "esp32-2432S022C", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.aliexpress.com/item/1005006284154750.html", + "vendor": "Sunton" + } \ No newline at end of file diff --git a/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json b/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json new file mode 100644 index 0000000..2d8de26 --- /dev/null +++ b/CYD-Klipper/boards/esp32-2432S028R-smartdisplay.json @@ -0,0 +1,126 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": [ + "'-D ARDUINO_ESP32_DEV'", + "'-D ESP32_2432S028Rv3'", + "'-D LCD_WIDTH=240'", + "'-D LCD_HEIGHT=320'", + "'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'", + "'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'", + "'-D BCKL=21'", + "'-D LCD_ST7789_SPI'", + "'-D ST7789_SPI_HOST=SPI2_HOST'", + "'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'", + "'-D ST7789_SPI_BUS_MOSI_IO_NUM=13'", + "'-D ST7789_SPI_BUS_MISO_IO_NUM=GPIO_NUM_NC'", + "'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'", + "'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'", + "'-D ST7789_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'", + "'-D ST7789_SPI_BUS_MAX_TRANSFER_SZ=0'", + "'-D ST7789_SPI_BUS_FLAGS=0'", + "'-D ST7789_SPI_BUS_INTR_FLAGS=0'", + "'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'", + "'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'", + "'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'", + "'-D ST7789_SPI_CONFIG_PCLK_HZ=55000000'", + "'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'", + "'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'", + "'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'", + "'-D ST7789_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'", + "'-D ST7789_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'", + "'-D ST7789_SPI_CONFIG_FLAGS_OCTAL_MODE=false'", + "'-D ST7789_SPI_CONFIG_FLAGS_LSB_FIRST=false'", + "'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'", + "'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'", + "'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'", + "'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'", + "'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'", + "'-D LCD_SWAP_XY=false'", + "'-D LCD_MIRROR_X=false'", + "'-D LCD_MIRROR_Y=false'", + "'-D BOARD_HAS_TOUCH'", + "'-D TOUCH_XPT2046_SPI'", + "'-D XPT2046_SPI_HOST=SPI3_HOST'", + "'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'", + "'-D XPT2046_SPI_BUS_MOSI_IO_NUM=32'", + "'-D XPT2046_SPI_BUS_MISO_IO_NUM=39'", + "'-D XPT2046_SPI_BUS_SCLK_IO_NUM=25'", + "'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'", + "'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'", + "'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=33'", + "'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'", + "'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'", + "'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'", + "'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'", + "'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'", + "'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'", + "'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'", + "'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'", + "'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'", + "'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'", + "'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'", + "'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'", + "'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'", + "'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=36'", + "'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'", + "'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'", + "'-D TOUCH_SWAP_XY=true'", + "'-D TOUCH_SWAP_X=true'", + "'-D TOUCH_SWAP_Y=false'", + "'-D BOARD_HAS_TF'", + "'-D TF_CS=5'", + "'-D TF_SPI_MOSI=23'", + "'-D TF_SPI_SCLK=18'", + "'-D TF_SPI_MISO=19'", + "'-D BOARD_HAS_RGB_LED'", + "'-D RGB_LED_R=4'", + "'-D RGB_LED_G=16'", + "'-D RGB_LED_B=17'", + "'-D BOARD_HAS_CDS'", + "'-D CDS=34'", + "'-D BOARD_HAS_SPEAK'", + "'-D SPEAK=26'", + + "-DCYD_SCREEN_GAP_PX=8", + "-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35", + "-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35", + "-DCYD_SCREEN_FONT=lv_font_montserrat_14", + "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10", + "-DCYD_SCREEN_SIDEBAR_SIZE_PX=40", + "-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1", + "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1" + ], + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "esp32-2432S028Rv3", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.aliexpress.com/item/1005004502250619.html", + "vendor": "Sunton" + } \ No newline at end of file diff --git a/CYD-Klipper/boards/esp32-2432S028R.json b/CYD-Klipper/boards/esp32-2432S028R.json index 640ec47..fe82521 100644 --- a/CYD-Klipper/boards/esp32-2432S028R.json +++ b/CYD-Klipper/boards/esp32-2432S028R.json @@ -16,9 +16,6 @@ "-DTFT_DC=2", "-DTFT_RST=-1", "-DLOAD_GCLD=1", - "-DLOAD_FONT2=1", - "-DLOAD_GFXFF=1", - "-DSMOOTH_FONT=1", "-DSPI_FREQUENCY=55000000", "-DSPI_READ_FREQUENCY=20000000", "-DSPI_TOUCH_FREQUENCY=2500000", diff --git a/CYD-Klipper/boards/esp32-3248S035C-smartdisplay.json b/CYD-Klipper/boards/esp32-3248S035C-smartdisplay.json index 07da97e..25e1f76 100644 --- a/CYD-Klipper/boards/esp32-3248S035C-smartdisplay.json +++ b/CYD-Klipper/boards/esp32-3248S035C-smartdisplay.json @@ -21,7 +21,7 @@ "'-D ST7796_SPI_CONFIG_CS_GPIO_NUM=15'", "'-D ST7796_SPI_CONFIG_DC_GPIO_NUM=2'", "'-D ST7796_SPI_CONFIG_SPI_MODE=SPI_MODE0'", - "'-D ST7796_SPI_CONFIG_PCLK_HZ=24000000'", + "'-D ST7796_SPI_CONFIG_PCLK_HZ=80000000'", "'-D ST7796_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'", "'-D ST7796_SPI_CONFIG_LCD_CMD_BITS=8'", "'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'", @@ -74,7 +74,17 @@ "'-D BOARD_HAS_CDS'", "'-D CDS=34'", "'-D BOARD_HAS_SPEAK'", - "'-D SPEAK=26'" + "'-D SPEAK=26'", + + "-DCYD_SCREEN_GAP_PX=10", + "-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40", + "-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40", + "-DCYD_SCREEN_FONT=lv_font_montserrat_16", + "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12", + "-DCYD_SCREEN_SIDEBAR_SIZE_PX=50", + "-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1", + "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1", + "-DCYD_SCREEN_DISABLE_INVERT_COLORS=1" ], "f_cpu": "240000000L", "f_flash": "40000000L", diff --git a/CYD-Klipper/boards/esp32-3248S035C.json b/CYD-Klipper/boards/esp32-3248S035C.json index 807eee6..5c39227 100644 --- a/CYD-Klipper/boards/esp32-3248S035C.json +++ b/CYD-Klipper/boards/esp32-3248S035C.json @@ -16,9 +16,6 @@ "-DTFT_DC=2", "-DTFT_RST=-1", "-DLOAD_GCLD=1", - "-DLOAD_FONT2=1", - "-DLOAD_GFXFF=1", - "-DSMOOTH_FONT=1", "-DSPI_FREQUENCY=80000000", "-DSPI_READ_FREQUENCY=20000000", "-DSPI_TOUCH_FREQUENCY=2500000", diff --git a/CYD-Klipper/extract_commit.py b/CYD-Klipper/extract_commit.py index e8f1e52..9362f66 100644 --- a/CYD-Klipper/extract_commit.py +++ b/CYD-Klipper/extract_commit.py @@ -15,11 +15,17 @@ except: version = "Unknown" flag = "-D REPO_VERSION=\\\"" + version + "\\\"" +dev_flag = "-DREPO_DEVELOPMENT=1" print(f"Version: {version}") print(f"Flag: {flag}") +flags = [flag] + +if ('(' in version): + flags.append(dev_flag) + Import("env") env.Append( - BUILD_FLAGS=[flag] + BUILD_FLAGS=flags ) \ No newline at end of file diff --git a/CYD-Klipper/platformio.ini b/CYD-Klipper/platformio.ini index 5a6c0ed..7a62560 100644 --- a/CYD-Klipper/platformio.ini +++ b/CYD-Klipper/platformio.ini @@ -21,7 +21,7 @@ monitor_filters = esp32_exception_decoder build_flags = -DLV_CONF_PATH="../../../../src/conf/lv_conf.h" extra_scripts = - pre:extract_commit.py + pre:extract_commit.py [env:esp32-2432S028R] board = esp32-2432S028R @@ -43,17 +43,8 @@ lib_deps = bblanchon/ArduinoJson@^7.0.0 plageoj/UrlEncode@^1.0.1 -# Terribly slow. Only use for development -# [env:esp32-3248S035C-smartdisplay] -# board = esp32-3248S035C-smartdisplay -# build_flags = -# -DLV_CONF_PATH="../../../../src/conf/lv_conf.h" -# -DCYD_SCREEN_HEIGHT_PX=320 -# -DCYD_SCREEN_WIDTH_PX=480 -# -DCYD_SCREEN_GAP_PX=10 -# -DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40 -# -DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40 -# -DCYD_SCREEN_FONT=lv_font_montserrat_16 -# -DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12 -# -DCYD_SCREEN_SIDEBAR_SIZE_PX=50 -# -DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1 \ No newline at end of file +[env:esp32-3248S035C-smartdisplay] +board = esp32-3248S035C-smartdisplay + +[env:esp32-2432S028R-smartdisplay] +board = esp32-2432S028R-smartdisplay diff --git a/CYD-Klipper/src/conf/global_config.h b/CYD-Klipper/src/conf/global_config.h index 55a85c9..4ed198e 100644 --- a/CYD-Klipper/src/conf/global_config.h +++ b/CYD-Klipper/src/conf/global_config.h @@ -5,6 +5,12 @@ #define CONFIG_VERSION 4 +enum { + REMAINING_TIME_CALC_PERCENTAGE = 0, + REMAINING_TIME_CALC_INTERPOLATED = 1, + REMAINING_TIME_CALC_SLICER = 2, +}; + typedef struct _GLOBAL_CONFIG { unsigned char version; union { @@ -21,6 +27,10 @@ typedef struct _GLOBAL_CONFIG { bool rotateScreen : 1; bool onDuringPrint : 1; bool autoOtaUpdate : 1; + unsigned char remaining_time_calc_mode : 2; + + // Internal + bool auth_configured : 1; }; }; float screenCalXOffset; @@ -40,6 +50,8 @@ typedef struct _GLOBAL_CONFIG { unsigned short hotend_presets[3]; unsigned short bed_presets[3]; + + char klipper_auth[33]; } GLOBAL_CONFIG; typedef struct _COLOR_DEF { diff --git a/CYD-Klipper/src/conf/lv_conf.h b/CYD-Klipper/src/conf/lv_conf.h index ef6a52c..76bbcbe 100644 --- a/CYD-Klipper/src/conf/lv_conf.h +++ b/CYD-Klipper/src/conf/lv_conf.h @@ -242,8 +242,12 @@ * Others *-----------*/ +#ifndef REPO_DEVELOPMENT + #define REPO_DEVELOPMENT 0 +#endif + /*1: Show CPU usage and FPS count*/ -#define LV_USE_PERF_MONITOR 0 +#define LV_USE_PERF_MONITOR REPO_DEVELOPMENT #if LV_USE_PERF_MONITOR #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT #endif @@ -497,7 +501,7 @@ #define LV_USE_MSG 1 -#define LV_USE_CHART 0 +#define LV_USE_CHART 1 #define LV_USE_COLORWHEEL 0 diff --git a/CYD-Klipper/src/core/data_setup.cpp b/CYD-Klipper/src/core/data_setup.cpp index d240d6d..d60de6e 100644 --- a/CYD-Klipper/src/core/data_setup.cpp +++ b/CYD-Klipper/src/core/data_setup.cpp @@ -50,6 +50,9 @@ void send_gcode(bool wait, const char *gcode) HTTPClient client; client.begin(buff); + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + if (!wait) { client.setTimeout(1000); @@ -65,6 +68,63 @@ void send_gcode(bool wait, const char *gcode) } } +int get_slicer_time_estimate_s() +{ + if (printer.state == PRINTER_STATE_IDLE) + return 0; + + delay(10); + + char buff[256] = {}; + sprintf(buff, "http://%s:%d/server/files/metadata?filename=%s", global_config.klipperHost, global_config.klipperPort, urlEncode(printer.print_filename).c_str()); + HTTPClient client; + client.useHTTP10(true); + client.begin(buff); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + + int httpCode = client.GET(); + + if (httpCode != 200) + return 0; + + JsonDocument doc; + deserializeJson(doc, client.getStream()); + int time_estimate_s = doc["result"]["estimated_time"]; + Serial.printf("Got slicer time estimate: %ds\n", time_estimate_s); + return time_estimate_s; +} + +void move_printer(const char* axis, float amount, bool relative) { + if (!printer.homed_axis || printer.state == PRINTER_STATE_PRINTING) + return; + + char gcode[64]; + const char* extra = (amount > 0) ? "+" : ""; + + bool absolute_coords = printer.absolute_coords; + + if (absolute_coords && relative) { + send_gcode(true, "G91"); + } + else if (!absolute_coords && !relative) { + send_gcode(true, "G90"); + } + + sprintf(gcode, "G1 %s%s%.3f F6000", axis, extra, amount); + send_gcode(true, gcode); + + if (absolute_coords && relative) { + send_gcode(true, "G90"); + } + else if (!absolute_coords && !relative) { + send_gcode(true, "G91"); + } +} + +int last_slicer_time_query = -15000; + void fetch_printer_data() { freeze_request_thread(); @@ -73,6 +133,10 @@ void fetch_printer_data() HTTPClient client; client.useHTTP10(true); client.begin(buff); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + int httpCode = client.GET(); delay(10); if (httpCode == 200) @@ -122,6 +186,7 @@ void fetch_printer_data() printer.extruder_target_temp = status["extruder"]["target"]; bool can_extrude = status["extruder"]["can_extrude"]; printer.pressure_advance = status["extruder"]["pressure_advance"]; + printer.smooth_time = status["extruder"]["smooth_time"]; printer.can_extrude = can_extrude == true; } @@ -175,7 +240,11 @@ void fetch_printer_data() const char *state = status["print_stats"]["state"]; - if (strcmp(state, "printing") == 0) + if (state == nullptr) + { + printer_state = PRINTER_STATE_ERROR; + } + else if (strcmp(state, "printing") == 0) { printer_state = PRINTER_STATE_PRINTING; } @@ -194,7 +263,36 @@ void fetch_printer_data() if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0) { - printer.remaining_time_s = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s; + float remaining_time_s_percentage = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s; + float remaining_time_s_slicer = 0; + + if (printer.slicer_estimated_print_time_s > 0) + { + remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.elapsed_time_s; + } + + if (remaining_time_s_slicer <= 0 || global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE) + { + printer.remaining_time_s = remaining_time_s_percentage; + } + else if (global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_INTERPOLATED) + { + printer.remaining_time_s = remaining_time_s_percentage * printer.print_progress + remaining_time_s_slicer * (1 - printer.print_progress); + } + else if (global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_SLICER) + { + printer.remaining_time_s = remaining_time_s_slicer; + } + } + + if (printer.remaining_time_s < 0) + { + printer.remaining_time_s = 0; + } + + if (printer.state == PRINTER_STATE_IDLE) + { + printer.slicer_estimated_print_time_s = 0; } lv_msg_send(DATA_PRINTER_DATA, &printer); @@ -205,6 +303,13 @@ void fetch_printer_data() printer.state = printer_state; lv_msg_send(DATA_PRINTER_STATE, &printer); } + + if (printer.state == PRINTER_STATE_PRINTING && millis() - last_slicer_time_query > 30000 && printer.slicer_estimated_print_time_s <= 0) + { + delay(10); + last_slicer_time_query = millis(); + printer.slicer_estimated_print_time_s = get_slicer_time_estimate_s(); + } unfreeze_render_thread(); } diff --git a/CYD-Klipper/src/core/data_setup.h b/CYD-Klipper/src/core/data_setup.h index 57e4e74..d1a4224 100644 --- a/CYD-Klipper/src/core/data_setup.h +++ b/CYD-Klipper/src/core/data_setup.h @@ -23,8 +23,8 @@ typedef struct _Printer { float elapsed_time_s; float remaining_time_s; float filament_used_mm; - char* print_filename; // 0 -> 1 - float print_progress; + char* print_filename; + float print_progress; // 0 -> 1 float fan_speed; // 0 -> 1 float gcode_offset[3]; float speed_mult; @@ -32,7 +32,9 @@ typedef struct _Printer { int total_layers; int current_layer; float pressure_advance; + float smooth_time; int feedrate_mm_per_s; + int slicer_estimated_print_time_s; } Printer; extern Printer printer; @@ -45,6 +47,7 @@ extern int klipper_request_consecutive_fail_count; void data_loop(); void data_setup(); void send_gcode(bool wait, const char* gcode); +void move_printer(const char* axis, float amount, bool relative); void freeze_request_thread(); void unfreeze_request_thread(); \ No newline at end of file diff --git a/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp b/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp index 3112dfa..1543e2c 100644 --- a/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp +++ b/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp @@ -25,71 +25,6 @@ static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10]; TFT_eSPI tft = TFT_eSPI(); -TS_Point touchscreen_point() -{ - TS_Point p = touchscreen.getPoint(); - p.x = round((p.x * global_config.screenCalXMult) + global_config.screenCalXOffset); - p.y = round((p.y * global_config.screenCalYMult) + global_config.screenCalYOffset); - return p; -} - -void touchscreen_calibrate(bool force) -{ - if (global_config.screenCalibrated && !force) - { - return; - } - - tft.fillScreen(TFT_BLACK); - tft.setCursor(20, 140); - tft.setTextColor(TFT_WHITE, TFT_BLACK); - tft.setTextSize(2); - tft.println("Calibrate Screen"); - - TS_Point p; - int16_t x1, y1, x2, y2; - - while (touchscreen.touched()) - ; - tft.drawFastHLine(0, 10, 20, ILI9341_WHITE); - tft.drawFastVLine(10, 0, 20, ILI9341_WHITE); - while (!touchscreen.touched()) - ; - delay(50); - p = touchscreen.getPoint(); - x1 = p.x; - y1 = p.y; - tft.drawFastHLine(0, 10, 20, ILI9341_BLACK); - tft.drawFastVLine(10, 0, 20, ILI9341_BLACK); - delay(500); - - while (touchscreen.touched()) - ; - tft.drawFastHLine(300, 230, 20, ILI9341_WHITE); - tft.drawFastVLine(310, 220, 20, ILI9341_WHITE); - - while (!touchscreen.touched()) - ; - delay(50); - p = touchscreen.getPoint(); - x2 = p.x; - y2 = p.y; - tft.drawFastHLine(300, 230, 20, ILI9341_BLACK); - tft.drawFastVLine(310, 220, 20, ILI9341_BLACK); - - int16_t xDist = 320 - 20; - int16_t yDist = 240 - 20; - - global_config.screenCalXMult = (float)xDist / (float)(x2 - x1); - global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult); - - global_config.screenCalYMult = (float)yDist / (float)(y2 - y1); - global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult); - - global_config.screenCalibrated = true; - WriteGlobalConfig(); -} - void screen_setBrightness(byte brightness) { // calculate duty, 4095 from 2 ^ 12 - 1 @@ -116,7 +51,7 @@ void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) { if (touchscreen.tirqTouched() && touchscreen.touched()) { - TS_Point p = touchscreen_point(); + TS_Point p = touchscreen.getPoint(); data->state = LV_INDEV_STATE_PR; data->point.x = p.x; data->point.y = p.y; @@ -152,8 +87,6 @@ void screen_setup() touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); touchscreen.begin(touchscreen_spi); - touchscreen_calibrate(false); - lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10); /*Initialize the display*/ diff --git a/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp b/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp index 3855bd6..e338982 100644 --- a/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp +++ b/CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp @@ -7,11 +7,8 @@ #include "lvgl.h" #include "../lv_setup.h" -void touchscreen_calibrate(bool force) -{ - // TODO: Stubbed - return; -} +typedef void (*lv_disp_drv_t_flush_cb)(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); +static lv_disp_drv_t_flush_cb original_screen_driver; void screen_setBrightness(byte brightness) { @@ -19,13 +16,34 @@ void screen_setBrightness(byte brightness) } void set_invert_display(){ - // Stubbed + lv_obj_invalidate(lv_scr_act()); +} + +void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +{ + if (global_config.invertColors) { + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + + for (int i = 0 ; i < w * h; i++){ + color_p[i].full ^= 0xFFFF; + } + } + + original_screen_driver(disp_drv, area, color_p); } void screen_setup() { smartdisplay_init(); +#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS + if (original_screen_driver == NULL){ + original_screen_driver = lv_disp_get_default()->driver->flush_cb; + lv_disp_get_default()->driver->flush_cb = lv_screen_intercept; + } +#endif // CYD_SCREEN_DISABLE_INVERT_COLORS + lv_disp_set_rotation(lv_disp_get_default(), (global_config.rotateScreen) ? LV_DISP_ROT_270 : LV_DISP_ROT_90); } diff --git a/CYD-Klipper/src/core/files_query.cpp b/CYD-Klipper/src/core/files_query.cpp index 0fce127..326623b 100644 --- a/CYD-Klipper/src/core/files_query.cpp +++ b/CYD-Klipper/src/core/files_query.cpp @@ -33,6 +33,10 @@ FILESYSTEM_FILE* get_files(int limit){ client.useHTTP10(true); client.setTimeout(5000); client.begin(buff); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + int httpCode = client.GET(); auto timer_parse = millis(); diff --git a/CYD-Klipper/src/core/lv_setup.cpp b/CYD-Klipper/src/core/lv_setup.cpp index ac84c49..eb9700d 100644 --- a/CYD-Klipper/src/core/lv_setup.cpp +++ b/CYD-Klipper/src/core/lv_setup.cpp @@ -2,6 +2,7 @@ #include "screen_driver.h" #include "../conf/global_config.h" #include "lvgl.h" +#include "../ui/ui_utils.h" #include #ifndef CPU_FREQ_HIGH @@ -13,8 +14,131 @@ typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data); -bool isScreenInSleep = false; -lv_timer_t *screenSleepTimer; +bool is_screen_in_sleep = false; +lv_timer_t *screen_sleep_timer; +lv_coord_t point[2] = {0}; + +static lv_indev_drv_read_cb_t original_touch_driver = NULL; + +void lv_touch_intercept_calibration(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) +{ + original_touch_driver(indev_driver, data); + + if (data->state == LV_INDEV_STATE_PR){ + point[0] = data->point.x; + point[1] = data->point.y; + + while (data->state == LV_INDEV_STATE_PR){ + original_touch_driver(indev_driver, data); + delay(20); + } + } + + data->state = LV_INDEV_STATE_REL; +} + +void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) +{ + original_touch_driver(indev_driver, data); + + if (data->state == LV_INDEV_STATE_PR) { + if (is_screen_asleep()) { + while (data->state == LV_INDEV_STATE_PR) { + original_touch_driver(indev_driver, data); + delay(20); + } + + data->state = LV_INDEV_STATE_REL; + } + + screen_timer_wake(); +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + data->point.x = round((data->point.x * global_config.screenCalXMult) + global_config.screenCalXOffset); + data->point.y = round((data->point.y * global_config.screenCalYMult) + global_config.screenCalYOffset); +#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + } +} + +void lv_do_calibration(){ + if (global_config.screenCalibrated){ + return; + } + + lv_indev_t * display_driver = lv_indev_get_next(NULL); + display_driver->driver->read_cb = lv_touch_intercept_calibration; + + lv_obj_clean(lv_scr_act()); + lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t * label = lv_label_create(lv_scr_act()); + lv_label_set_text(label, "Calibrate Screen"); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t * line = lv_line_create(lv_scr_act()); + static lv_point_t line_points_x[] = { {0, 10}, {21, 10} }; + static lv_point_t line_points_y[] = { {10, 0}, {10, 21} }; + + lv_line_set_points(line, line_points_x, 2); + lv_obj_align(line, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_set_style_line_width(line, 1, 0); + + lv_obj_t * line2 = lv_line_create(lv_scr_act()); + lv_line_set_points(line2, line_points_y, 2); + lv_obj_align(line2, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_set_style_line_width(line2, 1, 0); + + while (true){ + lv_timer_handler(); + lv_task_handler(); + + if (point[0] != 0 && point[1] != 0){ + break; + } + } + + lv_coord_t x1 = point[0]; + lv_coord_t y1 = point[1]; + point[0] = 0; + point[1] = 0; + + lv_obj_del(line); + lv_obj_del(line2); + + line = lv_line_create(lv_scr_act()); + lv_line_set_points(line, line_points_x, 2); + lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, 1, -10); + lv_obj_set_style_line_width(line, 1, 0); + + line = lv_line_create(lv_scr_act()); + lv_line_set_points(line, line_points_y, 2); + lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, -10, 1); + + while (true){ + lv_timer_handler(); + lv_task_handler(); + + if (point[0] != 0 && point[1] != 0){ + break; + } + } + + lv_coord_t x2 = point[0]; + lv_coord_t y2 = point[1]; + + int16_t xDist = CYD_SCREEN_WIDTH_PX - 20; + int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20; + + global_config.screenCalXMult = (float)xDist / (float)(x2 - x1); + global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult); + + global_config.screenCalYMult = (float)yDist / (float)(y2 - y1); + global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult); + + global_config.screenCalibrated = true; + WriteGlobalConfig(); + + lv_obj_clean(lv_scr_act()); +} void set_screen_brightness() { @@ -27,13 +151,13 @@ void set_screen_brightness() void screen_timer_wake() { #ifndef CYD_SCREEN_DISABLE_TIMEOUT - lv_timer_reset(screenSleepTimer); + lv_timer_reset(screen_sleep_timer); - if (!isScreenInSleep){ + if (!is_screen_in_sleep){ return; } - isScreenInSleep = false; + is_screen_in_sleep = false; set_screen_brightness(); // Reset cpu freq @@ -46,7 +170,7 @@ void screen_timer_sleep(lv_timer_t *timer) { #ifndef CYD_SCREEN_DISABLE_TIMEOUT screen_setBrightness(0); - isScreenInSleep = true; + is_screen_in_sleep = true; // Screen is off, no need to make the cpu run fast, the user won't notice ;) setCpuFrequencyMhz(CPU_FREQ_LOW); @@ -56,23 +180,23 @@ void screen_timer_sleep(lv_timer_t *timer) void screen_timer_setup() { - screenSleepTimer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL); - lv_timer_pause(screenSleepTimer); + screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL); + lv_timer_pause(screen_sleep_timer); } void screen_timer_start() { - lv_timer_resume(screenSleepTimer); + lv_timer_resume(screen_sleep_timer); } void screen_timer_stop() { - lv_timer_pause(screenSleepTimer); + lv_timer_pause(screen_sleep_timer); } void screen_timer_period(unsigned int period) { - lv_timer_set_period(screenSleepTimer, period); + lv_timer_set_period(screen_sleep_timer, period); } void set_screen_timer_period() @@ -100,41 +224,28 @@ void set_color_scheme() lv_disp_set_theme(dispp, theme); } -static lv_indev_drv_read_cb_t original_driver = NULL; - -void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) -{ - original_driver(indev_driver, data); - - if (data->state == LV_INDEV_STATE_PR) { - if (is_screen_asleep()) { - while (data->state == LV_INDEV_STATE_PR) { - original_driver(indev_driver, data); - delay(20); - } - - data->state = LV_INDEV_STATE_REL; - } - - screen_timer_wake(); - } -} - void lv_setup() { - screen_timer_setup(); - screen_timer_start(); + lv_indev_t * display_driver = lv_indev_get_next(NULL); + + if (original_touch_driver == NULL) + { + original_touch_driver = display_driver->driver->read_cb; + } + set_color_scheme(); - if (original_driver != NULL) - return; +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + lv_do_calibration(); +#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION - lv_indev_t * display_driver = lv_indev_get_next(NULL); - original_driver = display_driver->driver->read_cb; display_driver->driver->read_cb = lv_touch_intercept; + + screen_timer_setup(); + screen_timer_start(); } bool is_screen_asleep() { - return isScreenInSleep; + return is_screen_in_sleep; } \ No newline at end of file diff --git a/CYD-Klipper/src/core/macros_query.cpp b/CYD-Klipper/src/core/macros_query.cpp index 2ed0c0c..53e639d 100644 --- a/CYD-Klipper/src/core/macros_query.cpp +++ b/CYD-Klipper/src/core/macros_query.cpp @@ -18,6 +18,10 @@ static void _macros_query_internal(){ HTTPClient client; client.useHTTP10(true); client.begin(url.c_str()); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + int httpCode = client.GET(); if (httpCode == 200){ JsonDocument doc; @@ -42,23 +46,32 @@ static void _macros_query_internal(){ } } +void power_devices_clear(){ + for (int i = 0; i < power_devices_count; i++){ + free(power_devices[i]); + } + + power_devices_count = 0; +} + void _power_devices_query_internal(){ String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/devices"; HTTPClient client; client.useHTTP10(true); client.setTimeout(500); + client.setConnectTimeout(1000); client.begin(url.c_str()); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + int httpCode = client.GET(); if (httpCode == 200){ JsonDocument doc; deserializeJson(doc, client.getStream()); auto result = doc["result"]["devices"].as(); - for (int i = 0; i < power_devices_count; i++){ - free(power_devices[i]); - } - - power_devices_count = 0; + power_devices_clear(); for (auto i : result){ const char * device_name = i["device"]; @@ -85,6 +98,10 @@ bool set_power_state(const char* device_name, bool state) { HTTPClient client; client.useHTTP10(true); client.begin(url.c_str()); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + if (client.POST("") != 200) return false; diff --git a/CYD-Klipper/src/core/macros_query.h b/CYD-Klipper/src/core/macros_query.h index 6d58c25..1000dd3 100644 --- a/CYD-Klipper/src/core/macros_query.h +++ b/CYD-Klipper/src/core/macros_query.h @@ -15,4 +15,5 @@ MACROSQUERY macros_query(); POWERQUERY power_devices_query(); void macros_query_setup(); bool set_power_state(const char* device_name, bool state); -void _power_devices_query_internal(); \ No newline at end of file +void _power_devices_query_internal(); +void power_devices_clear(); \ No newline at end of file diff --git a/CYD-Klipper/src/core/screen_driver.h b/CYD-Klipper/src/core/screen_driver.h index e8f8e1a..00ca655 100644 --- a/CYD-Klipper/src/core/screen_driver.h +++ b/CYD-Klipper/src/core/screen_driver.h @@ -1,7 +1,6 @@ #pragma once // Adapted from https://github.com/xperiments-in/xtouch/blob/main/src/devices/2.8/screen.h -void touchscreen_calibrate(bool force = false); void screen_setBrightness(unsigned char brightness); void screen_setup(); void set_invert_display(); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/ip_setup.cpp b/CYD-Klipper/src/ui/ip_setup.cpp index 79887d8..8cfbbbd 100644 --- a/CYD-Klipper/src/ui/ip_setup.cpp +++ b/CYD-Klipper/src/ui/ip_setup.cpp @@ -29,20 +29,35 @@ static const lv_btnmatrix_ctrl_t kb_ctrl[] = { void ip_init_inner(); -bool verify_ip(){ +enum connection_status_t { + CONNECT_FAIL = 0, + CONNECT_OK = 1, + CONNECT_AUTH_REQUIRED = 2, +}; + +connection_status_t verify_ip(){ HTTPClient client; String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info"; int httpCode; try { - Serial.println(url); client.setTimeout(500); + client.setConnectTimeout(1000); client.begin(url.c_str()); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + httpCode = client.GET(); - return httpCode == 200; + Serial.printf("%d %s\n", httpCode, url.c_str()); + + if (httpCode == 401) + return CONNECT_AUTH_REQUIRED; + + return httpCode == 200 ? CONNECT_OK : CONNECT_FAIL; } catch (...) { Serial.println("Failed to connect"); - return false; + return CONNECT_FAIL; } } @@ -64,12 +79,19 @@ static void ta_event_cb(lv_event_t * e) { strcpy(global_config.klipperHost, lv_textarea_get_text(hostEntry)); global_config.klipperPort = atoi(lv_textarea_get_text(portEntry)); - if (verify_ip()) + connection_status_t status = verify_ip(); + if (status == CONNECT_OK) { global_config.ipConfigured = true; WriteGlobalConfig(); connect_ok = true; } + else if (status == CONNECT_AUTH_REQUIRED) + { + label = NULL; + global_config.ipConfigured = true; + WriteGlobalConfig(); + } else { lv_label_set_text(label, "Failed to connect"); @@ -148,6 +170,77 @@ void redraw_connect_screen(){ } } +static bool auth_entry_done = false; + +static void keyboard_event_auth_entry(lv_event_t * e) { + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * ta = lv_event_get_target(e); + lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); + + if (code == LV_EVENT_READY) + { + const char * txt = lv_textarea_get_text(ta); + int len = strlen(txt); + if (len > 0) + { + global_config.auth_configured = true; + strcpy(global_config.klipper_auth, txt); + WriteGlobalConfig(); + auth_entry_done = true; + } + } + else if (code == LV_EVENT_CANCEL) + { + auth_entry_done = true; + } +} + +void handle_auth_entry(){ + auth_entry_done = false; + global_config.klipper_auth[32] = 0; + lv_obj_clean(lv_scr_act()); + + lv_obj_t * root = lv_create_empty_panel(lv_scr_act()); + lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); + lv_layout_flex_column(root); + + lv_obj_t * top_root = lv_create_empty_panel(root); + lv_obj_set_width(top_root, CYD_SCREEN_WIDTH_PX); + lv_layout_flex_column(top_root); + lv_obj_set_flex_grow(top_root, 1); + lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0); + + lv_obj_t * label = lv_label_create(top_root); + lv_label_set_text(label, "Enter API Key"); + lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); + + lv_obj_t * keyboard = lv_keyboard_create(root); + lv_obj_t * passEntry = lv_textarea_create(top_root); + lv_textarea_set_max_length(passEntry, 32); + lv_textarea_set_one_line(passEntry, true); + + if (global_config.auth_configured) + lv_textarea_set_text(passEntry, global_config.klipper_auth); + else + lv_textarea_set_text(passEntry, ""); + + lv_obj_set_width(passEntry, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); + lv_obj_add_event_cb(passEntry, keyboard_event_auth_entry, LV_EVENT_ALL, keyboard); + lv_obj_set_flex_grow(passEntry, 1); + + + lv_keyboard_set_textarea(keyboard, passEntry); + lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl); + lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); + + while (!auth_entry_done) { + lv_timer_handler(); + lv_task_handler(); + } + + redraw_connect_screen(); +} + void ip_init_inner(){ if (global_config.ipConfigured) { redraw_connect_screen(); @@ -203,6 +296,7 @@ int retry_count = 0; void ip_init(){ connect_ok = false; retry_count = 0; + int prev_power_device_count = 0; ip_init_inner(); @@ -212,15 +306,25 @@ void ip_init(){ lv_task_handler(); if (!connect_ok && global_config.ipConfigured && (millis() - last_data_update_ip) > data_update_interval_ip){ - connect_ok = verify_ip(); + connection_status_t status = verify_ip(); + + connect_ok = status == CONNECT_OK; last_data_update_ip = millis(); retry_count++; - String retry_count_text = "Connecting to Klipper (Try " + String(retry_count + 1) + ")"; - lv_label_set_text(label, retry_count_text.c_str()); + if (label != NULL){ + String retry_count_text = "Connecting to Klipper (Try " + String(retry_count + 1) + ")"; + lv_label_set_text(label, retry_count_text.c_str()); + } - _power_devices_query_internal(); - if (power_devices_query().count >= 1) + if (status != CONNECT_AUTH_REQUIRED) + _power_devices_query_internal(); + else + handle_auth_entry(); + + if (power_devices_query().count != prev_power_device_count) { + prev_power_device_count = power_devices_query().count; redraw_connect_screen(); + } } } } @@ -228,6 +332,7 @@ void ip_init(){ void ip_ok(){ if (klipper_request_consecutive_fail_count > 5){ freeze_request_thread(); + power_devices_clear(); ip_init(); unfreeze_request_thread(); klipper_request_consecutive_fail_count = 0; diff --git a/CYD-Klipper/src/ui/nav_buttons.cpp b/CYD-Klipper/src/ui/nav_buttons.cpp index cec723d..3bfc6ec 100644 --- a/CYD-Klipper/src/ui/nav_buttons.cpp +++ b/CYD-Klipper/src/ui/nav_buttons.cpp @@ -2,8 +2,8 @@ #include "panels/panel.h" #include "../core/data_setup.h" #include "nav_buttons.h" -#include #include "ui_utils.h" +#include static lv_style_t nav_button_style; @@ -137,6 +137,9 @@ void nav_buttons_setup(unsigned char active_panel){ case 4: macros_panel_init(panel); break; + case 5: + stats_panel_init(panel); + break; } lv_msg_send(DATA_PRINTER_DATA, &printer); diff --git a/CYD-Klipper/src/ui/panels/macros_panel.cpp b/CYD-Klipper/src/ui/panels/macros_panel.cpp index 160cd17..7d61744 100644 --- a/CYD-Klipper/src/ui/panels/macros_panel.cpp +++ b/CYD-Klipper/src/ui/panels/macros_panel.cpp @@ -104,6 +104,7 @@ void macros_panel_init(lv_obj_t* panel) { } lv_obj_t * root_panel = lv_create_empty_panel(panel); + lv_obj_set_scrollbar_mode(root_panel, LV_SCROLLBAR_MODE_OFF); lv_obj_set_size(root_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_MIN_BUTTON_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); lv_obj_align(root_panel, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX + CYD_SCREEN_GAP_PX * 2); lv_layout_flex_column(root_panel); diff --git a/CYD-Klipper/src/ui/panels/move_panel.cpp b/CYD-Klipper/src/ui/panels/move_panel.cpp index 7217cd3..2f19873 100644 --- a/CYD-Klipper/src/ui/panels/move_panel.cpp +++ b/CYD-Klipper/src/ui/panels/move_panel.cpp @@ -1,48 +1,28 @@ #include "lvgl.h" #include "panel.h" #include "../../core/data_setup.h" +#include "../nav_buttons.h" #include "../ui_utils.h" #include static bool last_homing_state = false; -static void move_printer(const char* axis, float amount) { - if (!printer.homed_axis || printer.state == PRINTER_STATE_PRINTING) - return; - - char gcode[64]; - const char* extra = (amount > 0) ? "+" : ""; - - bool absolute_coords = printer.absolute_coords; - - if (absolute_coords) { - send_gcode(true, "G91"); - } - - sprintf(gcode, "G1 %s%s%.1f F6000", axis, extra, amount); - send_gcode(true, gcode); - - if (absolute_coords) { - send_gcode(true, "G90"); - } -} - static void x_line_button_press(lv_event_t * e) { float* data_pointer = (float*)lv_event_get_user_data(e); float data = *data_pointer; - move_printer("X", data); + move_printer("X", data, true); } static void y_line_button_press(lv_event_t * e) { float* data_pointer = (float*)lv_event_get_user_data(e); float data = *data_pointer; - move_printer("Y", data); + move_printer("Y", data, true); } static void z_line_button_press(lv_event_t * e) { float* data_pointer = (float*)lv_event_get_user_data(e); float data = *data_pointer; - move_printer("Z", data); + move_printer("Z", data, true); } char x_pos_buff[12]; @@ -103,6 +83,11 @@ static void disable_steppers_click(lv_event_t * e) { send_gcode(true, "M18"); } +static void switch_to_stat_panel(lv_event_t * e) { + lv_obj_t * panel = lv_event_get_target(e); + nav_buttons_setup(5); +} + inline void root_panel_steppers_locked(lv_obj_t * root_panel){ const auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2; @@ -121,7 +106,7 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){ lv_obj_set_flex_grow(btn, 1); lv_obj_t * label = lv_label_create(btn); - lv_label_set_text(label, LV_SYMBOL_HOME "Home Axis"); + lv_label_set_text(label, LV_SYMBOL_HOME "Home"); lv_obj_center(label); btn = lv_btn_create(home_button_row); @@ -130,7 +115,16 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){ lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); - lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Disable Step"); + lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Unlock"); + lv_obj_center(label); + + btn = lv_btn_create(home_button_row); + lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + lv_obj_add_event_cb(btn, switch_to_stat_panel, LV_EVENT_CLICKED, NULL); + lv_obj_set_flex_grow(btn, 1); + + label = lv_label_create(btn); + lv_label_set_text(label, LV_SYMBOL_EDIT " Params"); lv_obj_center(label); for (int row = 0; row < 3; row++) { diff --git a/CYD-Klipper/src/ui/panels/print_panel.cpp b/CYD-Klipper/src/ui/panels/print_panel.cpp index eeeb589..83819f9 100644 --- a/CYD-Klipper/src/ui/panels/print_panel.cpp +++ b/CYD-Klipper/src/ui/panels/print_panel.cpp @@ -37,6 +37,10 @@ static void btn_print_file(lv_event_t * e){ HTTPClient client; client.begin(buff); + + if (global_config.auth_configured) + client.addHeader("X-Api-Key", global_config.klipper_auth); + int httpCode = client.POST(""); Serial.printf("Print start: HTTP %d\n", httpCode); } diff --git a/CYD-Klipper/src/ui/panels/settings_panel.cpp b/CYD-Klipper/src/ui/panels/settings_panel.cpp index de4c0ec..915964a 100644 --- a/CYD-Klipper/src/ui/panels/settings_panel.cpp +++ b/CYD-Klipper/src/ui/panels/settings_panel.cpp @@ -29,6 +29,7 @@ static void reset_calibration_click(lv_event_t * e){ static void reset_wifi_click(lv_event_t * e){ global_config.wifiConfigured = false; global_config.ipConfigured = false; + global_config.auth_configured = false; WriteGlobalConfig(); ESP.restart(); } @@ -99,6 +100,14 @@ static void auto_ota_update_switch(lv_event_t* e){ WriteGlobalConfig(); } +const char* estimated_time_options = "Percentage\nInterpolated\nSlicer"; + +static void estimated_time_dropdown(lv_event_t * e){ + lv_obj_t * dropdown = lv_event_get_target(e); + global_config.remaining_time_calc_mode = lv_dropdown_get_selected(dropdown); + WriteGlobalConfig(); +} + const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} }; void create_settings_widget(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true){ @@ -122,13 +131,19 @@ void create_settings_widget(const char* label_text, lv_obj_t* object, lv_obj_t* } void settings_panel_init(lv_obj_t* panel){ + lv_obj_t * toggle = NULL; + lv_obj_t * btn = NULL; + lv_obj_t * label = NULL; + lv_obj_t * dropdown = NULL; + lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0); lv_layout_flex_column(panel); + lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); - lv_obj_t * btn = lv_btn_create(panel); + btn = lv_btn_create(panel); lv_obj_add_event_cb(btn, reset_wifi_click, LV_EVENT_CLICKED, NULL); - lv_obj_t * label = lv_label_create(btn); + label = lv_label_create(btn); lv_label_set_text(label, "Restart"); lv_obj_center(label); @@ -145,7 +160,8 @@ void settings_panel_init(lv_obj_t* panel){ create_settings_widget("Calibrate Touch", btn, panel); #endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION - lv_obj_t * toggle = lv_switch_create(panel); +#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS + toggle = lv_switch_create(panel); lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2); lv_obj_add_event_cb(toggle, invert_color_switch, LV_EVENT_VALUE_CHANGED, NULL); @@ -153,7 +169,7 @@ void settings_panel_init(lv_obj_t* panel){ lv_obj_add_state(toggle, LV_STATE_CHECKED); create_settings_widget("Invert Colors", toggle, panel); - +#endif // CYD_SCREEN_DISABLE_INVERT_COLORS toggle = lv_switch_create(panel); lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2); @@ -164,7 +180,7 @@ void settings_panel_init(lv_obj_t* panel){ create_settings_widget("Light Mode", toggle, panel); - lv_obj_t * dropdown = lv_dropdown_create(panel); + dropdown = lv_dropdown_create(panel); lv_dropdown_set_options(dropdown, "Blue\nGreen\nGrey\nYellow\nOrange\nRed\nPurple"); lv_dropdown_set_selected(dropdown, global_config.color_scheme); lv_obj_add_event_cb(dropdown, theme_dropdown, LV_EVENT_VALUE_CHANGED, NULL); @@ -199,6 +215,13 @@ void settings_panel_init(lv_obj_t* panel){ create_settings_widget("Wake Timeout", dropdown, panel); #endif + dropdown = lv_dropdown_create(panel); + lv_dropdown_set_options(dropdown, estimated_time_options); + lv_obj_add_event_cb(dropdown, estimated_time_dropdown, LV_EVENT_VALUE_CHANGED, NULL); + + lv_dropdown_set_selected(dropdown, global_config.remaining_time_calc_mode); + create_settings_widget("Estimated Time", dropdown, panel); + toggle = lv_switch_create(panel); lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2); lv_obj_add_event_cb(toggle, rotate_screen_switch, LV_EVENT_VALUE_CHANGED, NULL); @@ -219,6 +242,15 @@ void settings_panel_init(lv_obj_t* panel){ create_settings_widget("Screen On During Print", toggle, panel); #endif + toggle = lv_switch_create(panel); + lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2); + lv_obj_add_event_cb(toggle, auto_ota_update_switch, LV_EVENT_VALUE_CHANGED, NULL); + + if (global_config.autoOtaUpdate) + lv_obj_add_state(toggle, LV_STATE_CHECKED); + + create_settings_widget("Auto Update", toggle, panel); + label = lv_label_create(panel); lv_label_set_text(label, REPO_VERSION " "); @@ -240,13 +272,4 @@ void settings_panel_init(lv_obj_t* panel){ create_settings_widget("Device", label, panel, false); } - - toggle = lv_switch_create(panel); - lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2); - lv_obj_add_event_cb(toggle, auto_ota_update_switch, LV_EVENT_VALUE_CHANGED, NULL); - - if (global_config.autoOtaUpdate) - lv_obj_add_state(toggle, LV_STATE_CHECKED); - - create_settings_widget("Auto Update", toggle, panel); } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/stats_panel.cpp b/CYD-Klipper/src/ui/panels/stats_panel.cpp index f164b8b..8ef4687 100644 --- a/CYD-Klipper/src/ui/panels/stats_panel.cpp +++ b/CYD-Klipper/src/ui/panels/stats_panel.cpp @@ -36,19 +36,42 @@ static void set_zoffset_text(lv_event_t * e) { lv_label_set_text(label, data); } +static void set_zoffset_text_ex(lv_event_t * e) { + lv_obj_t * label = lv_event_get_target(e); + char data[64]; + sprintf(data, "Z Offset: %.03f, Z: %.03f", printer.gcode_offset[2], printer.position[2]); + lv_label_set_text(label, data); +} + static void set_zoffset(lv_event_t * e){ char* offset = (char*)lv_event_get_user_data(e); + char gcode[64]; - sprintf(gcode, "SET_GCODE_OFFSET Z_ADJUST=%s", offset); + sprintf(gcode, "SET_GCODE_OFFSET Z_ADJUST=%s MOVE=1", offset); send_gcode(true, gcode); } -const char* zoffsets[] = { "-0.005", "-0.01", "-0.025", "-0.05" }; -const char* zoffsets_2[] = { "+0.005", "+0.01", "+0.025", "+0.05" }; +static void set_z(lv_event_t * e){ + void* ptr = lv_event_get_user_data(e); + float value = *(float *)(&ptr); + + if (value < 0) { + send_gcode(true, "SET_GCODE_OFFSET Z=0 MOVE=1"); + return; + } + + move_printer("Z", value, false); +} + +const char* zoffsets[] = { "-0.01", "-0.025", "-0.05", "-0.2" }; +const char* zoffsets_2[] = { "+0.01", "+0.025", "+0.05", "+0.2" }; +const char* zabs[] = { "Z=0", "Z=0.1", "Z=1", "Clear" }; +const float zabsvalues[] = { 0, 0.1f, 1.0f, -1.0f }; lv_button_column_t zoffset_columns[] = { { set_zoffset, zoffsets, (const void**)zoffsets, 4}, - { set_zoffset, zoffsets_2, (const void**)zoffsets_2, 4} + { set_zoffset, zoffsets_2, (const void**)zoffsets_2, 4}, + { set_z, zabs, (const void**)zabsvalues, 4} }; static void set_speed_mult_text(lv_event_t * e){ @@ -126,7 +149,7 @@ static void open_fan_speed_panel(lv_event_t * e){ } static void open_zoffset_panel(lv_event_t * e){ - lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text, zoffset_columns, 2); + lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text_ex, zoffset_columns, (printer.state == PRINTER_STATE_IDLE) ? 3 : 2); lv_msg_send(DATA_PRINTER_DATA, &printer); } @@ -175,7 +198,7 @@ static void label_total_layers(lv_event_t * e){ static void label_pressure_advance(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); char pressure_buff[32]; - sprintf(pressure_buff, "%.3f", printer.pressure_advance); + sprintf(pressure_buff, "%.3f (%.2fs)", printer.pressure_advance, printer.smooth_time); lv_label_set_text(label, pressure_buff); } @@ -211,8 +234,12 @@ void stats_panel_init(lv_obj_t* panel) { lv_obj_align(left_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX); create_stat_text_block(left_panel, "Position:", label_pos); - create_stat_text_block(left_panel, "Filament Used:", label_filament_used_m); - create_stat_text_block(left_panel, "Layer:", label_total_layers); + + if (printer.state != PRINTER_STATE_IDLE){ + create_stat_text_block(left_panel, "Filament Used:", label_filament_used_m); + create_stat_text_block(left_panel, "Layer:", label_total_layers); + } + create_stat_text_block(left_panel, "Pressure Advance:", label_pressure_advance); create_stat_text_block(left_panel, "Feedrate:", label_feedrate); diff --git a/CYD-Klipper/src/ui/panels/temp_panel.cpp b/CYD-Klipper/src/ui/panels/temp_panel.cpp index de12bd9..7f4042f 100644 --- a/CYD-Klipper/src/ui/panels/temp_panel.cpp +++ b/CYD-Klipper/src/ui/panels/temp_panel.cpp @@ -207,22 +207,100 @@ static void btn_retract(lv_event_t * e){ send_gcode(true, "G1 E-25 F300"); } +static void set_chart_range(lv_event_t * e) { + lv_obj_t * chart_obj = lv_event_get_target(e); + lv_chart_t * chart = (lv_chart_t *)chart_obj; + int max_temp = 0; + lv_chart_series_t * prev = NULL; + + do { + prev = lv_chart_get_series_next(chart_obj, prev); + + if (prev != NULL) + for (int i = 0; i < chart->point_cnt; i++) + if (prev->y_points[i] > max_temp) + max_temp = prev->y_points[i]; + + } while (prev != NULL); + + int range = ((max_temp + 49) / 50) * 50; + + if (range < 100) + range = 100; + + lv_chart_set_range(chart_obj, LV_CHART_AXIS_PRIMARY_Y, 0, range); +} + +static void set_hotend_temp_chart(lv_event_t * e){ + lv_obj_t * chart = lv_event_get_target(e); + lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e); + lv_chart_set_next_value(chart, series, printer.extruder_temp); +} + +static void set_hotend_target_temp_chart(lv_event_t * e){ + lv_obj_t * chart = lv_event_get_target(e); + lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e); + lv_chart_set_next_value(chart, series, printer.extruder_target_temp); +} + +static void set_bed_temp_chart(lv_event_t * e){ + lv_obj_t * chart = lv_event_get_target(e); + lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e); + lv_chart_set_next_value(chart, series, printer.bed_temp); +} + +static void set_bed_target_temp_chart(lv_event_t * e){ + lv_obj_t * chart = lv_event_get_target(e); + lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e); + lv_chart_set_next_value(chart, series, printer.bed_target_temp); +} + void temp_panel_init(lv_obj_t * panel){ const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2; root_panel = panel; edit_mode = false; lv_obj_t * root_temp_panel = lv_create_empty_panel(panel); - lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, LV_SIZE_CONTENT); + lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); lv_obj_align(root_temp_panel, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_set_style_pad_all(root_temp_panel, CYD_SCREEN_GAP_PX, 0); lv_layout_flex_column(root_temp_panel); + lv_obj_set_flex_align(root_temp_panel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER); + lv_obj_set_scrollbar_mode(root_temp_panel, LV_SCROLLBAR_MODE_OFF); + + lv_obj_t * chart = lv_chart_create(root_temp_panel); + lv_obj_set_size(chart, element_width - CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * 3); + lv_chart_set_type(chart, LV_CHART_TYPE_LINE); + lv_chart_set_point_count(chart, 120); + lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR); + lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, CYD_SCREEN_GAP_PX / 2, CYD_SCREEN_GAP_PX / 4, 4, 3, true, CYD_SCREEN_MIN_BUTTON_WIDTH_PX); + lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT); + + lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_ORANGE), LV_CHART_AXIS_PRIMARY_Y); + lv_chart_set_all_value(chart, ser1, printer.extruder_target_temp); + lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y); + lv_chart_set_all_value(chart, ser2, printer.extruder_temp); + lv_chart_series_t * ser3 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_TEAL), LV_CHART_AXIS_PRIMARY_Y); + lv_chart_set_all_value(chart, ser3, printer.bed_target_temp); + lv_chart_series_t * ser4 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_PRIMARY_Y); + lv_chart_set_all_value(chart, ser4, printer.bed_temp); + + lv_obj_add_event_cb(chart, set_hotend_target_temp_chart, LV_EVENT_MSG_RECEIVED, ser1); + lv_obj_add_event_cb(chart, set_hotend_temp_chart, LV_EVENT_MSG_RECEIVED, ser2); + lv_obj_add_event_cb(chart, set_bed_target_temp_chart, LV_EVENT_MSG_RECEIVED, ser3); + lv_obj_add_event_cb(chart, set_bed_temp_chart, LV_EVENT_MSG_RECEIVED, ser4); + lv_obj_add_event_cb(chart, set_chart_range, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subscribe_obj(DATA_PRINTER_DATA, chart, NULL); + + lv_obj_t * single_screen_panel = lv_create_empty_panel(root_temp_panel); + lv_obj_set_size(single_screen_panel, element_width, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2 - CYD_SCREEN_GAP_PX / 2); + lv_layout_flex_column(single_screen_panel); lv_obj_t * temp_rows[2] = {0}; lv_obj_t * button_temp_rows[2] = {0}; for (int tempIter = 0; tempIter < 2; tempIter++){ - temp_rows[tempIter] = lv_create_empty_panel(root_temp_panel); + temp_rows[tempIter] = lv_create_empty_panel(single_screen_panel); lv_layout_flex_column(temp_rows[tempIter]); lv_obj_set_size(temp_rows[tempIter], element_width, LV_SIZE_CONTENT); @@ -259,16 +337,17 @@ void temp_panel_init(lv_obj_t * panel){ lv_obj_center(label); } - lv_obj_t * bottom_panel = lv_create_empty_panel(panel); - lv_obj_set_size(bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - lv_obj_align(bottom_panel, LV_ALIGN_BOTTOM_MID, 0, -1 * CYD_SCREEN_GAP_PX); - lv_layout_flex_row(bottom_panel, LV_FLEX_ALIGN_SPACE_EVENLY); + lv_obj_t * gap = lv_create_empty_panel(single_screen_panel); + lv_obj_set_flex_grow(gap, 1); - lv_obj_t * one_above_bottom_panel = lv_create_empty_panel(panel); + lv_obj_t * one_above_bottom_panel = lv_create_empty_panel(single_screen_panel); lv_obj_set_size(one_above_bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - lv_obj_align(one_above_bottom_panel, LV_ALIGN_BOTTOM_MID, 0, -1 * CYD_SCREEN_MIN_BUTTON_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); lv_layout_flex_row(one_above_bottom_panel, LV_FLEX_ALIGN_SPACE_EVENLY); + lv_obj_t * bottom_panel = lv_create_empty_panel(single_screen_panel); + lv_obj_set_size(bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + lv_layout_flex_row(bottom_panel, LV_FLEX_ALIGN_SPACE_EVENLY); + lv_obj_t * btn = lv_btn_create(bottom_panel); lv_obj_set_flex_grow(btn, 1); lv_obj_add_event_cb(btn, btn_extrude, LV_EVENT_CLICKED, NULL); @@ -306,5 +385,6 @@ void temp_panel_init(lv_obj_t * panel){ lv_label_set_text(label, "Edit Presets"); lv_obj_center(label); + lv_obj_scroll_to_y(root_temp_panel, 9999, LV_ANIM_OFF); lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer); } \ No newline at end of file