Generate a basic case bottom with PCB mounting holes

This commit is contained in:
Correl Roush 2023-06-06 17:29:19 -04:00
parent ba799aab7d
commit 986c9f00d2
5 changed files with 115 additions and 50 deletions

2
openscad/.gitignore vendored
View file

@ -1,2 +1,2 @@
*.stl
pcb.scad
pcb_dimensions.scad

View file

@ -2,11 +2,11 @@
all: case.stl
pcb.scad: generate.py ../kicad/Digital\ Audio\ Switch.kicad_pcb
pcb_dimensions.scad: generate.py ../kicad/Digital\ Audio\ Switch.kicad_pcb
python3 $< > $@
case.stl: case.scad pcb.scad
case.stl: case.scad pcb_dimensions.scad
openscad -o $@ case.scad
clean:
rm -f case.stl pcb.scad
rm -f case.stl pcb_dimensions.scad

View file

@ -1,9 +1,52 @@
$fn = 50;
use <pcb.scad>;
include <pcb_mount.scad>;
TOLERANCE=0.5;
wall_width = 3;
side_padding = 10;
case_width = pcb_width + (wall_width * 2) + (TOLERANCE * 2) + (side_padding * 2);
case_depth = pcb_height + (wall_width * 2) + (TOLERANCE * 2);
bottom_height = 30;
pcb_spacing = 10;
pcb_thickness = 1.6;
inside_offset = [wall_width + TOLERANCE + side_padding,wall_width + TOLERANCE,wall_width];
color("purple")
translate(inside_offset)
pcb_mount(w=wall_width,h=pcb_spacing);
color("green", 0.5)
translate([0,0,10])
pcb(1.6);
translate(inside_offset + [0,0,pcb_spacing]) {
difference() {
cube([pcb_width, pcb_height, pcb_thickness]);
translate([0,0,-0.5])
drill_hole_cutouts(h=pcb_thickness + 1);
}
}
module rounded_box(box, r) {
hull() {
cylinder(r=r,h=box.z);
translate([0,box.y])
cylinder(r=r,h=box.z);
translate([box.x,0])
cylinder(r=r,h=box.z);
translate([box.x, box.y])
cylinder(r=r,h=box.z);
}
}
mounting_supports(h=10,r=4);
difference() {
rounded_box(box=[case_width, case_depth, bottom_height], r=wall_width);
translate([wall_width,wall_width,wall_width + 1])
rounded_box(box=[pcb_width + (TOLERANCE * 2) + (side_padding * 2),
pcb_height + (TOLERANCE * 2),
bottom_height],
r=wall_width);
translate(inside_offset - [0,0,wall_width + 0.5]) {
drill_hole_cutouts(h=pcb_spacing);
posts(w=wall_width, h=wall_width/2 + 0.5);
}
}

View file

@ -1,5 +1,7 @@
import sexpdata as s
TOLERANCE = 0.2
def cadr(x):
return s.car(s.cdr(x))
@ -31,9 +33,8 @@ width = end_x - start_x
height = end_y - start_y
print(
f"""
module board() {{
square([{width}, {height}]);
}}
pcb_width = {width};
pcb_height = {height};
""".strip()
)
@ -51,45 +52,9 @@ for hole in footprints:
[[pad_x, pad_y]] = [s.cdr(x) for x in pad if s.car(x) == s.Symbol("at")]
drills = [cadr(x) for x in pad if s.car(x) == s.Symbol("drill")]
for diameter in drills:
# print([hole_x + pad_x, hole_y + pad_y, diameter])
pos_x = (hole_x + pad_x) - start_x
pos_y = (hole_y + pad_y) - start_y
holes.append((pos_x, pos_y, diameter))
holes.append([pos_x, pos_y, diameter])
print("module mounting_holes() {")
for pos_x, pos_y, diameter in holes:
print(f"translate([{pos_x}, {pos_y}]) circle(d={diameter});")
print("}")
print("module mounting_posts(r, h) {")
for pos_x, pos_y, diameter in holes:
print(
" ".join(
[
f"translate([{pos_x}, {pos_y}]) ",
f"linear_extrude(h)",
f"circle(d={diameter} + (r * 2));",
]
)
)
print("}")
print(
"""
module pcb(h=1) {
linear_extrude(h)
difference() {
board();
mounting_holes();
}
}
module mounting_supports(r, h) {
difference() {
mounting_posts(r=r, h=h);
linear_extrude(h+1) mounting_holes();
}
}
"""
)
# Y coordinates are inverted between KiCad and OpenSCAD
print(f"drill_holes = {[[[x, -y + height], r] for x, y, r in holes]};")

57
openscad/pcb_mount.scad Normal file
View file

@ -0,0 +1,57 @@
include <pcb_dimensions.scad>;
TOLERANCE=0.2;
h=10;
w=3;
module pcb_mount(w=w,h=h) {
difference() {
union() {
posts(w=w,h=h);
frame(w=w);
}
drill_hole_cutouts(h=h);
}
}
module drill_hole_cutouts(h=h) {
for (hole=drill_holes) {
pos = hole[0];
diameter = hole[1] + TOLERANCE;
translate([pos.x, pos.y, -0.5]) {
cylinder(d=diameter,h=h + 1);
}
}
}
module posts(w=w,h=h) {
// Posts
for (hole=drill_holes) {
pos = hole[0];
diameter = hole[1] + TOLERANCE;
translate(pos) {
difference() {
cylinder(d=diameter + (w * 2), h=h);
translate([0,0,-0.5])
cylinder(d=diameter,h=h + 1);
}
}
}
}
module frame(w=w) {
min_x = min([for (hole=drill_holes) hole[0].x]);
min_y = min([for (hole=drill_holes) hole[0].y]);
max_x = max([for (hole=drill_holes) hole[0].x]);
max_y = max([for (hole=drill_holes) hole[0].y]);
max_diameter = max([for (hole=drill_holes) hole[1]]);
translate([min_x - (w / 2), min_y - (w / 2)]) {
difference() {
cube([max_x - min_x + w, max_y - min_y + w, w]);
translate([w, w, -0.5])
cube([max_x - min_x - w, max_y - min_y - w, w + 1]);
}
}
}