3D printer hot-rodding: Klipper vs. Marlin

A few months back, I bought my first 3D printer, an Anet A8 kit for somewhere around $150, shipped.  It was an OK printer to start with, but various upgrades (and a repair or two) have made it into a fairly solid workhorse that still hasn’t come home from the office.

I replaced the stock firmware (whatever it was) with Marlin fairly early on.  When the original motherboard crapped out after a month or two, I replaced it with an Arduino Mega and RAMPS 1.4 combination with DRV8825 stepper drivers, which made the printer both quieter and more precise.

I’m now building a Hypercube 300 for use at home.  While looking into hardware and software options for that, I ran across Klipper, a relative newcomer with a different idea: move most of the computations for 3D printing out of the weedy little 16-MHz 8-bit AVR microcontroller on an Arduino and onto the much faster 1.4-GHz quad-core 64-bit ARM microprocessor in a Raspberry Pi 3.  (Raspbian only has a 32-bit userspace, but I’ve built Gentoo with a 64-bit userspace…but that’s straying off-topic.)  The Arduino is retained, but only as a real-time auxiliary controller that only makes sure the commands sent to it by the Raspberry Pi are carried out on time and in the right order.

I thought I’d seen some video of a Klipper-powered Hypercube a while back…can’t find it now, but here’s a Creality CR10 running at 100 mm/s with Klipper.  My A8’s been loafing along at 60.  I need to look into this.

Since I already had a Raspberry Pi running OctoPrint plugged into the A8, I thought I’d give Klipper a shot.  It took a while to get the configuration sorted out (it’s here), but this morning I got it pretty much stabilized.  First print was a Cali Dog, and it turned out just fine at 60 mm/s.  With basic functionality sorted, I figured I’d try seeing how fast my printer could go.

I knocked together a little cylinder in OpenSCAD:

cylinder(50, d=20, $fn=90);

I sliced it in Cura 3.4.1 with some basic settings: 60 mm/s base speed, 2 perimeters all around, 15% cubic infill, and a 350-mm skirt to get the nozzle primed.  I also used a set of ChangeAtZ post-processing scripts to increase the feedrate every 8 mm, from 100% at the bottom to 200% at the top.  This produces 8-mm sections printed at 60, 72, 84, 96, and 108 mm/s, capped by a 10-mm section printed at 120 mm/s.  That’s the theory, at least.

I used Dazzle Light red PLA for all prints, laid down with a 210°C hotend onto a 55°C bed.

Since Klipper was already on the printer, I let it go first:

You can hear it get faster on each programmed feedrate change, and the finished quality is pretty good.  There’s what looks like a seam on one side where I think it always started the outer wall, but that’s it.  Print time was 20 minutes.

Next up, I flashed Marlin back onto the printer.  I only tweaked the gcode for different homing and bed-leveling commands used by Klipper and Marlin; the rest was unaltered.  Here’s what I got with Marlin:

Even at 60 mm/s, the printer was stuttering on the inner perimeter.  Each “circle” is cut into 90 short line segments, and the resultant flood of gcode couldn’t be sent fast enough.  At 72 mm/s, it got even worse.  Now, the printer was stuttering on the (visible) outer perimeter as well, which produced stippling artifacts where the printhead stopped and restarted.  It never got any faster; if it was having trouble keeping up at slower speeds, it certainly wasn’t going to do any better with faster speeds.  To add insult to injury, print time increased to 33 minutes.  Slower and worse quality.

I’d heard somewhere that sometimes the USB serial connection from OctoPrint to Marlin can be a bottleneck, so I put the gcode on an SD card and printed it again:

Not much faster than when printing from OctoPrint (finished in about 30 minutes), but at least the quality was much better.  It wasn’t too different from what Klipper produced, other than that it took about 50% longer.

Here’s a close-up of the three prints side-by-side:

(K=Klipper, M=Marlin streamed from OctoPrint, MS=Marlin printed from SD card)

Even without zooming in, the stippling is quite visible on the middle cylinder.

Bottom line: Klipper’s a little bit more tricky to install, and it’s not yet as loaded with features as Marlin (Klipper currently does nothing with the rotary encoder or kill button on the display, and it doesn’t have automated filament changing), but the speed and quality improvements make it a winner for most daily use.  If I need something that only Marlin handles for now, it’s easy enough to switch back to it temporarily.