I have been exploring different firmware options for my TronXY X5S 3D Printer, and Klipper is interesting in that it runs the CNC control on a single board computer (SBC) and uses the 3D printer's control board as a motor controller. I've also added a touchscreen display to the SBC running Klipper for easy printer control.

Klipper is convenient in that the printer can be controlled via a WiFi interface. No need to use an SDCard to copy gcode files from the computer to the printer anymore, simply upload to OctoPrint and print away! The web UI is standard Octoprint, or you can install the Octoprint TouchUI plugin as shown above, depending what you prefer.

Even better though, Klipper offloads the motion planning from the control board to the single board computer. This allows for faster, more accurate motion planning and, hopefully, better prints.

The one downside of this setup is that the SBC needs to be properly powered down before turning off the power supply. This could be solved by a soft power switch, but I haven't gotten around to this yet.

Choosing a Linux SBC

Klipper needs a reasonable amount of computational power and while it can be run on any single board computer, a Raspberry Pi 3 is recommended

That said, I will be using the Orange Pi PC Plus I have on hand.

Running the whole printer stack plus Firefox, load on the Orange Pi PC Plus seems reasonable while printing:

I also tested out an Orange Pi Zero 512Mb I have on hand which runs fine without the display.

There are many, many SBCs with similar specs. I will be using armbian for the operating system. Armbian is an Ubuntu port for many ARM based SBCs. You can see the list of boards supported by armbian here and any one of these with specs similar or greater than the Raspberry Pi 3 should work fine.

You'll also need a MicroSD card. I'm using a 16GB Class10 MicroSD card

Optionally, we'll install a 5" HDMI display with a resistive touch panel. You'll also need a short HDMI cable if you're using an HDMI display. Note that the display is easy to get working, just plug it in, but the touch screen is much more difficult and your luck may vary depending on the precise display. I resorted to using a wireless mouse / keyboard combo

Power considerations

I will be using a 3A, 5v Voltage Regulator to power the Orange Pi PC.

Be sure to pick a power source that can provide the maximum current your board requires +20% extra.

If your board is unreliable or reboots randomly or is doing other strange things, it is likely your power supply is the problem.

Installing the Operating system

As mentioned, I'm using armbian on my Orange Pi PC. First order of business is installing the OS onto the 8GB onboard eMMC, which is sort of like an SD card soldered right to the board. This way, we can use the MicroSD slot for something else.

The full armbian guide to install to eMMC is here, but I'll walk you through the steps in this guide as well.

Download the latest version for your board and extract the 7z file, on my mac this is done in the terminal with:

wget https://dl.armbian.com/orangepipcplus/Ubuntu_bionic_next.7z
open Ubuntu_bionic_next.7z

Download and install Etcher

Create a bootable MicroSD card as follows:

  • insert a MicroSD card into your computer
  • run Etcher
  • for the image, pick the Armbian_5.65_Orangepipcplus_Ubuntu_bionic_next_4.14.78.img file you downloaded
  • for the target device, pick the SD card you inserted
  • hit start

The disk will be unreadable when done and your Mac (or maybe Windows machine too) will prompt you to eject it.

Eject it from your computer and insert the SD card into your Orange Pi.

Power on your Orange Pi.

Note that if you run into issues later, such as WiFi not working, it's probably because your power supply cannot supply enough power. Switch to a power supply that can supply more amperage and try again.

Once you've logged in with the username root and password 1234 you will be prompted to change the password. Do this then you'll be prompted to create a new user. Name the new user octoprint and set a password.

Now, logged in as root, run nand-sata-install. You'll see a few prompts, accept the defaults by hitting ENTER and soon the copy will begin. When it's complete, you will be prompted to power down the computer. At this point you can unplug the power and pull out the SD card. Plug the power back in and you should get a prompt to login again. Now you're running from eMMC.

Updates and Installing Dependencies

To connect to the Orange Pi, use a UART to serial adapter or plug it into the network and SSH.

For example the serial connection to the Pi Zero looks like the following, image source:

Configure wifi, if not connected via ethernet:

sudo nmtui

Then pick Activate and choose your network. Enter a password, pick activate then exit. Check your connection with:

iwconfig

Connections configured with nmtui will persist across reboots, so don't mess with your /etc/networking config files, just let nmtui do its thing.

Next we'll update the OS and install the necessary dependencies.

Start by updating the system with:

sudo apt update
sudo apt -y upgrade

Installing Octoprint

install Octoprint's Dependencies with:

sudo apt install -y python-pip python-dev git virtualenv python-setuptools psmisc

Add the Octoprint user to the necessary groups:

sudo usermod -a -G tty octoprint
sudo usermod -a -G dialout octoprint

Where `1.3.10` was the most recent release when I wrote this, feel free to upgrade. You can find [a list of Octoprint releases here](https://github.com/foosel/OctoPrint/releases)
cd $HOME
git clone --depth 1 --branch 1.3.10 https://github.com/foosel/OctoPrint.git
cd OctoPrint
virtualenv venv
source ./venv/bin/activate
pip install pyserial
pip install .
deactivate

Install a systemd service:

sudo tee -a /etc/systemd/system/octoprint.service << EOF
[Unit]
    Description=OctoPrint service

[Service]
    User=octoprint
    ExecStart=/home/octoprint/OctoPrint/venv/bin/octoprint

[Install]
    WantedBy=multi-user.target
EOF

Start the service with:

sudo systemctl enable octoprint
sudo systemctl start octoprint

Install Klipper

  • The first step is to install Klipper on the Orange Pi

Where `v0.7.0` was the most recent release when I wrote this, feel free to upgrade. You can find [a list of Klipper releases here](https://github.com/KevinOConnor/klipper/releases)
cd $HOME
git clone --depth 1 --branch v0.7.0 https://github.com/KevinOConnor/klipper.git
cd klipper
cd scripts
wget https://raw.githubusercontent.com/KevinOConnor/klipper/master/scripts/install-ubuntu-18.04.sh
chmod +x install-ubuntu-18.04.sh
cd ..
./scripts/install-ubuntu-18.04.sh

Enter your password when prompted

  • Next step is to install Klipper on the 3D Printer control board
cd $HOME/klipper
make menuconfig

Set the settings to use the 1284P, as this is the processor on the Melzi 2.0 control board on the TronXY X5S

Pick Exit and run:

make

We'll need to connect the Orange Pi to the TronXY control board.

You can either connect the boards via USB or via a UART. I used USB since there are no UART ports exposed on the Melzi board on the TronXY X5S. Using USB is as easy as plugging it in.

If you're using USB, skip to the Flashing Klipper section below. For UART connections, continue reading.

If you do have a 3D printer control board with a UART connection available, you can connect it to on of the UARTS available on the the Orange Pi as shown by the pinout here:

Source: https://linux-sunxi.org/Orange_Pi_PC#Expansion_Port

You will also need to enable a UART on the OrangePi. Remember though, you don't need to do this if you're using the USB connection.

There is documentation for the armbian-config tool we'll be using, here: https://docs.armbian.com/User-Guide_Armbian-Config/

Run:

sudo armbian-config

Open System -> Hardware find uart1 (or uart3 or whatever uart you chose when connected the 3D printer control board), enable it and hit save.

You'll be asked if you want to reboot. Hit OK.

Flashing Klipper

Now flash klipper with the following for USB connections:

sudo service klipper stop
# for USB
avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
sudo service klipper start

Or if you're using a UART, the command would be something like:

sudo service klipper stop
# for UART1
avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyS1 -U out/klipper.elf.hex
sudo service klipper start

Octoprint Configuration

Open http://192.168.1.100:5000/ where 192.168.1.100 is the IP of your Orange Pi.

Open the Serial Connection settings /tmp/printer and save.

Then under the Serial Connection -> Behaviour setting, change it to: Cancel any ongoing prints but stay connected to the printer and save.

Then open the terminal and type status and hit [send]. It should respond with an error about the config file. Now configure Klipper.

Klipper Configuration

Copy the default TronXY X5S config into your home directory:

cp ~/klipper/config/printer-tronxy-x5s-2018.cfg ~/printer.cfg

Or use my tuned config:

curl https://gist.githubusercontent.com/nathantsoi/5193550c12c5ec349b76d6fe4d5a7045/raw/7d3653ea0ef4af1eb81dd462bfd6c92621ec1370/tronxy-x5s-klipper-printer.cfg -o ~/printer.cfg

Then run restart from the octoprint termial.

Next you should run all the Config Checks

I have a 0.6mm nozzle, so I set that in the ~/printer.cfg

I also copied my extruder steps/mm settings from marlin, by taking this value from my Marlin steps per unit config:

echo:Steps per unit:
echo:  M92 X80.00 Y80.00 Z400.00 E458.00

And taking 1 over this value: 1/458 = .002183

In the OctoPrint terminal, run RESTART after changing the config to apply the settings

Now, run a test print with your regular slicer settings for your printer and make sure everything is working reasonably well.

Tuning Pressure Advance

Since we'll be using the Pressure Advance feature of Klipper, be sure to turn off retraction, jerk control and all flow compensation features in your slicer.

Slicer Configuration

In Cura, this means disabling:

Outer Wall Wipe Distance Infill Wipe Distance Retraction Equalize Filament Flow Enable Jerk Control Compensate Wall Overlaps

See https://github.com/KevinOConnor/klipper/blob/master/docs/Pressure_Advance.md#tuning-pressure-advance for details.

In the octoprint terminal run:

SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
SET_PRESSURE_ADVANCE ADVANCE_LOOKAHEAD_TIME=0
SET_PRESSURE_ADVANCE ADVANCE=0.050

You should see:

Send: SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
Recv: // max_velocity: 300.000000
Recv: // max_accel: 500.000000
Recv: // max_accel_to_decel: 500.000000
Recv: // square_corner_velocity: 1.000000
Recv: ok
[...]
Send: SET_PRESSURE_ADVANCE ADVANCE_LOOKAHEAD_TIME=0
Recv: // pressure_advance: 0.000000
Recv: // pressure_advance_lookahead_time: 0.000000
Recv: ok
[...]
Send: SET_PRESSURE_ADVANCE ADVANCE=0.050
Recv: // pressure_advance: 0.050000
Recv: // pressure_advance_lookahead_time: 0.000000
Recv: ok

Now download and print https://github.com/KevinOConnor/klipper/blob/master/docs/prints/square.stl

Inspect the corners of the print after printing and if there are blobs, increase SET_PRESSURE_ADVANCE ADVANCE=0.050 by 0.050 and try again until you have no blobbing.

You want the smallest value of SET_PRESSURE_ADVANCE ADVANCE=[x] that has no blobs. Note that this value may vary by printer, extruder and filament.

For my Titan E3D Extruder and DIY PETg filament, I ended up with a SET_PRESSURE_ADVANCE ADVANCE=0.100 which you'll want to add to your printer.cfg:

[extruder]
#...
filament_diameter: 1.750
pressure_advance: 0.100
pressure_advance_lookahead_time: 0.010
heater_pin: PD5
#...

Power button

I used to just use the power switch on my printer to turn it on and off, but since the SBC should be cleanly shutdown to avoid data corruption, I open the octoprint interface and choose System -> Shutdown to turn off the SBC before cutting power to the printer.

In the future, I plan to build a soft power-down (and power-up) switch to take care of all this in one button press. I'll leave that for a future project for now though.

Debugging

If you run into any trouble, you can find the klipper log here: /var/log/klipper.log

Armbian Desktop

Running a display is optional and fraught with peril. Just getting the display working is easy enough, as long as you use an HDMI display, (don't get an SPI display if you want to use a touch screen, since the Orange Pi only has 1 SPI). It is possible to run the touch screen with a software SPI, but this is even more difficult. Even with the HDMI display, the touch screen is very difficult. The resistive touch panels offer fairly terrible performance and capacitive screens are rare. Moreover, running a web browser on the Orange Pi can negatively impact performance (though in my tests the Orange Pi PC seems to handle the load OK). It might not be worth running a display at all, proceed at your own risk.

If you plan on using a display, update Armbian to include a desktop environment.

Go to System -> Minimal, it will install a minimal desktop. After it is done, reboot.

If your display is upside down, edit the file:

sudo vim /etc/X11/Xsession.d/45custom_xrandr-settings

And put this in it:

DISPLAY=:0 xrandr --output HDMI-1 --rotate inverted

Then restart the display manager with:

sudo systemctl restart display-manager

Touch Display

This part is optional and quite tricky to get working, but if you have a touch panel on your display, you can set it up as follows.

The octoprint touch UI is pretty awesome.

I ran into a couple issues setting this up. The MISO/MOSI lines on my display's silkscreen were reversed, which I only figured out by checking the continuity of each pin from the xpt2046 to the output pins.

Also, I had to remove the 2.54mm header from the display, since the CS line was wired to the wrong pin.

Here is the final photo of the wiring:

Run:

sudo armbian-config

Open Software and pick Headers. This will automatically install linux-headers-next-sunxi. Pick Cancel from the top level menu to exit.

Enable SPI in /boot/armbianEnv.txt by setting:

overlay_prefix=sun8i-h3
overlays=spi-spidev uart3
param_spidev_spi_bus=0

This will enable SPI on: SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3, futher described in /boot/dtb/overlay/README.sun8i-h3-overlays

Compile the driver:

mkdir ads7846
cd ads7846
curl https://sourceforge.net/p/openipmi/linux-ipmi/ci/master/tree/drivers/input/touchscreen/ads7846.c?format=raw -o ads7846.c
curl https://gist.githubusercontent.com/nathantsoi/488790d5165b09233ce15c2c13987081/raw/0f20378f379b3a9bb528d84a3b56f58c78f87912/Makefile -o Makefile
make
sudo make install
depmod

Compile fbtft_tools:

cd $HOME
git clone https://github.com/notro/fbtft_tools/
cd fbtft_tools/ads7846_device
make
sudo make install
sudo depmod

Load it on boot:

echo "ads7846\nads7846_device" | sudo tee -a /etc/modules-load.d/ads7846.conf 
echo "options ads7846_device model=7846 cs=0 gpio_pendown=2 keep_vref_on=1 swap_xy=0 pressure_max=255 x_plate_ohms=200 x_min=3900 x_max=200 y_min=3900 y_max=200" | sudo tee -a /etc/modprobe.d/ads7846_device.conf

When you're testing the ads7846_device you can edit the file and run rmmod ads7846_device && modprobe ads7846_device to reload the config

You can see all the configuration options here: https://github.com/notro/fbtft_tools/wiki/ads7846_device#arguments

While the touchscreen will be working, albeit pretty terribly at this point, it seems that tslib needs to be compiled from source to run ts_calibrate and properly configure the touchscreen. Perhaps I'll revisit this at some point, until then, if anyone gets a resistive touchscreen working well with Armbian, please let me know!

Further Reading

Official Klipper Documentation

Official Orange Pi PC Documentation