From 56ee44b6d739a67992eb00e373a27fb4a3908211 Mon Sep 17 00:00:00 2001 From: Stephen Kent Date: Sun, 8 Dec 2024 21:16:49 -0800 Subject: [PATCH] Create reflow-oven-parts --- electronics/reflow-oven-parts/LICENSE | 1 + electronics/reflow-oven-parts/README.md | 20 +++ electronics/reflow-oven-parts/SConscript | 13 ++ .../reflow-oven-parts/enclosure-mount.scad | 138 ++++++++++++++++++ .../reflow-oven-parts/images/publish/demo.png | Bin 0 -> 9756 bytes .../reflow-oven-parts/images/readme/demo.png | Bin 0 -> 20478 bytes .../reflow-oven-parts/panel-grommet.scad | 129 ++++++++++++++++ 7 files changed, 301 insertions(+) create mode 100644 electronics/reflow-oven-parts/LICENSE create mode 100644 electronics/reflow-oven-parts/README.md create mode 100644 electronics/reflow-oven-parts/SConscript create mode 100644 electronics/reflow-oven-parts/enclosure-mount.scad create mode 100644 electronics/reflow-oven-parts/images/publish/demo.png create mode 100644 electronics/reflow-oven-parts/images/readme/demo.png create mode 100644 electronics/reflow-oven-parts/panel-grommet.scad diff --git a/electronics/reflow-oven-parts/LICENSE b/electronics/reflow-oven-parts/LICENSE new file mode 100644 index 00000000..4cc9cb55 --- /dev/null +++ b/electronics/reflow-oven-parts/LICENSE @@ -0,0 +1 @@ +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. diff --git a/electronics/reflow-oven-parts/README.md b/electronics/reflow-oven-parts/README.md new file mode 100644 index 00000000..eb84eef3 --- /dev/null +++ b/electronics/reflow-oven-parts/README.md @@ -0,0 +1,20 @@ +# Controleo3 reflow oven add-ons + +![This model is a work in progress][work-in-progress-badge] +[![CC-BY-SA-4.0 license][license-badge]][license] + +Misc add-ons for Controleo3 reflow oven: + +* Front panel wiring grommet +* Enclosure mounting spacer + +![Model render](images/readme/demo.png) + +## License + +This model is licensed under [Creative Commons (4.0 International License) Attribution-ShareAlike][license]. + + +[license]: http://creativecommons.org/licenses/by-sa/4.0/ +[license-badge]: /_static/license-badge-cc-by-sa-4.0.svg +[work-in-progress-badge]: /_static/work-in-progress-badge.svg diff --git a/electronics/reflow-oven-parts/SConscript b/electronics/reflow-oven-parts/SConscript new file mode 100644 index 00000000..757e72ac --- /dev/null +++ b/electronics/reflow-oven-parts/SConscript @@ -0,0 +1,13 @@ +Import("env") +b = ModelBuilder(env) + +panel_model = "panel-grommet.scad" +enclosure_mount_model = "enclosure-mount.scad" + +b.STL("panel-grommet.stl", panel_model) +b.STL("enclosure-mount.stl", enclosure_mount_model) +b.Image("demo.png", panel_model) + +b.add_default_targets() + +# vim: ft=python diff --git a/electronics/reflow-oven-parts/enclosure-mount.scad b/electronics/reflow-oven-parts/enclosure-mount.scad new file mode 100644 index 00000000..72b2ae8e --- /dev/null +++ b/electronics/reflow-oven-parts/enclosure-mount.scad @@ -0,0 +1,138 @@ +/* + * Controleo3 reflow oven add-ons + * Enclosure mounting spacer + * By smkent (GitHub) / bulbasaur0 (Printables) + * + * Licensed under Creative Commons (4.0 International License) Attribution-ShareAlike + */ + +/* [Size] */ +// All units in millimeters + +Dimensions = [38, 15]; + +Thickness = 4; // [1.5:0.1:10] +Diameter = 35; +Hole_Diameter = 16; // [10:0.1:30] +Screw_Hole_Diameter = 3; // [2:0.1:5] +Screw_Hole_Offset = 14; +Screw_Separation = 19; +Grommet_Thickness = 3; // [0.8:0.1:5] +Grommet_Depth = 2; // [0.4:0.1:5] + +/* [Advanced Options] */ +Screw_Hole_Fit = 0.2; // [0:0.05:1] +Screw_Hole_Style = "inset"; // [flat: Flat, countersink: Countersink, inset: Inset] +Edge_Radius = 0.4; // [0:0.1:3] + +/* [Development Toggles] */ + +module __end_customizer_options__() { } + +// Constants // + +$fa = $preview ? $fa : 2; +$fs = $preview ? $fs / 2 : 0.4; + +slop = 0.001; + +// Modules // + +module _round_3d(radius = Edge_Radius) { + if (radius == 0) { + children(); + } else { + render() + minkowski() { + children(); + for (mz = [0, 1]) + mirror([0, 0, mz]) + cylinder(r1=radius, r2=0, h=radius); + } + } +} + +module _screw_hole(d, h, fit=0, style="flat", print_upside_down=false) { + inset_bare_min_h = 1.4; + inset_min_h = (style == "inset") ? max((h - d), inset_bare_min_h) - (h - d) : 0; + translate([0, 0, -slop]) + cylinder(d=(d + fit), h=h + slop * 2); + if (style == "countersink" || style == "inset") { + translate([0, 0, h + inset_min_h + slop * 2]) + mirror([0, 0, 1]) + cylinder(d1=d * 2, d2=d * (style == "inset" ? 2 : 1), h=d); + } + if (style == "inset" && print_upside_down) { + layer_height = 0.2; + translate([0, 0, (h + inset_min_h) - d - layer_height]) + linear_extrude(height=layer_height + slop * 2) + intersection() { + square([d * 2, d + fit], center=true); + circle(d=d*2); + } + } +} + +module at_enclosure_mount_screw_holes() { + for (mx = [0, 1]) + mirror([mx, 0]) + translate([Screw_Separation / 2, 0]) + children(); +} + +module enclosure_mount_body() { + difference() { + translate([0, 0, Edge_Radius]) + union() { + rr = 2; + _round_3d() + difference() { + linear_extrude(height=Thickness - Edge_Radius * 2) + offset(r=rr) + offset(r=-rr) + square(Dimensions, center=true); + translate([0, 0, Dimensions[1] + (Thickness - Edge_Radius * 2) / 2]) + rotate([0, 90, 0]) + cylinder(h=Dimensions[0], d=Dimensions[1] * 2, center=true); + } + } + if(0) + union() { + dd = Hole_Diameter - Grommet_Thickness * 2; + translate([0, 0, slop]) + linear_extrude(height=Thickness + Grommet_Depth + slop * 2) + circle(d=dd); + translate([0, 0, -slop]) + cylinder(d2=dd, d1=dd + Edge_Radius * 2, h=Edge_Radius); + translate([0, 0, Thickness + Grommet_Depth - Edge_Radius + slop]) + cylinder(d1=dd, d2=dd + Edge_Radius * 2, h=Edge_Radius); + } + } +} + +module enclosure_mount_screw_holes() { + translate([0, 0, Thickness]) + mirror([0, 0, 1]) + at_enclosure_mount_screw_holes() + hull() { + oy = (Dimensions[1] - Screw_Hole_Diameter) / 4; + for (my = [0, 1]) + mirror([0, my]) + translate([0, oy, 0]) + cylinder(d=Screw_Hole_Diameter + Screw_Hole_Fit, h=Thickness * 2); + } +} + +module panel_grommet() { + difference() { + enclosure_mount_body(); + enclosure_mount_screw_holes(); + } +} + +module main() { + color("yellowgreen", 0.8) + panel_grommet(); +} + +main(); diff --git a/electronics/reflow-oven-parts/images/publish/demo.png b/electronics/reflow-oven-parts/images/publish/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..8f13345796efaf11c7c26609f544572a2431302d GIT binary patch literal 9756 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 Y9wF}4C>ebMEBOE$3&+dVXl&wt0K%d?CjbBd literal 0 HcmV?d00001 diff --git a/electronics/reflow-oven-parts/panel-grommet.scad b/electronics/reflow-oven-parts/panel-grommet.scad new file mode 100644 index 00000000..d3f71be9 --- /dev/null +++ b/electronics/reflow-oven-parts/panel-grommet.scad @@ -0,0 +1,129 @@ +/* + * Controleo3 reflow oven add-ons + * Front panel wiring grommet + * By smkent (GitHub) / bulbasaur0 (Printables) + * + * Licensed under Creative Commons (4.0 International License) Attribution-ShareAlike + */ + +/* [Size] */ +// All units in millimeters + +Thickness = 3; // [1.5:0.1:10] +Diameter = 35; +Hole_Diameter = 16; // [10:0.1:30] +Screw_Hole_Diameter = 3; // [2:0.1:5] +Screw_Hole_Offset = 14; +Grommet_Thickness = 3; // [0.8:0.1:5] +Grommet_Depth = 2; // [0.4:0.1:5] + +/* [Advanced Options] */ +Screw_Hole_Fit = 0.2; // [0:0.05:1] +Screw_Hole_Style = "inset"; // [flat: Flat, countersink: Countersink, inset: Inset] +Edge_Radius = 0.4; // [0:0.1:3] + +/* [Development Toggles] */ + +module __end_customizer_options__() { } + +// Constants // + +$fa = $preview ? $fa : 2; +$fs = $preview ? $fs / 2 : 0.4; + +slop = 0.001; + +// Modules // + +module _round_3d(radius = Edge_Radius) { + if (radius == 0) { + children(); + } else { + render() + minkowski() { + children(); + for (mz = [0, 1]) + mirror([0, 0, mz]) + cylinder(r1=radius, r2=0, h=radius); + } + } +} + +module _screw_hole(d, h, fit=0, style="flat", print_upside_down=false) { + inset_bare_min_h = 1.4; + inset_min_h = (style == "inset") ? max((h - d), inset_bare_min_h) - (h - d) : 0; + translate([0, 0, -slop]) + cylinder(d=(d + fit), h=h + slop * 2); + if (style == "countersink" || style == "inset") { + translate([0, 0, h + inset_min_h + slop * 2]) + mirror([0, 0, 1]) + cylinder(d1=d * 2, d2=d * (style == "inset" ? 2 : 1), h=d); + } + if (style == "inset" && print_upside_down) { + layer_height = 0.2; + translate([0, 0, (h + inset_min_h) - d - layer_height]) + linear_extrude(height=layer_height + slop * 2) + intersection() { + square([d * 2, d + fit], center=true); + circle(d=d*2); + } + } +} + +module at_panel_grommet_screw_holes() { + for (angle = [0:90:270]) + rotate(angle) + translate([Screw_Hole_Offset, 0]) + children(); +} + +module panel_grommet_body() { + difference() { + translate([0, 0, Edge_Radius]) + union() { + _round_3d() + linear_extrude(height=Thickness - Edge_Radius * 2) + circle(d=Diameter); + _round_3d() + linear_extrude(height=Thickness + Grommet_Depth - Edge_Radius * 2) + circle(d=Hole_Diameter - Edge_Radius * 2); + } + union() { + dd = Hole_Diameter - Grommet_Thickness * 2; + translate([0, 0, slop]) + linear_extrude(height=Thickness + Grommet_Depth + slop * 2) + circle(d=dd); + translate([0, 0, -slop]) + cylinder(d2=dd, d1=dd + Edge_Radius * 2, h=Edge_Radius); + translate([0, 0, Thickness + Grommet_Depth - Edge_Radius + slop]) + cylinder(d1=dd, d2=dd + Edge_Radius * 2, h=Edge_Radius); + } + } +} + +module panel_grommet_screw_holes() { + translate([0, 0, Thickness]) + mirror([0, 0, 1]) + at_panel_grommet_screw_holes() + _screw_hole( + d=Screw_Hole_Diameter, + h=Thickness, + fit=Screw_Hole_Fit, + style=Screw_Hole_Style, + print_upside_down=true + ); +} + +module panel_grommet() { + difference() { + panel_grommet_body(); + panel_grommet_screw_holes(); + } +} + +module main() { + color("lightsteelblue", 0.8) + panel_grommet(); +} + +main();