31 Commits

Author SHA1 Message Date
suchmememanyskill
c8e34598ca Merge branch 'master' of https://github.com/suchmememanyskill/CYD-Klipper-Display 2025-09-30 00:19:48 +02:00
suchmememanyskill
77086b8ecf update virtual printer 2025-09-30 00:19:41 +02:00
Sims
93f3935480 Fix #178 2025-08-19 00:51:29 +02:00
suchmememanyskill
3e23ba935d Merge branch 'dev' 2025-08-18 23:29:01 +02:00
Stefan Naewe
07d5f95b00 use correct spelling for WiFiClientSecure.h (#202)
It's "WiFiClient..." and not "WifiClient..."

Signed-off-by: Stefan Naewe <stefan.naewe@gmail.com>
2025-08-10 14:14:53 +02:00
suchmememanyskill
19fb87d0bb Add support for esp32-JC3248W535C 2025-07-10 14:55:16 +02:00
suchmememanyskill
d126697cb0 Better CI pipeline 2025-07-10 00:45:25 +02:00
suchmememanyskill
63a0ca5233 Fix bad code 2025-07-09 23:55:50 +02:00
suchmememanyskill
c929b5e270 Merge main 2025-07-09 23:49:04 +02:00
Dylan Pryke-Watanabe
b6c2b505e0 Add support for JC3248W535C (Guition 3.5" ESP32-S3 Display) (#189)
* Guition Display outputs to screen

* Fix Display Flushing and Touch Screen works now!

* fix UI rotations

* set default orientation to 2

* Start trying to implement horizontal software rotation

* remove -w flag

* cleanup

* Rename to JC3248W535C

* Update lv_conf.h

* replace URL
2025-07-09 23:44:27 +02:00
Madrajib Lab
40932518ae serial_console: Add support to handle delete/arrow keys (#195)
This change adds support to serial console to handle delete
left & right arrow and backspace key by changing
result buffer based on the keypress and emulating the movement
with espace characters in the terminal.

This patch also takes care of buffer flow handling by checking
the cur and index with the max available length for each operations.
2025-07-09 23:42:57 +02:00
Madrajib Lab
266b5d76b1 lvgl API: use lv_obj_has_state to check state value (#198) 2025-07-09 23:42:29 +02:00
Madrajib Lab
4067f94407 platfromio: Update LovyanGFX from 1.2.0 to 1.2.7 (#196) 2025-07-09 23:41:46 +02:00
Evgeny Kapusta
5b7770246e feat: add Guition JC8048W550 display support (#185)
* Update readme

* Update README.md

* Add aliexpress links

* feat: add Guition JC8048W550 display support

* feat: adjust configuration for board

* feat: add option for jc8048w550 on page and in ci script

* fix: missing CYD_PORTS entry

---------

Co-authored-by: Sims <38142618+suchmememanyskill@users.noreply.github.com>
2025-05-02 23:42:06 +02:00
suchmememanyskill
04a3b78b21 Add crowpanel 3.5 inch to html 2025-02-09 02:37:37 +01:00
Sims
7c564e8ab8 Merge pull request #166 from suchmememanyskill/dev
Hopefully fix webflash for s3
2025-02-09 01:57:02 +01:00
suchmememanyskill
5c0ee08135 Hopefully fix webflash for s3 2025-02-09 01:14:07 +01:00
Sims
e6b5d17f6a Merge pull request #164 from suchmememanyskill/dev
v2.1.0
2025-02-01 19:39:18 +01:00
suchmememanyskill
d8a9b13fe1 Fix compile 2025-02-01 17:37:06 +01:00
suchmememanyskill
fbc2964ad8 Make serial script work with both sudo and not sudo 2025-02-01 17:20:06 +01:00
suchmememanyskill
d616ef5a6d Allow running service under root 2025-01-28 21:50:21 +01:00
suchmememanyskill
9bfbb1cb0e Change keyboard for bambu setup (#161) 2025-01-28 21:23:02 +01:00
suchmememanyskill
8d8e36fde9 Merge #152 2025-01-28 21:20:22 +01:00
Kire Dyfvelsten
4e3cd69b63 Sunton esp32 2.2" c (#151)
* Update readme

* Update README.md

* driver definition? for a vertical 2.2" with touch

* Update platformio.ini

* Update esp32-2432S022C-vertical.json

* Update esp32-2432S022C-vertical.json

---------

Co-authored-by: Sims <38142618+suchmememanyskill@users.noreply.github.com>
2025-01-28 21:19:36 +01:00
Sims
3aeb67cfdd esp32-CROWPANEL-35C (#159)
* :)

* Correct screen rotation

* Remove brightness adjustment

* Silence buzzer

* Fixes from atomique
2025-01-28 21:16:46 +01:00
suchmememanyskill
8f46b9972d Add aliexpress links 2025-01-15 22:18:36 +01:00
Sims
5756b31744 Update README.md 2025-01-10 18:15:56 +01:00
suchmememanyskill
99b70622fe Update readme 2025-01-09 23:14:15 +01:00
Sims
b3d405b355 Merge pull request #139 from suchmememanyskill/dev
v2.0.0 - Happy new year!
2025-01-09 23:05:35 +01:00
Sims
9a96f9336f Merge pull request #125 from suchmememanyskill/dev
v1.8.0
2024-08-31 11:49:48 +02:00
Sims
5c46764c7c Merge pull request #122 from suchmememanyskill/dev
v1.7.0
2024-08-02 21:39:42 +02:00
27 changed files with 1524 additions and 146 deletions

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -31,9 +31,9 @@ jobs:
# ~/.platformio/.cache
# key: ${{ runner.os }}-pio-cyd-klipper
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.13'
- name: Install PlatformIO Core
run: pip install --upgrade platformio esptool
@@ -43,13 +43,13 @@ jobs:
python3 ci.py
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: firmware
path: ./out
- name: Upload GitHub Page Artifact
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
deploy:
environment:
@@ -65,5 +65,5 @@ jobs:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4

View File

@@ -48,7 +48,8 @@
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
"typeinfo": "cpp",
"*.tpp": "cpp"
},
"cmake.configureOnOpen": false
}

View File

@@ -0,0 +1,127 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S022C'",
"'-D LCD_WIDTH=240'",
"'-D LCD_HEIGHT=320'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D 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'",
"'-D ST7789_I80_BUS_CONFIG_WR=4'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D8=15'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D9=13'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D10=12'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D11=14'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D12=27'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D13=25'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D14=33'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D15=32'",
"'-D ST7789_I80_BUS_CONFIG_BUS_WIDTH=8'",
"'-D ST7789_I80_BUS_CONFIG_MAX_TRANSFER_BYTES=(LVGL_BUFFER_PIXELS * sizeof(lv_color_t))'",
"'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'",
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=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'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_IDLE_LEVEL=0'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_CMD_LEVEL=0'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DUMMY_LEVEL=0'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DATA_LEVEL=1'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_CS_ACTIVE_HIGH=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_REVERSE_COLOR_BITS=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_SWAP_COLOR_BYTES=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=0'",
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_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 ST7789_RD_GPIO=2'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=false'",
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_CST816S_I2C'",
"'-D CST816S_I2C_HOST=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'",
"'-D CST816S_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'",
"'-D CST816S_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D CST816S_I2C_CONFIG_CLK_FLAGS=0'",
"'-D CST816S_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS'",
"'-D CST816S_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D CST816S_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D CST816S_IO_I2C_CONFIG_LCD_CMD_BITS=8'",
"'-D CST816S_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D CST816S_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D CST816S_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D CST816S_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=GPIO_NUM_NC'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=false'",
"'-D TOUCH_SWAP_X=false'",
"'-D TOUCH_SWAP_Y=false'",
"'-D BOARD_HAS_TF'",
"'-D TF_CS=5'",
"'-D TF_SPI_MOSI=23'",
"'-D TF_SPI_SCLK=18'",
"'-D TF_SPI_MISO=19'",
"'-D BOARD_HAS_SPEAK'",
"'-D SPEAK=26'",
"-DCYD_SCREEN_GAP_PX=8",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
"-DCYD_SCREEN_VERTICAL=1",
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-2432S022C-V",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005006284154750.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,55 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DCYD_SCREEN_HEIGHT_PX=320",
"-DCYD_SCREEN_WIDTH_PX=480",
"-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_CROWPANEL_35C=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.elecrow.com/esp-terminal-with-esp32-3-5-inch-parallel-480x320-tft-capacitive-touch-display-rgb-by-chip-ili9488.html",
"vendor": "CROWPANEL"
}

View File

@@ -0,0 +1,69 @@
{
"name": "ESP32-JC3248W535C",
"url": "https://www.aliexpress.com/item/1005007566315926.html",
"vendor": "Guition",
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"mcu": "esp32s3",
"variant": "esp32s3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"extra_flags": [
"-DLCD_WIDTH=320",
"-DLCD_HEIGHT=480",
"-DCYD_SCREEN_GAP_PX=8",
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
"-DCYD_SCREEN_WIDTH_PX=LCD_WIDTH",
"-DCYD_SCREEN_HEIGHT_PX=LCD_HEIGHT",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-DLCD_CS=45",
"-DLCD_CLK=47",
"-DLCD_D0=21",
"-DLCD_D1=48",
"-DLCD_D2=40",
"-DLCD_D3=39",
"-DLCD_RST=-1",
"-DLCD_DC=8",
"-DTOUCH_SDA=4",
"-DTOUCH_SCL=8",
"-DTOUCH_ADDR=0x3B",
"-DLCD_BL_PIN=1",
"-DCYD_BOARD_JC3248W535C",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION",
"-DUSER_SETUP_LOADED",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DCYD_SCREEN_VERTICAL=1"
],
"flash_mode": "qio",
"hwids": [
[
"0X303A",
"0x1001"
]
]
},
"upload": {
"flash_size": "16MB",
"flash_mode": "qio",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"frameworks": ["arduino", "espidf"],
"connectivity": ["wifi", "bluetooth"]
}

View File

@@ -0,0 +1,66 @@
{
"name": "ESP32-JC4827W543C",
"url": "https://s.click.aliexpress.com/e/_oEcVE26",
"vendor": "Guition",
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"mcu": "esp32s3",
"variant": "esp32s3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DLCD_WIDTH=480",
"-DLCD_HEIGHT=270",
"-DCYD_SCREEN_GAP_PX=8",
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
"-DCYD_SCREEN_WIDTH_PX=480",
"-DCYD_SCREEN_HEIGHT_PX=272",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-DLCD_CS=45",
"-DLCD_CLK=47",
"-DLCD_D0=21",
"-DLCD_D1=48",
"-DLCD_D2=40",
"-DLCD_D3=39",
"-DLCD_RST=-1",
"-DLCD_DC=8",
"-DLCD_BL_PIN=1",
"-DCYD_BOARD_JC4827W543C",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION",
"-DUSER_SETUP_LOADED",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DCYD_S3"
],
"flash_mode": "qio",
"hwids": [
[
"0X303A",
"0x1001"
]
]
},
"upload": {
"flash_size": "4MB",
"flash_mode": "qio",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"frameworks": ["arduino", "espidf"],
"connectivity": ["wifi", "bluetooth"]
}

View File

@@ -0,0 +1,142 @@
{
"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 JC8048W550'",
"'-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=(14.2*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=LCD_HEIGHT",
"-DCYD_SCREEN_WIDTH_PX=LCD_WIDTH",
"-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=0",
"-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-JC8048W550",
"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/1005006715581887.html",
"vendor": "Guition"
}

View File

@@ -84,7 +84,7 @@ board = esp32-3248S035C-smartdisplay
board = esp32-4827S043C-smartdisplay
[env:esp32-4827S043R-SD]
board = esp32-4827S043C-smartdisplay
board = esp32-4827S043R-smartdisplay
[env:esp32-8048S043C-SD]
board = esp32-8048S043C-smartdisplay
@@ -92,6 +92,9 @@ board = esp32-8048S043C-smartdisplay
[env:esp32-8048S043C-SD-alt]
board = esp32-8048S043C-smartdisplay-alt
[env:esp32-2432S022C-SD-V]
board = esp32-2432S022C-vertical
[env:esp32-CROWPANEL-28R]
board = esp32-CROWPANEL-28R
lib_deps =
@@ -102,3 +105,40 @@ lib_deps =
plageoj/UrlEncode@^1.0.1
knolleary/PubSubClient@^2.8
WiFiClientSecure
[env:esp32-CROWPANEL-35C]
board = esp32-CROWPANEL-35C
lib_deps =
SPI
https://github.com/suchmememanyskill/lvgl
https://github.com/lovyan03/LovyanGFX@1.2.7
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
knolleary/PubSubClient@^2.8
WiFiClientSecure
[env:esp32-JC8048W550]
board = esp32-JC8048W550
[env:ESP32-JC3248W535C]
board = esp32-JC3248W535C
lib_deps =
SPI
moononournation/GFX Library for Arduino
lvgl/lvgl@^8.4.0
plageoj/UrlEncode
bblanchon/ArduinoJson@^7.0.0
knolleary/PubSubClient@^2.8
WiFiClientSecure
[env:esp32-JC4827W543C]
board = esp32-JC4827W543C
lib_deps =
SPI
https://github.com/moononournation/Arduino_GFX#v1.4.9
https://github.com/mmMicky/TouchLib#ccaedcd9155ef8a6560ae9f594ea92e32c68020f
lvgl/lvgl@^8.4.0
plageoj/UrlEncode
bblanchon/ArduinoJson@^7.0.0
knolleary/PubSubClient@^2.8
WiFiClientSecure

View File

@@ -2,7 +2,7 @@
#include "../printer_integration.hpp"
#include <ArduinoJson.h>
#include <WifiClientSecure.h>
#include <WiFiClientSecure.h>
enum BambuSpeedProfile
{

View File

@@ -161,7 +161,7 @@ struct
};
} __internal_bambu_file_state = {};
#define SET_BOOL_STATE(bool_name, func_name) static void func_name (lv_event_t * e) { auto state = lv_obj_get_state(lv_event_get_target(e)); bool_name = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); }
#define SET_BOOL_STATE(bool_name, func_name) static void func_name (lv_event_t * e) { bool_name = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED); }
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_use_ams, set_bambu_option_use_ams)
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_timelapse, set_bambu_option_timelapse)

View File

@@ -0,0 +1,183 @@
// Adapted from https://github.com/OzInFl/Elecrow-3.5-RGB-TFT-SQUARELINE-EXAMPLE
#ifdef CYD_SCREEN_DRIVER_ESP32_CROWPANEL_35C
#include "../screen_driver.h"
#include "lvgl.h"
#include "../../conf/global_config.h"
#include <LovyanGFX.hpp>
#include <Arduino.h>
#include <Wire.h>
#ifdef CYD_SCREEN_VERTICAL
#error "Vertical screen not supported with the ESP32_CROWPANEL_28R driver"
#endif
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
#define BUZZER_PIN 20
#define LCD_BL 46
#define SDA_FT6236 38
#define SCL_FT6236 39
#define I2C_TOUCH_ADDR 0x38
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ILI9488 _panel_instance;
lgfx::Bus_Parallel16 _bus_instance;
lgfx::Touch_FT5x06 _touch_instance;
public:
LGFX()
{
auto bus_cfg = _bus_instance.config();
bus_cfg.port = 0;
bus_cfg.freq_write = 80000000;
bus_cfg.pin_wr = 18;
bus_cfg.pin_rd = 48;
bus_cfg.pin_rs = 45;
bus_cfg.pin_d0 = 47;
bus_cfg.pin_d1 = 21;
bus_cfg.pin_d2 = 14;
bus_cfg.pin_d3 = 13;
bus_cfg.pin_d4 = 12;
bus_cfg.pin_d5 = 11;
bus_cfg.pin_d6 = 10;
bus_cfg.pin_d7 = 9;
bus_cfg.pin_d8 = 3;
bus_cfg.pin_d9 = 8;
bus_cfg.pin_d10 = 16;
bus_cfg.pin_d11 = 15;
bus_cfg.pin_d12 = 7;
bus_cfg.pin_d13 = 6;
bus_cfg.pin_d14 = 5;
bus_cfg.pin_d15 = 4;
_bus_instance.config(bus_cfg);
_panel_instance.setBus(&_bus_instance);
auto panel_cfg = _panel_instance.config();
panel_cfg.pin_cs = -1;
panel_cfg.pin_rst = -1;
panel_cfg.pin_busy = -1;
panel_cfg.memory_width = 320;
panel_cfg.memory_height = 480;
panel_cfg.panel_width = 320;
panel_cfg.panel_height = 480;
panel_cfg.offset_x = 0;
panel_cfg.offset_y = 0;
panel_cfg.offset_rotation = 0;
panel_cfg.dummy_read_pixel = 8;
panel_cfg.dummy_read_bits = 1;
panel_cfg.readable = true;
panel_cfg.invert = global_config.printer_config[global_config.printer_index].invert_colors ? true : false;
panel_cfg.rgb_order = false;
panel_cfg.dlen_16bit = true;
panel_cfg.bus_shared = true;
_panel_instance.config(panel_cfg);
auto touch_cfg = _touch_instance.config();
touch_cfg.x_min = 0;
touch_cfg.x_max = 319;
touch_cfg.y_min = 0;
touch_cfg.y_max = 479;
touch_cfg.pin_int = -1;
touch_cfg.bus_shared = false;
touch_cfg.offset_rotation = 0;
touch_cfg.i2c_port = 1;
touch_cfg.i2c_addr = 0x38;
touch_cfg.pin_sda = 38;
touch_cfg.pin_scl = 39;
touch_cfg.freq = 400000;
_touch_instance.config(touch_cfg);
_panel_instance.setTouch(&_touch_instance);
setPanel(&_panel_instance);
}
};
LGFX tft;
void screen_setBrightness(unsigned char brightness)
{
// TODO
}
void set_invert_display()
{
// TODO
}
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);
tft.endWrite();
lv_disp_flush_ready(disp);
}
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY);
if (touchX > CYD_SCREEN_WIDTH_PX || touchY > CYD_SCREEN_HEIGHT_PX)
{
LOG_LN("Y or y outside of expected parameters..");
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
data->point.x = touchX;
data->point.y = touchY;
}
}
void screen_setup()
{
pinMode(BUZZER_PIN, OUTPUT);
ledcSetup(4, 5000, 8);
ledcAttachPin(BUZZER_PIN, 4);
tft.begin();
tft.setRotation(global_config.rotate_screen ? 3 : 1);
delay(500);
pinMode(LCD_BL, OUTPUT);
digitalWrite(LCD_BL, HIGH);
/*
ledcSetup(0, 5000, 12);
ledcAttachPin(LCD_BL, 0);
*/
lv_init();
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_WIDTH_PX * CYD_SCREEN_HEIGHT_PX / 10);
/*Initialize the display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = screen_lv_touchRead;
lv_indev_drv_register(&indev_drv);
}
#endif

View File

@@ -0,0 +1,184 @@
#ifdef CYD_BOARD_JC3248W535C
#include "../screen_driver.h"
#include <databus/Arduino_ESP32QSPI.h>
#include <display/Arduino_AXS15231B.h>
#include <canvas/Arduino_Canvas.h>
#include "lvgl.h"
#include "../lv_setup.h"
#include "../../conf/global_config.h"
#include <Wire.h>
#define CPU_FREQ_HIGH 240
#define CPU_FREQ_LOW 80
struct TouchPoint {
uint8_t gesture;
uint8_t num;
uint8_t x_h : 4;
uint8_t _pad1 : 2;
uint8_t event : 2;
uint8_t x_l;
uint8_t y_h : 4;
uint8_t _pad2 : 4;
uint8_t y_l;
} __attribute__((packed));
static Arduino_ESP32QSPI qspiBus(
LCD_CS, LCD_CLK,
LCD_D0, LCD_D1,
LCD_D2, LCD_D3,
false);
Arduino_GFX *gfx = new Arduino_AXS15231B(
&qspiBus, -1, 2, true,
LCD_WIDTH, LCD_HEIGHT,
0, 0, 0, 0);
#ifdef CYD_SCREEN_VERTICAL
static bool horizontal = false;
static Arduino_Canvas canvas(CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX, gfx, 0, 0);
#else
static bool horizontal = true;
static Arduino_Canvas canvas(CYD_SCREEN_HEIGHT_PX, CYD_SCREEN_WIDTH_PX, gfx, 0, 0);
#endif
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *buf = nullptr;
static lv_disp_t *main_disp = nullptr;
void screen_setBrightness(uint8_t brightness)
{
uint32_t duty = (4095UL * brightness) / 255UL;
ledcWrite(0, duty);
}
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
int x = area->x1;
int y = area->y1;
int w = area->x2 - area->x1 + 1;
int h = area->y2 - area->y1 + 1;
canvas.draw16bitRGBBitmap(x, y, (uint16_t *)color_p, w, h);
canvas.flush();
lv_disp_flush_ready(disp);
}
// Reads 1 touch point from AXS15231B controller at I2C addr 0x3B
bool read_touch(uint16_t &x, uint16_t &y) {
const uint8_t addr = 0x3B;
const uint8_t read_cmd[11] = {
0xB5, 0xAB, 0xA5, 0x5A, 0x00, 0x00,
0x00, 8, // length of expected reply (MSB, LSB)
0x00, 0x00, 0x00
};
Wire.beginTransmission(addr);
Wire.write(read_cmd, sizeof(read_cmd));
if (Wire.endTransmission(false) != 0) {
return false;
}
uint8_t data[8] = {0};
if (Wire.requestFrom(addr, (uint8_t)sizeof(data)) != sizeof(data)) {
return false;
}
for (uint8_t i = 0; i < sizeof(data); i++) {
data[i] = Wire.read();
}
TouchPoint *p = (TouchPoint *)data;
if (p->num > 0 && p->num <= 2) {
x = ((p->x_h & 0x0F) << 8) | p->x_l;
y = ((p->y_h & 0x0F) << 8) | p->y_l;
// Clamp to screen bounds
if (x >= CYD_SCREEN_WIDTH_PX) x = CYD_SCREEN_WIDTH_PX - 1;
if (y >= CYD_SCREEN_HEIGHT_PX) y = CYD_SCREEN_HEIGHT_PX - 1;
return true;
}
return false;
}
void screen_lv_touchRead(lv_indev_drv_t * /*indev_driver*/, lv_indev_data_t *data)
{
uint16_t x, y;
if (read_touch(x, y)) {
x = min(x, uint16_t(CYD_SCREEN_WIDTH_PX - 1));
y = min(y, uint16_t(CYD_SCREEN_HEIGHT_PX - 1));
// Adjust coordinates based on screen rotation
if (global_config.rotate_screen) {
// Assuming rotation = 2 (180 degrees)
x = CYD_SCREEN_WIDTH_PX - x;
y = CYD_SCREEN_HEIGHT_PX - y;
}
data->state = LV_INDEV_STATE_PR;
data->point.x = x;
data->point.y = y;
} else {
data->state = LV_INDEV_STATE_REL;
}
}
void set_invert_display()
{
gfx->invertDisplay(global_config.printer_config[global_config.printer_index].invert_colors);
}
void screen_setup()
{
pinMode(LCD_BL_PIN, OUTPUT);
ledcSetup(0, 5000, 12);
ledcAttachPin(LCD_BL_PIN, 0);
screen_setBrightness(255);
// gfx->begin();
canvas.begin();
gfx->invertDisplay(true); // OK after begin()
gfx->setRotation(global_config.rotate_screen ? 2 : 0);
canvas.fillScreen(0x0000);
canvas.flush();
Wire.begin(TOUCH_SDA, TOUCH_SCL);
lv_init();
// Allocate full canvas buffer for LVGL
buf = (lv_color_t *)heap_caps_malloc(
CYD_SCREEN_WIDTH_PX * CYD_SCREEN_HEIGHT_PX * sizeof(lv_color_t),
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
assert(buf);
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_WIDTH_PX * CYD_SCREEN_HEIGHT_PX);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf;
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
if(horizontal){
main_disp = lv_disp_drv_register(&disp_drv);
lv_disp_set_rotation(main_disp, LV_DISP_ROT_90);
} else {
lv_disp_drv_register(&disp_drv);
}
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = screen_lv_touchRead;
lv_indev_drv_register(&indev_drv);
}
#endif // CYD_BOARD_JC3248W535C

View File

@@ -0,0 +1,85 @@
#ifdef CYD_BOARD_JC4827W543C
#include "../screen_driver.h"
#include <Arduino_GFX_Library.h>
#include "lvgl.h"
#include "../lv_setup.h"
#include "../../conf/global_config.h"
#include "ESP32-JC4827W543C_touch.h"
#define CPU_FREQ_HIGH 240
#define CPU_FREQ_LOW 80
Arduino_DataBus *bus = new Arduino_ESP32QSPI(LCD_CS, LCD_CLK, LCD_D0, LCD_D1, LCD_D2, LCD_D3);
Arduino_NV3041A *panel = new Arduino_NV3041A(bus, LCD_RST, 0, true);
static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv;
static lv_color_t disp_draw_buf[LCD_WIDTH * 48];
void screen_setBrightness(uint8_t brightness)
{
uint32_t duty = 4095 * brightness / 255;
ledcWrite(0, duty);
}
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
panel->startWrite();
panel->setAddrWindow(area->x1, area->y1, w, h);
panel->writePixels((uint16_t *)&color_p->full, w * h);
panel->endWrite();
lv_disp_flush_ready(disp);
}
void IRAM_ATTR screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
if (touch_has_signal() && touch_touched())
{
data->state = LV_INDEV_STATE_PR;
data->point.x = touch_last_x;
data->point.y = touch_last_y;
}
else
{
data->state = LV_INDEV_STATE_REL;
}
}
void set_invert_display()
{
panel->invertDisplay(global_config.printer_config[global_config.printer_index].invert_colors);
}
void screen_setup()
{
pinMode(LCD_BL_PIN, OUTPUT);
ledcSetup(0, 5000, 12);
ledcAttachPin(LCD_BL_PIN, 0);
screen_setBrightness(128);
panel->begin();
panel->setRotation(global_config.rotate_screen ? 2 : 0);
touch_init(panel->width(), panel->height(), panel->getRotation());
lv_init();
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, LCD_WIDTH * 48);
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf;
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
lv_disp_drv_register(&disp_drv);
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = screen_lv_touchRead;
lv_indev_drv_register(&indev_drv);
}
#endif // CYD_BOARD_JC4827W543C

View File

@@ -0,0 +1,196 @@
/*******************************************************************************
*
* TouchLib https://github.com/mmMicky/TouchLib
Add Library from ZIP: TouchLib-main.zip
*
* Touch libraries:
* XPT2046: https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
*
* Capacitive touchscreen libraries
* TouchLib: https://github.com/mmMicky/TouchLib.git
******************************************************************************/
/* uncomment for XPT2046 */
// #define TOUCH_XPT2046
// #define TOUCH_XPT2046_SCK 12
// #define TOUCH_XPT2046_MISO 13
// #define TOUCH_XPT2046_MOSI 11
// #define TOUCH_XPT2046_CS 38
// #define TOUCH_XPT2046_INT 3
// #define TOUCH_XPT2046_ROTATION 0
// #define TOUCH_XPT2046_SAMPLES 50
//uncomment for most capacitive touchscreen
#define TOUCH_MODULES_GT911 // GT911 / CST_SELF / CST_MUTUAL / ZTW622 / L58 / FT3267 / FT5x06
#define TOUCH_MODULE_ADDR GT911_SLAVE_ADDRESS1 // CTS328_SLAVE_ADDRESS / L58_SLAVE_ADDRESS / CTS826_SLAVE_ADDRESS / CTS820_SLAVE_ADDRESS / CTS816S_SLAVE_ADDRESS / FT3267_SLAVE_ADDRESS / FT5x06_ADDR / GT911_SLAVE_ADDRESS1 / GT911_SLAVE_ADDRESS2 / ZTW622_SLAVE1_ADDRESS / ZTW622_SLAVE2_ADDRESS
#define TOUCH_SCL 4
#define TOUCH_SDA 8
#define TOUCH_RES 38
#define TOUCH_INT 3
// Please fill below values from Arduino_GFX Example - TouchCalibration
bool touch_swap_xy = false;
int16_t touch_map_x1 = -1;
int16_t touch_map_x2 = -1;
int16_t touch_map_y1 = -1;
int16_t touch_map_y2 = -1;
int16_t touch_max_x = 0, touch_max_y = 0;
int16_t touch_raw_x = 0, touch_raw_y = 0;
int16_t touch_last_x = 0, touch_last_y = 0;
#if defined(TOUCH_XPT2046)
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
XPT2046_Touchscreen ts(TOUCH_XPT2046_CS, TOUCH_XPT2046_INT);
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
#include <Wire.h>
#include <TouchLib.h>
TouchLib touch(Wire, TOUCH_SDA, TOUCH_SCL, TOUCH_MODULE_ADDR);
#endif // TouchLib
void touch_init(int16_t w, int16_t h, uint8_t r)
{
touch_max_x = w - 1;
touch_max_y = h - 1;
if (touch_map_x1 == -1)
{
switch (r)
{
case 3:
touch_swap_xy = true;
touch_map_x1 = touch_max_x;
touch_map_x2 = 0;
touch_map_y1 = 0;
touch_map_y2 = touch_max_y;
break;
case 2:
touch_swap_xy = false;
touch_map_x1 = touch_max_x;
touch_map_x2 = 0;
touch_map_y1 = touch_max_y;
touch_map_y2 = 0;
break;
case 1:
touch_swap_xy = true;
touch_map_x1 = 0;
touch_map_x2 = touch_max_x;
touch_map_y1 = touch_max_y;
touch_map_y2 = 0;
break;
default: // case 0:
touch_swap_xy = false;
touch_map_x1 = 0;
touch_map_x2 = touch_max_x;
touch_map_y1 = 0;
touch_map_y2 = touch_max_y;
break;
}
}
#if defined(TOUCH_XPT2046)
SPI.begin(TOUCH_XPT2046_SCK, TOUCH_XPT2046_MISO, TOUCH_XPT2046_MOSI, TOUCH_XPT2046_CS);
ts.begin();
ts.setRotation(TOUCH_XPT2046_ROTATION);
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
// Reset touchscreen
#if (TOUCH_RES > 0)
pinMode(TOUCH_RES, OUTPUT);
digitalWrite(TOUCH_RES, 0);
delay(200);
digitalWrite(TOUCH_RES, 1);
delay(200);
#endif
Wire.begin(TOUCH_SDA, TOUCH_SCL);
touch.init();
#endif // TouchLib
}
bool touch_has_signal()
{
#if defined(TOUCH_XPT2046)
return ts.tirqTouched();
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
// TODO: implement TOUCH_INT
return true;
#endif // TouchLib
return false;
}
void translate_touch_raw()
{
if (touch_swap_xy)
{
touch_last_x = map(touch_raw_y, touch_map_x1, touch_map_x2, 0, touch_max_x);
touch_last_y = map(touch_raw_x, touch_map_y1, touch_map_y2, 0, touch_max_y);
}
else
{
touch_last_x = map(touch_raw_x, touch_map_x1, touch_map_x2, 0, touch_max_x);
touch_last_y = map(touch_raw_y, touch_map_y1, touch_map_y2, 0, touch_max_y);
}
// Serial.printf("touch_raw_x: %d, touch_raw_y: %d, touch_last_x: %d, touch_last_y: %d\n", touch_raw_x, touch_raw_y, touch_last_x, touch_last_y);
}
bool touch_touched()
{
#if defined(TOUCH_XPT2046)
if (ts.touched())
{
TS_Point p = ts.getPoint();
touch_raw_x = p.x;
touch_raw_y = p.y;
int max_z = p.z;
int count = 0;
while ((ts.touched()) && (count < TOUCH_XPT2046_SAMPLES))
{
count++;
TS_Point p = ts.getPoint();
if (p.z > max_z)
{
touch_raw_x = p.x;
touch_raw_y = p.y;
max_z = p.z;
}
// Serial.printf("touch_raw_x: %d, touch_raw_y: %d, p.z: %d\n", touch_raw_x, touch_raw_y, p.z);
}
translate_touch_raw();
return true;
}
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
if (touch.read())
{
TP_Point t = touch.getPoint(0);
touch_raw_x = t.x;
touch_raw_y = t.y;
touch_last_x = touch_raw_x;
touch_last_y = touch_raw_y;
translate_touch_raw();
return true;
}
#endif // TouchLib
return false;
}
bool touch_released()
{
#if defined(TOUCH_XPT2046)
return true;
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
return false;
#endif // TouchLib
return false;
}

View File

@@ -271,9 +271,15 @@ int SerialKlipperPrinter::get_power_devices_count()
bool SerialKlipperPrinter::set_power_device_state(const char* device_name, bool state)
{
String request = "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off");
return make_serial_request_nocontent(HttpGet, request.c_str());
return make_serial_request_nocontent(HttpPost, request.c_str());
}
#ifdef CYD_S3
#define MAX_FILE_LIST_SIZE 200
#else
#define MAX_FILE_LIST_SIZE 20
#endif
Files SerialKlipperPrinter::get_files()
{
Files files_result = {0};
@@ -291,7 +297,7 @@ Files SerialKlipperPrinter::get_files()
return files_result;
}
parse_file_list(doc, files, 20);
parse_file_list(doc, files, MAX_FILE_LIST_SIZE);
files_result.available_files = (char**)malloc(sizeof(char*) * files.size());

View File

@@ -375,6 +375,8 @@ void show_ip_entry()
lv_textarea_set_placeholder_text(host_entry, "Printer IP");
lv_textarea_set_placeholder_text(port_entry, "Access code");
lv_textarea_set_placeholder_text(auth_entry, "Printer serial number");
lv_obj_clear_flag(auth_entry, LV_OBJ_FLAG_USER_2);
lv_obj_add_flag(auth_entry, LV_OBJ_FLAG_USER_3);
break;
case PrinterType::PrinterTypeOctoprint:
lv_obj_clear_flag(auth_entry, LV_OBJ_FLAG_USER_2);

View File

@@ -47,8 +47,7 @@ int macros_add_macros_to_panel(lv_obj_t * root_panel, BasePrinter* printer)
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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
DoubleStorage* device = (DoubleStorage*)lv_event_get_user_data(e);
LOG_F(("Power Device: %s, State: %d -> %d\n", device->power_device_name, !checked, checked))

View File

@@ -15,8 +15,7 @@
#endif // REPO_VERSION
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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.printer_config[global_config.printer_index].invert_colors = checked;
write_global_config();
set_invert_display();
@@ -46,16 +45,14 @@ static void reset_ip_click(lv_event_t * e){
}
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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
get_current_printer()->printer_config->light_mode = checked;
write_global_config();
set_color_scheme();
}
static void filament_move_mode_switch(lv_event_t * e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
get_current_printer()->printer_config->custom_filament_move_macros = checked;
write_global_config();
}
@@ -97,51 +94,44 @@ static void wake_timeout_dropdown(lv_event_t * e){
}
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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.display_mode = checked;
write_global_config();
ESP.restart();
}
static void disable_m117_messaging_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.disable_m117_messaging = checked;
write_global_config();
}
static void sort_macros_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.sort_macros = checked;
write_global_config();
}
static void show_estop_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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.show_estop = checked;
write_global_config();
}
static void full_filenames_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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.full_filenames = checked;
write_global_config();
}
static void double_size_gcode_img_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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.double_size_gcode_img = checked;
write_global_config();
}
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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.rotate_screen = checked;
global_config.screen_calibrated = false;
write_global_config();
@@ -149,8 +139,7 @@ static void rotate_screen_switch(lv_event_t* e){
}
static void on_during_print_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.on_during_print = checked;
check_if_screen_needs_to_be_disabled();
write_global_config();
@@ -161,15 +150,13 @@ 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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
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);
bool checked = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
global_config.multi_printer_mode = checked;
write_global_config();
nav_buttons_setup(PANEL_SETTINGS);

View File

@@ -161,9 +161,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);
temp_edit_mode = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
temp_edit_mode = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
}
static void btn_retract(lv_event_t * e){

View File

@@ -5,11 +5,49 @@
#define MAX_COMDLINE_SIZE 80
#define MAX_WORDS 6
#define BACKSPACE_CHAR 0x08
#define ESCAPE_CHAR '\x1b'
#define CSI_CHAR '['
#define LEFT_ARROW_CHAR 'D'
#define RIGHT_ARROW_CHAR 'C'
#define DELETE_KEY_1_CHAR '3'
#define DELETE_KEY_2_CHAR '~'
#define PRINT_CHAR_START 32
#define PRINT_CHAR_END 126
namespace serial_console
{
bool global_disable_serial_console = false;
/**
* @brief Redraws the characters from the current cursor position to the end of the buffer on the serial console.
*
* This function is used to update the terminal display when characters are inserted or deleted
* in the middle of the input buffer. It:
* - Saves the current cursor position
* - Clears the line from the cursor to the end
* - Prints characters from 'cur' to 'len'
* - Restores the original cursor position
*
* @param cur Current cursor position within the buffer
* @param len Current length of the buffer (number of characters entered)
* @param buf Character buffer containing the input string
*/
static inline void redraw(const int cur, const int len, char *buf) {
if (!temporary_config.remote_echo)
return;
Serial.print("\x1b[s");
Serial.print("\x1b[K");
// Reprint characters from cur to end
for (int i = cur; i < len; i++) {
Serial.print((char)buf[i]);
}
Serial.print(" \x1b[u");
}
/*
* read_string_until: Non-blocking replacement for Serial.readStringUntil()..
* With delimeter '\n' acts as 'read line'.
@@ -20,6 +58,7 @@ namespace serial_console
bool read_string_until(char delimiter, char *result, int max_len)
{
static int index = 0;
static int cur = 0;
int c; // read character, -1 if none
int cnt = 100; // limit on amount of iterations in one go; we're supposed to be non-blocking!
@@ -28,43 +67,75 @@ namespace serial_console
--cnt;
// backspaceF
if (c == 8)
{
if (index > 0)
{
if(temporary_config.remote_echo) Serial.print("\x08 \x08"); // overwrite last character with space and move cursor 1 back.
if (c == BACKSPACE_CHAR && cur > 0) {
// shift characters left from cursor position
memmove(&result[cur - 1], &result[cur], index - cur);
index--;
}
cur--;
// move cursor left on terminal and redraw updated string
if(temporary_config.remote_echo) Serial.print("\x1b[D");
redraw(cur, index, result);
// handle ANSI escape sequences (arrow keys, delete key)
} else if (c == ESCAPE_CHAR) {
if ((c = Serial.read()) == -1)
break;
// Expect '[' character
if (c != CSI_CHAR)
continue;
if ((c = Serial.read()) == -1)
break;
// Left arrow key
if (c == LEFT_ARROW_CHAR && cur > 0) {
// move cursor left on terminal
if(temporary_config.remote_echo) Serial.print("\x1b[D");
cur--;
// Right arrow key
} else if(c == RIGHT_ARROW_CHAR && cur < index) {
// move cursor right on terminal
if(temporary_config.remote_echo) Serial.print("\x1b[C");
cur++;
// Delete key
} else if(c == DELETE_KEY_1_CHAR) {
if ((c = Serial.read()) == -1)
break;
if (c == DELETE_KEY_2_CHAR && cur < index) {
memmove(&result[cur], &result[cur + 1], index - cur - 1);
index--;
redraw(cur, index, result);
}
}
if(temporary_config.remote_echo) Serial.print((char)c); // echo
// Buffer overflow handling:
// start treating current buffer as invalid:
// - stop collecting more data
// - return false on delimeter, flushing everything collected,
// - restart collection from scratch after delimeter,
// - return control as normal.
if (index >= max_len - 1)
{
if (c == delimiter) // got delimeter: flush buffer quietly, restart collection.
{
// Handle printable characters
} else if (c >= PRINT_CHAR_START && c <= PRINT_CHAR_END) {
// Append character at the end
if (index < max_len - 1 && cur == index) {
if(temporary_config.remote_echo) Serial.print((char)c);
result[index++] = c;
cur++;
// Insert character in the middl
} else if (index < max_len - 1) {
memmove(&result[cur + 1], &result[cur], index - cur);
result[cur] = c;
index++;
if(temporary_config.remote_echo) Serial.print((char)c);
cur++;
redraw(cur, index, result);
} else if (c == delimiter) { // got delimeter: flush buffer quietly, restart collection.
index = 0;
cur = 0;
return false;
}
else
continue; // discard any data past the end of the buffer, keep reading
}
result[index++] = c;
// delimiter was found
if (c == delimiter)
{
} else if (c == delimiter) {
if(temporary_config.remote_echo) Serial.println();
result[index] = '\0'; // Null-terminate the string
index = 0;
cur = 0;
return true; // Success: Delimiter found
}
}

View File

@@ -2,9 +2,10 @@
[![Donations](https://img.shields.io/badge/Support%20on-Ko--Fi-red)](https://ko-fi.com/suchmememanyskill)
# CYD-Klipper
An implementation of a wireless Klipper status display on an ESP32 + screen. Uses Moonraker to fetch data.
An implementation of a wireless Klipper, Bambu and Octoprint status display on an ESP32 + screen. Uses Moonraker to fetch data.
A simple and cheap solution to use a dedicated screen with Klipper, a 3d printing Firmware.
Also now with Bambu Lab and Octoprint printers!
![showcase_image](readme/PXL_20231113_171629383.jpg)
@@ -24,6 +25,8 @@ A ESP32-2432S028R is required to run this project. You can find out where to buy
- Toggle Moonraker power devices
- OTA updates
- Serial console over USB (115200 8n1, echo off, LF/LF)
- Control Klipper, Octoprint and Bambu printers.
- Wired Serial/Usb Klipper connection
### Install
@@ -39,6 +42,21 @@ If you found this project helpful, please consider a donation [to my Ko-Fi](http
Thank you!
### Where to buy hardware
All links below are affiliate links. Please also check yourself if there is a cheaper version available than the ones below. I have only linked ones that i have personally bought.
*ESP32-2432S028R (2.8" Resistive, Cheapest)*
- [USB C + microB version](https://s.click.aliexpress.com/e/_omjsYBJ)
- [Another USB C + microB version](https://s.click.aliexpress.com/e/_olKBkmz)
- [microB version](https://s.click.aliexpress.com/e/_oCWhgmN)
*ESP32-2432S032C (3.2" Capacitive)*
- [Only the capacitive version is supported! USB-C](https://s.click.aliexpress.com/e/_okbSGmd)
- [IPS version (not that great of a screen), Only the capacitive version is supported! USB-C](https://s.click.aliexpress.com/e/_oFygVwt)
*ESP32-3248S035C (3.5" Capacitive)*
- [microB version](https://s.click.aliexpress.com/e/_oCqygE9)
### Screenshots
(Quite literally shots of the screen. I'm sorry)

67
ci.json Normal file
View File

@@ -0,0 +1,67 @@
{
"esp32-2432S024C-SD": {
"name": "ESP32-2432S024 (2.4\" Capacitive)",
"site": true,
"s3": false
},
"esp32-2432S028R": {
"name": "ESP32-2432S028 (2.8\" Resistive)",
"site": true,
"s3": false,
"default": true
},
"esp32-2432S032C-SD": {
"name": "ESP32-2432S032 (3.2\" Capacitive)",
"site": true,
"s3": false
},
"esp32-3248S035C": {
"name": "ESP32-3248S035 (3.5\" Capacitive)",
"site": true,
"s3": false
},
"esp32-3248S035C-V": {
"name": "ESP32-3248S035 (3.5\" Capacitive) Vertical Orientation",
"site": true,
"s3": false
},
"esp32-4827S043C-SD": {
"name": "ESP32-4827S043 (4.3\" 480x270 Capacitive)",
"site": true,
"s3": true
},
"esp32-8048S043C-SD": {
"name": "ESP32-8048S043 (4.3\" 800x480 Capacitive)",
"site": true,
"s3": true
},
"esp32-8048S043C-SD-alt": {
"name": "ESP32-8048S043 Alt (4.3\" 800x480 Capacitive)",
"site": true,
"s3": true
},
"esp32-CROWPANEL-28R": {
"name": "ESP32-CROWPANEL-28R (2.8\" Resistive)",
"site": true,
"s3": false,
"brand": "CrowPanel"
},
"esp32-CROWPANEL-35C": {
"name": "ESP32-CROWPANEL-35C (3.5\" Capacitive)",
"site": true,
"s3": true,
"brand": "CrowPanel"
},
"esp32-JC4827W543C": {
"name": "ESP-JC4827W543C (4.3\" Capacitive)",
"site": true,
"s3": true,
"brand": "Guition"
},
"esp32-JC8048W550": {
"name": "Guition JC8048W550 (5\" Capacitive)",
"site": true,
"s3": true,
"brand": "Guition"
}
}

79
ci.py
View File

@@ -1,50 +1,31 @@
import subprocess, os, shutil, json
CYD_PORTS = [
"esp32-3248S035C",
"esp32-2432S028R",
"esp32-2432S032C-SD",
"esp32-8048S043C-SD",
"esp32-8048S043C-SD-alt",
"esp32-2432S024C-SD",
"esp32-4827S043C-SD",
"esp32-3248S035C-V",
#"esp32-4827S043R-SD",
"esp32-CROWPANEL-28R",
]
ESP_S3_CHIPS = [
"esp32-8048S043C-SD",
"esp32-8048S043C-SD-alt",
"esp32-4827S043C-SD",
]
BASE_DIR = os.getcwd()
def get_manifest(base_path : str, device_name : str):
def get_manifest(base_path : str, device_name : str, is_s3 : bool):
return {
"name": f"to {device_name}",
"funding_url": "https://ko-fi.com/suchmememanyskill",
"new_install_prompt_erase": True,
"builds": [
{
"chipFamily": "ESP32-S3" if device_name in ESP_S3_CHIPS else "ESP32",
"chipFamily": "ESP32-S3" if is_s3 else "ESP32",
"parts": [
{
"path": f"{base_path}/bootloader.bin",
"offset": 4096
"offset": 0 if is_s3 else 0x1000
},
{
"path": f"{base_path}/partitions.bin",
"offset": 32768
"offset": 0x8000
},
{
"path": f"{base_path}/boot_app0.bin",
"offset": 57344
"offset": 0xe000
},
{
"path": f"{base_path}/firmware.bin",
"offset": 65536
"offset": 0x10000
}
]
}
@@ -57,6 +38,7 @@ def extract_commit() -> str:
repo_version = extract_commit()
configurations = []
site_sections : dict[str, dict] = {"CYD": []}
def add_configuration(board : str):
configurations.append({
@@ -65,10 +47,32 @@ def add_configuration(board : str):
"URL": f"https://suchmememanyskill.github.io/CYD-Klipper/out/{board}/firmware.bin"
})
def add_site_section(port : str, data : dict[str, bool|str]):
brand = data["brand"] if "brand" in data else "CYD"
if brand not in site_sections:
site_sections[brand] = []
site_sections[brand].append({
"name": data["name"],
"port": port,
"default": "default" in data and data["default"],
})
if os.path.exists("out"):
shutil.rmtree("out")
for port in CYD_PORTS:
if not os.path.exists("_site"):
os.makedirs("_site")
with open("./ci.json", "r") as fp:
ci_data : dict[str, dict[str, bool|str]] = json.load(fp)
for port, data in ci_data.items():
if "skip" in data and data["skip"]:
print(f"Skipping {port}...")
continue
port_path = f"out/{port}"
os.chdir(BASE_DIR)
os.makedirs(port_path, exist_ok=True)
@@ -80,15 +84,21 @@ for port in CYD_PORTS:
shutil.copy(os.path.join(os.path.expanduser("~"), ".platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin"), f"{port_path}/boot_app0.bin")
os.chdir(port_path)
subprocess.run(["python3", "-m", "esptool", "--chip", "esp32", "merge_bin", "-o", "merged_firmware.bin", "--flash_mode", "dio", "--flash_freq", "40m", "--flash_size", "4MB", "0x1000", "bootloader.bin", "0x8000", "partitions.bin", "0xe000", "boot_app0.bin", "0x10000", "firmware.bin"], check=True)
if (bool(data["s3"])):
subprocess.run(["esptool", "--chip", "esp32s3", "merge_bin", "-o", "merged_firmware.bin", "--flash_mode", "dio", "--flash_freq", "80m", "--flash_size", "16MB", "0x0000", "bootloader.bin", "0x8000", "partitions.bin", "0xe000", "boot_app0.bin", "0x10000", "firmware.bin"], check=True)
else:
subprocess.run(["esptool", "--chip", "esp32", "merge_bin", "-o", "merged_firmware.bin", "--flash_mode", "dio", "--flash_freq", "40m", "--flash_size", "4MB", "0x1000", "bootloader.bin", "0x8000", "partitions.bin", "0xe000", "boot_app0.bin", "0x10000", "firmware.bin"], check=True)
os.chdir(BASE_DIR)
with open(f"./_site/{port}.json", "w") as f:
json.dump(get_manifest(port_path, port), f)
json.dump(get_manifest(port_path, port, bool(data["s3"])), f)
add_configuration(port)
if "site" in data and data["site"]:
add_site_section(port, data)
os.chdir(BASE_DIR)
out_dir = "./_site/out"
if os.path.exists(out_dir):
@@ -97,3 +107,16 @@ shutil.copytree("./out", out_dir)
with open("./_site/OTA.json", "w") as f:
json.dump({"Configurations": configurations}, f)
with open("./_site/index.html", "w") as fp:
with open("./template.html", "r") as template_fp:
template = template_fp.read()
insert_html = ""
for brand, sections in site_sections.items():
option_htmls = [f"<option {'selected' if x['default'] else ''} value=\"{x['port']}\">{x['name']}</option>" for x in sections]
section_html = f"<optgroup label=\"{brand}\">{''.join(option_htmls)}</optgroup>"
insert_html += section_html
fp.write(template.replace("{{%PORTS%}}", insert_html))

View File

@@ -1,9 +1,22 @@
#!/bin/bash
if [ "$EUID" -eq 0 ]; then
echo "Please do not run as root"
read -r -p "Are you sure you want to run this service as root? [y/N] " response
response=${response,,} # tolower
if ! [[ "$response" =~ ^(yes|y)$ ]]; then
exit
fi
SERVICE_PATH="/etc/systemd/system/cyd-klipper-serial.service"
else
echo "Are you sure you want to run this service as the current user?"
read -r -p "Make sure this user is logged in at boot! [y/N] " response
response=${response,,} # tolower
if ! [[ "$response" =~ ^(yes|y)$ ]]; then
exit
fi
mkdir -p ~/.config/systemd/user
SERVICE_PATH="$HOME/.config/systemd/user/cyd-klipper-serial.service"
fi
set -e
@@ -15,20 +28,26 @@ source ./env/bin/activate
pip3 install -r requirements.txt
# Create systemd unit file
mkdir -p ~/.config/systemd/user
echo "[Unit]" > ~/.config/systemd/user/cyd-klipper-serial.service
echo "Description=CYD Klipper serial server" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "After=network.target" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "[Service]" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "ExecStart=$(pwd)/run.sh" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "WorkingDirectory=$(pwd)" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "Restart=always" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "[Install]" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "WantedBy=multi-user.target" >> ~/.config/systemd/user/cyd-klipper-serial.service
echo "[Unit]" > $SERVICE_PATH
echo "Description=CYD Klipper serial server" >> $SERVICE_PATH
echo "After=network.target" >> $SERVICE_PATH
echo "" >> $SERVICE_PATH
echo "[Service]" >> $SERVICE_PATH
echo "ExecStart=$(pwd)/run.sh" >> $SERVICE_PATH
echo "WorkingDirectory=$(pwd)" >> $SERVICE_PATH
echo "Restart=always" >> $SERVICE_PATH
echo "" >> $SERVICE_PATH
echo "[Install]" >> $SERVICE_PATH
echo "WantedBy=multi-user.target" >> $SERVICE_PATH
# Start the service
if [ "$EUID" -eq 0 ]; then
systemctl daemon-reload
systemctl enable cyd-klipper-serial
systemctl start cyd-klipper-serial
else
systemctl --user daemon-reload
systemctl --user enable cyd-klipper-serial
systemctl --user start cyd-klipper-serial
fi

View File

@@ -1,13 +1,21 @@
#!/bin/bash
if [ "$EUID" -eq 0 ]; then
echo "Please do not run as root"
exit
fi
set -e
if [ "$EUID" -eq 0 ]; then
systemctl stop cyd-klipper-serial
systemctl disable cyd-klipper-serial
rm /etc/systemd/system/cyd-klipper-serial.service
systemctl daemon-reload
else
systemctl --user stop cyd-klipper-serial
systemctl --user disable cyd-klipper-serial
rm ~/.config/systemd/user/cyd-klipper-serial.service
systemctl --user daemon-reload
fi
rm -rf ./env

View File

@@ -24,7 +24,8 @@
max-width: 750px;
}
.main > section > :not(:first-child) {
.main > section > :not(:first-child),
.indent {
margin-left: 20px;
}
@@ -44,6 +45,17 @@
#changelog-body {
white-space: break-spaces;
}
.where-to-get details summary::marker
{
content: '';
}
.where-to-get details[open] summary p
{
display: none;
}
</style>
<script type="module" src="https://unpkg.com/esp-web-tools@9/dist/web/install-button.js?module"></script>
<script src="//code.iconify.design/1/1.0.6/iconify.min.js"></script>
@@ -71,7 +83,7 @@
<body>
<section class="main">
<h2>CYD-Klipper <span class="iconify" data-icon="mdi-printer-3d" style="color: #F44;"></span></h2>
<p>An implementation of a Klipper status display on an ESP32 + screen.<br>Uses Moonraker to fetch data.<br><a href="https://github.com/suchmememanyskill/CYD-Klipper">Source code is available on GitHub</a>.</p>
<p>An implementation of a wireless Klipper, Bambu and Octoprint 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">
<h3 id="changelog-header"><span class="iconify" data-icon="mdi-hammer-wrench" style="color: lightgray;"></span> Changelog <span id="changelog-header-version"></span></h3>
@@ -83,6 +95,34 @@
<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="where-to-get">
<details>
<summary>
<h3><span class="iconify" data-icon="mdi-shopping" style="color:orange; filter: drop-shadow(0 0 0.75rem orange);"></span> Where to buy hardware</h3>
<p class="indent">(Click to expand)</p>
</summary>
<section class="indent">
<p>All links below are affiliate links. Please also check yourself if there is a cheaper version available than the ones below. I have only linked ones that i have personally bought.</p>
<i>ESP32-2432S028R (2.8" Resistive, Cheapest)</i>
<ul>
<li><a href="https://s.click.aliexpress.com/e/_omjsYBJ">USB C + microB version</a></li>
<li><a href="https://s.click.aliexpress.com/e/_olKBkmz">Another USB C + microB version</a></li>
<li><a href="https://s.click.aliexpress.com/e/_oCWhgmN">microB version</a></li>
</ul>
<i>ESP32-2432S032C (3.2" Capacitive)</i>
<ul>
<li><a href="https://s.click.aliexpress.com/e/_okbSGmd">Only the capacitive version is supported! USB-C</a></li>
<li><a href="https://s.click.aliexpress.com/e/_oFygVwt">IPS version (not that great of a screen), Only the capacitive version is supported! USB-C</a></li>
</ul>
<i>ESP32-3248S035C (3.5" Capacitive)</i>
<ul>
<li><a href="https://s.click.aliexpress.com/e/_oCqygE9">microB version</a></li>
</ul>
</section>
</details>
</section>
<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>
@@ -92,15 +132,7 @@
<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>
<option value="esp32-8048S043C-SD-alt">ESP32-8048S043 Alt (4.3" 800x480 Capacitive)</option>
<option value="esp32-CROWPANEL-28R">ESP32-CROWPANEL-28R (2.8" Resistive)</option>
{{%PORTS%}}
</select>
<span id="install-btn"></span>
</section>

View File

@@ -4,7 +4,7 @@ services:
ports:
- "7125:7125"
- "8110:8110"
image: ghcr.io/mainsail-crew/virtual-klipper-printer:master
image: ghcr.io/mainsail-crew/virtual-klipper-printer:latest
webui:
container_name: mainsail
volumes: