Skip to content

Commit 721049e

Browse files
authored
Merge pull request #384 from smkent/ebox
Rework 40mm PCB model as library, create 40mm PCB project box model
2 parents 1df84a7 + 982330f commit 721049e

File tree

10 files changed

+413
-189
lines changed

10 files changed

+413
-189
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* ESPHome 40x40mm PCB mount
3+
* By smkent (GitHub) / bulbasaur0 (Printables)
4+
*
5+
* Licensed under Creative Commons (4.0 International License) Attribution-ShareAlike
6+
*/
7+
8+
include <esp-pcb-40mm-library.scad>;
9+
include <project-box-library.scad>;
10+
11+
/* [Rendering Options] */
12+
Print_Orientation = true;
13+
Part = "all"; // [preview: Assembled preview, all: Side-by-side, box: Box, lid: Lid]
14+
PCB_Preview = true;
15+
16+
/* [40mm PCB Size] */
17+
// 40(+2)mm units
18+
PCB_Units = [1, 1]; // [1:1:3]
19+
PCB_Mount_Height = 6;
20+
Extend_PCB_Mount = false;
21+
22+
/* [Box Size] */
23+
Box_Fit = [20, 20];
24+
Height = 30;
25+
Thickness = 2.4;
26+
// For a smooth look, set Lid Height to (Thickness + Edge Radius).
27+
Lid_Height = 3.9;
28+
29+
Screw_Diameter = 3.0;
30+
Screw_Style = "flat"; // [flat: Flat, countersink: Countersink, inset: Inset]
31+
Insert_Diameter = 4.5;
32+
Insert_Depth = 10;
33+
34+
/* [Mounting Screws] */
35+
Mounting_Screws_X = true;
36+
Mounting_Screws_Y = false;
37+
Mounting_Screw_Diameter = 4.0;
38+
Mounting_Screw_Style = "flat"; // [flat: Flat, countersink: Countersink, inset: Inset]
39+
40+
/* [Hexagon Pattern] */
41+
Pattern_Bottom = false;
42+
Pattern_Lid = false;
43+
// 1 = pattern, 0 = no pattern
44+
Pattern_Walls = [0, 0, 0, 0]; // [0:1:1]
45+
46+
/* [Advanced Options] */
47+
Screw_Inset = 4;
48+
Corner_Radius = 3; // [0:0.1:5]
49+
Edge_Radius = 1.5; // [0:0.1:4]
50+
Screw_Count = 4; // [2: 2, 4: 4]
51+
Screw_Fit = 0.4;
52+
53+
/* [Development Toggles] */
54+
55+
module __end_customizer_options__() { }
56+
57+
// Constants //
58+
59+
$fa = $preview ? $fa : 2;
60+
$fs = $preview ? $fs / 4 : 0.4;
61+
62+
pcb_thickness = 1.6;
63+
64+
// Internal Modules //
65+
66+
module ebox_interior() {
67+
pcb40_round_3d()
68+
pcb40_supports(cut=!Extend_PCB_Mount);
69+
pcb40_box_interior();
70+
}
71+
72+
module ebox_cutouts() {
73+
$p_height = $p_height - Thickness;
74+
translate([0, 0, Thickness])
75+
pcb40_screw_holes(chamfer_bottom=false);
76+
}
77+
78+
module ebox_extras() {
79+
if ($preview && PCB_Preview)
80+
translate([0, 0, Thickness + PCB_Mount_Height + slop])
81+
pcb40_pcb();
82+
}
83+
84+
pcb40(
85+
x=PCB_Units[0],
86+
y=PCB_Units[1],
87+
height=PCB_Mount_Height + Thickness
88+
)
89+
ebox(
90+
dimensions=concat(pcb40_dimensions() + Box_Fit, Height),
91+
thickness=Thickness,
92+
lid_height=Lid_Height,
93+
screw_diameter=Screw_Diameter,
94+
insert_diameter=Insert_Diameter,
95+
insert_depth=Insert_Depth,
96+
screw_style=Screw_Style,
97+
mounting_screws_x=Mounting_Screws_X,
98+
mounting_screws_y=Mounting_Screws_Y,
99+
mounting_screw_diameter=Mounting_Screw_Diameter,
100+
mounting_screw_style=Mounting_Screw_Style,
101+
pattern_lid=Pattern_Lid,
102+
pattern_bottom=Pattern_Bottom,
103+
pattern_walls=Pattern_Walls
104+
)
105+
ebox_adjustments(
106+
print_orientation=Print_Orientation,
107+
screw_inset=Screw_Inset,
108+
corner_radius=Corner_Radius,
109+
edge_radius=Edge_Radius,
110+
screw_count=Screw_Count,
111+
screw_fit=Screw_Fit
112+
) {
113+
ebox_part(Part);
114+
}
115+
116+
// User Modules //
117+
118+
module pcb40_box_interior() {
119+
// Add custom cutouts here
120+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* ESPHome 40x40mm PCB mount
3+
* By smkent (GitHub) / bulbasaur0 (Printables)
4+
*
5+
* Licensed under Creative Commons (4.0 International License) Attribution-ShareAlike
6+
*/
7+
8+
module __end_customizer_options__() { }
9+
10+
// Constants //
11+
12+
$fa = $preview ? $fa : 2;
13+
$fs = $preview ? $fs : 0.4;
14+
15+
pcb_grid = 40;
16+
pcb_grid_sep = 2;
17+
corner_radius = 3;
18+
hole_inset = 3;
19+
pcb_hole_d = 3.2;
20+
pcb_hole_clearance = 2.495 + 0.5;
21+
22+
edge_outset = 2;
23+
hole_to_edge = edge_outset + hole_inset;
24+
25+
pcb_thick = 1.6;
26+
27+
slop = 0.001;
28+
29+
// Functions //
30+
31+
function pcb40_dimensions() = [
32+
$p_x * pcb_grid + ($p_x - 1) * pcb_grid_sep,
33+
$p_y * pcb_grid + ($p_y - 1) * pcb_grid_sep,
34+
];
35+
36+
// Public Modules //
37+
38+
module pcb40(
39+
x=1,
40+
y=1,
41+
height=6,
42+
edge_radius=0.5,
43+
screw_insert_diameter=4.5,
44+
pcb_support_chamfer=1.5,
45+
inner_holes=true
46+
) {
47+
$p_x = x;
48+
$p_y = y;
49+
$p_height = height;
50+
$p_edge_radius = edge_radius;
51+
$p_screw_insert_diameter = screw_insert_diameter;
52+
$p_pcb_support_chamfer = pcb_support_chamfer;
53+
$p_inner_holes = inner_holes;
54+
children();
55+
}
56+
57+
module pcb40_round_3d(radius=$p_edge_radius) {
58+
if (radius == 0) {
59+
children();
60+
} else {
61+
render()
62+
minkowski() {
63+
children();
64+
for (mz = [0, 1])
65+
mirror([0, 0, mz])
66+
cylinder(r1=radius, r2=0, h=radius);
67+
}
68+
}
69+
}
70+
71+
module pcb40_supports(add_radius=true, cut=true) {
72+
intersection() {
73+
if (cut) {
74+
linear_extrude(height=$p_height * 2)
75+
pcb40_perimeter_shape();
76+
}
77+
translate([0, 0, $p_edge_radius])
78+
_at_pcb40_grid_corners()
79+
_pcb40_hull_pair($p_height - $p_edge_radius * 2) {
80+
offset(r=$p_pcb_support_chamfer)
81+
_pcb40_support_quad_shape();
82+
_pcb40_support_quad_shape();
83+
}
84+
}
85+
}
86+
87+
module pcb40_screw_holes(chamfer_bottom=true) {
88+
_at_pcb40_holes() {
89+
translate([0, 0, -slop])
90+
cylinder(d=$p_screw_insert_diameter, h=$p_height + slop * 2);
91+
translate([0, 0, $p_height - $p_edge_radius])
92+
cylinder(d1=$p_screw_insert_diameter, d2=$p_screw_insert_diameter + 2 * $p_edge_radius, h=$p_edge_radius + slop);
93+
if (chamfer_bottom)
94+
translate([0, 0, -slop])
95+
cylinder(d1=$p_screw_insert_diameter + 2 * $p_edge_radius, d2=$p_screw_insert_diameter, h=$p_edge_radius + slop);
96+
}
97+
}
98+
99+
module pcb40_perimeter_shape() {
100+
size = pcb40_dimensions();
101+
offset(r=-$p_edge_radius)
102+
offset(r=hole_to_edge)
103+
offset(r=-hole_to_edge)
104+
square([size[0] + edge_outset * 2, size[1] + edge_outset * 2], center=true);
105+
}
106+
107+
module pcb40_pcb() {
108+
color("darkseagreen", 0.5)
109+
linear_extrude(height=pcb_thick)
110+
difference() {
111+
$fs = $preview ? ($fs / 4) : $fs;
112+
offset(r=corner_radius)
113+
offset(r=-corner_radius)
114+
square(pcb40_dimensions(), center=true);
115+
_at_pcb40_holes()
116+
circle(d=pcb_hole_d);
117+
}
118+
}
119+
120+
// Internal Modules //
121+
122+
module _pcb40_hull_pair(height) {
123+
slop = 0.001;
124+
hull() {
125+
for (child_obj = [
126+
// Child index, height offset
127+
[0, 0],
128+
[1, height - slop]
129+
]) {
130+
translate([0, 0, child_obj[1]])
131+
linear_extrude(height=slop)
132+
children(child_obj[0]);
133+
}
134+
}
135+
}
136+
137+
module _at_pcb40_grid() {
138+
translate([
139+
-($p_x - 1) / 2 * (pcb_grid_sep + pcb_grid),
140+
-($p_y - 1) / 2 * (pcb_grid_sep + pcb_grid),
141+
])
142+
for (px = [0:1:$p_x - 1], py = [0:1:$p_y - 1])
143+
translate([px * (pcb_grid + pcb_grid_sep), py * (pcb_grid + pcb_grid_sep)])
144+
union() {
145+
$p_grid_x = px;
146+
$p_grid_y = py;
147+
children();
148+
}
149+
}
150+
151+
module _at_pcb40_grid_corners() {
152+
translate([
153+
-$p_x / 2 * (pcb_grid + pcb_grid_sep),
154+
-$p_y / 2 * (pcb_grid + pcb_grid_sep)
155+
])
156+
for (px = [0:1:$p_x], py = [0:1:$p_y]) {
157+
inner = (px > 0 && px < $p_x) && (py > 0 && py < $p_y);
158+
if (!inner || ($p_inner_holes && inner))
159+
translate([
160+
px * (pcb_grid + pcb_grid_sep),
161+
py * (pcb_grid + pcb_grid_sep)
162+
])
163+
children();
164+
}
165+
}
166+
167+
module _at_pcb40_holes() {
168+
_at_pcb40_grid()
169+
union() {
170+
px = $p_grid_x;
171+
py = $p_grid_y;
172+
for (hx = [0, 1], hy = [0, 1]) {
173+
edge_x0 = (px == 0 && hx == 0);
174+
edge_x1 = (px == ($p_x - 1) && hx == 1);
175+
edge_y0 = (py == 0 && hy == 0);
176+
edge_y1 = (py == ($p_y - 1) && hy == 1);
177+
inner_x = !(edge_x0 || edge_x1);
178+
inner_y = !(edge_y0 || edge_y1);
179+
inner = (inner_x && inner_y);
180+
if (!inner || ($p_inner_holes && inner))
181+
mirror([1 - hx, 0])
182+
mirror([0, 1 - hy])
183+
translate([pcb_grid / 2 - hole_inset, pcb_grid / 2 - hole_inset])
184+
children();
185+
}
186+
}
187+
}
188+
189+
module _pcb40_support_quad_shape() {
190+
offset(r=3)
191+
offset(r=-3)
192+
square((hole_inset + pcb_hole_clearance) * 2 + pcb_grid_sep, center=true);
193+
}

0 commit comments

Comments
 (0)