A custom round LCD touch panel for Klipper 3D printer firmware, built with a super cheap, round touch screen.
This project provides a very basic graphical touch interface for Klipper-based 3D printers using a cheap round 240x240 LCD display. It connects to Moonraker (Klipper's API server) via WebSocket to display real-time printer status and temperatures. It has 3 configurable buttons for telling Klipper to run macros.
Like most Klipper uses of custom printers I run my printers 100% from my PC. The problem is when I have to perform a task that requires me to be physically standing at my printer. The 3 tasks that require me to be physically at the printer is Loading new filament, Unloading filament, and Resuming after a pause/colour change where I need to remove purged material. These 3 tasks required that I click a button on my PC, then get over to the printer post haste in time to perform the task. Loading and unloading filament isn't really an issue but Resuming a print could sometimes be a problem. So I created this extremely simple, cheap and easy to use display. The 3 buttons can be customized with any name you want (assuming it fits on the button) and to send any macro name to Klipper you want run. This is all configurable from a single config file (round_klipper_conf.h)
- Display: ESP32-2424S012C-I Round LCD Module from AliExpress https://www.aliexpress.com/item/1005010512426009.html
- USB Cable: Flat USB-C cable from Amazon This is the Australian one - https://www.amazon.com.au/dp/B0FPCMK1J1
This is the default pin configuration for the device I used, if you use a different device you can modify the pin definitions in include/round_klipper_conf.h:
| Function | GPIO Pin |
|---|---|
| LCD SCK | GPIO 6 |
| LCD MOSI | GPIO 7 |
| LCD CS | GPIO 10 |
| LCD DC | GPIO 2 |
| LCD RST | GPIO 1 |
| Touch SDA | GPIO 4 |
| Touch SCL | GPIO 5 |
- Real-time Temperature Display: Shows hotend and bed temperatures in real time
- Print Status: Displays current printer state as a coloured arc that changes colour depending on the printer state, while printing it animates slightly
- Touch Controls: Three fully customizable buttons
- Screen Blanking: Screen will shut off when not printing and not being used after a configurable timeout
- WebSocket Connection: Direct communication with Moonraker API
- Custom UI: Round-optimized interface using LVGL
- Custom Touch Driver: I couldn't find a touch driver that worked so made my own
- Know your Klipper network address - 'klipper.local' is preferred if it's set up that way.
- Get your Moonraker API key:
- Navigate to
http://klipper.local/access/api_keyOr swap 'klipper.local' with your Klipper IP address. - Copy your API key into
include/round_klipper_conf.h
- Navigate to
- VSCode (recommended but not strictly required)
- PlatformIO (recommended)
- Arduino framework
- LVGL v9.1.0+
- WebSockets library
git clone https://github.com/PsyonicOne/Round-Klipper-Display.git
cd Round-Klipper-DisplayEdit include/round_klipper_conf.h and update:
// WiFi credentials
#define WIFI_SSID "Your_WiFi_SSID" // Your WiFi network name (SSID)
#define WIFI_PASSWORD "Your_WiFi_Password" // Your WiFi network password
#define HOST_NAME "Hostname" // Hostname for your device on the network (optional, but can be helpful for identifying it)
// Moonraker connection
#define MOONRAKER_HOST "klipper.local" // Your Klipper hostname/IP
#define MOONRAKER_PORT 7125 // Default Moonraker port
#define MOONRAKER_API_KEY "your_api_key" // Your Moonraker API keyUpdate the button actions in include/round_klipper_conf.h to match your Klipper macros.
The default ones are from my configuration, you will need to make sure the macro names match your Klipper macros:
#define RESUME_BTN_MACRO "RESUME" // Macro to resume print
#define BOTTOM_LEFT_BTN_MACRO "LOAD_FILAMENT" // Macro to load filament
#define BOTTOM_RIGHT_BTN_MACRO "UNLOAD_FILAMENT" // Macro to unload filamentThe display includes automatic screen blanking when not in use.
In include/round_klipper_conf.h:
// Screen blanking settings
#define SCREEN_BLANK_TIMEOUT_SECS 120 // Seconds of inactivity before blanking
#define SCREEN_BACKLIGHT_ON 100 // Backlight brightness when active (0-255)
#define SCREEN_BACKLIGHT_OFF 0 // Backlight brightness when blanked (0-255)- Blanking: Screen blanks after inactivity when NOT printing
- During Print: Screen stays on regardless of inactivity
- Print Start: Screen automatically wakes when print begins
- Print End: After print ends, the screen will wait before blanking
- Wake on Touch: First touch wakes the screen (buttons disabled for 1 second to prevent accidental triggers)
You are better off using the PlatformIO buttons in VSCode, but if you're more comfortable with the CLI:
# Build the project
pio run
# Upload to ESP32-C3
pio run --target upload
# Monitor serial output
pio device monitorThe coloured arc below the outer temperature arcs displays the current status of the machine.
- Fast Flashing Red: This indicates that either the WIFI or the Moonraker connection failed at startup
- Solid Red: The previous print failed or was canceled
- Solid Greed: The previous print completed successfully or the machine is in idle
- Slow Blue Movement: The machine is currently printing (little bit of pizazz 🤩)
These should be automatically downloaded when you open the project with PlatformIO running in VSCode.
- LVGL v9.1.0+ - Graphics library
- WebSockets - WebSocket client for Moonraker
- Arduino - ESP32 framework
This project is licensed under the MIT License - see the LICENSE file for details.
The files for printing can be found in prints/
The model is designed for the Enders with 40x40mm extrusion base, like the Ender 3 variants.
Print it however you like, there will be some areas that need supports, I don't use supports inside the holes for the clips and inside the back cavity. The diameter where the display goes in is a slight press fit, it should have some resistance when inserted. The hole through the mount is to get the display out if required, ask me how I figured that out!
The little clips slide into the profile of the extrusion.
It's easier to push the clips into the extrusion first, then gently push the clips into the display housing one-by-one. Do not glue the clips in, you'll need to adjust them as you slide them around. With all the tolerances everything should have a bit of a friction fit and not require any glue.
The cutout in the bottom of the housing for the USB cable to pass through is slightly offset. This was because the 2 particular displays I received were slightly off from where the centre of the screen graphics displayed and where the USB plugged in. Should you need a slightly different orientation please let me know and I'll add a variant. Its width is specifically for the cable I specified at the top in the Hardware section.