Designing an Espresso Tamper for 3D Printing using OpenSCAD

Since getting our 3D printer, I’ve made a few attempts to learn how to properly use CAD software to design my own objects. Unfortunately, I haven’t had enough time to truly familiarize myself with any CAD program, which tend to be considerably complex and have steep learning curves.

Fortunately, for those of us with a programmer’s mindset, there is OpenSCAD. Essentially, it provides you a programming language for defining objects. This lets me use vim as my editor, something I’m quite comfortable with, while letting me see a live preview of my object as I save.

One of the things I’ve been meaning to design and 3D print has been a tamper for my espresso machine. Besides being useful, it’s also something very simple to design: a flat, circular base with a handle for pushing down on.

The OpenSCAD Language

The syntax used by OpenSCAD vaguely C-like and thus pretty simple to pick up. For editing within vim, the openscad.vim syntax script might be useful. OpenSCAD supports variable assignment, mathematical calculation, and includes some functions for creating basic shapes.

Note that OpenSCAD itself assigns no units to the numbers it uses. The slicers used by MakerWare interpret units from STL files as as millimeters, so for our purposes, we can rely on all numbers expressing millimeters. In this case, my tamper needs to have a diameter of 52mm.

Creating a Tamper in OpenSCAD

Defining the Tamper Attributes

I started off by creating some variables to describe the tamper:

// In milimiters:
TamperDiameter = 52;
TamperHandleDiameter = 40;
TamperBaseHeight = 5;
TamperMidSectionHeight = 50;

Now, OpenSCAD functions like cylinder() and sphere() expect to be provided a radius, so we need to do some simple calculations:

TamperThinDiameter = TamperHandleDiameter * 0.5;
TamperRadius = TamperDiameter * 0.5;
TamperHandleRadius = TamperHandleDiameter * 0.5;
TamperThinRadius = TamperThinDiameter * 0.5;

Drawing the Tamper

Since the base needs to a simple cylinder, and OpenSCAD provides the cylinder() function, we are in luck:

cylinder(h = TamperBaseHeight, TamperRadius)

This will place the cylinder directly where we want it: above z=0. The Z axis is the vertical axis.

Next, I want to add another cylinder directly above this, that tapers from the overall width of the tamper to a smaller width for the handle to attach to. In order to place the cylinder above, we must apply a transformation before drawing it. In this case, we’ll be using translate(). Note that the transformation will only apply to the next statement and will be reset afterwards.

translate([0, 0, TamperBaseHeight])
	cylinder(h = TamperMidSectionHeight, r1 = TamperRadius, r2 = TamperThinRadius);

Finally, we can create the handle using sphere(). Remember that the translation is reset after the previous cylinder, so we need to account for both the tamper base and body when drawing the handle:

translate([0, 0, TamperBaseHeight + TamperMidSectionHeight])
	sphere(TamperHandleRadius);

Smoothing the Design

Now the design of the tamper is complete, but you’ll notice that OpenSCAD draws the surfaces of the cylinders and sphere rather polygonal and not smooth. This is due to how OpenSCAD renders arcs, and ultimately will affect how it outputs to the STL file and thus how the object is printed. For our purposes, we need to have a smooth, round surface so that it will fit in the portafilter properly. OpenSCAD provides some special variables to allow you to control how arcs are calculated, with the tradeoff that the smoother the arc, the more computation time is required to render it.

To smooth things out, I added the following line above the draw functions:

$fn = 200;

Which causes the arcs to be rendered with 200 fragments. This is smooth enough for our purposes.

Using OpenSCAD for 3d Printing

Next Steps

For me, the best thing about OpenSCAD is that it gives me a familiar environment and mental model for designing objects. While I didn’t have reason to use it for this project, OpenSCAD is a full programming language that allows you to use loops, logic, functions, and libraries.

I encourage you to check out the OpenSCAD User Manual.