Breadboard Holder
A base plate that keeps a solderless breadboard and a microcontroller board together on the desk. A shallow pocket locates the breadboard (half, full or mini size; its adhesive back sticks to the pocket floor) and standoffs with pins, or holes for self-tapping screws, hold an Arduino Uno, Mega 2560 or Raspberry Pi beside it; the board moves behind the breadboard when the pair would not fit a 210 mm bed. Rounded corners, a finger notch to lift the breadboard out and four recesses underneath for rubber feet. The default, a half-size breadboard with an Uno, is 172 x 67 x 10 mm. Plate thickness and margin are parameters. Prints flat, no supports.
# Breadboard Holder - a base plate for a breadboard and a microcontroller board, side by side
#
# A plate with a shallow pocket that locates a solderless breadboard (its adhesive
# back sticks to the pocket floor) and standoffs with pins for an Arduino Uno,
# Mega or Raspberry Pi next to it, so the two no longer slide apart on the desk.
# The board goes beside the breadboard when the pair fits a 210 mm bed, and
# behind it otherwise. Rounded corners, a finger notch to lift the breadboard,
# and four recesses underneath for rubber feet. Prints flat, no supports.
@param choices:["half", "full", "mini"] group:"Breadboard" desc:"Breadboard: half (83 x 55), full (165 x 55) or mini (46 x 35) mm"
$bb = "half"
@param choices:["uno", "mega", "pi", "none"] group:"Board" desc:"Board next to it: Arduino Uno, Mega 2560, Raspberry Pi, or none"
$board = "uno"
@param choices:["pins", "screws"] group:"Board" desc:"Pins through the mounting holes, or holes for self-tapping screws"
$fix = "pins"
@param 2.5..4 step:0.5 group:"Plate" desc:"Plate thickness (mm)"
$plate_t = 3
@param 5..12 step:1 group:"Plate" desc:"Margin around the parts (mm)"
$margin = 6
$bb_l = if $bb == "half" then 83 else if $bb == "full" then 165 else 46
$bb_w = if $bb == "mini" then 35 else 55
$pocket_d = 2
$fit = 0.4 # pocket clearance per side
$none = $board == "none"
$pi = $board == "pi"
$mega = $board == "mega"
$L = if $none then 0 else if $pi then 85 else if $mega then 101.6 else 68.6
$W = if $none then 0 else if $pi then 56 else 53.3
$n_holes = if $none then 0 else if $mega then 6 else 4
def hx($i) = if $pi then (3.5 + ($i % 2) * 58) else (if $i == 0 then 14.0 else if $i == 1 then 15.3 else if $i == 2 then 66.1 else if $i == 3 then 66.1 else if $i == 4 then 90.2 else 96.5)
def hy($i) = if $pi then (3.5 + floor($i / 2) * 49) else (if $i == 0 then 2.5 else if $i == 1 then 50.7 else if $i == 2 then 7.6 else if $i == 3 then 35.5 else if $i == 4 then 50.7 else 2.5)
$hole_d = if $pi then 2.75 else 3.2
$so_h = 5 # standoff: solder tails clear the plate
$so_d = 7
$pcb_t = 1.6
$gap = 8 # between the pocket and the board
# --- layout: beside (along X) if it fits a 210 mm bed, else behind (along Y) ---------
$beside = $none or ($bb_l + $gap + $L + 2 * $margin <= 210)
$plate_l = if $beside then $bb_l + (if $none then 0 else $gap + $L) + 2 * $margin else max($bb_l, $L) + 2 * $margin
$plate_w = if $beside then max($bb_w, $W) + 2 * $margin else $bb_w + $gap + $W + 2 * $margin
# the breadboard pocket is at the -X / -Y corner; the board origin follows
$bx0 = $margin # pocket corner
$by0 = $margin
$ox = if $beside then $margin + $bb_l + $gap else $margin
$oy = if $beside then $margin else $margin + $bb_w + $gap
print "plate (mm)" [$plate_l, $plate_w, $plate_t + (if $none then 0 else $so_h)]
def rr($w, $h, $r) = rect ($w - 2 * $r) ($h - 2 * $r) | offset $r
$plate = rr($plate_l, $plate_w, 4) | extrude $plate_t | translate ($plate_l / 2) ($plate_w / 2) 0
$pocket = rr($bb_l + 2 * $fit, $bb_w + 2 * $fit, 2) | extrude ($pocket_d + 1) | translate ($bx0 + $bb_l / 2) ($by0 + $bb_w / 2) ($plate_t - $pocket_d)
$notch = cylinder 7 ($pocket_d + 2) | translate ($bx0 + $bb_l / 2) ($by0 - 2) ($plate_t - $pocket_d + 0.5) # finger notch at the front edge of the pocket
$foot1 = cylinder 6 1.2 | floor | translate 0 0 -0.2
$feet = union [$foot1 | translate ($margin + 4 + ($i % 2) * ($plate_l - 2 * $margin - 8)) ($margin + 4 + floor($i / 2) * ($plate_w - 2 * $margin - 8)) 0 for $i in range(4)]
$base = $plate - $pocket - $notch - $feet
def at_holes($s) = union [$s | translate ($ox + hx($i)) ($oy + hy($i)) 0 for $i in range($n_holes)]
$so1 = cylinder ($so_d / 2) $so_h | floor | faces >Z | chamfer 0.4 | translate 0 0 $plate_t
$pin1 = cylinder (($hole_d - 0.3) / 2) ($pcb_t + 0.8) | floor | faces >Z | chamfer 0.4 | translate 0 0 ($plate_t + $so_h)
$tap1 = cylinder (($hole_d * 0.8) / 2) ($so_h + 1) | floor | translate 0 0 ($plate_t - 0.4)
$with_board = if $fix == "pins" then ($base + at_holes($so1) + at_holes($pin1)) else (($base + at_holes($so1)) - at_holes($tap1))
$holder = if $none then $base else $with_board
assert $holder.solids == 1
assert $holder.bbox.x ~ $plate_l
assert $holder.bbox.y ~ $plate_w
assert $holder.bbox.z ~ ($plate_t + (if $none then 0 else $so_h + (if $fix == "pins" then $pcb_t + 0.8 else 0)))
# the pocket floor is at least 1 mm thick and the pocket is inside the plate
assert $plate_t - $pocket_d >= 1
assert $bx0 + $bb_l + $fit < $plate_l - 2
# the board's mounting holes all lie on the plate
assert $none or ($ox + $L + 2 <= $plate_l and $oy + $W + 2 <= $plate_w)
$holder