1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-03 12:22:46 +02:00

Compare commits

...

15 Commits

Author SHA1 Message Date
Chris Palmer
05e8055ce2 Merge branch 'martinbudden-btt_skr_e3_turbo' 2021-02-07 22:01:41 +00:00
Chris Palmer
21822b9abb Updated pictures and readme. 2021-02-07 22:01:26 +00:00
Chris Palmer
d83d4b89bf Merge branch 'btt_skr_e3_turbo' of https://github.com/martinbudden/NopSCADlib into martinbudden-btt_skr_e3_turbo 2021-02-07 21:48:16 +00:00
Chris Palmer
613152f589 Merge branch 'martinbudden-bl30x10' 2021-02-07 21:46:28 +00:00
Chris Palmer
d90c00d140 Updated images and readme. 2021-02-07 21:46:15 +00:00
Chris Palmer
b52ca9589a Merge branch 'bl30x10' of https://github.com/martinbudden/NopSCADlib into martinbudden-bl30x10 2021-02-07 21:25:53 +00:00
Martin Budden
0d024060fc Added BTT_SKR_E3_TURBO. 2021-02-07 07:51:10 +00:00
Chris Palmer
a3ced6de45 Merge branch 'martinbudden-mgn9_correction' 2021-02-06 15:29:51 +00:00
Chris Palmer
1cdfe3267c Merge branch 'mgn9_correction' of https://github.com/martinbudden/NopSCADlib into martinbudden-mgn9_correction 2021-02-06 15:28:49 +00:00
Chris Palmer
b67cf4ce97 Library printed parts now make use of stl() child. 2021-02-06 15:24:19 +00:00
Chris Palmer
5bac2bf46d stl() and dxf() can now have the code to make the STL or DXF as a child.
This allows them to be replaced by the STL or DXF when making assembly views.

use_dxf() and use_stl() make use of $cwd and $target, so can be in bom.scad
and be documented.

Corrected the spelling of widget in BOM test.
2021-02-06 15:23:10 +00:00
Chris Palmer
079168142b Views.py and plateup.py now define $cwd and $target. 2021-02-06 15:12:21 +00:00
Martin Budden
812fbc106c Updated screw hole position. 2021-02-04 19:59:28 +00:00
Martin Budden
dd38fa6e5d Added 30x10 square radial fan. 2021-02-04 18:26:44 +00:00
Martin Budden
5cdcd4ad37 Corrected MGN9 rail end value. 2021-02-03 11:24:44 +00:00
34 changed files with 1010 additions and 870 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 875 KiB

After

Width:  |  Height:  |  Size: 882 KiB

View File

@@ -139,17 +139,17 @@ module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
}
module box_corner_profile(type) { //! Generates the corner profile STL for 3D printing.
stl("box_corner_profile");
length = box_height(type) - 2 * box_margin(type);
difference() {
linear_extrude(length, center = true, convexity = 5)
box_corner_profile_2D(type);
for(z = [-1, 1])
translate([box_hole_inset(type), box_hole_inset(type), z * length / 2])
insert_hole(box_insert(type), 5);
}
stl("box_corner_profile")
difference() {
linear_extrude(length, center = true, convexity = 5)
box_corner_profile_2D(type);
for(z = [-1, 1])
translate([box_hole_inset(type), box_hole_inset(type), z * length / 2])
insert_hole(box_insert(type), 5);
}
}
module box_corner_profile_section(type, section, sections) { //! Generates interlocking sections of the corner profile to allow it to be taller than the printer
@@ -209,7 +209,6 @@ module box_corner_quadrants(type, width, depth)
}
module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
stl(bottom ? "bottom_bezel" : "top_bezel");
feet = bottom && box_feet(type);
t = box_sheet_slot(type);
outset = box_outset(type);
@@ -221,66 +220,67 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
height = box_bezel_height(type, bottom);
foot_extension = foot_height - height;
difference() {
w = box_width(type);
d = box_depth(type);
translate_z(-box_profile_overlap(type)) difference() {
tw = w + 2 * outset;
td = d + 2 * outset;
rounded_rectangle([tw, td, feet ? foot_height : height], box_corner_rad(type), false);
//
// Remove edges between the feet
//
if(feet)
hull() {
translate_z(height + 0.5)
cube([w - 2 * foot_length, td + 1, 1], center = true);
stl(bottom ? "bottom_bezel" : "top_bezel")
difference() {
w = box_width(type);
d = box_depth(type);
translate_z(-box_profile_overlap(type)) difference() {
tw = w + 2 * outset;
td = d + 2 * outset;
rounded_rectangle([tw, td, feet ? foot_height : height], box_corner_rad(type), false);
//
// Remove edges between the feet
//
if(feet)
hull() {
translate_z(height + 0.5)
cube([w - 2 * foot_length, td + 1, 1], center = true);
translate_z(foot_height + 1)
cube([w - 2 * (foot_length - foot_extension), td + 1, 1], center = true);
}
if(feet)
hull() {
translate_z(height + 0.5)
cube([tw + 1, d - 2 * foot_length, 1], center = true);
translate_z(foot_height + 1)
cube([tw + 1, d - 2 * (foot_length - foot_extension), 1], center = true);
}
}
//
// slots for side panels
//
translate_z(-box_profile_overlap(type))
linear_extrude(2 * box_profile_overlap(type), center = true)
for(i = [-1, 1]) {
translate([i * (w + t - sheet_slot_clearance) / 2, 0])
square([t, d - 2 * cgap], center = true);
translate([0, i * (d + t - sheet_slot_clearance) / 2])
square([w - 2 * cgap, t], center = true);
}
//
// recess for top / bottom panel
//
translate_z(cgap)
rounded_rectangle([w + bezel_clearance, d + bezel_clearance, height], inner_r + bezel_clearance / 2, false);
//
// leave plastic over the corner profiles
//
translate_z(-box_profile_overlap(type) - 1)
linear_extrude(box_profile_overlap(type) + cgap + 2)
union() {
difference() {
square([w - 2 * inset,
d - 2 * inset], center = true);
box_corner_quadrants(type, w, d);
translate_z(foot_height + 1)
cube([w - 2 * (foot_length - foot_extension), td + 1, 1], center = true);
}
box_screw_hole_positions(type)
poly_circle(screw_clearance_radius(box_screw(type)));
}
}
if(feet)
hull() {
translate_z(height + 0.5)
cube([tw + 1, d - 2 * foot_length, 1], center = true);
translate_z(foot_height + 1)
cube([tw + 1, d - 2 * (foot_length - foot_extension), 1], center = true);
}
}
//
// slots for side panels
//
translate_z(-box_profile_overlap(type))
linear_extrude(2 * box_profile_overlap(type), center = true)
for(i = [-1, 1]) {
translate([i * (w + t - sheet_slot_clearance) / 2, 0])
square([t, d - 2 * cgap], center = true);
translate([0, i * (d + t - sheet_slot_clearance) / 2])
square([w - 2 * cgap, t], center = true);
}
//
// recess for top / bottom panel
//
translate_z(cgap)
rounded_rectangle([w + bezel_clearance, d + bezel_clearance, height], inner_r + bezel_clearance / 2, false);
//
// leave plastic over the corner profiles
//
translate_z(-box_profile_overlap(type) - 1)
linear_extrude(box_profile_overlap(type) + cgap + 2)
union() {
difference() {
square([w - 2 * inset,
d - 2 * inset], center = true);
box_corner_quadrants(type, w, d);
}
box_screw_hole_positions(type)
poly_circle(screw_clearance_radius(box_screw(type)));
}
}
}
dowel_length = 20;
@@ -485,7 +485,6 @@ module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = un
}
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts
stl("shelf_bracket");
w = is_undef(wall) ? box_wall(type) : wall;
insert = box_shelf_insert(type);
lip = 2 * insert_boss_radius(insert, w);
@@ -513,44 +512,45 @@ module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a
square([lip, eps]);
}
difference() {
union() {
linear_extrude(w)
difference() {
shape()
if($children)
children(0);
round(2) offset(-width)
stl("shelf_bracket")
difference() {
union() {
linear_extrude(w)
difference() {
shape()
if($children)
children(0);
}
linear_extrude(lip)
difference() {
shape()
if($children)
children(0);
round(2) offset(-width)
shape()
if($children)
children(0);
}
offset(-w)
linear_extrude(lip)
difference() {
shape()
if($children)
children(0);
}
offset(-w)
shape()
if($children)
children(0);
}
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
boss();
}
if($children > 1)
hflip()
children(1);
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
boss();
insert_hole(insert, counterbore = 1, horizontal = true);
}
if($children > 1)
hflip()
children(1);
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
insert_hole(insert, counterbore = 1, horizontal = true);
}
}
module box_shelf_bracket_section(type, rows, cols, x, y) { //! Generates sections of the shelf bracket to allow it to be bigger than the printer

View File

@@ -49,84 +49,84 @@ module ribbon_grommet_hole(ways, h = 50, expand = true) { //! Generate a hole fo
}
module ribbon_grommet(ways, thickness) { //! Generate the STL for a printed ribbon grommet
stl(str("ribbon_grommet_", ways, "_", thickness));
width = 2 * (wall + clearance) + thickness;
slot_length = ribbon_clamp_slot(ways);
length = slot_length + 2 * wall + 2 * overlap;
rotate([90, 0, 0])
union() {
for(side = [-1, 1])
translate_z(side * (width - wall) / 2)
linear_extrude(wall, center = true, convexity = 5)
difference() {
hull() {
translate([-length / 2, 0])
square([length, base]);
stl(str("ribbon_grommet_", ways, "_", thickness))
rotate([90, 0, 0])
union() {
for(side = [-1, 1])
translate_z(side * (width - wall) / 2)
linear_extrude(wall, center = true, convexity = 5)
difference() {
hull() {
translate([-length / 2, 0])
square([length, base]);
for(end = [-1, 1])
translate([end * (length / 2 - rad), height - rad])
semi_circle(rad);
for(end = [-1, 1])
translate([end * (length / 2 - rad), height - rad])
semi_circle(rad);
}
translate([-slot_length / 2, base])
square([slot_length, slot_height]);
}
translate([-slot_length / 2, base])
square([slot_length, slot_height]);
}
linear_extrude(width -1, center = true)
difference() {
ribbon_grommet_hole(ways, expand = false, h = 0);
linear_extrude(width -1, center = true)
difference() {
ribbon_grommet_hole(ways, expand = false, h = 0);
translate([-slot_length / 2, base])
square([slot_length, slot_height]);
}
}
translate([-slot_length / 2, base])
square([slot_length, slot_height]);
}
}
}
module round_grommet_top(diameter, thickness, od = undef) { //! Generate the STL for a round grommet top half
stl(str("round_grommet_top_", round(diameter * 10), "_", thickness));
chamfer = layer_height;
h = wall + thickness + wall;
r1 = diameter / 2;
r2 = od == undef ? corrected_radius(r1) + wall : od / 2;
r3 = r2 + overlap;
r0 = r1 + 1;
union() {
rotate_extrude()
polygon([
[r0, 0],
[r3 - chamfer, 0],
[r3, chamfer],
[r3, wall],
[r2, wall],
[r2, h - chamfer],
[r2 - chamfer, h],
[r0, h],
]);
stl(str("round_grommet_top_", round(diameter * 10), "_", thickness))
union() {
rotate_extrude()
polygon([
[r0, 0],
[r3 - chamfer, 0],
[r3, chamfer],
[r3, wall],
[r2, wall],
[r2, h - chamfer],
[r2 - chamfer, h],
[r0, h],
]);
render() difference() {
cylinder(r = r0 + eps, h = h);
render() difference() {
cylinder(r = r0 + eps, h = h);
poly_cylinder(r = r1, h = 100, center = true);
poly_cylinder(r = r1, h = 100, center = true);
}
}
}
}
module round_grommet_bottom(diameter, od = undef) { //! Generate the STL for a round grommet bottom half
stl(str("round_grommet_bottom_", round(diameter * 10)));
chamfer = layer_height;
r1 = diameter / 2;
r2 = od == undef ? corrected_radius(r1) + wall : od / 2;
r3 = r2 + max(overlap, wall + chamfer);
rotate_extrude()
polygon([
[r2, chamfer],
[r2 + chamfer, 0],
[r3, 0],
[r3, wall - chamfer],
[r3 - chamfer, wall],
[r2, wall],
]);
stl(str("round_grommet_bottom_", round(diameter * 10)))
rotate_extrude()
polygon([
[r2, chamfer],
[r2 + chamfer, 0],
[r3, 0],
[r3, wall - chamfer],
[r3 - chamfer, wall],
[r2, wall],
]);
}
module round_grommet_hole(diameter, h = 100) //! Make a hole for a round grommet
@@ -161,30 +161,30 @@ module mouse_grommet_hole(r, h = 50, z = undef, expand = wall + clearance) //! M
function mouse_grommet_offset(r) = r + wall;
module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
stl(str("mouse_grommet_", r * 10, "_", thickness));
width = 2 * (wall + clearance) + thickness;
length = 2 * r + 2 * wall + 2 * overlap;
rotate([90, 0, 0])
union() {
for(side = [-1, 1])
translate_z(side * (width - wall) / 2)
linear_extrude(wall, center = true)
difference() {
mouse_grommet_hole(r, z = r + wall, h = 0, expand = wall + overlap);
stl(str("mouse_grommet_", r * 10, "_", thickness))
rotate([90, 0, 0])
union() {
for(side = [-1, 1])
translate_z(side * (width - wall) / 2)
linear_extrude(wall, center = true)
difference() {
mouse_grommet_hole(r, z = r + wall, h = 0, expand = wall + overlap);
translate([0, wall])
mouse_grommet_hole(r, h = 0, expand = 0);
}
linear_extrude(width - 1, center = true)
difference() {
mouse_grommet_hole(r, h = 0, z = r + wall, expand = wall);
translate([0, wall])
mouse_grommet_hole(r, h = 0, expand = 0);
}
linear_extrude(width - 1, center = true)
difference() {
mouse_grommet_hole(r, h = 0, z = r + wall, expand = wall);
translate([0, wall])
mouse_grommet_hole(r, h = 0, expand = 0);
}
}
}
}
module mouse_grommet_assembly(r, thickness)

View File

@@ -82,7 +82,6 @@ module cam_holes(cam) {
}
module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
stl("rpi_camera_focus_ring");
rad = 15 / 2;
hole_r1 = 2.5 / 2;
@@ -93,58 +92,58 @@ module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
x = rad / (sin(angle / 2) + cos(angle / 2));
r = x * sin(angle / 2);
difference() {
linear_extrude(height = thickness, convexity = 5)
difference() {
union() {
circle(x);
stl("rpi_camera_focus_ring")
difference() {
linear_extrude(height = thickness, convexity = 5)
difference() {
union() {
circle(x);
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i])
translate([x, 0])
circle(r);
}
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i])
rotate([0, 0, 2 * angle * i + angle])
translate([x, 0])
circle(r);
}
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i + angle])
translate([x, 0])
circle(r);
}
hull() {
poly_cylinder(r = hole_r1, h = 0.1, center = true);
hull() {
poly_cylinder(r = hole_r1, h = 0.1, center = true);
translate([0, 0, thickness])
poly_cylinder(r = hole_r2, h = 0.1, center = true);
translate([0, 0, thickness])
poly_cylinder(r = hole_r2, h = 0.1, center = true);
}
}
}
}
module camera_back(cam) { //! Make the STL for a camera case back
stl(str("camera_back_", cam[0]));
pcb = camera_pcb(cam);
back = cam_back_size(cam);
screw = pcb_screw(pcb);
nut = screw_nut(screw);
translate_z(back.z)
hflip()
difference() {
translate_z(back.z / 2)
cube(back, center = true);
stl(str("camera_back_", cam[0]))
translate_z(back.z)
hflip()
difference() {
translate_z(back.z / 2)
cube(back, center = true);
translate([0, -cam_back_overlap])
cube([pcb_length(pcb) - 2 * cam_back_overlap, pcb_width(pcb), 2 * cam_back_clearance], center = true);
translate([0, -cam_back_overlap])
cube([pcb_length(pcb) - 2 * cam_back_overlap, pcb_width(pcb), 2 * cam_back_clearance], center = true);
translate([0, -pcb_width(pcb) / 2])
cube([connector_size.x + 2 * clearance, 2 * connector_size.y + 1, 2 * round_to_layer(connector_size.z + clearance)], center = true);
translate([0, -pcb_width(pcb) / 2])
cube([connector_size.x + 2 * clearance, 2 * connector_size.y + 1, 2 * round_to_layer(connector_size.z + clearance)], center = true);
translate_z(back.z)
cam_holes(cam)
hflip()
nut_trap(screw, nut, supported = true);
}
translate_z(back.z)
cam_holes(cam)
hflip()
nut_trap(screw, nut, supported = true);
}
}
module camera_front(cam, hinge = 0) { //! Make the STL for a camera case front
stl(str("camera_front_", cam[0]));
front = cam_front_size(cam);
back = cam_back_size(cam);
pcb = camera_pcb(cam);
@@ -170,70 +169,71 @@ module camera_front(cam, hinge = 0) { //! Make the STL for a camera case front
translate([0, (hinge ? front.x * hinge : front.y) / 2 + hinge_offset, hinge_r])
children();
difference() {
union() {
hull()
for(x = [-1, 1], y = [-1, 1])
translate([x * (front.x / 2 - rad), y * (front.y / 2 - rad)])
hull() { // 3D truncated teardrop gives radiused edges without exceeding 45 degree overhang
translate_z(front.z - 1)
cylinder(r = rad, h = 1);
stl(str("camera_front_", cam[0]))
difference() {
union() {
hull()
for(x = [-1, 1], y = [-1, 1])
translate([x * (front.x / 2 - rad), y * (front.y / 2 - rad)])
hull() { // 3D truncated teardrop gives radiused edges without exceeding 45 degree overhang
translate_z(front.z - 1)
cylinder(r = rad, h = 1);
translate_z(rad)
sphere(rad);
translate_z(rad)
sphere(rad);
cylinder(r = rad * (sqrt(2) - 1), h = eps);
}
cylinder(r = rad * (sqrt(2) - 1), h = eps);
}
hinge_pos()
hull() {
rotate([-90, 0, -90])
teardrop(r = hinge_r, h = hinge_h, center = false);
hinge_pos()
hull() {
rotate([-90, 0, -90])
teardrop(r = hinge_r, h = hinge_h, center = false);
translate([0, -10, -hinge_r])
cube([hinge_h, eps, 2 * hinge_r]);
}
}
hinge_pos()
rotate([90, 0, 90])
teardrop_plus(r = screw_clearance_radius(hinge_screw), h = 100, center = true);
translate_z(front.z / 2 + shelf - layer_height) // recess for the back
cube([back.x + 2 * clearance, back.y + 2 * clearance, front.z], center = true);
translate_z(front.z / 2 + shelf - pcb_size.z) // recess for PCB
cube([pcb_size.x + 2 * clearance, pcb_size.y + 2 * clearance, front.z], center = true);
translate_z(shelf)
hflip() {
pcb_component_position(pcb, "smd_led") // clearance for LED
cube(led_clearance, center = true);
pcb_component_position(pcb, "smd_res") // clearance for resistor
cube(res_clearance, center = true);
translate([0, -10, -hinge_r])
cube([hinge_h, eps, 2 * hinge_r]);
}
}
translate([conn_pos.x, lens_offset.y + sensor_length / 2, shelf - pcb_size.z]) // clearance for sensor connector
cube([conn.x + 2 * clearance, sensor_length, 2 * cam_front_clearance(cam)], center = true);
hinge_pos()
rotate([90, 0, 90])
teardrop_plus(r = screw_clearance_radius(hinge_screw), h = 100, center = true);
translate([0, -front.y / 2, shelf + front.z / 2]) // slot for connector
cube([connector_slot.x, connector_slot.y, front.z], center = true);
translate_z(front.z / 2 + shelf - layer_height) // recess for the back
cube([back.x + 2 * clearance, back.y + 2 * clearance, front.z], center = true);
translate_z(cam_back_clearance + layer_height)
cam_holes(cam)
rotate(90)
poly_cylinder(r = screw_clearance_radius(screw), h = 100, center = true);
translate_z(front.z / 2 + shelf - pcb_size.z) // recess for PCB
cube([pcb_size.x + 2 * clearance, pcb_size.y + 2 * clearance, front.z], center = true);
translate_z(shelf)
hflip() {
pcb_component_position(pcb, "smd_led") // clearance for LED
cube(led_clearance, center = true);
pcb_component_position(pcb, "smd_res") // clearance for resistor
cube(res_clearance, center = true);
}
translate([conn_pos.x, lens_offset.y + sensor_length / 2, shelf - pcb_size.z]) // clearance for sensor connector
cube([conn.x + 2 * clearance, sensor_length, 2 * cam_front_clearance(cam)], center = true);
translate([0, -front.y / 2, shelf + front.z / 2]) // slot for connector
cube([connector_slot.x, connector_slot.y, front.z], center = true);
translate_z(cam_back_clearance + layer_height)
cam_holes(cam)
rotate(90)
poly_cylinder(r = screw_clearance_radius(screw), h = 100, center = true);
translate_z(shelf - pcb_size.z)
hflip()
camera_lens(cam, clearance);
translate_z(shelf - pcb_size.z)
hflip()
camera_lens(cam, clearance);
hflip()
pcb_component_position(pcb, "smd_led")
rotate(45)
poly_cylinder(r = led_hole_r, h = 100, center = true); // hole for led
}
pcb_component_position(pcb, "smd_led")
rotate(45)
poly_cylinder(r = led_hole_r, h = 100, center = true); // hole for led
}
}
function bracket_thickness(cam) = max(wall, min(3.5, hinge_z(cam) - hinge_r - 1));
@@ -253,34 +253,35 @@ module camera_bracket_position(cam) //! Position children at the bracket positio
children();
module camera_bracket(cam) { //! Make the STL for the camera bracket
stl(str("camera_bracket_", cam[0]));
t = bracket_thickness(cam);
z = hinge_z(cam);
translate([hinge_h / 2, 0])
difference() {
hull() {
translate_z(eps / 2)
cube([hinge_h, 2 * hinge_r, eps], center = true);
translate_z(z)
rotate([0, 90, 0])
cylinder(r = hinge_r, h = hinge_h, center = true);
stl(str("camera_bracket_", cam[0])) union() {
translate([hinge_h / 2, 0])
difference() {
hull() {
translate_z(eps / 2)
cube([hinge_h, 2 * hinge_r, eps], center = true);
translate_z(z)
rotate([0, 90, 0])
cylinder(r = hinge_r, h = hinge_h, center = true);
}
translate([hinge_h / 2, 0, z])
rotate([90, 0, 90])
nut_trap(hinge_screw, screw_nut(hinge_screw), horizontal = true);
}
translate([hinge_h / 2, 0, z])
rotate([90, 0, 90])
nut_trap(hinge_screw, screw_nut(hinge_screw), horizontal = true);
}
linear_extrude(t)
difference() {
hull()
linear_extrude(t)
difference() {
hull()
camera_bracket_screw_positions(cam)
circle(washer_radius(screw_washer(bracket_screw)) + 0.5);
camera_bracket_screw_positions(cam)
circle(washer_radius(screw_washer(bracket_screw)) + 0.5);
camera_bracket_screw_positions(cam)
poly_circle(screw_clearance_radius(bracket_screw));
}
poly_circle(screw_clearance_radius(bracket_screw));
}
}
}
module camera_assembly(cam, angle = 0) //! Camera case assembly

View File

@@ -27,7 +27,6 @@ include <../utils/core/core.scad>
function carrier_height() = 3; //! Height of PCB carrier
module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
stl("ESP12F_carrier");
pins = 8;
pitch1 = 2;
pitch2 = 2.54;
@@ -43,29 +42,29 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
width1 = wpitch1 + hole + squeezed_wall * 2;
width2 = wpitch2 + hole2 + squeezed_wall * 2;
difference() {
hull() {
translate_z(height - eps / 2)
cube([width1, length1, eps], center = true);
stl("ESP12F_carrier")
difference() {
hull() {
translate_z(height - eps / 2)
cube([width1, length1, eps], center = true);
translate_z(eps / 2)
cube([width2, length2, eps], center = true);
translate_z(eps / 2)
cube([width2, length2, eps], center = true);
}
for(side = [-1, 1])
for(i = [0 : pins - 1])
hull() {
translate([side * wpitch1 / 2, i * pitch1 - (pins - 1) * pitch1 / 2, height])
cube([hole, hole, eps], center = true);
translate([side * wpitch2 / 2, i * pitch2 - (pins - 1) * pitch2 / 2])
cube([hole2, hole2, eps], center = true);
}
}
for(side = [-1, 1])
for(i = [0 : pins - 1])
hull() {
translate([side * wpitch1 / 2, i * pitch1 - (pins - 1) * pitch1 / 2, height])
cube([hole, hole, eps], center = true);
translate([side * wpitch2 / 2, i * pitch2 - (pins - 1) * pitch2 / 2])
cube([hole2, hole2, eps], center = true);
}
}
}
module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two required
stl("TP4056_carrier");
pitch = 2.54;
outer_pitch = 13.9;
inner_pitch = 7.54;
@@ -78,30 +77,30 @@ module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two re
width = hole + squeezed_wall * 2;
spacing = inch(0.9);
difference() {
hull() {
translate_z(height - eps / 2)
cube([width, length1, eps], center = true);
stl("TP4056_carrier")
difference() {
hull() {
translate_z(height - eps / 2)
cube([width, length1, eps], center = true);
translate_z(eps / 2)
cube([width, length2, eps], center = true);
translate_z(eps / 2)
cube([width, length2, eps], center = true);
}
for(i = [0 : pins - 1])
let(x = [-outer_pitch / 2, - inner_pitch / 2, 0, 0, inner_pitch / 2, outer_pitch / 2][i])
if(x)
hull() {
translate([0, x, height])
cube([hole, hole, eps], center = true);
translate([0, i * pitch - (pins - 1) * pitch / 2])
cube([hole, hole, eps], center = true);
}
}
for(i = [0 : pins - 1])
let(x = [-outer_pitch / 2, - inner_pitch / 2, 0, 0, inner_pitch / 2, outer_pitch / 2][i])
if(x)
hull() {
translate([0, x, height])
cube([hole, hole, eps], center = true);
translate([0, i * pitch - (pins - 1) * pitch / 2])
cube([hole, hole, eps], center = true);
}
}
}
module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two required
stl("MT3608_carrier");
pcb_width = 17;
w_pitch_top = 6.81;
w_pitch_bot = inch(0.3);
@@ -113,21 +112,22 @@ module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two re
width = hole + 2 * wall;
offset = (l_pitch_top - l_pitch_bot) / 2;
difference() {
hull() {
translate([offset, 0, height - eps / 2])
rounded_rectangle([width, pcb_width - 2, eps], 1);
translate_z(eps / 2)
rounded_rectangle([width, pcb_width - 2, eps], 1);
}
for(side = [-1, 1])
stl("MT3608_carrier")
difference() {
hull() {
translate([offset, side * w_pitch_top / 2, height])
cube([hole, hole, eps], center = true);
translate([offset, 0, height - eps / 2])
rounded_rectangle([width, pcb_width - 2, eps], 1);
translate([0, side * w_pitch_bot / 2])
cube([hole, hole, eps], center = true);
translate_z(eps / 2)
rounded_rectangle([width, pcb_width - 2, eps], 1);
}
}
for(side = [-1, 1])
hull() {
translate([offset, side * w_pitch_top / 2, height])
cube([hole, hole, eps], center = true);
translate([0, side * w_pitch_bot / 2])
cube([hole, hole, eps], center = true);
}
}
}

View File

@@ -72,8 +72,6 @@ module corner_block_holes(screw = def_screw) //! Place children at all the holes
children();
module corner_block(screw = def_screw, name = false) { //! Generate the STL for a printed corner block
stl(name ? name : str("corner_block", "_M", screw_radius(screw) * 20));
r = 1;
cb_width = corner_block_width(screw);
cb_height = cb_width;
@@ -81,39 +79,41 @@ module corner_block(screw = def_screw, name = false) { //! Generate the STL for
insert = screw_insert(screw);
corner_rad = insert_outer_d(insert) / 2 + wall;
offset = corner_block_hole_offset(screw);
difference() {
hull() {
translate([r, r])
rounded_cylinder(r = r, h = cb_height, r2 = r);
translate([r, cb_depth - r])
cylinder(r = r, h = cb_height - corner_rad);
stl(name ? name : str("corner_block", "_M", screw_radius(screw) * 20))
difference() {
hull() {
translate([r, r])
rounded_cylinder(r = r, h = cb_height, r2 = r);
translate([cb_width - r, r])
cylinder(r = r, h = cb_height - corner_rad);
translate([r, cb_depth - r])
cylinder(r = r, h = cb_height - corner_rad);
translate([offset, offset, offset])
sphere(corner_rad);
translate([cb_width - r, r])
cylinder(r = r, h = cb_height - corner_rad);
translate([offset, offset])
cylinder(r = corner_rad, h = offset);
translate([offset, offset, offset])
sphere(corner_rad);
translate([offset, r, offset])
rotate([-90, 0, 180])
rounded_cylinder(r = corner_rad, h = r, r2 = r);
translate([offset, offset])
cylinder(r = corner_rad, h = offset);
translate([r, offset, offset])
rotate([0, 90, 180])
rounded_cylinder(r = corner_rad, h = r, r2 = r);
translate([offset, r, offset])
rotate([-90, 0, 180])
rounded_cylinder(r = corner_rad, h = r, r2 = r);
translate([r, offset, offset])
rotate([0, 90, 180])
rounded_cylinder(r = corner_rad, h = r, r2 = r);
}
corner_block_v_hole(screw)
insert_hole(insert, overshoot);
corner_block_h_holes(screw)
insert_hole(insert, overshoot, true);
children();
}
corner_block_v_hole(screw)
insert_hole(insert, overshoot);
corner_block_h_holes(screw)
insert_hole(insert, overshoot, true);
children();
}
}
module corner_block_assembly(screw = def_screw, name = false) //! The printed block with inserts

View File

@@ -54,44 +54,44 @@ module door_hinge_hole_positions(dir = 0) { //! Position chidren
}
module door_hinge(door_thickness) { //! Generates STL for the moving part of the hinge
stl(str("door_hinge_", door_thickness));
hole_pitch = width - 10;
union() {
rotate([90, 0, 0])
linear_extrude(width, center = true)
stl(str("door_hinge_", door_thickness))
union() {
rotate([90, 0, 0])
linear_extrude(width, center = true)
difference() {
hull() {
translate([dia / 2, thickness + door_thickness / 2])
intersection() {
rotate(180)
teardrop(r = dia / 2, h = 0, truncate = false);
square([dia + 1, 2 * thickness + door_thickness], center = true);
}
square([1, thickness + door_thickness]);
}
translate([dia / 2, thickness + door_thickness / 2])
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
}
linear_extrude(thickness)
difference() {
hull() {
translate([dia / 2, thickness + door_thickness / 2])
intersection() {
rotate(180)
teardrop(r = dia / 2, h = 0, truncate = false);
translate([0, -width / 2])
square([1, width]);
square([dia + 1, 2 * thickness + door_thickness], center = true);
}
square([1, thickness + door_thickness]);
for(side = [-1, 1])
translate([-width + rad, side * (width / 2 - rad)])
circle4n(rad);
}
translate([dia / 2, thickness + door_thickness / 2])
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
rotate(180)
vflip()
door_hinge_hole_positions()
poly_circle(screw_clearance_radius(screw));
}
linear_extrude(thickness)
difference() {
hull() {
translate([0, -width / 2])
square([1, width]);
for(side = [-1, 1])
translate([-width + rad, side * (width / 2 - rad)])
circle4n(rad);
}
rotate(180)
vflip()
door_hinge_hole_positions()
poly_circle(screw_clearance_radius(screw));
}
}
}
}
module door_hinge_6_stl() door_hinge(6);

View File

@@ -38,23 +38,23 @@ function door_latch_offset() = width / 2 + 1; //! Offset of the axle from the do
nut_trap_depth = round_to_layer(screw_head_height(screw)) + 4 * layer_height;
module door_latch_stl() { //! Generates the STL for the printed part
stl("door_latch");
ridge = 4;
difference() {
union() {
hull() {
rounded_rectangle([length, width, thickness - tan(30) * (width - ridge) / 2], rad, center = false);
translate_z(thickness / 2)
cube([length, ridge, thickness], center = true);
stl("door_latch")
difference() {
union() {
hull() {
rounded_rectangle([length, width, thickness - tan(30) * (width - ridge) / 2], rad, center = false);
translate_z(thickness / 2)
cube([length, ridge, thickness], center = true);
}
cylinder(d = width, h = height);
}
cylinder(d = width, h = height);
hanging_hole(nut_trap_depth, screw_clearance_radius(screw))
circle(r = nut_trap_radius(screw_nut(screw)), $fn = 6);
}
hanging_hole(nut_trap_depth, screw_clearance_radius(screw))
circle(r = nut_trap_radius(screw_nut(screw)), $fn = 6);
}
}
module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specified sheet thickess

View File

@@ -71,38 +71,38 @@ module fixing_block_h_hole_2D(screw = def_screw) //! Position 2D child on the ho
children();
module fixing_block(screw = def_screw) { //! Generate the STL
stl(str("fixing_block_M", screw_radius(screw) * 20));
r = 1;
r = 1;
insert = screw_insert(screw);
corner_rad = insert_outer_d(insert) / 2 + wall;
fb_width = fixing_block_width(screw);
fb_height = fixing_block_height(screw);
fb_depth = fixing_block_depth(screw);
difference() {
union() {
linear_extrude(fb_height, convexity = 5)
difference() {
hull() {
for(side = [-1, 1]) {
translate([side * (fb_width / 2 - corner_rad), fb_depth - corner_rad])
circle4n(corner_rad);
stl(str("fixing_block_M", screw_radius(screw) * 20))
difference() {
union() {
linear_extrude(fb_height, convexity = 5)
difference() {
hull() {
for(side = [-1, 1]) {
translate([side * (fb_width / 2 - corner_rad), fb_depth - corner_rad])
circle4n(corner_rad);
translate([side * (fb_width / 2 - r), r])
circle4n(r);
translate([side * (fb_width / 2 - r), r])
circle4n(r);
}
}
fixing_block_v_holes(screw)
poly_circle(screw_clearance_radius(screw));
}
fixing_block_v_holes(screw)
poly_circle(screw_clearance_radius(screw));
}
}
translate_z(fb_height)
fixing_block_v_holes(screw)
insert_hole(insert);
}
translate_z(fb_height)
fixing_block_v_holes(screw)
insert_hole(insert);
fixing_block_h_hole(screw)
insert_hole(insert, 10, true);
}
fixing_block_h_hole(screw)
insert_hole(insert, 10, true);
}
}
module fixing_block_assembly(screw = def_screw) pose([55, 180, 25], [0, 4.8, 4.8]) //! Printed part with the inserts inserted

View File

@@ -65,8 +65,6 @@ module hinge_screw_positions(type) { //! Place children at the screw positions
}
module hinge_male(type, female = false) { //! The half with the stationary pin
stl(str("hinge_", female ? "fe": "", "male_", type[0]));
r = hinge_radius(type);
w = hinge_width(type);
t = hinge_thickness(type);
@@ -85,37 +83,40 @@ module hinge_male(type, female = false) { //! The half with the stationary
teardrop_r = kr / cos(22.5); // The corner on the teardrop
inset = sqrt(sqr(teardrop_r + gap) - sqr(kr - t)) - kr;
linear_extrude(t)
difference() {
hull() {
for(side = [-1, 1])
translate([side * (w / 2 - r), hinge_depth(type) - r])
circle4n(r);
stl(str("hinge_", female ? "fe": "", "male_", type[0]))
union() {
linear_extrude(t)
difference() {
hull() {
for(side = [-1, 1])
translate([side * (w / 2 - r), hinge_depth(type) - r])
circle4n(r);
translate([-w / 2, inset])
square([w, eps]);
}
hinge_screw_positions(type)
poly_circle(screw_clearance_radius(hinge_screw(type)));
translate([-w / 2, inset])
square([w, eps]);
}
hinge_screw_positions(type)
poly_circle(screw_clearance_radius(hinge_screw(type)));
}
pitch = mw + gap + fw + gap;
dir = female ? -1 : 1;
translate([0, -kr, kr])
rotate([90, 0, -90])
for(z = [0 : (female ? fn : mn) - 1])
translate_z(-dir * w / 2 + z * dir * pitch + (female ? -fw - mw - gap : 0))
linear_extrude(female ? fw : mw)
difference() {
hull() {
rotate(180)
teardrop(r = kr, h = 0);
translate([-kr - 1, -kr])
square(1);
}
teardrop_plus(r = pr + (female ? gap : 0), h = 0);
}
}
pitch = mw + gap + fw + gap;
dir = female ? -1 : 1;
translate([0, -kr, kr])
rotate([90, 0, -90])
for(z = [0 : (female ? fn : mn) - 1])
translate_z(-dir * w / 2 + z * dir * pitch + (female ? -fw - mw - gap : 0))
linear_extrude(female ? fw : mw)
difference() {
hull() {
rotate(180)
teardrop(r = kr, h = 0);
translate([-kr - 1, -kr])
square(1);
}
teardrop_plus(r = pr + (female ? gap : 0), h = 0);
}
}
module hinge_female(type) hinge_male(type, true);

View File

@@ -39,7 +39,6 @@ function foot_screw(type = foot) = type[4]; //! Screw type
function foot_slant(type = foot) = type[5]; //! Taper angle
module foot(type = foot) { //! Generate STL
stl("foot");
h = foot_height(type);
t = foot_thickness(type);
r1 = washer_radius(screw_washer(foot_screw(type)));
@@ -47,24 +46,25 @@ module foot(type = foot) { //! Generate STL
r2 = r3 - h * tan(foot_slant(type));
r = foot_rad(type);
union() {
rotate_extrude(convexity = 3) {
hull() {
translate([r1, 0])
square([r3 - r1, eps]);
stl("foot")
union() {
rotate_extrude(convexity = 3) {
hull() {
translate([r1, 0])
square([r3 - r1, eps]);
for(x = [r1 + r, r2 - r])
translate([x, h - r])
circle4n(r);
for(x = [r1 + r, r2 - r])
translate([x, h - r])
circle4n(r);
}
}
linear_extrude(t)
difference() {
circle(r1 + eps);
poly_circle( screw_clearance_radius(foot_screw(type)));
}
}
linear_extrude(t)
difference() {
circle(r1 + eps);
poly_circle( screw_clearance_radius(foot_screw(type)));
}
}
}
module foot_assembly(t = 0, type = foot, flip = false) { //! Assembly with fasteners in place for specified sheet thickness
@@ -93,7 +93,6 @@ module foot_assembly(t = 0, type = foot, flip = false) { //! Assembly with faste
}
module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
stl("insert_foot");
h = foot_height(type);
r3 = foot_diameter(type) / 2;
r2 = r3 - h * tan(foot_slant(type));
@@ -103,30 +102,31 @@ module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
h2 = insert_hole_length(insert);
r4 = insert_hole_radius(insert);
r5 = r4 + 1;
union() {
rotate_extrude() {
union() {
hull() {
translate([r5, 0]) {
square([r3 - r5, eps]);
square([eps, h]);
}
stl("insert_foot")
union() {
rotate_extrude() {
union() {
hull() {
translate([r5, 0]) {
square([r3 - r5, eps]);
square([eps, h]);
}
translate([r2 - r, h - r])
circle4n(r);
translate([r2 - r, h - r])
circle4n(r);
}
}
}
linear_extrude(h2 + eps)
difference() {
circle(r5 + eps);
poly_circle(r4);
}
translate_z(h2)
cylinder(r = r5 + eps, h = h - h2);
}
linear_extrude(h2 + eps)
difference() {
circle(r5 + eps);
poly_circle(r4);
}
translate_z(h2)
cylinder(r = r5 + eps, h = h - h2);
}
}
//
//! Place the insert in the bottom of the foot and push home with a soldering iron with a conical bit heated to 200&deg;C.

View File

@@ -46,8 +46,6 @@ module handle_holes(h = 100) //! Drills holes for the screws
drill(screw_clearance_radius(screw), h);
module handle_stl() { //! generate the STL
stl("handle");
module end(end)
translate([end * pitch / 2, 0])
rotate_extrude()
@@ -59,23 +57,24 @@ module handle_stl() { //! generate the STL
square([dia / 2 + 1, dia + 1]);
}
translate_z(dia / 2)
union() {
hull() {
end(-1);
stl("handle")
translate_z(dia / 2)
union() {
hull() {
end(-1);
end(1);
}
handle_screw_positions()
render() difference() {
h = height + dia / 2;
cylinder(d = dia, h = h);
translate_z(h)
insert_hole(insert, 6);
end(1);
}
}
handle_screw_positions()
render() difference() {
h = height + dia / 2;
cylinder(d = dia, h = h);
translate_z(h)
insert_hole(insert, 6);
}
}
}
//
//! Place inserts in the bottom of the posts and push them home with a soldering iron with a conical bit heated to 200&deg;C.

View File

@@ -66,35 +66,35 @@ module pcb_mount_washer_stl() //! A plastic washer to clamp a PCB
pcb_mount_ring();
module pcb_mount(pcb, height = 5, washers = true) { //! Make the STL of a pcb mount for the specified PCB.
stl(str("pcb_mount_", pcb[0], "_", height));
y_pitch = pcb_width(pcb) > 4 * pillar_r + 4 ? pillar_r + 1
: pcb_width(pcb) / 2 + frame_w + 1 + pillar_r;
if(washers)
for(x = [-1, 1], y = [-1, 1])
translate([x * (pillar_r + 1), y * y_pitch, 0])
pcb_mount_washer_stl();
stl(str("pcb_mount_", pcb[0], "_", height)) union() {
if(washers)
for(x = [-1, 1], y = [-1, 1])
translate([x * (pillar_r + 1), y * y_pitch, 0])
pcb_mount_washer_stl();
for(x = [-1, 1])
translate([x * pillar_x_pitch(pcb) / 2, 0, frame_t / 2])
cube([frame_w, pillar_y_pitch(pcb) - 2 * wall, frame_t], center = true);
for(x = [-1, 1])
translate([x * pillar_x_pitch(pcb) / 2, 0, frame_t / 2])
cube([frame_w, pillar_y_pitch(pcb) - 2 * wall, frame_t], center = true);
for(y = [-1, 1])
translate([0, y * pillar_y_pitch(pcb) / 2, frame_t / 2])
cube([pillar_x_pitch(pcb) - 2 * wall, frame_w, frame_t], center = true);
for(y = [-1, 1])
translate([0, y * pillar_y_pitch(pcb) / 2, frame_t / 2])
cube([pillar_x_pitch(pcb) - 2 * wall, frame_w, frame_t], center = true);
pcb_mount_screw_positions(pcb)
linear_extrude(height)
pcb_mount_ring();
linear_extrude(height + pcb_thickness(pcb) - layer_height)
difference() {
pcb_mount_screw_positions(pcb)
pcb_mount_screw_positions(pcb)
linear_extrude(height)
pcb_mount_ring();
square([pcb_length(pcb) + 2 * clearance, pcb_width(pcb) + 2 * clearance], center = true);
}
linear_extrude(height + pcb_thickness(pcb) - layer_height)
difference() {
pcb_mount_screw_positions(pcb)
pcb_mount_ring();
square([pcb_length(pcb) + 2 * clearance, pcb_width(pcb) + 2 * clearance], center = true);
}
}
}
module pcb_mount_assembly(pcb, thickness, height = 5) { //! A PCB mount assembly with fasteners

View File

@@ -129,28 +129,27 @@ module pbox_outer_shape(type) //! 2D outer shape of the box
offset(pbox_wall(type) / 2) pbox_mid_shape(type);
module pbox_base(type) { //! Generate the STL for the base
stl(str(pbox_name(type),"_base"));
t = pbox_base(type);
difference() {
union() {
linear_extrude(t)
offset(base_outset - 0.2)
pbox_inner_shape(type);
if($children > 0)
children(0);
stl(str(pbox_name(type),"_base"))
difference() {
union() {
linear_extrude(t)
offset(base_outset - 0.2)
pbox_inner_shape(type);
if($children > 0)
children(0);
}
pbox_screw_positions(type)
poly_cylinder(r = screw_clearance_radius(pbox_screw(type)), h = 2 * t + eps, center = true);
if($children > 1)
children(1);
}
pbox_screw_positions(type)
poly_cylinder(r = screw_clearance_radius(pbox_screw(type)), h = 2 * t + eps, center = true);
if($children > 1)
children(1);
}
}
module pbox(type) { //! Generate the STL for the main case
stl(pbox_name(type));
height = pbox_height(type);
total_height = pbox_total_height(type);
top_thickness = pbox_top(type);
@@ -159,60 +158,61 @@ module pbox(type) { //! Generate the STL for the main case
ledge_inset = base_outset - base_overlap;
ledge_h = pbox_base(type) ? (ledge_outset - ledge_inset) * 2 : 0;
difference() {
union() {
linear_extrude(total_height)
pbox_outer_shape(type);
if($children > 2)
children(2);
}
stl(pbox_name(type))
difference() {
translate_z(top_thickness)
union() {
linear_extrude(height + eps)
offset(-wall / 2) pbox_mid_shape(type);
union() {
linear_extrude(total_height)
pbox_outer_shape(type);
translate_z(height) // Recess for the base
linear_extrude(total_height - height)
offset(base_outset)
pbox_inner_shape(type);
}
// Ledge to support the lid
if(ledge_h)
translate_z(top_thickness + height - ledge_h)
difference() {
rounded_rectangle([pbox_width(type) + 2 * outset, pbox_depth(type) + 2 * outset, ledge_h], 1, center = false);
if($children > 2)
children(2);
}
difference() {
translate_z(top_thickness)
union() {
linear_extrude(height + eps)
offset(-wall / 2) pbox_mid_shape(type);
hull() {
linear_extrude(ledge_h + eps)
offset(ledge_inset)
translate_z(height) // Recess for the base
linear_extrude(total_height - height)
offset(base_outset)
pbox_inner_shape(type);
linear_extrude(eps)
offset(ledge_outset)
pbox_inner_shape(type);
}
pbox_screw_positions(type)
insert_hole(pbox_insert(type));
}
// Ledge to support the lid
if(ledge_h)
translate_z(top_thickness + height - ledge_h)
difference() {
rounded_rectangle([pbox_width(type) + 2 * outset, pbox_depth(type) + 2 * outset, ledge_h], 1, center = false);
// Corner lugs for inserts
outset = wall + pbox_ridges(type).y;
or = pbox_radius(type) + outset;
inset = pbox_screw_inset(type) + outset;
br = insert_boss_radius(pbox_insert(type), wall);
ext = sqrt(2) * inset - or * (sqrt(2) - 1) - br;
translate_z(height + top_thickness)
pbox_screw_positions(type)
insert_lug(pbox_insert(type), wall, counter_bore = 0, extension = ext, corner_r = or);
hull() {
linear_extrude(ledge_h + eps)
offset(ledge_inset)
pbox_inner_shape(type);
if($children > 0)
children(0);
linear_extrude(eps)
offset(ledge_outset)
pbox_inner_shape(type);
}
pbox_screw_positions(type)
insert_hole(pbox_insert(type));
}
// Corner lugs for inserts
outset = wall + pbox_ridges(type).y;
or = pbox_radius(type) + outset;
inset = pbox_screw_inset(type) + outset;
br = insert_boss_radius(pbox_insert(type), wall);
ext = sqrt(2) * inset - or * (sqrt(2) - 1) - br;
translate_z(height + top_thickness)
pbox_screw_positions(type)
insert_lug(pbox_insert(type), wall, counter_bore = 0, extension = ext, corner_r = or);
if($children > 0)
children(0);
}
if($children > 1)
children(1);
}
if($children > 1)
children(1);
}
}
module pbox_inserts(type) //! Place the inserts for the base screws

View File

@@ -93,7 +93,6 @@ module printed_pulley(type) { //! Draw a printable pulley
or = pulley_od(type) / 2;
screw_z = pulley_screw_z(type);
stl(str("printed_pulley_", type[0]));
module core() {
translate_z(pulley_hub_length(type) + ft)
@@ -129,54 +128,55 @@ module printed_pulley(type) { //! Draw a printable pulley
circle(d = pulley_bore(type));
}
translate_z(printed_pulley_inverted(type) ? - hl : 0) {
// hub
if(hl)
translate_z(printed_pulley_inverted(type) ? hl + w + 2 * ft : 0)
if(screw_z && screw_z < hl)
render()
difference() {
hub();
stl(str("printed_pulley_", type[0]))
translate_z(printed_pulley_inverted(type) ? - hl : 0) {
// hub
if(hl)
translate_z(printed_pulley_inverted(type) ? hl + w + 2 * ft : 0)
if(screw_z && screw_z < hl)
render()
difference() {
hub();
screw_holes();
}
else
hub();
// bottom flange
translate_z(hl)
linear_extrude(ft)
difference() {
circle(d = pulley_flange_dia(type));
circle(d = pulley_bore(type));
}
// top flange
translate_z(hl + ft + w) {
// inner part, supported by core
linear_extrude(ft)
difference() {
circle(r = or);
circle(d = pulley_bore(type));
}
// outer part at 45 degrees for printing
rotate_extrude()
translate([or - eps, ft])
vflip()
right_triangle(ft, ft);
}
if(screw_z && screw_z > hl)
render()
difference() { // T5 pulleys have screws through the teeth
core();
translate_z(printed_pulley_inverted(type) ? pulley_height(type) + hl - 2 * screw_z : 0)
screw_holes();
}
}
else
hub();
// bottom flange
translate_z(hl)
linear_extrude(ft)
difference() {
circle(d = pulley_flange_dia(type));
circle(d = pulley_bore(type));
}
// top flange
translate_z(hl + ft + w) {
// inner part, supported by core
linear_extrude(ft)
difference() {
circle(r = or);
circle(d = pulley_bore(type));
}
// outer part at 45 degrees for printing
rotate_extrude()
translate([or - eps, ft])
vflip()
right_triangle(ft, ft);
}
if(screw_z && screw_z > hl)
render()
difference() { // T5 pulleys have screws through the teeth
core();
translate_z(printed_pulley_inverted(type) ? pulley_height(type) + hl - 2 * screw_z : 0)
screw_holes();
}
else
core();
}
}
}
module printed_pulley_assembly(type, colour = pp1_colour) //! Draw a printed pulley with its grub screws in place

View File

@@ -79,8 +79,6 @@ module psu_shroud_holes(type, cable_d, cables = 1) {
}
module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file for a specified ssr and cable
stl(str("psu_shroud_", name));
extent = psu_shroud_extent(type);
depth = psu_shroud_depth(type);
width = psu_shroud_width(type);
@@ -109,38 +107,40 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
}
}
// base and sides
translate([centre_x, -centre_y]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
stl(str("psu_shroud_", name)) {
// base and sides
translate([centre_x, -centre_y]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
linear_extrude(height)
difference() {
linear_extrude(height)
difference() {
shape();
translate([depth / 2, width / 2 - 5])
square([2 * (depth - extent + terminal_clearance), 10], center = true);
}
linear_extrude(height - terminal_block_height(tb) - psu_terminal_block_z(type) - terminal_clearance)
shape();
translate([depth / 2, width / 2 - 5])
square([2 * (depth - extent + terminal_clearance), 10], center = true);
}
linear_extrude(height - terminal_block_height(tb) - psu_terminal_block_z(type) - terminal_clearance)
shape();
}
// cable slots
for(i = [0 : 1 : cables - 1])
translate([centre_x - depth / 2 + wall / 2, -centre_y + (i - cables / 2 + 0.5) * psu_shroud_cable_pitch(cable_d), height / 2])
rotate([90, 0, 90])
linear_extrude(wall, center = true)
difference() {
square([cable_d + eps, height], center = true);
// cable slots
for(i = [0 : 1 : cables - 1])
translate([centre_x - depth / 2 + wall / 2, -centre_y + (i - cables / 2 + 0.5) * psu_shroud_cable_pitch(cable_d), height / 2])
rotate([90, 0, 90])
linear_extrude(wall, center = true)
difference() {
square([cable_d + eps, height], center = true);
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
// insert lugs
mirror([0, 1, 0])
psu_shroud_hole_positions(type)
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
// insert lugs
mirror([0, 1, 0])
psu_shroud_hole_positions(type)
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
}
module psu_shroud_assembly(type, cable_d, name, cables = 1) //! The printed parts with inserts fitted
assembly(str("PSU_shroud_", name), ngb = true) {

View File

@@ -47,7 +47,6 @@ module ribbon_clamp_holes(ways, h = 20, screw = screw) //! Drill screw holes
module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of ways
screw_d = screw_radius(screw) * 2;
stl(str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : ""));
pitch = ribbon_clamp_hole_pitch(ways, screw);
d = ribbon_clamp_width(screw);
@@ -55,30 +54,31 @@ module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of
t = round_to_layer(ribbon_clamp_slot_depth() + wall);
insert = screw_insert(screw);
difference() {
union() {
hull() {
translate_z(h - t / 2)
cube([ribbon_clamp_hole_pitch(ways, screw), d, t], center = true);
stl(str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : ""))
difference() {
union() {
hull() {
translate_z(h - t / 2)
cube([ribbon_clamp_hole_pitch(ways, screw), d, t], center = true);
translate_z(1)
cube([pitch, max(wall, d - 2 * (h - t)), 2], center = true);
translate_z(1)
cube([pitch, max(wall, d - 2 * (h - t)), 2], center = true);
}
ribbon_clamp_hole_positions(ways, screw, -1)
cylinder(d = d, h = h);
ribbon_clamp_hole_positions(ways, screw, 1)
cylinder(d = d, h = h);
}
ribbon_clamp_hole_positions(ways, screw, -1)
cylinder(d = d, h = h);
ribbon_clamp_hole_positions(ways, screw, 1)
cylinder(d = d, h = h);
}
translate_z(h)
cube([ribbon_clamp_slot(ways), d + 1, ribbon_clamp_slot_depth() * 2], center = true);
ribbon_clamp_hole_positions(ways, screw)
translate_z(h)
rotate(22.5)
insert_hole(insert, ribbon_clamp_screw_depth(screw) - insert_length(insert));
}
cube([ribbon_clamp_slot(ways), d + 1, ribbon_clamp_slot_depth() * 2], center = true);
ribbon_clamp_hole_positions(ways, screw)
translate_z(h)
rotate(22.5)
insert_hole(insert, ribbon_clamp_screw_depth(screw) - insert_length(insert));
}
}
module ribbon_clamp_assembly(ways, screw = screw) pose([55, 180, 25]) //! Printed part with inserts in place

View File

@@ -34,27 +34,26 @@ knob_height = knob_stem_h + knob_thickness;
function knob_height() = knob_height;
module screw_knob(screw) { //! Generate the STL for a knob to fit the specified hex screw
stl(str("screw_knob_M", screw_radius(screw) * 20));
knob_stem_r = nut_trap_radius(screw_nut(screw)) + knob_wall;
function wave(a) = knob_r + sin(a * knob_waves) * knob_wave;
union() {
render() difference() {
cylinder(r = knob_stem_r, h = knob_thickness + knob_stem_h);
stl(str("screw_knob_M", screw_radius(screw) * 20))
union() {
render() difference() {
cylinder(r = knob_stem_r, h = knob_thickness + knob_stem_h);
hanging_hole(knob_nut_trap_depth(screw), screw_clearance_radius(screw))
rotate(45)
circle(r = nut_trap_radius(screw_nut(screw)), $fn = 6);
}
linear_extrude(knob_thickness, convexity = 3)
difference() {
polygon(points = [for(a = [0 : 359]) [wave(a) * sin(a), wave(a) * cos(a)]]);
circle(knob_stem_r - eps);
hanging_hole(knob_nut_trap_depth(screw), screw_clearance_radius(screw))
rotate(45)
circle(r = nut_trap_radius(screw_nut(screw)), $fn = 6);
}
}
linear_extrude(knob_thickness, convexity = 3)
difference() {
polygon(points = [for(a = [0 : 359]) [wave(a) * sin(a), wave(a) * cos(a)]]);
circle(knob_stem_r - eps);
}
}
}
//! Place the screw through the printed part

View File

@@ -41,7 +41,6 @@ height = base_thickness + box_height;
function socket_box_depth() = height; //! Outside depth of the backbox
module socket_box(type) { //! Generate STL of the backbox for the specified socket
stl(str("socket_box_",type[0]));
screw = mains_socket_screw(type);
screw_clearance_radius = screw_clearance_radius(screw);
@@ -51,37 +50,38 @@ module socket_box(type) { //! Generate STL of the backbox for the specified sock
insert_boss = mains_socket_insert_boss(type);
insert_hole_radius = insert_hole_radius(insert);
difference() {
linear_extrude(height, convexity = 5)
face_plate(type);
stl(str("socket_box_",type[0]))
difference() {
translate_z(base_thickness)
linear_extrude(height, convexity = 5)
offset(-wall) offset(1) face_plate(type);
linear_extrude(height, convexity = 5)
face_plate(type);
for(side = [-1, 1])
hull()
for(x = [1, 2])
translate([side * mains_socket_pitch(type) / x, 0])
cylinder(d = insert_boss, h = 100);
}
//
// Socket holes
//
translate_z(height)
mains_socket_hole_positions(type) {
poly_cylinder(r = screw_clearance_radius, h = 2 * box_height, center = true);
difference() {
translate_z(base_thickness)
linear_extrude(height, convexity = 5)
offset(-wall) offset(1) face_plate(type);
poly_cylinder(r = insert_hole_radius, h = 2 * insert_length, center = true);
for(side = [-1, 1])
hull()
for(x = [1, 2])
translate([side * mains_socket_pitch(type) / x, 0])
cylinder(d = insert_boss, h = 100);
}
//
// Cable hole
//
translate([cable_x, cable_y(type), cable_z])
rotate([90, 0, 0])
teardrop_plus(r = cable_d / 2, h = 30);
}
//
// Socket holes
//
translate_z(height)
mains_socket_hole_positions(type) {
poly_cylinder(r = screw_clearance_radius, h = 2 * box_height, center = true);
poly_cylinder(r = insert_hole_radius, h = 2 * insert_length, center = true);
}
//
// Cable hole
//
translate([cable_x, cable_y(type), cable_z])
rotate([90, 0, 0])
teardrop_plus(r = cable_d / 2, h = 30);
}
}
module socket_box_MKLOGIC_stl() socket_box(MKLOGIC);

View File

@@ -61,49 +61,50 @@ module ssr_shroud_holes(type, cable_d) { //! Drill the screw and ziptie holes
}
module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a specified ssr and cable
stl(str("ssr_shroud_", name));
width = ssr_shroud_width(type);
depth = ssr_length(type) / 3 + ssr_shroud_extent(type, cable_d);
height = ssr_shroud_height(type);
cable_x = ssr_shroud_cable_x(type, cable_d);
center_x = -ssr_length(type) / 6 - depth / 2;
// base and sides
translate([center_x, 0]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
linear_extrude(height) difference() {
round(or = wall / 2 - eps, ir = 0) difference() {
rounded_square([depth, width], rad);
stl(str("ssr_shroud_", name)) {
// base and sides
translate([center_x, 0]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
rounded_square([depth - 2 * wall, width - 2 * wall], rad - wall);
linear_extrude(height) difference() {
round(or = wall / 2 - eps, ir = 0) difference() {
rounded_square([depth, width], rad);
translate([depth / 2, 0])
square([2 * rad, width], center = true);
rounded_square([depth - 2 * wall, width - 2 * wall], rad - wall);
translate([depth / 2, 0])
square([2 * rad, width], center = true);
}
translate([cable_x - center_x, 0])
square([cable_d, width + 1], center = true);
}
translate([cable_x - center_x, 0])
square([cable_d, width + 1], center = true);
}
}
// cable slots
for(side = [-1, 1])
translate([cable_x, side * (width / 2 - wall / 2), height / 2])
rotate([90, 0, 0])
linear_extrude(wall, center = true)
difference() {
square([cable_d + eps, height], center = true);
// cable slots
for(side = [-1, 1])
translate([cable_x, side * (width / 2 - wall / 2), height / 2])
rotate([90, 0, 0])
linear_extrude(wall, center = true)
difference() {
square([cable_d + eps, height], center = true);
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
// insert boss
ssr_shroud_hole_positions(type)
vflip()
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
// insert boss
ssr_shroud_hole_positions(type)
vflip()
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
}
module ssr_shroud_assembly(type, cable_d, name) //! The printed parts with inserts fitted

View File

@@ -75,32 +75,29 @@ module strap_holes(length, type = strap, h = 100) //! The panel cut outs
strap_boss_shape(type);
module strap(length, type = strap) { //! Generate the STL for the rubber strap
stl("strap");
len = length - 2 * (wall + clearance);
w = strap_width(type);
linear_extrude(strap_thickness(type), convexity = 3)
difference() {
rounded_square([len, w], w / 2 - eps);
stl("strap")
linear_extrude(strap_thickness(type), convexity = 3)
difference() {
rounded_square([len, w], w / 2 - eps);
for(end = [-1, 1])
translate([end * (len / 2 - strap_min_width(type) - strap_boss_r(type) - clearance), 0])
rotate(end * 90 + 90)
hull() {
offset(clearance)
strap_boss_shape(type);
translate([strap_extension(type) / 2, 0])
for(end = [-1, 1])
translate([end * (len / 2 - strap_min_width(type) - strap_boss_r(type) - clearance), 0])
rotate(end * 90 + 90)
hull() {
offset(clearance)
strap_boss_shape(type);
}
}
translate([strap_extension(type) / 2, 0])
offset(clearance)
strap_boss_shape(type);
}
}
}
module strap_end(type = strap) { //! Generate the STL for end piece
stl("strap_end");
z1 = strap_height(type) - strap_thickness(type) - clearance;
z2 = strap_height(type) + strap_key(type);
r1 = strap_boss_r(type) - 1;
@@ -121,42 +118,43 @@ module strap_end(type = strap) { //! Generate the STL for end piece
circle(r1);
}
union() {
linear_extrude(z1)
with_hole()
outer();
translate_z(z1)
linear_extrude(strap_height(type) - z1)
difference() {
stl("strap_end")
union() {
linear_extrude(z1)
with_hole()
outer();
hull() {
translate([0, -strap_width(type) / 2 - clearance])
square([strap_boss_r(type) + overlap, strap_width(type) + 2 * clearance]);
translate_z(z1)
linear_extrude(strap_height(type) - z1)
difference() {
outer();
translate([-strap_extension(type) / 2, 0])
circle(d = strap_width(type) + 2 * clearance);
hull() {
translate([0, -strap_width(type) / 2 - clearance])
square([strap_boss_r(type) + overlap, strap_width(type) + 2 * clearance]);
translate([-strap_extension(type) / 2, 0])
circle(d = strap_width(type) + 2 * clearance);
}
}
}
linear_extrude(strap_height(type) - layer_height)
with_hole()
strap_boss_shape(type);
linear_extrude(strap_height(type) - layer_height)
with_hole()
strap_boss_shape(type);
linear_extrude(z2)
with_hole()
offset(cnc_bit_r)
offset(-step - cnc_bit_r)
strap_boss_shape(type);
linear_extrude(z2)
with_hole()
offset(cnc_bit_r)
offset(-step - cnc_bit_r)
strap_boss_shape(type);
render() difference() {
cylinder(r = r1 + eps, h = z2);
render() difference() {
cylinder(r = r1 + eps, h = z2);
translate_z(z2)
insert_hole(strap_insert(type), counterbore);
translate_z(z2)
insert_hole(strap_insert(type), counterbore);
}
}
}
}
//
//! * Place the insert into the hole and push home with a soldering iron with a tapered bit heated to 200&deg;C.

View File

@@ -288,6 +288,8 @@ Models of radial blowers.
| `blower_screw_holes(type)` | List of XY coordinates of the screw holes |
| `blower_top(type)` | Thickness of the top |
| `blower_wall(type)` | Side wall thickness |
| `blower_wall_left(type)` | Left side wall thickness |
| `blower_wall_right(type)` | Right wall thickness (for square fans) |
| `blower_width(type)` | Width of enclosing rectangle |
### Functions
@@ -311,10 +313,12 @@ Models of radial blowers.
| 1 | `blower(PE4020)` | Blower Pengda Technology 4020 |
| 1 | `blower(RB5015)` | Blower Runda RB5015 |
| 4 | `screw(M2_cap_screw, 8)` | Screw M2 cap x 8mm |
| 2 | `screw(M2_cap_screw, 10)` | Screw M2 cap x 10mm |
| 3 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
| 2 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
| 1 | `blower(BL30x10)` | Square radial fan 3010 |
| 1 | `blower(BL40x10)` | Square radial fan 4010 |
| 4 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
| 6 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
| 3 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 2 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
@@ -2311,6 +2315,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ---:|:--- |:---|
| 1 | `pcb(ArduinoLeonardo)` | Arduino Leonardo |
| 1 | `pcb(ArduinoUno3)` | Arduino Uno R3 |
| 1 | `pcb(BTT_SKR_E3_TURBO)` | BigTreeTech SKR E3 Turbo |
| 1 | `pcb(BTT_SKR_MINI_E3_V2_0)` | BigTreeTech SKR Mini E3 v2.0 |
| 1 | `pcb(BTT_SKR_V1_4_TURBO)` | BigTreeTech SKR v1.4 Turbo |
| 1 | | Cat 5 patch cable 300mm |
@@ -2321,7 +2326,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `pcb(ESP-01)` | ESP-01 |
| 1 | `pcb(EnviroPlus)` | Enviro+ |
| 1 | `pcb(ExtruderPCB)` | Extruder connection PCB |
| 1 | `pcb(Keyes5p1)` | Keyes5.1 Arduino Uno expansion board |
| 1 | `pcb(Keyes5p1)` | Keyes5.1 Arduino Uno expansion board - not shown |
| 1 | `pcb(MP1584EN)` | MP1584EN 3A buck converter |
| 1 | `pcb(MT3608)` | MT3608 boost converter module |
| 1 | `pcb(Melzi)` | Melzi electronics - not shown |
@@ -2330,8 +2335,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `molex_254(2)` | Molex KK header 2 way |
| 1 | `molex_254(3)` | Molex KK header 3 way |
| 16 | `nut(M2_nut, nyloc = true)` | Nut M2 x 1.6mm nyloc |
| 34 | `nut(M2p5_nut, nyloc = true)` | Nut M2.5 x 2.2mm nyloc |
| 17 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 30 | `nut(M2p5_nut, nyloc = true)` | Nut M2.5 x 2.2mm nyloc |
| 22 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 8 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc |
| 1 | `pcb(PI_IO)` | PI_IO V2 |
| 1 | `pcb(PSU12V1A)` | PSU 12V 1A - not shown |
@@ -2351,9 +2356,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 8 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm |
| 8 | `screw(M2p5_cap_screw, 30)` | Screw M2.5 cap x 30mm |
| 12 | `screw(M2p5_pan_screw, 25)` | Screw M2.5 pan x 25mm |
| 4 | `screw(M2p5_pan_screw, 30)` | Screw M2.5 pan x 30mm |
| 4 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm |
| 4 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
| 9 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
| 9 | `screw(M3_cap_screw, 35)` | Screw M3 cap x 35mm |
| 8 | `screw(M4_cap_screw, 35)` | Screw M4 cap x 35mm |
| 1 | `pcb(TP4056)` | TP4056 Li-lon Battery charger module |
@@ -2362,8 +2366,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | | USB A to Mini B lead - not shown |
| 1 | `pcb(WD2002SJ)` | WD2002SJ Buck Boost DC-DC converter |
| 16 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
| 34 | `washer(M2p5_washer)` | Washer M2.5 x 5.9mm x 0.5mm |
| 17 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 30 | `washer(M2p5_washer)` | Washer M2.5 x 5.9mm x 0.5mm |
| 22 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 8 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
| 1 | `pcb(ZC_A0591)` | ZC-A0591 ULN2003 driver PCB |
@@ -2379,11 +2383,11 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 4 | pcb_spacer25140.stl |
| 4 | pcb_spacer25150_2.stl |
| 4 | pcb_spacer25160_2.stl |
| 4 | pcb_spacer25170_2.stl |
| 4 | pcb_spacer25180.stl |
| 4 | pcb_spacer25190.stl |
| 4 | pcb_spacer25200.stl |
| 2 | pcb_spacer2580.stl |
| 4 | pcb_spacer30180.stl |
| 4 | pcb_spacer30170.stl |
| 5 | pcb_spacer30200.stl |
| 5 | pcb_spacer30210.stl |
| 4 | pcb_spacer30220.stl |
| 4 | pcb_spacer3050.stl |
@@ -6008,6 +6012,10 @@ This is to prevent the global BOM page becoming too wide in large projects by ha
The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
it with code.
This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
[utils/core/bom.scad](utils/core/bom.scad) Implementation.
[tests/BOM.scad](tests/BOM.scad) Code for this example.
@@ -6036,7 +6044,9 @@ The resulting flat BOM is shown but heirachical BOMs are also generated for real
| `pose_vflip(exploded = undef)` | Pose an STL or assembly for rendering to png by flipping around the X axis, `exploded = true for` just the exploded view or `false` for unexploded only. |
| `stl(name)` | Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it |
| `stl_colour(colour = pp1_colour, alpha = 1)` | Colour an stl where it is placed in an assembly. `alpha` can be used to make it appear transparent. |
| `vitamin(description)` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "wigit(42): Type 42 widget" |
| `use_dxf(name)` | Import a DXF to make a build panel |
| `use_stl(name)` | Import an STL to make a build platter |
| `vitamin(description)` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "widget(42): Widget size 42" |
![bom](tests/png/bom.png)
@@ -6063,9 +6073,9 @@ The resulting flat BOM is shown but heirachical BOMs are also generated for real
### Assemblies
| Qty | Name |
| ---:|:--- |
| 1 | widget_assembly |
| 1 | widget_base_assembly |
| 1 | widget_top_assembly |
| 1 | widgit_base_assembly |
| 1 | wigdit_assembly |
<a href="#top">Top</a>

View File

@@ -72,7 +72,9 @@ def plateup(target, part_type, usage = None):
changed = check_deps(part_file, dname)
if changed:
print(changed)
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
target_def = ['-D$target="%s"' % target] if target else []
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
openscad.run_list(["-D$bom=1"] + target_def + cwd_def + ["-d", dname, "-o", part_file, src_file])
if part_type == 'stl':
c14n_stl.canonicalise(part_file)
log_name = 'openscad.log'

View File

@@ -215,7 +215,9 @@ def views(target, do_assemblies = None):
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
t = time.time()
openscad.run_list(options.list() + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
target_def = ['-D$target="%s"' % target] if target else []
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
openscad.run_list(options.list() + target_def + cwd_def + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
times.add_time(png_name, t)
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
update_image(tmp_name, png_name)

View File

@@ -43,31 +43,29 @@ module widget(thickness) {
}
}
module widgit_stl() {
stl("widget");
module widget_stl() {
stl("widget")
union() {
rounded_rectangle([30, 30, 3], 2);
union() {
rounded_rectangle([30, 30, 3], 2);
render() insert_boss(insert, height, 2.2);
}
render() insert_boss(insert, height, 2.2);
}
}
module widgit_dxf() {
dxf("widget");
module widget_dxf() {
dxf("widget")
difference() {
sheet_2D(sheet, 20, 20, 1);
difference() {
sheet_2D(sheet, 20, 20, 1);
drill(screw_clearance_radius(screw), 0);
}
drill(screw_clearance_radius(screw), 0);
}
}
//! * Push the insert into the base with a soldering iron heated to 200&deg;C
module widgit_base_assembly()
assembly("widgit_base") {
module widget_base_assembly()
assembly("widget_base") {
stl_colour(pp1_colour)
widgit_stl();
widget_stl();
translate_z(height)
insert(insert);
@@ -80,14 +78,14 @@ assembly("widget_top") {
widget(sheet_thickness(sheet));
render_2D_sheet(sheet) // Must be last because it is transparent
widgit_dxf();
widget_dxf();
}
//! * Screw the two assemblies together
module widgit_assembly()
assembly("wigdit") {
module widget_assembly()
assembly("widget") {
widgit_base_assembly(); // Note this is not exloded because it is sub-assembly
widget_base_assembly(); // Note this is not exloded because it is sub-assembly
translate_z(height) {
translate_z(sheet_thickness(sheet))
@@ -100,7 +98,7 @@ assembly("wigdit") {
}
module boms() {
widgit_assembly();
widget_assembly();
}
boms();

View File

@@ -22,7 +22,7 @@ use <../utils/layout.scad>
include <../vitamins/blowers.scad>
module blowers()
layout([for(b = blowers) blower_width(b)], 10, true) let(b = blowers[$i]){
layout([for(b = blowers) blower_width(b)], 5, true) let(b = blowers[$i]){
screw = blower_screw(b);
h = blower_lug(b);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

View File

@@ -30,6 +30,10 @@
//!
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
//! The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
//!
//! If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
//! it with code.
//! This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
//
function bom_mode(n = 1) = $_bom >= n && (is_undef($on_bom) || $on_bom); //! Current BOM mode, 0 = none, 1 = printed and routed parts and assemblies, 2 includes vitamins as well
function exploded() = is_undef($exploded_parent) ? $exploded : 0; //! Returns the value of `$exploded` if it is defined, else `0`
@@ -111,19 +115,47 @@ module stl_colour(colour = pp1_colour, alpha = 1) { //! Colour an stl where it i
}
module stl(name) { //! Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it
if(bom_mode()) {
if(bom_mode() && is_undef($in_stl)) {
colour = is_undef($stl_colour) ? pp1_colour : $stl_colour;
echo(str("~", name, ".stl(colour='", colour, "')"));
}
if($children)
if(is_undef($pose))
let($in_stl = true)
children();
else {
path = is_undef($target) ? "/stls/" : str("/", $target, "/stls/");
import(str($cwd, path, name, ".stl"));
}
}
module dxf(name) { //! Name a dxf that will appear on the BOM, there needs to a module named `<name>_dxf` to make it
if(bom_mode()) {
if(bom_mode() && is_undef($in_dxf)) {
if(is_undef($dxf_colour))
echo(str("~", name, ".dxf"));
else
echo(str("~", name, ".dxf(colour='", $dxf_colour, "')"));
}
if($children)
if(is_undef($pose))
let($in_dfx = true)
children();
else {
path = is_undef($target) ? "/dxfs/" : str("/", $target, "/dxfs/");
import(str($cwd, path, name, ".dxf"));
}
}
module use_stl(name) { //! Import an STL to make a build platter
stl(name);
path = is_undef($target) ? "/stls/" : str("/", $target, "/stls/");
import(str($cwd, path, name, ".stl"));
}
module use_dxf(name) { //! Import a DXF to make a build panel
dxf(name);
path = is_undef($target) ? "/dxfs/" : str("/", $target, "/dxfs/");
import(str($cwd, path, name, ".dxf"));
}
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string
@@ -133,7 +165,7 @@ function arg(value, default, name = "") = //! Create string for arg if not def
: name ? str(", ", name, " = ", value_string(value))
: str(", ", value_string(value));
module vitamin(description) { //! Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "wigit(42): Type 42 widget"
module vitamin(description) { //! Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "widget(42): Widget size 42"
if(bom_mode(2))
echo(str("~", description, !is_undef($hidden) ? " - not shown" : ""));
}

View File

@@ -25,15 +25,3 @@ include <../../global_defs.scad>
// Global functions and modules
//
use <global.scad>
module use_stl(name) { //! Import an STL to make a build platter
stl(name);
path = is_undef($target) ? "../stls/" : str("../", $target, "/stls/");
import(str(path, name, ".stl"));
}
module use_dxf(name) { //! Import a DXF to make a build panel
dxf(name);
path = is_undef($target) ? "../dxfs/" : str("../", $target, "/dxfs/");
import(str(path, name, ".dxf"));
}

View File

@@ -40,8 +40,10 @@ function blower_base(type) = type[13]; //! Thickness of the base
function blower_top(type) = type[14]; //! Thickness of the top
function blower_wall(type) = type[15]; //! Side wall thickness
function blower_lug(type) = type[16]; //! Height of the lugs
function blower_wall_left(type) = type[15]; //! Left side wall thickness
function blower_wall_right(type) = type[17]; //! Right wall thickness (for square fans)
function blower_casing_is_square(type) = len(blower_screw_holes(type)) > 3; //! True for square radial fans, false for spiral shape radial blowers
function blower_casing_is_square(type) = blower_depth(type) < 15; //! True for square radial fans, false for spiral shape radial blowers
function blower_exit_offset(type) = blower_casing_is_square(type) ? blower_length(type) / 2 : blower_exit(type) / 2; //! Offset of exit's centre from the edge
fan_colour = grey(20);
@@ -74,41 +76,54 @@ module blower_fan(type, casing_is_square) {
module blower_square(type) { //! Draw a square blower
width = blower_width(type);
depth = blower_depth(type);
wall = blower_wall(type);
wall_left = blower_wall_left(type);
wall_right = blower_wall_right(type);
hole_count = len(blower_screw_holes(type));
hole_pitch = (blower_screw_holes(type)[1].x - blower_screw_holes(type)[0].x) / 2;
corner_radius = width / 2 - hole_pitch;
corner_inset = (width - blower_exit(type)) / 2;
corner_inset = (width - blower_exit(type) - wall_left - wall_right) / (hole_count == 2 ? 1 : 2);
module inset_corners()
translate([width / 2, width / 2])
for(i = hole_count == 2 ? [1, 3] : [0 : 3])
rotate(i * 90)
translate([-width / 2 - eps, -width/ 2 - eps])
quadrant(corner_inset, corner_inset - corner_radius);
module square_inset_corners(remove_center = false)
difference() {
//overall outside
square([width, width], center = false);
rounded_square([width, width], corner_radius, center = false);
if (remove_center) {
// cut out the inside, leaving the corners
translate([corner_inset + wall, -eps])
square([width - 2 * (wall + corner_inset), width - wall + eps], center = false);
translate([wall, corner_inset + wall])
square([width - 2 * wall, width - 2 * (wall + corner_inset)], center = false);
translate([hole_count == 2 ? wall_left : corner_inset + wall_left, -eps])
square([blower_exit(type), width / 2], center = false);
translate(blower_axis(type))
circle(d = blower_bore(type) + 1);
} else {
// cut out the bore for the fan
translate(blower_axis(type))
circle(d = blower_bore(type));
}
// corner inset
translate([width / 2, width / 2])
for(i = [0 : 3])
rotate(i * 90)
translate([-width / 2 - eps, -width/ 2 - eps])
quadrant(corner_inset, corner_inset - corner_radius);
inset_corners();
}
base_height = blower_base(type);
linear_extrude(base_height)
difference () {
rounded_square([width, width], corner_radius, center = false);
blower_hole_positions(type)
circle(d = blower_screw_hole(type));
}
// add the lugs which may be higher than the base
linear_extrude(blower_lug(type))
difference () {
intersection() {
rounded_square([width, width], corner_radius, center = false);
inset_corners();
}
blower_hole_positions(type)
circle(d = blower_screw_hole(type));
}

View File

@@ -24,8 +24,9 @@
// h h s t t
RB5015 = ["RB5015", "Blower Runda RB5015", 51.3, 51, 15, 31.5, M4_cap_screw, 26, [27.3, 25.4], 4.5, [[4.3, 45.4], [47.3,7.4]], 20, 14, 1.5, 1.3, 1.2, 15];
PE4020 = ["PE4020", "Blower Pengda Technology 4020", 40, 40, 20, 27.5, M3_cap_screw, 22, [21.5, 20 ], 3.2, [[37,3],[3,37],[37,37]], 29.3, 17, 1.7, 1.2, 1.3, 13];
BL40x10 =["BL40x10","Square radial fan 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 30 , 9.5, 1.5, 1.5, 1.1, 1.5];
BL30x10 =["BL30x10","Square radial fan 3010", 30, 30,10.1,25, M2_cap_screw, 16, [16, 15 ], 2.4, [[3,27],[27,3]], 21.2, 9.5, 1.1, 1.2, 2.5, 2.8, 0.9];
BL40x10 =["BL40x10","Square radial fan 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 27.8, 9.5, 1.5, 1.5, 1.1, 1.5, 1.1];
blowers = [BL40x10, PE4020, RB5015];
blowers = [BL30x10, BL40x10, PE4020, RB5015];
use <blower.scad>

View File

@@ -292,6 +292,99 @@ BTT_SKR_MINI_E3_V2_0 = [
[] // accessories
];
BTT_SKR_E3_TURBO = [
"BTT_SKR_E3_TURBO", "BigTreeTech SKR E3 Turbo",
102, 90.25, 1.6, // size
1, // corner radius
3.5, // mounting hole diameter
5, // pad around mounting hole
grey(30), // color
false, // true if parts should be separate BOM items
[ // hole positions
for ( i=[ [0, 0], [62.15, 0.25] ])
(i + [21.6, -13.3]),
for( i=[ [0, -34.98 ], [31.80, -37.62 ], [95.68, -64.47] ])
(i + [3.75, -13.25])
],
[ // components
// cpu
[ 62.8, 42.5, 0, "chip", 14, 14, 1, grey(15) ],
// driver chips
for (x = [8.5, 27.5, 43.2, 58.5, 74])
[x, -20, 0, "chip", 5, 5, 1, grey(15)],
// mock up heat sinks over the chips
for (x = [8.5, 27.5, 43.2, 58.5, 74])
[x, -20, 0, "chip", 9, 8.5, 2, "DeepSkyBlue" ],
for (x = [8.5, 27.5, 43.2, 58.5, 74], y = [-4,-2,0,2,4])
[x, -20 + y, 0, "chip", 9, 0.75, 11, "DeepSkyBlue" ],
// heat dissipation for drivers under board
[ 43, -21, 0, "-block", 85, 8, 0.1, gold ],
// hotend and heated bed
[ 25.5, 20, 0, "chip", 10, 8.5, 4, grey(15) ],
[ 25.5, 20, 0, "-block", 11, 11, 0.1, gold ],
[ 36.25, 16.75, 0, "chip", 6.5, 6, 2.5, grey(15) ],
[ 36.25, 17, 0, "-block", 7.5, 7.5, 0.1, gold ],
[ 44.25, 16.75, 0, "chip", 6.5, 6, 2.5, grey(15) ],
[ 44.25, 17, 0, "-block", 7.5, 7.5, 0.1, gold ],
// voltage regulator
[ 15.1, 44.2, 0, "chip", 4, 5, 2, grey(15) ],
[ 12.1, 44.2, 0, "-block", 10, 10, 0.1, gold ],
// terminals
[ 5.25, 5.3, 180, "gterm", gt_5x17, 2, undef, grey(20) ],
[ 16.25, 5.4, -90, "gterm", gt_5x17, 2, undef, grey(20) ],
[ 26.25, 5.4, -90, "gterm", gt_5x17, 2, undef, grey(20) ],
[ 36.1, 6.7, -90, "gterm", gt_5x11, 2, undef, "lightgreen" ],
[ 45.0, 6.7, -90, "gterm", gt_5x11, 2, undef, "lightgreen" ],
[ -3, -(32.27 + 39.92)/2, 0, "usb_uA" ],
[ -8, -(12.13 + 27.17)/2, 0, "uSD", [17.17 - 2.13, 16, 2] ],
[ -22.2, 51.6, 0, "button_6mm" ],
// EXP
[ -4.45, 27.2, -90, "2p54boxhdr", 5, 2 ],
// AUX-2
[ -3.4, 42.5, -90, "2p54header", 4, 2 ],
// TFT
[ 73.7, 21, 0, "2p54header", 5, 1 ],
// FAN0
[ 52.1, 15.3, 180, "jst_xh", 2, false, grey(20) ],
// FAN1
[ 60.1, 15.3, 180, "jst_xh", 2, false, grey(20) ],
// PS-ON
[ 67.9, 15.3, 180, "jst_xh", 2, false, grey(20) ],
// E0-STOP
[ 77.1, 15.3, 180, "jst_xh", 3, false, grey(20) ],
// E1-STOP
[ 87.5, 15.3, 180, "jst_xh", 3, false, grey(20) ],
// Z-PROBE
[ 85.05, 34.6, 180, "jst_xh", 5, false, grey(20) ],
// NEO Pixel
[ 77, 26.8, 180, "jst_xh", 3, false, grey(20) ],
// PWR-DET
[ 87.7, 26.8, 180, "jst_xh", 3, false, grey(20) ],
// FAN2
[ 52.1, 3.8, 0, "2p54header", 1, 2],
// end stops and thermistors
for (x = [58.5 : 7.9 : 98.1])
[x, 3.7, 180, "jst_xh", 2, false, grey(20)],
// motor connections
for (x = [7, 27.1, 47.3, 67.5, 87.9])
[x, -3.9, 0, "jst_xh", 4, false, grey(20)],
[47.3, -10.4, 0, "jst_xh", 4, false, grey(20)], // second Z connector
// motor jumpers
for (x = [9.4, 26.4, 42.5, 58.7, 75.3])
[x, -33.7, 0, "2p54header", 2, 1],
// SWD
[ 45.4, 35.7, 0, "2p54header", 5, 1 ],
// USB power jumber
[ -12.6, 40.3, 0, "2p54header", 3, 1 ],
// VOUT
[ -13.9, 44.5, 0, "2p54header", 2, 2 ],
// VIN
[ 18.6, 29.8, 0, "2p54header", 2, 2 ],
],
[] // accessories
];
TMC2130 = [
"TMC2130", "TMC2130",
20, 14, 1.6, // size
@@ -654,9 +747,9 @@ ESP_01 = [
[] // accessories
];
pcbs = [MP1584EN, TP4056, ESP_01, RAMPSEndstop, MT3608, PI_IO, ExtruderPCB, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, WD2002SJ, RPI3, RPI4, BTT_SKR_MINI_E3_V2_0, BTT_SKR_V1_4_TURBO, DuetE, Duex5];
pcbs = [MP1584EN, TP4056, ESP_01, RAMPSEndstop, MT3608, PI_IO, ExtruderPCB, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, WD2002SJ, RPI3, RPI4, BTT_SKR_MINI_E3_V2_0, BTT_SKR_E3_TURBO, BTT_SKR_V1_4_TURBO, DuetE, Duex5];
pcbs_not_shown = [Melzi, Duex2, PSU12V1A];
pcbs_not_shown = [Melzi, Duex2, PSU12V1A, Keyes5p1];
perfboards = [PERF74x51, PERF70x50, PERF60x40, PERF70x30, PERF80x20];

View File

@@ -23,7 +23,7 @@
// Wr Hr E P D d h go gw
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.6, 2.4, 0.8, M2_cs_cap_screw, M2_cs_cap_screw, 1, 1 ]; // Screw holes too small for M2 heads
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, M2_cs_cap_screw, 1.5, 1.5 ];
MGN9 = [ "MGN9", 9, 6, 7.5, 20, 6.0, 3.5, 3.5, M3_cap_screw, M3_cs_cap_screw, 1.5, 1.5 ];
MGN9 = [ "MGN9", 9, 6, 5, 20, 6.0, 3.5, 3.5, M3_cap_screw, M3_cs_cap_screw, 1.5, 1.5 ];
MGN12 =[ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, M3_cs_cap_screw, 2.25, 2.75];
MGN15 =[ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, M3_cs_cap_screw, 2.5, 2.75 ];
SSR15= [ "SSR15", 15, 12.5, 10, 60, 7.5, 4.5, 5.3, M4_cap_screw, M4_cs_cap_screw, 2.5, 2.75 ];