90 Commits

Author SHA1 Message Date
Sims
e2c2a38b20 v1.6.4 (#113)
* Fix gcode previews with special chars not loading

* Add .gitignore file (#108)

* Bulletproof ci.py (#107)

* Implement file sorting (implement #89)

* Set chip family to ESP32-S3 for specific models (fix #67)

* Add files menu to params panel while printing (implement #80)

* Update ci.py (#110)

Typo fix for ESP32-S3 boards array name

---------

Co-authored-by: Sebastian Göls <6608231+Abrynos@users.noreply.github.com>
Co-authored-by: Miroslav Zuzelka <mzuzelka@gmail.com>
2024-06-28 19:11:20 +02:00
Sims
c640d7fade Merge pull request #104 from suchmememanyskill/dev
Clear memory before doing OTA
2024-05-28 22:15:23 +02:00
suchmememanyskill
d22a9e1ee4 Clear memory before doing OTA 2024-05-28 22:03:51 +02:00
Sims
98c7364ce7 Merge pull request #103 from suchmememanyskill/dev
v1.6.2
2024-05-28 21:30:19 +02:00
suchmememanyskill
7815a0fbf4 Specify specific version for esp32 platform 2024-05-26 00:26:49 +02:00
suchmememanyskill
bd32fcb81e Allow accessing the parameters/stats panel from unlocked stepper move panel 2024-05-25 12:47:43 +02:00
suchmememanyskill
bc0502745d Allow custom extrude/retract macros 2024-05-25 12:40:07 +02:00
suchmememanyskill
d75cbb65dc Fix #99 2024-05-11 00:05:24 +02:00
Beebles
e004456ee9 Update README.md (#95) 2024-04-28 23:57:29 +02:00
Flaviu Tamas
ae34e91530 Custom API key keymap (#94)
Since the api key is just hex, we can use a keymap with larger buttons
that is easier to use.
2024-04-28 20:23:49 +02:00
Flaviu Tamas
cbd40414c8 Fix segfault on entering IP (#93)
On my esp32-3248S035C, after entering the IP address, I was seeing a
segfault at

lv_mem_free at .pio/libdeps/esp32-3248S035C/lvgl/src/misc/lv_mem.c:179
allocate_btn_areas_and_controls at .pio/libdeps/esp32-3248S035C/lvgl/src/widgets/lv_btnmatrix.c:877
lv_btnmatrix_set_map at .pio/libdeps/esp32-3248S035C/lvgl/src/widgets/lv_btnmatrix.c:94
lv_keyboard_update_map at .pio/libdeps/esp32-3248S035C/lvgl/src/extra/widgets/keyboard/lv_keyboard.c:397
lv_keyboard_set_mode at .pio/libdeps/esp32-3248S035C/lvgl/src/extra/widgets/keyboard/lv_keyboard.c:185
keyboard_event_ip_entry(_lv_event_t*) at src/ui/ip_setup.cpp:81
event_send_core at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:467
lv_event_send at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:63
lv_keyboard_def_event_cb at .pio/libdeps/esp32-3248S035C/lvgl/src/extra/widgets/keyboard/lv_keyboard.c:308
event_send_core at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:467
lv_event_send at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:63
lv_btnmatrix_event at .pio/libdeps/esp32-3248S035C/lvgl/src/widgets/lv_btnmatrix.c:520
lv_obj_event_base at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:91 (discriminator 1)
event_send_core at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:458
lv_event_send at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:63
indev_proc_release at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_indev.c:970
indev_button_proc at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_indev.c:808
lv_timer_exec at .pio/libdeps/esp32-3248S035C/lvgl/src/misc/lv_timer.c:313
set_screen_brightness() at src/core/lv_setup.cpp:191
ip_init() at src/ui/ip_setup.cpp:239
setup() at src/main.cpp:28
loopTask(void*) at /home/user/etc/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:41

This seems to be due to a free-after-free. The solution here is to
potentially change the keymap before running the rest of the logic,
because the later logic may tear down the context.

This change also only changes the keyboard mode on focus change, to
avoid running this code on the many un-related events that this handler
gets called for.
2024-04-28 20:22:06 +02:00
suchmememanyskill
06691df094 Remove esp32-4827S043R-SD from CI builds 2024-04-24 22:23:57 +02:00
suchmememanyskill
9b551915d7 Fix possible nullref in fetch_printer_data 2024-04-15 22:56:57 +02:00
suchmememanyskill
73be7c6c9f Forgot to add device to platformio cfg 2024-04-15 19:39:03 +02:00
suchmememanyskill
e06ea214c4 esp32-4827S043R 2024-04-15 18:02:05 +02:00
suchmememanyskill
9e739de731 Add more clear manual install instructions 2024-04-15 17:37:07 +02:00
Sims
29dcb4717a Merge pull request #87 from suchmememanyskill/dev
v1.6.1
2024-04-14 12:13:50 +02:00
suchmememanyskill
356c78ee5f Lock UI thread when setting state to offline, fix #86 2024-04-14 12:01:35 +02:00
suchmememanyskill
dce6f70ef9 Allow dismissing m117 messages, allow disabling m117 messages 2024-04-05 23:03:48 +02:00
Sims
2e3ac7b02c Merge pull request #83 from suchmememanyskill/dev
v1.6.0
2024-03-29 22:51:31 +01:00
suchmememanyskill
2e5a2dfbeb Add note about clearing touch calibration 2024-03-29 22:14:21 +01:00
suchmememanyskill
4a4fdb77d6 Clarify invert colors text 2024-03-29 22:07:14 +01:00
suchmememanyskill
db448ae401 Fix compile error 2024-03-29 21:26:23 +01:00
suchmememanyskill
9a9134da4a Reset touch calibration when holding BOOT for 8 seconds 2024-03-29 20:16:13 +01:00
suchmememanyskill
86a999253f Reorganise settings menu 2024-03-28 20:26:57 +01:00
suchmememanyskill
1238b7ee37 Add color fix for dual-usb 2432S028R 2024-03-28 18:25:32 +01:00
suchmememanyskill
f110feee1e Copy unstable manual ssid string 2024-03-27 17:37:25 +01:00
suchmememanyskill
41d0b77d17 Copy over move data from previous printer config 2024-03-26 23:16:51 +01:00
suchmememanyskill
364f1ee49c Add configurable move values 2024-03-26 22:57:54 +01:00
Kurt Haenen
ad68095124 Differentiated between printed and elapsed time (#75)
Co-authored-by: Kurt Haenen <kurt.haenen@quintux.com>
2024-03-26 21:13:53 +01:00
suchmememanyskill
38a1acb7b1 Refactor wifi setup; add option to type ssid manually 2024-03-26 20:05:58 +01:00
suchmememanyskill
f5f970afce Show macros help message even when there's power devices present 2024-03-26 18:51:25 +01:00
suchmememanyskill
e4dd146a96 Fix slicer estimate when switching between printers 2024-03-25 22:02:00 +01:00
suchmememanyskill
ea8a6b561f Allow setting absolute xyz pos 2024-03-24 18:10:22 +01:00
suchmememanyskill
a9a732daa6 Revert coloring active printer buttons; Put wifi icon instead 2024-03-24 00:28:58 +01:00
suchmememanyskill
713e04bfa5 Improve printer menu 2024-03-22 22:09:09 +01:00
suchmememanyskill
0f472ae78b Don't show error screen on null'd status 2024-03-22 21:15:00 +01:00
suchmememanyskill
400e2ae266 Use display_status for print progress 2024-03-22 21:13:02 +01:00
suchmememanyskill
315e066e27 Allow passwordless wifi networks; reconnect to wifi network once 2024-03-21 22:00:24 +01:00
suchmememanyskill
c7c6b26730 Move ip connect to panel; add restart to wifi 2024-03-20 22:24:06 +01:00
suchmememanyskill
6cde9cb887 Add printer switch to ip setup screen 2024-03-18 18:05:08 +01:00
suchmememanyskill
44e57995fb Fix lines in ESP32-2432S024 2024-03-18 17:41:53 +01:00
suchmememanyskill
56301d3d72 Show extra stats on progress panel 2024-03-17 14:59:43 +01:00
suchmememanyskill
ae3348d61e Fix a bit of wording 2024-03-16 11:02:24 +01:00
Sims
4bfe149244 Merge pull request #66 from suchmememanyskill/dev
v1.5.0
2024-03-15 22:42:34 +01:00
suchmememanyskill
7aceb85621 Move error ui to panel 2024-03-14 19:00:57 +01:00
suchmememanyskill
9c958b42b3 Fix macro panel in error screen 2024-03-14 18:28:22 +01:00
suchmememanyskill
92d47d8c07 Move print preview image to the top left 2024-03-13 22:42:06 +01:00
suchmememanyskill
1a31ef0758 map error text in moonraker as error state 2024-03-13 22:26:10 +01:00
suchmememanyskill
a7bde99442 Fix inverted vertical 2024-03-13 20:20:57 +01:00
suchmememanyskill
be3b2ddb24 3248S035C Vertical 2024-03-13 19:50:20 +01:00
suchmememanyskill
36b37176d6 Fix macros tab controlling other printers 2024-03-13 18:46:13 +01:00
suchmememanyskill
d0d80e8980 Imrpove site 2024-03-12 22:06:52 +01:00
suchmememanyskill
65abe295c9 Fix button disable conditions 2024-03-12 21:30:23 +01:00
suchmememanyskill
a8c94fe207 Refactor + Power menu in printer menu 2024-03-12 21:08:48 +01:00
suchmememanyskill
a265301d97 Update smartdisplay driver to v2.0.7 2024-03-11 22:20:56 +01:00
suchmememanyskill
90dcf95cf6 Merge branch 'experimental-multi-printer' into dev 2024-03-11 21:55:44 +01:00
suchmememanyskill
8d6d22c38a Change status to 'In Control' when in control 2024-03-11 21:55:33 +01:00
suchmememanyskill
fb1e264df7 Display M117 message on screen 2024-03-10 01:08:47 +01:00
suchmememanyskill
e457114402 (Hopefully) fix touch on 2432S024C 2024-03-10 00:03:30 +01:00
suchmememanyskill
61f15ff6f3 Fix bugs 2024-03-09 21:43:46 +01:00
suchmememanyskill
451304b5df Add 2432S024C and 4827S043C to CI 2024-03-09 21:16:55 +01:00
suchmememanyskill
68ff78eb49 Add 2432S024C-smartdisplay 2024-03-09 21:16:40 +01:00
Andrey Melnikov
215439df2f adds esp32-4827s043C-smartdisplay (#63)
* +add esp32-4827s043C

* DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX 40 to 35
2024-03-09 21:10:39 +01:00
suchmememanyskill
397c835129 Add build instructions 2024-03-09 21:08:45 +01:00
suchmememanyskill
870d109c92 Implement printer switching in ip connect/error screen 2024-03-09 20:47:45 +01:00
suchmememanyskill
f98c2eff78 Small refactor 2024-03-09 19:22:24 +01:00
suchmememanyskill
67b5ce1948 Set max printer name limit to 24 chars 2024-03-09 01:56:35 +01:00
suchmememanyskill
e9b58e0a6f Implement printer panel fully 2024-03-09 01:55:31 +01:00
suchmememanyskill
3b7b49c62b Split configuration; start printer panel 2024-03-07 23:25:12 +01:00
suchmememanyskill
f0cc211e30 Unify http client creation 2024-03-06 22:32:49 +01:00
suchmememanyskill
9427381e05 Add other CYD 2.8R inch models for smartdisplay 2024-03-03 01:02:52 +01:00
suchmememanyskill
02e27e6d83 Set screen brightness in lvgl setup 2024-03-03 01:00:09 +01:00
suchmememanyskill
b65003e40b Better button sizes for esp32-3248S035C 2024-03-02 23:50:24 +01:00
suchmememanyskill
cb242240d3 Remove unneeded code 2024-03-02 22:11:39 +01:00
suchmememanyskill
c061164edf Fix compile on linux 2024-03-02 22:06:15 +01:00
suchmememanyskill
ea42bf775d Merge branch 'experimental_load_gcode_img-2' into dev 2024-03-02 22:03:14 +01:00
suchmememanyskill
4e6457c729 Misc fixes 2024-03-02 22:02:20 +01:00
themacboy
bc3ca3892f Some visual UI tweaks for ESP32-8048S043C (#57)
* Some visual UI tweaks

* more visual UI tweaks adjustements
2024-03-02 21:57:00 +01:00
suchmememanyskill
639eb50371 A 2024-03-02 21:16:31 +01:00
suchmememanyskill
1adb966ee1 Image load round 2 (slightly less unstable) 2024-03-02 21:05:16 +01:00
suchmememanyskill
64290afd89 Set size for settings dropdown 2024-03-02 14:18:37 +01:00
suchmememanyskill
3fbd14f154 Hopefully fix esp32-8048S043C 2024-03-02 10:38:34 +01:00
suchmememanyskill
ef3676faef Merge branch 'dev' into 4.3inch 2024-03-02 10:32:14 +01:00
suchmememanyskill
fc7cfbd85b Add esp32-2432S032C to CI 2024-03-02 10:22:18 +01:00
suchmememanyskill
49c27f2b01 Add esp32-2432S032C 2024-03-02 10:21:09 +01:00
suchmememanyskill
801432c3a6 Driver configuration improvements 2024-03-02 10:19:03 +01:00
suchmememanyskill
55e9ce3d81 Vertical UI, round 2 2024-03-01 22:28:35 +01:00
suchmememanyskill
f467e8a604 Add esp32-8048S043C 2024-02-27 21:32:00 +01:00
suchmememanyskill
45779b5a13 Make calibration work with smartdisplay driver 2024-02-24 14:27:03 +01:00
63 changed files with 3764 additions and 1104 deletions

10
.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
_site/out/
_site/OTA.json
_site/esp32-*.json
pyvenv.cfg
bin/
out/
lib
lib64

View File

@@ -11,7 +11,7 @@
"'-D LCD_HEIGHT=320'", "'-D LCD_HEIGHT=320'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'", "'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'", "'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D BCKL=0'", "'-D GPIO_BCKL=0'",
"'-D LCD_ST7789_I80'", "'-D LCD_ST7789_I80'",
"'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'", "'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-D ST7789_I80_BUS_CONFIG_DC=16'", "'-D ST7789_I80_BUS_CONFIG_DC=16'",
@@ -29,7 +29,7 @@
"'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'", "'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'", "'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'", "'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'",
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=55000000'", "'-D ST7789_IO_I80_CONFIG_PCLK_HZ=12000000'",
"'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'", "'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'", "'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'", "'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'",
@@ -43,7 +43,7 @@
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'", "'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=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_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'", "'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'", "'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'", "'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'", "'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
@@ -53,7 +53,7 @@
"'-D LCD_MIRROR_Y=false'", "'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'", "'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_CST816S_I2C'", "'-D TOUCH_CST816S_I2C'",
"'-D CST816S_I2C_HOST=0'", "'-D CST816S_I2C_HOST=I2C_NUM_0'",
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=21'", "'-D CST816S_I2C_CONFIG_SDA_IO_NUM=21'",
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=22'", "'-D CST816S_I2C_CONFIG_SCL_IO_NUM=22'",
"'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'", "'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'",
@@ -73,7 +73,7 @@
"'-D CST816S_TOUCH_CONFIG_INT_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_RESET=0'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'", "'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=false'", "'-D TOUCH_SWAP_XY=true'",
"'-D TOUCH_SWAP_X=false'", "'-D TOUCH_SWAP_X=false'",
"'-D TOUCH_SWAP_Y=false'", "'-D TOUCH_SWAP_Y=false'",
"'-D BOARD_HAS_TF'", "'-D BOARD_HAS_TF'",

View File

@@ -0,0 +1,122 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S024C'",
"'-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 GPIO_BCKL=27'",
"'-D LCD_ILI9341_SPI'",
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ILI9341_SPI_BUS_FLAGS=0'",
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=\"(ili9341_vendor_config_t[]){{.init_cmds=(ili9341_lcd_init_cmd_t[]){{.cmd=0xCF,.data=(uint8_t[]){0x00,0xC1,0x30},.data_bytes=3},{.cmd=0xED,.data=(uint8_t[]){0x64,0x03,0x12,0x81},.data_bytes=4},{.cmd=0xE8,.data=(uint8_t[]){0x85,0x00,0x78},.data_bytes=3},{.cmd=0xCB,.data=(uint8_t[]){0x39,0x2C,0x00,0x34,0x02},.data_bytes=5},{.cmd=0xF7,.data=(uint8_t[]){0x20},.data_bytes=1},{.cmd=0xEA,.data=(uint8_t[]){0x00,0x00},.data_bytes=2},{.cmd=0xC0,.data=(uint8_t[]){0x10},.data_bytes=1},{.cmd=0xC1,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0xC5,.data=(uint8_t[]){0x30,0x30},.data_bytes=2,},{.cmd=0xC7,.data=(uint8_t[]){0xB7},.data_bytes=1},{.cmd=0x3A,.data=(uint8_t[]){0x55},.data_bytes=1},{.cmd=0x36,.data=(uint8_t[]){0x08},.data_bytes=1},{.cmd=0xB1,.data=(uint8_t[]){0x00,0x1A},.data_bytes=2},{.cmd=0xB6,.data=(uint8_t[]){0x08,0x82,0x27},.data_bytes=3},{.cmd=0xF2,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0x26,.data=(uint8_t[]){0x01},.data_bytes=1},{.cmd=0xE0,.data=(uint8_t[]){0x0F,0x2A,0x28,0x08,0x0E,0x08,0x54,0xA9,0x43,0x0A,0x0F,0x00,0x00,0x00,0x00},.data_bytes=15},{.cmd=0xE1,.data=(uint8_t[]){0x00,0x15,0x17,0x07,0x11,0x06,0x2B,0x56,0x3C,0x05,0x10,0x0F,0x3F,0x3F,0x0F},.data_bytes=15},{.cmd=0x2B,.data=(uint8_t[]){0x00,0x00,0x01,0x3F},.data_bytes=4},{.cmd=0x2A,.data=(uint8_t[]){0x00,0x00,0x00,0xEF},.data_bytes=4},{.cmd=0x21},{.cmd=0x11,.delay_ms=120},{.cmd=0x29,.delay_ms=1}},.init_cmds_size=23}}\"'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_CST816S_I2C'",
"'-D CST816S_I2C_HOST=I2C_NUM_0'",
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=33'",
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=32'",
"'-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=25'",
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=21'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=true'",
"'-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_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-2432S024C-SD",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005005865107357.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,125 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S028R'",
"'-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 GPIO_BCKL=21'",
"'-D LCD_ILI9341_SPI'",
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ILI9341_SPI_BUS_FLAGS=0'",
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=NULL'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-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"
],
"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-2432S028Rv1-SD",
"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"
}

View File

@@ -0,0 +1,125 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S028Rv2'",
"'-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 GPIO_BCKL=21'",
"'-D LCD_ILI9341_SPI'",
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ILI9341_SPI_BUS_FLAGS=0'",
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=\"(ili9341_vendor_config_t[]){{.init_cmds=(ili9341_lcd_init_cmd_t[]){{.cmd=0xCF,.data=(uint8_t[]){0x00,0xC1,0x30},.data_bytes=3},{.cmd=0xED,.data=(uint8_t[]){0x64,0x03,0x12,0x81},.data_bytes=4},{.cmd=0xE8,.data=(uint8_t[]){0x85,0x00,0x78},.data_bytes=3},{.cmd=0xCB,.data=(uint8_t[]){0x39,0x2C,0x00,0x34,0x02},.data_bytes=5},{.cmd=0xF7,.data=(uint8_t[]){0x20},.data_bytes=1},{.cmd=0xEA,.data=(uint8_t[]){0x00,0x00},.data_bytes=2},{.cmd=0xC0,.data=(uint8_t[]){0x10},.data_bytes=1},{.cmd=0xC1,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0xC5,.data=(uint8_t[]){0x30,0x30},.data_bytes=2,},{.cmd=0xC7,.data=(uint8_t[]){0xB7},.data_bytes=1},{.cmd=0x3A,.data=(uint8_t[]){0x55},.data_bytes=1},{.cmd=0x36,.data=(uint8_t[]){0x08},.data_bytes=1},{.cmd=0xB1,.data=(uint8_t[]){0x00,0x1A},.data_bytes=2},{.cmd=0xB6,.data=(uint8_t[]){0x08,0x82,0x27},.data_bytes=3},{.cmd=0xF2,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0x26,.data=(uint8_t[]){0x01},.data_bytes=1},{.cmd=0xE0,.data=(uint8_t[]){0x0F,0x2A,0x28,0x08,0x0E,0x08,0x54,0xA9,0x43,0x0A,0x0F,0x00,0x00,0x00,0x00},.data_bytes=15},{.cmd=0xE1,.data=(uint8_t[]){0x00,0x15,0x17,0x07,0x11,0x06,0x2B,0x56,0x3C,0x05,0x10,0x0F,0x3F,0x3F,0x0F},.data_bytes=15},{.cmd=0x2B,.data=(uint8_t[]){0x00,0x00,0x01,0x3F},.data_bytes=4},{.cmd=0x2A,.data=(uint8_t[]){0x00,0x00,0x00,0xEF},.data_bytes=4},{.cmd=0x21},{.cmd=0x11,.delay_ms=120},{.cmd=0x29,.delay_ms=1}},.init_cmds_size=23}}\"'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-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"
],
"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-2432S028Rv2-SD",
"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"
}

View File

@@ -11,7 +11,7 @@
"'-D LCD_HEIGHT=320'", "'-D LCD_HEIGHT=320'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'", "'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'", "'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D BCKL=21'", "'-D GPIO_BCKL=21'",
"'-D LCD_ST7789_SPI'", "'-D LCD_ST7789_SPI'",
"'-D ST7789_SPI_HOST=SPI2_HOST'", "'-D ST7789_SPI_HOST=SPI2_HOST'",
"'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'", "'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
@@ -20,13 +20,13 @@
"'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'", "'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'", "'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ST7789_SPI_BUS_QUADHD_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_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ST7789_SPI_BUS_FLAGS=0'", "'-D ST7789_SPI_BUS_FLAGS=0'",
"'-D ST7789_SPI_BUS_INTR_FLAGS=0'", "'-D ST7789_SPI_BUS_INTR_FLAGS=0'",
"'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'", "'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'", "'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'", "'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'",
"'-D ST7789_SPI_CONFIG_PCLK_HZ=55000000'", "'-D ST7789_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'", "'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'", "'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'", "'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'",
@@ -91,8 +91,7 @@
"-DCYD_SCREEN_FONT=lv_font_montserrat_14", "-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10", "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40", "-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1", "-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1"
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
], ],
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "40000000L", "f_flash": "40000000L",
@@ -113,7 +112,7 @@
"arduino", "arduino",
"espidf" "espidf"
], ],
"name": "esp32-2432S028Rv3", "name": "esp32-2432S028Rv3-SD",
"upload": { "upload": {
"flash_size": "4MB", "flash_size": "4MB",
"maximum_ram_size": 327680, "maximum_ram_size": 327680,

View File

@@ -0,0 +1,125 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S032C'",
"'-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 GPIO_BCKL=27'",
"'-D LCD_IPS'",
"'-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=12'",
"'-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=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-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=24000000'",
"'-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_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=25'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=21'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=true'",
"'-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_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_HEIGHT_PX=240",
"-DCYD_SCREEN_WIDTH_PX=320",
"-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-2432S032C-SD",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005006224494145.html",
"vendor": "Sunton"
}

View File

@@ -9,7 +9,9 @@
"'-D ESP32_3248S035C'", "'-D ESP32_3248S035C'",
"'-D LCD_WIDTH=320'", "'-D LCD_WIDTH=320'",
"'-D LCD_HEIGHT=480'", "'-D LCD_HEIGHT=480'",
"'-D BCKL=27'", "'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D GPIO_BCKL=27'",
"'-D LCD_ST7796_SPI'", "'-D LCD_ST7796_SPI'",
"'-D ST7796_SPI_HOST=SPI2_HOST'", "'-D ST7796_SPI_HOST=SPI2_HOST'",
"'-D ST7796_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'", "'-D ST7796_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
@@ -18,10 +20,13 @@
"'-D ST7796_SPI_BUS_SCLK_IO_NUM=14'", "'-D ST7796_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ST7796_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'", "'-D ST7796_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ST7796_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'", "'-D ST7796_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ST7796_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ST7796_SPI_BUS_FLAGS=0'",
"'-D ST7796_SPI_BUS_INTR_FLAGS=0'",
"'-D ST7796_SPI_CONFIG_CS_GPIO_NUM=15'", "'-D ST7796_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ST7796_SPI_CONFIG_DC_GPIO_NUM=2'", "'-D ST7796_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ST7796_SPI_CONFIG_SPI_MODE=SPI_MODE0'", "'-D ST7796_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ST7796_SPI_CONFIG_PCLK_HZ=80000000'", "'-D ST7796_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ST7796_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'", "'-D ST7796_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7796_SPI_CONFIG_LCD_CMD_BITS=8'", "'-D ST7796_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'", "'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'",
@@ -39,13 +44,13 @@
"'-D LCD_MIRROR_Y=false'", "'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'", "'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_GT911_I2C'", "'-D TOUCH_GT911_I2C'",
"'-D GT911_I2C_HOST=0'", "'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'", "'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'", "'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'", "'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'", "'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'", "'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=0'", "'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'", "'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'", "'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'", "'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
@@ -77,14 +82,13 @@
"'-D SPEAK=26'", "'-D SPEAK=26'",
"-DCYD_SCREEN_GAP_PX=10", "-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40", "-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40", "-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-DCYD_SCREEN_FONT=lv_font_montserrat_16", "-DCYD_SCREEN_FONT=lv_font_montserrat_16",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12", "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50", "-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1", "-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1", "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
], ],
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "40000000L", "f_flash": "40000000L",

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DUSER_SETUP_LOADED=1",
"-DST7796_DRIVER=1",
"-DTFT_BL=27",
"-DTFT_BACKLIGHT_ON=HIGH",
"-DTFT_MISO=12",
"-DTFT_MOSI=13",
"-DTFT_SCLK=14",
"-DTFT_CS=15",
"-DTFT_DC=2",
"-DTFT_RST=-1",
"-DLOAD_GCLD=1",
"-DSPI_FREQUENCY=80000000",
"-DSPI_READ_FREQUENCY=20000000",
"-DSPI_TOUCH_FREQUENCY=2500000",
"-DTOUCH_CS=-1",
"-DCYD_SCREEN_HEIGHT_PX=480",
"-DCYD_SCREEN_WIDTH_PX=320",
"-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-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_3248S035C=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
"-DCYD_SCREEN_VERTICAL=1",
"-DCYD_SCREEN_NO_TEMP_SCROLL=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-3248S035C-V",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004632953455.html",
"vendor": "Sunton"
}

View File

@@ -24,8 +24,8 @@
"-DCYD_SCREEN_HEIGHT_PX=320", "-DCYD_SCREEN_HEIGHT_PX=320",
"-DCYD_SCREEN_WIDTH_PX=480", "-DCYD_SCREEN_WIDTH_PX=480",
"-DCYD_SCREEN_GAP_PX=10", "-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40", "-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40", "-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-DCYD_SCREEN_FONT=lv_font_montserrat_16", "-DCYD_SCREEN_FONT=lv_font_montserrat_16",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12", "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50", "-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",

View File

@@ -0,0 +1,143 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32S3_DEV'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
"'-D ESP32_4827S043C'",
"'-D LCD_WIDTH=480'",
"'-D LCD_HEIGHT=272'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
"'-D GPIO_BCKL=2'",
"'-D LCD_ST7262_PAR'",
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(8*1000000)'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=43'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=12'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_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=10'",
"'-D TF_SPI_MOSI=11'",
"'-D TF_SPI_SCLK=12'",
"'-D TF_SPI_MISO=13'",
"'-DCYD_SCREEN_HEIGHT_PX=272'",
"'-DCYD_SCREEN_WIDTH_PX=480'",
"-DROTATION_INVERTED=LV_DISP_ROT_180",
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
"'-DCYD_SCREEN_GAP_PX=10'",
"'-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35'",
"'-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'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-4827S043C-SD",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004788147691.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,146 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32S3_DEV'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
"'-D ESP32_4827S043R'",
"'-D LCD_WIDTH=480'",
"'-D LCD_HEIGHT=272'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
"'-D GPIO_BCKL=2'",
"'-D LCD_ST7262_PAR'",
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(8*1000000)'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=43'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=12'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_XPT2046_SPI'",
"'-D XPT2046_SPI_HOST=SPI2_HOST'",
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=11'",
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=13'",
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=12'",
"'-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=38'",
"'-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=18'",
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D XPT2046_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=10'",
"'-D TF_SPI_MOSI=11'",
"'-D TF_SPI_SCLK=12'",
"'-D TF_SPI_MISO=13'",
"'-DCYD_SCREEN_HEIGHT_PX=272'",
"'-DCYD_SCREEN_WIDTH_PX=480'",
"-DROTATION_INVERTED=LV_DISP_ROT_180",
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
"'-DCYD_SCREEN_GAP_PX=10'",
"'-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35'",
"'-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'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-4827S043R-SD",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004788147691.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,143 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32S3_DEV'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
"'-D ESP32_8048S043C'",
"'-D LCD_WIDTH=800'",
"'-D LCD_HEIGHT=480'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
"'-D GPIO_BCKL=2'",
"'-D LCD_ST7262_PAR'",
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(12.5*1000000)'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_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=10'",
"'-D TF_SPI_MOSI=11'",
"'-D TF_SPI_SCLK=12'",
"'-D TF_SPI_MISO=13'",
"-DCYD_SCREEN_HEIGHT_PX=480",
"-DCYD_SCREEN_WIDTH_PX=800",
"-DROTATION_INVERTED=LV_DISP_ROT_180",
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
"-DCYD_SCREEN_GAP_PX=15",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=60",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=60",
"-DCYD_SCREEN_FONT=lv_font_montserrat_22",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_16",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=70",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-8048S043C-SD",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005006110360174.html",
"vendor": "Sunton"
}

View File

@@ -9,14 +9,15 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[env] [env]
platform = espressif32 platform = https://github.com/platformio/platform-espressif32#v6.4.0
board = esp32dev board = esp32dev
framework = arduino framework = arduino
monitor_speed = 115200 monitor_speed = 115200
lib_deps = lib_deps =
https://github.com/suchmememanyskill/esp32-smartdisplay https://github.com/suchmememanyskill/esp32-smartdisplay#9c1d737
bblanchon/ArduinoJson@^7.0.0 bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1 plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
monitor_filters = esp32_exception_decoder monitor_filters = esp32_exception_decoder
build_flags = build_flags =
-DLV_CONF_PATH="../../../../src/conf/lv_conf.h" -DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
@@ -32,6 +33,7 @@ lib_deps =
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
bblanchon/ArduinoJson@^7.0.0 bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1 plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-3248S035C] [env:esp32-3248S035C]
board = esp32-3248S035C board = esp32-3248S035C
@@ -42,9 +44,43 @@ lib_deps =
https://github.com/OperatorB/gt911-arduino-fixed-reset.git https://github.com/OperatorB/gt911-arduino-fixed-reset.git
bblanchon/ArduinoJson@^7.0.0 bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1 plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-3248S035C-smartdisplay] [env:esp32-3248S035C-V]
board = esp32-3248S035C-vertical
lib_deps =
SPI
https://github.com/suchmememanyskill/lvgl
https://github.com/Bodmer/TFT_eSPI.git
https://github.com/OperatorB/gt911-arduino-fixed-reset.git
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-2432S024C-SD]
board = esp32-2432S024C-smartdisplay
[env:esp32-2432S028Rv1-SD]
board = esp32-2432S028RV1-smartdisplay
[env:esp32-2432S028Rv2-SD]
board = esp32-2432S028RV2-smartdisplay
[env:esp32-2432S028Rv3-SD]
board = esp32-2432S028RV3-smartdisplay
[env:esp32-2432S032C-SD]
board = esp32-2432S032C-smartdisplay
[env:esp32-3248S035C-SD]
board = esp32-3248S035C-smartdisplay board = esp32-3248S035C-smartdisplay
[env:esp32-2432S028R-smartdisplay] [env:esp32-4827S043C-SD]
board = esp32-2432S028R-smartdisplay board = esp32-4827S043C-smartdisplay
[env:esp32-4827S043R-SD]
board = esp32-4827S043C-smartdisplay
[env:esp32-8048S043C-SD]
board = esp32-8048S043C-smartdisplay

View File

@@ -6,22 +6,25 @@ GLOBAL_CONFIG global_config = {0};
COLOR_DEF color_defs[] = { COLOR_DEF color_defs[] = {
{LV_PALETTE_BLUE, 0, LV_PALETTE_RED}, {LV_PALETTE_BLUE, 0, LV_PALETTE_RED},
{LV_PALETTE_GREEN, 0, LV_PALETTE_PURPLE},
{LV_PALETTE_LIME, -2, LV_PALETTE_PURPLE}, {LV_PALETTE_LIME, -2, LV_PALETTE_PURPLE},
{LV_PALETTE_GREY, 0, LV_PALETTE_CYAN}, {LV_PALETTE_GREY, 0, LV_PALETTE_CYAN},
{LV_PALETTE_YELLOW, -2, LV_PALETTE_PINK}, {LV_PALETTE_YELLOW, -2, LV_PALETTE_PINK},
{LV_PALETTE_ORANGE, -2, LV_PALETTE_BLUE}, {LV_PALETTE_ORANGE, -2, LV_PALETTE_BLUE},
{LV_PALETTE_RED, 0, LV_PALETTE_GREEN}, {LV_PALETTE_RED, 0, LV_PALETTE_BLUE},
{LV_PALETTE_PURPLE, 0, LV_PALETTE_GREY}, {LV_PALETTE_PURPLE, 0, LV_PALETTE_CYAN},
}; };
void WriteGlobalConfig() { void write_global_config()
{
Preferences preferences; Preferences preferences;
preferences.begin("global_config", false); preferences.begin("global_config", false);
preferences.putBytes("global_config", &global_config, sizeof(global_config)); preferences.putBytes("global_config", &global_config, sizeof(global_config));
preferences.end(); preferences.end();
} }
void VerifyVersion(){ void verify_version()
{
Preferences preferences; Preferences preferences;
if (!preferences.begin("global_config", false)) if (!preferences.begin("global_config", false))
return; return;
@@ -37,17 +40,93 @@ void VerifyVersion(){
preferences.end(); preferences.end();
} }
void LoadGlobalConfig() { PRINTER_CONFIG* get_current_printer_config()
{
return &global_config.printer_config[global_config.printer_index];
}
int get_printer_config_count()
{
int count = 0;
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++) {
if (global_config.printer_config[i].ip_configured)
count++;
}
return count;
}
int get_printer_config_free_index()
{
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++) {
if (!global_config.printer_config[i].ip_configured)
return i;
}
return -1;
}
void set_printer_config_index(int index)
{
if (index < 0 || index >= PRINTER_CONFIG_COUNT)
return;
PRINTER_CONFIG* old_config = &global_config.printer_config[global_config.printer_index];
PRINTER_CONFIG* new_config = &global_config.printer_config[index];
global_config.printer_index = index;
if (!new_config->ip_configured){
new_config->raw = old_config->raw;
new_config->ip_configured = false;
new_config->auth_configured = false;
new_config->printer_name[0] = 0;
new_config->klipper_host[0] = 0;
new_config->klipper_auth[0] = 0;
new_config->klipper_port = 0;
new_config->color_scheme = old_config->color_scheme;
// TODO: Replace with memcpy
for (int i = 0; i < 3; i++){
new_config->hotend_presets[i] = old_config->hotend_presets[i];
new_config->bed_presets[i] = old_config->bed_presets[i];
}
for (int i = 0; i < 3; i++){
new_config->printer_move_x_steps[i] = old_config->printer_move_x_steps[i];
new_config->printer_move_y_steps[i] = old_config->printer_move_y_steps[i];
new_config->printer_move_z_steps[i] = old_config->printer_move_z_steps[i];
}
write_global_config();
ESP.restart();
}
write_global_config();
}
void load_global_config()
{
global_config.version = CONFIG_VERSION; global_config.version = CONFIG_VERSION;
global_config.brightness = 255; global_config.brightness = 255;
global_config.screenTimeout = 5; global_config.screen_timeout = 5;
global_config.hotend_presets[0] = 0; global_config.printer_config[0].hotend_presets[0] = 0;
global_config.hotend_presets[1] = 200; global_config.printer_config[0].hotend_presets[1] = 200;
global_config.hotend_presets[2] = 240; global_config.printer_config[0].hotend_presets[2] = 240;
global_config.bed_presets[0] = 0; global_config.printer_config[0].bed_presets[0] = 0;
global_config.bed_presets[1] = 60; global_config.printer_config[0].bed_presets[1] = 60;
global_config.bed_presets[2] = 70; global_config.printer_config[0].bed_presets[2] = 70;
VerifyVersion(); global_config.printer_config[0].printer_move_x_steps[0] = 10;
global_config.printer_config[0].printer_move_x_steps[1] = 100;
global_config.printer_config[0].printer_move_x_steps[2] = 1000;
global_config.printer_config[0].printer_move_y_steps[0] = 10;
global_config.printer_config[0].printer_move_y_steps[1] = 100;
global_config.printer_config[0].printer_move_y_steps[2] = 1000;
global_config.printer_config[0].printer_move_z_steps[0] = 1;
global_config.printer_config[0].printer_move_z_steps[1] = 10;
global_config.printer_config[0].printer_move_z_steps[2] = 100;
verify_version();
Preferences preferences; Preferences preferences;
preferences.begin("global_config", true); preferences.begin("global_config", true);
preferences.getBytes("global_config", &global_config, sizeof(global_config)); preferences.getBytes("global_config", &global_config, sizeof(global_config));

View File

@@ -3,7 +3,8 @@
#include "lvgl.h" #include "lvgl.h"
#define CONFIG_VERSION 4 #define CONFIG_VERSION 6
#define PRINTER_CONFIG_COUNT 8
enum { enum {
REMAINING_TIME_CALC_PERCENTAGE = 0, REMAINING_TIME_CALC_PERCENTAGE = 0,
@@ -11,47 +12,79 @@ enum {
REMAINING_TIME_CALC_SLICER = 2, REMAINING_TIME_CALC_SLICER = 2,
}; };
enum {
SHOW_STATS_ON_PROGRESS_PANEL_NONE = 0,
SHOW_STATS_ON_PROGRESS_PANEL_LAYER = 1,
SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL = 2,
SHOW_STATS_ON_PROGRESS_PANEL_ALL = 3,
};
typedef struct _PRINTER_CONFIG {
union {
unsigned int raw;
struct {
// Internal
bool ip_configured : 1;
bool auth_configured : 1;
// External
bool light_mode : 1;
bool invert_colors : 1;
unsigned char remaining_time_calc_mode : 2;
unsigned char show_stats_on_progress_panel : 2;
bool custom_filament_move_macros : 1;
};
};
char printer_name[25];
char klipper_host[65];
char klipper_auth[33];
unsigned short klipper_port;
unsigned char color_scheme;
unsigned short hotend_presets[3];
unsigned short bed_presets[3];
unsigned short printer_move_x_steps[3];
unsigned short printer_move_y_steps[3];
unsigned short printer_move_z_steps[3];
} PRINTER_CONFIG;
typedef struct _GLOBAL_CONFIG { typedef struct _GLOBAL_CONFIG {
unsigned char version; unsigned char version;
union { union {
unsigned int raw; unsigned int raw;
struct { struct {
// Internal // Internal
bool screenCalibrated : 1; bool screen_calibrated : 1;
bool wifiConfigured : 1; bool wifi_configured : 1;
bool ipConfigured : 1;
// External // External
bool lightMode : 1; bool rotate_screen : 1;
bool invertColors : 1; bool auto_ota_update : 1;
bool rotateScreen : 1; bool multi_printer_mode : 1;
bool onDuringPrint : 1; bool on_during_print : 1;
bool autoOtaUpdate : 1; bool display_mode : 1; // Driver specifc usage. Currently only used on ESP32-2432S028R to fix the screen on the usb-c model
unsigned char remaining_time_calc_mode : 2; bool disable_m117_messaging : 1;
bool sort_macros : 1;
// Internal
bool auth_configured : 1;
}; };
}; };
float screenCalXOffset;
float screenCalXMult;
float screenCalYOffset;
float screenCalYMult;
char wifiSSID[32]; PRINTER_CONFIG printer_config[PRINTER_CONFIG_COUNT];
char wifiPassword[64];
char klipperHost[64]; float screen_cal_x_offset;
unsigned short klipperPort; float screen_cal_x_mult;
float screen_cal_y_offset;
float screen_cal_y_mult;
char wifi_SSID[33];
char wifi_password[65];
unsigned char color_scheme;
unsigned char brightness; unsigned char brightness;
unsigned char screenTimeout; unsigned char screen_timeout;
unsigned char printer_index;
unsigned short hotend_presets[3];
unsigned short bed_presets[3];
char klipper_auth[33];
} GLOBAL_CONFIG; } GLOBAL_CONFIG;
typedef struct _COLOR_DEF { typedef struct _COLOR_DEF {
@@ -63,8 +96,13 @@ typedef struct _COLOR_DEF {
extern GLOBAL_CONFIG global_config; extern GLOBAL_CONFIG global_config;
extern COLOR_DEF color_defs[]; extern COLOR_DEF color_defs[];
void WriteGlobalConfig(); void write_global_config();
void VerifyVersion(); void verify_version();
void LoadGlobalConfig(); void load_global_config();
PRINTER_CONFIG* get_current_printer_config();
int get_printer_config_count();
void set_printer_config_index(int index);
int get_printer_config_free_index();
#endif // !_GLOBAL_CONFIG_INIT #endif // !_GLOBAL_CONFIG_INIT

View File

@@ -49,7 +49,7 @@
#define LV_MEM_CUSTOM 0 #define LV_MEM_CUSTOM 0
#if LV_MEM_CUSTOM == 0 #if LV_MEM_CUSTOM == 0
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/ /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
#define LV_MEM_SIZE (32U * 1024U) /*[bytes]*/ #define LV_MEM_SIZE (40U * 1024U) /*[bytes]*/
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
#define LV_MEM_ADR 0 /*0: unused*/ #define LV_MEM_ADR 0 /*0: unused*/
@@ -194,7 +194,7 @@
*-----------*/ *-----------*/
/*Enable the log module*/ /*Enable the log module*/
#define LV_USE_LOG 1 #define LV_USE_LOG 0
#if LV_USE_LOG #if LV_USE_LOG
/*How important log should be added: /*How important log should be added:
@@ -204,7 +204,7 @@
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
*LV_LOG_LEVEL_USER Only logs added by the user *LV_LOG_LEVEL_USER Only logs added by the user
*LV_LOG_LEVEL_NONE Do not log anything*/ *LV_LOG_LEVEL_NONE Do not log anything*/
#define LV_LOG_LEVEL LV_LOG_LEVEL_USER #define LV_LOG_LEVEL LV_LOG_LEVEL_NONE
/*1: Print the log with 'printf'; /*1: Print the log with 'printf';
*0: User need to register a callback with `lv_log_register_print_cb()`*/ *0: User need to register a callback with `lv_log_register_print_cb()`*/
@@ -336,7 +336,7 @@
#define LV_FONT_MONTSERRAT_16 1 #define LV_FONT_MONTSERRAT_16 1
#define LV_FONT_MONTSERRAT_18 0 #define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_20 0 #define LV_FONT_MONTSERRAT_20 0
#define LV_FONT_MONTSERRAT_22 0 #define LV_FONT_MONTSERRAT_22 1
#define LV_FONT_MONTSERRAT_24 0 #define LV_FONT_MONTSERRAT_24 0
#define LV_FONT_MONTSERRAT_26 0 #define LV_FONT_MONTSERRAT_26 0
#define LV_FONT_MONTSERRAT_28 1 #define LV_FONT_MONTSERRAT_28 1
@@ -607,7 +607,7 @@
#endif #endif
/*PNG decoder library*/ /*PNG decoder library*/
#define LV_USE_PNG 0 #define LV_USE_PNG 1
/*BMP decoder library*/ /*BMP decoder library*/
#define LV_USE_BMP 0 #define LV_USE_BMP 0
@@ -678,16 +678,16 @@
====================*/ ====================*/
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ /*Show some widget. It might be required to increase `LV_MEM_SIZE` */
#define LV_USE_DEMO_WIDGETS 1 #define LV_USE_DEMO_WIDGETS 0
#if LV_USE_DEMO_WIDGETS #if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 1 #define LV_DEMO_WIDGETS_SLIDESHOW 1
#endif #endif
/*Demonstrate the usage of encoder and keyboard*/ /*Demonstrate the usage of encoder and keyboard*/
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 1 #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
/*Benchmark your system*/ /*Benchmark your system*/
#define LV_USE_DEMO_BENCHMARK 1 #define LV_USE_DEMO_BENCHMARK 0
/*Stress test for LVGL*/ /*Stress test for LVGL*/
#define LV_USE_DEMO_STRESS 0 #define LV_USE_DEMO_STRESS 0

View File

@@ -2,22 +2,21 @@
#include "data_setup.h" #include "data_setup.h"
#include "lvgl.h" #include "lvgl.h"
#include "../conf/global_config.h" #include "../conf/global_config.h"
#include <HTTPClient.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <esp_task_wdt.h> #include <esp_task_wdt.h>
#include "macros_query.h" #include "macros_query.h"
#include <UrlEncode.h> #include <UrlEncode.h>
#include "http_client.h"
const char *printer_state_messages[] = { #include "../ui/ui_utils.h"
"Error", #include "macros_query.h"
"Idle",
"Printing"};
Printer printer = {0}; Printer printer = {0};
int klipper_request_consecutive_fail_count = 0; PrinterMinimal *printer_minimal;
int klipper_request_consecutive_fail_count = 999;
char filename_buff[512] = {0}; char filename_buff[512] = {0};
SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore; SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore;
const long data_update_interval = 780; const long data_update_interval = 780;
unsigned char lock_absolute_relative_mode_swap = 0;
void semaphore_init(){ void semaphore_init(){
freezeRenderThreadSemaphore = xSemaphoreCreateMutex(); freezeRenderThreadSemaphore = xSemaphoreCreateMutex();
@@ -45,19 +44,8 @@ void unfreeze_render_thread(){
void send_gcode(bool wait, const char *gcode) void send_gcode(bool wait, const char *gcode)
{ {
Serial.printf("Sending gcode: %s\n", gcode); Serial.printf("Sending gcode: %s\n", gcode);
char buff[256] = {};
sprintf(buff, "http://%s:%d/printer/gcode/script?script=%s", global_config.klipperHost, global_config.klipperPort, urlEncode(gcode).c_str());
HTTPClient client;
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
if (!wait)
{
client.setTimeout(1000);
}
SETUP_HTTP_CLIENT_FULL("/printer/gcode/script?script=" + urlEncode(gcode), false, wait ? 5000 : 750);
try try
{ {
client.GET(); client.GET();
@@ -75,14 +63,7 @@ int get_slicer_time_estimate_s()
delay(10); delay(10);
char buff[256] = {}; SETUP_HTTP_CLIENT("/server/files/metadata?filename=" + urlEncode(printer.print_filename));
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(); int httpCode = client.GET();
@@ -102,25 +83,29 @@ void move_printer(const char* axis, float amount, bool relative) {
char gcode[64]; char gcode[64];
const char* extra = (amount > 0) ? "+" : ""; const char* extra = (amount > 0) ? "+" : "";
const char* start = "";
const char* end = "";
bool absolute_coords = printer.absolute_coords; bool absolute_coords = printer.absolute_coords;
if (absolute_coords && relative) { if (absolute_coords && relative) {
send_gcode(true, "G91"); start = "G91\n";
} }
else if (!absolute_coords && !relative) { else if (!absolute_coords && !relative) {
send_gcode(true, "G90"); start = "G90\n";
} }
sprintf(gcode, "G1 %s%s%.3f F6000", axis, extra, amount);
send_gcode(true, gcode);
if (absolute_coords && relative) { if (absolute_coords && relative) {
send_gcode(true, "G90"); end = "\nG90";
} }
else if (!absolute_coords && !relative) { else if (!absolute_coords && !relative) {
send_gcode(true, "G91"); end = "\nG91";
} }
sprintf(gcode, "%sG1 %s%s%.3f F6000%s", start, axis, extra, amount, end);
send_gcode(true, gcode);
lock_absolute_relative_mode_swap = 2;
} }
int last_slicer_time_query = -15000; int last_slicer_time_query = -15000;
@@ -128,25 +113,26 @@ int last_slicer_time_query = -15000;
void fetch_printer_data() void fetch_printer_data()
{ {
freeze_request_thread(); freeze_request_thread();
char buff[256] = {}; PRINTER_CONFIG *config = get_current_printer_config();
sprintf(buff, "http://%s:%d/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan", global_config.klipperHost, global_config.klipperPort); SETUP_HTTP_CLIENT("/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status")
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(); int httpCode = client.GET();
delay(10); delay(10);
if (httpCode == 200) if (httpCode == 200)
{ {
int printer_state = printer.state;
if (printer.state == PRINTER_STATE_OFFLINE)
{
printer.state = PRINTER_STATE_ERROR;
}
klipper_request_consecutive_fail_count = 0; klipper_request_consecutive_fail_count = 0;
JsonDocument doc; JsonDocument doc;
deserializeJson(doc, client.getStream()); deserializeJson(doc, client.getStream());
auto status = doc["result"]["status"]; auto status = doc["result"]["status"];
bool emit_state_update = false; bool emit_state_update = false;
int printer_state = printer.state;
delay(10); delay(10);
unfreeze_request_thread(); unfreeze_request_thread();
freeze_render_thread(); freeze_render_thread();
@@ -160,7 +146,7 @@ void fetch_printer_data()
{ {
printer_state = PRINTER_STATE_IDLE; printer_state = PRINTER_STATE_IDLE;
} }
else if (strcmp(state, "shutdown") == 0 && printer.state != PRINTER_STATE_ERROR) else if ((strcmp(state, "shutdown") == 0 || strcmp(state, "error") == 0) && printer.state != PRINTER_STATE_ERROR)
{ {
printer_state = PRINTER_STATE_ERROR; printer_state = PRINTER_STATE_ERROR;
} }
@@ -211,7 +197,16 @@ void fetch_printer_data()
printer.gcode_offset[1] = status["gcode_move"]["homing_origin"][1]; printer.gcode_offset[1] = status["gcode_move"]["homing_origin"][1];
printer.gcode_offset[2] = status["gcode_move"]["homing_origin"][2]; printer.gcode_offset[2] = status["gcode_move"]["homing_origin"][2];
bool absolute_coords = status["gcode_move"]["absolute_coordinates"]; bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
if (lock_absolute_relative_mode_swap > 0)
{
lock_absolute_relative_mode_swap--;
}
else
{
printer.absolute_coords = absolute_coords == true; printer.absolute_coords = absolute_coords == true;
}
printer.speed_mult = status["gcode_move"]["speed_factor"]; printer.speed_mult = status["gcode_move"]["speed_factor"];
printer.extrude_mult = status["gcode_move"]["extrude_factor"]; printer.extrude_mult = status["gcode_move"]["extrude_factor"];
printer.feedrate_mm_per_s = status["gcode_move"]["speed"]; printer.feedrate_mm_per_s = status["gcode_move"]["speed"];
@@ -231,9 +226,10 @@ void fetch_printer_data()
if (status.containsKey("print_stats")) if (status.containsKey("print_stats"))
{ {
const char *filename = status["print_stats"]["filename"]; const char *filename = status["print_stats"]["filename"];
strcpy(filename_buff, filename); strcpy(filename_buff, filename == NULL ? "" : filename);
printer.print_filename = filename_buff; printer.print_filename = filename_buff;
printer.elapsed_time_s = status["print_stats"]["print_duration"]; printer.elapsed_time_s = status["print_stats"]["total_duration"];
printer.printed_time_s = status["print_stats"]["print_duration"];
printer.filament_used_mm = status["print_stats"]["filament_used"]; printer.filament_used_mm = status["print_stats"]["filament_used"];
printer.total_layers = status["print_stats"]["info"]["total_layer"]; printer.total_layers = status["print_stats"]["info"]["total_layer"];
printer.current_layer = status["print_stats"]["info"]["current_layer"]; printer.current_layer = status["print_stats"]["info"]["current_layer"];
@@ -242,7 +238,7 @@ void fetch_printer_data()
if (state == nullptr) if (state == nullptr)
{ {
printer_state = PRINTER_STATE_ERROR; // Continue
} }
else if (strcmp(state, "printing") == 0) else if (strcmp(state, "printing") == 0)
{ {
@@ -258,28 +254,36 @@ void fetch_printer_data()
} }
} }
// TODO: make a call to /server/files/metadata to get more accurate time estimates if (status.containsKey("display_status"))
// https://moonraker.readthedocs.io/en/latest/web_api/#server-administration {
printer.print_progress = status["display_status"]["progress"];
const char* message = status["display_status"]["message"];
if (!global_config.disable_m117_messaging)
{
lv_create_popup_message(message, 10000);
}
}
if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0) if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0)
{ {
float remaining_time_s_percentage = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s; float remaining_time_s_percentage = (printer.printed_time_s / printer.print_progress) - printer.printed_time_s;
float remaining_time_s_slicer = 0; float remaining_time_s_slicer = 0;
if (printer.slicer_estimated_print_time_s > 0) if (printer.slicer_estimated_print_time_s > 0)
{ {
remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.elapsed_time_s; remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.printed_time_s;
} }
if (remaining_time_s_slicer <= 0 || global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE) if (remaining_time_s_slicer <= 0 || config->remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE)
{ {
printer.remaining_time_s = remaining_time_s_percentage; printer.remaining_time_s = remaining_time_s_percentage;
} }
else if (global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_INTERPOLATED) else if (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); 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) else if (config->remaining_time_calc_mode == REMAINING_TIME_CALC_SLICER)
{ {
printer.remaining_time_s = remaining_time_s_slicer; printer.remaining_time_s = remaining_time_s_slicer;
} }
@@ -315,10 +319,111 @@ void fetch_printer_data()
} }
else else
{ {
unfreeze_request_thread();
klipper_request_consecutive_fail_count++; klipper_request_consecutive_fail_count++;
if (klipper_request_consecutive_fail_count == 5)
{
freeze_render_thread();
printer.state = PRINTER_STATE_OFFLINE;
lv_msg_send(DATA_PRINTER_STATE, &printer);
unfreeze_render_thread();
}
Serial.printf("Failed to fetch printer data: %d\n", httpCode); Serial.printf("Failed to fetch printer data: %d\n", httpCode);
}
}
void fetch_printer_data_minimal()
{
PrinterMinimal data[PRINTER_CONFIG_COUNT] = {0};
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG *config = &global_config.printer_config[i];
if (!config->ip_configured)
{
data[i].state = PRINTER_STATE_OFFLINE;
continue;
}
delay(10);
HTTPClient client;
configure_http_client(client, get_full_url("/printer/objects/query?webhooks&print_stats&virtual_sdcard", config), true, 1000);
freeze_request_thread();
int httpCode = client.GET();
delay(10);
if (httpCode == 200)
{
if (data[i].state == PRINTER_STATE_OFFLINE)
{
data[i].state = PRINTER_STATE_ERROR;
}
data[i].power_devices = power_devices_count(config);
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto status = doc["result"]["status"];
unfreeze_request_thread();
if (status.containsKey("webhooks"))
{
const char *state = status["webhooks"]["state"];
if (strcmp(state, "ready") == 0 && data[i].state == PRINTER_STATE_ERROR)
{
data[i].state = PRINTER_STATE_IDLE;
}
else if (strcmp(state, "shutdown") == 0 && data[i].state != PRINTER_STATE_ERROR)
{
data[i].state = PRINTER_STATE_ERROR;
}
}
if (data[i].state != PRINTER_STATE_ERROR)
{
if (status.containsKey("virtual_sdcard"))
{
data[i].print_progress = status["virtual_sdcard"]["progress"];
}
if (status.containsKey("print_stats"))
{
const char *state = status["print_stats"]["state"];
if (state == nullptr)
{
data[i].state = PRINTER_STATE_ERROR;
}
else if (strcmp(state, "printing") == 0)
{
data[i].state = PRINTER_STATE_PRINTING;
}
else if (strcmp(state, "paused") == 0)
{
data[i].state = PRINTER_STATE_PAUSED;
}
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
{
data[i].state = PRINTER_STATE_IDLE;
}
}
}
}
else
{
data[i].state = PRINTER_STATE_OFFLINE;
data[i].power_devices = power_devices_count(config);
unfreeze_request_thread(); unfreeze_request_thread();
} }
}
freeze_render_thread();
memcpy(printer_minimal, data, sizeof(PrinterMinimal) * PRINTER_CONFIG_COUNT);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
unfreeze_render_thread();
} }
void data_loop() void data_loop()
@@ -331,9 +436,16 @@ void data_loop()
void data_loop_background(void * param){ void data_loop_background(void * param){
esp_task_wdt_init(10, true); esp_task_wdt_init(10, true);
int loop_iter = 20;
while (true){ while (true){
delay(data_update_interval); delay(data_update_interval);
fetch_printer_data(); fetch_printer_data();
if (global_config.multi_printer_mode) {
if (loop_iter++ > 20){
fetch_printer_data_minimal();
loop_iter = 0;
}
}
} }
} }
@@ -341,10 +453,11 @@ TaskHandle_t background_loop;
void data_setup() void data_setup()
{ {
printer_minimal = (PrinterMinimal *)calloc(sizeof(PrinterMinimal), PRINTER_CONFIG_COUNT);
semaphore_init(); semaphore_init();
printer.print_filename = filename_buff; printer.print_filename = filename_buff;
fetch_printer_data(); fetch_printer_data();
macros_query_setup();
freeze_render_thread(); freeze_render_thread();
xTaskCreatePinnedToCore(data_loop_background, "data_loop_background", 5000, NULL, 0, &background_loop, 0); xTaskCreatePinnedToCore(data_loop_background, "data_loop_background", 5000, NULL, 2, &background_loop, 0);
} }

View File

@@ -1,14 +1,13 @@
#pragma once #pragma once
enum { enum {
PRINTER_STATE_ERROR = 0, PRINTER_STATE_OFFLINE = 0,
PRINTER_STATE_IDLE = 1, PRINTER_STATE_ERROR = 1,
PRINTER_STATE_PRINTING = 2, PRINTER_STATE_IDLE = 2,
PRINTER_STATE_PAUSED = 3, PRINTER_STATE_PRINTING = 3,
PRINTER_STATE_PAUSED = 4,
}; };
extern const char* printer_state_messages[];
typedef struct _Printer { typedef struct _Printer {
unsigned char state; unsigned char state;
char* state_message; char* state_message;
@@ -21,6 +20,7 @@ typedef struct _Printer {
unsigned char homed_axis; unsigned char homed_axis;
unsigned char absolute_coords; unsigned char absolute_coords;
float elapsed_time_s; float elapsed_time_s;
float printed_time_s;
float remaining_time_s; float remaining_time_s;
float filament_used_mm; float filament_used_mm;
char* print_filename; char* print_filename;
@@ -37,12 +37,20 @@ typedef struct _Printer {
int slicer_estimated_print_time_s; int slicer_estimated_print_time_s;
} Printer; } Printer;
typedef struct _PrinterMinimal {
unsigned char state;
float print_progress; // 0 -> 1
unsigned int power_devices;
} PrinterMinimal;
extern Printer printer; extern Printer printer;
extern PrinterMinimal *printer_minimal;
extern int klipper_request_consecutive_fail_count; extern int klipper_request_consecutive_fail_count;
#define DATA_PRINTER_STATE 1 #define DATA_PRINTER_STATE 1
#define DATA_PRINTER_DATA 2 #define DATA_PRINTER_DATA 2
#define DATA_PRINTER_TEMP_PRESET 3 #define DATA_PRINTER_TEMP_PRESET 3
#define DATA_PRINTER_MINIMAL 4
void data_loop(); void data_loop();
void data_setup(); void data_setup();

View File

@@ -1,6 +1,10 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R #ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
#include "../screen_driver.h" #include "../screen_driver.h"
#ifdef CYD_SCREEN_VERTICAL
#error "Vertical screen not supported with the ESP32_2432S028R driver"
#endif
#include <SPI.h> #include <SPI.h>
#include <TFT_eSPI.h> #include <TFT_eSPI.h>
#include "../../conf/global_config.h" #include "../../conf/global_config.h"
@@ -63,27 +67,34 @@ void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
} }
void set_invert_display(){ void set_invert_display(){
tft.invertDisplay(global_config.invertColors); tft.invertDisplay(get_current_printer_config()->invert_colors);
} }
void screen_setup() void screen_setup()
{ {
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi); touchscreen.begin(touchscreen_spi);
touchscreen.setRotation(global_config.rotateScreen ? 3 : 1); touchscreen.setRotation(global_config.rotate_screen ? 3 : 1);
lv_init(); lv_init();
tft.init(); tft.init();
if (global_config.display_mode) {
// <3 https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/cyd.md#the-display-doesnt-look-as-good
tft.writecommand(ILI9341_GAMMASET); //Gamma curve selected
tft.writedata(2);
delay(120);
tft.writecommand(ILI9341_GAMMASET); //Gamma curve selected
tft.writedata(1);
}
ledcSetup(0, 5000, 12); ledcSetup(0, 5000, 12);
ledcAttachPin(21, 0); ledcAttachPin(21, 0);
tft.setRotation(global_config.rotateScreen ? 3 : 1); tft.setRotation(global_config.rotate_screen ? 3 : 1);
tft.fillScreen(TFT_BLACK); tft.fillScreen(TFT_BLACK);
set_screen_brightness();
set_invert_display(); set_invert_display();
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi); touchscreen.begin(touchscreen_spi);

View File

@@ -1,4 +1,5 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_3248S035C #ifdef CYD_SCREEN_DRIVER_ESP32_3248S035C
#include "../screen_driver.h"
#include "lvgl.h" #include "lvgl.h"
#include <TAMC_GT911.h> #include <TAMC_GT911.h>
@@ -60,15 +61,21 @@ void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{ {
uint16_t magicX; // fix GT911 driver - orientation and handle rotation uint16_t magicX; // fix GT911 driver - orientation and handle rotation
uint16_t magicY; uint16_t magicY;
if (!global_config.rotateScreen) if (!global_config.rotate_screen)
{ {
magicY = tp.points[i].x; magicY = tp.points[i].x;
magicX = TOUCH_HEIGHT - tp.points[i].y; magicX = TOUCH_HEIGHT - tp.points[i].y;
} }
else else
{ {
#ifdef CYD_SCREEN_VERTICAL
// I don't even want to know why this works...
magicY = TOUCH_HEIGHT - tp.points[i].x;
magicX = tp.points[i].y - 160;
#else
magicY = TOUCH_WIDTH - tp.points[i].x; magicY = TOUCH_WIDTH - tp.points[i].x;
magicX = tp.points[i].y; magicX = tp.points[i].y;
#endif
} }
data->point.x = magicX; data->point.x = magicX;
@@ -79,7 +86,7 @@ void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
void set_invert_display() void set_invert_display()
{ {
tft.invertDisplay(global_config.invertColors); tft.invertDisplay(get_current_printer_config()->invert_colors);
} }
void set_LED_color(uint8_t rgbVal[3]) void set_LED_color(uint8_t rgbVal[3])
@@ -102,24 +109,36 @@ void screen_setup()
{ {
// Initialize the touchscreen // Initialize the touchscreen
tp.begin(); tp.begin();
tp.setRotation(ROTATION_NORMAL);
// Initialize LVGL // Initialize LVGL
lv_init(); lv_init();
// Initialize the display // Initialize the display
tft.init(); tft.init();
ledcSetup(0, 5000, 12); ledcSetup(0, 5000, 12);
ledcAttachPin(TFT_BL, 0); ledcAttachPin(TFT_BL, 0);
tft.setRotation(global_config.rotateScreen ? 3 : 1);
tft.fillScreen(TFT_BLACK); tft.fillScreen(TFT_BLACK);
set_screen_brightness();
set_invert_display(); set_invert_display();
LED_init(); LED_init();
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10); lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10);
static lv_disp_drv_t disp_drv; static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv); lv_disp_drv_init(&disp_drv);
#ifdef CYD_SCREEN_VERTICAL
disp_drv.hor_res = TFT_WIDTH;
disp_drv.ver_res = TFT_HEIGHT;
tp.setRotation(2);
tft.setRotation(global_config.rotate_screen ? 2 : 0);
#else
disp_drv.hor_res = TFT_HEIGHT; disp_drv.hor_res = TFT_HEIGHT;
disp_drv.ver_res = TFT_WIDTH; disp_drv.ver_res = TFT_WIDTH;
tft.setRotation(global_config.rotate_screen ? 3 : 1);
tp.setRotation(ROTATION_NORMAL);
#endif
disp_drv.flush_cb = screen_lv_flush; disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf; disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv); lv_disp_drv_register(&disp_drv);

View File

@@ -1,4 +1,3 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY #ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
#include "../screen_driver.h" #include "../screen_driver.h"
@@ -15,13 +14,14 @@ void screen_setBrightness(byte brightness)
smartdisplay_lcd_set_backlight(brightness / 255.0f); smartdisplay_lcd_set_backlight(brightness / 255.0f);
} }
void set_invert_display(){ void set_invert_display()
{
lv_obj_invalidate(lv_scr_act()); 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) void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{ {
if (global_config.invertColors) { if (get_current_printer_config()->invert_colors) {
uint32_t w = (area->x2 - area->x1 + 1); uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1); uint32_t h = (area->y2 - area->y1 + 1);
@@ -33,6 +33,23 @@ void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_col
original_screen_driver(disp_drv, area, color_p); original_screen_driver(disp_drv, area, color_p);
} }
#ifndef ROTATION_INVERTED
#ifdef CYD_SCREEN_VERTICAL
#define ROTATION_INVERTED LV_DISP_ROT_180
#else
#define ROTATION_INVERTED LV_DISP_ROT_270
#endif
#endif
#ifndef ROTATION_NORMAL
#ifdef CYD_SCREEN_VERTICAL
#define ROTATION_NORMAL LV_DISP_ROT_NONE
#else
#define ROTATION_NORMAL LV_DISP_ROT_90
#endif
#endif
void screen_setup() void screen_setup()
{ {
smartdisplay_init(); smartdisplay_init();
@@ -44,7 +61,7 @@ void screen_setup()
} }
#endif // CYD_SCREEN_DISABLE_INVERT_COLORS #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); lv_disp_set_rotation(lv_disp_get_default(), (global_config.rotate_screen) ? ROTATION_INVERTED : ROTATION_NORMAL);
} }
#endif // CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY #endif // CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY

View File

@@ -2,16 +2,15 @@
#include "files_query.h" #include "files_query.h"
#include "../conf/global_config.h" #include "../conf/global_config.h"
#include "data_setup.h" #include "data_setup.h"
#include <HTTPClient.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <HardwareSerial.h> #include <HardwareSerial.h>
#include "http_client.h"
// Always has +1 entry with a null'd name // Always has +1 entry with a null'd name
FILESYSTEM_FILE* last_query = NULL; FILESYSTEM_FILE* last_query = NULL;
FILESYSTEM_FILE* get_files(int limit){ void clear_files()
freeze_request_thread(); {
if (last_query != NULL){ if (last_query != NULL){
FILESYSTEM_FILE* current = last_query; FILESYSTEM_FILE* current = last_query;
@@ -21,21 +20,20 @@ FILESYSTEM_FILE* get_files(int limit){
} }
free(last_query); free(last_query);
last_query = NULL;
} }
}
FILESYSTEM_FILE* get_files(int limit)
{
freeze_request_thread();
clear_files();
Serial.printf("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()); Serial.printf("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size());
std::list<FILESYSTEM_FILE> files; std::list<FILESYSTEM_FILE> files;
auto timer_request = millis(); auto timer_request = millis();
char buff[256] = {}; SETUP_HTTP_CLIENT_FULL("/server/files/list", true, 5000);
sprintf(buff, "http://%s:%d/server/files/list", global_config.klipperHost, global_config.klipperPort);
HTTPClient client;
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(); int httpCode = client.GET();
auto timer_parse = millis(); auto timer_parse = millis();

View File

@@ -20,3 +20,4 @@ typedef struct _FILESYSTEM_FILE {
} FILESYSTEM_FILE; } FILESYSTEM_FILE;
FILESYSTEM_FILE* get_files(int limit); FILESYSTEM_FILE* get_files(int limit);
void clear_files();

View File

@@ -0,0 +1,29 @@
#include "http_client.h"
String get_full_url(String url_part, PRINTER_CONFIG * config)
{
return "http://" + String(config->klipper_host) + ":" + String(config->klipper_port) + url_part;
}
String get_full_url(String url_part)
{
return "http://" + String(get_current_printer_config()->klipper_host) + ":" + String(get_current_printer_config()->klipper_port) + url_part;
}
void configure_http_client(HTTPClient &client, String url, bool stream, int timeout)
{
if (stream){
client.useHTTP10(true);
}
if (timeout > 0){
client.setTimeout(timeout);
client.setConnectTimeout(timeout);
}
client.begin(url);
if (get_current_printer_config()->auth_configured) {
client.addHeader("X-Api-Key", get_current_printer_config()->klipper_auth);
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include <HTTPClient.h>
#include "../conf/global_config.h"
String get_full_url(String url_part);
String get_full_url(String url_part, PRINTER_CONFIG * config);
void configure_http_client(HTTPClient &client, String url, bool stream = true, int timeout = 1000);
#define SETUP_HTTP_CLIENT(url_part) HTTPClient client; configure_http_client(client, get_full_url(url_part));
#define SETUP_HTTP_CLIENT_FULL(url_part, stream, timeout) HTTPClient client; configure_http_client(client, get_full_url(url_part), stream, timeout);

View File

@@ -12,6 +12,27 @@
#define CPU_FREQ_LOW 80 #define CPU_FREQ_LOW 80
#endif #endif
unsigned long last_milis = 0;
void lv_handler()
{
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
if (digitalRead(0) == HIGH)
{
last_milis = millis();
}
else if (millis() - last_milis > 8000)
{
global_config.screen_calibrated = false;
write_global_config();
ESP.restart();
}
#endif
lv_timer_handler();
lv_task_handler();
}
typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data); typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
bool is_screen_in_sleep = false; bool is_screen_in_sleep = false;
@@ -25,13 +46,14 @@ void lv_touch_intercept_calibration(lv_indev_drv_t *indev_driver, lv_indev_data_
original_touch_driver(indev_driver, data); original_touch_driver(indev_driver, data);
if (data->state == LV_INDEV_STATE_PR){ if (data->state == LV_INDEV_STATE_PR){
point[0] = data->point.x; lv_coord_t local_point[] = {data->point.x, data->point.y};
point[1] = data->point.y;
while (data->state == LV_INDEV_STATE_PR){ while (data->state == LV_INDEV_STATE_PR){
original_touch_driver(indev_driver, data); original_touch_driver(indev_driver, data);
delay(20); delay(20);
} }
point[0] = local_point[0];
point[1] = local_point[1];
} }
data->state = LV_INDEV_STATE_REL; data->state = LV_INDEV_STATE_REL;
@@ -53,14 +75,14 @@ void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
screen_timer_wake(); screen_timer_wake();
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION #ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
data->point.x = round((data->point.x * global_config.screenCalXMult) + global_config.screenCalXOffset); data->point.x = round((data->point.x * global_config.screen_cal_x_mult) + global_config.screen_cal_x_offset);
data->point.y = round((data->point.y * global_config.screenCalYMult) + global_config.screenCalYOffset); data->point.y = round((data->point.y * global_config.screen_cal_y_mult) + global_config.screen_cal_y_offset);
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION #endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
} }
} }
void lv_do_calibration(){ void lv_do_calibration(){
if (global_config.screenCalibrated){ if (global_config.screen_calibrated){
return; return;
} }
@@ -74,48 +96,61 @@ void lv_do_calibration(){
lv_label_set_text(label, "Calibrate Screen"); lv_label_set_text(label, "Calibrate Screen");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * line = lv_line_create(lv_scr_act()); lv_obj_t * line_x = lv_line_create(lv_scr_act());
lv_obj_t * line_y = lv_line_create(lv_scr_act());
static lv_point_t line_points_x[] = { {0, 10}, {21, 10} }; static lv_point_t line_points_x[] = { {0, 10}, {21, 10} };
static lv_point_t line_points_y[] = { {10, 0}, {10, 21} }; static lv_point_t line_points_y[] = { {10, 0}, {10, 21} };
lv_line_set_points(line, line_points_x, 2); lv_line_set_points(line_x, line_points_x, 2);
lv_obj_align(line, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_set_style_line_width(line_x, 1, 0);
lv_obj_set_style_line_width(line, 1, 0); lv_line_set_points(line_y, line_points_y, 2);
lv_obj_set_style_line_width(line_y, 1, 0);
lv_obj_t * line2 = lv_line_create(lv_scr_act()); #ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
lv_line_set_points(line2, line_points_y, 2); lv_obj_align(line_x, LV_ALIGN_TOP_RIGHT, 1, 0);
lv_obj_align(line2, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_align(line_y, LV_ALIGN_TOP_RIGHT, -10, 0);
lv_obj_set_style_line_width(line2, 1, 0); #else
lv_obj_align(line_x, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_align(line_y, LV_ALIGN_TOP_LEFT, 0, 0);
#endif
while (true){ while (true){
lv_timer_handler(); lv_handler();
lv_task_handler();
if (point[0] != 0 && point[1] != 0){ if (point[0] != 0 && point[1] != 0){
break; break;
} }
} }
delay(300);
lv_coord_t x1 = point[0]; lv_coord_t x1 = point[0];
lv_coord_t y1 = point[1]; lv_coord_t y1 = point[1];
point[0] = 0; point[0] = 0;
point[1] = 0; point[1] = 0;
lv_obj_del(line); lv_obj_del(line_x);
lv_obj_del(line2); lv_obj_del(line_y);
line = lv_line_create(lv_scr_act()); line_x = lv_line_create(lv_scr_act());
lv_line_set_points(line, line_points_x, 2); line_y = lv_line_create(lv_scr_act());
lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, 1, -10); lv_line_set_points(line_x, line_points_x, 2);
lv_obj_set_style_line_width(line, 1, 0); lv_line_set_points(line_y, line_points_y, 2);
lv_obj_set_style_line_width(line_x, 1, 0);
lv_obj_set_style_line_width(line_y, 1, 0);
line = lv_line_create(lv_scr_act());
lv_line_set_points(line, line_points_y, 2); #ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, -10, 1); lv_obj_align(line_x, LV_ALIGN_BOTTOM_LEFT, 0, -10);
lv_obj_align(line_y, LV_ALIGN_BOTTOM_LEFT, 0, 1);
#else
lv_obj_align(line_x, LV_ALIGN_BOTTOM_RIGHT, 1, -10);
lv_obj_align(line_y, LV_ALIGN_BOTTOM_RIGHT, -10, 1);
#endif
while (true){ while (true){
lv_timer_handler(); lv_handler();
lv_task_handler();
if (point[0] != 0 && point[1] != 0){ if (point[0] != 0 && point[1] != 0){
break; break;
@@ -125,19 +160,30 @@ void lv_do_calibration(){
lv_coord_t x2 = point[0]; lv_coord_t x2 = point[0];
lv_coord_t y2 = point[1]; lv_coord_t y2 = point[1];
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
int16_t xDist = CYD_SCREEN_HEIGHT_PX - 20;
int16_t yDist = CYD_SCREEN_WIDTH_PX - 20;
#else
int16_t xDist = CYD_SCREEN_WIDTH_PX - 20; int16_t xDist = CYD_SCREEN_WIDTH_PX - 20;
int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20; int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20;
#endif
global_config.screenCalXMult = (float)xDist / (float)(x2 - x1); global_config.screen_cal_x_mult = (float)xDist / (float)(x2 - x1);
global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult); global_config.screen_cal_x_offset = 10.0 - ((float)x1 * global_config.screen_cal_x_mult);
global_config.screenCalYMult = (float)yDist / (float)(y2 - y1); global_config.screen_cal_y_mult = (float)yDist / (float)(y2 - y1);
global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult); global_config.screen_cal_y_offset = 10.0 - ((float)y1 * global_config.screen_cal_y_mult);
global_config.screenCalibrated = true; if (global_config.screen_cal_x_mult == std::numeric_limits<float>::infinity() || global_config.screen_cal_y_mult == std::numeric_limits<float>::infinity()){
WriteGlobalConfig(); Serial.println("Calibration failed, please try again");
ESP.restart();
}
global_config.screen_calibrated = true;
write_global_config();
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
Serial.printf("Calibration done: X*%.2f + %.2f, Y*%.2f + %.2f\n", global_config.screen_cal_x_mult, global_config.screen_cal_x_offset, global_config.screen_cal_y_mult, global_config.screen_cal_y_offset);
} }
void set_screen_brightness() void set_screen_brightness()
@@ -180,7 +226,7 @@ void screen_timer_sleep(lv_timer_t *timer)
void screen_timer_setup() void screen_timer_setup()
{ {
screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL); screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screen_timeout * 1000 * 60, NULL);
lv_timer_pause(screen_sleep_timer); lv_timer_pause(screen_sleep_timer);
} }
@@ -201,31 +247,34 @@ void screen_timer_period(unsigned int period)
void set_screen_timer_period() void set_screen_timer_period()
{ {
screen_timer_period(global_config.screenTimeout * 1000 * 60); screen_timer_period(global_config.screen_timeout * 1000 * 60);
} }
void set_color_scheme() void set_color_scheme()
{ {
PRINTER_CONFIG *config = get_current_printer_config();
lv_disp_t *dispp = lv_disp_get_default(); lv_disp_t *dispp = lv_disp_get_default();
lv_color_t main_color = {0}; lv_color_t main_color = {0};
COLOR_DEF color_def = color_defs[global_config.color_scheme]; COLOR_DEF color_def = color_defs[config->color_scheme];
if (color_defs[global_config.color_scheme].primary_color_light > 0){ if (color_defs[config->color_scheme].primary_color_light > 0){
main_color = lv_palette_lighten(color_def.primary_color, color_def.primary_color_light); main_color = lv_palette_lighten(color_def.primary_color, color_def.primary_color_light);
} }
else if (color_defs[global_config.color_scheme].primary_color_light < 0) { else if (color_defs[config->color_scheme].primary_color_light < 0) {
main_color = lv_palette_darken(color_def.primary_color, color_def.primary_color_light * -1); main_color = lv_palette_darken(color_def.primary_color, color_def.primary_color_light * -1);
} }
else { else {
main_color = lv_palette_main(color_defs[global_config.color_scheme].primary_color); main_color = lv_palette_main(color_defs[config->color_scheme].primary_color);
} }
lv_theme_t *theme = lv_theme_default_init(dispp, main_color, lv_palette_main(color_def.secondary_color), !global_config.lightMode, &CYD_SCREEN_FONT); lv_theme_t *theme = lv_theme_default_init(dispp, main_color, lv_palette_main(color_def.secondary_color), !config->light_mode, &CYD_SCREEN_FONT);
lv_disp_set_theme(dispp, theme); lv_disp_set_theme(dispp, theme);
} }
void lv_setup() void lv_setup()
{ {
set_screen_brightness();
lv_indev_t * display_driver = lv_indev_get_next(NULL); lv_indev_t * display_driver = lv_indev_get_next(NULL);
if (original_touch_driver == NULL) if (original_touch_driver == NULL)
@@ -243,6 +292,7 @@ void lv_setup()
screen_timer_setup(); screen_timer_setup();
screen_timer_start(); screen_timer_start();
lv_png_init();
} }
bool is_screen_asleep() bool is_screen_asleep()

View File

@@ -8,3 +8,4 @@ void screen_timer_stop();
void set_color_scheme(); void set_color_scheme();
void lv_setup(); void lv_setup();
bool is_screen_asleep(); bool is_screen_asleep();
void lv_handler();

View File

@@ -1,38 +1,39 @@
#include "lvgl.h" #include "lvgl.h"
#include "macros_query.h" #include "macros_query.h"
#include "./data_setup.h" #include "./data_setup.h"
#include <HTTPClient.h>
#include "../conf/global_config.h"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <UrlEncode.h> #include <UrlEncode.h>
#include "http_client.h"
static char* macros[64] = {0}; static char* macros[64] = {0};
static int macros_count = 0; static int macros_count = 0;
static char* power_devices[16] = {0}; static char* power_devices[16] = {0};
static bool power_device_states[16] = {0}; static bool power_device_states[16] = {0};
static int power_devices_count = 0; static unsigned int stored_power_devices_count = 0;
static void _macros_query_internal(){
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/gcode/help";
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;
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonObject>();
void macros_clear()
{
for (int i = 0; i < macros_count; i++){ for (int i = 0; i < macros_count; i++){
free(macros[i]); free(macros[i]);
} }
macros_count = 0; macros_count = 0;
}
MACROSQUERY macros_query(PRINTER_CONFIG * config)
{
HTTPClient client;
configure_http_client(client, get_full_url("/printer/gcode/help", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonObject>();
macros_clear();
for (JsonPair i : result){ for (JsonPair i : result){
const char *key = i.key().c_str(); const char *key = i.key().c_str();
@@ -43,29 +44,75 @@ static void _macros_query_internal(){
macros[macros_count++] = macro; macros[macros_count++] = macro;
} }
} }
if (global_config.sort_macros)
{
std::sort(macros, macros + macros_count, [](const char* a, const char* b) {
return strcmp(a, b) < 0;
});
}
return {(const char**)macros, (unsigned int)macros_count};
}
else {
return {NULL, 0};
} }
} }
void power_devices_clear(){ MACROSQUERY macros_query()
for (int i = 0; i < power_devices_count; i++){ {
return macros_query(get_current_printer_config());
}
unsigned int macro_count(PRINTER_CONFIG * config)
{
HTTPClient client;
configure_http_client(client, get_full_url("/printer/gcode/help", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonObject>();
unsigned int count = 0;
for (JsonPair i : result){
const char *value = i.value().as<String>().c_str();
if (strcmp(value, "CYD_SCREEN_MACRO") == 0) {
count++;
}
}
return count;
}
else {
return 0;
}
}
unsigned int macro_count()
{
return macro_count(get_current_printer_config());
}
void power_devices_clear()
{
for (int i = 0; i < stored_power_devices_count; i++){
free(power_devices[i]); free(power_devices[i]);
} }
power_devices_count = 0; stored_power_devices_count = 0;
} }
void _power_devices_query_internal(){ POWERQUERY power_devices_query(PRINTER_CONFIG * config)
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/devices"; {
HTTPClient client; HTTPClient client;
client.useHTTP10(true); configure_http_client(client, get_full_url("/machine/device_power/devices", config), true, 1000);
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(); int httpCode = client.GET();
if (httpCode == 200){ if (httpCode == 200){
JsonDocument doc; JsonDocument doc;
deserializeJson(doc, client.getStream()); deserializeJson(doc, client.getStream());
@@ -76,54 +123,63 @@ void _power_devices_query_internal(){
for (auto i : result){ for (auto i : result){
const char * device_name = i["device"]; const char * device_name = i["device"];
const char * device_state = i["status"]; const char * device_state = i["status"];
power_devices[power_devices_count] = (char*)malloc(strlen(device_name) + 1); power_devices[stored_power_devices_count] = (char*)malloc(strlen(device_name) + 1);
strcpy(power_devices[power_devices_count], device_name); strcpy(power_devices[stored_power_devices_count], device_name);
power_device_states[power_devices_count] = strcmp(device_state, "on") == 0; power_device_states[stored_power_devices_count] = strcmp(device_state, "on") == 0;
power_devices_count++; stored_power_devices_count++;
} }
return {(const char**)power_devices, (const bool*)power_device_states, (unsigned int)stored_power_devices_count};
}
else {
return {NULL, NULL, 0};
} }
} }
static void on_state_change(void * s, lv_msg_t * m) { POWERQUERY power_devices_query()
if (printer.state == PRINTER_STATE_ERROR || printer.state == PRINTER_STATE_PAUSED){ {
return; return power_devices_query(get_current_printer_config());
}
_macros_query_internal();
_power_devices_query_internal();
} }
bool set_power_state(const char* device_name, bool state) { unsigned int power_devices_count(PRINTER_CONFIG * config)
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off"); {
HTTPClient client; HTTPClient client;
client.useHTTP10(true); configure_http_client(client, get_full_url("/machine/device_power/devices", config), true, 1000);
client.begin(url.c_str());
if (global_config.auth_configured) int httpCode = client.GET();
client.addHeader("X-Api-Key", global_config.klipper_auth);
if (client.POST("") != 200) if (httpCode == 200){
return false; JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"]["devices"].as<JsonArray>();
for (int i = 0; i < power_devices_count; i++){ unsigned int count = 0;
if (strcmp(power_devices[i], device_name) == 0){
power_device_states[i] = state; for (auto i : result){
return true; count++;
}
} }
return true; return count;
}
else {
return 0;
}
} }
MACROSQUERY macros_query() { unsigned int power_devices_count()
return {(const char**)macros, (unsigned int)macros_count}; {
return power_devices_count(get_current_printer_config());
} }
POWERQUERY power_devices_query() { bool set_power_state(const char* device_name, bool state, PRINTER_CONFIG * config)
return {(const char**)power_devices, (const bool*)power_device_states, (unsigned int)power_devices_count}; {
HTTPClient client;
configure_http_client(client, get_full_url("/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off"), config), true, 1000);
return client.POST("") == 200;
} }
void macros_query_setup(){ bool set_power_state(const char* device_name, bool state)
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL); {
on_state_change(NULL, NULL); return set_power_state(device_name, state, get_current_printer_config());
} }

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include "../conf/global_config.h"
typedef struct { typedef struct {
const char** macros; const char** macros;
uint32_t count; uint32_t count;
@@ -11,9 +13,15 @@ typedef struct {
uint32_t count; uint32_t count;
} POWERQUERY; } POWERQUERY;
MACROSQUERY macros_query(PRINTER_CONFIG * config);
MACROSQUERY macros_query(); MACROSQUERY macros_query();
unsigned int macro_count(PRINTER_CONFIG * config);
unsigned int macro_count();
POWERQUERY power_devices_query(PRINTER_CONFIG * config);
POWERQUERY power_devices_query(); POWERQUERY power_devices_query();
void macros_query_setup(); unsigned int power_devices_count(PRINTER_CONFIG * config);
unsigned int power_devices_count();
bool set_power_state(const char* device_name, bool state, PRINTER_CONFIG * config);
bool set_power_state(const char* device_name, bool state); bool set_power_state(const char* device_name, bool state);
void _power_devices_query_internal(); void macros_clear();
void power_devices_clear(); void power_devices_clear();

View File

@@ -13,7 +13,7 @@
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
Serial.println("Hello World"); Serial.println("Hello World");
LoadGlobalConfig(); load_global_config();
screen_setup(); screen_setup();
lv_setup(); lv_setup();
Serial.println("Screen init done"); Serial.println("Screen init done");
@@ -29,10 +29,8 @@ void setup() {
void loop(){ void loop(){
wifi_ok(); wifi_ok();
ip_ok();
data_loop(); data_loop();
lv_timer_handler(); lv_handler();
lv_task_handler();
if (is_ready_for_ota_update()) if (is_ready_for_ota_update())
{ {

View File

@@ -0,0 +1,141 @@
#include "gcode_img.h"
#include "lvgl.h"
#include "ui_utils.h"
#include <Esp.h>
#include <UrlEncode.h>
#include <ArduinoJson.h>
#include "../conf/global_config.h"
#include "../core/http_client.h"
static unsigned char * data_png = NULL;
static char img_filename_path[256] = {0};
static lv_img_dsc_t img_header = {0};
bool has_32_32_gcode_img(const char* filename)
{
if (filename == NULL){
Serial.println("No gcode filename");
return false;
}
SETUP_HTTP_CLIENT("/server/files/thumbnails?filename=" + urlEncode(filename));
int httpCode = 0;
try {
httpCode = client.GET();
}
catch (...){
Serial.println("Exception while fetching gcode img location");
return false;
}
if (httpCode == 200)
{
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonArray>();
const char* chosen_thumb = NULL;
for (auto file : result){
int width = file["width"];
int height = file["height"];
int size = file["size"];
const char* thumbnail = file["thumbnail_path"];
if (width != height || width != 32)
continue;
if (strcmp(thumbnail + strlen(thumbnail) - 4, ".png"))
continue;
chosen_thumb = thumbnail;
break;
}
if (chosen_thumb != NULL){
Serial.printf("Found 32x32 PNG gcode img at %s\n", filename);
strcpy(img_filename_path, chosen_thumb);
return true;
}
}
else
{
Serial.printf("Failed to fetch gcode image data: %d\n", httpCode);
}
return false;
}
lv_obj_t* draw_gcode_img()
{
clear_img_mem();
if (img_filename_path[0] == 0){
Serial.println("No gcode img path");
return NULL;
}
SETUP_HTTP_CLIENT_FULL("/server/files/gcodes/" + urlEncode(img_filename_path), false, 2000);
int httpCode = 0;
try {
httpCode = client.GET();
}
catch (...){
Serial.println("Exception while fetching gcode img");
return NULL;
}
if (httpCode == 200)
{
size_t len = client.getSize();
if (len <= 0)
{
Serial.println("No gcode img data");
return NULL;
}
data_png = (unsigned char*)malloc(len + 1);
if (len != client.getStream().readBytes(data_png, len)){
Serial.println("Failed to read gcode img data");
clear_img_mem();
return NULL;
}
memset(&img_header, 0, sizeof(img_header));
img_header.header.w = 32;
img_header.header.h = 32;
img_header.data_size = len;
img_header.header.cf = LV_IMG_CF_RAW_ALPHA;
img_header.data = data_png;
lv_obj_t * img = lv_img_create(lv_scr_act());
lv_img_set_src(img, &img_header);
return img;
}
return NULL;
}
lv_obj_t* show_gcode_img(const char* filename)
{
if (filename == NULL){
Serial.println("No gcode filename");
return NULL;
}
if (!has_32_32_gcode_img(filename)){
Serial.println("No 32x32 gcode img found");
return NULL;
}
return draw_gcode_img();
}
void clear_img_mem()
{
if (data_png != NULL){
free(data_png);
data_png = NULL;
}
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "lvgl.h"
lv_obj_t* show_gcode_img(const char* filename);
bool has_32_32_gcode_img(const char* filename);
void clear_img_mem();

View File

@@ -6,12 +6,18 @@
#include "ui_utils.h" #include "ui_utils.h"
#include "../core/macros_query.h" #include "../core/macros_query.h"
#include "panels/panel.h" #include "panels/panel.h"
#include "../core/http_client.h"
#include "switch_printer.h"
#include "macros.h"
#include "../core/lv_setup.h"
bool connect_ok = false;
lv_obj_t * hostEntry; lv_obj_t * hostEntry;
lv_obj_t * portEntry; lv_obj_t * portEntry;
lv_obj_t * label = NULL; lv_obj_t * label = NULL;
void show_ip_entry();
void show_auth_entry();
/* Create a custom keyboard to allow hostnames or ip addresses (a-z, 0 - 9, and -) */ /* Create a custom keyboard to allow hostnames or ip addresses (a-z, 0 - 9, and -) */
static const char * kb_map[] = { static const char * kb_map[] = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
@@ -27,7 +33,19 @@ static const lv_btnmatrix_ctrl_t kb_ctrl[] = {
LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6 LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6
}; };
void ip_init_inner(); static const char * hex_numpad_map[] = {
"1", "2", "3", "f", LV_SYMBOL_BACKSPACE, "\n",
"4", "5", "6", "e", LV_SYMBOL_OK, "\n",
"7", "8", "9", "d", LV_SYMBOL_LEFT, "\n",
"0", "a", "b", "c", LV_SYMBOL_RIGHT, NULL
};
static const lv_btnmatrix_ctrl_t hex_numpad_ctrl[] = {
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
};
enum connection_status_t { enum connection_status_t {
CONNECT_FAIL = 0, CONNECT_FAIL = 0,
@@ -36,19 +54,11 @@ enum connection_status_t {
}; };
connection_status_t verify_ip(){ connection_status_t verify_ip(){
HTTPClient client; SETUP_HTTP_CLIENT_FULL("/printer/info", true, 1000);
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
int httpCode; int httpCode;
try { try {
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(); httpCode = client.GET();
Serial.printf("%d %s\n", httpCode, url.c_str());
if (httpCode == 401) if (httpCode == 401)
return CONNECT_AUTH_REQUIRED; return CONNECT_AUTH_REQUIRED;
@@ -61,11 +71,25 @@ connection_status_t verify_ip(){
} }
} }
static void ta_event_cb(lv_event_t * e) { static void keyboard_event_ip_entry(lv_event_t * e) {
lv_event_code_t code = lv_event_get_code(e); lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e); lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
if ((code == LV_EVENT_FOCUSED || code == LV_EVENT_DEFOCUSED) && ta != NULL)
{
// make sure we alter the keymap before taking actions that might
// destroy the keyboard
if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_1))
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);
}
else
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
}
}
if(code == LV_EVENT_FOCUSED) { if(code == LV_EVENT_FOCUSED) {
lv_keyboard_set_textarea(kb, ta); lv_keyboard_set_textarea(kb, ta);
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
@@ -76,21 +100,18 @@ static void ta_event_cb(lv_event_t * e) {
} }
else if (code == LV_EVENT_READY) else if (code == LV_EVENT_READY)
{ {
strcpy(global_config.klipperHost, lv_textarea_get_text(hostEntry)); strcpy(get_current_printer_config()->klipper_host, lv_textarea_get_text(hostEntry));
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry)); get_current_printer_config()->klipper_port = atoi(lv_textarea_get_text(portEntry));
connection_status_t status = verify_ip(); connection_status_t status = verify_ip();
if (status == CONNECT_OK) if (status == CONNECT_OK)
{ {
global_config.ipConfigured = true; get_current_printer_config()->ip_configured = true;
WriteGlobalConfig(); write_global_config();
connect_ok = true;
} }
else if (status == CONNECT_AUTH_REQUIRED) else if (status == CONNECT_AUTH_REQUIRED)
{ {
label = NULL; show_auth_entry();
global_config.ipConfigured = true;
WriteGlobalConfig();
} }
else else
{ {
@@ -101,77 +122,8 @@ static void ta_event_cb(lv_event_t * e) {
{ {
return; return;
} }
if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_1))
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);
}
else
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
}
} }
static void reset_btn_event_handler(lv_event_t * e){
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
global_config.ipConfigured = false;
ip_init_inner();
}
}
static void power_devices_button(lv_event_t * e) {
lv_obj_t * panel = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(panel, LV_OPA_COVER, 0);
lv_layout_flex_column(panel);
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX);
lv_obj_align(panel, LV_ALIGN_TOP_LEFT, 0, CYD_SCREEN_GAP_PX);
lv_obj_t * button = lv_btn_create(panel);
lv_obj_set_size(button, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(button, destroy_event_user_data, LV_EVENT_CLICKED, panel);
lv_obj_t * label = lv_label_create(button);
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
lv_obj_center(label);
macros_panel_add_power_devices_to_panel(panel, power_devices_query());
}
void redraw_connect_screen(){
lv_obj_clean(lv_scr_act());
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Connecting to Klipper");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * button_row = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(button_row, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(button_row, LV_FLEX_ALIGN_CENTER);
lv_obj_align(button_row, LV_ALIGN_CENTER, 0, CYD_SCREEN_GAP_PX + CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * reset_btn = lv_btn_create(button_row);
lv_obj_add_event_cb(reset_btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(reset_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * btn_label = lv_label_create(reset_btn);
lv_label_set_text(btn_label, "Reset");
lv_obj_center(btn_label);
if (power_devices_query().count >= 1){
lv_obj_t * power_devices_btn = lv_btn_create(button_row);
lv_obj_add_event_cb(power_devices_btn, power_devices_button, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(power_devices_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
btn_label = lv_label_create(power_devices_btn);
lv_label_set_text(btn_label, "Power Devices");
lv_obj_center(btn_label);
}
}
static bool auth_entry_done = false;
static void keyboard_event_auth_entry(lv_event_t * e) { static void keyboard_event_auth_entry(lv_event_t * e) {
lv_event_code_t code = lv_event_get_code(e); lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e); lv_obj_t * ta = lv_event_get_target(e);
@@ -183,21 +135,29 @@ static void keyboard_event_auth_entry(lv_event_t * e) {
int len = strlen(txt); int len = strlen(txt);
if (len > 0) if (len > 0)
{ {
global_config.auth_configured = true; get_current_printer_config()->auth_configured = true;
strcpy(global_config.klipper_auth, txt); strcpy(get_current_printer_config()->klipper_auth, txt);
WriteGlobalConfig();
auth_entry_done = true; if (verify_ip() == CONNECT_OK)
{
get_current_printer_config()->ip_configured = true;
write_global_config();
}
else
{
lv_label_set_text(label, "Failed to connect");
}
} }
} }
else if (code == LV_EVENT_CANCEL) else if (code == LV_EVENT_CANCEL)
{ {
auth_entry_done = true; show_ip_entry();
} }
} }
void handle_auth_entry(){ void show_auth_entry()
auth_entry_done = false; {
global_config.klipper_auth[32] = 0; get_current_printer_config()->klipper_auth[32] = 0;
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
lv_obj_t * root = lv_create_empty_panel(lv_scr_act()); lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
@@ -210,7 +170,7 @@ void handle_auth_entry(){
lv_obj_set_flex_grow(top_root, 1); lv_obj_set_flex_grow(top_root, 1);
lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0); lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0);
lv_obj_t * label = lv_label_create(top_root); label = lv_label_create(top_root);
lv_label_set_text(label, "Enter API Key"); lv_label_set_text(label, "Enter API Key");
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
@@ -219,8 +179,8 @@ void handle_auth_entry(){
lv_textarea_set_max_length(passEntry, 32); lv_textarea_set_max_length(passEntry, 32);
lv_textarea_set_one_line(passEntry, true); lv_textarea_set_one_line(passEntry, true);
if (global_config.auth_configured) if (get_current_printer_config()->auth_configured)
lv_textarea_set_text(passEntry, global_config.klipper_auth); lv_textarea_set_text(passEntry, get_current_printer_config()->klipper_auth);
else else
lv_textarea_set_text(passEntry, ""); lv_textarea_set_text(passEntry, "");
@@ -228,25 +188,13 @@ void handle_auth_entry(){
lv_obj_add_event_cb(passEntry, keyboard_event_auth_entry, LV_EVENT_ALL, keyboard); lv_obj_add_event_cb(passEntry, keyboard_event_auth_entry, LV_EVENT_ALL, keyboard);
lv_obj_set_flex_grow(passEntry, 1); lv_obj_set_flex_grow(passEntry, 1);
lv_keyboard_set_textarea(keyboard, passEntry); lv_keyboard_set_textarea(keyboard, passEntry);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl); lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_2, hex_numpad_map, hex_numpad_ctrl);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_2);
while (!auth_entry_done) {
lv_timer_handler();
lv_task_handler();
}
redraw_connect_screen();
} }
void ip_init_inner(){ void show_ip_entry()
if (global_config.ipConfigured) { {
redraw_connect_screen();
return;
}
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
lv_obj_t * root = lv_create_empty_panel(lv_scr_act()); lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
@@ -283,59 +231,27 @@ void ip_init_inner(){
lv_obj_t * keyboard = lv_keyboard_create(root); lv_obj_t * keyboard = lv_keyboard_create(root);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl); lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
lv_obj_add_event_cb(hostEntry, ta_event_cb, LV_EVENT_ALL, keyboard); lv_obj_add_event_cb(hostEntry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard);
lv_obj_add_event_cb(portEntry, ta_event_cb, LV_EVENT_ALL, keyboard); lv_obj_add_event_cb(portEntry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
lv_keyboard_set_textarea(keyboard, hostEntry); lv_keyboard_set_textarea(keyboard, hostEntry);
}
long last_data_update_ip = -10000; if (global_config.multi_printer_mode)
const long data_update_interval_ip = 10000; {
int retry_count = 0; lv_obj_t * btn = draw_switch_printer_button();
lv_obj_set_parent(btn, textbow_row);
lv_obj_align(btn, LV_ALIGN_DEFAULT, 0, 0);
}
}
void ip_init(){ void ip_init(){
connect_ok = false; if (!get_current_printer_config()->ip_configured)
retry_count = 0;
int prev_power_device_count = 0;
ip_init_inner();
while (!connect_ok)
{ {
lv_timer_handler(); show_ip_entry();
lv_task_handler();
if (!connect_ok && global_config.ipConfigured && (millis() - last_data_update_ip) > data_update_interval_ip){
connection_status_t status = verify_ip();
connect_ok = status == CONNECT_OK;
last_data_update_ip = millis();
retry_count++;
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());
} }
if (status != CONNECT_AUTH_REQUIRED) while (!get_current_printer_config()->ip_configured)
_power_devices_query_internal(); {
else lv_handler();
handle_auth_entry();
if (power_devices_query().count != prev_power_device_count) {
prev_power_device_count = power_devices_query().count;
redraw_connect_screen();
}
}
}
}
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;
lv_msg_send(DATA_PRINTER_STATE, &printer);
} }
} }

View File

@@ -1,2 +1,3 @@
#pragma once
void ip_init(); void ip_init();
void ip_ok();

View File

@@ -0,0 +1,77 @@
#include "macros.h"
#include "ui_utils.h"
#include <Esp.h>
#include "../core/data_setup.h"
PRINTER_CONFIG * curernt_config = NULL;
static void btn_press(lv_event_t * e){
lv_obj_t * btn = lv_event_get_target(e);
const char* macro = (const char*)lv_event_get_user_data(e);
Serial.printf("Macro: %s\n", macro);
send_gcode(false, macro);
}
void macros_add_macros_to_panel(lv_obj_t * root_panel, MACROSQUERY query)
{
for (int i = 0; i < query.count; i++){
const char* macro = query.macros[i];
lv_create_custom_menu_button(macro, root_panel, btn_press, "Run", (void*)macro);
}
}
static void power_device_toggle(lv_event_t * e)
{
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
const char* power_device_name = (const char*)lv_event_get_user_data(e);
Serial.printf("Power Device: %s, State: %d -> %d\n", power_device_name, !checked, checked);
if (curernt_config != NULL)
set_power_state(power_device_name, checked, curernt_config);
}
void macros_add_power_devices_to_panel(lv_obj_t * root_panel, POWERQUERY query)
{
for (int i = 0; i < query.count; i++){
const char* power_device_name = query.power_devices[i];
const bool power_device_state = query.power_states[i];
lv_create_custom_menu_switch(power_device_name, root_panel, power_device_toggle, power_device_state, (void*)power_device_name);
}
}
void macros_set_current_config(PRINTER_CONFIG * config)
{
curernt_config = config;
}
void macros_draw_power_fullscreen(PRINTER_CONFIG * config)
{
macros_set_current_config(config);
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(parent, LV_OPA_100, 0);
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(parent);
lv_obj_set_size(lv_create_empty_panel(parent), 0, 0);
auto width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * btn = lv_btn_create(parent);
lv_obj_set_size(btn, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, parent);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
lv_obj_center(label);
POWERQUERY power = power_devices_query(config);
macros_add_power_devices_to_panel(parent, power);
}
void macros_draw_power_fullscreen()
{
macros_draw_power_fullscreen(get_current_printer_config());
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "lvgl.h"
#include "../core/macros_query.h"
void macros_add_macros_to_panel(lv_obj_t * root_panel, MACROSQUERY query);
void macros_add_power_devices_to_panel(lv_obj_t * root_panel, POWERQUERY query);
void macros_set_current_config(PRINTER_CONFIG * config);
void macros_draw_power_fullscreen(PRINTER_CONFIG * config);
void macros_draw_power_fullscreen();

View File

@@ -8,92 +8,11 @@
#include "panels/panel.h" #include "panels/panel.h"
#include "../core/macros_query.h" #include "../core/macros_query.h"
#include "../core/lv_setup.h" #include "../core/lv_setup.h"
#include "switch_printer.h"
char extruder_temp_buff[20]; #include "macros.h"
char bed_temp_buff[20];
char position_buff[20];
static void btn_click_restart(lv_event_t * e){
send_gcode(false, "RESTART");
}
static void btn_click_firmware_restart(lv_event_t * e){
send_gcode(false, "FIRMWARE_RESTART");
}
void error_ui_macros_open(lv_event_t * e){
lv_obj_t * panel = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(panel, LV_OPA_COVER, 0);
lv_layout_flex_column(panel);
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX);
lv_obj_align(panel, LV_ALIGN_TOP_LEFT, 0, CYD_SCREEN_GAP_PX);
lv_obj_t * button = lv_btn_create(panel);
lv_obj_set_size(button, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(button, destroy_event_user_data, LV_EVENT_CLICKED, panel);
lv_obj_t * label = lv_label_create(button);
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
lv_obj_center(label);
macros_panel_add_power_devices_to_panel(panel, power_devices_query());
}
void error_ui(){
lv_obj_clean(lv_scr_act());
lv_obj_t * panel = lv_create_empty_panel(lv_scr_act());
lv_layout_flex_column(panel);
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_obj_set_flex_align(panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_t * label;
label = lv_label_create(panel);
lv_label_set_text(label, LV_SYMBOL_WARNING " Printer is not ready");
label = lv_label_create(panel);
lv_label_set_text(label, printer.state_message);
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_clear_flag(label, LV_OBJ_FLAG_SCROLLABLE);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_t * button_row = lv_create_empty_panel(panel);
lv_obj_set_size(button_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(button_row);
lv_obj_t * btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_click_restart, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_click_firmware_restart, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "FW Restart");
lv_obj_center(label);
if (power_devices_query().count >= 1){
btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, error_ui_macros_open, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "Devices");
lv_obj_center(label);
}
}
void check_if_screen_needs_to_be_disabled(){ void check_if_screen_needs_to_be_disabled(){
if (global_config.onDuringPrint && printer.state == PRINTER_STATE_PRINTING){ if (global_config.on_during_print && printer.state == PRINTER_STATE_PRINTING){
screen_timer_wake(); screen_timer_wake();
screen_timer_stop(); screen_timer_stop();
} }
@@ -105,11 +24,17 @@ void check_if_screen_needs_to_be_disabled(){
static void on_state_change(void * s, lv_msg_t * m){ static void on_state_change(void * s, lv_msg_t * m){
check_if_screen_needs_to_be_disabled(); check_if_screen_needs_to_be_disabled();
if (printer.state == PRINTER_STATE_ERROR){ if (printer.state == PRINTER_STATE_OFFLINE){
error_ui(); nav_buttons_setup(PANEL_CONNECTING);
}
else if (printer.state == PRINTER_STATE_ERROR){
nav_buttons_setup(PANEL_ERROR);
}
else if (printer.state == PRINTER_STATE_IDLE) {
nav_buttons_setup(PANEL_FILES);
} }
else { else {
nav_buttons_setup(0); nav_buttons_setup(PANEL_PROGRESS);
} }
} }

View File

@@ -4,6 +4,7 @@
#include "nav_buttons.h" #include "nav_buttons.h"
#include "ui_utils.h" #include "ui_utils.h"
#include <stdio.h> #include <stdio.h>
#include "../conf/global_config.h"
static lv_style_t nav_button_style; static lv_style_t nav_button_style;
@@ -57,29 +58,51 @@ static void update_printer_data_time(lv_event_t * e){
} }
static void btn_click_files(lv_event_t * e){ static void btn_click_files(lv_event_t * e){
nav_buttons_setup(0); nav_buttons_setup(PANEL_FILES);
}
static void btn_click_progress(lv_event_t * e){
nav_buttons_setup(PANEL_PROGRESS);
} }
static void btn_click_move(lv_event_t * e){ static void btn_click_move(lv_event_t * e){
nav_buttons_setup(1); nav_buttons_setup(PANEL_MOVE);
} }
static void btn_click_extrude(lv_event_t * e){ static void btn_click_extrude(lv_event_t * e){
nav_buttons_setup(2); nav_buttons_setup(PANEL_TEMP);
} }
static void btn_click_settings(lv_event_t * e){ static void btn_click_settings(lv_event_t * e){
nav_buttons_setup(3); nav_buttons_setup(PANEL_SETTINGS);
} }
static void btn_click_macros(lv_event_t * e){ static void btn_click_macros(lv_event_t * e){
nav_buttons_setup(4); nav_buttons_setup(PANEL_MACROS);
}
static void btn_click_printer(lv_event_t * e){
nav_buttons_setup(PANEL_PRINTER);
}
static void btn_click_err(lv_event_t * e){
nav_buttons_setup(PANEL_ERROR);
}
static void btn_click_conn(lv_event_t * e){
nav_buttons_setup(PANEL_CONNECTING);
} }
void create_button(const char* icon, const char* name, lv_event_cb_t button_click, lv_event_cb_t label_update, lv_obj_t * root){ void create_button(const char* icon, const char* name, lv_event_cb_t button_click, lv_event_cb_t label_update, lv_obj_t * root){
lv_obj_t* btn = lv_btn_create(root); lv_obj_t* btn = lv_btn_create(root);
lv_obj_set_flex_grow(btn, 1); lv_obj_set_flex_grow(btn, 1);
#ifdef CYD_SCREEN_VERTICAL
lv_obj_set_height(btn, CYD_SCREEN_SIDEBAR_SIZE_PX);
#else
lv_obj_set_width(btn, CYD_SCREEN_SIDEBAR_SIZE_PX); lv_obj_set_width(btn, CYD_SCREEN_SIDEBAR_SIZE_PX);
#endif
lv_obj_add_style(btn, &nav_button_style, 0); lv_obj_add_style(btn, &nav_button_style, 0);
if (button_click != NULL) if (button_click != NULL)
lv_obj_add_event_cb(btn, button_click, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(btn, button_click, LV_EVENT_CLICKED, NULL);
@@ -96,50 +119,93 @@ void create_button(const char* icon, const char* name, lv_event_cb_t button_clic
lv_obj_add_style(label, &nav_button_text_style, 0); lv_obj_add_style(label, &nav_button_text_style, 0);
} }
void nav_buttons_setup(unsigned char active_panel){ void nav_buttons_setup(PANEL_TYPE active_panel){
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE); lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t * root_panel = lv_create_empty_panel(lv_scr_act()); lv_obj_t * root_panel = lv_create_empty_panel(lv_scr_act());
#ifdef CYD_SCREEN_VERTICAL
lv_obj_set_size(root_panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_SIDEBAR_SIZE_PX);
lv_obj_align(root_panel, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_layout_flex_row(root_panel, LV_FLEX_ALIGN_START, 0, 0);
#else
lv_obj_set_size(root_panel, CYD_SCREEN_SIDEBAR_SIZE_PX, CYD_SCREEN_HEIGHT_PX); lv_obj_set_size(root_panel, CYD_SCREEN_SIDEBAR_SIZE_PX, CYD_SCREEN_HEIGHT_PX);
lv_obj_align(root_panel, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_align(root_panel, LV_ALIGN_TOP_LEFT, 0, 0);
lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_START, 0, 0); lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_START, 0, 0);
#endif
if (printer.state > PRINTER_STATE_ERROR){
// Files/Print // Files/Print
if (printer.state == PRINTER_STATE_IDLE)
{
create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel); create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel);
}
else
{
create_button(LV_SYMBOL_FILE, "Paused", btn_click_progress, update_printer_data_time, root_panel);
}
// Move // Move
create_button(printer.state == PRINTER_STATE_PRINTING ? LV_SYMBOL_EDIT : LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel); create_button(printer.state == PRINTER_STATE_PRINTING ? LV_SYMBOL_EDIT : LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel);
// Extrude/Temp // Extrude/Temp
create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel); create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel);
}
else if (printer.state == PRINTER_STATE_ERROR) {
// Error UI
create_button(LV_SYMBOL_WARNING, "Error", btn_click_err, NULL, root_panel);
}
else {
// Connecting
create_button(LV_SYMBOL_REFRESH, "Link", btn_click_conn, NULL, root_panel);
}
// Macros // Macros
create_button(LV_SYMBOL_GPS, "Macro", btn_click_macros, NULL, root_panel); create_button(LV_SYMBOL_GPS, "Macro", btn_click_macros, NULL, root_panel);
if (global_config.multi_printer_mode)
{
// Printers
create_button(LV_SYMBOL_HOME, "Printer", btn_click_printer, NULL, root_panel);
}
lv_obj_t * panel = lv_create_empty_panel(lv_scr_act()); lv_obj_t * panel = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, 0, 0);
switch (active_panel){ switch (active_panel){
case 0: case PANEL_FILES:
print_panel_init(panel); files_panel_init(panel);
break; break;
case 1: case PANEL_MOVE:
move_panel_init(panel); move_panel_init(panel);
break; break;
case 2: case PANEL_TEMP:
temp_panel_init(panel); temp_panel_init(panel);
break; break;
case 3: case PANEL_SETTINGS:
settings_panel_init(panel); settings_panel_init(panel);
break; break;
case 4: case PANEL_MACROS:
macros_panel_init(panel); macros_panel_init(panel);
break; break;
case 5: case PANEL_STATS:
stats_panel_init(panel); stats_panel_init(panel);
break; break;
case PANEL_PRINTER:
printer_panel_init(panel);
break;
case PANEL_ERROR:
error_panel_init(panel);
break;
case PANEL_CONNECTING:
connecting_panel_init(panel);
break;
case PANEL_PROGRESS:
progress_panel_init(panel);
break;
} }
lv_msg_send(DATA_PRINTER_DATA, &printer); lv_msg_send(DATA_PRINTER_DATA, &printer);

View File

@@ -1,2 +1,17 @@
void nav_buttons_setup(unsigned char active_panel); #pragma once
enum PANEL_TYPE {
PANEL_FILES = 0,
PANEL_MOVE = 1,
PANEL_TEMP = 2,
PANEL_SETTINGS = 3,
PANEL_MACROS = 4,
PANEL_STATS = 5,
PANEL_PRINTER = 6,
PANEL_ERROR = 7,
PANEL_CONNECTING = 8,
PANEL_PROGRESS = 9,
};
void nav_buttons_setup(PANEL_TYPE active_panel);
void nav_style_setup(); void nav_style_setup();

View File

@@ -5,6 +5,9 @@
#include "../core/data_setup.h" #include "../core/data_setup.h"
#include "../conf/global_config.h" #include "../conf/global_config.h"
#include "ota_setup.h" #include "ota_setup.h"
#include "../core/macros_query.h"
#include "../core/files_query.h"
#include "gcode_img.h"
//const char *ota_url = "https://gist.githubusercontent.com/suchmememanyskill/ece418fe199e155340de6c224a0badf2/raw/0d6762d68bc807cbecc71e40d55b76692397a7b3/update.json"; // Test url //const char *ota_url = "https://gist.githubusercontent.com/suchmememanyskill/ece418fe199e155340de6c224a0badf2/raw/0d6762d68bc807cbecc71e40d55b76692397a7b3/update.json"; // Test url
const char *ota_url = "https://suchmememanyskill.github.io/CYD-Klipper/OTA.json"; // Prod url const char *ota_url = "https://suchmememanyskill.github.io/CYD-Klipper/OTA.json"; // Prod url
@@ -74,6 +77,11 @@ void ota_do_update(bool variant_automatic)
lv_timer_handler(); lv_timer_handler();
lv_task_handler(); lv_task_handler();
macros_clear();
power_devices_clear();
clear_files();
clear_img_mem();
ota_pull.SetCallback(do_update_callback); ota_pull.SetCallback(do_update_callback);
ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::UPDATE_AND_BOOT); ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::UPDATE_AND_BOOT);
} }
@@ -85,7 +93,7 @@ void ota_init()
Serial.printf("OTA Update Result: %d\n", result); Serial.printf("OTA Update Result: %d\n", result);
update_available = result == ESP32OTAPull::UPDATE_AVAILABLE; update_available = result == ESP32OTAPull::UPDATE_AVAILABLE;
if (global_config.autoOtaUpdate && update_available) if (global_config.auto_ota_update && update_available)
{ {
ota_do_update(true); ota_do_update(true);
} }

View File

@@ -0,0 +1,9 @@
#include "panel.h"
#include "../../conf/global_config.h"
void connecting_panel_init(lv_obj_t* panel)
{
lv_obj_t* label = lv_label_create(panel);
lv_label_set_text_fmt(label, "Connecting to %s...", (get_current_printer_config()->printer_name[0] == 0) ? get_current_printer_config()->klipper_host : get_current_printer_config()->printer_name);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

View File

@@ -0,0 +1,53 @@
#include "panel.h"
#include "../../core/data_setup.h"
#include "../ui_utils.h"
static void btn_click_restart(lv_event_t * e){
send_gcode(false, "RESTART");
}
static void btn_click_firmware_restart(lv_event_t * e){
send_gcode(false, "FIRMWARE_RESTART");
}
void error_panel_init(lv_obj_t* panel)
{
lv_layout_flex_column(panel, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_obj_t * label;
label = lv_label_create(panel);
lv_label_set_text(label, LV_SYMBOL_WARNING " Printer is not ready");
lv_obj_t * panel_with_text = lv_create_empty_panel(panel);
lv_layout_flex_column(panel_with_text, LV_FLEX_ALIGN_START);
lv_obj_set_flex_grow(panel_with_text, 1);
lv_obj_set_width(panel_with_text, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
label = lv_label_create(panel_with_text);
lv_label_set_text(label, printer.state_message);
lv_obj_set_width(label, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_t * button_row = lv_create_empty_panel(panel);
lv_obj_set_size(button_row, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(button_row);
lv_obj_t * btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_click_restart, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_click_firmware_restart, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "FW Restart");
lv_obj_center(label);
}

View File

@@ -4,9 +4,11 @@
#include "../../core/files_query.h" #include "../../core/files_query.h"
#include "../../conf/global_config.h" #include "../../conf/global_config.h"
#include <HardwareSerial.h> #include <HardwareSerial.h>
#include <HTTPClient.h>
#include "../ui_utils.h" #include "../ui_utils.h"
#include "../../core/lv_setup.h" #include "../../core/lv_setup.h"
#include "../gcode_img.h"
#include "../../core/http_client.h"
#include <UrlEncode.h>
FILESYSTEM_FILE* selected_file = NULL; FILESYSTEM_FILE* selected_file = NULL;
@@ -14,38 +16,17 @@ static void btn_print_file(lv_event_t * e){
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e); lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
lv_obj_del(panel); lv_obj_del(panel);
char* buff = (char*)malloc(128 + (strlen(selected_file->name) * 3)); SETUP_HTTP_CLIENT("/printer/print/start?filename=" + urlEncode(selected_file->name));
sprintf(buff, "http://%s:%d/printer/print/start?filename=", global_config.klipperHost, global_config.klipperPort);
char* ptr = buff + strlen(buff);
int filename_length = strlen(selected_file->name);
for (int i = 0; i < filename_length; i++){
char c = selected_file->name[i];
if (c == ' '){
*ptr = '%';
ptr++;
*ptr = '2';
ptr++;
*ptr = '0';
} else {
*ptr = c;
}
ptr++;
}
*ptr = 0;
HTTPClient client;
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.POST(""); int httpCode = client.POST("");
Serial.printf("Print start: HTTP %d\n", httpCode); Serial.printf("Print start: HTTP %d\n", httpCode);
} }
static void btn_print_file_verify(lv_event_t * e){ static void btn_print_file_verify(lv_event_t * e){
if (printer.state != PRINTER_STATE_IDLE){
return;
}
const auto button_size_mult = 1.3f; const auto button_size_mult = 1.3f;
lv_obj_t * btn = lv_event_get_target(e); lv_obj_t * btn = lv_event_get_target(e);
@@ -56,11 +37,11 @@ static void btn_print_file_verify(lv_event_t * e){
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 4, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 3); lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 4, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 3);
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0); lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * label = lv_label_create(panel); lv_obj_t * label_print_file = lv_label_create(panel);
lv_label_set_text(label, "Print File"); lv_label_set_text(label_print_file, "Print File");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0); lv_obj_align(label_print_file, LV_ALIGN_TOP_LEFT, 0, 0);
label = lv_label_create(panel); lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, selected_file->name); lv_label_set_text(label, selected_file->name);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -20); lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 10); lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 10);
@@ -83,19 +64,30 @@ static void btn_print_file_verify(lv_event_t * e){
label = lv_label_create(btn); label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_OK); lv_label_set_text(label, LV_SYMBOL_OK);
lv_obj_center(label); lv_obj_center(label);
lv_obj_t* img = show_gcode_img(selected_file->name);
if (img != NULL){
lv_obj_set_parent(img, panel);
lv_obj_align(img, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t * text_center_panel = lv_create_empty_panel(panel);
lv_obj_set_size(text_center_panel, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2, 32);
lv_obj_align(text_center_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX + 32, 0);
lv_obj_set_parent(label_print_file, text_center_panel);
lv_obj_align(label_print_file, LV_ALIGN_LEFT_MID, 0, 0);
}
} }
void print_panel_init(lv_obj_t* panel){ void files_panel_init(lv_obj_t* panel){
if (printer.state == PRINTER_STATE_PRINTING || printer.state == PRINTER_STATE_PAUSED){ clear_img_mem();
progress_panel_init(panel);
return;
}
lv_obj_t * list = lv_list_create(panel); lv_obj_t * list = lv_list_create(panel);
lv_obj_set_style_radius(list, 0, 0); lv_obj_set_style_radius(list, 0, 0);
lv_obj_set_style_border_width(list, 0, 0); lv_obj_set_style_border_width(list, 0, 0);
lv_obj_set_style_bg_opa(list, LV_OPA_TRANSP, 0); lv_obj_set_style_bg_opa(list, LV_OPA_TRANSP, 0);
lv_obj_set_size(list, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); lv_obj_set_size(list, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_align(list, LV_ALIGN_CENTER, 0, 0); lv_obj_align(list, LV_ALIGN_CENTER, 0, 0);
FILESYSTEM_FILE* files = get_files(25); FILESYSTEM_FILE* files = get_files(25);

View File

@@ -1,90 +1,18 @@
#include "lvgl.h" #include "../macros.h"
#include "panel.h" #include "panel.h"
#include "../nav_buttons.h" #include "../nav_buttons.h"
#include "../../core/data_setup.h" #include "../../core/data_setup.h"
#include "../../core/macros_query.h"
#include "../../conf/global_config.h" #include "../../conf/global_config.h"
#include "../ui_utils.h" #include "../ui_utils.h"
#include <HardwareSerial.h> #include <HardwareSerial.h>
const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} };
static void btn_press(lv_event_t * e){
lv_obj_t * btn = lv_event_get_target(e);
const char* macro = (const char*)lv_event_get_user_data(e);
Serial.printf("Macro: %s\n", macro);
send_gcode(false, macro);
}
static void btn_goto_settings(lv_event_t * e){ static void btn_goto_settings(lv_event_t * e){
nav_buttons_setup(3); nav_buttons_setup(PANEL_SETTINGS);
}
void macros_panel_add_macros_to_panel(lv_obj_t * root_panel, MACROSQUERY query){
for (int i = 0; i < query.count; i++){
const char* macro = query.macros[i];
lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_layout_flex_row(panel, LV_FLEX_ALIGN_END);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, macro);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_flex_grow(label, 1);
lv_obj_t * btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, btn_press, LV_EVENT_CLICKED, (void*)macro);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(btn);
lv_label_set_text(label, "Run");
lv_obj_center(label);
lv_obj_t * line = lv_line_create(root_panel);
lv_line_set_points(line, line_points, 2);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
}
}
static void power_device_toggle(lv_event_t * e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
const char* power_device_name = (const char*)lv_event_get_user_data(e);
Serial.printf("Power Device: %s, State: %d -> %d\n", power_device_name, !checked, checked);
set_power_state(power_device_name, checked);
}
void macros_panel_add_power_devices_to_panel(lv_obj_t * root_panel, POWERQUERY query){
for (int i = 0; i < query.count; i++){
const char* power_device_name = query.power_devices[i];
const bool power_device_state = query.power_states[i];
lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_layout_flex_row(panel, LV_FLEX_ALIGN_END);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, power_device_name);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_flex_grow(label, 1);
lv_obj_t * toggle = lv_switch_create(panel);
lv_obj_add_event_cb(toggle, power_device_toggle, LV_EVENT_VALUE_CHANGED, (void*)power_device_name);
lv_obj_set_size(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
if (power_device_state)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
lv_obj_t * line = lv_line_create(root_panel);
lv_line_set_points(line, line_points, 2);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
}
} }
void macros_panel_init(lv_obj_t* panel) { void macros_panel_init(lv_obj_t* panel) {
macros_set_current_config(get_current_printer_config());
lv_obj_t * btn = lv_btn_create(panel); lv_obj_t * btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, btn_goto_settings, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(btn, btn_goto_settings, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
@@ -94,21 +22,27 @@ void macros_panel_init(lv_obj_t* panel) {
lv_label_set_text(label, LV_SYMBOL_SETTINGS " Screen Settings"); lv_label_set_text(label, LV_SYMBOL_SETTINGS " Screen Settings");
lv_obj_center(label); lv_obj_center(label);
MACROSQUERY query = macros_query(); MACROSQUERY macros = macros_query();
POWERQUERY power = power_devices_query(); POWERQUERY power = power_devices_query();
if (query.count == 0 && power.count == 0){
label = lv_label_create(panel);
lv_label_set_text(label, "No macros found.\nMacros with the description\n\"CYD_SCREEN_MACRO\"\nwill show up here.");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
return;
}
lv_obj_t * root_panel = lv_create_empty_panel(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_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_set_size(root_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_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_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); lv_layout_flex_column(root_panel);
macros_panel_add_power_devices_to_panel(root_panel, power); macros_add_power_devices_to_panel(root_panel, power);
macros_panel_add_macros_to_panel(root_panel, query);
if (macros.count == 0){
label = lv_label_create(root_panel);
lv_label_set_text(label, "No macros found.\nMacros with the description\n\"CYD_SCREEN_MACRO\"\nwill show up here.");
if (power.count == 0){
lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_CENTER);
}
return;
}
macros_add_macros_to_panel(root_panel, macros);
} }

View File

@@ -4,47 +4,157 @@
#include "../nav_buttons.h" #include "../nav_buttons.h"
#include "../ui_utils.h" #include "../ui_utils.h"
#include <stdio.h> #include <stdio.h>
#include <Esp.h>
static bool last_homing_state = false; static bool last_homing_state = false;
static bool move_edit_mode = false;
float x_offsets[6] = {0};
float y_offsets[6] = {0};
float z_offsets[6] = {0};
#define OFFSET_LABEL_SIZE 7
char x_offset_labels[6 * OFFSET_LABEL_SIZE] = {0};
char y_offset_labels[6 * OFFSET_LABEL_SIZE] = {0};
char z_offset_labels[6 * OFFSET_LABEL_SIZE] = {0};
static void calculate_offsets_from_current_printer()
{
unsigned short* items[] = {get_current_printer_config()->printer_move_x_steps, get_current_printer_config()->printer_move_y_steps, get_current_printer_config()->printer_move_z_steps};
float* offsets[] = {(float*)x_offsets, (float*)y_offsets, (float*)z_offsets};
char * labels[] = {(char*)x_offset_labels, (char*)y_offset_labels, (char*)z_offset_labels};
for (int i = 0; i < 3; i++)
{
offsets[i][0] = items[i][2] / 10.0f * -1;
offsets[i][1] = items[i][1] / 10.0f * -1;
offsets[i][2] = items[i][0] / 10.0f * -1;
offsets[i][3] = items[i][0] / 10.0f;
offsets[i][4] = items[i][1] / 10.0f;
offsets[i][5] = items[i][2] / 10.0f;
for (int j = 0; j < 6; j++) {
const char * formats[] = {"%.0f", "%.1f", "+%.0f", "+%.1f"};
const char ** format = formats;
if (offsets[i][j] != (int)offsets[i][j])
{
format += 1;
}
if (j >= 3)
{
format += 2;
}
sprintf(labels[i] + OFFSET_LABEL_SIZE * j, *format, offsets[i][j]);
}
}
}
static int selected_column = 0;
static int selected_row = 0;
static void keyboard_cb_edit_move_increment(lv_event_t * e)
{
lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
const char * text = lv_textarea_get_text(ta);
float increment = atof(text);
if (increment < 0)
{
increment *= -1;
}
if (increment == 0 || increment > 999)
{
return;
}
unsigned short* items[] = {get_current_printer_config()->printer_move_x_steps, get_current_printer_config()->printer_move_y_steps, get_current_printer_config()->printer_move_z_steps};
Serial.printf("Setting increment %d %d %f\n", selected_column, selected_row, increment);
items[selected_column][selected_row] = increment * 10;
write_global_config();
nav_buttons_setup(PANEL_MOVE);
}
static void edit_move_increment(int column, float* idx)
{
float* offsets[] = {(float*)x_offsets, (float*)y_offsets, (float*)z_offsets};
int row = idx - offsets[column];
if (row < 3)
{
selected_row = 2 - row;
}
else
{
selected_row = row - 3;
}
selected_column = column;
lv_create_keyboard_text_entry(keyboard_cb_edit_move_increment, "Set increment", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6);
}
static void x_line_button_press(lv_event_t * e) { static void x_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e); float* data_pointer = (float*)lv_event_get_user_data(e);
if (move_edit_mode)
{
edit_move_increment(0, data_pointer);
return;
}
float data = *data_pointer; float data = *data_pointer;
move_printer("X", data, true); move_printer("X", data, true);
} }
static void y_line_button_press(lv_event_t * e) { static void y_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e); float* data_pointer = (float*)lv_event_get_user_data(e);
if (move_edit_mode)
{
edit_move_increment(1, data_pointer);
return;
}
float data = *data_pointer; float data = *data_pointer;
move_printer("Y", data, true); move_printer("Y", data, true);
} }
static void z_line_button_press(lv_event_t * e) { static void z_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e); float* data_pointer = (float*)lv_event_get_user_data(e);
if (move_edit_mode)
{
edit_move_increment(2, data_pointer);
return;
}
float data = *data_pointer; float data = *data_pointer;
move_printer("Z", data, true); move_printer("Z", data, true);
} }
char x_pos_buff[12];
static void x_pos_update(lv_event_t * e){ static void x_pos_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char x_pos_buff[12];
sprintf(x_pos_buff, "X: %.1f", printer.position[0]); sprintf(x_pos_buff, "X: %.1f", printer.position[0]);
lv_label_set_text(label, x_pos_buff); lv_label_set_text(label, x_pos_buff);
} }
char y_pos_buff[12];
static void y_pos_update(lv_event_t * e){ static void y_pos_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char y_pos_buff[12];
sprintf(y_pos_buff, "Y: %.1f", printer.position[1]); sprintf(y_pos_buff, "Y: %.1f", printer.position[1]);
lv_label_set_text(label, y_pos_buff); lv_label_set_text(label, y_pos_buff);
} }
char z_pos_buff[12];
static void z_pos_update(lv_event_t * e){ static void z_pos_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char z_pos_buff[12];
sprintf(z_pos_buff, "Z: %.2f", printer.position[2]); sprintf(z_pos_buff, "Z: %.2f", printer.position[2]);
lv_label_set_text(label, z_pos_buff); lv_label_set_text(label, z_pos_buff);
} }
@@ -52,23 +162,6 @@ static void z_pos_update(lv_event_t * e){
lv_event_cb_t button_callbacks[] = {x_line_button_press, y_line_button_press, z_line_button_press}; lv_event_cb_t button_callbacks[] = {x_line_button_press, y_line_button_press, z_line_button_press};
lv_event_cb_t position_callbacks[] = {x_pos_update, y_pos_update, z_pos_update}; lv_event_cb_t position_callbacks[] = {x_pos_update, y_pos_update, z_pos_update};
const float xy_offsets[] = {-100, -10, -1, 1, 10, 100};
const float z_offsets[] = {-10, -1, -0.1, 0.1, 1, 10};
const float* offsets[] = {
xy_offsets,
xy_offsets,
z_offsets
};
const char* xy_offset_labels[] = {"-100", "-10", "-1", "+1", "+10", "+100"};
const char* z_offset_labels[] = {"-10", "-1", "-0.1", "+0.1", "+1", "+10"};
const char** offset_labels[] = {
xy_offset_labels,
xy_offset_labels,
z_offset_labels
};
static void home_button_click(lv_event_t * e) { static void home_button_click(lv_event_t * e) {
if (printer.state == PRINTER_STATE_PRINTING) if (printer.state == PRINTER_STATE_PRINTING)
return; return;
@@ -85,14 +178,59 @@ static void disable_steppers_click(lv_event_t * e) {
static void switch_to_stat_panel(lv_event_t * e) { static void switch_to_stat_panel(lv_event_t * e) {
lv_obj_t * panel = lv_event_get_target(e); lv_obj_t * panel = lv_event_get_target(e);
nav_buttons_setup(5); nav_buttons_setup(PANEL_STATS);
} }
static void move_edit_toggle(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
move_edit_mode = lv_obj_get_state(btn) & LV_STATE_CHECKED;
}
static void line_custom_set(const char * axis, const char *text)
{
float pos = atof(text);
if (pos < 0 || pos > 500)
return;
move_printer(axis, pos, false);
}
static void x_line_custom_callback(lv_event_t * e) {
const char * text = lv_textarea_get_text(lv_event_get_target(e));
line_custom_set("X", text);
}
static void y_line_custom_callback(lv_event_t * e) {
const char * text = lv_textarea_get_text(lv_event_get_target(e));
line_custom_set("Y", text);
}
static void z_line_custom_callback(lv_event_t * e) {
const char * text = lv_textarea_get_text(lv_event_get_target(e));
line_custom_set("Z", text);
}
static void x_line_custom(lv_event_t * e) {
lv_create_keyboard_text_entry(x_line_custom_callback, "Set X position", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6);
}
static void y_line_custom(lv_event_t * e) {
lv_create_keyboard_text_entry(y_line_custom_callback, "Set Y position", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6);
}
static void z_line_custom(lv_event_t * e) {
lv_create_keyboard_text_entry(z_line_custom_callback, "Set Z position", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6);
}
lv_event_cb_t custom_callbacks[] = {x_line_custom, y_line_custom, z_line_custom};
inline void root_panel_steppers_locked(lv_obj_t * root_panel){ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
const auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2; const auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * panel = lv_create_empty_panel(root_panel); lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0); lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(panel, LV_FLEX_ALIGN_SPACE_BETWEEN, 0, 0); lv_layout_flex_column(panel, LV_FLEX_ALIGN_SPACE_BETWEEN, 0, 0);
@@ -115,7 +253,7 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
lv_obj_set_flex_grow(btn, 1); lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn); label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Unlock"); lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE "Free");
lv_obj_center(label); lv_obj_center(label);
btn = lv_btn_create(home_button_row); btn = lv_btn_create(home_button_row);
@@ -124,11 +262,29 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
lv_obj_set_flex_grow(btn, 1); lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn); label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_EDIT " Params"); lv_label_set_text(label, LV_SYMBOL_SETTINGS "Param");
lv_obj_center(label); lv_obj_center(label);
btn = lv_btn_create(home_button_row);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, move_edit_toggle, LV_EVENT_CLICKED, NULL);
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
if (move_edit_mode)
{
lv_obj_add_state(btn, LV_STATE_CHECKED);
}
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_EDIT);
lv_obj_center(label);
float* offsets[] = {(float*)x_offsets, (float*)y_offsets, (float*)z_offsets};
char * labels[] = {(char*)x_offset_labels, (char*)y_offset_labels, (char*)z_offset_labels};
for (int row = 0; row < 3; row++) { for (int row = 0; row < 3; row++) {
label = lv_label_create(panel); label = lv_label_btn_create(panel, custom_callbacks[row]);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(label, "???"); lv_label_set_text(label, "???");
lv_obj_set_width(label, width); lv_obj_set_width(label, width);
lv_obj_add_event_cb(label, position_callbacks[row], LV_EVENT_MSG_RECEIVED, NULL); lv_obj_add_event_cb(label, position_callbacks[row], LV_EVENT_MSG_RECEIVED, NULL);
@@ -146,7 +302,7 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
lv_obj_set_flex_grow(btn, 1); lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn); label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[row][col]); lv_label_set_text(label, labels[row] + OFFSET_LABEL_SIZE * col);
lv_obj_center(label); lv_obj_center(label);
} }
} }
@@ -155,20 +311,31 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
inline void root_panel_steppers_unlocked(lv_obj_t * root_panel){ inline void root_panel_steppers_unlocked(lv_obj_t * root_panel){
lv_obj_t * panel = lv_create_empty_panel(root_panel); lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER); lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER);
lv_obj_t * label = lv_label_create(panel); lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Steppers unlocked"); lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Steppers unlocked");
lv_obj_t * btn = lv_btn_create(panel); lv_obj_t * btn_row = lv_create_empty_panel(panel);
lv_obj_set_size(btn_row, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(btn_row, LV_FLEX_ALIGN_CENTER);
lv_obj_t * btn = lv_btn_create(btn_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, home_button_click, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(btn, home_button_click, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn); label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_HOME "Home Axis"); lv_label_set_text(label, LV_SYMBOL_HOME "Home Axis");
lv_obj_center(label); lv_obj_center(label);
btn = lv_btn_create(btn_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);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_SETTINGS "Parameters");
lv_obj_center(label);
} }
static void root_panel_state_update(lv_event_t * e){ static void root_panel_state_update(lv_event_t * e){
@@ -192,6 +359,7 @@ void move_panel_init(lv_obj_t* panel){
return; return;
} }
calculate_offsets_from_current_printer();
last_homing_state = !printer.homed_axis; last_homing_state = !printer.homed_axis;
lv_obj_add_event_cb(panel, root_panel_state_update, LV_EVENT_MSG_RECEIVED, NULL); lv_obj_add_event_cb(panel, root_panel_state_update, LV_EVENT_MSG_RECEIVED, NULL);

View File

@@ -5,9 +5,11 @@
void settings_panel_init(lv_obj_t* panel); void settings_panel_init(lv_obj_t* panel);
void temp_panel_init(lv_obj_t* panel); void temp_panel_init(lv_obj_t* panel);
void print_panel_init(lv_obj_t* panel); void files_panel_init(lv_obj_t* panel);
void move_panel_init(lv_obj_t* panel); void move_panel_init(lv_obj_t* panel);
void progress_panel_init(lv_obj_t* panel); void progress_panel_init(lv_obj_t* panel);
void macros_panel_init(lv_obj_t* panel); void macros_panel_init(lv_obj_t* panel);
void stats_panel_init(lv_obj_t* panel); void stats_panel_init(lv_obj_t* panel);
void macros_panel_add_power_devices_to_panel(lv_obj_t * panel, POWERQUERY query); void printer_panel_init(lv_obj_t* panel);
void error_panel_init(lv_obj_t* panel);
void connecting_panel_init(lv_obj_t* panel);

View File

@@ -0,0 +1,316 @@
#include "panel.h"
#include "../../conf/global_config.h"
#include "../../core/data_setup.h"
#include "../ui_utils.h"
#include "../../core/lv_setup.h"
#include <stdio.h>
#include "../nav_buttons.h"
#include "../../core/macros_query.h"
#include "../switch_printer.h"
#include "../macros.h"
const char * printer_status[] = {
"Offline",
"Error",
"Idle",
"Printing",
"Paused"
};
const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} };
static void update_printer_name_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
lv_label_set_text(label, config->printer_name[0] == 0 ? config->klipper_host : config->printer_name);
}
static void update_printer_status_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (config == get_current_printer_config())
{
lv_label_set_text(label, "In Control");
return;
}
if (printer->state == PRINTER_STATE_OFFLINE)
{
lv_label_set_text(label, "Offline");
return;
}
lv_label_set_text(label, printer_status[printer->state]);
}
static void update_printer_label_visible_active_printer(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
if (config == get_current_printer_config())
{
lv_label_set_text(label, LV_SYMBOL_WIFI);
}
else
{
lv_label_set_text(label, "");
}
}
static void update_printer_percentage_bar(lv_event_t * e)
{
lv_obj_t * percentage = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (printer->state != PRINTER_STATE_OFFLINE && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED)){
lv_bar_set_value(percentage, printer->print_progress * 100, LV_ANIM_OFF);
}
else {
lv_bar_set_value(percentage, 0, LV_ANIM_OFF);
}
}
static void update_printer_percentage_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (printer->state != PRINTER_STATE_OFFLINE && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED))
{
char percentage_buffer[12];
sprintf(percentage_buffer, "%.2f%%", printer->print_progress * 100);
lv_label_set_text(label, percentage_buffer);
}
else
{
lv_label_set_text(label, "-%");
}
}
static void update_printer_control_button_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (printer->power_devices > 0 && (config == get_current_printer_config() || printer->state == PRINTER_STATE_OFFLINE))
{
lv_label_set_text(label, "Power");
}
else
{
lv_label_set_text(label, "Control");
}
}
static void btn_set_secondary_button_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
if (config == get_current_printer_config())
{
lv_label_set_text(label, LV_SYMBOL_SETTINGS);
}
else
{
lv_label_set_text(label, LV_SYMBOL_TRASH);
}
}
static void btn_enable_control(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if ((config == get_current_printer_config() || printer->state == PRINTER_STATE_OFFLINE) && printer->power_devices <= 0)
{
// Disable
lv_obj_add_state(btn, LV_STATE_DISABLED);
}
else
{
// Enable
lv_obj_clear_state(btn, LV_STATE_DISABLED);
}
}
PRINTER_CONFIG * keyboard_config = NULL;
static void keyboard_callback(lv_event_t * e){
lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
const char * text = lv_textarea_get_text(ta);
strcpy(keyboard_config->printer_name, text);
write_global_config();
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
}
static void btn_printer_secondary(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
if (config == get_current_printer_config())
{
nav_buttons_setup(PANEL_SETTINGS);
return;
}
config->ip_configured = false;
write_global_config();
nav_buttons_setup(PANEL_PRINTER);
}
static void btn_printer_rename(lv_event_t * e)
{
keyboard_config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
lv_create_keyboard_text_entry(keyboard_callback, "Rename Printer", LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 24, keyboard_config->printer_name, false);
}
static void btn_printer_activate(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (printer->power_devices > 0 && (config == get_current_printer_config() || printer->state == PRINTER_STATE_OFFLINE))
{
macros_draw_power_fullscreen(config);
return;
}
switch_printer(index);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
}
static void btn_printer_add(lv_event_t * e)
{
set_printer_config_index(get_printer_config_free_index());
}
void create_printer_ui(PRINTER_CONFIG * config, lv_obj_t * root)
{
int index = config - global_config.printer_config;
auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * data_row_name = lv_create_empty_panel(root);
lv_layout_flex_row(data_row_name, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_set_size(data_row_name, width, LV_SIZE_CONTENT);
lv_obj_t * label = lv_label_create(data_row_name);
lv_obj_add_event_cb(label, update_printer_name_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
label = lv_label_create(data_row_name);
lv_obj_add_event_cb(label, update_printer_label_visible_active_printer, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
label = lv_label_create(data_row_name);
lv_obj_add_event_cb(label, update_printer_status_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
lv_obj_t * progress_row = lv_create_empty_panel(root);
lv_layout_flex_row(progress_row);
lv_obj_set_size(progress_row, width, LV_SIZE_CONTENT);
lv_obj_t * progress_bar = lv_bar_create(progress_row);
lv_obj_set_flex_grow(progress_bar, 1);
lv_obj_add_event_cb(progress_bar, update_printer_percentage_bar, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, progress_bar, config);
label = lv_label_create(progress_row);
lv_obj_set_style_text_font(label, &CYD_SCREEN_FONT_SMALL, 0);
lv_obj_add_event_cb(label, update_printer_percentage_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
lv_obj_t * button_row = lv_create_empty_panel(root);
lv_layout_flex_row(button_row);
lv_obj_set_size(button_row, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * btn = lv_btn_create(button_row);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_printer_secondary, LV_EVENT_CLICKED, config);
label = lv_label_create(btn);
lv_obj_center(label);
lv_obj_add_event_cb(label, btn_set_secondary_button_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
btn = lv_btn_create(button_row);
lv_obj_set_flex_grow(btn, 2);
lv_obj_add_event_cb(btn, btn_printer_rename, LV_EVENT_CLICKED, config);
label = lv_label_create(btn);
lv_label_set_text(label, "Rename");
lv_obj_center(label);
btn = lv_btn_create(button_row);
lv_obj_set_flex_grow(btn, 2);
lv_obj_add_event_cb(btn, btn_printer_activate, LV_EVENT_CLICKED, config);
lv_obj_add_event_cb(btn, btn_enable_control, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, btn, config);
label = lv_label_create(btn);
lv_obj_center(label);
lv_obj_add_event_cb(label, update_printer_control_button_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
lv_obj_t * line = lv_line_create(root);
lv_line_set_points(line, line_points, 2);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
}
void printer_panel_init(lv_obj_t* panel)
{
lv_obj_t * inner_panel = lv_create_empty_panel(panel);
lv_obj_align(inner_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, 0);
lv_obj_set_size(inner_panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_layout_flex_column(inner_panel);
lv_obj_set_scrollbar_mode(inner_panel, LV_SCROLLBAR_MODE_OFF);
lv_obj_set_size(lv_create_empty_panel(inner_panel), 0, 0);
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG * config = &global_config.printer_config[i];
if (config->ip_configured) {
create_printer_ui(&global_config.printer_config[i], inner_panel);
}
}
// Add Printer Button
if (get_printer_config_free_index() != -1){
lv_obj_t * btn = lv_btn_create(inner_panel);
lv_obj_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_printer_add, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Add Printer");
lv_obj_center(label);
}
lv_obj_set_size(lv_create_empty_panel(inner_panel), 0, 0);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
}

View File

@@ -28,6 +28,28 @@ static void update_printer_data_remaining_time(lv_event_t * e){
lv_label_set_text(label, time_display(printer.remaining_time_s)); lv_label_set_text(label, time_display(printer.remaining_time_s));
} }
static void update_printer_data_stats(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char buff[256] = {0};
switch (get_current_printer_config()->show_stats_on_progress_panel)
{
case SHOW_STATS_ON_PROGRESS_PANEL_LAYER:
sprintf(buff, "Layer %d of %d", printer.current_layer, printer.total_layers);
break;
case SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL:
sprintf(buff, "Position: X%.2f Y%.2f\nFeedrate: %d mm/s\nFilament Used: %.2f m\nLayer %d of %d",
printer.position[0], printer.position[1], printer.feedrate_mm_per_s, printer.filament_used_mm / 1000, printer.current_layer, printer.total_layers);
break;
case SHOW_STATS_ON_PROGRESS_PANEL_ALL:
sprintf(buff, "Pressure Advance: %.3f (%.2fs)\nPosition: X%.2f Y%.2f Z%.2f\nFeedrate: %d mm/s\nFilament Used: %.2f m\nFan: %.0f%%\nSpeed: %.0f%%\nFlow: %.0f%%\nLayer %d of %d",
printer.pressure_advance, printer.smooth_time, printer.position[0], printer.position[1], printer.position[2], printer.feedrate_mm_per_s, printer.filament_used_mm / 1000, printer.fan_speed * 100, printer.speed_mult * 100, printer.extrude_mult * 100, printer.current_layer, printer.total_layers);
break;
}
lv_label_set_text(label, buff);
}
static void update_printer_data_percentage(lv_event_t * e){ static void update_printer_data_percentage(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char percentage_buffer[12]; char percentage_buffer[12];
@@ -52,10 +74,28 @@ void progress_panel_init(lv_obj_t* panel){
const auto button_size_mult = 1.3f; const auto button_size_mult = 1.3f;
lv_obj_t * center_panel = lv_create_empty_panel(panel); lv_obj_t * center_panel = lv_create_empty_panel(panel);
lv_obj_align(center_panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(center_panel, panel_width, LV_SIZE_CONTENT); lv_obj_set_size(center_panel, panel_width, LV_SIZE_CONTENT);
lv_layout_flex_column(center_panel); lv_layout_flex_column(center_panel);
if (get_current_printer_config()->show_stats_on_progress_panel == SHOW_STATS_ON_PROGRESS_PANEL_ALL)
{
lv_obj_align(center_panel, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_GAP_PX);
}
else
{
lv_obj_align(center_panel, LV_ALIGN_CENTER, 0, 0);
}
if (get_current_printer_config()->show_stats_on_progress_panel == SHOW_STATS_ON_PROGRESS_PANEL_LAYER)
{
lv_obj_t * label = lv_label_create(panel);
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_GAP_PX);
lv_obj_set_style_text_font(label, &CYD_SCREEN_FONT_SMALL, 0);
lv_obj_add_event_cb(label, update_printer_data_stats, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
}
// Filename // Filename
lv_obj_t * label = lv_label_create(center_panel); lv_obj_t * label = lv_label_create(center_panel);
lv_label_set_text(label, printer.print_filename); lv_label_set_text(label, printer.print_filename);
@@ -124,4 +164,13 @@ void progress_panel_init(lv_obj_t* panel){
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -2 * CYD_SCREEN_GAP_PX - CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, -1 * CYD_SCREEN_GAP_PX); lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -2 * CYD_SCREEN_GAP_PX - CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, -1 * CYD_SCREEN_GAP_PX);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult); lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult);
if (get_current_printer_config()->show_stats_on_progress_panel >= SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL)
{
label = lv_label_create(panel);
lv_obj_align(label, LV_ALIGN_BOTTOM_LEFT, CYD_SCREEN_GAP_PX, -1 * CYD_SCREEN_GAP_PX);
lv_obj_set_style_text_font(label, &CYD_SCREEN_FONT_SMALL, 0);
lv_obj_add_event_cb(label, update_printer_data_stats, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
}
} }

View File

@@ -7,6 +7,7 @@
#include <Esp.h> #include <Esp.h>
#include "../../core/lv_setup.h" #include "../../core/lv_setup.h"
#include "../ota_setup.h" #include "../ota_setup.h"
#include "../nav_buttons.h"
#ifndef REPO_VERSION #ifndef REPO_VERSION
#define REPO_VERSION "Unknown" #define REPO_VERSION "Unknown"
@@ -15,50 +16,72 @@
static void invert_color_switch(lv_event_t * e){ static void invert_color_switch(lv_event_t * e){
auto state = lv_obj_get_state(lv_event_get_target(e)); auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.invertColors = checked; get_current_printer_config()->invert_colors = checked;
WriteGlobalConfig(); write_global_config();
set_invert_display(); set_invert_display();
} }
static void reset_calibration_click(lv_event_t * e){ static void reset_calibration_click(lv_event_t * e){
global_config.screenCalibrated = false; global_config.screen_calibrated = false;
WriteGlobalConfig(); write_global_config();
ESP.restart();
}
static void reset_click(lv_event_t * e){
ESP.restart(); ESP.restart();
} }
static void reset_wifi_click(lv_event_t * e){ static void reset_wifi_click(lv_event_t * e){
global_config.wifiConfigured = false; global_config.wifi_configured = false;
global_config.ipConfigured = false; write_global_config();
global_config.auth_configured = false; ESP.restart();
WriteGlobalConfig(); }
static void reset_ip_click(lv_event_t * e){
get_current_printer_config()->ip_configured = false;
get_current_printer_config()->auth_configured = false;
write_global_config();
ESP.restart(); ESP.restart();
} }
static void light_mode_switch(lv_event_t * e){ static void light_mode_switch(lv_event_t * e){
auto state = lv_obj_get_state(lv_event_get_target(e)); auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.lightMode = checked; get_current_printer_config()->light_mode = checked;
WriteGlobalConfig(); write_global_config();
set_color_scheme(); set_color_scheme();
} }
static void filament_move_mode_switch(lv_event_t * e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
get_current_printer_config()->custom_filament_move_macros = checked;
write_global_config();
}
static void show_stats_on_progress_panel_dropdown(lv_event_t * e){
auto selected = lv_dropdown_get_selected(lv_event_get_target(e));
get_current_printer_config()->show_stats_on_progress_panel = selected;
write_global_config();
}
static void theme_dropdown(lv_event_t * e){ static void theme_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e); lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown); auto selected = lv_dropdown_get_selected(dropdown);
global_config.color_scheme = selected; get_current_printer_config()->color_scheme = selected;
set_color_scheme(); set_color_scheme();
WriteGlobalConfig(); write_global_config();
} }
const char* brightness_options = "100%\n75%\n50%\n25%"; const char* brightness_options = "100%\n75%\n50%\n25%";
const char brightness_options_values[] = { 255, 192, 128, 64 }; const unsigned char brightness_options_values[] = { 255, 192, 128, 64 };
static void brightness_dropdown(lv_event_t * e){ static void brightness_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e); lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown); auto selected = lv_dropdown_get_selected(dropdown);
global_config.brightness = brightness_options_values[selected]; global_config.brightness = brightness_options_values[selected];
set_screen_brightness(); set_screen_brightness();
WriteGlobalConfig(); write_global_config();
} }
const char* wake_timeout_options = "1m\n2m\n5m\n10m\n15m\n30m\n1h\n2h\n4h"; const char* wake_timeout_options = "1m\n2m\n5m\n10m\n15m\n30m\n1h\n2h\n4h";
@@ -67,26 +90,48 @@ const char wake_timeout_options_values[] = { 1, 2, 5, 10, 15, 30, 60, 120, 240
static void wake_timeout_dropdown(lv_event_t * e){ static void wake_timeout_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e); lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown); auto selected = lv_dropdown_get_selected(dropdown);
global_config.screenTimeout = wake_timeout_options_values[selected]; global_config.screen_timeout = wake_timeout_options_values[selected];
set_screen_timer_period(); set_screen_timer_period();
WriteGlobalConfig(); write_global_config();
}
static void dualusb_screen_fix_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.display_mode = checked;
write_global_config();
ESP.restart();
}
static void disable_m117_messaging_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.disable_m117_messaging = checked;
write_global_config();
}
static void sort_macros_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.sort_macros = checked;
write_global_config();
} }
static void rotate_screen_switch(lv_event_t* e){ static void rotate_screen_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e)); auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.rotateScreen = checked; global_config.rotate_screen = checked;
global_config.screenCalibrated = false; global_config.screen_calibrated = false;
WriteGlobalConfig(); write_global_config();
ESP.restart(); ESP.restart();
} }
static void on_during_print_switch(lv_event_t* e){ static void on_during_print_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e)); auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.onDuringPrint = checked; global_config.on_during_print = checked;
check_if_screen_needs_to_be_disabled(); check_if_screen_needs_to_be_disabled();
WriteGlobalConfig(); write_global_config();
} }
static void btn_ota_do_update(lv_event_t * e){ static void btn_ota_do_update(lv_event_t * e){
@@ -96,180 +141,140 @@ static void btn_ota_do_update(lv_event_t * e){
static void auto_ota_update_switch(lv_event_t* e){ static void auto_ota_update_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e)); auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.autoOtaUpdate = checked; global_config.auto_ota_update = checked;
WriteGlobalConfig(); write_global_config();
}
static void multi_printer_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.multi_printer_mode = checked;
write_global_config();
nav_buttons_setup(PANEL_SETTINGS);
} }
const char* estimated_time_options = "Percentage\nInterpolated\nSlicer"; const char* estimated_time_options = "Percentage\nInterpolated\nSlicer";
static void estimated_time_dropdown(lv_event_t * e){ static void estimated_time_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e); lv_obj_t * dropdown = lv_event_get_target(e);
global_config.remaining_time_calc_mode = lv_dropdown_get_selected(dropdown); get_current_printer_config()->remaining_time_calc_mode = lv_dropdown_get_selected(dropdown);
WriteGlobalConfig(); write_global_config();
} }
const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} }; #define PRINTER_SPECIFIC_SETTING global_config.multi_printer_mode ? "Stored per printer" : NULL
void create_settings_widget(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true){
lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
void settings_section_theming(lv_obj_t* panel)
{
lv_obj_t * label = lv_label_create(panel); lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, label_text); lv_label_set_text(label, "Theming");
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_set_parent(object, panel); lv_create_custom_menu_dropdown("Theme", panel, theme_dropdown, "Blue\nGreen\nLime\nGrey\nYellow\nOrange\nRed\nPurple", get_current_printer_config()->color_scheme, NULL, PRINTER_SPECIFIC_SETTING);
lv_obj_align(object, LV_ALIGN_RIGHT_MID, 0, 0);
if (set_height) #ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
lv_obj_set_height(object, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors, NULL, (global_config.multi_printer_mode) ? "Stored per printer"
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
"\nIntended for the 2.8\" dual USB model screen" : "Intended for the 2.8\" dual USB model screen"
#else
: NULL
#endif
);
#endif // CYD_SCREEN_DISABLE_INVERT_COLORS
lv_obj_t * line = lv_line_create(root_panel); lv_create_custom_menu_switch("Light Mode", panel, light_mode_switch, get_current_printer_config()->light_mode, NULL, PRINTER_SPECIFIC_SETTING);
lv_line_set_points(line, line_points, 2); }
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0); void settings_section_behaviour(lv_obj_t* panel)
{
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "\nBehaviour");
lv_create_custom_menu_dropdown("Estimated Time", panel, estimated_time_dropdown, estimated_time_options, get_current_printer_config()->remaining_time_calc_mode, NULL, PRINTER_SPECIFIC_SETTING);
lv_create_custom_menu_dropdown("Stats in Progress Screen", panel, show_stats_on_progress_panel_dropdown, "None\nLayers\nPartial\nAll", get_current_printer_config()->show_stats_on_progress_panel, NULL, PRINTER_SPECIFIC_SETTING);
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
int wake_timeout_settings_index = 0;
for (int i = 0; i < SIZEOF(wake_timeout_options_values); i++){
if (wake_timeout_options_values[i] == global_config.screen_timeout){
wake_timeout_settings_index = i;
break;
}
}
lv_create_custom_menu_dropdown("Wake Timeout", panel, wake_timeout_dropdown, wake_timeout_options, wake_timeout_settings_index);
#endif
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
lv_create_custom_menu_switch("Screen On During Print", panel, on_during_print_switch, global_config.on_during_print);
#endif
lv_create_custom_menu_switch("Multi Printer Mode", panel, multi_printer_switch, global_config.multi_printer_mode);
lv_create_custom_menu_switch("Disable M117 Messaging", panel, disable_m117_messaging_switch, global_config.disable_m117_messaging);
lv_create_custom_menu_button("Configure Printer IP", panel, reset_ip_click, "Restart");
lv_create_custom_menu_switch("Custom Filament Move Macros", panel, filament_move_mode_switch, get_current_printer_config()->custom_filament_move_macros, NULL,
global_config.multi_printer_mode
? "Calls FILAMENT_RETRACT and\nFILAMENT_EXTRUDE in temperature menu\nwhen enabled. Stored per printer."
: "Calls FILAMENT_RETRACT and\nFILAMENT_EXTRUDE in temperature menu\nwhen enabled");
lv_create_custom_menu_switch("Sort Macros A->Z", panel, sort_macros_switch, global_config.sort_macros);
}
void settings_section_device(lv_obj_t* panel)
{
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "\nDevice");
int brightness_settings_index = 0;
for (int i = 0; i < SIZEOF(brightness_options_values); i++){
if (brightness_options_values[i] == global_config.brightness){
brightness_settings_index = i;
break;
}
}
lv_create_custom_menu_dropdown("Brightness", panel, brightness_dropdown, brightness_options, brightness_settings_index);
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
lv_create_custom_menu_switch("Screen Color Fix", panel, dualusb_screen_fix_switch, global_config.display_mode, NULL, "ONLY for the 2.8\" dual USB model screen");
#endif
#if defined(CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY) && !defined(CYD_SCREEN_DISABLE_TOUCH_CALIBRATION)
// TODO: Rotating screen requires different calibration points.
#else
lv_create_custom_menu_switch("Rotate Screen", panel, rotate_screen_switch, global_config.rotate_screen);
#endif
lv_create_custom_menu_switch("Auto Update", panel, auto_ota_update_switch, global_config.auto_ota_update);
lv_create_custom_menu_label("Version", panel, REPO_VERSION " ");
if (ota_has_update()){
lv_obj_t *btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, btn_ota_do_update, LV_EVENT_CLICKED, NULL);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text_fmt(label, "Update to %s", ota_new_version_name().c_str());
lv_obj_center(label);
lv_create_custom_menu_entry("Device", btn, panel);
}
else {
lv_create_custom_menu_label("Device", panel, ARDUINO_BOARD " ");
}
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_create_custom_menu_button("Calibrate Touch", panel, reset_calibration_click, "Restart");
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_create_custom_menu_button("Configure WiFi", panel, reset_wifi_click, "Restart");
lv_create_custom_menu_button("Restart ESP", panel, reset_click, "Restart");
} }
void settings_panel_init(lv_obj_t* panel){ 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_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(panel); lv_layout_flex_column(panel);
lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF);
btn = lv_btn_create(panel); settings_section_theming(panel);
lv_obj_add_event_cb(btn, reset_wifi_click, LV_EVENT_CLICKED, NULL); settings_section_behaviour(panel);
settings_section_device(panel);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
create_settings_widget("Configure WiFi", btn, panel);
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, reset_calibration_click, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
create_settings_widget("Calibrate Touch", btn, panel);
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
#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);
if (global_config.invertColors)
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);
lv_obj_add_event_cb(toggle, light_mode_switch, LV_EVENT_VALUE_CHANGED, NULL);
if (global_config.lightMode)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Light Mode", toggle, 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);
create_settings_widget("Theme", dropdown, panel);
dropdown = lv_dropdown_create(panel);
lv_dropdown_set_options(dropdown, brightness_options);
lv_obj_add_event_cb(dropdown, brightness_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
for (int i = 0; i < SIZEOF(brightness_options_values); i++){
if (brightness_options_values[i] == global_config.brightness){
lv_dropdown_set_selected(dropdown, i);
break;
}
}
create_settings_widget("Brightness", dropdown, panel);
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
dropdown = lv_dropdown_create(panel);
lv_dropdown_set_options(dropdown, wake_timeout_options);
lv_obj_add_event_cb(dropdown, wake_timeout_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
for (int i = 0; i < SIZEOF(wake_timeout_options_values); i++){
if (wake_timeout_options_values[i] == global_config.screenTimeout){
lv_dropdown_set_selected(dropdown, i);
break;
}
}
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);
if (global_config.rotateScreen)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Rotate Screen", toggle, panel);
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
toggle = lv_switch_create(panel);
lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2);
lv_obj_add_event_cb(toggle, on_during_print_switch, LV_EVENT_VALUE_CHANGED, NULL);
if (global_config.onDuringPrint)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
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 " ");
create_settings_widget("Version", label, panel, false);
if (ota_has_update()){
btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, btn_ota_do_update, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text_fmt(label, "Update to %s", ota_new_version_name().c_str());
lv_obj_center(label);
create_settings_widget("Device", btn, panel);
}
else {
label = lv_label_create(panel);
lv_label_set_text(label, ARDUINO_BOARD " ");
create_settings_widget("Device", label, panel, false);
}
} }

View File

@@ -1,9 +1,14 @@
#include "panel.h" #include "panel.h"
#include "../ui_utils.h" #include "../ui_utils.h"
#include "../../core/data_setup.h" #include "../../core/data_setup.h"
#include "../nav_buttons.h"
#include <stdio.h> #include <stdio.h>
#include <Esp.h> #include <Esp.h>
static void swap_to_files_menu(lv_event_t * e) {
nav_buttons_setup(PANEL_FILES);
}
static void set_fan_speed_text(lv_event_t * e) { static void set_fan_speed_text(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char data[64]; char data[64];
@@ -225,13 +230,14 @@ void create_stat_text_block(lv_obj_t * root, const char* label, lv_event_cb_t va
} }
void stats_panel_init(lv_obj_t* panel) { void stats_panel_init(lv_obj_t* panel) {
auto panel_width = CYD_SCREEN_PANEL_WIDTH_PX / 2 - CYD_SCREEN_GAP_PX * 3; auto panel_width = CYD_SCREEN_PANEL_WIDTH_PX / 2 - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * left_panel = lv_create_empty_panel(panel); lv_obj_t * left_panel = lv_create_empty_panel(panel);
lv_obj_set_size(left_panel, panel_width, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); lv_obj_set_size(left_panel, panel_width, CYD_SCREEN_PANEL_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
lv_layout_flex_column(left_panel); lv_layout_flex_column(left_panel);
lv_obj_set_flex_align(left_panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_flex_align(left_panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_align(left_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX); lv_obj_align(left_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_clear_flag(left_panel, LV_OBJ_FLAG_SCROLLABLE);
create_stat_text_block(left_panel, "Position:", label_pos); create_stat_text_block(left_panel, "Position:", label_pos);
@@ -244,10 +250,20 @@ void stats_panel_init(lv_obj_t* panel) {
create_stat_text_block(left_panel, "Feedrate:", label_feedrate); create_stat_text_block(left_panel, "Feedrate:", label_feedrate);
lv_obj_t * right_panel = lv_create_empty_panel(panel); lv_obj_t * right_panel = lv_create_empty_panel(panel);
lv_obj_set_size(right_panel, panel_width, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); lv_obj_set_size(right_panel, panel_width, CYD_SCREEN_PANEL_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
lv_layout_flex_column(right_panel, LV_FLEX_ALIGN_CENTER); lv_layout_flex_column(right_panel, LV_FLEX_ALIGN_CENTER);
lv_obj_align(right_panel, LV_ALIGN_TOP_RIGHT, -1 * CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX); lv_obj_align(right_panel, LV_ALIGN_TOP_RIGHT, -1 * CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
if (printer.state >= PRINTER_STATE_PRINTING){
lv_obj_t * btn = lv_btn_create(right_panel);
lv_obj_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX / 2 - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, swap_to_files_menu, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Files");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
create_state_button(right_panel, set_fan_speed_text, open_fan_speed_panel); create_state_button(right_panel, set_fan_speed_text, open_fan_speed_panel);
create_state_button(right_panel, set_zoffset_text, open_zoffset_panel); create_state_button(right_panel, set_zoffset_text, open_zoffset_panel);
create_state_button(right_panel, set_speed_mult_text, open_speed_mult_panel); create_state_button(right_panel, set_speed_mult_text, open_speed_mult_panel);

View File

@@ -18,7 +18,7 @@ enum temp_target{
static temp_target keyboard_target; static temp_target keyboard_target;
static char hotend_buff[40]; static char hotend_buff[40];
static char bed_buff[40]; static char bed_buff[40];
static bool edit_mode = false; static bool temp_edit_mode = false;
lv_obj_t* root_panel; lv_obj_t* root_panel;
static void update_printer_data_hotend_temp(lv_event_t * e){ static void update_printer_data_hotend_temp(lv_event_t * e){
@@ -36,17 +36,17 @@ static void update_printer_data_bed_temp(lv_event_t * e){
static short get_temp_preset(int target){ static short get_temp_preset(int target){
switch (target){ switch (target){
case TARGET_HOTEND_CONFIG_1: case TARGET_HOTEND_CONFIG_1:
return global_config.hotend_presets[0]; return get_current_printer_config()->hotend_presets[0];
case TARGET_HOTEND_CONFIG_2: case TARGET_HOTEND_CONFIG_2:
return global_config.hotend_presets[1]; return get_current_printer_config()->hotend_presets[1];
case TARGET_HOTEND_CONFIG_3: case TARGET_HOTEND_CONFIG_3:
return global_config.hotend_presets[2]; return get_current_printer_config()->hotend_presets[2];
case TARGET_BED_CONFIG_1: case TARGET_BED_CONFIG_1:
return global_config.bed_presets[0]; return get_current_printer_config()->bed_presets[0];
case TARGET_BED_CONFIG_2: case TARGET_BED_CONFIG_2:
return global_config.bed_presets[1]; return get_current_printer_config()->bed_presets[1];
case TARGET_BED_CONFIG_3: case TARGET_BED_CONFIG_3:
return global_config.bed_presets[2]; return get_current_printer_config()->bed_presets[2];
default: default:
return -1; return -1;
} }
@@ -62,16 +62,14 @@ static void update_temp_preset_label(lv_event_t * e){
} }
void UpdateConfig(){ void UpdateConfig(){
WriteGlobalConfig(); write_global_config();
lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer); lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer);
} }
static void keyboard_callback(lv_event_t * e){ static void keyboard_callback(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 * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
if (code == LV_EVENT_READY) {
const char * text = lv_textarea_get_text(ta); const char * text = lv_textarea_get_text(ta);
int temp = atoi(text); int temp = atoi(text);
@@ -91,68 +89,40 @@ static void keyboard_callback(lv_event_t * e){
send_gcode(true, gcode); send_gcode(true, gcode);
break; break;
case TARGET_HOTEND_CONFIG_1: case TARGET_HOTEND_CONFIG_1:
global_config.hotend_presets[0] = temp; get_current_printer_config()->hotend_presets[0] = temp;
UpdateConfig(); UpdateConfig();
break; break;
case TARGET_HOTEND_CONFIG_2: case TARGET_HOTEND_CONFIG_2:
global_config.hotend_presets[1] = temp; get_current_printer_config()->hotend_presets[1] = temp;
UpdateConfig(); UpdateConfig();
break; break;
case TARGET_HOTEND_CONFIG_3: case TARGET_HOTEND_CONFIG_3:
global_config.hotend_presets[2] = temp; get_current_printer_config()->hotend_presets[2] = temp;
UpdateConfig(); UpdateConfig();
break; break;
case TARGET_BED_CONFIG_1: case TARGET_BED_CONFIG_1:
global_config.bed_presets[0] = temp; get_current_printer_config()->bed_presets[0] = temp;
UpdateConfig(); UpdateConfig();
break; break;
case TARGET_BED_CONFIG_2: case TARGET_BED_CONFIG_2:
global_config.bed_presets[1] = temp; get_current_printer_config()->bed_presets[1] = temp;
UpdateConfig(); UpdateConfig();
break; break;
case TARGET_BED_CONFIG_3: case TARGET_BED_CONFIG_3:
global_config.bed_presets[2] = temp; get_current_printer_config()->bed_presets[2] = temp;
UpdateConfig(); UpdateConfig();
break; break;
} }
}
if(code == LV_EVENT_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY) {
lv_keyboard_set_textarea(kb, NULL);
lv_obj_del(lv_obj_get_parent(kb));
}
}
static void show_keyboard(lv_event_t * e){
lv_obj_t * parent = lv_create_empty_panel(root_panel);
lv_obj_set_style_bg_opa(parent, LV_OPA_50, 0);
lv_obj_set_size(parent, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(parent, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_t * empty_panel = lv_create_empty_panel(parent);
lv_obj_set_flex_grow(empty_panel, 1);
lv_obj_t * ta = lv_textarea_create(parent);
lv_obj_t * keyboard = lv_keyboard_create(parent);
lv_obj_set_width(ta, CYD_SCREEN_PANEL_WIDTH_PX / 2);
lv_textarea_set_max_length(ta, 3);
lv_textarea_set_one_line(ta, true);
lv_textarea_set_text(ta, "");
lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_ALL, keyboard);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER);
lv_keyboard_set_textarea(keyboard, ta);
} }
static void show_keyboard_with_hotend(lv_event_t * e){ static void show_keyboard_with_hotend(lv_event_t * e){
keyboard_target = TARGET_HOTEND; keyboard_target = TARGET_HOTEND;
show_keyboard(e); lv_create_keyboard_text_entry(keyboard_callback, "Set Hotend Temp");
} }
static void show_keyboard_with_bed(lv_event_t * e){ static void show_keyboard_with_bed(lv_event_t * e){
keyboard_target = TARGET_BED; keyboard_target = TARGET_BED;
show_keyboard(e); lv_create_keyboard_text_entry(keyboard_callback, "Set Bed Temp");
} }
static void cooldown_temp(lv_event_t * e){ static void cooldown_temp(lv_event_t * e){
@@ -169,17 +139,24 @@ static void btn_extrude(lv_event_t * e){
return; return;
} }
if (get_current_printer_config()->custom_filament_move_macros)
{
send_gcode(true, "FILAMENT_EXTRUDE");
}
else
{
send_gcode(true, "M83"); send_gcode(true, "M83");
send_gcode(true, "G1 E25 F300"); send_gcode(true, "G1 E25 F300");
}
} }
static void set_temp_via_preset(lv_event_t * e){ static void set_temp_via_preset(lv_event_t * e){
int target = static_cast<int>(reinterpret_cast<intptr_t>(lv_event_get_user_data(e))); int target = static_cast<int>(reinterpret_cast<intptr_t>(lv_event_get_user_data(e)));
int value = get_temp_preset(target); int value = get_temp_preset(target);
if (edit_mode) { if (temp_edit_mode) {
keyboard_target = (temp_target)target; keyboard_target = (temp_target)target;
show_keyboard(e); lv_create_keyboard_text_entry(keyboard_callback, "Set Preset Temp");
return; return;
} }
@@ -195,7 +172,7 @@ static void set_temp_via_preset(lv_event_t * e){
static void btn_toggleable_edit(lv_event_t * e){ static void btn_toggleable_edit(lv_event_t * e){
lv_obj_t * btn = lv_event_get_target(e); lv_obj_t * btn = lv_event_get_target(e);
auto state = lv_obj_get_state(btn); auto state = lv_obj_get_state(btn);
edit_mode = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); temp_edit_mode = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
} }
static void btn_retract(lv_event_t * e){ static void btn_retract(lv_event_t * e){
@@ -203,8 +180,15 @@ static void btn_retract(lv_event_t * e){
return; return;
} }
if (get_current_printer_config()->custom_filament_move_macros)
{
send_gcode(true, "FILAMENT_RETRACT");
}
else
{
send_gcode(true, "M83"); send_gcode(true, "M83");
send_gcode(true, "G1 E-25 F300"); send_gcode(true, "G1 E-25 F300");
}
} }
static void set_chart_range(lv_event_t * e) { static void set_chart_range(lv_event_t * e) {
@@ -255,20 +239,10 @@ static void set_bed_target_temp_chart(lv_event_t * e){
lv_chart_set_next_value(chart, series, printer.bed_target_temp); lv_chart_set_next_value(chart, series, printer.bed_target_temp);
} }
void temp_panel_init(lv_obj_t * panel){ void create_charts(lv_obj_t * root)
{
const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2; const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
root_panel = panel; lv_obj_t * chart = lv_chart_create(root);
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, 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_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_type(chart, LV_CHART_TYPE_LINE);
lv_chart_set_point_count(chart, 120); lv_chart_set_point_count(chart, 120);
@@ -291,16 +265,16 @@ void temp_panel_init(lv_obj_t * panel){
lv_obj_add_event_cb(chart, set_bed_temp_chart, LV_EVENT_MSG_RECEIVED, ser4); 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_obj_add_event_cb(chart, set_chart_range, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subscribe_obj(DATA_PRINTER_DATA, chart, NULL); lv_msg_subscribe_obj(DATA_PRINTER_DATA, chart, NULL);
}
lv_obj_t * single_screen_panel = lv_create_empty_panel(root_temp_panel); void create_temp_buttons(lv_obj_t * root, lv_obj_t * 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); const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * temp_rows[2] = {0}; lv_obj_t * temp_rows[2] = {0};
lv_obj_t * button_temp_rows[2] = {0}; lv_obj_t * button_temp_rows[2] = {0};
for (int tempIter = 0; tempIter < 2; tempIter++){ for (int tempIter = 0; tempIter < 2; tempIter++){
temp_rows[tempIter] = lv_create_empty_panel(single_screen_panel); temp_rows[tempIter] = lv_create_empty_panel(root);
lv_layout_flex_column(temp_rows[tempIter]); lv_layout_flex_column(temp_rows[tempIter]);
lv_obj_set_size(temp_rows[tempIter], element_width, LV_SIZE_CONTENT); lv_obj_set_size(temp_rows[tempIter], element_width, LV_SIZE_CONTENT);
@@ -336,9 +310,40 @@ void temp_panel_init(lv_obj_t * panel){
lv_label_set_text(label, "Set"); lv_label_set_text(label, "Set");
lv_obj_center(label); lv_obj_center(label);
} }
}
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;
temp_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, CYD_SCREEN_PANEL_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);
#ifndef CYD_SCREEN_NO_TEMP_SCROLL
create_charts(root_temp_panel);
lv_obj_t * single_screen_panel = lv_create_empty_panel(root_temp_panel);
lv_obj_set_size(single_screen_panel, element_width, CYD_SCREEN_PANEL_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2 - CYD_SCREEN_GAP_PX / 2);
lv_layout_flex_column(single_screen_panel);
#else
lv_obj_clear_flag(root_temp_panel, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t * single_screen_panel = root_temp_panel;
#endif
create_temp_buttons(single_screen_panel, panel);
#ifdef CYD_SCREEN_NO_TEMP_SCROLL
create_charts(single_screen_panel);
#else
lv_obj_t * gap = lv_create_empty_panel(single_screen_panel); lv_obj_t * gap = lv_create_empty_panel(single_screen_panel);
lv_obj_set_flex_grow(gap, 1); lv_obj_set_flex_grow(gap, 1);
#endif
lv_obj_t * one_above_bottom_panel = lv_create_empty_panel(single_screen_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_set_size(one_above_bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);

View File

@@ -0,0 +1,89 @@
#include "switch_printer.h"
#include "../conf/global_config.h"
#include "ui_utils.h"
#include "../core/http_client.h"
#include "../core/lv_setup.h"
#include "../core/macros_query.h"
#include "../core/screen_driver.h"
#include "../core/data_setup.h"
void switch_printer(int index)
{
set_printer_config_index(index);
set_color_scheme();
set_invert_display();
printer.slicer_estimated_print_time_s = 0;
}
static void btn_switch_printer(lv_event_t *e){
lv_obj_t *btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
switch_printer(index);
lv_obj_del(lv_obj_get_parent(lv_obj_get_parent(btn)));
}
void switch_printer_init() {
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(parent, LV_OPA_100, 0);
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(parent);
lv_obj_set_size(lv_create_empty_panel(parent), 0, 0);
auto width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * btn = lv_btn_create(parent);
lv_obj_set_size(btn, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, parent);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
lv_obj_center(label);
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG * config = &global_config.printer_config[i];
const char* printer_name = (config->printer_name[0] == 0) ? config->klipper_host : config->printer_name;
if (config == get_current_printer_config() && config->ip_configured)
{
lv_create_custom_menu_label(printer_name, parent, "Active");
continue;
}
if (config->ip_configured) {
HTTPClient client;
configure_http_client(client, get_full_url("/printer/objects/query?webhooks&print_stats&virtual_sdcard", config), true, 1000);
int httpCode = client.GET();
lv_create_custom_menu_button(printer_name, parent, btn_switch_printer, (httpCode == 200) ? "Switch" : "Offline", config);
}
}
}
static void show_switch_printer_screen(lv_event_t * e){
switch_printer_init();
}
lv_obj_t * draw_switch_printer_button()
{
if (!global_config.multi_printer_mode)
{
return NULL;
}
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_add_event_cb(btn, show_switch_printer_screen, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_HOME);
lv_obj_center(label);
return btn;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "lvgl.h"
void switch_printer(int index);
void switch_printer_init();
lv_obj_t * draw_switch_printer_button();

View File

@@ -2,12 +2,14 @@
#include "ui_utils.h" #include "ui_utils.h"
#include "../core/data_setup.h" #include "../core/data_setup.h"
#include "../core/lv_setup.h" #include "../core/lv_setup.h"
#include <ErriezCRC32.h>
lv_obj_t* lv_create_empty_panel(lv_obj_t* root) { lv_obj_t* lv_create_empty_panel(lv_obj_t* root) {
lv_obj_t* panel = lv_obj_create(root); lv_obj_t* panel = lv_obj_create(root);
lv_obj_set_style_border_width(panel, 0, 0); lv_obj_set_style_border_width(panel, 0, 0);
lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, 0); lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, 0);
lv_obj_set_style_pad_all(panel, 0, 0); lv_obj_set_style_pad_all(panel, 0, 0);
lv_obj_set_style_radius(panel, 0, 0);
return panel; return panel;
} }
@@ -86,3 +88,195 @@ void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t tit
} }
} }
} }
void lv_keyboard_text_entry_close(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_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY)
{
lv_keyboard_set_textarea(kb, NULL);
lv_obj_del(lv_obj_get_parent(kb));
}
}
void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, const char* title, lv_keyboard_mode_t keyboard_mode, lv_coord_t width, uint8_t max_length, const char* fill_text, bool contain_in_panel)
{
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(parent, LV_OPA_50, 0);
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_layout_flex_column(parent, LV_FLEX_ALIGN_SPACE_BETWEEN);
if (contain_in_panel)
{
lv_obj_set_size(parent, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
}
else
{
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
}
if (title != nullptr)
{
lv_obj_t * empty_panel = lv_create_empty_panel(parent);
lv_obj_set_size(empty_panel, 0, 0);
lv_obj_t * title_container = lv_obj_create(parent);
lv_obj_set_style_pad_all(title_container, CYD_SCREEN_GAP_PX / 2, 0);
lv_obj_set_size(title_container, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_t * title_label = lv_label_create(title_container);
lv_label_set_text(title_label, title);
}
lv_obj_t * empty_panel = lv_create_empty_panel(parent);
lv_obj_set_flex_grow(empty_panel, 1);
lv_obj_t * ta = lv_textarea_create(parent);
lv_obj_t * keyboard = lv_keyboard_create(parent);
lv_obj_set_width(ta, width);
lv_textarea_set_max_length(ta, max_length);
lv_textarea_set_one_line(ta, true);
lv_textarea_set_text(ta, fill_text);
lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_READY, keyboard);
lv_obj_add_event_cb(ta, lv_keyboard_text_entry_close, LV_EVENT_ALL, keyboard);
lv_keyboard_set_mode(keyboard, keyboard_mode);
lv_keyboard_set_textarea(keyboard, ta);
}
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 lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height, const char * comment)
{
lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_layout_flex_row(panel, LV_FLEX_ALIGN_END);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, label_text);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_flex_grow(label, 1);
lv_obj_set_parent(object, panel);
if (set_height)
lv_obj_set_height(object, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
if (comment != NULL)
{
lv_obj_t * comment_label = lv_label_create(root_panel);
lv_label_set_text(comment_label, comment);
lv_obj_set_style_text_font(comment_label, &CYD_SCREEN_FONT_SMALL, 0);
}
lv_obj_t * line = lv_line_create(root_panel);
lv_line_set_points(line, line_points, 2);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
}
#define DROPDOWN_WIDTH CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 3.75
#define TOGGLE_WIDTH CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2
void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data, const char * comment)
{
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn, on_click, LV_EVENT_CLICKED, user_data);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, btn_text);
lv_obj_center(label);
lv_create_custom_menu_entry(label_text, btn, root_panel, true, comment);
}
void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data, const char * comment)
{
lv_obj_t * toggle = lv_switch_create(lv_scr_act());
lv_obj_add_event_cb(toggle, on_toggle, LV_EVENT_VALUE_CHANGED, user_data);
lv_obj_set_width(toggle, TOGGLE_WIDTH);
if (state)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
lv_create_custom_menu_entry(label_text, toggle, root_panel, true, comment);
}
void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data, const char * comment)
{
lv_obj_t * dropdown = lv_dropdown_create(lv_scr_act());
lv_dropdown_set_options(dropdown, options);
lv_dropdown_set_selected(dropdown, index);
lv_obj_set_width(dropdown, DROPDOWN_WIDTH);
lv_obj_add_event_cb(dropdown, on_change, LV_EVENT_VALUE_CHANGED, user_data);
lv_create_custom_menu_entry(label_text, dropdown, root_panel, true, comment);
}
void lv_create_custom_menu_label(const char *label_text, lv_obj_t* root_panel, const char *text)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, text);
lv_create_custom_menu_entry(label_text, label, root_panel, false);
}
uint32_t message_hash = 0;
lv_timer_t* timer = NULL;
void on_timer_destroy(lv_event_t * e)
{
lv_timer_del(timer);
timer = NULL;
}
void timer_callback(lv_timer_t *timer)
{
lv_obj_t * panel = (lv_obj_t *)timer->user_data;
lv_obj_del(panel);
}
void lv_create_popup_message(const char* message, uint16_t timeout_ms)
{
if (message == nullptr || timer != NULL)
{
return;
}
uint32_t new_hash = crc32String(message);
if (new_hash == message_hash)
{
return;
}
message_hash = new_hash;
lv_obj_t* panel = lv_obj_create(lv_scr_act());
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER);
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, -CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_add_event_cb(panel, on_timer_destroy, LV_EVENT_DELETE, NULL);
lv_obj_add_event_cb(panel, destroy_event_user_data, LV_EVENT_CLICKED, panel);
lv_obj_set_style_border_color(panel, lv_color_hex(0xFF0000), 0);
lv_obj_t* label = lv_label_create(panel);
lv_label_set_text_fmt(label, "%s", message);
lv_obj_set_size(label, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 6, LV_SIZE_CONTENT);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
timer = lv_timer_create(timer_callback, timeout_ms, panel);
}
lv_obj_t * lv_label_btn_create(lv_obj_t * parent, lv_event_cb_t btn_callback, void* user_data)
{
lv_obj_t * panel = lv_create_empty_panel(parent);
lv_obj_set_size(panel, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_add_event_cb(panel, btn_callback, LV_EVENT_CLICKED, user_data);
lv_obj_t * label = lv_label_create(panel);
return label;
}

View File

@@ -1,15 +1,30 @@
#pragma once #pragma once
#ifndef CYD_SCREEN_WIDTH_PX #ifdef CYD_SCREEN_VERTICAL
#define CYD_SCREEN_WIDTH_PX LCD_HEIGHT #ifndef CYD_SCREEN_WIDTH_PX
#endif #define CYD_SCREEN_WIDTH_PX LCD_WIDTH
#endif
#ifndef CYD_SCREEN_HEIGHT_PX #ifndef CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_HEIGHT_PX LCD_WIDTH #define CYD_SCREEN_HEIGHT_PX LCD_HEIGHT
#endif #endif
#define CYD_SCREEN_PANEL_WIDTH_PX \ #define CYD_SCREEN_PANEL_HEIGHT_PX \
(CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_SIDEBAR_SIZE_PX)
#define CYD_SCREEN_PANEL_WIDTH_PX CYD_SCREEN_WIDTH_PX
#else
#ifndef CYD_SCREEN_WIDTH_PX
#define CYD_SCREEN_WIDTH_PX LCD_HEIGHT
#endif
#ifndef CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_HEIGHT_PX LCD_WIDTH
#endif
#define CYD_SCREEN_PANEL_HEIGHT_PX CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_PANEL_WIDTH_PX \
(CYD_SCREEN_WIDTH_PX - CYD_SCREEN_SIDEBAR_SIZE_PX) (CYD_SCREEN_WIDTH_PX - CYD_SCREEN_SIDEBAR_SIZE_PX)
#endif
typedef struct { typedef struct {
lv_event_cb_t event; lv_event_cb_t event;
@@ -23,3 +38,11 @@ void lv_layout_flex_column(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN
void lv_layout_flex_row(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN_START, lv_coord_t pad_column = CYD_SCREEN_GAP_PX, lv_coord_t pad_row = CYD_SCREEN_GAP_PX); void lv_layout_flex_row(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN_START, lv_coord_t pad_column = CYD_SCREEN_GAP_PX, lv_coord_t pad_row = CYD_SCREEN_GAP_PX);
void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t title, lv_button_column_t* columns, int column_count); void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t title, lv_button_column_t* columns, int column_count);
void destroy_event_user_data(lv_event_t * e); void destroy_event_user_data(lv_event_t * e);
void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, const char* title = NULL, lv_keyboard_mode_t keyboard_mode = LV_KEYBOARD_MODE_NUMBER, lv_coord_t width = CYD_SCREEN_PANEL_WIDTH_PX / 2, uint8_t max_length = 3, const char* fill_text = "", bool contain_in_panel= true);
void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true, const char * comment = NULL);
void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data = NULL, const char * comment = NULL);
void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data = NULL, const char * comment = NULL);
void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data = NULL, const char * comment = NULL);
void lv_create_custom_menu_label(const char *label_text, lv_obj_t* root_panel, const char *text);
void lv_create_popup_message(const char* message, uint16_t timeout_ms);
lv_obj_t * lv_label_btn_create(lv_obj_t * parent, lv_event_cb_t btn_callback, void* user_data = NULL);

View File

@@ -3,94 +3,123 @@
#include "../conf/global_config.h" #include "../conf/global_config.h"
#include "ui_utils.h" #include "ui_utils.h"
#include "WiFi.h" #include "WiFi.h"
#include "../core/data_setup.h"
#include "../core/lv_setup.h"
void wifi_init_inner(); void wifi_init_inner();
void wifi_pass_entry(const char* ssid);
const char * current_ssid_ptr = NULL;
static void reset_btn_event_handler(lv_event_t * e) { static void reset_btn_event_handler(lv_event_t * e) {
lv_event_code_t code = lv_event_get_code(e); global_config.wifi_configured = false;
if(code == LV_EVENT_CLICKED) {
global_config.wifiConfigured = false;
wifi_init_inner(); wifi_init_inner();
}
} }
static void refresh_btn_event_handler(lv_event_t * e){ static void keyboard_cb_enter_password(lv_event_t * e) {
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
wifi_init_inner();
}
}
static void ta_event_cb(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 * 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); const char * txt = lv_textarea_get_text(ta);
int len = strlen(txt); global_config.wifi_configured = true;
if (len > 0) strcpy(global_config.wifi_SSID, current_ssid_ptr);
{ strcpy(global_config.wifi_password, txt);
global_config.wifiConfigured = true; write_global_config();
strcpy(global_config.wifiPassword, txt);
WriteGlobalConfig();
wifi_init_inner(); wifi_init_inner();
}
}
else if (code == LV_EVENT_CANCEL)
{
wifi_init_inner();
}
} }
void wifi_pass_entry(const char* ssid){ static void btn_reuse_password(lv_event_t * e)
lv_obj_clean(lv_scr_act()); {
ESP.restart();
}
lv_obj_t * root = lv_create_empty_panel(lv_scr_act()); static void btn_no_reuse_password(lv_event_t * e)
lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); {
lv_layout_flex_column(root); lv_create_keyboard_text_entry(keyboard_cb_enter_password, "Enter WiFi Password", LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 63, "", false);
}
lv_obj_t * top_root = lv_create_empty_panel(root); void ask_reuse_password(const char * ssid){
lv_obj_set_width(top_root, CYD_SCREEN_WIDTH_PX); lv_obj_t * root = lv_obj_create(lv_scr_act());
lv_layout_flex_column(top_root); lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_set_flex_grow(top_root, 1); lv_obj_align(root, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0); lv_layout_flex_column(root, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_t * label = lv_label_create(top_root); lv_obj_t * label = lv_label_create(root);
lv_label_set_text(label, "Enter WiFi Password"); lv_label_set_text_fmt(label, "Reuse stored WiFi Password?\n(Password Length: %d)", strlen(global_config.wifi_password));
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_t * passEntry = lv_textarea_create(top_root); lv_obj_t * button_row = lv_create_empty_panel(root);
lv_textarea_set_one_line(passEntry, true); lv_layout_flex_row(button_row, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_textarea_set_text(passEntry, ""); lv_obj_set_size(button_row, lv_pct(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_set_width(passEntry, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_add_event_cb(passEntry, ta_event_cb, LV_EVENT_ALL, NULL);
lv_obj_set_flex_grow(passEntry, 1);
lv_obj_t * keyboard = lv_keyboard_create(root); lv_obj_t * no_btn = lv_btn_create(button_row);
lv_keyboard_set_textarea(keyboard, passEntry); lv_obj_add_event_cb(no_btn, btn_no_reuse_password, LV_EVENT_CLICKED, (void*)ssid);
lv_obj_add_event_cb(no_btn, destroy_event_user_data, LV_EVENT_CLICKED, root);
lv_obj_set_height(no_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_set_width(no_btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX);
lv_obj_set_style_pad_all(no_btn, CYD_SCREEN_GAP_PX, 0);
label = lv_label_create(no_btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE);
lv_obj_center(label);
lv_obj_t * yes_btn = lv_btn_create(button_row);
lv_obj_add_event_cb(yes_btn, btn_reuse_password, LV_EVENT_CLICKED, (void*)ssid);
lv_obj_set_height(yes_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_set_width(yes_btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX);
lv_obj_set_style_pad_all(yes_btn, CYD_SCREEN_GAP_PX, 0);
label = lv_label_create(yes_btn);
lv_label_set_text(label, LV_SYMBOL_OK);
lv_obj_center(label);
}
void wifi_pass_entry(const char* ssid)
{
current_ssid_ptr = ssid;
if (strcmp(ssid, global_config.wifi_SSID) == 0){
ask_reuse_password(ssid);
return;
}
btn_no_reuse_password(NULL);
} }
static void wifi_btn_event_handler(lv_event_t * e){ static void wifi_btn_event_handler(lv_event_t * e){
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
delay(100); delay(100);
char* ssid = (char*)e->user_data; char* ssid = (char*)e->user_data;
strcpy(global_config.wifiSSID, ssid);
Serial.println(ssid); Serial.println(ssid);
wifi_pass_entry(ssid); wifi_pass_entry(ssid);
} }
static void wifi_keyboard_cb_manual_ssid(lv_event_t * e){
lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
const char * text = lv_textarea_get_text(ta);
char * text_copy = (char*)malloc(strlen(text) + 1);
strcpy(text_copy, text);
Serial.println(text_copy);
wifi_pass_entry(text_copy);
}
static void wifi_btn_manual_ssid(lv_event_t * e){
lv_create_keyboard_text_entry(wifi_keyboard_cb_manual_ssid, "Enter SSID Manually", LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 31, "", false);
} }
void wifi_init_inner(){ void wifi_init_inner(){
WiFi.disconnect(); WiFi.disconnect();
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
if (global_config.wifiConfigured){ if (global_config.wifi_configured){
WiFi.begin(global_config.wifiSSID, global_config.wifiPassword); if (global_config.wifi_password[0] == '\0')
{
WiFi.begin(global_config.wifi_SSID);
}
else
{
WiFi.begin(global_config.wifi_SSID, global_config.wifi_password);
}
Serial.printf("Connecting to %s with a password length of %d\n", global_config.wifi_SSID, strlen(global_config.wifi_password));
lv_obj_t * label = lv_label_create(lv_scr_act()); lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Connecting to WiFi"); lv_label_set_text(label, "Connecting to WiFi");
@@ -125,16 +154,25 @@ void wifi_init_inner(){
lv_obj_t * top_row = lv_create_empty_panel(root); lv_obj_t * top_row = lv_create_empty_panel(root);
lv_obj_set_size(top_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT); lv_obj_set_size(top_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
lv_layout_flex_row(top_row, LV_FLEX_ALIGN_SPACE_BETWEEN); lv_layout_flex_row(top_row);
label = lv_label_create(top_row); label = lv_label_create(top_row);
lv_label_set_text(label, "Select a network"); lv_label_set_text(label, "Select a network");
lv_obj_set_flex_grow(label, 1);
lv_obj_t * refreshBtn = lv_btn_create(top_row); lv_obj_t * btn = lv_btn_create(top_row);
lv_obj_add_event_cb(refreshBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL); lv_obj_add_event_cb(btn, wifi_btn_manual_ssid, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(refreshBtn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(refreshBtn); label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_KEYBOARD);
lv_obj_center(label);
btn = lv_btn_create(top_row);
lv_obj_add_event_cb(btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_REFRESH); lv_label_set_text(label, LV_SYMBOL_REFRESH);
lv_obj_center(label); lv_obj_center(label);
@@ -159,7 +197,7 @@ void wifi_init_inner(){
ssid_copy[j] = '\0'; ssid_copy[j] = '\0';
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_WIFI, ssid_copy); lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_WIFI, ssid_copy);
lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_ALL, (void*)ssid_copy); lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_CLICKED, (void*)ssid_copy);
} }
} }
@@ -180,19 +218,45 @@ void wifi_init(){
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
wifi_init_inner(); wifi_init_inner();
while (!global_config.wifiConfigured || WiFi.status() != WL_CONNECTED){ while (!global_config.wifi_configured || WiFi.status() != WL_CONNECTED){
if (millis() - print_timer > print_freq){ if (millis() - print_timer > print_freq){
print_timer = millis(); print_timer = millis();
Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]); Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]);
} }
lv_timer_handler(); lv_handler();
lv_task_handler();
} }
} }
ulong start_time_recovery = 0;
void wifi_ok(){ void wifi_ok(){
if (WiFi.status() != WL_CONNECTED){ if (WiFi.status() != WL_CONNECTED){
Serial.println("WiFi Connection Lost. Reconnecting...");
freeze_request_thread();
WiFi.disconnect();
delay(5000); // Wait for the WiFi to disconnect
start_time_recovery = millis();
if (global_config.wifi_password[0] == '\0')
{
WiFi.begin(global_config.wifi_SSID);
}
else
{
WiFi.begin(global_config.wifi_SSID, global_config.wifi_password);
}
while (WiFi.status() != WL_CONNECTED){
delay(1000);
Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]);
if (millis() - start_time_recovery > 15000){
Serial.println("WiFi Connection failed to reconnect. Restarting...");
ESP.restart(); ESP.restart();
} }
}
unfreeze_request_thread();
}
} }

48
Manual_Install.md Normal file
View File

@@ -0,0 +1,48 @@
# Manual install
## Flashing a build via the commandline
#### Release firmware image
1. Go to [the releases tab](https://github.com/suchmememanyskill/CYD-Klipper/releases), and download the latest `firmware.zip` release.
2. Open the firmware.zip archive you just downloaded, open the corresponding folder for your screen, then extract `merged_firmware.bin`
This merged_firmware.bin file is a ready to flash image. Note that flashing this image does wipe your current configuration.
#### Developer firmware image
On every change made in this repository, [Github Actions](https://github.com/suchmememanyskill/CYD-Klipper/actions) automatically builds the firmware images for various screens.
0. Make sure you are logged into github
1. Go to a [Github Actions](https://github.com/suchmememanyskill/CYD-Klipper/actions) build summary, then download the `firmware` Artifact.
2. Open the firmware.zip archive you just downloaded, open the corresponding folder for your screen, then extract `merged_firmware.bin`
This merged_firmware.bin file is a ready to flash image. Note that flashing this image does wipe your current configuration.
### Flashing merged_firmware.bin
1. Download and extract [esptool](https://github.com/espressif/esptool/releases) to a new folder
- For windows, download `esptool-v4.7.0-win64.zip`
2. Open a terminal window and navigate to this new folder containing esptool
- In windows, you can type cmd and press enter in the address bar in explorer to jump to the folder in cmd ![cmd](readme/cmd.jpg)
3. Move `merged-firmware.bin` into this new folder
4. Connect the display to your computer
5. Execute the command `esptool write_flash 0x0 merged_firmware.bin`
- Don't forget to hold down the boot button on the display
## Building & Flashing via PlatformIO
0. Install the following tools:
- [Visual Studio Code](https://code.visualstudio.com/) and install the PlatformIO IDE plugin.
- [Git](https://git-scm.com/download/win)
1. Download the source code of CYD-Klipper
- This can be done via the `git clone https://github.com/suchmememanyskill/CYD-Klipper` command or via the green `<> Code` button on Github
2. Open the CYD-Klipper folder inside the CYD-Klipper folder in Visual Studio Code
3. Click on the Alien/Bug tab (PlatformIO) on the left
4. Expand the folder/tab for your specific screen
- Entries with the suffix '-SD' are using the smartdisplay driver. Entries without this suffix are using a custom driver
- Usually, a custom driver is preferred over the smartdisplay driver
5. Connect the display to your computer
6. Click 'Upload and Monitor'
- This will start compiling the code, and after upload it to the display
- Don't forget to hold the boot button while flashing. The screen will flash when the firmware is attempted to be flashed
![platformio](readme/platformio.png)

View File

@@ -26,7 +26,7 @@ A ESP32-2432S028R is required to run this project. You can find out where to buy
### Install ### Install
[There is a web-based installer available. This is only supported on Chrome, Edge or Opera, and only on Desktop.](https://suchmememanyskill.github.io/CYD-Klipper/) [There is a web-based installer available. This is only supported on Chrome, Edge, Arc or Opera, and only on Desktop.](https://suchmememanyskill.github.io/CYD-Klipper/)
On initial install, all data should be wiped. On updates, data should be able to be kept without issues. On initial install, all data should be wiped. On updates, data should be able to be kept without issues.

View File

@@ -24,7 +24,11 @@
} }
.main a { .main a {
color: #F00; color: #F44;
}
.install {
margin-bottom: 300px;
} }
.install .iconify { .install .iconify {
@@ -46,13 +50,22 @@
document.getElementById("changelog-header-version").innerText += data.tag_name; document.getElementById("changelog-header-version").innerText += data.tag_name;
} }
function setInstallButton(esp){
document.getElementById("install-btn").innerHTML = `<esp-web-install-button manifest="https://suchmememanyskill.github.io/CYD-Klipper/${esp}.json"></esp-web-install-button>`;
}
function setInstallButtonDefault(){
setInstallButton("esp32-2432S028R")
}
fetchChangelog(); fetchChangelog();
window.onload = setInstallButtonDefault;
</script> </script>
</head> </head>
<body> <body>
<section class="main"> <section class="main">
<h2>CYD-Klipper <span class="iconify" data-icon="mdi-printer-3d" style="color: orange;"></span></h2> <h2>CYD-Klipper <span class="iconify" data-icon="mdi-printer-3d" style="color: #F44;"></span></h2>
<p>An implementation of a Klipper status display on an ESP32 + screen.<br>Uses Moonraker to fetch data.<br><a href="https://github.com/suchmememanyskill/CYD-Klipper">Source code is available on GitHub</a>.</p> <p>An implementation of a Klipper status display on an ESP32 + screen.<br>Uses Moonraker to fetch data.<br><a href="https://github.com/suchmememanyskill/CYD-Klipper">Source code is available on GitHub</a>.</p>
<section class="changelog"> <section class="changelog">
@@ -65,17 +78,24 @@
<p>If you found this project helpful, please consider a donation to <a href="https://ko-fi.com/suchmememanyskill">my Ko-Fi</a>.<br>It would help out a lot in the development of this project, due to the need to buy the screens.<br>Thank you!</p> <p>If you found this project helpful, please consider a donation to <a href="https://ko-fi.com/suchmememanyskill">my Ko-Fi</a>.<br>It would help out a lot in the development of this project, due to the need to buy the screens.<br>Thank you!</p>
</section> </section>
<section class="install"> <section class="issues">
<h3><span class="iconify" data-icon="mdi-download"></span> Install on ESP32-2432S028 (2.8" Resistive)</h3> <h3><span class="iconify" data-icon="mdi-github" style="color: white; filter: drop-shadow(0 0 0.75rem gray);"></span> Report Issues</h3>
<p>Note: You may need to hold the 'BOOT' button on the device while pressing install.</p> <p>If you experience any issues with this project, or have any feature requests for the project, please report them on the <a href="https://github.com/suchmememanyskill/CYD-Klipper/issues">issues tab on Github</a>.</p>
<esp-web-install-button
manifest="https://suchmememanyskill.github.io/CYD-Klipper/esp32-2432S028R.json"></esp-web-install-button>
</section> </section>
<section class="install"> <section class="install">
<h3><span class="iconify" data-icon="mdi-download"></span> Install on ESP32-3248S035 (3.5" Capacitive)</h3> <h3><span class="iconify" data-icon="mdi-download"></span> Install</h3>
<p>Note: You may need to hold the 'BOOT' button on the device while pressing install.</p> <p>Select your device from the list below and click 'Connect'.<br>Note: You may need to hold the 'BOOT' button on the device while pressing install.<br><br>The 2.8" Resistive and 3.5" Capacitive models are best suited (in my opinion) for CYD-Klipper.<br><br>Note for any resistive models: You can clear touch calibration by holding the BOOT button for 8 seconds while the screen is on.</p>
<esp-web-install-button <select id="select-install-btn" onchange="setInstallButton(getElementById('select-install-btn').value)">
manifest="https://suchmememanyskill.github.io/CYD-Klipper/esp32-3248S035C.json"></esp-web-install-button> <option value="esp32-2432S024C-SD">ESP32-2432S024 (2.4" Capacitive)</option>
<option selected value="esp32-2432S028R">ESP32-2432S028 (2.8" Resistive)</option>
<option value="esp32-2432S032C-SD">ESP32-2432S032 (3.2" Capacitive)</option>
<option value="esp32-3248S035C">ESP32-3248S035 (3.5" Capacitive)</option>
<option value="esp32-3248S035C-V">ESP32-3248S035 (3.5" Capacitive) Vertical Orientation</option>
<option value="esp32-4827S043C-SD">ESP32-4827S043 (4.3" 480x270 Capacitive)</option>
<option value="esp32-8048S043C-SD">ESP32-8048S043 (4.3" 800x480 Capacitive)</option>
</select>
<span id="install-btn"></span>
</section> </section>
</section> </section>
</body> </body>

25
ci.py
View File

@@ -1,15 +1,31 @@
import subprocess, os, shutil, json import subprocess, os, shutil, json
CYD_PORTS = ["esp32-3248S035C", "esp32-2432S028R"] CYD_PORTS = [
"esp32-3248S035C",
"esp32-2432S028R",
"esp32-2432S032C-SD",
"esp32-8048S043C-SD",
"esp32-2432S024C-SD",
"esp32-4827S043C-SD",
"esp32-3248S035C-V",
#"esp32-4827S043R-SD",
]
ESP_S3_CHIPS = [
"esp32-8048S043C-SD",
"esp32-4827S043C-SD",
]
BASE_DIR = os.getcwd() BASE_DIR = os.getcwd()
def get_manifest(base_path : str, device_name : str): def get_manifest(base_path : str, device_name : str):
return { return {
"name": f"to {device_name}", "name": f"to {device_name}",
"funding_url": "https://ko-fi.com/suchmememanyskill",
"new_install_prompt_erase": True, "new_install_prompt_erase": True,
"builds": [ "builds": [
{ {
"chipFamily": "ESP32", "chipFamily": "ESP32-S3" if device_name in ESP_S3_CHIPS else "ESP32",
"parts": [ "parts": [
{ {
"path": f"{base_path}/bootloader.bin", "path": f"{base_path}/bootloader.bin",
@@ -71,7 +87,10 @@ for port in CYD_PORTS:
add_configuration(port) add_configuration(port)
os.chdir(BASE_DIR) os.chdir(BASE_DIR)
shutil.copytree("./out", "./_site/out") out_dir = "./_site/out"
if os.path.exists(out_dir):
shutil.rmtree(out_dir)
shutil.copytree("./out", out_dir)
with open("./_site/OTA.json", "w") as f: with open("./_site/OTA.json", "w") as f:
json.dump({"Configurations": configurations}, f) json.dump({"Configurations": configurations}, f)

BIN
readme/cmd.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
readme/platformio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB