From 99b70622fe48cd57c2f48d8c11790a90c409f617 Mon Sep 17 00:00:00 2001 From: suchmememanyskill <38142618+suchmememanyskill@users.noreply.github.com> Date: Thu, 9 Jan 2025 23:14:15 +0100 Subject: [PATCH 1/4] Update readme --- README.md | 4 +++- _site/index.html | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13e7171..1975077 100644 --- a/README.md +++ b/README.md @@ -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,7 @@ 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) +- Supports Klipper, Octoprint and Bambu printers. ### Install diff --git a/_site/index.html b/_site/index.html index 62444d5..da92100 100644 --- a/_site/index.html +++ b/_site/index.html @@ -71,7 +71,7 @@

CYD-Klipper

-

An implementation of a Klipper status display on an ESP32 + screen.
Uses Moonraker to fetch data.
Source code is available on GitHub.

+

An implementation of a wireless Klipper, Bambu and Octoprint status display on an ESP32 + screen.
Uses Moonraker to fetch data.
Source code is available on GitHub.

Changelog

From 5756b317447f220bac5138fcf38bff02646e06c4 Mon Sep 17 00:00:00 2001 From: Sims <38142618+suchmememanyskill@users.noreply.github.com> Date: Fri, 10 Jan 2025 18:15:56 +0100 Subject: [PATCH 2/4] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1975077..5d52b2a 100644 --- a/README.md +++ b/README.md @@ -25,7 +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) -- Supports Klipper, Octoprint and Bambu printers. +- Control Klipper, Octoprint and Bambu printers. +- Wired Serial/Usb Klipper connection ### Install From 8f46b9972d10badba085684823261d0848cb8da8 Mon Sep 17 00:00:00 2001 From: suchmememanyskill <38142618+suchmememanyskill@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:18:36 +0100 Subject: [PATCH 3/4] Add aliexpress links --- README.md | 15 +++++++++++++++ _site/index.html | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d52b2a..97c5b83 100644 --- a/README.md +++ b/README.md @@ -42,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) diff --git a/_site/index.html b/_site/index.html index da92100..b3766a9 100644 --- a/_site/index.html +++ b/_site/index.html @@ -8,7 +8,7 @@ font-family: 'Roboto', sans-serif; } - TT { + TT { font-family: 'Terminal', monospace; background-color: #080a0b; } @@ -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; + } + @@ -83,6 +95,34 @@

If you found this project helpful, please consider a donation to my Ko-Fi.
It would help out a lot in the development of this project, due to the need to buy the screens.
Thank you!

+
+
+ +

Where to buy hardware

+

(Click to expand)

+
+
+

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) + + ESP32-2432S032C (3.2" Capacitive) + + ESP32-3248S035C (3.5" Capacitive) + +
+
+ +
+

Report Issues

If you experience any issues with this project, or have any feature requests for the project, please report them on the issues tab on Github.

From b6c2b505e0052ab46e88ab379d337912c746b445 Mon Sep 17 00:00:00 2001 From: Dylan Pryke-Watanabe Date: Thu, 10 Jul 2025 07:44:27 +1000 Subject: [PATCH 4/4] 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 --- CYD-Klipper/boards/esp32-JC3248W535C.json | 69 +++++++ CYD-Klipper/platformio.ini | 26 +++ .../src/core/device/ESP32-JC3248W535C.cpp | 185 ++++++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 CYD-Klipper/boards/esp32-JC3248W535C.json create mode 100644 CYD-Klipper/src/core/device/ESP32-JC3248W535C.cpp diff --git a/CYD-Klipper/boards/esp32-JC3248W535C.json b/CYD-Klipper/boards/esp32-JC3248W535C.json new file mode 100644 index 0000000..0c4b6d5 --- /dev/null +++ b/CYD-Klipper/boards/esp32-JC3248W535C.json @@ -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": [ + "-DESP32S3", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-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" + ], + "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"] + } + \ No newline at end of file diff --git a/CYD-Klipper/platformio.ini b/CYD-Klipper/platformio.ini index ee36d08..bd72d02 100644 --- a/CYD-Klipper/platformio.ini +++ b/CYD-Klipper/platformio.ini @@ -117,3 +117,29 @@ lib_deps = knolleary/PubSubClient@^2.8 WiFiClientSecure +[env:ESP32-JC3248W535C] +platform = espressif32@^6.4.0 +board = esp32-JC3248W535C +framework = arduino +board_build.flash_mode = qio +board_build.partitions = huge_app.csv +board_build.psram_size = 8MB +build_flags = + -DLV_CONF_PATH="../../../../src/conf/lv_conf.h" + -DUSER_SETUP_LOADED + -DARDUINO_USB_CDC_ON_BOOT=1 + -DCYD_SCREEN_VERTICAL=1 + + +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 + +monitor_filters = esp32_exception_decoder +monitor_speed = 115200 +upload_speed = 921600 diff --git a/CYD-Klipper/src/core/device/ESP32-JC3248W535C.cpp b/CYD-Klipper/src/core/device/ESP32-JC3248W535C.cpp new file mode 100644 index 0000000..8723e6e --- /dev/null +++ b/CYD-Klipper/src/core/device/ESP32-JC3248W535C.cpp @@ -0,0 +1,185 @@ +#ifdef CYD_BOARD_JC3248W535C + +#include "../screen_driver.h" +#include +#include +#include +#include "lvgl.h" +#include "../lv_setup.h" +#include "../../conf/global_config.h" +#include +#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