Tag Archives: eagle

Designing a capacitive touch wheel in OpenSCAD and EAGLE

I’m a big fan of DIY capacitive touch sensors. Without any custom parts or special fabrication techniques (beyond regular PCB creation), you can create really impressive interfaces. I first used this on the Question Block Lamp (Getting ready to ship! Order yours now!), and ever since I’ve been looking for great places to apply the technique.

Recently, I decided that one of my projects would really benefit from the addition of a capacitive touch wheel. I didn’t want to re-invent the wheel, so to speak, so I started Googling for designs.

The design

The page for the Arduino CapSense library sent me looking for the Quantum Scrollwheel sensor datasheet, which contains a handy schematic for a scroll wheel. wheel_schematic So how’s this thing supposed to work? The wheel is composed of three separate, identical electrodes that are tessellated together to form a ring. Each electrode is interleaved with its neighbors such that as you move away from the center of one electrode, the current electrode exposes less and less surface area while the next one exposes more and more. This means that if you measure the capacitance values of all three electrodes in succession, you should see approximately complimentary values on two of them, and an “untouched” value on the third. This should be sufficient information to figure out the orientation of the touch.

Ok, so how do we draw this?

The schematic for this wheel design is straight-forward enough, but this is far from an easy shape to draw. As I highlighted in a previous post, EAGLE really isn’t going to help you draw something like this, so you need to turn to another program to do it and then import the results. My tool of choice is OpenSCAD, so I got to work on a script to generate this shape.

Since all the electrodes are identical, we really only have to draw one and then rotate some copies around to complete the tessellation. Only, this shape is a bit unique – the curved triangular sections don’t lend themselves to being described with simple OpenSCAD primitives.

The first approach I considered was to think of each curved triangle is as a regular 2D triangle, only rendered incrementally along an arc. Polar coordinates would make this especially easy to describe. While this feels like it would be an elegant way to express these sections, OpenSCAD isn’t friendly to this approach. You can define arbitrary polygons, but you can’t add points to a polygon with any sort of native loop. In the past, when I had no other choice, I’ve written a Ruby script to generate the point list manually and then pasted them into my OpenSCAD script. This is clunky and involved, so I try to avoid it if at all possible.

However, I came up with another way to express this shape that is more amenable to being generated directly in OpenSCAD. It’s a technique I found on the OpenSCAD mailing list that the creator referred to as “chain hull”. A chain hull of a list of primitives is the union of the convex hulls of neighboring pairs of said primitives. Did you follow that? This page has a good visual example of the operation in action. I think chain hulling is a brilliant use of the primitive functions available in OpenSCAD and allows for complex shapes to be described very concisely.

To build our curved triangle sections with a chain hull, I laid out an arc of very thin squares ranging from the minimum width to the maximum width in a linear fashion. The chain hull magic takes each pair of squares, hulls them, and then unions all the results. Here’s the code that generates the shape:

And here’s a view of the intermediate shapes and the resulting chain hull:


The base shapes, and the chain hull that gets drawn around them.

With a module built to create these curved triangles, the rest of the script is glue code to put the triangles in the right places. I wrote one module to generate the concentric/alternating triangles for an entire electrode, and then another module to generate the whole scroll wheel by rotating three electrodes into their proper positions. The final result comes out looking pretty good:


One gotcha I figured out in the course of this project is that EAGLE really doesn’t like to have zero-width lines, even if they’re just describing the outline of a polygon. To account for this, I drew the wheel sections a tiny bit smaller to account for the line width I’d use in EAGLE. This is not unlike accounting for the kerf on a laser cutter, so if you’ve done that before you’ll be familiar.

Getting it into EAGLE

The next step is getting it out of OpenSCAD and into EAGLE. I wrote about using OpenSCAD shapes as board outlines in another post, but this case is a little different. Board outlines can just be simple wires, but polygons need to be closed shapes. The DXFs that come out of OpenSCAD are just collections of segments. I needed a way to convert these segment lists into ordered lists of points that they could be entered with the POLYGON command. So, of course, I wrote a Ruby script to do it.

The operation for converting a set of segments into a ordered list of points is pretty easy. The trick is to think of the list of segments as edges in a graph, and then the objective becomes traversing the graph and outputting a list of connected components. To do this, first I read all the segments into memory, then put them into a map indexed by their start point. Then I pick an arbitrary segment, write its two points to a list, and then use the second point to do a map lookup for the next segment that matches it. This process then repeats with the second point of each segment until we’re back to the start point. This process nets a list of lists of points, each list being a closed polygon. Once all the segments appear in a polygon, we’re done, and from there it’s easy to generate a set of EAGLE commands and write them into a .scr file.

Before I run this generated script from the EAGLE command prompt, I do one hand editing pass to name the polygons so that they are connected to the proper signals in the schematic. With that done, I set the my desired line width to match what I used in the OpenSCAD script, and then load the polygons into EAGLE by running the command “script poly” where poly is the name of the .scr file created in the last step.

When EAGLE renders the polygons, they’ll start out empty with dotted borders. To get them filled in, you need to route connections to them and then run the RATSNEST command. If you’re planning to use the autorouter, a good practice at this point is to use the restrict and keepout layers to defend these polygons. If you cover the electrodes with a polygon in tRestrict or bRestrict layer (depending on whether your electrode is on the top or bottom), then the autorouter will leave it alone when routing other traces. Just make sure to hand-route a connection point through the protective layer, and then the autorouter will be able to take it from there. (tRestrict/bRestrict are just hints to the autorouter and will not trigger design rule warnings. Pretty handy!)


The whole bottom of the board, featuring the the scroll wheel!

Next steps

I just ordered a batch of boards using the scroll wheel described in this post, so when they arrive, I will populate one and get to work on creating a library for easily reading out a position. Stay tuned for a future post!


Using an OpenSCAD shape as the board outline in EAGLE

I’ve been working on a Charlieplexed LED analog clock. The finished product will be an artfully routed PCB in a clear acrylic enclosure. Since the PCB will be the centerpiece, I want it to be pretty cool looking, including an interesting outline. The design I’m going for pictured below. It’s the union of four different rotations of the convex hull of a central circle and a smaller outer circle. Simple, right?


While EAGLE is a pretty capable CAD package, it stops short of making it easy to lay out complex shapes like this one. On the other hand, OpenSCAD is designed with exactly this use case in mind. (Check out how easy it was to make the shape above.) So we just have to find a way to get from OpenSCAD into EAGLE. Should be simple!

OpenSCAD supports exporting 2D shapes to the DXF format. Some initial Googling made it seem like EAGLE could import DXFs, but after some clicking I found myself on a plugin page that was in German and had a link to a .EXE file. (I’m on a Mac.) Not exactly what I’m looking for.

Lacking an out of the box solution, I did what any self-respecting hacker would do, and wrote a script. DXF files are text, which is helpful, though they are in an impressively goofy format. A little searching got me to the format specification, which explained how to read the sets of points that formed line segments. With the points in hand, I had my script output a set of EAGLE WIRE commands. After switching into the “dimension” layer, I pasted the WIRE commands into the command bar. Voila, I’ve got my outline!


While it works, this script is pretty hacky. It makes a bunch of assumptions about the structure of the file that might not hold in DXFs generated by programs other than OpenSCAD. But given the amount of time invested, I’m pretty comfortable with the results!