You are currently viewing Klipper on Ender 3

Klipper on Ender 3

Is it possible to print fast on the Ender 3 without sacrificing quality? Absolutely! With Klipper and its amazing input shaping, speeds and accelerations that are unthinkable with other firmwares are now possible.

What is Klipper?

Klipper is an alternative 3d printer firmware. Like Marlin, it is the piece of software that controls all the hardware in your 3d printer. It interprets g-code commands, controls the stepper motors and is in charge to control the temperatures.

Unlike Marlin, the most popular 3d printer firmware, Klipper is meant to work with a 3D printer mainboard alongside an additional single-board computer, like a Rasberry Pi. Klipper utilizes the additional computing power to print faster and more precisely.

What you need to install Klipper on your Ender 3

Raspberry Pi 4 Model B
64GB Micro SD Card
XT60 Y-splitter cable
Short USB A to Micro USB B Cable (30 cm or 1 foot)
ADXL345 Triple-Axis Accelerometer
LM2596S DC-DC Buck Regulator Power Module

Raspberry Pi camera
Raspberry Pi camera extension cable 1 meter
DISCLAIMER: Some links are affiliate links. As an Amazon Associate I receive a small commission (at no extra cost to you) if you make a purchase after clicking one of the affiliate links

3D printed parts to install Klipper on your Ender 3


Klipper print speed on Ender 3

It normally takes about 30 minutes to print a xyz calibration cube with the Ender 3. With Klipper, this time is reduced to less than 7 minutes!

A 3DBenchy requires around 2 hours to print with the Ender 3. Klipper can print it in only 28 minutes with no loss in quality!

How to install Klipper on Ender 3

The easiest way to get started with Klipper is to use a Raspberry Pi image like MainsailOS or FluiddPI. Download FluiddPI from GitHub.

Write the image to an SD card, using Raspberry Pi imager. Before clicking on WRITE, press CTRL+SHIFT+X to configure advanced options.

Insert the SD Card into your Raspberry Pi and turn it on.

Connect to the Raspberry Pi web interface using the hostname you set when you wrote the image (e.g. http://ender3). This gives you access to the Fluidd web interface for Klipper. Donā€™t worry about the ā€œUnable to open config fileā€ error message: we will fix this shortly.

To compile the micro-controller code for the 3d printer mainboard, connect to the Raspberry Pi with ssh. On Linux, open a terminal, on windows, open a command prompt, and type:

ssh pi@ender3

Open the Klipper Firmware Configuration tool.

pi@ender3:~ $ cd ~/klipper
pi@ender3:~ $ make menuconfig

Select STM32 for the Micro-controller architecture, STM32F103 for the processor model, a 28KiB bootloader, and the Serial communication interface. These are the valid settings for the Creality V4.2.2 or V4.2.7 mainboards.

Now exit (type Q), save the configuration (type Y) and compile the firmware by typing:

pi@ender3:~ $ make

This creates a klipper.bin file in the klipper/out directory. Copy this file to an SD Card using scp and give it a unique name (e.g. H: is the SD Card drive)

scp pi@ender3:~/klipper/out/klipper.bin H:\firmware-20211012-150900.bin

Insert the SD card into the printer and turn it on to flash the firmware. Now connect the Raspberry PI to the printer using a Micro USB B to USB cable.

Ender 3 Klipper config

The next step is to create a printer configuration file. You can find my configuration files for Klipper on GitHub. The printer.cfg file must be updated for each specific printer configuration. In this section, I explain how to adjust a generic printer configuration file.

As a starting point, I use the example that come with Klipper for the Creality 4.2.7 mainboard.

I copy and paste this configuration into a printer.cfg file, save and restart the firmware.

There are a couple of Fluidd warnings. Indeed, Fluidd requires certain settings to be defined in the configuration file. I copy and paste them from the Fluidd documentation, save & restart the firmwareā€¦

path: ~/gcode_files


#Pause/Resume functionality with support of position capture and restore.
#recover_velocity: 50.
#   When capture/restore is enabled, the speed at which to return to
#   the captured position (in mm/s). Default is 50.0 mm/s.

[gcode_macro PAUSE]
description: Pause the actual running print
rename_existing: PAUSE_BASE
# change this if you need more or less extrusion
variable_extrude: 1.0
  ##### read E from pause macro #####
  {% set E = printer["gcode_macro PAUSE"].extrude|float %}
  ##### set park positon for x and y #####
  # default is your max posion from your printer.cfg
  {% set x_park = printer.toolhead.axis_maximum.x|float - 5.0 %}
  {% set y_park = printer.toolhead.axis_maximum.y|float - 5.0 %}
  ##### calculate save lift position #####
  {% set max_z = printer.toolhead.axis_maximum.z|float %}
  {% set act_z = printer.toolhead.position.z|float %}
  {% if act_z < (max_z - 2.0) %}
      {% set z_safe = 2.0 %}
  {% else %}
      {% set z_safe = max_z - act_z %}
  {% endif %}
  ##### end of definitions #####
  {% if printer.extruder.can_extrude|lower == 'true' %}
    G1 E-{E} F2100
  {% else %}
    {action_respond_info("Extruder not hot enough")}
  {% endif %}
  {% if "xyz" in printer.toolhead.homed_axes %}
    G1 Z{z_safe} F900
    G1 X{x_park} Y{y_park} F6000
  {% else %}
    {action_respond_info("Printer not homed")}
  {% endif %} 

[gcode_macro RESUME]
description: Resume the actual running print
rename_existing: RESUME_BASE
  ##### read E from pause macro #####
  {% set E = printer["gcode_macro PAUSE"].extrude|float %}
  #### get VELOCITY parameter if specified ####
  {% if 'VELOCITY' in params|upper %}
    {% set get_params = ('VELOCITY=' + params.VELOCITY)  %}
  {%else %}
    {% set get_params = "" %}
  {% endif %}
  ##### end of definitions #####
  {% if printer.extruder.can_extrude|lower == 'true' %}
    G1 E{E} F2100
  {% else %}
    {action_respond_info("Extruder not hot enough")}
  {% endif %}  
  RESUME_BASE {get_params}

[gcode_macro CANCEL_PRINT]
description: Cancel the actual running print
rename_existing: CANCEL_PRINT_BASE

OK, all Fluidd warnings are gone.

Adding a BLTouch to Klipper

Now letā€™s configure a BLTouch Auto Bed Leveling sensor by adding a bltouch section to the configuration file:

sensor_pin: PB1
control_pin: PB0
x_offset: -36
y_offset: 0
z_offset: 2.00

I also define a safe_z_home section to home toward the center of the print area:

home_xy_position: 151,115   # Nozzle coordinates
speed: 250
z_hop: 10
z_hop_speed: 5

To use the probe in place of the z endstop, I set the stepper_z endstop_pin to ā€œprobe:z_virtual_endstopā€:

step_pin: PB5
dir_pin: !PB6
enable_pin: !PC3
microsteps: 16
rotation_distance: 8
endstop_pin: probe:z_virtual_endstop
#position_endstop: 0.0

Adding an LCD display to Klipper

In order to keep using the LCD display of my Ender 3 Pro with Klipper, I add a display section:

lcd_type: st7920
cs_pin: PB12
sclk_pin: PB13
sid_pin: PB15
encoder_pins: ^PB14, ^PB10
click_pin: ^!PB2

To make configuration changes in Klipper, I just need to update printer.cfg and restart the firmware.

Bed leveling configuration

Now I configure Auto Bed Leveling by adding a bed_mesh section to the config file:

speed: 250
horizontal_move_z: 5
mesh_min: 40,40     # Probe coordinates
mesh_max: 190, 190
probe_count: 3,3

I also add a G29 macro to emulate Marlinā€™s G29 Gcode which is not available in Klipper:

[gcode_macro G29]
 G1 X151 Y115 Z5 F15000

To perform auto bed leveling, I issue a G29 command in the console. Fluidd provides a graphical tool to visualize the result of the bed mesh leveling.

Hardware setup

We will configure pressure advance and input shaping in a short moment. Before that, I want to mount the Raspberry Pi to the printer and power it directly from the Ender 3 power supply. This is optional but results in a cleaner and more organized setup.

I printed a Raspberry Pi enclosure which mounts the Raspberry Pi to the Ender 3’s extruded aluminum rails. In order to power the Raspberry Pi directly from the Ender 3 power supply, I use a XT60 Y-splitter cable and reduce the voltage to 5 volts with an LM2596 buck converter.

Finally, I connect the Raspberry Pi to the printer with a micro USB B to USB cable.

Adding a camera

Optionally you can use a Raspberry Pi camera to remotely monitor the printer from the web interfaceā€¦ For the camera to work it must be enabled in raspi-config.

Klipper input shaping

Now letā€™s take a look at Klipperā€™s most awesome feature: Input shapingā€¦

Using an ADXL 345 accelerometer connected to the Raspberry Pi, we will measure the resonance frequencies of the printer. Knowing the resonance frequencies allows Klipper to control the print head in such a way that it cancels its own vibrations!

We need to do some additional setup on the Pi first in order to perform these tests. Just follow the steps in the Klipper documentationā€¦ This completes the configuration. Letā€™s check if we can read some data from the accelerometerā€¦

I start the resonance test on the X axis by mounting the accelerometer on the print head. The test shakes the printhead along the X axis and measure printer vibrations amplitude as function of frequency.

To perform the resonance test on the Y axis, I mount the accelerometer on the bed.

To post-process the accelerometer data and compute the optimal input shaping parameters, I run the calibrate_shaper Python script as per the documentation. This script generates two plots, one for X and one for Y and makes recommendations about which input shaper settings to use.

Frequency response – X axis
Frequency response – Y axis

All I have to do to enable input shaping is to add an input_shaper section to the printer configuration file and cut and paste the recommended settings:

shaper_freq_x: 67.8
shaper_type_x: 3hump_ei
shaper_freq_y: 34.8
shaper_type_y: mzv

Letā€™s compare the print quality with and without input shaping by printing a test model. Wow! The result is impressive! Input shaping almost completely eliminates ringing even when using accelerations as high as 7000 mm/sĀ²!

Klipper pressure advance

The next step is to tune pressure advance. Pressure advance does two useful things: it reduces ooze during non extruding-moves and it reduces blobbing during cornering.

Tuning pressure advance is done by printing a test model. The TUNING_TOWER command instructs Klipper to increase the pressure_advance value by 0.005 per mm of Z height.

Inspect the print and then use a caliper to find the height that has the best quality corners.

Compute the pressure_advance value as the measured height x 0.005

Add the pressure advance value in the extruder section.

In my case, the pressure advance value was too high. I reduced the value from 0.0725 to 0.04 and got much better print qualityā€¦