Introduction

I have wanted a 3D printer ever since Vik Olliver spoke at Linux.Conf.Au 2006 about the RepRap project -- a 3D printer that "prints itself" -- and then showed working models at later Linux.Conf.Au conferences. Vik went on to spend years working on the RepRap project, helping open up 3D printing to makers.

The whole idea of a "self replicating machine" was inspiring,and over the years I have seen many makers produce lots of custom one off designs using 3D printers, as the technology has matured. However I had no practical use for a 3D Printer, particular at the early innovation stage, and so I just looked on in admiration from a distance.

Over the past couple of years FDM 3D printing ("Fused Deposition Modelling", sometimes called "Fused Filament Fabrication" or "FFF") has matured to the point that there are numerous 3D printing machines, many of which descend directly or indirectly from the RepRap project.

The "Original Prusa I3 MK3s" is one of the best known for maximum refinement of the RepRap deisgn, starting with the Prusa Mendel, and has great reviews. But it is also US$750 even as a DIY kit, plus shipping, and it's costly enough to require paying GST on the way into New Zealand as well (so all up NZ$1350 or so). Which still was more than I could justify for an something to use occasionally to make custom parts, and "experiment with 3D design/printing".

Creality Ender 3

After a bit of a rocky start (with controversy around source license compliance, and quality control/cost optimisation choices), the Creality Ender 3 has emerged as one of the most popular, highly reviewed budget 3D printers, and considered a "good printer for the price" particularly when it is on sale (Ender 3 Unboxing).

I have been aware of Creality for a couple of years, ever since Naomi Wu started working with Creality to improve their relationship with the western maker community (both Creality and Naomi are based in Shenzhen, Guangdong, China). Naomi's work led to the Creality Ender 3 being one of the first Open Source Hardware Association Certified projects out of China (Ender 3 OSHWA certificate -- CN000003; see also Naomi's announcement video), with the firmware source code, PCB design, and mechanical hardware all on GitHub. (Naomi is also responsible for OSHWA CN000001, and encouraging OSHWA CN000004 and OSHWA CN000005 -- the first for her sino:bit project, and the other two for the Creality CR-10 3D Printer.)

A few weeks ago, reminded by the USA "4th of July" sales, I happened to see the Creality Ender 3 on sale at Kiwi 3D for NZ$500, including "free" shipping and GST, and finally ordered one -- spending the $NZ$100 discount on some PLA filament to have something to start testing the printer with. (While the printer was available from overseas, including direct from Creality for cheaper -- US$189.99 is a common sale price -- by the time that shipping and GST at import were added, the sale price in New Zealand was was less than 20% more than the likely landed price importing it myself -- and by buying from a New Zealand retailer it arrived just over one business day after ordering, with much less hassle.)

The Creality Ender 3 arrives as a "partially assembled" kit -- the base print bed / Y axis, and the extruder unit are assembled, and the remainder is flat packed for end user assembly. I spent an afternoon carefully assembly the kit, following the Tomb of 3D Printed Horrors "Creality Ender 3 assembly and pro build tips" video guide, as well as the "Creality Ender-3 Official Assembly Instruction" PDF (downloaded from Creality's site); the PDF guide has more instructional text than the provided "one large sheet" diagram.

Other than challenges identifying the correct parts needed at each step (there are a lot of subtly different bolt sizes for instance and extras supplied for many of them), the assembly went fairly smoothly -- and the "Tomb of 3D Printed Horrors" build video helped identify some things to check during the build at times when they were easy to change, avoiding finding those issues later when they were more difficult to correct. (Of note, my base arrived so that it was slightly wobbly on a flat surface, and a couple of the bed levelling knobs and springs had come loose during shipping; but putting the assembled unit on a flat surface and slightly loosening the two bolts holding the right -- LCD panel -- side base on to the unit was enough to allow everything to drop into alignment with no wobble, and the bed levelling springs and knobs were easy to put back onto the base. The only other surprise I found was that the control box fan does not spin all the time, seemingly not even at the start of a print -- but it definitely spins once the printing is under way, so presumably there is a thermal sensor for the control box fan now too. My XT60 power supply connectors appear to be genuine, which was not true of all earlier Creality Ender 3 printers due to a quality control issue.)

After assembly, and manual bed levelling, my Ender 3 printed the "Tomb of 3D Printed Horrors" bed levelling test model (downloaded from their DropBox) successfully, and I declared success on the initial assembly. (The "bed levelling test" was supplied as G-Code, which was convenient for just getting started -- but fortunately also short enough I could manually review it to determine it was safe before sending it to my printer; as Thomas Sanladerer points out G-Code can include instructions which make changes that persist over power cycling the device, or attempt to cause mechanical damage, so verifying G-Code is important if it comes from an unknown origin.)

Ultimaker Cura

The usual exchange format for 3D printing models is STL, and this is what is available from, eg, Thingiverse and other 3D model sites. STL is a widely supported 3D model format that describes 3D objects in terms of meshes of triangles (and is encoded either in ASCII, or in a binary format; not all STL files are 3D printable but most 3D printable models are provided as STL files).

For 3D FDM printing, the STL model needs to be translated by a "slicer", which decides how to move the X / Y / Z axes of the printer to produce a physical representation of the model, and produces a GCode file to instruct the printer on what to do. In software terms the STL file is the source code, the slicer is the compiler, and the GCode is the executable file (which is one reason why GCode from unknown sources cannot be completely trusted; see above).

There are several Open Source 3D slicers, including:

I decided to start with Cura because Maker's Muse found that the Cura slicer chose movement paths that better reduced filament stringing on the Creality Ender 3, Thomas Pietrowski maintains an Ubuntu PPA for Cura (stable version), and several makers published Cura profiles for the Ender 3 that worked for them, so it seemed like a good place to start. While writing this blog post, I also found another guide to tuning Cura for the Ender 3 -- 6mm extruder retraction at 25mm/s, without z-hop, seems to be the magic setting to reduce stringing, resulting in a slight "nozzle wipe" over the part. (These days Creality ship a Microsoft Windows only "Creality Slicer" which I have not used; but as far as I can tell Creality used to ship with Cura, which is another reason to start with Cura for the Ender 3.)

Unfortunately the latest releases of Cura 4.x will not run on older Ubuntu versions, including Ubuntu 16.04 LTS and Ubuntu 18.04 LTS, because they rely on newer QT library functions. However with a bit of tweaking, I was able to get Cura running in an Ubuntu 19.04 ("Disco") Docker image, using Thomas's Ubuntu PPA packages, following the approach of Steve Baker, but updated to a later Ubuntu version and a later Cura version, and with some startup tweaks. (My cura-docker repository.)

For now I have simply used the built in Creality Ender 3 profile provided with Cura 4.1, for PLA filament, which prints at 200C with a 60C bed. It seems to work reasonably well for me, with the "Kiwi 3D PLA Filament". (I did notice that Cura wanted to "phone home" with usage information, which I dislike, but it is possible to disable the feature early in the application setup by clicking on "more information" when the panel advising it will "send anonymized data" and then choosing to disable that feature, and that setting appears to be persisted in the Cura preferences.

OpenSCAD

In order to have the whole 3D printing experience, I wanted to try designing my own 3D model and printing it. As with most beginning 3D printers, in the true RepRap fashion, the first one does is print something to improve the printer. Since the manual bed levelling is a common issue in Ender 3 printers, and the relatively extended, relatively thin springs are commonly identified as something to upgraded, I decided to tackle that issue first by creating a shim to ensure the springs were more compressed. This had the advantage of being a trivial 3D object to model -- a small washer -- which was a great "first project". (While writing this blog post I also found someone created an Ender 3 Bed Spring Stabliser, which combines the shim with an inner spring support to fill the gap between the inner bolt and the outer spring; which I might investigate further later.)

Since I am a programmer at heart, and I was designing a simple mechanical part, I decided to use OpenSCAD to model the part (conveniently it was packaged for Ubuntu 16.04 LTS, in the Ubuntu repository, so I could just install it; that is a somewhat old version but sufficient for my simple initial needs). OpenSCAD is a compiler for a parametric [modelling] language -- it translates .scad source files containing combinations of simple objects into (ASCII) STL files. Following the first couple of parts of a four part OpenSCAD tutorial got me started pretty quickly (note: there is no fifth part; by the time they finished the fourth part they decided a fifth part was not needed...).

After some experimentation I came up with this simple OpenSCAD model:

$fa=2;   // default facet angle
$fs=1;   // default facet size

// Parametric shim washer
//
// Measurements are diameter.  We divide them in half to get required radius.
//
module shim_washer(od, id, height, offset=0.5) {
    difference() {
        cylinder(r=(od/2), h=height);
        translate([0,0,-offset]) cylinder(r=(id/2),  h=height+(2*offset));
    }
}

shim_washer(od=13, id=6, height=2.75);

which I could load into OpenSCAD (using vim for editing, rather than the built in editing pane which can be closed), preview it, then render it (F6), validate it, and then export it as a STL file (File -> Export -> Export as STL...), and then load into Cura for "slicing" to convert it to GCode. (Conveniently, both OpenSCAD and Cura default to auto-reload of the model when their relevant files are written, which means having vim, OpenSCAD, and Cura all open, and saving changes as they are ready works quite well; the one issue I found was that while Cura will auto reload models, if you have duplicated a model for printing, it appears to only reload one of them :-( So I spent a while clearing the build bed and re-duplicating / re-laying out three of them for printing efficiently at once.)

It took a few attempts to get reasonable sized shims to put under the springs -- my first attempt confused diameter and radius resulting in washers much too wide, my second had the inner hole a little too small, my third had the shim a little too high (at 5mm), and the fourth worked. But each attempt only took about 20 minutes, even with beginner stumbling blocks, so it was fairly quick to iterate to a useful solution. I ended up printing only three shim washers, for the three corners without the bed power support bar -- and settled on the 2.75mm as being approximately the same height as that bed support bar. (If I were doing it again I might pick a 3mm height, and would probably also try a 5mm inner diameter; 4mm was definitely too tight, but 6mm is a little loose.)

Overall I was pleased to be able to go from conception to something that is now installed -- printed in black PLA, with 0.2mm layers and 70% infill for strength -- on my 3D printer. (I installed the shims at the bottom of the springs, immediately above the print bed support base, which should leave them more than far away from the bed heater that they do not get hot; and besides the bed will usually only be 60C, which is well under the PLA melting temperature.)

Next steps

Most likely my next step will be to install OctoPrint, probably via OctoPi on a Raspberry Pi 3B that I have sitting around, to enable "network printing". SneakerNetting images to print back and forth between my computer and the Ender 3 gets old quickly, and the Ender 3 "TF" ("TransFlash", aka MicroSD) slot is a bit fiddly to reach anyway, in addition to the need to put it into/take it out of a USB adapter.

Possibly then followed by 3D printing a few more of the "recommended upgrades" for the Ender 3, such as a filament guide (one of the main design flaws of the Ender 3 is that, as supplied, the filament is practically certain to drag along the Z axis lead screw in normal use, picking up oil -- and removing needed oil from that lead screw).

I might also upgrade the Marlin Firmware (on GitHub) on my Ender 3 with a more recent version, as I believe Creality are still shipping firmware based on the Marlin 1.0.1 firmware, but there is Marlin 1.1.x firmware including Ender 3 example configuration available now. The Creality Ender 3 mainboard apparently does not include an Arduino Bootloader (for space reasons), but it is possible to use another Arduino as an In-circuit Serial Programmer and I have a couple of suitable Arduino boards available. Being able to upgrade the firmware is one of the advantages of Open Source hardware :-)