Klipper is an open source firmware for 3D Printers than can improve the performance and print quality of your device by offloading its computational tasks to a more powerful computer. There are a few other guides out there for accomplishing this with an Ender-6, but at the time of writing this they were outdated, lacking in details, or both. I was always intimidated to set up Klipper on my device as a result. So when I finally decided to go through with it I wanted to write an updated and detailed guide for the community. Additionally, I wanted to write it in markdown and put it on GitHub instead of a blog post so that other members of the community can amend it or add to it in the future.
Before you flash anything to your printer or take anything apart, you need to use it to print a few things.
-
Raspberry Pi & Buck Converter Mount: here
- Since Klipper runs on a Raspberry Pi which you will power via the printer's power supply, you need a place to install the new components. I chose the electronics compartment below the printer. This model does not shield the buck converter, so take care when handling it as there is a risk of being shocked. Buck converters come in different shapes and sizes, so make sure you compare the dimensions of this part to the one you choose to purchase.
-
PIT TFT43 Screen Adapter: here
- KlipperScreen does not work with the default touchscreen for the Ender 6. There is a fork floating around that adds support, but it is unmaintained and the code was never merged upstream. In order to preserve the functionality of a touchscreen, you must replace it with one that is compatible. I chose the
PI TFT43
because it fits well in the housing. However, you will need to print an adapter to mount it correctly.
- KlipperScreen does not work with the default touchscreen for the Ender 6. There is a fork floating around that adds support, but it is unmaintained and the code was never merged upstream. In order to preserve the functionality of a touchscreen, you must replace it with one that is compatible. I chose the
-
Optional - Gantry Fan Mount: here
- Should you wish you provide cooling to the Raspberry Pi and buck converter, you can print this model I designed that allows you to mount a Noctua NF-A4x10 fan on the gantry rails.
-
Optional - M3 T-Nuts: here
- These are only needed if you wish to save a little bit of money and avoid purchasing them. But you need a way to mount the Raspberry Pi/buck converter part on the rails in your electronics compartment.
-
Raspberry Pi: here
- I bought the 5, you can probably get away with something cheaper if you wish. In hindsight the 4 might actually be a better choice if you plan to use a webcam as it supports hardware encoding.
-
MicroSD Card
-
BIGTREETECH PI TFT43 Screen: here
-
Buck Converter: here
-
50CM 22Pin -> 15Pin DSI Cable: here
- I found that anything shorter will not reach adequately from the touch screen housing into the electronics compartment. Additionally, the Raspberry Pi 5 uses a different DSI pinout than the
PI TFT43
touchscreen. So while it does come with a DSI cable, it is both too short and uses the incorrect pinout.
- I found that anything shorter will not reach adequately from the touch screen housing into the electronics compartment. Additionally, the Raspberry Pi 5 uses a different DSI pinout than the
-
MicroUSB Cable
- This is needed to connect the Raspberry Pi to the microcontroller. Mine is 24” long, but 12” would probably be sufficient.
-
USB-C Cable
- This is only needed temporarily to power the Raspberry Pi for testing and configuration before you connect it to your power supply. I powered mine with my Macbook Pro charger.
-
M2.5 & M3 Screws & Nuts
- The Raspberry Pi holes are M2.5 and the buck converter holes are M3. I used M2.5x10mm for the Raspberry Pi and M3x10 for the buck converter which allowed me to thread nuts on the other side of the adapter. I'm not sure if the print lacks proper threading or my print quality just wasn't good enough to do without. You would also need four M3 screws to attach a Noctua NF-A4x10 fan to the gantry rail part I designed should you choose to print it.
-
14-16AWG Wiring: here
- Used for wiring the buck converter with the Ender 6's power supply. The stock power supply outputs 24V at 15A. Consult this table to determine the proper rating for your power supply.
-
14-16AWG Spade Terminals: here
- Used for connecting the wiring to the Ender 6's Power Supply
-
20-22AWG Dupont Wires: here
- Used for connecting the buck converter to the Raspberry Pi.
-
Optional - USB Wireless Adapter: here
- Since the Rasberry Pi will be housed inside the electronics compartment, it will have poor wireless reception. You can optionally connect a USB wireless adapter to it to improve the signal by mounting it ouside of the printer. If you include this, be sure you read the optional Configure the Input Current section.
-
Optional - Noctua NF-A4x10 Fan: here
- You can optionally install a Noctua fan alongside the Raspberry Pi and buck converter on the gantry rails to help keep things cool.
-
Optional - M3 T Nuts
- Used to mount the Raspberry Pi/buck converter part on the gantry rails in the electronics compartment. You could print these instead.
-
Optional - USB Power Blocker: here
- When you power the printer and the Raspberry Pi separately (Like via a USB-C cable for testing), the microcontroller will also receive power from the Raspberry Pi through the USB cable. Using a power blocker on the Raspberry Pi can help prevent damage to your printer's microcontroller. It's also possible to use tape or print a part to accomplish this instead.
-
Clone the Klipper repo and change into the directory.
git clone https://github.com/Klipper3d/klipper cd klipper
-
Run
make menuconfig
and provide the following configuration: -
Save the configuration and run
make
to build the binary. -
Copy
./out/klipper.bin
to an SD Card, insert it into your Ender 6, and power on the printer. When the device detects the binary file it will automatically flash it to the motherboard. The screen will not indicate that this is happening, however, and it will appear frozen. Wait a minute or two for it to finish and then power the printer back off. At this point in time, your printer will no longer function until you finish setting up Klipper or flash an original firmware back onto it.
-
Download Raspberry Pi Imager and flash
Raspberry Pi OS Lite (64-bit)
to your MicroSD Card. Configure the installer to enable SSH and, If relevant, connect to your wireless network. -
Insert the Micro SD Card into the Raspberry Pi and power it on with a USB-C cable. Wait a minute and SSH into the device.
-
Run
apt update
to update Debian’s package repositories and then installgit
and any other tools you like such asvim
,lm-sensors
, etc.sudo apt update sudo apt-get install git
-
Install Klipper, Moonraker, Mainsail, Fluidd, KlipperScreen, Crowsnest, Mobileraker Companion, and whatever other tools you require using whichever method you prefer. The current popular method is with an interactive tool named KIAUH. If you’ve done everything correctly, KIAUH will have littered your home directory with directories and everything should be automatically configured for you.
git clone https://github.com/dw-0/kiauh.git ./kiauh/kiauh.sh
-
Copy the contents of printer-creality-ender6-2020.cfg to
~/printer_data/config/printer.cfg
. If you have a BLTouch installed make sure you edit the file according to the comments in thestepper_z
,safe_z_home
,bltouch
, andbed_mesh
sections.
-
Unplug the printer, flip it on it’s side and remove the bottom cover to access the electronics compartment. Finally, unscrew the touch screen housing and remove it from the printer. There are four T15 screws located near the microcontroller and two T8 screws each on the bottom and back of the housing. Remove the original screen from the housing, but keep the rubber gasket in place.
-
Connect the DSI cable to one of the Raspberry Pi's
CAM/DISP
headers and the header on thePI TFT43
screen. The orientation of the cable matters as there are only pins on one side of the ribbon. On the Raspberry Pi, the pins should face towards the USB ports. On thePI TFT43
, the pins should face away from the screen. -
Power on the Raspberry Pi with a USB-C cable and test that the screen works. After a moment, you should see Debian boot and Klipper Screen should load. Adjust the brightness wheel on the
PI TFT43
until you are satisfied and power off the Raspberry Pi with the power button. The brightness wheel will no longer be accessible once it is installed inside the housing, so make sure you dial this in first. -
Mount the screen onto the printed adapter, being extra careful not to overtighten the screws as doing so could break the screen. Power on the Raspberry Pi once more to confirm there is no backlight bleed from overtightened screws. Afterwards, mount the
PI TFT43
into the screen housing being sure it is oriented correctly. The brightness scroll wheel should face the top of the housing and be near the SD Card slot. I don’t believe it’s possible to continue using the SD Card reader located inside the touchscreen housing. Some Googling told me the connector is referred to as a 8 wire Molex PicoBlade but I was unable to find a cable to connect this to the Raspberry Pi. However, if you did manage to puzzle this out, you would probably be able to make it work if you configure Debian to mount the SD Card at your Klipper Virtual SD card path. I left the speaker inside the electronics compartment disconnected for the same reason. You could probably replace this speaker with a USB device if you so desired. -
Put the housing back together and screw it back into place on the printer.
-
Connect the Raspberry Pi to the microcontroller using the MicroUSB cable and, optionally, any other peripherals like a webcam and USB wireless adapter. Make sure you use the blue USB 3.0 ports for any high-bandwidth devices, if they’re available. If you're using a power blocker, go ahead and power on the Ender 6 and Raspberry Pi. At this point, if you've done everything correctly, Klipper should automatically detect your printer and KlipperScreen should appear on the screen.
-
Power everything back off and disconnect the Raspberry Pi and microcontroller.
-
Cut the 14-16AWG wires to length, strip both sides, and attach the spade terminals to one end. Attach the terminals to an open positive and negative rail on the power supply. Attach the other end of the wires to the input side of the buck converter.
-
Twist the voltage regulator knob on the buck converter to step it down to 5v.
-
Power the printer back off and connect the 20-22AWG dupont connectors to the output of the buck converter. Optionally use a multimeter to doublecheck the output before connecting it to your Raspberry Pi to avoid setting it on fire and releasing any magic smoke.
-
Connect the wires to the 5V and Ground GPIO pins on your Raspberry Pi. You'll likely need to consult a pinout guide to identify the correct pins.
-
Double check everything is connected correctly and power the printer on. The Raspberry Pi should boot up and KlipperScreen should load and Moonsail should connect to your printer. Try and perform an action like Home X/Y/Z to confirm the printer is operational.
-
Power everything back off and attach the T-Nuts to the bottom of the mounting bracket. Secure it against the gantry rail on your printer. Tidy up all of the cabling.
-
Optional - Attach the Noctua fan to the T-Nuts and the USB Port of the Raspberry Pi and mount in next to the raspberry pi and buck converter adapter.
-
Reinstall the bottom cover and flip the printer back upright.
-
If everything is installed correctly, when you power on the printer the Raspberry Pi and the TFT43 screen should turn on and Klipper should load.
-
Connect to Mainsail/Fludd/KlipperScreen and warm the bed and hotend to the temperature you most usually print at. I use PETG so I used 235/90.
-
Once the hotend is at temperature, retract any filament from the nozzle so that it doesn’t ooze while you level the bed and calculate a bed mesh.
-
If you use a BLTouch, you first need to calculate your z-offset. Using Klipper’s web console, issue the
PROBE_CALIBRATE
command. Using a piece of paper, adjust the offset as you normally would. When you are satisfied with the results, runSAVE_CONFIG
. Klipper will write thez_offset
to yourprinter.cfg
file for you and restart itself to load the configuration. -
Now that you have determined the z-offset, it's important to set the
position_min
in thestepper_z
section to prevent the nozzle from colliding with the bed. To do this, you can performPROBE_CALIBRATE
again and find the lowest possible position where the paper can still move between the nozzle and the bed. This should be closer to the bed than the z-offset value you calculated so that you can perform adjustments later on, but not so close that a collision occurs. For example, my z-offset is 1.8 and the minimum value for my nozzle to avoid a collision is around 2.0. Theposition_min
for the z-axis should then be the additive inverse of the difference between the two numbers since it is that amount lower than the nozzle. In my case,-1 * (2.0-1.8) = -0.2
.[stepper_z] position_min: -0.2
-
Restart Klipper so the changes take effect. Then home the nozzle and perform
PROBE_CALIBRATE
to test that yourposition_min
is functioning correctly. If it is, when you attempt to lower the nozzle beneathposition_min
, Klipper should throw an error instead of colliding the nozzle with the bed.sudo systemctl restart klipper
-
After calculating your z-offset, you should calculate a bed mesh. Under Fluidd, this is in the
Tune
section. Under Mainsail, this is under theHeightmap
section. First home the hotend on all three axes, then calibrate a bed mesh. I’m no expert, but from what I’ve read you want to shoot to have your mesh range be within at least 0.2mm. I personally shoot for 0.1mm, but it is difficult unless your bed plate is milled with high precision. -
If your range exceeds 0.2mm, review the visualization of the mesh and adjust your bed accordingly. You can control the X/Y/Z position of the hotend using Klipper and perform the paper test at different locations to assist in leveling the bed.
-
Once you’ve finished leveling the bed, perform steps 4 and 5 again. Repeat 4-6 over and over until your bed mesh is satisfactory. Once it is, save the mesh and add this to your
printer.cfg
to load it automatically:[delayed_gcode my_delayed_gcode] initial_duration: 1.0 gcode: BED_MESH_PROFILE LOAD="default"
-
Restart Klipper once more so the mesh changes take effect.
sudo systemctl restart klipper
The following steps are are optional, but I found much of the nuance in installing Klipper was spent figuring this stuff out so I wanted to include it in the guide as well.
Crowsnest can be used to set up a webcam by defining a ~/printer_data/config/crowsnest.conf
file. But first you'll need to identify some information about your device.
The device
path can be found by running ls
against /dev/v4l/by-id/
. Afterwards, you can use v4l2-ctl -d $DEVICE --list-formats-ext
to determine the resolution
and max_fps
. You might be tempted to choose the highest available resolution and fps, but I have found that there are some bandwidth/latency issues at higher resolutions; especially on a wireless network. You’ll have to play around to see what works best.
For my Logitech C920 and C270 webcams, the best configurations I could come up with looks like this. On my wireless network, each camera yields a feed of around 15fps with the following configuration. The C920
works at a lower resolution but performs better in low-light conditions while the C270
works at a higher resolution and performs worse in low-light conditions.
[crowsnest]
log_path: ~/klipper_logs/crowsnest.log
log_level: verbose
delete_log: false
no_proxy: false
[cam c920]
mode: ustreamer
port: 8080
device: /dev/v4l/by-id/usb-046d_HD_Pro_Webcam_C920_809E7D1F-video-index0
resolution: 800x600
max_fps: 30
v4l2ctl: focus_automatic_continuous=0,focus_absolute=70,brightness=100,contrast=100,saturation=100,sharpness=200,backlight_compensation=1
custom_flags: --format=yuyv
[cam c270]
mode: ustreamer
port: 8081
device: /dev/v4l/by-id/usb-046d_0825_28E73D80-video-index0
resolution: 1280x720
max_fps: 30
v4l2ctl: brightness=100,contrast=100,saturation=100,sharpness=200,backlight_compensation=1
You'll probably want to adjust the v4l2ctl
arguments according to the placement of your camera and the lighting in the room. v4l2-ctl -d $DEVICE -l
can be used to list the camera controls that are available for each device. I've also read that you could get better performance by using WebRTC
and camera-streamer
. But these are not supported on the Raspberry Pi 5 because it lacks the required hardware encoders.
Afterwards, you'll need to reboot or restart Crowsnest.
systemctl restart crowsnest
After you’ve configured the webcam profile, go into Mainsail/Fluidd’s settings and add a webcam. Here are my settings:
I noticed that Linux was randomly choosing between wlan0
and wlan1
on boot after I installed my USB wireless adapter. wlan0
is the Raspberry Pi's internal wireless chip so that wasn't ideal. To force it to use wlan1
, the USB wireless adapter, you can add interface-name=wlan1
to the [connection]
section in the /etc/NetworkManager/system-connections/preconfigured.nmconnection
file that Raspberry Pi OS automatically created for you.
[connection]
interface-name=wlan1
Disabling power management can also allegedly help improve performance. Or at least prevent the NIC from disconnecting after some time idling. Alternatively, you might be able to use something like Sonar to accomplish the same thing.
Disabling power management can be accomplished by adding wifi.powersave = 2
to the [connection]
block. However, I noticed that when I added this to the preconfigured.nmconnection
file, iw wlan1 get power_save
showed that it was still on. So instead I created a new /etc/NetworkManager/conf.d/wifi-powersave.conf
that contained the following.
[connection]
wifi.powersave = 2
Afterwards you'll need to either reboot or restart NetworkManager.
systemctl restart NetworkManager
The Raspberry Pi 5 is capable of providing up to 1.6A to the connected USB devices. However, when the Raspberry Pi is powered on it requests the input current from the USB-C port. Since the device is powered by the GPIO pins no response is received and the Raspberry Pi limits the current for the USB devices to 600mA. In my case, this resulted in the kernel frequently resetting my wireless USB adapter when it was under load because it would exceed this threshold.
[ 129.573465] usb usb1-port1: over-current change #1
[ 129.708999] usb 1-1: USB disconnect, device number 2
[ 131.309504] usb 4-1: reset SuperSpeed USB device number 10 using xhci-hcd
This can be resolved by disabling the USB current limit with raspi-config
, manually setting the input milliamps with rpi-eeprom-config --edit
, and rebooting the device.
sudo raspi-config
# 4 Performance Options
# P4 USB Current
# Would you like the USB current limit to be disabled? -> Yes
sudo rpi-eeprom-config --edit
# Add: PSU_MAX_CURRENT=5000
# Save and exit the file: Ctrl+X -> Return
sudo reboot
The wires connecting the Raspberry Pi to the buck converter have a small amount of resistance, so the Raspberry Pi will not receive the exact voltage shown on the buck converter. Technically the acceptable range is 5.0V ±5%, but if you'd like to get it closer to 5.0v this can be accomplished by running vcgencmd pmic_read_adc EXT5V_V
on the Raspberry Pi to display the current input voltage in a watch
loop and then adjusting the buck converter's output voltage until the Raspberry Pi is receiving closer to 5V.
watch -n .1 vcgencmd pmic_read_adc EXT5V_V