The printer I kept modifying
There is a Two Trees Bluer on my desk that still prints. It's a 3-in-1 machine, and the 3D printer is the part that works: I home it, I level it, I extrude plastic with it. What I can't seem to do is leave it stock. Over the years it has become a running project in its own right, a base I keep modifying because each fix opens the door to the next one.
The improvements started with the printing itself. I replaced the extruder gear, and I added my own inductive sensor probe so the bed auto-levels off a real height map instead of a hand-set nozzle. Small upgrades, but they're the reason I trust the machine enough to keep bolting new things onto it.
Then I decided to make it do something it was never sold to do: build circuit boards. That's the journey this post is about. The same printed-mount, swap-the- toolhead instinct that improved the printer is what turned it into a one-machine PCB shop built from parts already on the bench.
It started, like a lot of my projects, with a purchase. I bought a 775 motor for a drill spindle and a diode laser module, and once they arrived I prototyped holders for both. I hadn't done the homework first. I didn't really know what wavelength or power it takes to lift paint off copper, or whether a cheap diode could do it at all. It was a discount on the laser module and a hunch: "well, maybe that works?"
So I designed the two mounts, a holder for the laser and a cradle for the 775
motor, both libfive models (.scm), parametric and printed on the same machine
they bolt onto. Here they are. Drag to orbit.
Then the laser sat in a drawer for over a year.
The reason is honest enough: the laser scared me a little, and the marker worked. A diode laser wants a clean 12V supply and a control signal I hadn't wired yet. Meanwhile I already had a way to make boards that produced real, working PCBs. So I did what most people do with a working process. I kept using it, and I left the upgrade for later.
This is the story of finally doing the upgrade, a year late, and all the small disasters between the drawer and a drilled board.
The pen years
The first process never used the laser at all. It drew the etch resist directly onto the copper with a paint marker.
The trick is a small abuse of pcb2gcode, the tool that normally turns a board
design into isolation-milling G-code. Milling cuts the copper away around the
traces. I wanted the opposite: lay an ink line on the traces and leave them as
resist. So the config inverts the Gerber and sets a comically large isolation
width, and the mill "tool" becomes a 1.0 mm PILOT marker.
# Mill options
extra-passes=0
mill-feed=600
zwork=-0.0500
invert-gerbers=true # So that we fill in the middle.
mill-diameters=0.4mm # This is how wide a mark your marker makes.
milling-overlap=25% # How much overlap on those marker lines.
isolation-width=2000mm # Fill up to 2 metres wide, plenty for any trace.
mill-diameters=0.4mm is, literally, how wide a line the marker draws. The
machine lowers the pen to zwork=-0.05 (just kissing the copper) and traces
every track as a filled-in shape. Before it starts, it scribbles a tiny 2 mm
triangle in the corner to get the ink flowing and wipe crud off the tip, a
hand-tuned ritual baked right into the preamble.
G01 F400
G01 Z-0.05
G01 X2.0 Y0.0 ( draw triangular marker to clean the pen tip )
G01 X0.0 Y2.0 ( draw triangular marker to clean the pen tip )
G01 X0.0 Y0.0 ( draw triangular marker to clean the pen tip )
G01 X0.0 Y0.0 Z0.0 ( move back to home )
I made one or two boards this way for another project, and they came out fine. Honestly, the pen era had one real advantage the laser would later take away: the board never left the printer. The same head that drew the traces also held the drill. Draw, swap the pen for the bit, drill. The motor was the same, the bed clamp never moved, so the only calibration I owned was the fixed offset between where the marker tip sat and where the drill bit sat.
M0 (Moving to drilling position.)
G00 X36.80 Y16.90 Z10
(MSG, Resetting tool coordinates to current position.)
M0 (Adjust Z position.)
G92 X0 Y0 Z0
X36.80 Y16.90. One hand-measured jump from the pen's zero to the drill's zero.
Get it right once and every hole lands on its pad.
So why change anything? Because the marker has a ceiling. The line is whatever width the tip is, no finer. A large copper fill has to be drawn as a raster of overlapping strokes, and a marker dragged back and forth over the same patch starts to dry, skip, and clog. Fine pitch was out of reach. The pen made good boards as long as the boards weren't asking for much.
I wanted to ask for more.
Talking to the spindle, and the MOSFET that didn't make it
After a year, I decided to stop avoiding the laser. Finer traces were the goal, but before it could ablate anything the printer had to actually drive it, and the same was true of the drill spindle. That turned out to be the hardest electronics of the whole project.
In the pen era the spindle was dumb. It ran off an external speed controller; I flipped a switch and it spun at some fixed RPM while the printer did the moving. The G-code never knew the spindle existed.
The laser changed that, because the laser has to be driven by the printer: power and on/off come from a PWM pin in Marlin. And here's the thing I'd been avoiding for a year. If the laser rides a Marlin PWM pin, the spindle might as well ride the same one. One control signal, two tools.
Getting there cost me a MOSFET.
My first instinct was to drive the 24V spindle off the printer's heater channel, since a heater MOSFET is already a beefy switch sitting right there on the board. It worked twice. On the third run the heater MOSFET failed shorted: instead of switching the spindle, it became a permanent closed circuit, and the motor spun flat out with no way to stop it short of cutting power. A shorted MOSFET is a special kind of bad, because the failure mode is "always on."
Two problems, really. The spindle wanted 24V but the laser wants a clean 12V, so they couldn't share the heater line even if I'd wanted them to. The fix was to stop abusing the heater channel entirely. I wired in a small optocoupler-isolated MOSFET switch board on its own pin to switch 12V for the spindle, and used the logic-level (TTL) adapter board that came with the laser for the laser itself. Both take their cue from the same PWM pin: the optocoupled switch drives the spindle, the TTL board drives the laser. The optocoupler keeps the motor's electrical noise off the logic side, which after the last failure I was very motivated to guarantee.
With the hardware sane, Marlin still had to be told what it was driving. And Marlin makes you choose: you configure the firmware as a laser or as a spindle, not both. That sounds like a problem and isn't, because underneath it's the same PWM either way. I configured it as a laser and live with one quirk: laser mode only applies power on cutting moves that carry a power value, and drops it on rapids and dwells. That's exactly right for a laser (you never want a stationary beam sitting on one spot, charring a hole through your board) and exactly backwards for a drill.
The laser's safe default is the drill's failure mode.
For the spindle the dangerous move is the opposite: you must never lower Z with the spindle off, because a non-spinning bit driven into copper just snaps. So the firmware's laser safety stays on, and the burden of "spin up before you plunge" moves into the G-code generator, which is allowed to be careful in a way firmware modes aren't.
Even after all that, the spindle wouldn't spin. The G-code pcb2gcode emits is a
bare M3 (plus a cosmetic standalone speed line). On Marlin, a bare M3 only
toggles the enable pin; the PWM duty is never set, so the spindle is "on" at zero
power. The duty has to be on the M3 line. A tiny post-processor rewrites it:
# Marlin needs the duty value ON the M3 line (`M3 S255`) or the spindle
# PWM is never set (see MarlinFirmware/Marlin#8379).
m3 = BARE_M3_RE.match(stripped)
if m3:
code = m3.group("rest").split("(", 1)[0]
if "S" not in code.upper():
if dry_run:
out.append("( dry run: spindle left OFF )")
continue
out.append(f"M3 S{speed} (Spindle on clockwise at full PWM.)")
continue
S255 is full PWM duty (CUTTER_POWER_UNIT=PWM255). One missing letter was the
entire difference between a spinning bit and a dead one. The finished tool-change
block, post-processed, reads the way it should: lift, stop, pause for a manual bit
swap, spin up then descend.
G00 Z30.00000 (Retract)
T1
M5 (Spindle stop.)
(MSG, Change tool bit to drill size 0.6mm)
M6 (Tool change.)
M0 (Temporary machine stop.)
M3 S255 (Spindle on clockwise at full PWM.)
G0 Z5.00000
G1 F200.00000
G0 X57.15000 Y77.47000
G1 Z-2.50000
G1 Z5.00000
Spindle on, then Z goes down. The bit is always turning before it touches the board.
Spray, burn, etch
With the laser finally under the printer's control, I could use it for what I'd bought it for.
The new process throws out the marker entirely. Instead of drawing the thin thing you want to keep, you cover everything and burn away the part you don't.
"We're not using the pen to draw the tracks anymore. I use a laser to remove the paint, and then the board is readily etched with ferric chloride."
Three steps. First, paint: a copper-clad board gets an even coat of matte black high-temperature acrylic spray (TEK BOND Super Color Alta Temperatura). High-temp because the laser is about to dump a lot of local heat into it, and I wanted a resist that chars cleanly rather than melting into a gummy mess.
Then burn: the laser rasters over the board and ablates the paint off everything that should be etched, leaving black resist only on the traces. This is the inverse of the pen. The pen added ink to the 5% of the board that's copper trace; the laser removes paint from the 95% that's gap. But the laser can hold a far finer edge than a 0.4 mm felt tip, and a big copper pour is now trivial: it's just area the laser doesn't visit.
Getting the laser to mark cleanly took a calibration pass of its own: a grid of squares burned at a sweep of powers and speeds, reading off which cell stripped the paint to clean copper without scorching the board around it.
The laser doesn't leave clean copper, though. It leaves a film of charred, half-burnt paint sitting in the gaps where it ablated. If that goes into the bath, the etchant has to fight through the soot first, which is slow and uneven. So before etching I scrub the board under running water with dish soap and an old toothbrush. The loosened char rinses away and the bare copper comes up bright, while the hardened resist on the traces stays put. A minute of scrubbing saves a lot of etch time.
Last, etch: the cleaned board goes into a ferric chloride bath (the classic hobbyist copper etchant). The bath eats every bit of exposed copper and leaves the resist-protected traces behind. Strip the remaining resist off the traces afterward and you have a board.
That's the whole arc of the project in one sentence each: the pen added the small thing; the laser subtracts everything else. On paper it wins on precision, fill handling, and fine pitch.
It also wins somewhere I didn't expect, by being smart about how much paint to burn. Keeping a copper pour means the laser only clears thin isolation channels around the traces, not the whole background. It burns far less area, so the job is faster and there's less toxic smoke. And with less copper left exposed, the etchant has less to dissolve and the bath lasts longer.
What the laser costs you is a step (the paint) and, as I'd find out, a pile of new ways to fail. The trade is real but lopsided: the pen is genuinely simpler to set up and align, while the laser wins on everything to do with how fine the copper can get. For the boards I want to make next, fineness is the thing I can't buy any other way.
Don't trust the edge
The last set of problems were physical, and the etch caused most of them.
Start with alignment. In the pen era I zeroed on the board's corner, because the corner was right there. But in the laser flow the copper outline gets etched away along with everything else, so after the bath the board's edge is no longer a reliable reference. It's literally a slightly different shape than it was.
The answer is to put copper fiducials on the board: little cross marks in the corners, on the same copper layer, that get protected by resist and survive the etch. You align the drill to a fiducial, not an edge.
Then there's the stepper snap, which cost me a few minutes of confusion before I understood it.
"When the motors are off and it re-engages, it shakes and gives a big jump, and it ends up off by about 1 to 2 mm. It is better to make the final adjustment while the motors are energized."
Stepper motors hold position only while energised. When they're idle and then re-engage, each one snaps to its nearest full step, and the head lurches a millimetre or two. So if you carefully hand-nudge the bit onto the fiducial with the motors off and then start the job, the very act of starting throws your alignment away. The fix is procedural: energise the motors first, jog each axis a hair to confirm they're holding, and only then fine-tune onto the fiducial with the jog control. Never push the head by hand and let it re-engage.
The board I was drilling, segby_v1, is the prototype controller for my first
self-balancing robot, the start of the ar-tur project.
It has 130 holes in five drill sizes.
Plotting those positions is a picture of it:
The dense vertical columns are through-hole pads. The long row of forty 0.6 mm holes along the top is a header strip. The block on the left edge is a connector.
That left one fear: 130 holes, and no way to know they'd land right until the bit
was already cutting. So I added a dry run. From the one pcb2gcode output the
post-processor emits two files. The real one plunges to Z-2.5, through the
1.6 mm board into a sacrificial backing layer. The dry-run one keeps every X/Y
move identical but replaces each plunge with a small +0.2 mm hover, spindle
left off. You watch the bit trace all 130 positions a fraction of a millimetre
above the board, confirm the pattern sits dead on, and only then commit to the
real cut.
The whole safety idea of the post is in that 2.7 mm gap between the two lines: the
dry run hovers at +0.2, the real run cuts to -2.5. The single Z30 spike here
is a manual bit change. The real job has five, one per drill size, and each is a
pause, a manual bit swap, and a Z re-touch. With the dry run passing, the real cut
went clean: spindle up, plunge, retract, 130 times.
Now the honest part, the thing I'd do differently. I etch in batches, and the batch I ran sat in a tired, weak bath for three to four hours. A weak etchant is slow, and a slow etch is an indiscriminate etch: it keeps eating long after the gaps are clear, and it starts undercutting the edges of everything thin. By the time it finished, the bath had nibbled away my finest traces, lifted the silkscreen text, and in places eaten into the fiducial markers I was relying on to align the drill. The resist holds the line; a bath left running too long does not care.
The lesson is the one every etching guide states and I had to relearn by ruining a board: a fresh, warm, agitated bath that finishes fast does less collateral damage than a weak one left to soak. And there's a floor on how fine a trace this process can hold, set as much by the etch as by the laser.
I haven't pinned that floor down with a number yet, and guessing one here would be exactly the kind of invented precision this board just taught me to distrust. What I actually need is a characterization coupon: a single board of trace widths and gaps stepped down in known increments, with some geometric fiducials, run through the whole spray-burn-etch-drill process so I can read the smallest feature that survives straight off the copper. Until I burn one, I design with more margin than the laser alone would need and call it respect for the etchant.
From ritual to software
Step back from all of this and a pattern shows up. Almost every hard part was the same kind of problem wearing different clothes.
The pen→drill offset. The back-side mirror that drill-side=back applies (drill
from the wrong side and every hole lands flipped). The fiducial touch-off and its
G92. Every one of them is a coordinate transform: a shift, a flip, a re-zero,
applied in the right order to get from "where the design thinks a point is" to
"where the bit actually goes." I'd been doing that transform by hand, spread across
a marker offset, a config flag, and a G92 I edited with a Python script. Plenty
of ways to get a sign wrong.
And there's one part I still do entirely by hand, the part the laser actually made worse. In the pen era the board never moved: one head drew the resist and then drilled, so there was nothing to re-align. The laser brought back a swap. The laser and the drill are different units on the same carriage, so the board gets etched under one tool and drilled under another, with my hands in between. After the bath I have to remount the board and find the fiducials all over again, and the etch may have chewed on those fiducials too. Re-registering the drill to a board that's already been etched is the fiddliest, most error-prone step left, and it's exactly the kind of repeatable coordinate math a human should not be eyeballing.
There's a second idea I want to try, and it falls out of the resist itself. Right now I strip the paint off after etching. But the paint is high-temperature, which is exactly what a solder mask needs to survive a soldering iron. So on the next board I want to leave it on: etch, then laser a second time to open the mask only over the pads I need to solder, then drill. One coat of paint, two jobs, no extra material. The catch is that each pad spent the etch under paint, so opening it means lasering through that paint to bare copper. The open question is whether solder will wet and bind to a copper surface that's been painted and then laser-cleaned, or whether the char and residue spoil it. Worth a test board.
So that's the loose thread this post ends on: the alignment ritual wants to be software, not memory. That's the next thing I want to build. But that's a story for the next post.
What's built today is a 3D printer that also makes circuit boards, a process that turns a sprayed-black board into a drilled PCB, and a healthy respect for how many small things sit between a clean design and a finished board. The laser was in a drawer for a year because the marker worked. It turns out the marker was the easy 80%, and this post is mostly the other 20%.
Next time, the alignment. And a fresh bath.
References & Links
- LASER TREE 450nm diode laser moduleslasertree.com
- pcb2gcode — Gerber/Excellon to G-codegithub
- KiCad EDA — board design + Gerber/Excellon exportkicad.org
- Marlin #8379 — bare M3 does not set spindle PWMgithub
- Marlin — laser/spindle (CUTTER_POWER_UNIT)marlinfw.org
- Ferric chloride (iron(III) chloride) — the copper etchant used herewikipedia