71 Commits

Author SHA1 Message Date
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
58 changed files with 3366 additions and 1060 deletions

37
Build.md Normal file
View File

@@ -0,0 +1,37 @@
# Building
## Running a developer build
On every change made in this repository, [Github Actions](https://github.com/suchmememanyskill/CYD-Klipper/actions) automatically builds the firmware images for various screens. You can run one of these images as follows:
#### Getting a firmware image
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 via PlatformIO
0. Install [Visual Studio Code](https://code.visualstudio.com/) and install the PlatformIO IDE plugin.
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

View File

@@ -11,7 +11,7 @@
"'-D LCD_HEIGHT=320'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D BCKL=0'",
"'-D GPIO_BCKL=0'",
"'-D LCD_ST7789_I80'",
"'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-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_SRAM_TRANS_ALIGN=4'",
"'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'",
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=55000000'",
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=12000000'",
"'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'",
@@ -43,7 +43,7 @@
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=0'",
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ST7789_DEV_CONFIG_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'",
@@ -53,7 +53,7 @@
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-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_SCL_IO_NUM=22'",
"'-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_LEVELS_RESET=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_Y=false'",
"'-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 LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D BCKL=21'",
"'-D GPIO_BCKL=21'",
"'-D LCD_ST7789_SPI'",
"'-D ST7789_SPI_HOST=SPI2_HOST'",
"'-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_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ST7789_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ST7789_SPI_BUS_MAX_TRANSFER_SZ=0'",
"'-D ST7789_SPI_BUS_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=55000000'",
"'-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'",
@@ -91,8 +91,7 @@
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
@@ -113,7 +112,7 @@
"arduino",
"espidf"
],
"name": "esp32-2432S028Rv3",
"name": "esp32-2432S028Rv3-SD",
"upload": {
"flash_size": "4MB",
"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 LCD_WIDTH=320'",
"'-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 ST7796_SPI_HOST=SPI2_HOST'",
"'-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_QUADWP_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_DC_GPIO_NUM=2'",
"'-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_LCD_CMD_BITS=8'",
"'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'",
@@ -39,13 +44,13 @@
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-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_SCL_IO_NUM=32'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'",
"'-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=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_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
@@ -77,14 +82,13 @@
"'-D SPEAK=26'",
"-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40",
"-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_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
],
"f_cpu": "240000000L",
"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_WIDTH_PX=480",
"-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40",
"-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",

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,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

@@ -14,9 +14,10 @@ board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
https://github.com/suchmememanyskill/esp32-smartdisplay
https://github.com/suchmememanyskill/esp32-smartdisplay#9c1d737
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
monitor_filters = esp32_exception_decoder
build_flags =
-DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
@@ -32,6 +33,7 @@ lib_deps =
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-3248S035C]
board = esp32-3248S035C
@@ -42,9 +44,39 @@ lib_deps =
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-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
[env:esp32-2432S028R-smartdisplay]
board = esp32-2432S028R-smartdisplay
[env:esp32-4827S043C-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[] = {
{LV_PALETTE_BLUE, 0, LV_PALETTE_RED},
{LV_PALETTE_GREEN, 0, LV_PALETTE_PURPLE},
{LV_PALETTE_LIME, -2, LV_PALETTE_PURPLE},
{LV_PALETTE_GREY, 0, LV_PALETTE_CYAN},
{LV_PALETTE_YELLOW, -2, LV_PALETTE_PINK},
{LV_PALETTE_ORANGE, -2, LV_PALETTE_BLUE},
{LV_PALETTE_RED, 0, LV_PALETTE_GREEN},
{LV_PALETTE_PURPLE, 0, LV_PALETTE_GREY},
{LV_PALETTE_RED, 0, LV_PALETTE_BLUE},
{LV_PALETTE_PURPLE, 0, LV_PALETTE_CYAN},
};
void WriteGlobalConfig() {
void write_global_config()
{
Preferences preferences;
preferences.begin("global_config", false);
preferences.putBytes("global_config", &global_config, sizeof(global_config));
preferences.end();
}
void VerifyVersion(){
void verify_version()
{
Preferences preferences;
if (!preferences.begin("global_config", false))
return;
@@ -37,17 +40,93 @@ void VerifyVersion(){
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.brightness = 255;
global_config.screenTimeout = 5;
global_config.hotend_presets[0] = 0;
global_config.hotend_presets[1] = 200;
global_config.hotend_presets[2] = 240;
global_config.bed_presets[0] = 0;
global_config.bed_presets[1] = 60;
global_config.bed_presets[2] = 70;
VerifyVersion();
global_config.screen_timeout = 5;
global_config.printer_config[0].hotend_presets[0] = 0;
global_config.printer_config[0].hotend_presets[1] = 200;
global_config.printer_config[0].hotend_presets[2] = 240;
global_config.printer_config[0].bed_presets[0] = 0;
global_config.printer_config[0].bed_presets[1] = 60;
global_config.printer_config[0].bed_presets[2] = 70;
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.begin("global_config", true);
preferences.getBytes("global_config", &global_config, sizeof(global_config));

View File

@@ -3,7 +3,8 @@
#include "lvgl.h"
#define CONFIG_VERSION 4
#define CONFIG_VERSION 6
#define PRINTER_CONFIG_COUNT 8
enum {
REMAINING_TIME_CALC_PERCENTAGE = 0,
@@ -11,47 +12,75 @@ enum {
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;
};
};
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 {
unsigned char version;
union {
unsigned int raw;
struct {
// Internal
bool screenCalibrated : 1;
bool wifiConfigured : 1;
bool ipConfigured : 1;
bool screen_calibrated : 1;
bool wifi_configured : 1;
// External
bool lightMode : 1;
bool invertColors : 1;
bool rotateScreen : 1;
bool onDuringPrint : 1;
bool autoOtaUpdate : 1;
unsigned char remaining_time_calc_mode : 2;
// Internal
bool auth_configured : 1;
bool rotate_screen : 1;
bool auto_ota_update : 1;
bool multi_printer_mode : 1;
bool on_during_print : 1;
bool display_mode : 1; // Driver specifc usage. Currently only used on ESP32-2432S028R to fix the screen on the usb-c model
};
};
float screenCalXOffset;
float screenCalXMult;
float screenCalYOffset;
float screenCalYMult;
char wifiSSID[32];
char wifiPassword[64];
PRINTER_CONFIG printer_config[PRINTER_CONFIG_COUNT];
char klipperHost[64];
unsigned short klipperPort;
float screen_cal_x_offset;
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 screenTimeout;
unsigned short hotend_presets[3];
unsigned short bed_presets[3];
char klipper_auth[33];
unsigned char screen_timeout;
unsigned char printer_index;
} GLOBAL_CONFIG;
typedef struct _COLOR_DEF {
@@ -63,8 +92,13 @@ typedef struct _COLOR_DEF {
extern GLOBAL_CONFIG global_config;
extern COLOR_DEF color_defs[];
void WriteGlobalConfig();
void VerifyVersion();
void LoadGlobalConfig();
void write_global_config();
void verify_version();
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

View File

@@ -49,7 +49,7 @@
#define LV_MEM_CUSTOM 0
#if LV_MEM_CUSTOM == 0
/*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.*/
#define LV_MEM_ADR 0 /*0: unused*/
@@ -194,7 +194,7 @@
*-----------*/
/*Enable the log module*/
#define LV_USE_LOG 1
#define LV_USE_LOG 0
#if LV_USE_LOG
/*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_USER Only logs added by the user
*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';
*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_18 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_26 0
#define LV_FONT_MONTSERRAT_28 1
@@ -607,7 +607,7 @@
#endif
/*PNG decoder library*/
#define LV_USE_PNG 0
#define LV_USE_PNG 1
/*BMP decoder library*/
#define LV_USE_BMP 0
@@ -678,16 +678,16 @@
====================*/
/*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
#define LV_DEMO_WIDGETS_SLIDESHOW 1
#endif
/*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*/
#define LV_USE_DEMO_BENCHMARK 1
#define LV_USE_DEMO_BENCHMARK 0
/*Stress test for LVGL*/
#define LV_USE_DEMO_STRESS 0

View File

@@ -2,19 +2,17 @@
#include "data_setup.h"
#include "lvgl.h"
#include "../conf/global_config.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <esp_task_wdt.h>
#include "macros_query.h"
#include <UrlEncode.h>
const char *printer_state_messages[] = {
"Error",
"Idle",
"Printing"};
#include "http_client.h"
#include "../ui/ui_utils.h"
#include "macros_query.h"
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};
SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore;
const long data_update_interval = 780;
@@ -45,19 +43,8 @@ void unfreeze_render_thread(){
void send_gcode(bool wait, const char *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
{
client.GET();
@@ -75,14 +62,7 @@ int get_slicer_time_estimate_s()
delay(10);
char buff[256] = {};
sprintf(buff, "http://%s:%d/server/files/metadata?filename=%s", global_config.klipperHost, global_config.klipperPort, urlEncode(printer.print_filename).c_str());
HTTPClient client;
client.useHTTP10(true);
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
SETUP_HTTP_CLIENT("/server/files/metadata?filename=" + urlEncode(printer.print_filename));
int httpCode = client.GET();
@@ -128,25 +108,26 @@ int last_slicer_time_query = -15000;
void fetch_printer_data()
{
freeze_request_thread();
char buff[256] = {};
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);
HTTPClient client;
client.useHTTP10(true);
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
PRINTER_CONFIG *config = get_current_printer_config();
SETUP_HTTP_CLIENT("/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status")
int httpCode = client.GET();
delay(10);
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;
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto status = doc["result"]["status"];
bool emit_state_update = false;
int printer_state = printer.state;
delay(10);
unfreeze_request_thread();
freeze_render_thread();
@@ -160,7 +141,7 @@ void fetch_printer_data()
{
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;
}
@@ -233,7 +214,8 @@ void fetch_printer_data()
const char *filename = status["print_stats"]["filename"];
strcpy(filename_buff, filename);
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.total_layers = status["print_stats"]["info"]["total_layer"];
printer.current_layer = status["print_stats"]["info"]["current_layer"];
@@ -242,7 +224,7 @@ void fetch_printer_data()
if (state == nullptr)
{
printer_state = PRINTER_STATE_ERROR;
// Continue
}
else if (strcmp(state, "printing") == 0)
{
@@ -258,28 +240,32 @@ void fetch_printer_data()
}
}
// TODO: make a call to /server/files/metadata to get more accurate time estimates
// https://moonraker.readthedocs.io/en/latest/web_api/#server-administration
if (status.containsKey("display_status"))
{
printer.print_progress = status["display_status"]["progress"];
const char* message = status["display_status"]["message"];
lv_create_popup_message(message, 10000);
}
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;
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;
}
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);
}
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;
}
@@ -316,11 +302,110 @@ void fetch_printer_data()
else
{
klipper_request_consecutive_fail_count++;
if (klipper_request_consecutive_fail_count == 5)
{
printer.state = PRINTER_STATE_OFFLINE;
lv_msg_send(DATA_PRINTER_STATE, &printer);
}
Serial.printf("Failed to fetch printer data: %d\n", httpCode);
unfreeze_request_thread();
}
}
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();
}
}
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()
{
// Causes other threads that are trying to lock the thread to actually lock it
@@ -331,9 +416,16 @@ void data_loop()
void data_loop_background(void * param){
esp_task_wdt_init(10, true);
int loop_iter = 20;
while (true){
delay(data_update_interval);
fetch_printer_data();
if (global_config.multi_printer_mode) {
if (loop_iter++ > 20){
fetch_printer_data_minimal();
loop_iter = 0;
}
}
}
}
@@ -341,10 +433,11 @@ TaskHandle_t background_loop;
void data_setup()
{
printer_minimal = (PrinterMinimal *)calloc(sizeof(PrinterMinimal), PRINTER_CONFIG_COUNT);
semaphore_init();
printer.print_filename = filename_buff;
fetch_printer_data();
macros_query_setup();
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
enum {
PRINTER_STATE_ERROR = 0,
PRINTER_STATE_IDLE = 1,
PRINTER_STATE_PRINTING = 2,
PRINTER_STATE_PAUSED = 3,
PRINTER_STATE_OFFLINE = 0,
PRINTER_STATE_ERROR = 1,
PRINTER_STATE_IDLE = 2,
PRINTER_STATE_PRINTING = 3,
PRINTER_STATE_PAUSED = 4,
};
extern const char* printer_state_messages[];
typedef struct _Printer {
unsigned char state;
char* state_message;
@@ -21,6 +20,7 @@ typedef struct _Printer {
unsigned char homed_axis;
unsigned char absolute_coords;
float elapsed_time_s;
float printed_time_s;
float remaining_time_s;
float filament_used_mm;
char* print_filename;
@@ -37,12 +37,20 @@ typedef struct _Printer {
int slicer_estimated_print_time_s;
} Printer;
typedef struct _PrinterMinimal {
unsigned char state;
float print_progress; // 0 -> 1
unsigned int power_devices;
} PrinterMinimal;
extern Printer printer;
extern PrinterMinimal *printer_minimal;
extern int klipper_request_consecutive_fail_count;
#define DATA_PRINTER_STATE 1
#define DATA_PRINTER_DATA 2
#define DATA_PRINTER_TEMP_PRESET 3
#define DATA_PRINTER_MINIMAL 4
void data_loop();
void data_setup();

View File

@@ -1,6 +1,10 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
#include "../screen_driver.h"
#ifdef CYD_SCREEN_VERTICAL
#error "Vertical screen not supported with the ESP32_2432S028R driver"
#endif
#include <SPI.h>
#include <TFT_eSPI.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(){
tft.invertDisplay(global_config.invertColors);
tft.invertDisplay(get_current_printer_config()->invert_colors);
}
void screen_setup()
{
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);
touchscreen.setRotation(global_config.rotateScreen ? 3 : 1);
touchscreen.setRotation(global_config.rotate_screen ? 3 : 1);
lv_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);
ledcAttachPin(21, 0);
tft.setRotation(global_config.rotateScreen ? 3 : 1);
tft.setRotation(global_config.rotate_screen ? 3 : 1);
tft.fillScreen(TFT_BLACK);
set_screen_brightness();
set_invert_display();
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);

View File

@@ -1,4 +1,5 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_3248S035C
#include "../screen_driver.h"
#include "lvgl.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 magicY;
if (!global_config.rotateScreen)
if (!global_config.rotate_screen)
{
magicY = tp.points[i].x;
magicX = TOUCH_HEIGHT - tp.points[i].y;
}
else
{
magicY = TOUCH_WIDTH - tp.points[i].x;
magicX = tp.points[i].y;
#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;
magicX = tp.points[i].y;
#endif
}
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()
{
tft.invertDisplay(global_config.invertColors);
tft.invertDisplay(get_current_printer_config()->invert_colors);
}
void set_LED_color(uint8_t rgbVal[3])
@@ -102,24 +109,36 @@ void screen_setup()
{
// Initialize the touchscreen
tp.begin();
tp.setRotation(ROTATION_NORMAL);
// Initialize LVGL
lv_init();
// Initialize the display
tft.init();
ledcSetup(0, 5000, 12);
ledcAttachPin(TFT_BL, 0);
tft.setRotation(global_config.rotateScreen ? 3 : 1);
tft.fillScreen(TFT_BLACK);
set_screen_brightness();
set_invert_display();
LED_init();
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = TFT_HEIGHT;
disp_drv.ver_res = TFT_WIDTH;
#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.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.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);

View File

@@ -1,4 +1,3 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
#include "../screen_driver.h"
@@ -15,13 +14,14 @@ void screen_setBrightness(byte brightness)
smartdisplay_lcd_set_backlight(brightness / 255.0f);
}
void set_invert_display(){
void set_invert_display()
{
lv_obj_invalidate(lv_scr_act());
}
void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
if (global_config.invertColors) {
if (get_current_printer_config()->invert_colors) {
uint32_t w = (area->x2 - area->x1 + 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);
}
#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()
{
smartdisplay_init();
@@ -44,7 +61,7 @@ void screen_setup()
}
#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

View File

@@ -2,9 +2,9 @@
#include "files_query.h"
#include "../conf/global_config.h"
#include "data_setup.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <HardwareSerial.h>
#include "http_client.h"
// Always has +1 entry with a null'd name
FILESYSTEM_FILE* last_query = NULL;
@@ -27,15 +27,7 @@ FILESYSTEM_FILE* get_files(int limit){
std::list<FILESYSTEM_FILE> files;
auto timer_request = millis();
char buff[256] = {};
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);
SETUP_HTTP_CLIENT_FULL("/server/files/list", true, 5000);
int httpCode = client.GET();
auto timer_parse = millis();

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
#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);
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);
if (data->state == LV_INDEV_STATE_PR){
point[0] = data->point.x;
point[1] = data->point.y;
lv_coord_t local_point[] = {data->point.x, data->point.y};
while (data->state == LV_INDEV_STATE_PR){
original_touch_driver(indev_driver, data);
delay(20);
}
point[0] = local_point[0];
point[1] = local_point[1];
}
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();
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
data->point.x = round((data->point.x * global_config.screenCalXMult) + global_config.screenCalXOffset);
data->point.y = round((data->point.y * global_config.screenCalYMult) + global_config.screenCalYOffset);
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.screen_cal_y_mult) + global_config.screen_cal_y_offset);
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
}
}
void lv_do_calibration(){
if (global_config.screenCalibrated){
if (global_config.screen_calibrated){
return;
}
@@ -74,48 +96,61 @@ void lv_do_calibration(){
lv_label_set_text(label, "Calibrate Screen");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * line = lv_line_create(lv_scr_act());
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_y[] = { {10, 0}, {10, 21} };
lv_line_set_points(line, line_points_x, 2);
lv_obj_align(line, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_t * line2 = lv_line_create(lv_scr_act());
lv_line_set_points(line2, line_points_y, 2);
lv_obj_align(line2, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_line_width(line2, 1, 0);
lv_line_set_points(line_x, line_points_x, 2);
lv_obj_set_style_line_width(line_x, 1, 0);
lv_line_set_points(line_y, line_points_y, 2);
lv_obj_set_style_line_width(line_y, 1, 0);
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
lv_obj_align(line_x, LV_ALIGN_TOP_RIGHT, 1, 0);
lv_obj_align(line_y, LV_ALIGN_TOP_RIGHT, -10, 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){
lv_timer_handler();
lv_task_handler();
lv_handler();
if (point[0] != 0 && point[1] != 0){
break;
}
}
delay(300);
lv_coord_t x1 = point[0];
lv_coord_t y1 = point[1];
point[0] = 0;
point[1] = 0;
lv_obj_del(line);
lv_obj_del(line2);
lv_obj_del(line_x);
lv_obj_del(line_y);
line = lv_line_create(lv_scr_act());
lv_line_set_points(line, line_points_x, 2);
lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, 1, -10);
lv_obj_set_style_line_width(line, 1, 0);
line_x = lv_line_create(lv_scr_act());
line_y = lv_line_create(lv_scr_act());
lv_line_set_points(line_x, line_points_x, 2);
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);
lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, -10, 1);
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
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){
lv_timer_handler();
lv_task_handler();
lv_handler();
if (point[0] != 0 && point[1] != 0){
break;
@@ -125,19 +160,30 @@ void lv_do_calibration(){
lv_coord_t x2 = point[0];
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 yDist = CYD_SCREEN_HEIGHT_PX - 20;
#endif
global_config.screenCalXMult = (float)xDist / (float)(x2 - x1);
global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult);
global_config.screen_cal_x_mult = (float)xDist / (float)(x2 - x1);
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.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult);
global_config.screen_cal_y_mult = (float)yDist / (float)(y2 - y1);
global_config.screen_cal_y_offset = 10.0 - ((float)y1 * global_config.screen_cal_y_mult);
global_config.screenCalibrated = true;
WriteGlobalConfig();
if (global_config.screen_cal_x_mult == std::numeric_limits<float>::infinity() || global_config.screen_cal_y_mult == std::numeric_limits<float>::infinity()){
Serial.println("Calibration failed, please try again");
ESP.restart();
}
global_config.screen_calibrated = true;
write_global_config();
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()
@@ -180,7 +226,7 @@ void screen_timer_sleep(lv_timer_t *timer)
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);
}
@@ -201,31 +247,34 @@ void screen_timer_period(unsigned int 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()
{
PRINTER_CONFIG *config = get_current_printer_config();
lv_disp_t *dispp = lv_disp_get_default();
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);
}
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);
}
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);
}
void lv_setup()
{
set_screen_brightness();
lv_indev_t * display_driver = lv_indev_get_next(NULL);
if (original_touch_driver == NULL)
@@ -240,9 +289,10 @@ void lv_setup()
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
display_driver->driver->read_cb = lv_touch_intercept;
screen_timer_setup();
screen_timer_start();
lv_png_init();
}
bool is_screen_asleep()

View File

@@ -7,4 +7,5 @@ void screen_timer_start();
void screen_timer_stop();
void set_color_scheme();
void lv_setup();
bool is_screen_asleep();
bool is_screen_asleep();
void lv_handler();

View File

@@ -1,28 +1,24 @@
#include "lvgl.h"
#include "macros_query.h"
#include "./data_setup.h"
#include <HTTPClient.h>
#include "../conf/global_config.h"
#include <ArduinoJson.h>
#include <UrlEncode.h>
#include "http_client.h"
static char* macros[64] = {0};
static int macros_count = 0;
static char* power_devices[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";
MACROSQUERY macros_query(PRINTER_CONFIG * config)
{
HTTPClient client;
client.useHTTP10(true);
client.begin(url.c_str());
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
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());
@@ -43,87 +39,132 @@ static void _macros_query_internal(){
macros[macros_count++] = macro;
}
}
return {(const char**)macros, (unsigned int)macros_count};
}
else {
return {NULL, 0};
}
}
void power_devices_clear(){
for (int i = 0; i < power_devices_count; i++){
free(power_devices[i]);
}
power_devices_count = 0;
MACROSQUERY macros_query()
{
return macros_query(get_current_printer_config());
}
void _power_devices_query_internal(){
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/devices";
unsigned int macro_count(PRINTER_CONFIG * config)
{
HTTPClient client;
client.useHTTP10(true);
client.setTimeout(500);
client.setConnectTimeout(1000);
client.begin(url.c_str());
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
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());
}
POWERQUERY power_devices_query(PRINTER_CONFIG * config)
{
HTTPClient client;
configure_http_client(client, get_full_url("/machine/device_power/devices", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"]["devices"].as<JsonArray>();
power_devices_clear();
for (int i = 0; i < stored_power_devices_count; i++){
free(power_devices[i]);
}
stored_power_devices_count = 0;
for (auto i : result){
const char * device_name = i["device"];
const char * device_state = i["status"];
power_devices[power_devices_count] = (char*)malloc(strlen(device_name) + 1);
strcpy(power_devices[power_devices_count], device_name);
power_device_states[power_devices_count] = strcmp(device_state, "on") == 0;
power_devices_count++;
power_devices[stored_power_devices_count] = (char*)malloc(strlen(device_name) + 1);
strcpy(power_devices[stored_power_devices_count], device_name);
power_device_states[stored_power_devices_count] = strcmp(device_state, "on") == 0;
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) {
if (printer.state == PRINTER_STATE_ERROR || printer.state == PRINTER_STATE_PAUSED){
return;
}
_macros_query_internal();
_power_devices_query_internal();
POWERQUERY power_devices_query()
{
return power_devices_query(get_current_printer_config());
}
bool set_power_state(const char* device_name, bool state) {
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off");
unsigned int power_devices_count(PRINTER_CONFIG * config)
{
HTTPClient client;
client.useHTTP10(true);
client.begin(url.c_str());
configure_http_client(client, get_full_url("/machine/device_power/devices", config), true, 1000);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.GET();
if (client.POST("") != 200)
return false;
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"]["devices"].as<JsonArray>();
for (int i = 0; i < power_devices_count; i++){
if (strcmp(power_devices[i], device_name) == 0){
power_device_states[i] = state;
return true;
unsigned int count = 0;
for (auto i : result){
count++;
}
return count;
}
else {
return 0;
}
return true;
}
MACROSQUERY macros_query() {
return {(const char**)macros, (unsigned int)macros_count};
unsigned int power_devices_count()
{
return power_devices_count(get_current_printer_config());
}
POWERQUERY power_devices_query() {
return {(const char**)power_devices, (const bool*)power_device_states, (unsigned int)power_devices_count};
bool set_power_state(const char* device_name, bool state, PRINTER_CONFIG * config)
{
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(){
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL);
on_state_change(NULL, NULL);
bool set_power_state(const char* device_name, bool state)
{
return set_power_state(device_name, state, get_current_printer_config());
}

View File

@@ -1,5 +1,7 @@
#pragma once
#include "../conf/global_config.h"
typedef struct {
const char** macros;
uint32_t count;
@@ -11,9 +13,13 @@ typedef struct {
uint32_t count;
} POWERQUERY;
MACROSQUERY macros_query(PRINTER_CONFIG * config);
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();
void macros_query_setup();
bool set_power_state(const char* device_name, bool state);
void _power_devices_query_internal();
void power_devices_clear();
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);

View File

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

View File

@@ -0,0 +1,138 @@
#include "gcode_img.h"
#include "lvgl.h"
#include "ui_utils.h"
#include <Esp.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_128_128_gcode(const char* filename)
{
if (filename == NULL){
Serial.println("No gcode filename");
return false;
}
SETUP_HTTP_CLIENT("/server/files/thumbnails?filename=" + String(filename));
int httpCode = 0;
try {
httpCode = client.GET();
}
catch (...){
Serial.println("Exception while fetching gcode img location");
return {0};
}
if (httpCode == 200)
{
String payload = client.getString();
JsonDocument doc;
deserializeJson(doc, payload);
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;
}
}
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/" + String(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_128_128_gcode(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_128_128_gcode(const char* filename);
void clear_img_mem();

View File

@@ -6,12 +6,18 @@
#include "ui_utils.h"
#include "../core/macros_query.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 * portEntry;
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 -) */
static const char * kb_map[] = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
@@ -27,8 +33,6 @@ 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
};
void ip_init_inner();
enum connection_status_t {
CONNECT_FAIL = 0,
CONNECT_OK = 1,
@@ -36,19 +40,11 @@ enum connection_status_t {
};
connection_status_t verify_ip(){
HTTPClient client;
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
SETUP_HTTP_CLIENT_FULL("/printer/info", true, 1000);
int httpCode;
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();
Serial.printf("%d %s\n", httpCode, url.c_str());
if (httpCode == 401)
return CONNECT_AUTH_REQUIRED;
@@ -61,7 +57,7 @@ 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_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
@@ -76,21 +72,18 @@ static void ta_event_cb(lv_event_t * e) {
}
else if (code == LV_EVENT_READY)
{
strcpy(global_config.klipperHost, lv_textarea_get_text(hostEntry));
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry));
strcpy(get_current_printer_config()->klipper_host, lv_textarea_get_text(hostEntry));
get_current_printer_config()->klipper_port = atoi(lv_textarea_get_text(portEntry));
connection_status_t status = verify_ip();
if (status == CONNECT_OK)
{
global_config.ipConfigured = true;
WriteGlobalConfig();
connect_ok = true;
get_current_printer_config()->ip_configured = true;
write_global_config();
}
else if (status == CONNECT_AUTH_REQUIRED)
{
label = NULL;
global_config.ipConfigured = true;
WriteGlobalConfig();
show_auth_entry();
}
else
{
@@ -112,66 +105,6 @@ static void ta_event_cb(lv_event_t * e) {
}
}
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) {
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e);
@@ -183,21 +116,29 @@ static void keyboard_event_auth_entry(lv_event_t * e) {
int len = strlen(txt);
if (len > 0)
{
global_config.auth_configured = true;
strcpy(global_config.klipper_auth, txt);
WriteGlobalConfig();
auth_entry_done = true;
get_current_printer_config()->auth_configured = true;
strcpy(get_current_printer_config()->klipper_auth, txt);
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)
{
auth_entry_done = true;
show_ip_entry();
}
}
void handle_auth_entry(){
auth_entry_done = false;
global_config.klipper_auth[32] = 0;
void show_auth_entry()
{
get_current_printer_config()->klipper_auth[32] = 0;
lv_obj_clean(lv_scr_act());
lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
@@ -210,7 +151,7 @@ void handle_auth_entry(){
lv_obj_set_flex_grow(top_root, 1);
lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0);
lv_obj_t * label = lv_label_create(top_root);
label = lv_label_create(top_root);
lv_label_set_text(label, "Enter API Key");
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
@@ -219,8 +160,8 @@ void handle_auth_entry(){
lv_textarea_set_max_length(passEntry, 32);
lv_textarea_set_one_line(passEntry, true);
if (global_config.auth_configured)
lv_textarea_set_text(passEntry, global_config.klipper_auth);
if (get_current_printer_config()->auth_configured)
lv_textarea_set_text(passEntry, get_current_printer_config()->klipper_auth);
else
lv_textarea_set_text(passEntry, "");
@@ -228,25 +169,13 @@ void handle_auth_entry(){
lv_obj_add_event_cb(passEntry, keyboard_event_auth_entry, LV_EVENT_ALL, keyboard);
lv_obj_set_flex_grow(passEntry, 1);
lv_keyboard_set_textarea(keyboard, passEntry);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
while (!auth_entry_done) {
lv_timer_handler();
lv_task_handler();
}
redraw_connect_screen();
}
void ip_init_inner(){
if (global_config.ipConfigured) {
redraw_connect_screen();
return;
}
void show_ip_entry()
{
lv_obj_clean(lv_scr_act());
lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
@@ -283,59 +212,27 @@ void ip_init_inner(){
lv_obj_t * keyboard = lv_keyboard_create(root);
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(portEntry, 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, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
lv_keyboard_set_textarea(keyboard, hostEntry);
}
long last_data_update_ip = -10000;
const long data_update_interval_ip = 10000;
int retry_count = 0;
if (global_config.multi_printer_mode)
{
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(){
connect_ok = false;
retry_count = 0;
int prev_power_device_count = 0;
ip_init_inner();
while (!connect_ok)
if (!get_current_printer_config()->ip_configured)
{
lv_timer_handler();
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)
_power_devices_query_internal();
else
handle_auth_entry();
if (power_devices_query().count != prev_power_device_count) {
prev_power_device_count = power_devices_query().count;
redraw_connect_screen();
}
}
show_ip_entry();
}
}
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);
while (!get_current_printer_config()->ip_configured)
{
lv_handler();
}
}

View File

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

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 "../core/macros_query.h"
#include "../core/lv_setup.h"
char extruder_temp_buff[20];
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);
}
}
#include "switch_printer.h"
#include "macros.h"
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_stop();
}
@@ -105,11 +24,14 @@ void check_if_screen_needs_to_be_disabled(){
static void on_state_change(void * s, lv_msg_t * m){
check_if_screen_needs_to_be_disabled();
if (printer.state == PRINTER_STATE_ERROR){
error_ui();
if (printer.state == PRINTER_STATE_OFFLINE){
nav_buttons_setup(PANEL_CONNECTING);
}
else if (printer.state == PRINTER_STATE_ERROR){
nav_buttons_setup(PANEL_ERROR);
}
else {
nav_buttons_setup(0);
nav_buttons_setup(PANEL_PRINT);
}
}

View File

@@ -4,6 +4,7 @@
#include "nav_buttons.h"
#include "ui_utils.h"
#include <stdio.h>
#include "../conf/global_config.h"
static lv_style_t nav_button_style;
@@ -57,29 +58,47 @@ static void update_printer_data_time(lv_event_t * e){
}
static void btn_click_files(lv_event_t * e){
nav_buttons_setup(0);
nav_buttons_setup(PANEL_PRINT);
}
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){
nav_buttons_setup(2);
nav_buttons_setup(PANEL_TEMP);
}
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){
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){
lv_obj_t* btn = lv_btn_create(root);
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);
#endif
lv_obj_add_style(btn, &nav_button_style, 0);
if (button_click != NULL)
lv_obj_add_event_cb(btn, button_click, LV_EVENT_CLICKED, NULL);
@@ -101,45 +120,78 @@ void nav_buttons_setup(unsigned char active_panel){
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
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_align(root_panel, LV_ALIGN_TOP_LEFT, 0, 0);
lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_START, 0, 0);
// Files/Print
create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel);
#endif
// 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);
if (printer.state > PRINTER_STATE_ERROR){
// Files/Print
create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel);
// Extrude/Temp
create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel);
// 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);
// Extrude/Temp
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
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_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);
switch (active_panel){
case 0:
case PANEL_PRINT:
print_panel_init(panel);
break;
case 1:
case PANEL_MOVE:
move_panel_init(panel);
break;
case 2:
case PANEL_TEMP:
temp_panel_init(panel);
break;
case 3:
case PANEL_SETTINGS:
settings_panel_init(panel);
break;
case 4:
case PANEL_MACROS:
macros_panel_init(panel);
break;
case 5:
case PANEL_STATS:
stats_panel_init(panel);
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;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);

View File

@@ -1,2 +1,14 @@
#pragma once
#define PANEL_PRINT 0
#define PANEL_MOVE 1
#define PANEL_TEMP 2
#define PANEL_SETTINGS 3
#define PANEL_MACROS 4
#define PANEL_STATS 5
#define PANEL_PRINTER 6
#define PANEL_ERROR 7
#define PANEL_CONNECTING 8
void nav_buttons_setup(unsigned char active_panel);
void nav_style_setup();

View File

@@ -85,7 +85,7 @@ void ota_init()
Serial.printf("OTA Update Result: %d\n", result);
update_available = result == ESP32OTAPull::UPDATE_AVAILABLE;
if (global_config.autoOtaUpdate && update_available)
if (global_config.auto_ota_update && update_available)
{
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

@@ -1,90 +1,18 @@
#include "lvgl.h"
#include "../macros.h"
#include "panel.h"
#include "../nav_buttons.h"
#include "../../core/data_setup.h"
#include "../../core/macros_query.h"
#include "../../conf/global_config.h"
#include "../ui_utils.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){
nav_buttons_setup(3);
}
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);
}
nav_buttons_setup(PANEL_SETTINGS);
}
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_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);
@@ -94,21 +22,27 @@ void macros_panel_init(lv_obj_t* panel) {
lv_label_set_text(label, LV_SYMBOL_SETTINGS " Screen Settings");
lv_obj_center(label);
MACROSQUERY query = macros_query();
MACROSQUERY macros = macros_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_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_layout_flex_column(root_panel);
macros_panel_add_power_devices_to_panel(root_panel, power);
macros_panel_add_macros_to_panel(root_panel, query);
macros_add_power_devices_to_panel(root_panel, power);
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 "../ui_utils.h"
#include <stdio.h>
#include <Esp.h>
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) {
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;
move_printer("X", data, true);
}
static void y_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e);
if (move_edit_mode)
{
edit_move_increment(1, data_pointer);
return;
}
float data = *data_pointer;
move_printer("Y", data, true);
}
static void z_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e);
if (move_edit_mode)
{
edit_move_increment(2, data_pointer);
return;
}
float data = *data_pointer;
move_printer("Z", data, true);
}
char x_pos_buff[12];
static void x_pos_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char x_pos_buff[12];
sprintf(x_pos_buff, "X: %.1f", printer.position[0]);
lv_label_set_text(label, x_pos_buff);
}
char y_pos_buff[12];
static void y_pos_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char y_pos_buff[12];
sprintf(y_pos_buff, "Y: %.1f", printer.position[1]);
lv_label_set_text(label, y_pos_buff);
}
char z_pos_buff[12];
static void z_pos_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char z_pos_buff[12];
sprintf(z_pos_buff, "Z: %.2f", printer.position[2]);
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 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) {
if (printer.state == PRINTER_STATE_PRINTING)
return;
@@ -85,14 +178,59 @@ static void disable_steppers_click(lv_event_t * e) {
static void switch_to_stat_panel(lv_event_t * 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){
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_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_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);
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);
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);
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);
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++) {
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_obj_set_width(label, width);
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);
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);
}
}
@@ -155,7 +311,7 @@ inline void root_panel_steppers_locked(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_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);
@@ -192,6 +348,7 @@ void move_panel_init(lv_obj_t* panel){
return;
}
calculate_offsets_from_current_printer();
last_homing_state = !printer.homed_axis;
lv_obj_add_event_cb(panel, root_panel_state_update, LV_EVENT_MSG_RECEIVED, NULL);

View File

@@ -10,4 +10,6 @@ void move_panel_init(lv_obj_t* panel);
void progress_panel_init(lv_obj_t* panel);
void macros_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

@@ -4,9 +4,11 @@
#include "../../core/files_query.h"
#include "../../conf/global_config.h"
#include <HardwareSerial.h>
#include <HTTPClient.h>
#include "../ui_utils.h"
#include "../../core/lv_setup.h"
#include "../gcode_img.h"
#include "../../core/http_client.h"
#include <UrlEncode.h>
FILESYSTEM_FILE* selected_file = NULL;
@@ -14,32 +16,7 @@ static void btn_print_file(lv_event_t * e){
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
lv_obj_del(panel);
char* buff = (char*)malloc(128 + (strlen(selected_file->name) * 3));
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);
SETUP_HTTP_CLIENT("/printer/print/start?filename=" + urlEncode(selected_file->name));
int httpCode = client.POST("");
Serial.printf("Print start: HTTP %d\n", httpCode);
@@ -56,11 +33,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_align(panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "Print File");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t * label_print_file = lv_label_create(panel);
lv_label_set_text(label_print_file, "Print File");
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_obj_align(label, LV_ALIGN_CENTER, 0, -20);
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 10);
@@ -83,6 +60,20 @@ static void btn_print_file_verify(lv_event_t * e){
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_OK);
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){
@@ -91,11 +82,13 @@ void print_panel_init(lv_obj_t* panel){
return;
}
clear_img_mem();
lv_obj_t * list = lv_list_create(panel);
lv_obj_set_style_radius(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_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);
FILESYSTEM_FILE* files = get_files(25);

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));
}
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){
lv_obj_t * label = lv_event_get_target(e);
char percentage_buffer[12];
@@ -52,10 +74,28 @@ void progress_panel_init(lv_obj_t* panel){
const auto button_size_mult = 1.3f;
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_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
lv_obj_t * label = lv_label_create(center_panel);
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_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 "../../core/lv_setup.h"
#include "../ota_setup.h"
#include "../nav_buttons.h"
#ifndef REPO_VERSION
#define REPO_VERSION "Unknown"
@@ -15,50 +16,65 @@
static void invert_color_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.invertColors = checked;
WriteGlobalConfig();
get_current_printer_config()->invert_colors = checked;
write_global_config();
set_invert_display();
}
static void reset_calibration_click(lv_event_t * e){
global_config.screenCalibrated = false;
WriteGlobalConfig();
global_config.screen_calibrated = false;
write_global_config();
ESP.restart();
}
static void reset_click(lv_event_t * e){
ESP.restart();
}
static void reset_wifi_click(lv_event_t * e){
global_config.wifiConfigured = false;
global_config.ipConfigured = false;
global_config.auth_configured = false;
WriteGlobalConfig();
global_config.wifi_configured = false;
write_global_config();
ESP.restart();
}
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();
}
static void light_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);
global_config.lightMode = checked;
WriteGlobalConfig();
get_current_printer_config()->light_mode = checked;
write_global_config();
set_color_scheme();
}
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){
lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown);
global_config.color_scheme = selected;
get_current_printer_config()->color_scheme = selected;
set_color_scheme();
WriteGlobalConfig();
write_global_config();
}
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){
lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown);
global_config.brightness = brightness_options_values[selected];
set_screen_brightness();
WriteGlobalConfig();
write_global_config();
}
const char* wake_timeout_options = "1m\n2m\n5m\n10m\n15m\n30m\n1h\n2h\n4h";
@@ -67,26 +83,34 @@ const char wake_timeout_options_values[] = { 1, 2, 5, 10, 15, 30, 60, 120, 240
static void wake_timeout_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
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();
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 rotate_screen_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.rotateScreen = checked;
global_config.screenCalibrated = false;
WriteGlobalConfig();
global_config.rotate_screen = checked;
global_config.screen_calibrated = false;
write_global_config();
ESP.restart();
}
static void on_during_print_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.onDuringPrint = checked;
global_config.on_during_print = checked;
check_if_screen_needs_to_be_disabled();
WriteGlobalConfig();
write_global_config();
}
static void btn_ota_do_update(lv_event_t * e){
@@ -96,180 +120,127 @@ static void btn_ota_do_update(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));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.autoOtaUpdate = checked;
WriteGlobalConfig();
global_config.auto_ota_update = checked;
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";
static void estimated_time_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
global_config.remaining_time_calc_mode = lv_dropdown_get_selected(dropdown);
WriteGlobalConfig();
get_current_printer_config()->remaining_time_calc_mode = lv_dropdown_get_selected(dropdown);
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} };
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);
#define PRINTER_SPECIFIC_SETTING global_config.multi_printer_mode ? LV_SYMBOL_PLUS " Stored per printer" : NULL
void settings_section_theming(lv_obj_t* panel)
{
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, label_text);
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
lv_label_set_text(label, "Theming");
lv_obj_set_parent(object, panel);
lv_obj_align(object, LV_ALIGN_RIGHT_MID, 0, 0);
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);
if (set_height)
lv_obj_set_height(object, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors, NULL, (global_config.multi_printer_mode) ? LV_SYMBOL_PLUS " 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_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);
lv_create_custom_menu_switch("Light Mode", panel, light_mode_switch, get_current_printer_config()->light_mode, NULL, PRINTER_SPECIFIC_SETTING);
}
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_button("Configure Printer IP", panel, reset_ip_click, "Restart");
}
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
lv_create_custom_menu_switch("Rotate Screen", panel, rotate_screen_switch, global_config.rotate_screen);
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){
lv_obj_t * toggle = NULL;
lv_obj_t * btn = NULL;
lv_obj_t * label = NULL;
lv_obj_t * dropdown = NULL;
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(panel);
lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF);
btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, reset_wifi_click, LV_EVENT_CLICKED, NULL);
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);
}
settings_section_theming(panel);
settings_section_behaviour(panel);
settings_section_device(panel);
}

View File

@@ -225,13 +225,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) {
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_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_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_clear_flag(left_panel, LV_OBJ_FLAG_SCROLLABLE);
create_stat_text_block(left_panel, "Position:", label_pos);
@@ -244,7 +245,7 @@ void stats_panel_init(lv_obj_t* panel) {
create_stat_text_block(left_panel, "Feedrate:", label_feedrate);
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_obj_align(right_panel, LV_ALIGN_TOP_RIGHT, -1 * CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);

View File

@@ -18,7 +18,7 @@ enum temp_target{
static temp_target keyboard_target;
static char hotend_buff[40];
static char bed_buff[40];
static bool edit_mode = false;
static bool temp_edit_mode = false;
lv_obj_t* root_panel;
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){
switch (target){
case TARGET_HOTEND_CONFIG_1:
return global_config.hotend_presets[0];
return get_current_printer_config()->hotend_presets[0];
case TARGET_HOTEND_CONFIG_2:
return global_config.hotend_presets[1];
return get_current_printer_config()->hotend_presets[1];
case TARGET_HOTEND_CONFIG_3:
return global_config.hotend_presets[2];
return get_current_printer_config()->hotend_presets[2];
case TARGET_BED_CONFIG_1:
return global_config.bed_presets[0];
return get_current_printer_config()->bed_presets[0];
case TARGET_BED_CONFIG_2:
return global_config.bed_presets[1];
return get_current_printer_config()->bed_presets[1];
case TARGET_BED_CONFIG_3:
return global_config.bed_presets[2];
return get_current_printer_config()->bed_presets[2];
default:
return -1;
}
@@ -62,97 +62,67 @@ static void update_temp_preset_label(lv_event_t * e){
}
void UpdateConfig(){
WriteGlobalConfig();
write_global_config();
lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer);
}
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 * 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);
if (temp < 0 || temp > 500){
return;
}
int temp = atoi(text);
if (temp < 0 || temp > 500){
return;
}
char gcode[64];
char gcode[64];
switch (keyboard_target){
case TARGET_HOTEND:
sprintf(gcode, "M104 S%d", temp);
send_gcode(true, gcode);
break;
case TARGET_BED:
sprintf(gcode, "M140 S%d", temp);
send_gcode(true, gcode);
break;
case TARGET_HOTEND_CONFIG_1:
global_config.hotend_presets[0] = temp;
UpdateConfig();
break;
case TARGET_HOTEND_CONFIG_2:
global_config.hotend_presets[1] = temp;
UpdateConfig();
break;
case TARGET_HOTEND_CONFIG_3:
global_config.hotend_presets[2] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_1:
global_config.bed_presets[0] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_2:
global_config.bed_presets[1] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_3:
global_config.bed_presets[2] = temp;
UpdateConfig();
break;
}
switch (keyboard_target){
case TARGET_HOTEND:
sprintf(gcode, "M104 S%d", temp);
send_gcode(true, gcode);
break;
case TARGET_BED:
sprintf(gcode, "M140 S%d", temp);
send_gcode(true, gcode);
break;
case TARGET_HOTEND_CONFIG_1:
get_current_printer_config()->hotend_presets[0] = temp;
UpdateConfig();
break;
case TARGET_HOTEND_CONFIG_2:
get_current_printer_config()->hotend_presets[1] = temp;
UpdateConfig();
break;
case TARGET_HOTEND_CONFIG_3:
get_current_printer_config()->hotend_presets[2] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_1:
get_current_printer_config()->bed_presets[0] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_2:
get_current_printer_config()->bed_presets[1] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_3:
get_current_printer_config()->bed_presets[2] = temp;
UpdateConfig();
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){
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){
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){
@@ -177,9 +147,9 @@ 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 value = get_temp_preset(target);
if (edit_mode) {
if (temp_edit_mode) {
keyboard_target = (temp_target)target;
show_keyboard(e);
lv_create_keyboard_text_entry(keyboard_callback, "Set Preset Temp");
return;
}
@@ -195,7 +165,7 @@ static void set_temp_via_preset(lv_event_t * e){
static void btn_toggleable_edit(lv_event_t * e){
lv_obj_t * btn = lv_event_get_target(e);
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){
@@ -255,20 +225,10 @@ static void set_bed_target_temp_chart(lv_event_t * e){
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;
root_panel = panel;
edit_mode = false;
lv_obj_t * root_temp_panel = lv_create_empty_panel(panel);
lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, 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_t * chart = lv_chart_create(root);
lv_obj_set_size(chart, element_width - CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * 3);
lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
lv_chart_set_point_count(chart, 120);
@@ -291,16 +251,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_chart_range, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subscribe_obj(DATA_PRINTER_DATA, chart, NULL);
}
lv_obj_t * single_screen_panel = lv_create_empty_panel(root_temp_panel);
lv_obj_set_size(single_screen_panel, element_width, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2 - CYD_SCREEN_GAP_PX / 2);
lv_layout_flex_column(single_screen_panel);
void create_temp_buttons(lv_obj_t * root, lv_obj_t * 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 * button_temp_rows[2] = {0};
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_obj_set_size(temp_rows[tempIter], element_width, LV_SIZE_CONTENT);
@@ -336,9 +296,40 @@ void temp_panel_init(lv_obj_t * panel){
lv_label_set_text(label, "Set");
lv_obj_center(label);
}
}
lv_obj_t * gap = lv_create_empty_panel(single_screen_panel);
lv_obj_set_flex_grow(gap, 1);
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_set_flex_grow(gap, 1);
#endif
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);

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 "../core/data_setup.h"
#include "../core/lv_setup.h"
#include <ErriezCRC32.h>
lv_obj_t* lv_create_empty_panel(lv_obj_t* root) {
lv_obj_t* panel = lv_obj_create(root);
lv_obj_set_style_border_width(panel, 0, 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_radius(panel, 0, 0);
return panel;
}
@@ -85,4 +87,195 @@ void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t tit
lv_obj_center(label);
}
}
}
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_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
#ifndef CYD_SCREEN_WIDTH_PX
#define CYD_SCREEN_WIDTH_PX LCD_HEIGHT
#endif
#ifdef CYD_SCREEN_VERTICAL
#ifndef CYD_SCREEN_WIDTH_PX
#define CYD_SCREEN_WIDTH_PX LCD_WIDTH
#endif
#ifndef CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_HEIGHT_PX LCD_WIDTH
#endif
#ifndef CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_HEIGHT_PX LCD_HEIGHT
#endif
#define CYD_SCREEN_PANEL_WIDTH_PX \
(CYD_SCREEN_WIDTH_PX - CYD_SCREEN_SIDEBAR_SIZE_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)
#endif
typedef struct {
lv_event_cb_t event;
@@ -22,4 +37,12 @@ lv_obj_t* lv_create_empty_panel(lv_obj_t* root);
void lv_layout_flex_column(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 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,95 +3,124 @@
#include "../conf/global_config.h"
#include "ui_utils.h"
#include "WiFi.h"
#include "../core/data_setup.h"
#include "../core/lv_setup.h"
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) {
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
global_config.wifiConfigured = false;
wifi_init_inner();
}
global_config.wifi_configured = false;
wifi_init_inner();
}
static void refresh_btn_event_handler(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);
static void keyboard_cb_enter_password(lv_event_t * e) {
lv_obj_t * ta = lv_event_get_target(e);
if (code == LV_EVENT_READY)
{
const char * txt = lv_textarea_get_text(ta);
int len = strlen(txt);
if (len > 0)
{
global_config.wifiConfigured = true;
strcpy(global_config.wifiPassword, txt);
WriteGlobalConfig();
wifi_init_inner();
}
}
else if (code == LV_EVENT_CANCEL)
{
wifi_init_inner();
}
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
const char * txt = lv_textarea_get_text(ta);
global_config.wifi_configured = true;
strcpy(global_config.wifi_SSID, current_ssid_ptr);
strcpy(global_config.wifi_password, txt);
write_global_config();
wifi_init_inner();
}
void wifi_pass_entry(const char* ssid){
lv_obj_clean(lv_scr_act());
static void btn_reuse_password(lv_event_t * e)
{
ESP.restart();
}
lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(root);
static void btn_no_reuse_password(lv_event_t * e)
{
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);
lv_obj_set_width(top_root, CYD_SCREEN_WIDTH_PX);
lv_layout_flex_column(top_root);
lv_obj_set_flex_grow(top_root, 1);
lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0);
void ask_reuse_password(const char * ssid){
lv_obj_t * root = lv_obj_create(lv_scr_act());
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_align(root, LV_ALIGN_CENTER, 0, 0);
lv_layout_flex_column(root, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_t * label = lv_label_create(top_root);
lv_label_set_text(label, "Enter WiFi Password");
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_t * label = lv_label_create(root);
lv_label_set_text_fmt(label, "Reuse stored WiFi Password?\n(Password Length: %d)", strlen(global_config.wifi_password));
lv_obj_t * passEntry = lv_textarea_create(top_root);
lv_textarea_set_one_line(passEntry, true);
lv_textarea_set_text(passEntry, "");
lv_obj_set_width(passEntry, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_add_event_cb(passEntry, ta_event_cb, LV_EVENT_ALL, NULL);
lv_obj_set_flex_grow(passEntry, 1);
lv_obj_t * button_row = lv_create_empty_panel(root);
lv_layout_flex_row(button_row, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_set_size(button_row, lv_pct(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * keyboard = lv_keyboard_create(root);
lv_keyboard_set_textarea(keyboard, passEntry);
lv_obj_t * no_btn = lv_btn_create(button_row);
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){
lv_event_code_t code = lv_event_get_code(e);
delay(100);
char* ssid = (char*)e->user_data;
Serial.println(ssid);
wifi_pass_entry(ssid);
}
if(code == LV_EVENT_CLICKED) {
delay(100);
char* ssid = (char*)e->user_data;
strcpy(global_config.wifiSSID, ssid);
Serial.println(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(){
WiFi.disconnect();
lv_obj_clean(lv_scr_act());
if (global_config.wifiConfigured){
WiFi.begin(global_config.wifiSSID, global_config.wifiPassword);
if (global_config.wifi_configured){
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_label_set_text(label, "Connecting to WiFi");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
@@ -125,16 +154,25 @@ void wifi_init_inner(){
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_layout_flex_row(top_row, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_layout_flex_row(top_row);
label = lv_label_create(top_row);
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_add_event_cb(refreshBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL);
lv_obj_set_size(refreshBtn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * btn = lv_btn_create(top_row);
lv_obj_add_event_cb(btn, wifi_btn_manual_ssid, 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(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_obj_center(label);
@@ -159,7 +197,7 @@ void wifi_init_inner(){
ssid_copy[j] = '\0';
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_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){
print_timer = millis();
Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]);
}
lv_timer_handler();
lv_task_handler();
lv_handler();
}
}
ulong start_time_recovery = 0;
void wifi_ok(){
if (WiFi.status() != WL_CONNECTED){
ESP.restart();
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();
}
}
unfreeze_request_thread();
}
}

View File

@@ -24,7 +24,11 @@
}
.main a {
color: #F00;
color: #F44;
}
.install {
margin-bottom: 300px;
}
.install .iconify {
@@ -46,13 +50,22 @@
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();
window.onload = setInstallButtonDefault;
</script>
</head>
<body>
<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>
<section class="changelog">
@@ -64,18 +77,25 @@
<h3><span class="iconify" data-icon="mdi-heart" style="color:orangered; filter: drop-shadow(0 0 0.75rem crimson);"></span> Donate</h3>
<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 class="install">
<h3><span class="iconify" data-icon="mdi-download"></span> Install on ESP32-2432S028 (2.8" Resistive)</h3>
<p>Note: You may need to hold the 'BOOT' button on the device while pressing install.</p>
<esp-web-install-button
manifest="https://suchmememanyskill.github.io/CYD-Klipper/esp32-2432S028R.json"></esp-web-install-button>
<section class="issues">
<h3><span class="iconify" data-icon="mdi-github" style="color: white; filter: drop-shadow(0 0 0.75rem gray);"></span> Report Issues</h3>
<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>
</section>
<section class="install">
<h3><span class="iconify" data-icon="mdi-download"></span> Install on ESP32-3248S035 (3.5" Capacitive)</h3>
<p>Note: You may need to hold the 'BOOT' button on the device while pressing install.</p>
<esp-web-install-button
manifest="https://suchmememanyskill.github.io/CYD-Klipper/esp32-3248S035C.json"></esp-web-install-button>
<h3><span class="iconify" data-icon="mdi-download"></span> Install</h3>
<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>
<select id="select-install-btn" onchange="setInstallButton(getElementById('select-install-btn').value)">
<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>
</body>

10
ci.py
View File

@@ -1,6 +1,14 @@
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"
]
BASE_DIR = os.getcwd()
def get_manifest(base_path : str, device_name : str):

BIN
readme/cmd.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB