A published snapshot of a workshop tool, 21 September 2026. The live version runs on the shop LAN, where the result sheets save to disk and the 3D viewer talks to the printer.

Breadboard Bench / build hub

check.py ALL CLEAR screws.py ALL SCREWS OK rev 2026-08-24
Where the build stands
Print-readiness review blockers6 / 6 fixed
Geometry gate (check.py)ALL CLEAR
Fastener gate (screws.py)ALL SCREWS OK
Interference sweep (side bin)0.000 mm³
Export freshness guardACTIVE

The structure is print-ready; board retention is not. Plates 01 and 02 and their follow-ups are printed and read back, and eleven constants are settled. What is still moving is how a breadboard is held: the printed indexing teeth failed three times and have been dropped for the board's own dovetail cleats, which is what the Storyboard's last panels cover. Every blocker from the August print review is fixed and re-gated. Since then the bench grew a universal display mount (an open H-frame sized for the Elecrow 7″ CrowPanel, T-slots with captive square nuts), a side bin that snaps on magnetically to the steel bar-end screw heads (three N52 discs, nothing visible, nothing cut into the frame), and the expressed rail-joint buttress chosen from the workflow’s verified options.

Nothing gets trusted by eye: geometry, fasteners, freshness and interference are all measured on every rebuild.

Next at the printer
  • Cut a span gauge to the measured 65.21 and print it — the last open constant
  • Redraw deck_rail() around pocket and peg; drop the indexing teeth
  • Decide the rail counterbore for the M3 × 12 cap screws
  • Make the CAD changes on the PC, re-gate, then slice plate 04
  • Plate 03 in PETG: the clip trio on edge, the production regime
bench 300 × 165 mm · +35 side bin · display face 19 mm off rail
PLA structure 170.1 cm³ · frame total 281.7 cm³ · 22 TPU inserts · 14 screws · 17 magnets
Frame bench, hero view: breadboards in the cradle, 7-inch display on the mount, side bin on the right
drag to orbit · parts list toggles subassemblies · explode slider pulls the build apart frame: tie seated full-length, display on two clip-on posts — current
19 September 2026 · plate 02 and what it taught us

Storyboard

0.15
RAIL_FIT_MORTISE
rail slot clearance
0.20
SOCKET CLEARANCE
round bar seats — already correct
+0.30
FOOT POCKET
16.30 × 6.30 mm
6.25
MAGNET_FIT
pocket for a 6 mm disc
0.00
SHRINK
152.00 and 84.01 as drawn
9.32
VS 9.0 LIMIT
M3×16 cap bottoms out — see 21
MATTE
SCREWS HOLD
cleared for the whole structure
0.80
RAIL_PAD_D
O-ring pocket, 1 dot — replaces the TPU pad
1Rail stub with loose strands along both edges
FIXED · see 2 and 3

The rail's lips sagged

Where it started: printed over thin air, no support.

2 BEFORE AFTER
DONE

Flipped it over

Lips on the bed. Nothing hangs in the air.

3Clean rail stub standing in the one-dot slot
DONE

One dot is the right fit

Slot clearance 0.15. The old 0.25 came from the fat stub.

4 +0.10+0.20+0.40+0.50 +0.30 forcedfits
DONE

Pocket 3 wins

Foot pockets grow 0.30. Pad holds even when bent.

5aExploded view: block, two O-rings, rail stub, two cap screws
DONE · plate 02c

What goes on, in order

Two WHOLE rings in the pocket. Stub on top. Two black M3 × 16 cap screws (16 mm under the head). Not 20: the hole is 11 deep.

5bThe assembled joint sliced through both screws
X-RAY VIEW · nothing is really cut

Same joint, seen inside

The empty pocket on the left is the second one to try.

5cClose-up: one O-ring squeezed in its pocket around the screw
X-RAY VIEW · nothing is really cut

The ring gets squeezed

The two black ovals are one whole ring, seen from the side. It pushes back on the rail.

5dThe O-ring joint assembled, two cap screws driven
IT WORKS

Solid connection

One dot — pocket 0.80 deep. O-rings replace the printed TPU gasket.

6O-ring kit lid listing sizes
IN THE KIT

The ring marked 3x1

3 mm hole, 1 mm thick. You need 8: one per rail screw.

7Kit of black cap screws and hex nuts
MISMATCH

Cap screws. No countersunk.

The rail was drawn for eight countersunk screws.

8 countersunk M3 × 12 cap
YOUR CALL

Counterbore the rail?

Now the better answer: it is the only way a cap screw reaches deep enough without bottoming out. See 21.

9 5.8 channel
DONE

Hex nuts are fine

5.5 across flats slides in. Corners stop it spinning.

10 plate 02: strong way real frame: weak way
PASSED

Screws hold in Matte PLA

02c was the honest test: pilots the weak way, no crack. Only a print line.

11 DRAWN 0.9 mm PRINTED about 0.65 mm
ON THE PC · before plate 07

Ladder teeth lose their tips

About 0.65 mm of the drawn 0.9 survives — 30% short, not gone. A flat-topped tooth would keep all of it. Plate 02d says whether it matters.

12 tie: clean ladder: half filled
ON THE PC · before plate 07

Ladder screw holes blocked

Found in software. Try an M3 in the ladder stub to confirm.

13 PLA MATTE NO BRIM ON RAIL
DONE

Matte PLA, fewer brims

Plate 02 was Basic by mistake. Ladder and tie keep a loose brim.

17 6.15too small 6.25right 6.35too big
DONE

Magnet pocket 6.25

Thumb start, tool seat, holds upside down. Glue is optional.

18 152.00  ·  drawn 152.00 84.01 · drawn 84.00
DONE

No shrink to correct

The plate came out its drawn size, because the printer has had Bambu's motion accuracy calibration. The 294 mm parts will too.

19The fat bar seated in the coupon's sockets
2 DOTS WIN

Socket clearance 0.2

The fat bar fits best in 2 dots. The thin bar only fits its own small hole, which is the design working. The frames are already cut at 0.2 — nothing to change.

20A real breadboard resting on the ladder stub
PASSED

Breadboard sits flat

No rock, paper slides down both sides. The board's dovetail pegs are a touch awkward but fine — grooving for them would pin the board to one spot and kill the 2 mm sliding.

21A cap screw through the rail, tip sticking out the back
FOUND IT

M3 × 16 cap is too long

It reaches 9.32 past the rail. The shallowest hole is 9.0, so it hits the bottom before it clamps. Counterbore + M3 × 12 reaches 7.8 and fits everywhere.

15Kit of stainless button head screws and nuts
CAREFUL

Stainless will not hold a magnet

Fine for the display. Use the BLACK screws wherever a magnet grabs the head.

163D printing super glue
GOOD TO USE

Glue for the magnets

A small drop in the pocket. Which way the magnet faces does not matter.

22Two deck stations cut from the real ladder
TEST THIS · printed

Two stations, and the stops

The real ladder trimmed to 178 mm, plus two stops. Does a board sit flat across both? Slide a stop along the strip — does it step every 2 mm and hold?

23A breadboard held above two rails, its cleats over their pockets and pegs
DECIDED

The board brings its own joint

The printed teeth are finished — they failed on plate 02d, they failed again on a full-size print, and the reason is a process limit rather than a tuning one: a triangular tooth cannot print its own tip. So retention moves onto a feature the board already has. One rail carries an open pocket its dovetail tab falls into; the opposite rail carries a peg that falls into the notch across from it. The board goes straight down onto both.

24The board's tab hanging above the open pocket cut into the rail
SETTLED

Tab into pocket

The tab is 5.20 tall, 4.07 across its tip and stands 1.41 proud, and its bottom is flush with the board's underside. The pocket is cut 0.3 wider and open at the top, so the tab drops in rather than sliding along. Nothing here relies on the tab's 3° undercut: 0.11 mm per side is smaller than this printer's own pocket error.

25A peg on the far rail standing under the board's notch
PEG_W = 3.8

Peg into notch

The other edge is female, and its notch sits directly opposite a tab. A peg 3.8 wide drops in cleanly — four dots on the peg gauge — which also puts the notch’s mouth at 4.00 or wider. That mouth was the one dimension on this board still being guessed at, because a notch that mirrors the tab is narrowest where you enter it.

26A cradle gauge, one piece
CAUGHT IN TIME

The gauge was two loose rails

The first cradle gauges were severed by their own tape relief — it was cut the full depth of the floor, so the part that exists to hold a measured gap came out as two separate pieces. is_watertight passed all three, because two disjoint closed solids are each watertight. A body count is the check that catches it, and it has since caught a second, unrelated floating-geometry bug in another gauge.

27One station, board lifted over its rails
RAIL_GAP = 55.14

Across, and along

Two dots across is the fit: rails 55.14 apart, 0.40 of clearance on the board’s 54.74 plain width. Along the board is less settled. The stations measure 65.21 tip centre to tip centre, and there are three cleats per edge, not two — an earlier estimate of “about 71” was wrong by two hole pitches and sent a whole plate of gauges out too wide. A slotted second pocket may remove the need for that number to be exact at all.

14 1Re-cut the spans to 65.21 2Counterbore: yes or no 3CAD fixes, then plate 04
NEXT

What is left

Two constants are settled and one is not: the station span needs a gauge cut to 65.21. Then the rail counterbore decision, the CAD changes, and plate 04.

Measured off the exported models, not typed in

Catalogue

Every printed piece of the bench with its exact size. Sizes are the part as modelled, length × width × height in millimetres; “as printed” is the same part turned the way it sits on the plate. Weights are solid-equivalent at the filament's density — sliced parts weigh 50–65% of that. The whole bench first:

Test pieces

The gauges: small parts printed to settle a fit before the big part that depends on it. None of them ends up in the bench.

Hardware and electronics

Everything that goes into the bench that is not printed. Where the assembly carries a model of the item, its size is measured off that model and its quantity is the number of copies in the assembly; items the assembly does not model are drawn to their standard's nominal size and marked so.

Design constants

Every numeric constant in cad/params.py and cad/frame.py, with the note written beside it in the source. These are the numbers the parts are generated from.

True orthographic views, 1 drawing unit = 1 mm

Schematics

The assembled bench from the front, from above and from the right. The views are rendered from the seated assembly at exactly 5 pixels per millimetre and the dimension lines are drawn over them in the same millimetres, so each number sits on the geometry it measures. Heights are taken from the desk: the bench stands on TPU pads 1.0 mm proud of the printed parts. Orange parts are PETG, red is TPU, the dark bar is the DIN rail, grey-blue is the display and breadboards.

Rendered in the same studio as the stills

Motion

TurntableThe model rotates under fixed studio light, so the key and rim rake across every surface. Loops.
Assembly sequence (first cut)The August exploded-view fly-in. Superseded: the software test fit showed this order cannot be built — the bars cannot drop into standing frames, and the rail does not descend onto the posts. Kept for the look; follow the verified build instead.
Verified buildThe order the meshes allow, every move checked for collisions by cad/assembly_fit_check.py: ladder and tie down, tray onto the tie, frames close in along x, end screws, gaskets into their glands, the DIN rail slides through both mortises, rail screws along the post slope, caps, stops, side tray and bin, then the clip-on modules and the boards. Feet and magnets ride in with the part that holds them. The clip-on modules rock onto the rail by hand and are the one step not checked.
Stage 2 fit testHow the plate-02 test board is used: rail stub into three slots, bars into the sockets, pads into the foot gauge. Captioned step by step on the Build plan tab.
What gets printed, and how

Build sheet

Print settings — per part

PartMat.LayerWallsInfillBrimSupports
End frame (L + R, two STLs)PLA0.2315%nono
Deck ladderPLA0.2315%yesno
Rear tiePLA0.2425%yesno
DIN rail (structural)PLA0.24–625%nono
Rear trayPLA0.28415%nono
Board plates, carrierPETG0.2315%yes2 dabs, clip channel
Screen bezel, rail binPETG0.2315%no2 dabs, clip channel
Display post ×2 (mount v2 — one part, printed twice)PETG0.2325%yes2 dabs in clip channel
Side binPETG0.2 only315%nopaint support under the rolled edge (8 mm cantilever); pause at Z = 3.2 for 2 magnets
Screw tray (left)PETG0.2 only315%nopause at Z = 3.2 for 5 magnets
Rail cap ×2 (top face down)PLA0.23100%nono
Deck stop ×2 (on its side)PETG0.23100%nono
Rail pads ×4, foot pads ×18TPU 95A0.2—100%nono

0.4 nozzle. 0.2 mm everywhere except the rear tray, which goes to 0.28 — it has ~190 layers of two isolated 6 × 25 mm fins, and a coarser layer carries 40% more material each while cutting the starved layer count by 30%. The side bin and screw tray must stay at 0.2: their magnet pause is at Z = 3.2, which is exactly 16 layers at 0.2 but has no layer boundary at 0.28 — you would pause either before the pockets open or after the roof has started. Coupon first — every fit constant is read off a printed gauge before the big parts run.

Cooling — Filament settings → Cooling

SettingValueWhere / why
Chamber temperature0Every plate. The H2S actively holds up to 65 °C. N52 fades permanently above ~80 °C, and nearly every part here is cooling-starved. Check it is not still hot from an ABS job
Slow printing down for better layer coolingonStock default is already on
Max fan speed threshold (layer time)8 sEnd-frame plate and rear-tray plate only. Stock is 4 s. Do NOT raise it globally — at the H2S's 21 mm³/s almost the whole build sits under 8 s, so a blanket setting forces min speed everywhere and roughly doubles print time
Part cooling fan100%Those two plates
Support → On build plate onlyonSide bin and screw tray. Their magnet pockets are sealed voids; “everywhere” (especially tree) can colonise an internal cavity, and you would not see it until the magnets refuse to seat. Slice, drag to layer 16, confirm seven open holes

Measured at 21 mm³/s (verified H2S max volumetric flow for PLA, standard hardened steel nozzle; 40 with the High Flow hotend). Layers under 8 s, per part: end frame 298 of 300 — the worst in the build, and it carries the rail mortise; rear tray 195; side bin, screw tray, ladder, rail and tie all zero.

Hardware

ItemQtyWhere
M3 × 12 socket head cap, black-oxide alloy steel (ISO 4762)6Bar ends, through the frames — the magnetic six; alloy steel grips hardest, stainless will not hold
N52 neodymium disc Ø6 × 2173 + 3 in the bin and tray back walls (in sideways through the head pockets; captive between skin and screw head once mounted). 2 in the bin’s screw cells + 5 in the tray’s: pause-and-insert — pause at Z = 3.2 mm, drop in, resume, and the print seals them under. 2 in each rail cap, press fit (the cap is 2.45 thick, nothing to seal under). Never heat a magnet — N52 fades permanently above ~80 °C, so chamber = 0
M3 × 16 countersunk, carbon steel4DIN rail at the end frames, flush in the clip face — hide under magnetic rail caps, so not stainless
M3 × 14 countersunk4DIN rail at the tray buttresses — the buttress pilots are 9.0 deep; a ×16 bottoms out before its head seats (DFM review)
M3 × 8 pan head2–4Display flange screws into the posts' slots, captive square nuts (12 mm if the flange is thick). Mount v2 needs no spine or crossbar screws — the eight M3 × 12 pan heads v1 used are gone
M3 hex nut (DIN 934, 5.5 AF × 2.4) — the ones on hand~8Nut channel on the back of each display post, loaded from the top. The channel was drawn for a DIN 562 square nut (5.5 × 1.8); a hex nut fits, cannot turn in the 5.8 mm channel, and stands 0.2 mm proud of the back face into free air. Snug, do not crank: it bears on less ledge than a square nut

Regenerating

python cad/bench.py        # console + shared modules
python cad/frame.py        # frame variant + side bin
python cad/coupon.py       # console fit gauges
python cad/coupon_frame.py # frame fit gauges
python cad/check.py        # printability + freshness
python cad/screws.py       # every fastener, measured
python cad/build_viewer.py # the 3D viewer tab

check.py fails stale exports: an STL older than the code that generates it can’t pass. That guard has caught real drift twice.

Result sheets · tapped at the printer · what they settled

Checks

Every printed gauge exists to settle a number, and a number that stays in your head is a number the CAD never gets. On the workshop LAN these are tap-through sheets on an iPad that save to disk as you go and work the constant out for you. Here they are the results: what was answered, and the constants that went back into the CAD.

Plate 01 - TPU

PLATE 01

Caliper readings for the TPU pads and the control block, spoken rather than typed so both hands stay on the caliper. Settles FOOT_FIT and how much TPU over-prints on this machine.

15 answered

Plate 02 - fits

PLATES 02, 02B, 02C, 02D

Push each printed gauge into its slot and tap what happened. Settles the rail slot, the round sockets, the foot pocket, the pilot screws, the gasket and the magnet caps.

25 answered · complete
  • RAIL_FIT_MORTISE0.15
  • FOOT_POCKET_OVER0.3
  • ORING_GASKETworks
  • RAIL_PAD_D0.8
  • MATTE_PILOT_STRENGTHpass
  • MAGNET_FIT6.25
  • span_loss_2880.0
  • LADDER_SHELFpass

Cleat gauges

PLATES 02E-02I

The board retention rework: drop a breadboard onto each gauge by its own dovetail cleats. Settles the rail gap and the station span that replace the indexing teeth.

2 of 16 answered
  • PEG_W3.8
  • NOTCH_MOUTH_MIN4
  • RAIL_GAP55.14
  • BOARD_CLEAR0.4
Staged pilot build · cheapest plate first · nothing prints until its fits have passed

Build plan

Never print a part until every fit it depends on has passed on something smaller. Click a stage for its files and checks. Ticks persist here.

Every stage below is already a Bambu Studio project. out/plates/ holds one .3mf per stage — right machine, right filament, parts in their gated print pose, per-object wall / infill / brim overrides applied. Open 01_tpu_regime.3mf and print. The per-plate card, including the two things a .3mf cannot carry (painted support dabs, and the Z = 3.2 magnet pause on stage 9), is out/plates/PLATES.md. Regenerate with python cad/plates.py.

Stage 2 · how the fit test worksThe big flat piece on plate 02 is a test board, not a bench part: the same joint cut at three clearances, marked with 1, 2 or 3 dots. The loose pieces from the same plate get pushed into it by hand, and the winner’s number goes into the design. The loose pieces are drawn in orange so they read against the board — yours are all the same PLA. Which slot wins in the film is made up; yours is whatever your print says.
Rail-joint rework · 5 designs × 3 angles · every option double-verified by adversarial agents

Joint study

The question under review: the end frame’s rail joint reads as a thick block patched behind the mortise, and its gasket pocket (the indent) may be redundant now the shroud captures the rail by shape. Each candidate below was built as real geometry by an independent agent, then attacked by two more (structural + printability). Angles: front three-quarter, rear-top (boss depth and gasket land), inner-face silhouette. Click any image to zoom.


Tie-rod joint · second pass · no brackets

Where the tray meets the rear tie

The first pass asked “what bracket holds the rod?” and got five trapezoids for an answer. Wrong question. The actual offence is that TRAY_Y1 sits at TIE_Y − TIE_R − 2, so there is a 2 mm slot running the whole 288 mm between the tray's rear wall and the rod. That slot is the gap — and the tails were lumps stuck on to bridge it.

So: delete both tails and let the rear wall do the job along its entire length. The wall comes down and lands on the rod, and the rod's own cutter carves the mating surface, so the fit is conforming by construction and there is nothing to align. Contact goes from 21 mm² to ~1400 mm² — and the part count goes down, not up.

How far back the wall may come is not a style choice. The tray prints upright, so the wall's underside may not exceed 45°. That lands it exactly on the rod's 45° tangent point, y = 144.65 — the geometry hands over the design line for free. The three options differ only in how the wall face gets there.


Buttress tops · a printability study, measured

Two seconds a layer, 190 layers running

The tray is 288 × 53 × 53 and 61 g. Below z = 14 it prints 1 300–14 000 mm² layers. Above the rim it collapses to two isolated 6 × 25 mm fins and stays there for ~190 layers — 4.8 s at the rim, 2.3 s at the rail land. Nothing cools before the next layer lands, and it happens on the one surface that has to be accurate.

Geometry can only do so much. Layer time = area × height ÷ flow, so 8 s at 0.2 mm and 12 mm³/s needs ~480 mm² — more than 3× what the fins give, and the H2S runs faster than 12, which makes every number here optimistic. All times below are measured off the real solids at 0.2 mm / 12 mm³/s.

First pass — five brackets, rejected

Kept for the record and for one genuinely useful finding: the tie's flat sits on the desk plane, so nothing can reach under it. No closed eye, no hook below centreline, no split bearing — the build proved that last one by handing back a U-block whose two cheeks were separate solids with nothing to join them. Every bracket could only ever work the top 180°, and every one of them read as a trapezoid bolted to the back.