Compare commits
95 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ec891c8013 | ||
|
c7811f21e0 | ||
|
782deccf6b | ||
|
69da4c1c23 | ||
|
0a00f244e4 | ||
|
76ea28e88e | ||
|
44cf9e910b | ||
|
0261362794 | ||
|
2e6b55bcbc | ||
|
20901f0356 | ||
|
77ffdcb1ac | ||
|
6ab4bad97a | ||
|
14c6219733 | ||
|
b21b7b9de0 | ||
|
73d814d2fe | ||
|
fa658d9eaa | ||
|
6d3f54b7a5 | ||
|
157ff60e19 | ||
|
cbd3cf29af | ||
|
bf618bb482 | ||
|
1e6f0a5c4d | ||
|
53c3cdb598 | ||
|
f4857f6862 | ||
|
1acc8d01c0 | ||
|
344e8d1583 | ||
|
dd757a1461 | ||
|
b4f8892b1a | ||
|
4b033d9945 | ||
|
d5a711f4cc | ||
|
42b76ab8d3 | ||
|
f18044915d | ||
|
17b12c7f31 | ||
|
18ff4c6d46 | ||
|
2eecce819c | ||
|
f7d81738bb | ||
|
6d44124bab | ||
|
9bb9f09dca | ||
|
773a53829f | ||
|
07766d8cf0 | ||
|
ceac5cdb27 | ||
|
c5b35daeac | ||
|
ffb4512523 | ||
|
35ffbad74c | ||
|
fb685a0f42 | ||
|
5d42b2e1ab | ||
|
2fe815d1bd | ||
|
5c577cccd0 | ||
|
1dbfafd366 | ||
|
68b3dfb098 | ||
|
25dceee20a | ||
|
d70ddf5359 | ||
|
70b60522ce | ||
|
ecba7eaea4 | ||
|
f751dd9a73 | ||
|
3f359f6839 | ||
|
3e5947c161 | ||
|
66dc430541 | ||
|
4dc83d62cb | ||
|
ebbec3c903 | ||
|
9944aab73e | ||
|
eb9bcf0ada | ||
|
ff5e8c0372 | ||
|
17ebf36e27 | ||
|
e38d9abfa0 | ||
|
fc7fd5482e | ||
|
cee1202fd9 | ||
|
6e342441c6 | ||
|
072c38f955 | ||
|
b342549d74 | ||
|
2b83a15e5d | ||
|
ab81c6538c | ||
|
27b0a442e4 | ||
|
38acef9e27 | ||
|
5415beb80d | ||
|
040985c0db | ||
|
0216093a68 | ||
|
30302431c0 | ||
|
1fb429e9a5 | ||
|
9571e68629 | ||
|
b01e6a673c | ||
|
9239c6da3c | ||
|
ba5e5fa390 | ||
|
c7dfdd0fb9 | ||
|
814ce4f15d | ||
|
f661cf6934 | ||
|
305d2146f2 | ||
|
e39ee1797d | ||
|
520569cb30 | ||
|
f73a7b46a2 | ||
|
fb9eca85c6 | ||
|
166ed05d4a | ||
|
ce6aec428d | ||
|
1810160103 | ||
|
b583202fb7 | ||
|
03beaec470 |
@@ -35,8 +35,8 @@ extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // fil
|
||||
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
|
||||
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // minimum tool radius when milling 2D objects
|
||||
pp1_colour = is_undef($pp1_colour) ? [0, 146/255, 0] : $pp1_colour; // printed part colour 1, RepRap logo colour
|
||||
pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // printed part colour 2
|
||||
pp3_colour = is_undef($pp3_colour) ? "blue" : $pp3_colour; // printed part colour 3
|
||||
pp2_colour = is_undef($pp2_colour) ? "Crimson" : $pp2_colour; // printed part colour 2
|
||||
pp3_colour = is_undef($pp3_colour) ? "SteelBlue" : $pp3_colour; // printed part colour 3
|
||||
pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4
|
||||
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
|
||||
show_threads = is_undef($show_threads) ? false : $show_threads; // show screw threads
|
||||
|
1
lib.scad
@@ -54,6 +54,7 @@ include <vitamins/ring_terminals.scad>
|
||||
include <vitamins/rails.scad>
|
||||
include <vitamins/rod.scad>
|
||||
include <vitamins/scs_bearing_blocks.scad>
|
||||
include <vitamins/shaft_couplings.scad>
|
||||
include <vitamins/sheets.scad>
|
||||
include <vitamins/sk_brackets.scad>
|
||||
include <vitamins/spools.scad>
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 818 KiB After Width: | Height: | Size: 854 KiB |
21
libtest.scad
@@ -47,10 +47,12 @@ use <tests/bulldogs.scad>
|
||||
use <tests/buttons.scad>
|
||||
use <tests/cable_strips.scad>
|
||||
use <tests/cameras.scad>
|
||||
use <tests/camera_housing.scad>
|
||||
use <tests/circlips.scad>
|
||||
use <tests/components.scad>
|
||||
use <tests/d_connectors.scad>
|
||||
use <tests/displays.scad>
|
||||
use <tests/drag_chain.scad>
|
||||
use <tests/extrusions.scad>
|
||||
use <tests/extrusion_brackets.scad>
|
||||
use <tests/fans.scad>
|
||||
@@ -76,6 +78,7 @@ use <tests/opengrab.scad>
|
||||
use <tests/panel_meters.scad>
|
||||
use <tests/PCBs.scad>
|
||||
use <tests/pillars.scad>
|
||||
use <tests/press_fit.scad>
|
||||
use <tests/PSUs.scad>
|
||||
use <tests/pulleys.scad>
|
||||
use <tests/rails.scad>
|
||||
@@ -85,6 +88,7 @@ use <tests/rod.scad>
|
||||
use <tests/screws.scad>
|
||||
use <tests/SCS_bearing_blocks.scad>
|
||||
use <tests/sealing_strip.scad>
|
||||
use <tests/shaft_couplings.scad>
|
||||
use <tests/sheets.scad>
|
||||
use <tests/SK_brackets.scad>
|
||||
use <tests/spades.scad>
|
||||
@@ -134,9 +138,12 @@ cable_grommets_y = 0;
|
||||
translate([x5, cable_grommets_y])
|
||||
cable_grommets();
|
||||
|
||||
translate([x5 + 80, cable_grommets_y])
|
||||
translate([x5 + 50, cable_grommets_y])
|
||||
ribbon_clamps();
|
||||
|
||||
translate([x5 + 95, cable_grommets_y])
|
||||
press_fits();
|
||||
|
||||
translate([x5, cable_grommets_y + 60])
|
||||
fixing_blocks();
|
||||
|
||||
@@ -363,6 +370,9 @@ translate([x3 + 170, veroboard_y + 16])
|
||||
translate([x3, d_connectors_y])
|
||||
d_connectors();
|
||||
|
||||
translate([x3 + 170, d_connectors_y - 10])
|
||||
camera_housings();
|
||||
|
||||
translate([x3, iecs_y])
|
||||
iecs();
|
||||
|
||||
@@ -412,12 +422,16 @@ translate([x4 + 200, belts_y + 58]) {
|
||||
|
||||
translate([0, 60])
|
||||
opengrab_test();
|
||||
|
||||
}
|
||||
|
||||
translate([x4 + 175, belts_y, -20])
|
||||
drag_chains();
|
||||
|
||||
translate([x4, rails_y + 130])
|
||||
rails();
|
||||
|
||||
translate([800, fans_y + 50])
|
||||
translate([770, fans_y + 50])
|
||||
cable_strips();
|
||||
|
||||
translate([x4, kp_pillow_blocks_y])
|
||||
@@ -429,6 +443,9 @@ translate([x4, sk_brackets_y])
|
||||
translate([x4, extrusion_brackets_y])
|
||||
extrusion_brackets();
|
||||
|
||||
translate([x4 + 120, extrusion_brackets_y])
|
||||
shaft_couplings();
|
||||
|
||||
translate([x4, scs_bearing_blocks_y])
|
||||
scs_bearing_blocks();
|
||||
|
||||
|
@@ -121,11 +121,12 @@ module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered arr
|
||||
|
||||
module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
|
||||
t = box_sheet_slot(type);
|
||||
inset = box_corner_gap(type) + box_profile_overlap(type);
|
||||
difference() {
|
||||
union() {
|
||||
quadrant(box_hole_inset(type) + box_boss_r(type), box_boss_r(type)); // inside corner
|
||||
|
||||
translate([box_corner_gap(type) + box_profile_overlap(type), box_corner_gap(type) + box_profile_overlap(type)])
|
||||
translate([inset, inset])
|
||||
rotate(180)
|
||||
quadrant(box_profile_overlap(type) + box_corner_rad(type), box_corner_rad(type)); // outside corner
|
||||
}
|
||||
@@ -212,33 +213,39 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
|
||||
feet = bottom && box_feet(type);
|
||||
t = box_sheet_slot(type);
|
||||
outset = box_outset(type);
|
||||
inset = box_inset(type);
|
||||
inner_r = box_sheet_r(type);
|
||||
foot_height = box_corner_gap(type) + sheet_thickness(box_base_sheet(type)) + washer_thickness(box_washer(type)) + screw_head_height(box_screw(type)) + box_profile_overlap(type) + 2;
|
||||
cgap = box_corner_gap(type);
|
||||
foot_height = cgap + sheet_thickness(box_base_sheet(type)) + washer_thickness(box_washer(type)) + screw_head_height(box_screw(type)) + box_profile_overlap(type) + 2;
|
||||
foot_length = box_corner_rad(type) * 2;
|
||||
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() {
|
||||
rounded_rectangle([box_width(type) + 2 * outset, box_depth(type) + 2 * outset, feet ? foot_height : height], box_corner_rad(type), false);
|
||||
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([box_width(type) - 2 * foot_length, box_depth(type) + 2 * outset + 1, 1], center = true);
|
||||
cube([w - 2 * foot_length, td + 1, 1], center = true);
|
||||
|
||||
translate_z(foot_height + 1)
|
||||
cube([box_width(type) - 2 * (foot_length - foot_extension), box_depth(type) + 2 * outset + 1, 1], center = true);
|
||||
cube([w - 2 * (foot_length - foot_extension), td + 1, 1], center = true);
|
||||
}
|
||||
if(feet)
|
||||
hull() {
|
||||
translate_z(height + 0.5)
|
||||
cube([box_width(type) + 2 * outset + 1, box_depth(type) - 2 * foot_length, 1], center = true);
|
||||
cube([tw + 1, d - 2 * foot_length, 1], center = true);
|
||||
|
||||
translate_z(foot_height + 1)
|
||||
cube([box_width(type) + 2 * outset + 1, box_depth(type) - 2 * (foot_length - foot_extension), 1], center = true);
|
||||
cube([tw + 1, d - 2 * (foot_length - foot_extension), 1], center = true);
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -247,28 +254,28 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
|
||||
translate_z(-box_profile_overlap(type))
|
||||
linear_extrude(2 * box_profile_overlap(type), center = true)
|
||||
for(i = [-1, 1]) {
|
||||
translate([i * (box_width(type) / 2 + t / 2 - sheet_slot_clearance / 2), 0])
|
||||
square([t, box_depth(type) - 2 * box_corner_gap(type)], center = true);
|
||||
translate([i * (w + t - sheet_slot_clearance) / 2, 0])
|
||||
square([t, d - 2 * cgap], center = true);
|
||||
|
||||
translate([0, i * (box_depth(type) / 2 + t / 2 - sheet_slot_clearance / 2)])
|
||||
square([box_width(type) - 2 * box_corner_gap(type), t], 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(box_corner_gap(type))
|
||||
rounded_rectangle([box_width(type) + bezel_clearance, box_depth(type) + bezel_clearance, height], inner_r + bezel_clearance / 2, false);
|
||||
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) + box_corner_gap(type) + 2)
|
||||
linear_extrude(box_profile_overlap(type) + cgap + 2)
|
||||
union() {
|
||||
difference() {
|
||||
square([box_width(type) - 2 * box_inset(type),
|
||||
box_depth(type) - 2 * box_inset(type)], center = true);
|
||||
square([w - 2 * inset,
|
||||
d - 2 * inset], center = true);
|
||||
|
||||
box_corner_quadrants(type, box_width(type), box_depth(type));
|
||||
box_corner_quadrants(type, w, d);
|
||||
}
|
||||
box_screw_hole_positions(type)
|
||||
poly_circle(screw_clearance_radius(box_screw(type)));
|
||||
@@ -291,7 +298,9 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
dw = bw - 2 * dowel_wall;
|
||||
dh = box_bezel_height(type, bottom) - dowel_h_wall;
|
||||
|
||||
dh2 = box_profile_overlap(type) + box_corner_gap(type) - dowel_h_wall;
|
||||
profile_overlap = box_profile_overlap(type);
|
||||
|
||||
dh2 = profile_overlap + box_corner_gap(type) - dowel_h_wall;
|
||||
|
||||
end_clearance = 0.5;
|
||||
module male() {
|
||||
@@ -299,14 +308,14 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
linear_extrude(dowel_length - 2 * end_clearance, center = true)
|
||||
difference() {
|
||||
union() {
|
||||
h = dh - layer_height;
|
||||
h1 = dh - layer_height;
|
||||
h2 = dh2 - layer_height;
|
||||
hull() {
|
||||
translate([bw / 2, h / 2])
|
||||
square([dw - 1, h], center = true);
|
||||
translate([bw / 2, h1 / 2])
|
||||
square([dw - 1, h1], center = true);
|
||||
|
||||
translate([bw / 2, (h - 1) / 2])
|
||||
square([dw, h - 1], center = true);
|
||||
translate([bw / 2, (h1 - 1) / 2])
|
||||
square([dw, h1 - 1], center = true);
|
||||
}
|
||||
|
||||
hull() {
|
||||
@@ -318,7 +327,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
}
|
||||
}
|
||||
translate([bw2 / 2, 0])
|
||||
square([box_sheet_slot(type), 2 * box_profile_overlap(type)], center = true);
|
||||
square([box_sheet_slot(type), 2 * profile_overlap], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +368,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
render() difference() {
|
||||
union() {
|
||||
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
|
||||
translate([tw / 2 - x * w, th / 2 - y * h, box_profile_overlap(type)])
|
||||
translate([tw / 2 - x * w, th / 2 - y * h, profile_overlap])
|
||||
box_bezel(type, bottom);
|
||||
|
||||
if(x < cols - 1 && y == 0)
|
||||
@@ -419,10 +428,14 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
}
|
||||
}
|
||||
|
||||
module box_screw_hole_positions(type)
|
||||
module box_screw_hole_positions(type) {
|
||||
inset = box_hole_inset(type);
|
||||
w = box_width(type) / 2 - inset;
|
||||
d = box_depth(type) / 2 - inset;
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate([x * (box_width(type) / 2 - box_hole_inset(type)), y * (box_depth(type) / 2 - box_hole_inset(type))])
|
||||
translate([x * w, y * d])
|
||||
children();
|
||||
}
|
||||
|
||||
module box_base_blank(type) { //! Generates a 2D template for the base sheet
|
||||
dxf("box_base");
|
||||
|
392
printed/camera_housing.scad
Normal file
@@ -0,0 +1,392 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Housings for PCB cameras.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/cameras.scad>
|
||||
use <../vitamins/pcb.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
wall = 1.75;
|
||||
min_wall = 2 * extrusion_width;
|
||||
clearance = 0.2;
|
||||
|
||||
connector_size = [23, 6, 2.65]; // Worst case size of flat flex connector
|
||||
|
||||
cam_back_clearance = round_to_layer(1.5); // Clearance for components on the back of the pcb
|
||||
cam_back_overlap = 1; // How much the back overlaps the edge of the pcb
|
||||
cam_back_wall = min_wall;
|
||||
|
||||
function cam_front_clearance(cam) = round_to_layer(camera_connector_size(cam).z + clearance);
|
||||
|
||||
function cam_back_size(cam) = let(
|
||||
pcb = camera_pcb(cam),
|
||||
pcb_size = pcb_size(pcb),
|
||||
nut = screw_nut(pcb_screw(pcb)),
|
||||
holes = [for(h = pcb_holes(pcb)) pcb_coord(pcb, h).x],
|
||||
pitch = max(holes) - min(holes),
|
||||
length = pitch + 2 * (nut_radius(nut) + min_wall),
|
||||
width = pcb_size.y + (length - pcb_size.x) * cos(30)
|
||||
) [length, width, wall + max(connector_size.z, cam_back_clearance + nut_trap_depth(nut))];
|
||||
|
||||
|
||||
function cam_front_size(cam) = cam_back_size(cam) + [ //! Outside dimensions of the case
|
||||
2 * (wall + clearance),
|
||||
2 * (wall + clearance),
|
||||
pcb_thickness(camera_pcb(cam)) + cam_front_clearance(cam) + wall
|
||||
];
|
||||
|
||||
hinge_screw = M2_cap_screw;
|
||||
hinge_nut = screw_nut(hinge_screw);
|
||||
hinge_screw_length = 12;
|
||||
|
||||
hinge_r = nut_trap_radius(hinge_nut) + 3 * extrusion_width;
|
||||
hinge_h = wall + nut_trap_depth(hinge_nut);
|
||||
hinge_offset = hinge_r + 1;
|
||||
|
||||
bracket_screw = M3_dome_screw;
|
||||
|
||||
function cam_screw_length(cam) = let(
|
||||
front = cam_front_size(cam),
|
||||
screw = pcb_screw(camera_pcb(cam)),
|
||||
nut = screw_nut(screw)
|
||||
) screw_longer_than(front.z + washer_thickness(screw_washer(screw)) - nut_trap_depth(nut) + nut_thickness(nut, true));
|
||||
|
||||
function hinge_z(cam) = cam_screw_length(cam) - hinge_r;
|
||||
|
||||
module cam_holes(cam) {
|
||||
pcb = camera_pcb(cam);
|
||||
lens_y = camera_lens_offset(cam).y;
|
||||
two_holes = !!len([for (h = pcb_holes(pcb)) if(abs(pcb_coord(pcb, h).y - lens_y) < 1) true]);
|
||||
pcb_screw_positions(pcb) // screw holes
|
||||
if($i > 1 || !two_holes)
|
||||
children();
|
||||
}
|
||||
|
||||
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;
|
||||
hole_r2 = 5 / 2;
|
||||
thickness = 3;
|
||||
flutes = 8;
|
||||
angle = 180 / flutes;
|
||||
x = rad / (sin(angle / 2) + cos(angle / 2));
|
||||
r = x * sin(angle / 2);
|
||||
|
||||
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 + angle])
|
||||
translate([x, 0])
|
||||
circle(r);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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_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);
|
||||
pcb_size = pcb_size(pcb);
|
||||
lens_offset = camera_lens_offset(cam);
|
||||
screw = pcb_screw(pcb);
|
||||
|
||||
shelf = front.z - back.z;
|
||||
|
||||
connector_slot = connector_size + 2 * [clearance, 0, layer_height];
|
||||
rad = wall;
|
||||
led_hole_r = 1;
|
||||
led_clearance = [5, 2, 1 * 2];
|
||||
res_clearance = [3.5, 2, 1 * 2];
|
||||
|
||||
conn_pos = camera_connector_pos(cam);
|
||||
conn = camera_connector_size(cam);
|
||||
sensor_length = conn_pos.y + conn.y / 2 - lens_offset.y + clearance;
|
||||
|
||||
module hinge_pos()
|
||||
if(!is_undef(hinge))
|
||||
rotate(hinge * 90)
|
||||
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);
|
||||
|
||||
translate_z(rad)
|
||||
sphere(rad);
|
||||
|
||||
cylinder(r = rad * (sqrt(2) - 1), h = eps);
|
||||
}
|
||||
|
||||
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([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);
|
||||
|
||||
hflip()
|
||||
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));
|
||||
|
||||
module camera_bracket_screw_positions(cam) { //! Position children at the bracket screw positions
|
||||
r = washer_radius(screw_washer(bracket_screw)) + 0.5;
|
||||
wide = bracket_thickness(cam) == wall;
|
||||
pitch = wide ? cam_front_size(cam).x / 2 - r : hinge_h + 1 + r;
|
||||
|
||||
for(side = [-1, 1])
|
||||
translate([side * pitch, 0])
|
||||
children();
|
||||
}
|
||||
|
||||
module camera_bracket_position(cam) //! Position children at the bracket position
|
||||
translate([0, cam_front_size(cam).y / 2 + hinge_offset])
|
||||
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);
|
||||
}
|
||||
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()
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
module camera_assembly(cam, angle = 0) //! Camera case assembly
|
||||
assembly(str("camera_", cam[0])) {
|
||||
front = cam_front_size(cam);
|
||||
screw = pcb_screw(camera_pcb(cam));
|
||||
nut = screw_nut(screw);
|
||||
screw_length = cam_screw_length(cam);
|
||||
hinge_z = hinge_z(cam);
|
||||
hinge_pos = [0, front.y / 2 + hinge_offset, -hinge_r];
|
||||
|
||||
camera_bracket_position(cam) {
|
||||
nut = screw_nut(hinge_screw);
|
||||
|
||||
stl_colour(pp1_colour) render()
|
||||
camera_bracket(cam);
|
||||
|
||||
translate([-hinge_h, 0, hinge_z(cam)])
|
||||
rotate([-90, 0, 90]) {
|
||||
vflip()
|
||||
translate_z(2 * hinge_h - nut_trap_depth(nut))
|
||||
nut(nut, true);
|
||||
|
||||
screw_and_washer(hinge_screw, screw_longer_than(2 * hinge_h));
|
||||
}
|
||||
}
|
||||
|
||||
translate_z(hinge_z(cam) + hinge_r)
|
||||
translate(hinge_pos)
|
||||
rotate([-angle, 0, 0])
|
||||
translate(-hinge_pos) {
|
||||
translate_z(cam_back_size(cam).z - front.z)
|
||||
camera(cam);
|
||||
|
||||
stl_colour(pp1_colour) render()
|
||||
translate_z(-front.z)
|
||||
camera_back(cam);
|
||||
|
||||
cam_holes(cam) {
|
||||
screw_and_washer(screw, screw_length);
|
||||
|
||||
translate_z(-front.z + nut_trap_depth(nut))
|
||||
vflip()
|
||||
nut(nut, true);
|
||||
}
|
||||
|
||||
*translate(camera_lens_offset(cam))
|
||||
translate_z(1.5)
|
||||
stl_colour(pp1_colour) render()
|
||||
rpi_camera_focus_ring_stl();
|
||||
|
||||
stl_colour(pp2_colour) render()
|
||||
hflip()
|
||||
camera_front(cam, 0);
|
||||
}
|
||||
}
|
||||
|
||||
module camera_fastened_assembly(cam, thickness, angle = 0) {
|
||||
camera_assembly(cam, angle);
|
||||
|
||||
camera_bracket_position(cam)
|
||||
camera_bracket_screw_positions(cam) {
|
||||
nut = screw_nut(bracket_screw);
|
||||
washer = screw_washer(bracket_screw);
|
||||
t = bracket_thickness(cam);
|
||||
screw_length = screw_longer_than(thickness + t + nut_thickness(nut, true) + 2 * washer_thickness(washer));
|
||||
vflip()
|
||||
translate_z(thickness)
|
||||
screw_and_washer(bracket_screw, screw_length);
|
||||
|
||||
translate_z(t)
|
||||
nut_and_washer(nut, true);
|
||||
}
|
||||
}
|
||||
|
||||
module camera_back_rpi_camera_stl() camera_back(rpi_camera);
|
||||
module camera_back_rpi_camera_v1_stl() camera_back(rpi_camera_v1);
|
||||
module camera_back_rpi_camera_v2_stl() camera_back(rpi_camera_v2);
|
||||
|
||||
module camera_front_rpi_camera_stl() camera_front(rpi_camera);
|
||||
module camera_front_rpi_camera_v1_stl() camera_front(rpi_camera_v1);
|
||||
module camera_front_rpi_camera_v2_stl() camera_front(rpi_camera_v2);
|
||||
|
||||
module camera_bracket_rpi_camera_stl() camera_bracket(rpi_camera);
|
||||
module camera_bracket_rpi_camera_v1_stl() camera_bracket(rpi_camera_v1);
|
||||
module camera_bracket_rpi_camera_v2_stl() camera_bracket(rpi_camera_v2);
|
||||
|
||||
module camera_rpi_camera_assembly() camera_assembly(rpi_camera);
|
||||
module camera_rpi_camera_v1_assembly() camera_assembly(rpi_camera_v1);
|
||||
module camera_rpi_camera_v2_assembly() camera_assembly(rpi_camera_v2);
|
||||
|
||||
module camera_housing(cam) {
|
||||
front = cam_front_size(cam);
|
||||
|
||||
camera_front(cam, 0);
|
||||
|
||||
translate([front.x, 0])
|
||||
camera_back(cam);
|
||||
|
||||
translate([-front.x / 2 - 2 - hinge_r, 0])
|
||||
rotate(90)
|
||||
camera_bracket(cam);
|
||||
}
|
||||
|
||||
cam = rpi_camera_v2;
|
||||
if($preview)
|
||||
camera_fastened_assembly(cam, 3);
|
||||
else
|
||||
camera_housing(cam);
|
321
printed/drag_chain.scad
Normal file
@@ -0,0 +1,321 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Parametric cable drag chain to limit the bend radius of a cable run.
|
||||
//!
|
||||
//! Each link has a maximum bend angle of 45°, so the mininium radius is proportional to the link length.
|
||||
//!
|
||||
//! The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
|
||||
//!
|
||||
//! The ends can have screw lugs with four screw positions to choose from, specified by a list of two arrays of four bools.
|
||||
//! If none are enabled then a child object is expected to customise the end and this gets unioned with the blank end.
|
||||
//! If both ends are customised then two children are expected.
|
||||
//! Each child is called twice, once with ```$fasteners``` set to 0 to augment the STL and again with ```$fasteners``` set to 1 to add
|
||||
//! to the assembly, for example to add inserts.
|
||||
//
|
||||
|
||||
include <../core.scad>
|
||||
use <../utils/horiholes.scad>
|
||||
use <../utils/maths.scad>
|
||||
|
||||
clearance = 0.1;
|
||||
|
||||
function drag_chain_name(type) = type[0]; //! The name to allow more than one in a project
|
||||
function drag_chain_size(type) = type[1]; //! The internal size and link length
|
||||
function drag_chain_travel(type) = type[2]; //! X travel
|
||||
function drag_chain_wall(type) = type[3]; //! Side wall thickness
|
||||
function drag_chain_bwall(type) = type[4]; //! Bottom wall
|
||||
function drag_chain_twall(type) = type[5]; //! Top wall
|
||||
function drag_chain_screw(type) = type[6]; //! Mounting screw for the ends
|
||||
function drag_chain_screw_lists(type) = type[7]; //! Two lists of four bools to say which screws positions are used
|
||||
|
||||
function drag_chain_clearance() = clearance; //! Clearance around joints.
|
||||
|
||||
function drag_chain_radius(type) = //! The bend radius at the pivot centres
|
||||
let(s = drag_chain_size(type))
|
||||
s.x / 2 / sin(360 / 16);
|
||||
|
||||
function drag_chain_z(type) = //! Outside dimension of a 180 bend
|
||||
let(os = drag_chain_outer_size(type), s = drag_chain_size(type))
|
||||
2 * drag_chain_radius(type) + os.z;
|
||||
|
||||
function drag_chain(name, size, travel, wall = 1.6, bwall = 1.5, twall = 1.5, screw = M2_cap_screw, screw_lists = [[1,0,0,1],[1,0,0,1]]) = //! Constructor
|
||||
[name, size, travel, wall, bwall, twall, screw, screw_lists];
|
||||
|
||||
function drag_chain_outer_size(type) = //! Link outer dimensions
|
||||
let(s = drag_chain_size(type), z = s.z + drag_chain_bwall(type) + drag_chain_twall(type))
|
||||
[s.x + z, s.y + 4 * drag_chain_wall(type) + 2 * clearance, z];
|
||||
|
||||
function screw_lug_radius(screw) = //! Radius of a screw lug
|
||||
corrected_radius(screw_clearance_radius(screw)) + 3.1 * extrusion_width;
|
||||
|
||||
module screw_lug(screw, h = 0) //! Create a D shaped lug for a screw
|
||||
extrude_if(h, center = false)
|
||||
difference() {
|
||||
r = screw_lug_radius(screw);
|
||||
hull() {
|
||||
circle4n(r);
|
||||
|
||||
translate([-r, -r])
|
||||
square([2 * r, eps]);
|
||||
}
|
||||
poly_circle(screw_clearance_radius(screw));
|
||||
}
|
||||
|
||||
function bool2int(b) = b ? 1 : 0;
|
||||
|
||||
module drag_chain_screw_positions(type, end) { //! Place children at the screw positions, end = 0 for the start, 1 for the end
|
||||
r = screw_lug_radius(drag_chain_screw(type));
|
||||
s = drag_chain_size(type);
|
||||
os = drag_chain_outer_size(type);
|
||||
R = os.z / 2;
|
||||
x0 = end ? R + norm([drag_chain_cam_x(type), R - drag_chain_twall(type)]) + clearance + r : r;
|
||||
x1 = end ? os.x - r : os.x - 2 * R - clearance - r;
|
||||
for(i = [0 : 3], x = [x0, x1, x0, x1][i], y = [-1, -1, 1, 1][i])
|
||||
if(drag_chain_screw_lists(type)[bool2int(end)][i])
|
||||
translate([x, y * (s.y / 2 + r)])
|
||||
let($a = [180, 0, 180, 0][i])
|
||||
children();
|
||||
}
|
||||
|
||||
function drag_chain_cam_x(type) = // how far the cam sticks out
|
||||
let(s = drag_chain_size(type),
|
||||
r = drag_chain_outer_size(type).z / 2,
|
||||
wall = drag_chain_wall(type),
|
||||
cam_r = s.x - 2 * clearance - wall - r, // inner_x_normal - clearance - r
|
||||
twall = drag_chain_twall(type)
|
||||
) min(sqrt(max(sqr(cam_r) - sqr(r - twall), 0)), r);
|
||||
|
||||
module drag_chain_link(type, start = false, end = false, check_kids = true) { //! One link of the chain, special case for start and end
|
||||
stl(str(drag_chain_name(type), "_drag_chain_link", start ? "_start" : end ? "_end" : ""));
|
||||
|
||||
s = drag_chain_size(type);
|
||||
wall = drag_chain_wall(type);
|
||||
bwall = drag_chain_bwall(type);
|
||||
twall = drag_chain_twall(type);
|
||||
os = drag_chain_outer_size(type);
|
||||
r = os.z / 2;
|
||||
pin_r = r / 2;
|
||||
|
||||
socket_x = r;
|
||||
pin_x = socket_x + s.x;
|
||||
|
||||
outer_normal_x = pin_x - r - clearance; // s.x - clearance
|
||||
outer_end_x = end ? os.x : outer_normal_x;
|
||||
|
||||
inner_x = start ? 0 : outer_normal_x - wall; // s.x - clearance - wall
|
||||
|
||||
roof_x_normal = 2 * r - twall;
|
||||
roof_x = start ? 0 : roof_x_normal;
|
||||
|
||||
floor_x = start ? 0 : 2 * r;
|
||||
cam_x = drag_chain_cam_x(type);
|
||||
assert(r + norm([drag_chain_cam_x(type), r - drag_chain_twall(type)]) + clearance <= inner_x || start, "Link must be longer");
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
for(side = [-1, 1])
|
||||
rotate([90, 0, 0]) {
|
||||
// Outer cheeks
|
||||
translate_z(side * (os.y / 2 - wall / 2))
|
||||
linear_extrude(wall, center = true)
|
||||
difference() {
|
||||
hull() {
|
||||
if(start)
|
||||
square([eps, os.z]);
|
||||
else
|
||||
translate([socket_x, r])
|
||||
rotate(180)
|
||||
teardrop(r = r, h = 0);
|
||||
|
||||
translate([outer_end_x - eps, 0])
|
||||
square([eps, os.z]);
|
||||
}
|
||||
if(!start)
|
||||
translate([socket_x, r])
|
||||
horihole(pin_r, r);
|
||||
}
|
||||
// Inner cheeks
|
||||
translate_z(side * (s.y / 2 + wall / 2))
|
||||
linear_extrude(wall, center = true)
|
||||
difference() {
|
||||
union() {
|
||||
hull() {
|
||||
if(!end) {
|
||||
translate([pin_x, r])
|
||||
rotate(180)
|
||||
teardrop(r = r, h = 0);
|
||||
|
||||
translate([pin_x, twall])
|
||||
square([cam_x, eps]);
|
||||
}
|
||||
else
|
||||
translate([os.x - eps, 0])
|
||||
square([eps, os.z]);
|
||||
|
||||
translate([inner_x, 0])
|
||||
square([eps, os.z]);
|
||||
}
|
||||
}
|
||||
// Cutout for top wall
|
||||
if(!end)
|
||||
intersection() {
|
||||
translate([pin_x - r, 0])
|
||||
square([3 * r, twall]); // When straight
|
||||
|
||||
translate([pin_x, r])
|
||||
rotate(-45)
|
||||
translate([-r + roof_x_normal, -r - twall]) // When bent fully
|
||||
square(os.z);
|
||||
}
|
||||
}
|
||||
// Pin
|
||||
if(!end)
|
||||
translate([pin_x, r, side * (s.y / 2 + wall + clearance)])
|
||||
horicylinder(r = pin_r, z = r, h = 2 * wall);
|
||||
|
||||
// Cheek joint
|
||||
translate([inner_x, 0, side * (s.y / 2 + wall) - 0.5])
|
||||
cube([outer_end_x - inner_x, os.z, 1]);
|
||||
}
|
||||
|
||||
// Roof, actually the floor when printed
|
||||
roof_end = end ? s.x + 2 * r : s.x + r - twall - clearance;
|
||||
translate([roof_x, -s.y / 2 - 0.5])
|
||||
cube([roof_end - roof_x , s.y + 1, twall]);
|
||||
|
||||
translate([roof_x, -os.y / 2 + 0.5])
|
||||
cube([s.x - clearance - roof_x, os.y - 1, twall]);
|
||||
|
||||
// Floor, actually the roof when printed
|
||||
floor_end = end ? s.x + 2 * r : s.x + r;
|
||||
translate([floor_x, -s.y / 2 - wall, os.z - bwall])
|
||||
cube([floor_end - floor_x, s.y + 2 * wall, bwall]);
|
||||
|
||||
translate([floor_x, -os.y / 2 + 0.5, os.z - bwall])
|
||||
cube([s.x - floor_x - clearance, os.y -1, bwall]);
|
||||
|
||||
if(start || end) {
|
||||
drag_chain_screw_positions(type, end)
|
||||
rotate($a)
|
||||
screw_lug(drag_chain_screw(type), os.z);
|
||||
|
||||
if(check_kids) {
|
||||
custom = drag_chain_screw_lists(type)[bool2int(end)] == [0, 0, 0, 0];
|
||||
assert($children == bool2int(custom), str("wrong number of children for ", end ? "end" : "start", " STL customisation: ", $children));
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
if(start || end)
|
||||
translate_z(-eps)
|
||||
drag_chain_screw_positions(type, end)
|
||||
rotate($a)
|
||||
poly_cylinder(r = screw_clearance_radius(drag_chain_screw(type)), h = os.z + 2 * eps, center = false);
|
||||
|
||||
}
|
||||
|
||||
if(show_supports() && !end) {
|
||||
for(side = [-1, 1]) {
|
||||
w = 2.1 * extrusion_width;
|
||||
translate([s.x + r + cam_x - w / 2, side * (s.y / 2 + wall / 2), twall / 2])
|
||||
cube([w, wall, twall], center = true);
|
||||
|
||||
h = round_to_layer(r - pin_r / sqrt(2));
|
||||
y = s.y / 2 + max(wall + w / 2 + clearance, 2 * wall + clearance - w / 2);
|
||||
translate([s.x + r, side * y, h / 2])
|
||||
cube([pin_r * sqrt(2), w, h], center = true);
|
||||
|
||||
gap = cam_x - pin_r / sqrt(2) + extrusion_width;
|
||||
translate([s.x + r + cam_x - gap / 2, side * (s.y / 2 + wall + clearance / 2), layer_height / 2])
|
||||
cube([gap, 2 * wall + clearance, layer_height], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to use a wrapper because can't define nested modules in an assembly
|
||||
module _drag_chain_assembly(type, pos = 0) {
|
||||
s = drag_chain_size(type);
|
||||
x = (1 + exploded()) * s.x;
|
||||
r = drag_chain_radius(type) * x / s.x;
|
||||
travel = drag_chain_travel(type);
|
||||
links = ceil(travel / s.x);
|
||||
actual_travel = links * s.x;
|
||||
z = drag_chain_outer_size(type).z;
|
||||
|
||||
zb = z / 2; // z of bottom track
|
||||
c = [actual_travel / 2 + pos / 2, 0, r + zb]; // centre of bend
|
||||
|
||||
points = [ // Calculate list of hinge points
|
||||
for(i = 0, p = [0, 0, z / 2 + 2 * r]; i < links + 5;
|
||||
i = i + 1,
|
||||
dx = p.z > c.z ? x : -x,
|
||||
p = max(p.x + dx, p.x) <= c.x ? p + [dx, 0, 0] // Straight sections
|
||||
: let(q = circle_intersect(p, x, c, r))
|
||||
q.x <= c.x ? [p.x - sqrt(sqr(x) - sqr(p.z - zb)), 0, zb] // Transition back to straight
|
||||
: q) // Circular section
|
||||
p
|
||||
];
|
||||
npoints = len(points);
|
||||
|
||||
module link(n) // Position and colour link with origin at the hinge hole
|
||||
translate([-z / 2, 0, -z / 2]) {
|
||||
stl_colour(n < 0 || n == npoints - 1 ? pp3_colour : n % 2 ? pp1_colour : pp2_colour)
|
||||
drag_chain_link(type, start = n == -1, end = n == npoints - 1, check_kids = false)
|
||||
let($fasteners = 0) children();
|
||||
let($fasteners = 1) children();
|
||||
}
|
||||
|
||||
screws = drag_chain_screw_lists(type);
|
||||
custom_start = screws[0] == [0, 0, 0, 0];
|
||||
custom_end = screws[1] == [0, 0, 0, 0];
|
||||
assert($children == bool2int(custom_start) + bool2int(custom_end), str("wrong number of children for end customisation: ", $children));
|
||||
|
||||
for(i = [0 : npoints - 2]) let(v = points[i + 1] - points[i])
|
||||
translate(points[i])
|
||||
rotate([0, -atan2(v.z, v.x), 0])
|
||||
link(i);
|
||||
|
||||
translate(points[0] - [x, 0, 0])
|
||||
link(-1)
|
||||
if(custom_start)
|
||||
children(0);
|
||||
|
||||
translate(points[npoints - 1])
|
||||
hflip()
|
||||
link(npoints - 1)
|
||||
if(custom_end)
|
||||
children(custom_start ? 1 : 0);
|
||||
}
|
||||
|
||||
//! 1. Remove the support material from the links with side cutters.
|
||||
//! 1. Clip the links together with the special ones at the ends.
|
||||
module drag_chain_assembly(type, pos = 0) //! Drag chain assembly
|
||||
assembly(str(drag_chain_name(type), "_drag_chain"), big = true)
|
||||
if($children == 2)
|
||||
_drag_chain_assembly(type, pos) {
|
||||
children(0);
|
||||
children(1);
|
||||
}
|
||||
else if($children == 1)
|
||||
_drag_chain_assembly(type, pos)
|
||||
children(0);
|
||||
else
|
||||
_drag_chain_assembly(type, pos);
|
50
printed/press_fit.scad
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Utility for making printed press fit connectors to join printed parts.
|
||||
//!
|
||||
//! Add solvent or glue to make a permanent fixture.
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
interference = 0.0;
|
||||
|
||||
bridge_droop = layer_height; //sqrt(4 * layer_height * filament_width / PI) - layer_height;
|
||||
|
||||
module press_fit_socket(w = 5, h = 50, horizontal = false) { //! Make a square hole to accept a peg
|
||||
h = horizontal ? h : h + bridge_droop;
|
||||
|
||||
cube([w, w, 2 * h], center = true);
|
||||
}
|
||||
|
||||
module press_fit_peg(h, w = 5, horizontal = false) { //! Make a rounded chamfered peg for easy insertion
|
||||
module chamfered_square(w, horizontal) {
|
||||
h = horizontal ? w - bridge_droop : w;
|
||||
rounded_square([w, h], 1);
|
||||
}
|
||||
|
||||
translate_z(-eps)
|
||||
linear_extrude(height = h + eps - layer_height)
|
||||
chamfered_square(w + interference, horizontal);
|
||||
|
||||
translate_z(h - layer_height - eps)
|
||||
linear_extrude(height = layer_height + eps)
|
||||
chamfered_square(w - layer_height, horizontal);
|
||||
}
|
@@ -81,7 +81,7 @@ module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of
|
||||
}
|
||||
}
|
||||
|
||||
module ribbon_clamp_assembly(ways, screw) pose([55, 180, 25]) //! Printed part with inserts in place
|
||||
module ribbon_clamp_assembly(ways, screw = screw) pose([55, 180, 25]) //! Printed part with inserts in place
|
||||
assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : "")) {
|
||||
h = ribbon_clamp_height(screw);
|
||||
insert = screw_insert(screw);
|
||||
@@ -117,9 +117,13 @@ module ribbon_clamp_fastened_assembly(ways, thickness, screw = screw) { //! Clam
|
||||
|
||||
module ribbon_clamp_20_stl() ribbon_clamp(20);
|
||||
module ribbon_clamp_8_2_stl() ribbon_clamp(8, M2_dome_screw);
|
||||
module ribbon_clamp_7_2_stl() ribbon_clamp(8, M2_dome_screw);
|
||||
|
||||
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
module ribbon_clamp_20_assembly() ribbon_clamp_assembly(20);
|
||||
|
||||
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
module ribbon_clamp_8_2_assembly() ribbon_clamp_assembly(8, M2_dome_screw);
|
||||
|
||||
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
module ribbon_clamp_7_2_assembly() ribbon_clamp_assembly(8, M2_dome_screw);
|
||||
|
313
readme.md
@@ -23,27 +23,28 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||
<tr><td> <a href = "#Axials">Axials</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
|
||||
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#KP_pillow_blocks">KP_pillow_blocks</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
|
||||
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
|
||||
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
|
||||
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
|
||||
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td></td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
@@ -207,7 +208,7 @@ exposing enough information to make a battery box.
|
||||
<a name="Belts"></a>
|
||||
## Belts
|
||||
Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
|
||||
Only models 2D paths, so not core XY!
|
||||
Only models 2D paths, so not crossed belt core XY!
|
||||
|
||||
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||
|
||||
@@ -249,15 +250,16 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```belt(GT2x6, [ ... ])``` | Belt GT2 x 6mm x 128mm |
|
||||
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 696mm |
|
||||
| 2 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 572mm |
|
||||
| 1 | ```belt(T2p5x6, [ ... ])``` | Belt T2.5 x 6mm x 130mm |
|
||||
| 1 | ```belt(T5x10, [ ... ])``` | Belt T5 x 10mm x 130mm |
|
||||
| 1 | ```belt(T5x6, [ ... ])``` | Belt T5 x 6mm x 130mm |
|
||||
| 1 | ```insert(F1BM3)``` | Heatfit insert M3 |
|
||||
| 2 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
|
||||
| 2 | ```insert(F1BM3)``` | Heatfit insert M3 |
|
||||
| 2 | ```pulley(GT2x16_toothed_idler)``` | Pulley GT2 idler 16 teeth |
|
||||
| 4 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
|
||||
| 2 | ```pulley(GT2x16_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 2 | ```pulley(GT2x20ob_pulley)``` | Pulley GT2OB 20 teeth |
|
||||
| 1 | ```screw(M3_cs_cap_screw, 20)``` | Screw M3 cs cap x 20mm |
|
||||
| 2 | ```screw(M3_cs_cap_screw, 20)``` | Screw M3 cs cap x 20mm |
|
||||
| 4 | ```screw(M3_grub_screw, 6)``` | Screw M3 grub x 6mm |
|
||||
|
||||
|
||||
@@ -294,11 +296,18 @@ Models of radial blowers.
|
||||
| ```blower_wall(type)``` | Side wall thickness |
|
||||
| ```blower_width(type)``` | Width of enclosing rectangle |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```blower_casing_is_square(type)``` | True for square radial fans, false for spiral shape radial blowers |
|
||||
| ```blower_exit_offset(type)``` | Offset of exit's centre from the edge |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```blower(type)``` | Draw specified blower |
|
||||
| ```blower_hole_positions(type)``` | Translate children to screw hole positions |
|
||||
| ```blower_square(type)``` | Draw a square blower |
|
||||
|
||||

|
||||
|
||||
@@ -307,8 +316,11 @@ 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 |
|
||||
| 3 | ```screw(M3_cap_screw, 20)``` | Screw M3 cap x 20mm |
|
||||
| 2 | ```screw(M4_cap_screw, 25)``` | Screw M4 cap x 25mm |
|
||||
| 1 | ```blower(BL40x10)``` | Square radial 4010 |
|
||||
| 4 | ```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 |
|
||||
|
||||
@@ -462,8 +474,8 @@ PCB cameras.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```camera(type)``` | Draw specified PCB camera |
|
||||
| ```camera_lens(type, offset = 0)``` | Draw the lens stack, with optional offset for making a clearance hole |
|
||||
| ```camera(type, show_lens = true)``` | Draw specified PCB camera |
|
||||
| ```camera_lens(type, offset = 0, show_lens = true)``` | Draw the lens stack, with optional offset for making a clearance hole |
|
||||
|
||||

|
||||
|
||||
@@ -756,6 +768,7 @@ LCD dispays.
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```display(BigTreeTech_TFT35v3_0)``` | BigTreeTech TFT35 v3.0 |
|
||||
| 1 | ```display(HDMI5)``` | HDMI display 5" |
|
||||
| 1 | ```display(LCD1602A)``` | LCD display 1602A |
|
||||
| 1 | ```display(LCDS7282B)``` | LCD display S-7282B |
|
||||
@@ -1104,7 +1117,7 @@ Needs updating as mostly obsolete versions.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0])``` | Draw specified hot end |
|
||||
| ```hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false)``` | Draw specified hot end |
|
||||
|
||||

|
||||
|
||||
@@ -2642,6 +2655,7 @@ Timing belt pulleys, both toothed and plain with internal bearings for idlers.
|
||||
| 1 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
|
||||
| 1 | ```pulley(GT2x20_plain_idler)``` | Pulley GT2 idler smooth 12mm |
|
||||
| 1 | ```pulley(GT2x16_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 1 | ```pulley(GT2x16x7_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 1 | ```pulley(GT2x20ob_pulley)``` | Pulley GT2OB 20 teeth |
|
||||
| 1 | ```pulley(GT2x12_pulley)``` | Pulley GT2RD 12 teeth |
|
||||
| 1 | ```pulley(GT2x20um_pulley)``` | Pulley GT2UM 20 teeth |
|
||||
@@ -2693,6 +2707,7 @@ Linear rails with carriages.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```carriage_screw_depth(type)``` | Carriage thread depth |
|
||||
| ```rail_holes(type, length)``` | Number of holes in a rail given its ```length``` |
|
||||
| ```rail_screw_height(type, screw)``` | Position screw taking into account countersink into counterbored hole |
|
||||
| ```rail_travel(type, length)``` | How far the carriage can travel |
|
||||
|
||||
@@ -2889,6 +2904,8 @@ These items are sysmtrical, so by default the origin is in the centre but it can
|
||||
## Screws
|
||||
Machine screws and wood screws with various head styles.
|
||||
|
||||
For an explanation of ```screw_polysink()``` see <https://hydraraptor.blogspot.com/2020/12/sinkholes.html>.
|
||||
|
||||
|
||||
[vitamins/screws.scad](vitamins/screws.scad) Object definitions.
|
||||
|
||||
@@ -2915,9 +2932,10 @@ Machine screws and wood screws with various head styles.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```screw_boss_diameter(type)``` | Boss big enough for nut trap and washer |
|
||||
| ```screw_head_depth(type, d)``` | How far a counter sink head will go into a straight hole diameter d |
|
||||
| ```screw_head_depth(type, d = 0)``` | How far a counter sink head will go into a straight hole diameter d |
|
||||
| ```screw_longer_than(x)``` | Returns shortest screw length longer or equal to x |
|
||||
| ```screw_nut_radius(type)``` | Radius of matching nut |
|
||||
| ```screw_polysink_r(type, z)``` | Countersink hole profile corrected for rounded staircase extrusions. |
|
||||
| ```screw_shorter_than(x)``` | Returns longest screw length shorter than or equal to x |
|
||||
|
||||
### Modules
|
||||
@@ -2925,7 +2943,8 @@ Machine screws and wood screws with various head styles.
|
||||
|:--- |:--- |
|
||||
| ```screw(type, length, hob_point = 0, nylon = false)``` | Draw specified screw, optionally hobbed or nylon |
|
||||
| ```screw_and_washer(type, length, star = false, penny = false)``` | Screw with a washer which can be standard or penny and an optional star washer on top |
|
||||
| ```screw_countersink(type)``` | Countersink shape |
|
||||
| ```screw_countersink(type, drilled = true)``` | Countersink shape |
|
||||
| ```screw_polysink(type, h = 100, alt = false)``` | A countersink hole made from stacked polyholes for printed parts |
|
||||
|
||||

|
||||
|
||||
@@ -2964,6 +2983,11 @@ Machine screws and wood screws with various head styles.
|
||||
| 1 | ```screw(No6_cs_screw, 30)``` | Screw No6 cs wood x 30mm |
|
||||
| 1 | ```screw(No6_screw, 30)``` | Screw No6 pan wood x 30mm |
|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 1 | polysink.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
@@ -3053,6 +3077,41 @@ Sealing strip from B&Q used to seal around the door of 3D printers.
|
||||
| 1 | ```sealing_strip(100)``` | Sealing strip 10mm x 4mm x 100mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Shaft_couplings"></a>
|
||||
## Shaft_couplings
|
||||
Shaft couplings
|
||||
|
||||
|
||||
[vitamins/shaft_couplings.scad](vitamins/shaft_couplings.scad) Object definitions.
|
||||
|
||||
[vitamins/shaft_coupling.scad](vitamins/shaft_coupling.scad) Implementation.
|
||||
|
||||
[tests/shaft_couplings.scad](tests/shaft_couplings.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```sc_diameter(type)``` | Coupling outer diameter |
|
||||
| ```sc_diameter1(type)``` | Diameter of smaller shaft |
|
||||
| ```sc_diameter2(type)``` | Diameter of larger shaft |
|
||||
| ```sc_length(type)``` | Coupling length |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```shaft_coupling(type, colour = "silver")``` | Draw the shaft coupling |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```shaft_coupling(SC_5x8_rigid)``` | Shaft coupling SC_5x8_rigid |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -3652,6 +3711,7 @@ Tubing and sleeving. The internal diameter can be forced to stretch it over some
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```tubing(CBNFIB10)``` | Carbon fiber OD 10mm ID 8mm x 15mm |
|
||||
| 1 | ```tubing(HSHRNK16)``` | Heatshrink sleeving ID 1.6mm x 15mm |
|
||||
| 1 | ```tubing(HSHRNK100)``` | Heatshrink sleeving ID 10mm x 15mm |
|
||||
| 1 | ```tubing(HSHRNK24)``` | Heatshrink sleeving ID 2.4mm x 15mm |
|
||||
@@ -4223,6 +4283,72 @@ of conductive panels, an extra layer of insulation.
|
||||
| 1 | round_grommet_top_60_3.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Camera_housing"></a>
|
||||
## Camera_housing
|
||||
Housings for PCB cameras.
|
||||
|
||||
|
||||
[printed/camera_housing.scad](printed/camera_housing.scad) Implementation.
|
||||
|
||||
[tests/camera_housing.scad](tests/camera_housing.scad) Code for this example.
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```cam_front_size(cam)``` | Outside dimensions of the case |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```camera_assembly(cam, angle = 0)``` | Camera case assembly |
|
||||
| ```camera_back(cam)``` | Make the STL for a camera case back |
|
||||
| ```camera_bracket(cam)``` | Make the STL for the camera bracket |
|
||||
| ```camera_bracket_position(cam)``` | Position children at the bracket position |
|
||||
| ```camera_bracket_screw_positions(cam)``` | Position children at the bracket screw positions |
|
||||
| ```camera_front(cam, hinge = 0)``` | Make the STL for a camera case front |
|
||||
| ```rpi_camera_focus_ring_stl()``` | Focus ring the glue onto RPI lens |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 7 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
|
||||
| 10 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 1 | ```camera(rpi_camera_v1)``` | Raspberry Pi camera V1 |
|
||||
| 1 | ```camera(rpi_camera_v2)``` | Raspberry Pi camera V2 |
|
||||
| 1 | ```camera(rpi_camera)``` | Raspberry Pi focusable camera |
|
||||
| 7 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
|
||||
| 4 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
|
||||
| 4 | ```screw(M3_dome_screw, 10)``` | Screw M3 dome x 10mm |
|
||||
| 2 | ```screw(M3_dome_screw, 12)``` | Screw M3 dome x 12mm |
|
||||
| 7 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
|
||||
| 16 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 1 | camera_back_rpi_camera.stl |
|
||||
| 1 | camera_back_rpi_camera_v1.stl |
|
||||
| 1 | camera_back_rpi_camera_v2.stl |
|
||||
| 1 | camera_bracket_rpi_camera.stl |
|
||||
| 1 | camera_bracket_rpi_camera_v1.stl |
|
||||
| 1 | camera_bracket_rpi_camera_v2.stl |
|
||||
| 1 | camera_front_rpi_camera.stl |
|
||||
| 1 | camera_front_rpi_camera_v1.stl |
|
||||
| 1 | camera_front_rpi_camera_v2.stl |
|
||||
|
||||
### Assemblies
|
||||
| Qty | Name |
|
||||
| ---:|:--- |
|
||||
| 1 | camera_rpi_camera_assembly |
|
||||
| 1 | camera_rpi_camera_v1_assembly |
|
||||
| 1 | camera_rpi_camera_v2_assembly |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -4433,6 +4559,73 @@ Door latch for 6mm acrylic door for 3D printer. See [door_hinge](#door_hinge).
|
||||
| 1 | door_latch.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Drag_chain"></a>
|
||||
## Drag_chain
|
||||
Parametric cable drag chain to limit the bend radius of a cable run.
|
||||
|
||||
Each link has a maximum bend angle of 45°, so the mininium radius is proportional to the link length.
|
||||
|
||||
The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
|
||||
|
||||
The ends can have screw lugs with four screw positions to choose from, specified by a list of two arrays of four bools.
|
||||
If none are enabled then a child object is expected to customise the end and this gets unioned with the blank end.
|
||||
If both ends are customised then two children are expected.
|
||||
Each child is called twice, once with ```$fasteners``` set to 0 to augment the STL and again with ```$fasteners``` set to 1 to add
|
||||
to the assembly, for example to add inserts.
|
||||
|
||||
|
||||
[printed/drag_chain.scad](printed/drag_chain.scad) Implementation.
|
||||
|
||||
[tests/drag_chain.scad](tests/drag_chain.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```drag_chain_bwall(type)``` | Bottom wall |
|
||||
| ```drag_chain_name(type)``` | The name to allow more than one in a project |
|
||||
| ```drag_chain_screw(type)``` | Mounting screw for the ends |
|
||||
| ```drag_chain_screw_lists(type)``` | Two lists of four bools to say which screws positions are used |
|
||||
| ```drag_chain_size(type)``` | The internal size and link length |
|
||||
| ```drag_chain_travel(type)``` | X travel |
|
||||
| ```drag_chain_twall(type)``` | Top wall |
|
||||
| ```drag_chain_wall(type)``` | Side wall thickness |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```drag_chain(name, size, travel, wall = 1.6, bwall = 1.5, twall = 1.5, screw = M2_cap_screw, screw_lists = [[1,0,0,1],[1,0,0,1]])``` | Constructor |
|
||||
| ```drag_chain_clearance()``` | Clearance around joints. |
|
||||
| ```drag_chain_outer_size(type)``` | Link outer dimensions |
|
||||
| ```drag_chain_radius(type)``` | The bend radius at the pivot centres |
|
||||
| ```drag_chain_z(type)``` | Outside dimension of a 180 bend |
|
||||
| ```screw_lug_radius(screw)``` | Radius of a screw lug |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```drag_chain_assembly(type, pos = 0)``` | Drag chain assembly |
|
||||
| ```drag_chain_link(type, start = false, end = false, check_kids = true)``` | One link of the chain, special case for start and end |
|
||||
| ```drag_chain_screw_positions(type, end)``` | Place children at the screw positions, end = 0 for the start, 1 for the end |
|
||||
| ```screw_lug(screw, h = 0)``` | Create a D shaped lug for a screw |
|
||||
|
||||

|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 14 | x_drag_chain_link.stl |
|
||||
| 1 | x_drag_chain_link_end.stl |
|
||||
| 1 | x_drag_chain_link_start.stl |
|
||||
|
||||
### Assemblies
|
||||
| Qty | Name |
|
||||
| ---:|:--- |
|
||||
| 1 | x_drag_chain_assembly |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -4794,6 +4987,29 @@ The stl must be given a parameterless wrapper in the project that uses it.
|
||||
| 1 | pcb_mount_PI_IO_5.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Press_fit"></a>
|
||||
## Press_fit
|
||||
Utility for making printed press fit connectors to join printed parts.
|
||||
|
||||
Add solvent or glue to make a permanent fixture.
|
||||
|
||||
|
||||
[printed/press_fit.scad](printed/press_fit.scad) Implementation.
|
||||
|
||||
[tests/press_fit.scad](tests/press_fit.scad) Code for this example.
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```press_fit_peg(h, w = 5, horizontal = false)``` | Make a rounded chamfered peg for easy insertion |
|
||||
| ```press_fit_socket(w = 5, h = 50, horizontal = false)``` | Make a square hole to accept a peg |
|
||||
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -4961,7 +5177,7 @@ Clamp for ribbon cable and polypropylene strip.
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```ribbon_clamp(ways, screw = screw)``` | Generate STL for given number of ways |
|
||||
| ```ribbon_clamp_assembly(ways, screw)``` | Printed part with inserts in place |
|
||||
| ```ribbon_clamp_assembly(ways, screw = screw)``` | Printed part with inserts in place |
|
||||
| ```ribbon_clamp_fastened_assembly(ways, thickness, screw = screw)``` | Clamp with fasteners in place |
|
||||
| ```ribbon_clamp_hole_positions(ways, screw = screw, side = undef)``` | Place children at hole positions |
|
||||
| ```ribbon_clamp_holes(ways, h = 20, screw = screw)``` | Drill screw holes |
|
||||
@@ -5295,8 +5511,10 @@ a square cornered part fits in the hole then circles are placed in the corners m
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```dogbone_rectangle(size, r = cnc_bit_r, center = true, xy_center = true)``` | Rectangle with cylinders at the corners |
|
||||
| ```dogbone_square(size, r = cnc_bit_r, center = true)``` | Square with circles at the corners |
|
||||
| ```dogbone_rectangle(size, r = cnc_bit_r, center = true, xy_center = true, x_offset, y_offset)``` | Rectangle with cylinders at the corners |
|
||||
| ```dogbone_rectangle_x(size, r = cnc_bit_r, center = true, xy_center = true)``` | Rectangle with cylinders at the corners, offset in the x direction |
|
||||
| ```dogbone_rectangle_y(size, r = cnc_bit_r, center = true, xy_center = true)``` | Rectangle with cylinders at the corners, offset in the y direction |
|
||||
| ```dogbone_square(size, r = cnc_bit_r, center = true, x_offset, y_offset)``` | Square with circles at the corners, with optional offsets |
|
||||
|
||||

|
||||
|
||||
@@ -5645,7 +5863,7 @@ A sector of a circle between two angles.
|
||||
Utility to generate a polhedron by sweeping a 2D profile along a 3D path and utilities for generating paths.
|
||||
|
||||
The initial orientation is the Y axis of the profile points towards the initial center of curvature, Frenet-Serret style.
|
||||
This means the first three points must not be colinear. Subsequent rotations use the minimum rotation method.
|
||||
Subsequent rotations use the minimum rotation method.
|
||||
|
||||
The path can be open or closed. If closed sweep ensures that the start and end have the same rotation to line up.
|
||||
An additional twist around the path can be specified. If the path is closed this should be a multiple of 360.
|
||||
@@ -5740,6 +5958,7 @@ Simple tube or ring
|
||||
|:--- |:--- |
|
||||
| ```ring(or, ir)``` | Create a ring with specified external and internal radii |
|
||||
| ```tube(or, ir, h, center = true)``` | Create a tube with specified external and internal radii and height ```h``` |
|
||||
| ```woven_tube(or, ir, h, center= true, colour = grey(30)``` | Create a woven tube with specified external and internal radii, height ```h```, colours, warp and weft |
|
||||
|
||||

|
||||
|
||||
@@ -5880,11 +6099,12 @@ Global constants, functions and modules. This file is used directly or indirectl
|
||||
| ```circle4n(r, d = undef)``` | Circle with multiple of 4 vertices |
|
||||
| ```ellipse(xr, yr)``` | Draw an ellipse |
|
||||
| ```extrude_if(h, center = true)``` | Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D |
|
||||
| ```hflip()``` | Invert children by doing a 180° flip around the Y axis |
|
||||
| ```hflip(flip=true)``` | Invert children by doing a 180° flip around the Y axis |
|
||||
| ```render_if(render = true, convexity = 2)``` | Renders an object if ```render``` is true, otherwise leaves it unrendered |
|
||||
| ```right_triangle(width, height, h, center = true)``` | A right angled triangle with the 90° corner at the origin. 3D when ```h``` is nonzero, otherwise 2D |
|
||||
| ```semi_circle(r, d = undef)``` | A semi circle in the positive Y domain |
|
||||
| ```translate_z(z)``` | Shortcut for Z only translations |
|
||||
| ```vflip()``` | Invert children by doing a 180° flip around the X axis |
|
||||
| ```vflip(flip=true)``` | Invert children by doing a 180° flip around the X axis |
|
||||
|
||||

|
||||
|
||||
@@ -5899,6 +6119,16 @@ it gets the linear dimensions right. See <https://hydraraptor.blogspot.com/2011/
|
||||
|
||||
The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is useful for making printed washers and pillars.
|
||||
|
||||
`poly_cylinder()` has a `twist` parameter which can be set to make the polygon rotate each layer.
|
||||
This can be used to mitigate the number of sides being small and make small holes stronger and more round, but is quite slow due to the
|
||||
large increase in the number of facets.
|
||||
When set to 1 the polygons alternate each layer, when set higher the rotation takes `twist + 1` layers to repeat.
|
||||
A small additional rotation is added to make the polygon rotate one more side over the length of the hole to make it appear round when
|
||||
veiwed end on.
|
||||
|
||||
When `twist` is set the resulting cylinder is extended by `eps` at each end so that the exact length of the hole can be used without
|
||||
leaving a scar on either surface.
|
||||
|
||||
|
||||
[utils/core/polyholes.scad](utils/core/polyholes.scad) Implementation.
|
||||
|
||||
@@ -5916,7 +6146,7 @@ The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is
|
||||
|:--- |:--- |
|
||||
| ```drill(r, h = 100, center = true)``` | Make a cylinder for drilling holes suitable for CNC routing, set h = 0 for circle |
|
||||
| ```poly_circle(r, sides = 0)``` | Make a circle adjusted to print the correct size |
|
||||
| ```poly_cylinder(r, h, center = false, sides = 0, chamfer = false)``` | Make a cylinder adjusted to print the correct size |
|
||||
| ```poly_cylinder(r, h, center = false, sides = 0, chamfer = false, twist = 0)``` | Make a cylinder adjusted to print the correct size |
|
||||
| ```poly_drill(r, h = 100, center = true)``` | Make a cylinder for drilling holes suitable for CNC routing if cnc_bit_r is non zero, otherwise a poly_cylinder. |
|
||||
| ```poly_ring(or, ir, sides = 0)``` | Make a 2D ring adjusted to have the correct internal radius |
|
||||
| ```poly_tube(or, ir, h, center = false)``` | Make a tube adjusted to have the correct internal radius |
|
||||
@@ -5950,6 +6180,11 @@ The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is
|
||||
| 1 | ```rod(9.5, 43)``` | Smooth rod 9.5mm x 43mm |
|
||||
| 1 | ```rod(9, 41)``` | Smooth rod 9mm x 41mm |
|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 1 | polyhole.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
@@ -5967,6 +6202,8 @@ Rectangle with rounded corners.
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```rounded_rectangle(size, r, center = true, xy_center = true)``` | Like ```cube()``` but corners rounded in XY plane and separate centre options for xy and z. |
|
||||
| ```rounded_rectangle_xz(size, r, center = true, xy_center = true)``` | Like ```cube()``` but corners rounded in XZ plane and separate centre options for xy and z. |
|
||||
| ```rounded_rectangle_yz(size, r, center = true, xy_center = true)``` | Like ```cube()``` but corners rounded in YX plane and separate centre options for xy and z. |
|
||||
| ```rounded_square(size, r, center = true)``` | Like ```square()``` but with with rounded corners |
|
||||
|
||||

|
||||
|
@@ -87,24 +87,25 @@ def plateup(target, part_type, usage = None):
|
||||
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
|
||||
if match:
|
||||
used.append(match.group(1))
|
||||
#
|
||||
# Copy file that are not included
|
||||
#
|
||||
copied = []
|
||||
for file in os.listdir(parts_dir):
|
||||
if file.endswith('.' + part_type) and not file in used:
|
||||
src = parts_dir + '/' + file
|
||||
dst = target_dir + '/' + file
|
||||
if mtime(src) > mtime(dst):
|
||||
print("Copying %s to %s" % (src, dst))
|
||||
copyfile(src, dst)
|
||||
copied.append(file)
|
||||
#
|
||||
# Remove any cruft
|
||||
#
|
||||
targets = [file[:-4] + part_type for file in all_sources]
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.' + part_type):
|
||||
if not file in targets and not file in copied:
|
||||
print("Removing %s" % file)
|
||||
os.remove(target_dir + '/' + file)
|
||||
if all_sources:
|
||||
#
|
||||
# Copy files that are not included
|
||||
#
|
||||
for file in os.listdir(parts_dir):
|
||||
if file.endswith('.' + part_type) and not file in used:
|
||||
src = parts_dir + '/' + file
|
||||
dst = target_dir + '/' + file
|
||||
if mtime(src) > mtime(dst):
|
||||
print("Copying %s to %s" % (src, dst))
|
||||
copyfile(src, dst)
|
||||
copied.append(file)
|
||||
#
|
||||
# Remove any cruft
|
||||
#
|
||||
targets = [file[:-4] + part_type for file in all_sources]
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.' + part_type):
|
||||
if not file in targets and not file in copied:
|
||||
print("Removing %s" % file)
|
||||
os.remove(target_dir + '/' + file)
|
||||
|
@@ -308,8 +308,7 @@ def views(target, do_assemblies = None):
|
||||
if printed:
|
||||
print('### 3D Printed parts', file = doc_file)
|
||||
keys = sorted(list(printed.keys()))
|
||||
for i in range(len(keys)):
|
||||
p = keys[i]
|
||||
for i, p in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p]["count"], p), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(printed) - 1:
|
||||
n = (i % 3) + 1
|
||||
@@ -324,8 +323,7 @@ def views(target, do_assemblies = None):
|
||||
if routed:
|
||||
print("### CNC Routed parts", file = doc_file)
|
||||
keys = sorted(list(routed.keys()))
|
||||
for i in range(len(keys)):
|
||||
r = keys[i]
|
||||
for i, r in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r]["count"], r), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(routed) - 1:
|
||||
n = (i % 3) + 1
|
||||
@@ -340,8 +338,7 @@ def views(target, do_assemblies = None):
|
||||
if sub_assemblies:
|
||||
print("### Sub-assemblies", file = doc_file)
|
||||
keys = sorted(list(sub_assemblies.keys()))
|
||||
for i in range(len(keys)):
|
||||
a = keys[i]
|
||||
for i, a in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(keys) - 1:
|
||||
n = (i % 3) + 1
|
||||
|
@@ -23,46 +23,52 @@ use <../vitamins/insert.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module belt_test() {
|
||||
p1 = [75, -50];
|
||||
p2 = [-75, -50];
|
||||
p3 = [-75, 100];
|
||||
p4 = [75, 100];
|
||||
|
||||
p5 = [75 - pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
|
||||
translate(p1) pulley_assembly(GT2x20ob_pulley);
|
||||
translate(p2) pulley_assembly(GT2x20ob_pulley);
|
||||
translate(p3) pulley_assembly(GT2x20_toothed_idler);
|
||||
translate(p4) pulley_assembly(GT2x20_toothed_idler);
|
||||
module pulleys(flip = false) {
|
||||
translate(p2) rotate([0, flip ? 180 : 0, 0]) pulley_assembly(GT2x20ob_pulley);
|
||||
translate(p3) pulley_assembly(GT2x20_toothed_idler);
|
||||
translate(p4) pulley_assembly(GT2x20_toothed_idler);
|
||||
translate(p5) {
|
||||
pulley = GT2x16_toothed_idler;
|
||||
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
|
||||
insert = screw_insert(screw);
|
||||
|
||||
translate(p5) {
|
||||
pulley = GT2x16_plain_idler;
|
||||
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
|
||||
insert = screw_insert(screw);
|
||||
|
||||
pulley_assembly(pulley);
|
||||
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
|
||||
screw(screw, 20);
|
||||
|
||||
translate_z(pulley_offset(pulley) - insert_length(insert))
|
||||
vflip()
|
||||
insert(insert);
|
||||
hflip(flip) {
|
||||
pulley_assembly(pulley);
|
||||
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
|
||||
screw(screw, 20);
|
||||
|
||||
translate_z(pulley_offset(pulley) - insert_length(insert))
|
||||
vflip()
|
||||
insert(insert);
|
||||
}
|
||||
}
|
||||
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
||||
}
|
||||
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
||||
|
||||
path = [ [p1.x, p1.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p5.x, p5.y, -pulley_pr(GT2x16_plain_idler)],
|
||||
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
|
||||
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
|
||||
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
|
||||
];
|
||||
|
||||
belt = GT2x6;
|
||||
belt(belt, path, 80, [0, 0]);
|
||||
pulleys();
|
||||
translate_z(20)
|
||||
hflip() {
|
||||
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
|
||||
pulleys(flip=true);
|
||||
}
|
||||
|
||||
translate([-25, 0])
|
||||
translate([-25, 0, 10])
|
||||
layout([for(b = belts) belt_width(b)], 10)
|
||||
rotate([0, 90, 0])
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
|
||||
|
33
tests/camera_housing.scad
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
use <../printed/camera_housing.scad>
|
||||
|
||||
include <../vitamins/cameras.scad>
|
||||
|
||||
use <../vitamins/pcb.scad>
|
||||
|
||||
module camera_housings()
|
||||
layout([for(c = cameras) pcb_length(camera_pcb(c))], 15, false) let(c = cameras[$i])
|
||||
camera_fastened_assembly(c, 3);
|
||||
|
||||
if($preview)
|
||||
camera_housings();
|
@@ -24,7 +24,7 @@ include <../vitamins/cameras.scad>
|
||||
use <../vitamins/pcb.scad>
|
||||
|
||||
module cameras()
|
||||
layout([for(c = cameras) pcb_length(camera_pcb(c))], 10, false) let(c = cameras[$i])
|
||||
layout([for(c = cameras) pcb_length(camera_pcb(c))], 15, false) let(c = cameras[$i])
|
||||
camera(c);
|
||||
|
||||
if($preview)
|
||||
|
@@ -26,6 +26,12 @@ module dogbones() {
|
||||
#translate([15, 0])
|
||||
dogbone_rectangle([10, 20, 5], center = false);
|
||||
|
||||
#translate([30, 0])
|
||||
dogbone_rectangle_x([10, 20, 5], center = false);
|
||||
|
||||
#translate([45, 0])
|
||||
dogbone_rectangle_y([10, 20, 5], center = false);
|
||||
|
||||
sq = 3;
|
||||
translate([-5 + sq / 2 + eps, -10 + sq / 2 + eps])
|
||||
%cube([sq, sq, 1], center = true);
|
||||
|
59
tests/drag_chain.scad
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// Link length between hinges
|
||||
x = 10; //[8 : 30]
|
||||
|
||||
// Link inner width
|
||||
y = 10; //[5 : 30]
|
||||
|
||||
// Link inner height
|
||||
z = 5; //[4 : 11]
|
||||
// Side wall thickness
|
||||
wall = 1.6; //[0.9: 0.1: 3]
|
||||
// Bottom wall thickness
|
||||
bwall = 1.5; //[1: 0.25: 3]
|
||||
// Top wall thickness
|
||||
twall = 1.5; //[1: 0.25: 3]
|
||||
// Max travel in each direction
|
||||
travel = 100;
|
||||
// Current position
|
||||
pos = 50; // [-100 : 1 : 100]
|
||||
|
||||
include <../core.scad>
|
||||
use <../printed/drag_chain.scad>
|
||||
|
||||
include <../vitamins/leadnuts.scad>
|
||||
|
||||
drag_chain = drag_chain("x", [x, y, z], travel, wall = wall, bwall = bwall, twall = twall);
|
||||
|
||||
module drag_chains()
|
||||
drag_chain_assembly(drag_chain, pos);
|
||||
|
||||
if($preview)
|
||||
drag_chains();
|
||||
else {
|
||||
drag_chain_link(drag_chain);
|
||||
|
||||
translate([-x * 2, 0])
|
||||
drag_chain_link(drag_chain, start = true);
|
||||
|
||||
translate([x * 2, 0])
|
||||
drag_chain_link(drag_chain, end = true);
|
||||
}
|
@@ -25,7 +25,7 @@ module hot_ends()
|
||||
layout([for(h = hot_ends) 40])
|
||||
translate([-20, 0])
|
||||
rotate(90)
|
||||
hot_end(hot_ends[$i], 3);
|
||||
hot_end(hot_ends[$i], 3, bowden = $i == 3);
|
||||
|
||||
if($preview)
|
||||
hot_ends();
|
||||
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 133 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 68 KiB |
BIN
tests/png/camera_housing.png
Normal file
After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 76 KiB |
BIN
tests/png/drag_chain.png
Normal file
After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 136 KiB |
BIN
tests/png/press_fit.png
Normal file
After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 148 KiB |
BIN
tests/png/shaft_couplings.png
Normal file
After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 181 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 26 KiB |
@@ -21,30 +21,60 @@ include <../utils/core/core.scad>
|
||||
use <../vitamins/rod.scad>
|
||||
include <../vitamins/sheets.scad>
|
||||
|
||||
module polyholes() {
|
||||
module positions()
|
||||
for(i = [1 : 10]) {
|
||||
translate([(i * i + i) / 2 + 3 * i , 8])
|
||||
let($r = i / 2)
|
||||
module positions()
|
||||
for(i = [1 : 10]) {
|
||||
translate([(i * i + i) / 2 + 3 * i , 8])
|
||||
let($r = i / 2)
|
||||
children();
|
||||
|
||||
let(d = i + 0.5)
|
||||
translate([(d * d + d) / 2 + 3 * d, 19])
|
||||
let($r = d / 2)
|
||||
children();
|
||||
}
|
||||
|
||||
let(d = i + 0.5)
|
||||
translate([(d * d + d) / 2 + 3 * d, 19])
|
||||
let($r = d / 2)
|
||||
children();
|
||||
}
|
||||
module polyhole_stl() {
|
||||
stl("polyhole");
|
||||
|
||||
stl_colour(pp1_colour) linear_extrude(3, center = true)
|
||||
linear_extrude(3, center = true)
|
||||
difference() {
|
||||
square([100, 27]);
|
||||
|
||||
positions()
|
||||
poly_circle(r = $r);
|
||||
}
|
||||
}
|
||||
|
||||
positions()
|
||||
module alt_polyhole_stl() {
|
||||
holes = [2.5, 2, 1.5];
|
||||
n = len(holes);
|
||||
size = [n * 10, 10, 10];
|
||||
difference() {
|
||||
translate([-size.x / n / 2, $preview ? 0 : -size.y / 2])
|
||||
cube($preview ? [size.x, size.y / 2, size.z] : size);
|
||||
|
||||
for(i = [0 : n - 1])
|
||||
translate([i * 10, 0])
|
||||
if(i % 2)
|
||||
translate_z(size.z)
|
||||
poly_cylinder(r = holes[i] / 2, h = 2 * size.z, center = true, twist = i + 1);
|
||||
else
|
||||
poly_cylinder(r = holes[i] / 2, h = size.z, center = false, twist = i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
module polyholes() {
|
||||
stl_colour(pp1_colour)
|
||||
polyhole_stl();
|
||||
|
||||
positions()
|
||||
rod(d = 2 * $r, l = 8 * $r + 5);
|
||||
//
|
||||
// Alternating polyholes
|
||||
//
|
||||
translate([30, -40])
|
||||
alt_polyhole_stl();
|
||||
//
|
||||
// Poly rings
|
||||
//
|
||||
ir = 3 / 2;
|
||||
@@ -74,4 +104,11 @@ module polyholes() {
|
||||
}
|
||||
}
|
||||
|
||||
polyholes();
|
||||
if($preview)
|
||||
polyholes();
|
||||
else {
|
||||
polyhole_stl();
|
||||
|
||||
translate([50, -20])
|
||||
alt_polyhole_stl();
|
||||
}
|
||||
|
71
tests/press_fit.scad
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
include <../printed/press_fit.scad>
|
||||
|
||||
module press_fits()
|
||||
{
|
||||
thickness = 2;
|
||||
width = 20;
|
||||
vthickness = 4;
|
||||
|
||||
translate([0, width + 2])
|
||||
difference() {
|
||||
cube([width, width, thickness]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x * width, y * width])
|
||||
press_fit_socket();
|
||||
}
|
||||
|
||||
union() {
|
||||
cube([width, width, thickness]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x * width, y * width, thickness])
|
||||
press_fit_peg(h = thickness);
|
||||
}
|
||||
|
||||
translate([width + 2, width + 2])
|
||||
difference() {
|
||||
cube([width, vthickness, width]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x, 0, y] * width)
|
||||
rotate([90, 0, 0])
|
||||
press_fit_socket();
|
||||
}
|
||||
|
||||
translate([width + 2, 0])
|
||||
union() {
|
||||
cube([width, width, thickness]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x * width, y * width, thickness])
|
||||
press_fit_peg(h = vthickness, horizontal = true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
press_fits();
|
@@ -23,6 +23,7 @@ use <../utils/layout.scad>
|
||||
use <../vitamins/nut.scad>
|
||||
|
||||
sheet = 3;
|
||||
pos = 1; //[-1 : 0.1 : 1]
|
||||
|
||||
module rails()
|
||||
layout([for(l = rails) carriage_width(rail_carriage(l))], 20)
|
||||
@@ -33,7 +34,7 @@ module rails()
|
||||
nut = screw_nut(screw);
|
||||
washer = screw_washer(screw);
|
||||
|
||||
rail_assembly(rail, length, rail_travel(rail, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
rail_assembly(rail, length, pos * rail_travel(rail, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
|
||||
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));
|
||||
|
||||
|
@@ -25,6 +25,12 @@ module rounded_rectangles() {
|
||||
|
||||
translate([40, 0])
|
||||
rounded_rectangle([30, 20, 10], 3);
|
||||
|
||||
translate([80, 0])
|
||||
rounded_rectangle_xz([30, 20, 10], 3);
|
||||
|
||||
translate([120, 0])
|
||||
rounded_rectangle_yz([30, 20, 10], 3);
|
||||
}
|
||||
|
||||
rounded_rectangles();
|
||||
|
@@ -18,20 +18,46 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
module screws()
|
||||
for(y = [0 : len(screw_lists) -1])
|
||||
for(x = [0 : len(screw_lists[y]) -1]) {
|
||||
screw = screw_lists[y][x];
|
||||
if(screw) {
|
||||
length = screw_head_type(screw) == hs_grub ? 6
|
||||
: screw_radius(screw) <= 1.5 ? 10
|
||||
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
|
||||
: 30;
|
||||
translate([x * 20, y * 20])
|
||||
screw(screw, length);
|
||||
}
|
||||
module polysink_stl() {
|
||||
stl("polysink");
|
||||
|
||||
cs_screws = [for(list = screw_lists, screw = list) if(screw_head_type(screw) == hs_cs_cap) screw];
|
||||
n = len(cs_screws);
|
||||
size = [n * 20, 20, 10];
|
||||
difference() {
|
||||
translate([-size.x / n / 2, $preview ? 0 : -size.y / 2])
|
||||
cube($preview ? [size.x, size.y / 2, size.z] : size);
|
||||
|
||||
for(i = [0 : n - 1])
|
||||
let(s = cs_screws[i])
|
||||
translate([i * 20, 0]) {
|
||||
translate_z(size.z)
|
||||
screw_polysink(s, 2 * size.z + 1);
|
||||
|
||||
screw_polysink(s, 2 * size.z + 1, alt = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module screws() {
|
||||
for(y = [0 : len(screw_lists) -1])
|
||||
for(x = [0 : len(screw_lists[y]) -1]) {
|
||||
screw = screw_lists[y][x];
|
||||
if(screw) {
|
||||
length = screw_head_type(screw) == hs_grub ? 6
|
||||
: screw_radius(screw) <= 1.5 ? 10
|
||||
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
|
||||
: 30;
|
||||
translate([x * 20, y * 20])
|
||||
screw(screw, length);
|
||||
}
|
||||
}
|
||||
translate([80, 20])
|
||||
polysink_stl();
|
||||
}
|
||||
|
||||
if($preview)
|
||||
let($show_threads = true)
|
||||
screws();
|
||||
else
|
||||
polysink_stl();
|
||||
|
30
tests/shaft_couplings.scad
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2018
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/shaft_couplings.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module shaft_couplings()
|
||||
layout([for(s = shaft_couplings) sc_diameter(s)],5)
|
||||
shaft_coupling(shaft_couplings[$i]);
|
||||
|
||||
if($preview)
|
||||
shaft_couplings();
|
||||
|
@@ -22,7 +22,7 @@ use <../utils/layout.scad>
|
||||
include <../vitamins/tubings.scad>
|
||||
|
||||
module tubings()
|
||||
layout([for(t = tubings) tubing_od(t)], 10)
|
||||
layout([for(t = tubings) tubing_od(t)], 8)
|
||||
tubing(tubings[$i]);
|
||||
|
||||
if($preview)
|
||||
|
@@ -39,8 +39,8 @@ function r2sides4n(r) = floor((r2sides(r) + 3) / 4) * 4;
|
||||
function limit(x, min, max) = max(min(x, max), min); //! Force x in range min <= x <= max
|
||||
|
||||
module translate_z(z) translate([0, 0, z]) children(); //! Shortcut for Z only translations
|
||||
module vflip() rotate([180, 0, 0]) children(); //! Invert children by doing a 180° flip around the X axis
|
||||
module hflip() rotate([0, 180, 0]) children(); //! Invert children by doing a 180° flip around the Y axis
|
||||
module vflip(flip=true) rotate([flip ? 180 : 0, 0, 0]) children(); //! Invert children by doing a 180° flip around the X axis
|
||||
module hflip(flip=true) rotate([0, flip ? 180: 0, 0]) children(); //! Invert children by doing a 180° flip around the Y axis
|
||||
module ellipse(xr, yr) scale([1, yr / xr]) circle4n(xr); //! Draw an ellipse
|
||||
|
||||
function slice_str(str, start, end, s ="") = start >= end ? s : slice_str(str, start + 1, end, str(s, str[start])); // Helper for slice()
|
||||
@@ -52,6 +52,13 @@ function slice(list, start = 0, end = undef) = let( //! Slice a list or string w
|
||||
) is_string(list) ? slice_str(list, start, end) : [for(i = [start : 1 : end - 1]) list[i]];
|
||||
|
||||
|
||||
module render_if(render = true, convexity = 2) //! Renders an object if ```render``` is true, otherwise leaves it unrendered
|
||||
if (render)
|
||||
render(convexity = convexity)
|
||||
children();
|
||||
else
|
||||
children();
|
||||
|
||||
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D
|
||||
if(h)
|
||||
linear_extrude(h, center = center, convexity = 2) // 3D
|
||||
|
@@ -22,6 +22,16 @@
|
||||
//! it gets the linear dimensions right. See <https://hydraraptor.blogspot.com/2011/02/polyholes.html>
|
||||
//!
|
||||
//! The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is useful for making printed washers and pillars.
|
||||
//!
|
||||
//! `poly_cylinder()` has a `twist` parameter which can be set to make the polygon rotate each layer.
|
||||
//! This can be used to mitigate the number of sides being small and make small holes stronger and more round, but is quite slow due to the
|
||||
//! large increase in the number of facets.
|
||||
//! When set to 1 the polygons alternate each layer, when set higher the rotation takes `twist + 1` layers to repeat.
|
||||
//! A small additional rotation is added to make the polygon rotate one more side over the length of the hole to make it appear round when
|
||||
//! veiwed end on.
|
||||
//!
|
||||
//! When `twist` is set the resulting cylinder is extended by `eps` at each end so that the exact length of the hole can be used without
|
||||
//! leaving a scar on either surface.
|
||||
//
|
||||
function sides(r) = max(round(4 * r), 3); //! Optimium number of sides for specified radius
|
||||
function corrected_radius(r, n = 0) = r / cos(180 / (n ? n : sides(r))); //! Adjusted radius to make flats lie on the circle
|
||||
@@ -32,9 +42,26 @@ module poly_circle(r, sides = 0) { //! Make a circle adjusted to print the corre
|
||||
circle(r = corrected_radius(r,n), $fn = n);
|
||||
}
|
||||
|
||||
module poly_cylinder(r, h, center = false, sides = 0, chamfer = false) {//! Make a cylinder adjusted to print the correct size
|
||||
extrude_if(h, center)
|
||||
poly_circle(r, sides);
|
||||
module poly_cylinder(r, h, center = false, sides = 0, chamfer = false, twist = 0) {//! Make a cylinder adjusted to print the correct size
|
||||
if(twist) {
|
||||
slices = ceil(h / layer_height);
|
||||
twists = min(twist + 1, slices);
|
||||
sides = sides ? sides : sides(r);
|
||||
rot = 360 / sides / twists * (twists < slices ? (1 + 1 / slices) : 1);
|
||||
if(center)
|
||||
for(side = [0, 1])
|
||||
mirror([0, 0, side])
|
||||
poly_cylinder(r = r, h = h / 2, sides = sides, twist = twist);
|
||||
else
|
||||
render(convexity = 5)
|
||||
for(i = [0 : slices - 1])
|
||||
translate_z(i * layer_height - eps)
|
||||
rotate(rot * i)
|
||||
poly_cylinder(r = r, h = layer_height + 2 * eps, sides = sides);
|
||||
}
|
||||
else
|
||||
extrude_if(h, center)
|
||||
poly_circle(r, sides);
|
||||
|
||||
if(h && chamfer)
|
||||
poly_cylinder(r + layer_height, center ? layer_height * 2 : layer_height, center, sides = sides ? sides : sides(r));
|
||||
|
@@ -28,6 +28,21 @@ module rounded_square(size, r, center = true) //! Like ```square()``` but with w
|
||||
|
||||
module rounded_rectangle(size, r, center = true, xy_center = true) //! Like ```cube()``` but corners rounded in XY plane and separate centre options for xy and z.
|
||||
{
|
||||
linear_extrude(size[2], center = center)
|
||||
rounded_square([size[0], size[1]], r, xy_center);
|
||||
linear_extrude(size.z, center = center)
|
||||
rounded_square([size.x, size.y], r, xy_center);
|
||||
}
|
||||
|
||||
module rounded_rectangle_xz(size, r, center = true, xy_center = true) //! Like ```cube()``` but corners rounded in XZ plane and separate centre options for xy and z.
|
||||
{
|
||||
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, center ? 0 : size.z / 2])
|
||||
rotate([90, 0, 0])
|
||||
rounded_rectangle([size.x, size.z, size.y], r, center = true, xy_center = true);
|
||||
}
|
||||
|
||||
module rounded_rectangle_yz(size, r, center = true, xy_center = true) //! Like ```cube()``` but corners rounded in YX plane and separate centre options for xy and z.
|
||||
{
|
||||
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, center ? 0 : size.z / 2])
|
||||
rotate([90, 0, 90])
|
||||
rounded_rectangle([size.y, size.z, size.x], r, center = true, xy_center = true);
|
||||
}
|
||||
|
||||
|
@@ -23,24 +23,36 @@
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
module dogbone_square(size, r = cnc_bit_r, center = true) //! Square with circles at the corners
|
||||
module dogbone_square(size, r = cnc_bit_r, center = true, x_offset, y_offset) //! Square with circles at the corners, with optional offsets
|
||||
{
|
||||
x_offset = is_undef(x_offset) ? r / sqrt(2) : x_offset;
|
||||
y_offset = is_undef(y_offset) ? r / sqrt(2) : y_offset;
|
||||
|
||||
union() {
|
||||
square(size, center = center);
|
||||
|
||||
if(r > 0) {
|
||||
origin = center ? [0, 0] : size / 2;
|
||||
offset = r / sqrt(2);
|
||||
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate(origin + [x * (size.x / 2 - offset), y * (size.y / 2 - offset)])
|
||||
translate(origin + [x * (size.x / 2 - x_offset), y * (size.y / 2 - y_offset)])
|
||||
drill(r, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module dogbone_rectangle(size, r = cnc_bit_r, center = true, xy_center = true) //! Rectangle with cylinders at the corners
|
||||
module dogbone_rectangle(size, r = cnc_bit_r, center = true, xy_center = true, x_offset, y_offset) //! Rectangle with cylinders at the corners
|
||||
{
|
||||
extrude_if(h = size.z, center = center)
|
||||
dogbone_square([size.x, size.y], r, xy_center);
|
||||
dogbone_square([size.x, size.y], r, xy_center, x_offset, y_offset);
|
||||
}
|
||||
|
||||
module dogbone_rectangle_x(size, r = cnc_bit_r, center = true, xy_center = true) //! Rectangle with cylinders at the corners, offset in the x direction
|
||||
{
|
||||
dogbone_rectangle(size = size, r = r, center = center, x_offset = 0, y_offset = r);
|
||||
}
|
||||
|
||||
module dogbone_rectangle_y(size, r = cnc_bit_r, center = true, xy_center = true) //! Rectangle with cylinders at the corners, offset in the y direction
|
||||
{
|
||||
dogbone_rectangle(size = size, r = r, center = center, x_offset = r, y_offset = 0);
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ module hanging_hole(z, ir, h = 100, h2 = 100) { //! Hole radius ```ir``` hanging
|
||||
poly_cylinder(r - eps, h - layer_height);
|
||||
}
|
||||
}
|
||||
assert(z % layer_height == 0, str(z));
|
||||
assert(z - layer_height * floor(z / layer_height) < eps, str(z));
|
||||
infill_angle = z % (2 * layer_height) ? -45 : 45;
|
||||
below = min(z + eps, h2);
|
||||
big = 1000;
|
||||
|
@@ -60,7 +60,7 @@ function rounded_polygon_length(points, tangents) = //! Calculate the length giv
|
||||
v1 = p1 - c,
|
||||
v2 = p2 - c,
|
||||
r = abs(corner.z),
|
||||
a = acos((v1 * v2) / sqr(r))) PI * (cross(v1,v2) <= 0 ? a : 360 - a) * r / 180]
|
||||
a = acos((v1 * v2) / sqr(r))) r ? PI * (cross(v1, v2) <= 0 ? a : 360 - a) * r / 180 : 0]
|
||||
)
|
||||
sumv(concat(straights, arcs));
|
||||
|
||||
|
@@ -21,7 +21,7 @@
|
||||
//! Utility to generate a polhedron by sweeping a 2D profile along a 3D path and utilities for generating paths.
|
||||
//!
|
||||
//! The initial orientation is the Y axis of the profile points towards the initial center of curvature, Frenet-Serret style.
|
||||
//! This means the first three points must not be colinear. Subsequent rotations use the minimum rotation method.
|
||||
//! Subsequent rotations use the minimum rotation method.
|
||||
//!
|
||||
//! The path can be open or closed. If closed sweep ensures that the start and end have the same rotation to line up.
|
||||
//! An additional twist around the path can be specified. If the path is closed this should be a multiple of 360.
|
||||
|
@@ -31,3 +31,41 @@ module ring(or, ir) //! Create a ring with specified external and internal radii
|
||||
module tube(or, ir, h, center = true) //! Create a tube with specified external and internal radii and height ```h```
|
||||
linear_extrude(h, center = center, convexity = 5)
|
||||
ring(or, ir);
|
||||
|
||||
module woven_tube(or, ir, h, center= true, colour = grey(30), colour2, warp = 2, weft) {//! Create a woven tube with specified external and internal radii, height ```h```, colours, warp and weft
|
||||
colour2 = colour2 ? colour2 : colour * 0.8;
|
||||
weft = weft ? weft : warp;
|
||||
warp_count = max(floor(PI * or / warp), 0.5);
|
||||
angle = 360 / (2 * warp_count);
|
||||
|
||||
module layer(weft) {
|
||||
points = [[ir, weft / 2], [or, weft / 2], [or, -weft / 2], [ir, -weft / 2]];
|
||||
color(colour)
|
||||
for (i = [0 : warp_count])
|
||||
rotate(2 * i * angle)
|
||||
rotate_extrude(angle = angle)
|
||||
polygon(points);
|
||||
color(colour2)
|
||||
for (i = [0 : warp_count])
|
||||
rotate((2 * i + 1) * angle)
|
||||
rotate_extrude(angle = angle)
|
||||
polygon(points);
|
||||
}
|
||||
|
||||
translate_z(center ? -h / 2 : 0) {
|
||||
weft_count = floor(h / weft);
|
||||
if (weft_count > 0)
|
||||
for (i = [0 : weft_count - 1]) {
|
||||
translate_z(i * weft + weft / 2)
|
||||
rotate(i * angle)
|
||||
layer(weft);
|
||||
}
|
||||
remainder = h - weft * weft_count;
|
||||
if (remainder) {
|
||||
translate_z(weft_count * weft + remainder / 2)
|
||||
rotate(weft_count * angle)
|
||||
layer(remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
//
|
||||
//! Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
|
||||
//! Only models 2D paths, so not core XY!
|
||||
//! Only models 2D paths, so not crossed belt core XY!
|
||||
//!
|
||||
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||
//!
|
||||
@@ -54,7 +54,7 @@ module belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20), toot
|
||||
|
||||
tangents = rounded_polygon_tangents(points);
|
||||
|
||||
length = ceil((rounded_polygon_length(points, tangents) - gap) / pitch) * pitch;
|
||||
length = ceil((rounded_polygon_length(points, tangents) - (is_list(gap) ? gap.x + gap.y : gap)) / pitch) * pitch;
|
||||
|
||||
module shape() rounded_polygon(points, tangents);
|
||||
|
||||
@@ -65,7 +65,7 @@ module belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20), toot
|
||||
translate([gap_pos.x, gap_pos.y])
|
||||
rotate(is_undef(gap_pos.z) ? 0 : gap_pos.z)
|
||||
translate([0, ph - thickness / 2])
|
||||
square([gap, thickness + eps], center = true);
|
||||
square(is_list(gap) ? [gap.x, gap.y + thickness + eps] : [gap, thickness + eps], center = true);
|
||||
|
||||
color(belt_colour)
|
||||
linear_extrude(width, center = true)
|
||||
|
@@ -22,6 +22,8 @@
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/rounded_cylinder.scad>
|
||||
use <../utils/quadrant.scad>
|
||||
use <screw.scad>
|
||||
|
||||
function blower_length(type) = type[2]; //! Length of enclosing rectangle
|
||||
function blower_width(type) = type[3]; //! Width of enclosing rectangle
|
||||
@@ -39,8 +41,87 @@ 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_casing_is_square(type) = len(blower_screw_holes(type)) > 3; //! 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);
|
||||
|
||||
module blower_fan(type, casing_is_square) {
|
||||
module squarish(s, n) {
|
||||
polygon([
|
||||
for(i = [0 : n]) [i * s.x / n, s.y + (i % 2) * eps],
|
||||
for(i = [0 : n]) [s.x - i * s.x / n, (i % 2) * eps],
|
||||
]);
|
||||
}
|
||||
|
||||
depth = blower_depth(type);
|
||||
blade_ir = blower_hub(type) / 2 + 0.5; // slight gap between main part of blades and hub
|
||||
blade_len = casing_is_square
|
||||
? (blower_bore(type) - 1) / 2 - blade_ir // fan constrained by bore hole
|
||||
: blower_width(type) - blower_axis(type).x- blower_wall(type) - blade_ir; // fan extends to casing
|
||||
blade_thickness = 0.75;
|
||||
blade_count = 25;
|
||||
|
||||
base_offset = 1;
|
||||
translate([blower_axis(type).x, blower_axis(type).y, blower_base(type) + base_offset])
|
||||
linear_extrude(blower_hub_height(type) - 0.5 - blower_base(type) - base_offset, center = false, convexity = 4, twist = -30, slices = round(depth / 2))
|
||||
for(i = [0 : blade_count - 1])
|
||||
rotate((360 * i) / blade_count)
|
||||
translate([blade_ir, -blade_thickness / 2])
|
||||
squarish([blade_len, blade_thickness], round(blade_len / 2));
|
||||
}
|
||||
|
||||
module blower_square(type) { //! Draw a square blower
|
||||
width = blower_width(type);
|
||||
depth = blower_depth(type);
|
||||
wall = blower_wall(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;
|
||||
|
||||
module square_inset_corners(remove_center = false)
|
||||
difference() {
|
||||
//overall outside
|
||||
square([width, width], 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);
|
||||
} 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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
translate_z(base_height)
|
||||
linear_extrude(depth - base_height)
|
||||
square_inset_corners(remove_center = true);
|
||||
|
||||
translate_z(depth - base_height)
|
||||
linear_extrude(blower_top(type))
|
||||
square_inset_corners();
|
||||
}
|
||||
|
||||
module blower(type) { //! Draw specified blower
|
||||
length = blower_length(type);
|
||||
width = blower_width(type);
|
||||
@@ -70,55 +151,63 @@ module blower(type) { //! Draw specified blower
|
||||
|
||||
vitamin(str("blower(", type[0], "): ", type[1]));
|
||||
|
||||
is_square = blower_casing_is_square(type); // Description starts with square!
|
||||
color(fan_colour) {
|
||||
// screw lugs
|
||||
linear_extrude(blower_lug(type), center = false)
|
||||
for(hole = blower_screw_holes(type))
|
||||
difference() {
|
||||
hull() {
|
||||
if (is_square) {
|
||||
blower_square(type);
|
||||
} else {
|
||||
// screw lugs
|
||||
linear_extrude(blower_lug(type), center = false)
|
||||
for(hole = blower_screw_holes(type))
|
||||
difference() {
|
||||
hull() {
|
||||
translate(hole)
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type));
|
||||
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type) + 7);
|
||||
}
|
||||
translate(hole)
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type));
|
||||
circle(d = blower_screw_hole(type));
|
||||
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type) + 7);
|
||||
}
|
||||
translate(hole)
|
||||
circle(d = blower_screw_hole(type));
|
||||
shape(true);
|
||||
}
|
||||
|
||||
shape(true);
|
||||
}
|
||||
// rotor
|
||||
translate(concat(blower_axis(type), [blower_base(type) + 1]))
|
||||
rounded_cylinder(r = blower_hub(type) / 2, h = blower_hub_height(type) - blower_base(type) - 1, r2 = 1);
|
||||
*%square([length, width]);
|
||||
|
||||
*%square([length, width]);
|
||||
|
||||
// base
|
||||
linear_extrude(blower_base(type))
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
translate(concat(blower_axis(type), [blower_base(type)]))
|
||||
circle(d = 2);
|
||||
}
|
||||
// sides
|
||||
linear_extrude(depth)
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
offset(-blower_wall(type))
|
||||
shape(true);
|
||||
}
|
||||
|
||||
// top
|
||||
translate_z(depth -blower_top(type))
|
||||
linear_extrude(blower_top(type))
|
||||
// base
|
||||
linear_extrude(blower_base(type))
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
translate(concat(blower_axis(type), [blower_base(type)]))
|
||||
circle(d = blower_bore(type));
|
||||
}
|
||||
circle(d = 2);
|
||||
}
|
||||
|
||||
// sides
|
||||
linear_extrude(depth)
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
offset(-blower_wall(type))
|
||||
shape(true);
|
||||
}
|
||||
|
||||
// top
|
||||
translate_z(depth -blower_top(type))
|
||||
linear_extrude(blower_top(type))
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
translate(concat(blower_axis(type), [blower_base(type)]))
|
||||
circle(d = blower_bore(type));
|
||||
}
|
||||
}
|
||||
// rotor
|
||||
translate(concat(blower_axis(type), [blower_base(type) + 1]))
|
||||
rounded_cylinder(r = blower_hub(type) / 2, h = blower_hub_height(type) - blower_base(type) - 1, r2 = 1);
|
||||
|
||||
blower_fan(type, is_square);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,10 +16,16 @@
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
// l w d b s h a s s e h b t w l
|
||||
// e i e o c u x c c x u a o a u
|
||||
// n d p r r b i r r i b s p l g
|
||||
// g t t e e s e e t e l
|
||||
// t h h w d w w t
|
||||
// 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 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];
|
||||
|
||||
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];
|
||||
|
||||
blowers = [PE4020, RB5015];
|
||||
blowers = [BL40x10, PE4020, RB5015];
|
||||
|
||||
use <blower.scad>
|
||||
|
@@ -29,7 +29,7 @@ function camera_lens(type) = type[4]; //! Stack of lens parts, can be r
|
||||
function camera_connector_pos(type) = type[5]; //! The flex connector block for the camera itself's position
|
||||
function camera_connector_size(type)= type[6]; //! The flex connector block for the camera itself's size
|
||||
|
||||
module camera_lens(type, offset = 0) //! Draw the lens stack, with optional offset for making a clearance hole
|
||||
module camera_lens(type, offset = 0, show_lens = true) //! Draw the lens stack, with optional offset for making a clearance hole
|
||||
color(grey(20))
|
||||
translate(camera_lens_offset(type))
|
||||
for(p = camera_lens(type)) {
|
||||
@@ -39,24 +39,25 @@ module camera_lens(type, offset = 0) //! Draw the lens stack, with optional offs
|
||||
if(size.x)
|
||||
rounded_rectangle(size + [2 * offset, 2 * offset, round_to_layer(offset)], r, center = false);
|
||||
else
|
||||
translate_z(size.y)
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
square([r, size.z + round_to_layer(offset)]);
|
||||
if (show_lens)
|
||||
translate_z(size.y)
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
square([r, size.z + round_to_layer(offset)]);
|
||||
|
||||
if(app)
|
||||
translate([0, size.z])
|
||||
hull() {
|
||||
translate([0, -eps])
|
||||
square([app.y, eps * 2]);
|
||||
if(app)
|
||||
translate([0, size.z])
|
||||
hull() {
|
||||
translate([0, -eps])
|
||||
square([app.y, eps * 2]);
|
||||
|
||||
translate([0, -app.z])
|
||||
square([app.x, app.z]);
|
||||
}
|
||||
}
|
||||
translate([0, -app.z])
|
||||
square([app.x, app.z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module camera(type) { //! Draw specified PCB camera
|
||||
module camera(type, show_lens = true) { //! Draw specified PCB camera
|
||||
vitamin(str("camera(", type[0], "): ", type[1]));
|
||||
pcb = camera_pcb(type);
|
||||
|
||||
@@ -64,7 +65,7 @@ module camera(type) { //! Draw specified PCB camera
|
||||
pcb(pcb);
|
||||
|
||||
translate_z(pcb_thickness(pcb)) {
|
||||
camera_lens(type);
|
||||
camera_lens(type, show_lens = show_lens);
|
||||
|
||||
conn = camera_connector_size(type);
|
||||
if(conn) {
|
||||
|
@@ -68,6 +68,6 @@ rpi_camera = ["rpi_camera", "Raspberry Pi focusable camera", rpi_camera_pcb, [0,
|
||||
[0, 18 - 1.5 - 2.5], [8, 5, 1.6]
|
||||
];
|
||||
|
||||
cameras = [rpi_camera_v1, rpi_camera, rpi_camera_v2];
|
||||
cameras = [rpi_camera_v1, rpi_camera_v2, rpi_camera];
|
||||
|
||||
use <camera.scad>
|
||||
|
@@ -73,6 +73,42 @@ SSD1963_4p3 = ["SSD1963_4p3", "LCD display SSD1963 4.3\"", 105.5, 67.2, 3.4, SSD
|
||||
[[0, -34.5], [12, -31.5]],
|
||||
];
|
||||
|
||||
displays = [HDMI5, SSD1963_4p3, LCD1602A, LCDS7282B];
|
||||
BigTreeTech_TFT35v3_0_PCB = ["", "",
|
||||
110, 55.77, 1.6, 0, 3, 0, "green", false,
|
||||
[ [-3.12, 3.17], [-3.12, -3.17], [3.12, -3.17], [3.12, 3.17] ],
|
||||
[
|
||||
[ 10, 7.5, 0, "-button_6mm" ],
|
||||
[ 9, 43, 0, "-buzzer", 5, 9 ],
|
||||
[ 9, 27, 0, "-potentiometer" ],
|
||||
[ 102,28.82, 0, "uSD", [26.5, 16, 3] ],
|
||||
[16.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
|
||||
[36.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
|
||||
[56.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
|
||||
[82.5, 4, 0, "jst_xh", 5 ],
|
||||
[26.5, 52.8, 180, "jst_xh", 2 ],
|
||||
[39.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[52.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[65.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[78.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[94.5, 52.8, 180, "jst_xh", 5 ],
|
||||
[ 8, 43, 180, "usb_A" ],
|
||||
[ 97, 4, 0, "chip", 9, 3.5, 1, grey(20) ],
|
||||
// ESP-8266
|
||||
[ 23, 28, 90, "2p54socket", 4, 2 ],
|
||||
],
|
||||
[]
|
||||
];
|
||||
|
||||
BigTreeTech_TFT35v3_0 = ["BigTreeTech_TFT35v3_0", "BigTreeTech TFT35 v3.0",
|
||||
84.5, 54.5, 4, BigTreeTech_TFT35v3_0_PCB,
|
||||
[-6, 0, 0], // pcb offset
|
||||
[[-40, -26.5], [41.5, 26.5, 0.5]], // aperture
|
||||
[], // touch screen
|
||||
0, // thread length
|
||||
[], // clearance need for the ts ribbon
|
||||
];
|
||||
|
||||
|
||||
displays = [HDMI5, SSD1963_4p3, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B];
|
||||
|
||||
use <display.scad>
|
||||
|
@@ -26,6 +26,8 @@ include <tubings.scad>
|
||||
include <zipties.scad>
|
||||
include <fans.scad>
|
||||
|
||||
use <../utils/rounded_cylinder.scad>
|
||||
use <../utils/thread.scad>
|
||||
use <../utils/tube.scad>
|
||||
|
||||
rad_dia = 22; // Diam of the part with ailettes
|
||||
@@ -94,7 +96,34 @@ module heater_block(type, naked = false, resistor_wire_rotate = [0,0,0]) {
|
||||
}
|
||||
}
|
||||
|
||||
module bowden_connector(cap_colour = grey(20)) {
|
||||
ir = 4.25 / 2;
|
||||
body_colour = silver;
|
||||
|
||||
color(body_colour) {
|
||||
translate_z(-4.5) {
|
||||
tube(or = 2.5, ir = ir, h = 4.5, center = false);
|
||||
male_metric_thread(6, metric_coarse_pitch(5), length = 4.5, center = false, solid = false, colour = body_colour);
|
||||
}
|
||||
tube(or = 7.7 / 2, ir = ir, h = 2, center = false);
|
||||
translate_z(2)
|
||||
linear_extrude(6.5)
|
||||
difference() {
|
||||
circle(d = 11.55, $fn = 6);
|
||||
circle(r = ir);
|
||||
}
|
||||
translate_z(8.5)
|
||||
rounded_cylinder(r = 9.8 / 2, h = 2, r2 = 1.5, ir = ir);
|
||||
translate_z(10.5)
|
||||
tube(or = 3.5, ir = ir, h = 0.5, center = false);
|
||||
}
|
||||
color(cap_colour) {
|
||||
translate_z(11)
|
||||
tube(or = 3, ir = ir, h = 1, center = false);
|
||||
translate_z(12)
|
||||
tube(or = 5.5, ir = ir, h = 1.75, center = false);
|
||||
}
|
||||
}
|
||||
|
||||
module e3d_fan_duct(type) {
|
||||
color("DeepSkyBlue")
|
||||
@@ -123,7 +152,7 @@ module e3d_fan(type) {
|
||||
fan(fan30x10);
|
||||
}
|
||||
|
||||
module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) {
|
||||
module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false) {
|
||||
insulator_length = hot_end_insulator_length(type);
|
||||
inset = hot_end_inset(type);
|
||||
h_ailettes = rad_len / (2 * rad_nb_ailettes - 1);
|
||||
@@ -150,6 +179,10 @@ module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]
|
||||
square([100, hot_end_groove(type)]);
|
||||
}
|
||||
|
||||
if(bowden)
|
||||
translate_z(inset)
|
||||
bowden_connector();
|
||||
|
||||
rotate(90)
|
||||
heater_block(type, naked, resistor_wire_rotate);
|
||||
|
||||
@@ -158,10 +191,10 @@ module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]
|
||||
e3d_fan();
|
||||
}
|
||||
|
||||
module e3d_hot_end_assembly(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) {
|
||||
module e3d_hot_end_assembly(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false) {
|
||||
bundle = 3.2;
|
||||
|
||||
e3d_hot_end(type, filament, naked, resistor_wire_rotate);
|
||||
e3d_hot_end(type, filament, naked, resistor_wire_rotate, bowden);
|
||||
|
||||
// Wire and ziptie
|
||||
if(!naked)
|
||||
|
@@ -44,10 +44,10 @@ function hot_end_length(type) = hot_end_total_length(type) - hot_end_inset(type)
|
||||
use <jhead.scad>
|
||||
use <e3d.scad>
|
||||
|
||||
module hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) { //! Draw specified hot end
|
||||
module hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false) { //! Draw specified hot end
|
||||
if(hot_end_style(type) == jhead)
|
||||
jhead_hot_end_assembly(type, filament, naked);
|
||||
|
||||
if(hot_end_style(type) == e3d)
|
||||
e3d_hot_end_assembly(type, filament, naked, resistor_wire_rotate);
|
||||
e3d_hot_end_assembly(type, filament, naked, resistor_wire_rotate, bowden);
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@
|
||||
// d d h d d
|
||||
// d
|
||||
//
|
||||
F1BM2 = [ "F1BM2", 4.0, 3.6, 3.2, 2, 3.0, 1.0, 3.4, 3.1 ];
|
||||
F1BM2 = [ "F1BM2", 4.0, 3.6, 3.2, 2, 3.0, 1.0, 3.4, 3.1 ];
|
||||
F1BM2p5 = [ "F1BM2p5", 5.8, 4.6, 4.0, 2.5, 3.65, 1.6, 4.4, 3.9 ];
|
||||
F1BM3 = [ "F1BM3", 5.8, 4.6, 4.0, 3, 3.65, 1.6, 4.4, 3.9 ];
|
||||
F1BM4 = [ "F1BM4", 8.2, 6.3, 5.6, 4, 5.15, 2.3, 6.0, 5.55 ];
|
||||
|
@@ -116,7 +116,7 @@ module mains_socket(type) { //! Draw specified 13A socket
|
||||
cylinder(r = screw_clearance_radius(screw), h = 100, center = true);
|
||||
|
||||
translate_z(height)
|
||||
screw_countersink(screw);
|
||||
screw_countersink(screw, drilled = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,8 @@ GT2x12_pulley = ["GT2x12_pulley", "GT2RD", 12, 7.15, GT2x6, 6.5,
|
||||
GT2x20_toothed_idler = ["GT2x20_toothed_idler", "GT2", 20, 12.22, GT2x6, 6.5, 18, 0, 4, 18.0, 1.0, 0, 0, false, 0];
|
||||
GT2x20_plain_idler = ["GT2x20_plain_idler", "GT2", 0, 12.0, GT2x6, 6.5, 18, 0, 4, 18.0, 1.0, 0, 0, false, 0];
|
||||
GT2x16_toothed_idler = ["GT2x16_toothed_idler", "GT2", 16, 9.75, GT2x6, 6.5, 14, 0, 3, 14.0, 1.0, 0, 0, false, 0];
|
||||
GT2x16_plain_idler = ["GT2x16_plain_idler", "GT2", 0, 9.63, GT2x6, 7.0, 13, 0, 3, 13.0, 1.0, 0, 0, false, 0];
|
||||
GT2x16_plain_idler = ["GT2x16_plain_idler", "GT2", 0, 9.63, GT2x6, 6.5, 13, 0, 3, 13.0, 1.0, 0, 0, false, 0];
|
||||
GT2x16x7_plain_idler = ["GT2x16x7_plain_idler", "GT2", 0, 9.63, GT2x6, 7.0, 13, 0, 3, 13.0, 1.0, 0, 0, false, 0];
|
||||
|
||||
pulleys = [T5x10_pulley,
|
||||
T2p5x16_pulley,
|
||||
@@ -45,6 +46,7 @@ pulleys = [T5x10_pulley,
|
||||
GT2x20_toothed_idler,
|
||||
GT2x20_plain_idler,
|
||||
GT2x16_toothed_idler,
|
||||
GT2x16_plain_idler];
|
||||
GT2x16_plain_idler,
|
||||
GT2x16x7_plain_idler];
|
||||
|
||||
use <pulley.scad>
|
||||
|
@@ -46,12 +46,16 @@ function carriage_pitch_y(type) = type[6]; //! Screw hole y pitch
|
||||
function carriage_screw(type) = type[7]; //! Carriage screw type
|
||||
function carriage_screw_depth(type) = 2 * screw_radius(carriage_screw(type)); //! Carriage thread depth
|
||||
|
||||
function rail_holes(type, length) = //! Number of holes in a rail given its ```length```
|
||||
floor((length - 2 * rail_end(type)) / rail_pitch(type)) + 1;
|
||||
|
||||
module rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true) { //! Position children over screw holes
|
||||
pitch = rail_pitch(type);
|
||||
holes = floor((length - 2 * rail_end(type)) / pitch) + 1;
|
||||
for(i = [first : holes - 1 - first])
|
||||
if(i < screws || (holes - i <= screws && both_ends))
|
||||
translate([i * pitch - length / 2 + (length - (holes -1) * pitch) / 2, 0, 0])
|
||||
holes = rail_holes(type, length);
|
||||
last = first + screws;
|
||||
for(i = [first : holes - 1], j = holes - 1 - i)
|
||||
if(i < last || both_ends && (j >= first && j < last))
|
||||
translate([i * pitch - length / 2 + (length - (holes - 1) * pitch) / 2, 0])
|
||||
children();
|
||||
}
|
||||
|
||||
@@ -104,24 +108,27 @@ module carriage(type, rail, end_colour = grey(20), wiper_colour = grey(20)) { //
|
||||
|
||||
module carriage_end(type, end_w, end_h, end_l) {
|
||||
wiper_length = 0.5;
|
||||
color(wiper_colour) translate_z(-end_l/2) linear_extrude(wiper_length)
|
||||
color(wiper_colour) translate_z(-end_l / 2) linear_extrude(wiper_length)
|
||||
difference() {
|
||||
translate([-end_w/2, carriage_clearance(type)])
|
||||
translate([-end_w / 2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
|
||||
cutout();
|
||||
}
|
||||
color(end_colour) translate_z(wiper_length-end_l/2) linear_extrude(end_l-wiper_length)
|
||||
color(end_colour) translate_z(wiper_length-end_l / 2) linear_extrude(end_l - wiper_length)
|
||||
difference() {
|
||||
translate([-end_w/2, carriage_clearance(type)])
|
||||
translate([-end_w / 2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
|
||||
cutout();
|
||||
}
|
||||
}
|
||||
|
||||
translate([-(block_l+end_l)/2,0,0])
|
||||
translate([-(block_l + end_l) / 2, 0])
|
||||
rotate([90, 0, 90])
|
||||
carriage_end(type, end_w, end_h, end_l);
|
||||
translate([(block_l+end_l)/2,0,0])
|
||||
|
||||
translate([(block_l + end_l) / 2, 0])
|
||||
rotate([90, 0, -90])
|
||||
carriage_end(type, end_w, end_h, end_l);
|
||||
}
|
||||
@@ -171,7 +178,6 @@ module rail_assembly(type, length, pos, carriage_end_colour = grey(20), carriage
|
||||
|
||||
translate([pos, 0])
|
||||
carriage(rail_carriage(type), type, carriage_end_colour, carriage_wiper_colour);
|
||||
|
||||
}
|
||||
|
||||
module rail_screws(type, length, thickness, screws = 100) { //! Place screws in the rail
|
||||
@@ -187,6 +193,6 @@ module rail_screws(type, length, thickness, screws = 100) { //! Place screws in
|
||||
screw(end_screw, end_screw_len);
|
||||
|
||||
translate_z(rail_screw_height(type, screw))
|
||||
rail_hole_positions(type, length, index_screws, screws)
|
||||
rail_hole_positions(type, length, index_screws, min(screws, rail_holes(type, length)) - 2 * index_screws)
|
||||
screw(screw, screw_len);
|
||||
}
|
||||
|
@@ -33,11 +33,11 @@ SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw ];
|
||||
//
|
||||
//
|
||||
// Wr Hr E P D d h
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.5, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriage, M2_cs_cap_screw ]; // Screw holes too small for M2 heads
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.6, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriage, M2_cs_cap_screw ]; // Screw holes too small for M2 heads
|
||||
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, MGN7_carriage, M2_cs_cap_screw ];
|
||||
MGN9 = [ "MGN9", 9, 6, 7.5, 20, 6.0, 3.5, 3.5, M3_cap_screw, MGN9_carriage, M3_cs_cap_screw ];
|
||||
MGN12= [ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12_carriage, M3_cs_cap_screw ];
|
||||
MGN12H=[ "MGN12H",12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12H_carriage,M3_cs_cap_screw ];
|
||||
MGN12H=[ "MGN12H",12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12H_carriage,M3_cs_cap_screw ];
|
||||
MGN15= [ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, MGN15_carriage, M3_cs_cap_screw ];
|
||||
SSR15= [ "SSR15", 15, 12.5,10, 60, 7.5, 4.5, 5.3, M4_cap_screw, SSR15_carriage, M4_cs_cap_screw ];
|
||||
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
//
|
||||
//! Machine screws and wood screws with various head styles.
|
||||
//!
|
||||
//! For an explanation of ```screw_polysink()``` see <https://hydraraptor.blogspot.com/2020/12/sinkholes.html>.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
@@ -41,9 +43,13 @@ function screw_pilot_hole(type) = type[11]; //! Pilot hole radius for w
|
||||
function screw_clearance_radius(type) = type[12]; //! Clearance hole radius
|
||||
function screw_nut_radius(type) = screw_nut(type) ? nut_radius(screw_nut(type)) : 0; //! Radius of matching nut
|
||||
function screw_boss_diameter(type) = max(washer_diameter(screw_washer(type)) + 1, 2 * (screw_nut_radius(type) + 3 * extrusion_width)); //! Boss big enough for nut trap and washer
|
||||
function screw_head_depth(type, d) = screw_head_height(type) ? 0 : screw_head_radius(type) - d / 2; //! How far a counter sink head will go into a straight hole diameter d
|
||||
function screw_head_depth(type, d = 0) = //! How far a counter sink head will go into a straight hole diameter d
|
||||
screw_head_height(type)
|
||||
? 0
|
||||
: let(r = screw_radius(type)) screw_head_radius(type) - max(r, d / 2) + r / 5;
|
||||
|
||||
function screw_longer_than(x) = x <= 5 ? 5 : //! Returns shortest screw length longer or equal to x
|
||||
x <= 6 ? 6 :
|
||||
x <= 8 ? 8 :
|
||||
x <= 10 ? 10 :
|
||||
x <= 12 ? 12 :
|
||||
@@ -109,6 +115,27 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
cylinder(r = rad + eps, h = shank);
|
||||
}
|
||||
|
||||
module cs_head(socket_rad, socket_depth) {
|
||||
head_t = rad / 5;
|
||||
head_height = head_rad + head_t;
|
||||
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
polygon([[0, 0], [head_rad, 0], [head_rad, -head_t], [0, -head_height]]);
|
||||
|
||||
translate([0, -socket_depth + eps])
|
||||
square([socket_rad, 10]);
|
||||
}
|
||||
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(socket_depth)
|
||||
difference() {
|
||||
circle(socket_rad + 0.1);
|
||||
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
explode(length + 10) {
|
||||
if(head_type == hs_cap) {
|
||||
color(colour) {
|
||||
@@ -201,63 +228,76 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
}
|
||||
|
||||
if(head_type == hs_cs) {
|
||||
head_height = head_rad;
|
||||
socket_rad = 0.6 * head_rad;
|
||||
socket_depth = 0.3 * head_rad;
|
||||
socket_width = 1;
|
||||
color(colour) {
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
polygon([[0, 0], [head_rad, 0], [0, -head_height]]);
|
||||
color(colour)
|
||||
cs_head(socket_rad, socket_depth) {
|
||||
square([2 * socket_rad, socket_width], center = true);
|
||||
square([socket_width, 2 * socket_rad], center = true);
|
||||
}
|
||||
|
||||
translate([0, -socket_depth + eps])
|
||||
square([socket_rad + 0.1, 10]);
|
||||
}
|
||||
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(socket_depth)
|
||||
difference() {
|
||||
circle(socket_rad + 0.1);
|
||||
|
||||
square([2 * socket_rad, socket_width], center = true);
|
||||
square([socket_width, 2 * socket_rad], center = true);
|
||||
}
|
||||
}
|
||||
shaft(socket_depth);
|
||||
}
|
||||
|
||||
if(head_type == hs_cs_cap) {
|
||||
head_height = head_rad;
|
||||
color(colour) {
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
polygon([[0, 0], [head_rad, 0], [0, -head_height]]);
|
||||
color(colour)
|
||||
cs_head(socket_rad, socket_depth)
|
||||
circle(socket_rad, $fn = 6);
|
||||
|
||||
translate([0, -socket_depth + eps])
|
||||
square([socket_rad, 10]);
|
||||
}
|
||||
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(socket_depth)
|
||||
difference() {
|
||||
circle(socket_rad + 0.1);
|
||||
|
||||
circle(socket_rad, $fn = 6);
|
||||
}
|
||||
}
|
||||
shaft(socket_depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module screw_countersink(type) { //! Countersink shape
|
||||
module screw_countersink(type, drilled = true) { //! Countersink shape
|
||||
head_type = screw_head_type(type);
|
||||
head_rad = screw_head_radius(type);
|
||||
head_height = head_rad;
|
||||
rad = screw_radius(type);
|
||||
head_t = rad / 5;
|
||||
head_height = head_rad + head_t;
|
||||
|
||||
if(head_type == hs_cs || head_type == hs_cs_cap)
|
||||
translate_z(-head_height)
|
||||
cylinder(h = head_height, r1 = 0, r2 = head_rad);
|
||||
if(drilled)
|
||||
cylinder(h = head_height + eps, r1 = 0, r2 = head_rad + head_t);
|
||||
else
|
||||
intersection() {
|
||||
cylinder(h = head_height + eps, r1 = 0, r2 = head_rad + head_t);
|
||||
|
||||
cylinder(h = head_height + eps, r = head_rad + eps);
|
||||
}
|
||||
}
|
||||
|
||||
function screw_polysink_r(type, z) = //! Countersink hole profile corrected for rounded staircase extrusions.
|
||||
let(rad = screw_radius(type),
|
||||
head_t = rad / 5,
|
||||
head_rad = screw_head_radius(type)
|
||||
)
|
||||
limit(head_rad + head_t - z + (sqrt(2) - 1) * layer_height / 2, screw_clearance_radius(type), head_rad);
|
||||
|
||||
module screw_polysink(type, h = 100, alt = false) { //! A countersink hole made from stacked polyholes for printed parts
|
||||
head_depth = screw_head_depth(type);
|
||||
assert(head_depth, "Not a countersunk screw");
|
||||
layers = ceil(head_depth / layer_height);
|
||||
rmin = screw_clearance_radius(type);
|
||||
sides = sides(rmin);
|
||||
lh = layer_height + eps;
|
||||
render(convexity = 5)
|
||||
for(side = [0, 1]) mirror([0, 0, side]) {
|
||||
for(i = [0 : layers - 1])
|
||||
translate_z(i * layer_height) {
|
||||
r = screw_polysink_r(type, i * layer_height + layer_height / 2);
|
||||
if(alt)
|
||||
rotate(i % 2 == layers % 2 ? 180 / sides : 0)
|
||||
poly_cylinder(r = r, h = lh, center = false, sides = sides);
|
||||
else
|
||||
poly_cylinder(r = r, h = lh, center = false);
|
||||
}
|
||||
|
||||
translate_z(layers * layer_height)
|
||||
poly_cylinder(r = rmin, h = h / 2 - layers * layer_height, center = false);
|
||||
}
|
||||
}
|
||||
|
||||
module screw_and_washer(type, length, star = false, penny = false) { //! Screw with a washer which can be standard or penny and an optional star washer on top
|
||||
|
@@ -107,14 +107,14 @@ No6_screw = ["No6", "No6 pan wood", hs_pan, 3.5, 6.7, 2.2, 0, 0
|
||||
No6_cs_screw = ["No6_cs", "No6 cs wood", hs_cs, 3.5, 7.0, 0, 0, 0, 0, M4_washer, false, No6_pilot_radius, No6_clearance_radius];
|
||||
|
||||
screw_lists = [
|
||||
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
|
||||
[ 0, 0, M3_low_cap_screw],
|
||||
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
|
||||
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
|
||||
[ 0, No2_screw, No4_screw, No6_screw, No6_cs_screw],
|
||||
[ 0, M2_cs_cap_screw,M3_cs_cap_screw, M4_cs_cap_screw],
|
||||
[ 0, M2_dome_screw, M3_dome_screw, M4_dome_screw],
|
||||
[ 0, 0, M3_grub_screw, M4_grub_screw]
|
||||
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
|
||||
[ 0, 0, M3_low_cap_screw],
|
||||
[ M2_cs_cap_screw, 0, M3_cs_cap_screw, M4_cs_cap_screw],
|
||||
[ M2_dome_screw, 0, M3_dome_screw, M4_dome_screw],
|
||||
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
|
||||
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
|
||||
[ No2_screw, 0, No4_screw, No6_screw, No6_cs_screw],
|
||||
[ 0, 0, M3_grub_screw, M4_grub_screw]
|
||||
];
|
||||
|
||||
use <screw.scad>
|
||||
|
65
vitamins/shaft_coupling.scad
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//
|
||||
//! Shaft couplings
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/tube.scad>
|
||||
|
||||
function sc_length(type) = type[1]; //! Coupling length
|
||||
function sc_diameter(type) = type[2]; //! Coupling outer diameter
|
||||
function sc_diameter1(type) = type[3]; //! Diameter of smaller shaft
|
||||
function sc_diameter2(type) = type[4]; //! Diameter of larger shaft
|
||||
|
||||
module shaft_coupling(type, colour = "silver") { //! Draw the shaft coupling
|
||||
vitamin(str("shaft_coupling(", type[0], "): Shaft coupling ", type[0]));
|
||||
|
||||
length = sc_length(type);
|
||||
radius = sc_diameter(type) / 2;
|
||||
r1 = sc_diameter1(type) / 2;
|
||||
r2 = sc_diameter2(type) / 2;
|
||||
|
||||
grub_length = 3;
|
||||
module grub_screw_positions() {
|
||||
grub_offset_z = 5;
|
||||
for(z = [-length / 2 + grub_offset_z, length / 2 - grub_offset_z])
|
||||
translate_z(z)
|
||||
for(a = [0, 90])
|
||||
rotate([-90, 0, a])
|
||||
translate_z(radius + 1)
|
||||
children();
|
||||
}
|
||||
|
||||
color(colour) {
|
||||
render(convexity=2) difference() {
|
||||
union() {
|
||||
translate_z(-length / 2)
|
||||
tube(radius, r1, length / 2, false);
|
||||
|
||||
tube(radius, r2, length / 2, false);
|
||||
}
|
||||
grub_screw_positions()
|
||||
rotate([180, 0, 0])
|
||||
cylinder(r = screw_radius(M3_grub_screw), h = 5);
|
||||
}
|
||||
}
|
||||
|
||||
grub_screw_positions()
|
||||
not_on_bom() screw(M3_grub_screw, grub_length);
|
||||
}
|
29
vitamins/shaft_couplings.scad
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Shaft couplings
|
||||
//
|
||||
|
||||
// L D d1 d2
|
||||
SC_5x8_rigid = [ "SC_5x8_rigid", 25, 12.5, 5, 8 ];
|
||||
|
||||
shaft_couplings = [SC_5x8_rigid];
|
||||
|
||||
use <shaft_coupling.scad>
|
@@ -38,7 +38,7 @@ PMMA8 = [ "PMMA8", "Sheet acrylic", 8, [1, 1, 1, 0.5 ],
|
||||
PMMA10 = [ "PMMA10", "Sheet acrylic", 10, [1, 1, 1, 0.5 ], false]; // ~3/8"
|
||||
glass2 = [ "glass2", "Sheet glass", 2, [1, 1, 1, 0.25 ], false];
|
||||
DiBond = [ "DiBond", "Sheet DiBond", 3, [0.2, 0.2, 0.2, 1 ], false];
|
||||
DiBond6 = [ "DiBond6", "Sheet DiBond", 6, "RoyalBlue", false];
|
||||
DiBond6 = [ "DiBond6", "Sheet DiBond", 6, [0.2, 0.2, 0.2, 1 ], false];
|
||||
Cardboard = [ "Cardboard", "Corrugated cardboard", 5, [0.8, 0.6, 0.3, 1 ], false];
|
||||
FoilTape = [ "FoilTape", "Aluminium foil tape", 0.05,[0.9, 0.9, 0.9, 1 ], false];
|
||||
Foam20 = [ "Foam20", "Foam sponge", 20,[0.3, 0.3, 0.3, 1 ], true];
|
||||
|
@@ -21,6 +21,7 @@
|
||||
//! Tubing and sleeving. The internal diameter can be forced to stretch it over something.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
include <../utils/tube.scad>
|
||||
|
||||
function tubing_material(type) = type[1]; //! Material description
|
||||
function tubing_od(type) = type[2]; //! Outside diameter
|
||||
@@ -38,10 +39,15 @@ module tubing(type, length = 15, forced_id = 0, center = true) { //! Draw specif
|
||||
vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " ID ", original_id, "mm x ",length, "mm"));
|
||||
else
|
||||
vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " OD ", original_od, "mm ID ", original_id,"mm x ",length, "mm"));
|
||||
color(tubing_colour(type))
|
||||
linear_extrude(length, center = center, convexity = 4)
|
||||
difference() {
|
||||
circle(d = od);
|
||||
circle(d = id);
|
||||
}
|
||||
|
||||
if(tubing_material(type) == "Carbon fiber")
|
||||
woven_tube(od / 2, id /2, center = center, length, colour = tubing_colour(type));
|
||||
else
|
||||
color(tubing_colour(type))
|
||||
linear_extrude(length, center = center, convexity = 4)
|
||||
difference() {
|
||||
circle(d = od);
|
||||
circle(d = id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,22 +19,23 @@
|
||||
|
||||
//
|
||||
// Tubing and sleeving
|
||||
//
|
||||
PVC64 = ["PVC64", "PVC aquarium tubing", 6, 4, [0.8, 0.8, 0.8, 0.75 ]];
|
||||
PVC85 = ["PVC85", "PVC aquarium tubing", 8, 5, [0.8, 0.8, 0.8, 0.75 ]];
|
||||
NEOP85 = ["NEOP85", "Neoprene tubing", 8, 5, [0.2,0.2,0.2]];
|
||||
PTFE07 = ["PTFE07", "PTFE sleeving", 1.2, 0.71, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE20 = ["PTFE20", "PTFE sleeving", 2.6, 2, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE2_4 = ["PTFE2_4", "PTFE tubing", 4, 2, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE2_3 = ["PTFE2_3", "PTFE tubing", 3, 2, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE4_6 = ["PTFE4_6", "PTFE tubing", 6, 4, [0.95, 0.95, 0.95, 0.9]];
|
||||
PF7 = ["PF7", "PTFE tubing", 46/10, 3.84, [0.95, 0.95, 0.95, 0.9]];
|
||||
HSHRNK16 = ["HSHRNK16", "Heatshrink sleeving", 2.0, 1.6, "grey"];
|
||||
HSHRNK24 = ["HSHRNK24", "Heatshrink sleeving", 2.8, 2.4, "grey"];
|
||||
HSHRNK32 = ["HSHRNK32", "Heatshrink sleeving", 3.6, 3.2, "grey"];
|
||||
HSHRNK64 = ["HSHRNK64", "Heatshrink sleeving", 6.8, 6.4, "grey"];
|
||||
HSHRNK100 = ["HSHRNK100", "Heatshrink sleeving",10.4, 10.0, [0.2,0.2,0.2]];
|
||||
// Description OD ID Colour
|
||||
PVC64 = ["PVC64", "PVC aquarium tubing", 6, 4, [0.8, 0.8, 0.8, 0.75 ]];
|
||||
PVC85 = ["PVC85", "PVC aquarium tubing", 8, 5, [0.8, 0.8, 0.8, 0.75 ]];
|
||||
NEOP85 = ["NEOP85", "Neoprene tubing", 8, 5, [0.2,0.2,0.2]];
|
||||
PTFE07 = ["PTFE07", "PTFE sleeving", 1.2, 0.71, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE20 = ["PTFE20", "PTFE sleeving", 2.6, 2, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE2_4 = ["PTFE2_4", "PTFE tubing", 4, 2, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE2_3 = ["PTFE2_3", "PTFE tubing", 3, 2, [0.95, 0.95, 0.95, 0.9]];
|
||||
PTFE4_6 = ["PTFE4_6", "PTFE tubing", 6, 4, [0.95, 0.95, 0.95, 0.9]];
|
||||
PF7 = ["PF7", "PTFE tubing", 46/10, 3.84, [0.95, 0.95, 0.95, 0.9]];
|
||||
HSHRNK16 = ["HSHRNK16", "Heatshrink sleeving", 2.0, 1.6, "grey"];
|
||||
HSHRNK24 = ["HSHRNK24", "Heatshrink sleeving", 2.8, 2.4, "grey"];
|
||||
HSHRNK32 = ["HSHRNK32", "Heatshrink sleeving", 3.6, 3.2, "grey"];
|
||||
HSHRNK64 = ["HSHRNK64", "Heatshrink sleeving", 6.8, 6.4, "grey"];
|
||||
HSHRNK100 = ["HSHRNK100", "Heatshrink sleeving",10.4, 10.0, [0.2,0.2,0.2]];
|
||||
CARBONFIBER10 = ["CBNFIB10", "Carbon fiber", 10.0, 8.0, [0.3,0.3,0.3]];
|
||||
|
||||
tubings = [PVC64, PVC85, NEOP85, PTFE07, PTFE20, PF7, PTFE2_3, PTFE2_4, PTFE4_6, HSHRNK16, HSHRNK24, HSHRNK64, HSHRNK100];
|
||||
tubings = [PVC64, PVC85, NEOP85, PTFE07, PTFE20, PF7, PTFE2_3, PTFE2_4, PTFE4_6, HSHRNK16, HSHRNK24, HSHRNK64, HSHRNK100, CARBONFIBER10];
|
||||
|
||||
use <tubing.scad>
|
||||
|