Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3cf275579c | ||
|
fb41f218fe | ||
|
e6a26bc7b1 | ||
|
cb4fa40643 | ||
|
6a26903514 | ||
|
d08d949887 | ||
|
574a73e527 | ||
|
87a35126de | ||
|
1ca485b66b | ||
|
bc919529d3 | ||
|
9f4ed2b915 | ||
|
7ce055373a | ||
|
71ac571346 | ||
|
e4d93366fa | ||
|
f047ac27f7 | ||
|
a9e479d971 | ||
|
47b01af1ea | ||
|
fe19eba237 | ||
|
235f7b86e3 | ||
|
92d7e18b16 | ||
|
6a7226120f | ||
|
8aa00cd041 | ||
|
f6b512da1f | ||
|
c7ea0939b9 | ||
|
265b5ab555 | ||
|
186dbbfd08 | ||
|
60659a43f8 | ||
|
f412cb1736 | ||
|
2b878556fc | ||
|
1f1a360b7c | ||
|
a547c98995 | ||
|
d9fa8c8668 | ||
|
bf5b6d7c30 | ||
|
9cfde7f524 |
2
lib.scad
@@ -29,6 +29,7 @@ include <vitamins/batteries.scad>
|
||||
include <vitamins/blowers.scad>
|
||||
include <vitamins/bulldogs.scad>
|
||||
include <vitamins/buttons.scad>
|
||||
include <vitamins/cameras.scad>
|
||||
include <vitamins/components.scad>
|
||||
include <vitamins/displays.scad>
|
||||
include <vitamins/extrusions.scad>
|
||||
@@ -83,6 +84,7 @@ use <utils/rounded_cylinder.scad>
|
||||
use <utils/dogbones.scad>
|
||||
use <utils/tube.scad>
|
||||
use <utils/quadrant.scad>
|
||||
use <utils/gears.scad>
|
||||
use <utils/hanging_hole.scad>
|
||||
use <utils/fillet.scad>
|
||||
use <utils/rounded_polygon.scad>
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 798 KiB After Width: | Height: | Size: 813 KiB |
@@ -29,6 +29,7 @@ use <tests/blowers.scad>
|
||||
use <tests/bulldogs.scad>
|
||||
use <tests/buttons.scad>
|
||||
use <tests/cable_strips.scad>
|
||||
use <tests/cameras.scad>
|
||||
use <tests/circlips.scad>
|
||||
use <tests/components.scad>
|
||||
use <tests/d_connectors.scad>
|
||||
@@ -72,7 +73,7 @@ use <tests/spades.scad>
|
||||
use <tests/springs.scad>
|
||||
use <tests/SSRs.scad>
|
||||
use <tests/stepper_motors.scad>
|
||||
use <tests/swiss_clips.scad>
|
||||
use <tests/Swiss_clips.scad>
|
||||
use <tests/toggles.scad>
|
||||
use <tests/transformers.scad>
|
||||
use <tests/tubings.scad>
|
||||
@@ -334,6 +335,9 @@ translate([x3 + 70, veroboard_y + 30])
|
||||
translate([x3 + 140, veroboard_y + 20])
|
||||
pcb_mounts();
|
||||
|
||||
translate([x3 + 170, veroboard_y + 16])
|
||||
cameras();
|
||||
|
||||
translate([x3, d_connectors_y])
|
||||
d_connectors();
|
||||
|
||||
@@ -381,7 +385,7 @@ sk_brackets_y = extrusion_brackets_y + 80;
|
||||
kp_pillow_blocks_y = sk_brackets_y + 50;
|
||||
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
|
||||
|
||||
translate([x4 + 150, belts_y + 58]) {
|
||||
translate([x4 + 200, belts_y + 58]) {
|
||||
belt_test();
|
||||
|
||||
translate([0, 60])
|
||||
|
169
printed/box.scad
@@ -31,29 +31,29 @@
|
||||
//!
|
||||
//! Normally the side sheets are the same type but they can be overridden individually as long as the substitute has the same thickness.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
include <../core.scad>
|
||||
use <../vitamins/sheet.scad>
|
||||
use <../vitamins/screw.scad>
|
||||
use <../vitamins/washer.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../utils/quadrant.scad>
|
||||
use <../utils/round.scad>
|
||||
|
||||
bezel_clearance = 0.2;
|
||||
sheet_end_clearance = 1;
|
||||
sheet_slot_clearance = 0.2;
|
||||
|
||||
function box_screw(type) = type[0]; //! Screw type to be used at the corners
|
||||
function box_wall(type) = type[1]; //! Wall thickness of 3D parts
|
||||
function box_sheets(type) = type[2]; //! Sheet type used for the sides
|
||||
function box_top_sheet(type) = type[3]; //! Sheet type for the top
|
||||
function box_base_sheet(type)= type[4]; //! Sheet type for the bottom
|
||||
function box_feet(type) = type[5]; //! True to enable feet on the bottom bezel
|
||||
function box_width(type) = type[6]; //! Internal width
|
||||
function box_depth(type) = type[7]; //! Internal depth
|
||||
function box_height(type) = type[8]; //! Internal height
|
||||
function box_screw(type) = type[0]; //! Screw type to be used at the corners
|
||||
function box_shelf_screw(type) = type[1]; //! Screw type to hold a shelf
|
||||
function box_wall(type) = type[2]; //! Wall thickness of 3D parts
|
||||
function box_sheets(type) = type[3]; //! Sheet type used for the sides
|
||||
function box_top_sheet(type) = type[4]; //! Sheet type for the top
|
||||
function box_base_sheet(type) = type[5]; //! Sheet type for the bottom
|
||||
function box_feet(type) = type[6]; //! True to enable feet on the bottom bezel
|
||||
function box_width(type) = type[7]; //! Internal width
|
||||
function box_depth(type) = type[8]; //! Internal depth
|
||||
function box_height(type) = type[9]; //! Internal height
|
||||
|
||||
function box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false) = //! Construct a property list for a box.
|
||||
concat([screw, wall, sheets, top_sheet, base_sheet, feet], size);
|
||||
function box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false, shelf_screw = M3_dome_screw) = //! Construct a property list for a box.
|
||||
concat([screw, shelf_screw, wall, sheets, top_sheet, base_sheet, feet], size);
|
||||
|
||||
function box_bezel_clearance(type) = bezel_clearance;
|
||||
|
||||
@@ -62,6 +62,7 @@ function box_profile_overlap(type) = 3 + sheet_end_clearance / 2;
|
||||
|
||||
function box_washer(type) = screw_washer(box_screw(type));
|
||||
function box_insert(type) = screw_insert(box_screw(type));
|
||||
function box_shelf_insert(type) = screw_insert(box_shelf_screw(type));
|
||||
|
||||
function box_hole_inset(type) = washer_radius(box_washer(type)) + 1;
|
||||
function box_insert_r(type) = insert_hole_radius(box_insert(type));
|
||||
@@ -90,23 +91,32 @@ function box_bezel_height(type, bottom) = //! Bezel height for top or bottom
|
||||
|
||||
grill_hole = 5;
|
||||
grill_gap = 1.9;
|
||||
module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling.
|
||||
|
||||
function box_grill_hole_r() = grill_hole / 2;
|
||||
|
||||
module grill_hole_positions(width, height, r = 1000) {
|
||||
nx = floor(width / (grill_hole + grill_gap));
|
||||
xpitch = width / nx;
|
||||
ny = floor(height / ((grill_hole + grill_gap) * cos(30)));
|
||||
ypitch = height / ny;
|
||||
|
||||
for(y = [0 : ny - 1], x = [0 : nx - 1 - (y % 2)]) {
|
||||
$x = -width / 2 + (x + 0.5 + (y % 2) / 2) * xpitch;
|
||||
$y = -height / 2 + (y + 0.5) * ypitch;
|
||||
if(sqrt(sqr($x) + sqr($y)) + grill_hole / 2 <= r)
|
||||
translate([$x, $y])
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling.
|
||||
extrude_if(h)
|
||||
for(y = [0 : ny - 1], x = [0 : nx - 1 - (y % 2)]) {
|
||||
x = -width / 2 + (x + 0.5 + (y % 2) / 2) * xpitch;
|
||||
y = -height / 2 + (y + 0.5) * ypitch;
|
||||
if(sqrt(sqr(x) + sqr(y)) + grill_hole / 2 <= r)
|
||||
translate([x, y])
|
||||
if(poly)
|
||||
poly_circle(r = grill_hole / 2);
|
||||
else
|
||||
circle(d = grill_hole);
|
||||
}
|
||||
if(poly)
|
||||
grill_hole_positions(width, height, r)
|
||||
poly_circle(r = grill_hole / 2);
|
||||
else
|
||||
grill_hole_positions(width, height, r)
|
||||
circle(d = grill_hole);
|
||||
}
|
||||
|
||||
module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
|
||||
@@ -178,6 +188,15 @@ module box_corner_profile_section(type, section, sections) { //! Generates inter
|
||||
}
|
||||
}
|
||||
|
||||
module box_corner_profile_sections(type, section, sections) { //! Generate four copies of a corner profile section
|
||||
stl("box_corner_profile");
|
||||
offset = box_boss_r(type) + 1;
|
||||
for(i = [0 : 3])
|
||||
rotate(i * 90)
|
||||
translate([offset, offset])
|
||||
box_corner_profile_section(type, section, sections);
|
||||
}
|
||||
|
||||
module box_corner_quadrants(type, width, depth)
|
||||
for(corner = [0:3]) {
|
||||
x = [-1,1,1,-1][corner];
|
||||
@@ -261,10 +280,11 @@ dowel_length = 20;
|
||||
dowel_wall = extrusion_width * 3;
|
||||
dowel_h_wall = layer_height * 6;
|
||||
|
||||
|
||||
module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlocking sections of the bezel to allow it to be bigger than the printer
|
||||
w = (box_width(type) + 2 * box_outset(type)) / cols;
|
||||
h = (box_depth(type) + 2 * box_outset(type)) / rows;
|
||||
tw = box_width(type) + 2 * box_outset(type);
|
||||
w = tw / cols;
|
||||
th = box_depth(type) + 2 * box_outset(type);
|
||||
h = th / rows;
|
||||
bw = box_outset(type) - bezel_clearance / 2;
|
||||
bw2 = box_outset(type) + box_inset(type);
|
||||
|
||||
@@ -339,7 +359,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([box_width(type) / 2 + box_outset(type) - x * w, box_depth(type) / 2 + box_outset(type) - y * h, box_profile_overlap(type)])
|
||||
translate([tw / 2 - x * w, th / 2 - y * h, box_profile_overlap(type)])
|
||||
box_bezel(type, bottom);
|
||||
|
||||
if(x < cols - 1 && y == 0)
|
||||
@@ -399,7 +419,6 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module box_screw_hole_positions(type)
|
||||
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))])
|
||||
@@ -442,6 +461,96 @@ module box_shelf_blank(type, sheet = false) { //! Generates a 2D template for a
|
||||
}
|
||||
}
|
||||
|
||||
module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = undef) { //! Place children at the shelf screw positions
|
||||
w = is_undef(wall) ? box_wall(type) : wall;
|
||||
insert = box_shelf_insert(type);
|
||||
translate_z(-insert_boss_radius(insert, w))
|
||||
for(p = screw_positions)
|
||||
multmatrix(p)
|
||||
translate_z(thickness)
|
||||
children();
|
||||
}
|
||||
|
||||
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts
|
||||
stl("shelf_bracket");
|
||||
w = is_undef(wall) ? box_wall(type) : wall;
|
||||
insert = box_shelf_insert(type);
|
||||
lip = 2 * insert_boss_radius(insert, w);
|
||||
width = insert_length(insert) + w;
|
||||
|
||||
module shape()
|
||||
difference() {
|
||||
square([box_width(type), box_depth(type)], center = true);
|
||||
|
||||
offset(bezel_clearance / 2)
|
||||
box_corner_quadrants(type, box_width(type), box_depth(type));
|
||||
|
||||
if($children)
|
||||
hflip()
|
||||
children();
|
||||
}
|
||||
|
||||
module boss()
|
||||
translate_z(-width + eps)
|
||||
linear_extrude(width - 2 * eps)
|
||||
hull() {
|
||||
circle4n(r = lip / 2 - eps);
|
||||
|
||||
translate([-lip / 2, -lip / 2 + eps])
|
||||
square([lip, eps]);
|
||||
}
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(w)
|
||||
difference() {
|
||||
shape()
|
||||
if($children)
|
||||
children(0);
|
||||
|
||||
round(2) offset(-width)
|
||||
shape()
|
||||
if($children)
|
||||
children(0);
|
||||
}
|
||||
|
||||
linear_extrude(lip)
|
||||
difference() {
|
||||
shape()
|
||||
if($children)
|
||||
children(0);
|
||||
|
||||
offset(-w)
|
||||
shape()
|
||||
if($children)
|
||||
children(0);
|
||||
}
|
||||
|
||||
hflip()
|
||||
box_shelf_screw_positions(type, screw_positions, 0, w)
|
||||
boss();
|
||||
}
|
||||
if($children > 1)
|
||||
hflip()
|
||||
children(1);
|
||||
|
||||
hflip()
|
||||
box_shelf_screw_positions(type, screw_positions, 0, w)
|
||||
insert_hole(insert, counterbore = 1, horizontal = true);
|
||||
}
|
||||
}
|
||||
|
||||
module box_shelf_bracket_section(type, rows, cols, x, y) { //! Generates sections of the shelf bracket to allow it to be bigger than the printer
|
||||
tw = box_width(type);
|
||||
w = tw / cols;
|
||||
th = box_depth(type);
|
||||
h = th / rows;
|
||||
|
||||
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
|
||||
translate([tw / 2 - x * w, th / 2 - y * h])
|
||||
children();
|
||||
}
|
||||
|
||||
module box_left_blank(type, sheet = false) { //! Generates a 2D template for the left sheet, ```sheet``` can be set to override the type
|
||||
dxf("box_left");
|
||||
|
||||
|
@@ -110,12 +110,9 @@ function fixing_block_positions(type) = let(
|
||||
|
||||
function side_holes(type) = [for(p = fixing_block_positions(type), q = fixing_block_holes(bbox_screw(type))) p * q];
|
||||
|
||||
module drill_holes(type, t)
|
||||
for(list = [corner_holes(type), side_holes(type)], p = list)
|
||||
let(q = t * p)
|
||||
if(abs(transform([0, 0, 0], q).z) < eps)
|
||||
multmatrix(q)
|
||||
drill(screw_clearance_radius(bbox_screw(type)), 0);
|
||||
module bbox_drill_holes(type, t)
|
||||
position_children(concat(corner_holes(type), side_holes(type)), t)
|
||||
drill(screw_clearance_radius(bbox_screw(type)), 0);
|
||||
|
||||
module bbox_base_blank(type) { //! 2D template for the base
|
||||
dxf(str(bbox_name(type), "_base"));
|
||||
@@ -123,7 +120,7 @@ module bbox_base_blank(type) { //! 2D template for the base
|
||||
difference() {
|
||||
sheet_2D(bbox_base_sheet(type), bbox_width(type), bbox_depth(type), 1);
|
||||
|
||||
drill_holes(type, translate(bbox_height(type) / 2));
|
||||
bbox_drill_holes(type, translate(bbox_height(type) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +133,7 @@ module bbox_top_blank(type) { //! 2D template for the top
|
||||
translate([0, t / 2])
|
||||
sheet_2D(bbox_top_sheet(type), bbox_width(type) + 2 * t, bbox_depth(type) + t);
|
||||
|
||||
drill_holes(type, translate(-bbox_height(type) / 2));
|
||||
bbox_drill_holes(type, translate(-bbox_height(type) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +151,7 @@ module bbox_left_blank(type, sheet = false) { //! 2D template for the left side
|
||||
translate([-t / 2, -bb / 2])
|
||||
sheet_2D(subst_sheet(type, sheet), bbox_depth(type) + t, bbox_height(type) + bb);
|
||||
|
||||
drill_holes(type, rotate([0, 90, 90]) * translate([bbox_width(type) / 2, 0]));
|
||||
bbox_drill_holes(type, rotate([0, 90, 90]) * translate([bbox_width(type) / 2, 0]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +165,7 @@ module bbox_right_blank(type, sheet = false) { //! 2D template for the right sid
|
||||
translate([t / 2, -bb / 2])
|
||||
sheet_2D(subst_sheet(type, sheet), bbox_depth(type) + t, bbox_height(type) + bb);
|
||||
|
||||
drill_holes(type, rotate([0, 90, 90]) * translate([-bbox_width(type) / 2, 0]));
|
||||
bbox_drill_holes(type, rotate([0, 90, 90]) * translate([-bbox_width(type) / 2, 0]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +180,7 @@ module bbox_front_blank(type, sheet = false, width = 0) { //! 2D template for th
|
||||
translate([0, (bt - bb) / 2])
|
||||
sheet_2D(subst_sheet(type, sheet), max(bbox_width(type) + 2 * t, width), bbox_height(type) + bb + bt);
|
||||
|
||||
drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
|
||||
bbox_drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +194,7 @@ module bbox_back_blank(type, sheet = false) { //! 2D template for the back
|
||||
translate([0, -bb / 2])
|
||||
sheet_2D(subst_sheet(type, sheet), bbox_width(type), bbox_height(type) + bb);
|
||||
|
||||
drill_holes(type, rotate([-90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
|
||||
bbox_drill_holes(type, rotate([-90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -74,7 +74,7 @@ module door_hinge(door_thickness) { //! Generates STL fo
|
||||
square([1, thickness + door_thickness]);
|
||||
}
|
||||
translate([dia / 2, thickness + door_thickness / 2])
|
||||
teardrop(r = screw_clearance_radius(pin_screw), h = 0);
|
||||
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
|
||||
}
|
||||
linear_extrude(thickness)
|
||||
difference() {
|
||||
@@ -127,7 +127,7 @@ module door_hinge_stat_stl() { //! Generates the STL for the stationary part
|
||||
square([dia, 1], center = true);
|
||||
}
|
||||
translate([0, dia / 2 + stat_clearance])
|
||||
teardrop(r = screw_clearance_radius(pin_screw), h = 0);
|
||||
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
247
readme.md
@@ -22,26 +22,26 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||
<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 = "#Dogbones">Dogbones</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 = "#Fillet">Fillet</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 = "#Hanging_hole">Hanging_hole</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 = "#Layout">Layout</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 = "#Maths">Maths</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 = "#Offset">Offset</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 = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Round">Round</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 = "#Foot">Foot</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</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 = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</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 = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Sector">Sector</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 = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sweep">Sweep</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 = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</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 = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</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 = "#SSR_shroud">SSR_shroud</a> </td><td></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 = "#Screw_knob">Screw_knob</a> </td><td></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 = "#Socket_box">Socket_box</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 = "#Strap_handle">Strap_handle</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></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></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>
|
||||
<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 = "#Gears">Gears</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 = "#Hanging_hole">Hanging_hole</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 = "#Horiholes">Horiholes</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 = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pillars">Pillars</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 = "#Pin_headers">Pin_headers</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 = "#Pulleys">Pulleys</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></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>
|
||||
</table>
|
||||
|
||||
---
|
||||
@@ -133,7 +133,8 @@ Also single bearing balls are modelled as just a silver sphere and a BOM entry.
|
||||
| 1 | ```ball_bearing(BB6201)``` | Ball bearing 6201-2RS 12mm x 32mm x 10mm |
|
||||
| 1 | ```ball_bearing(BB624)``` | Ball bearing 624-2RS 4mm x 13mm x 5mm |
|
||||
| 1 | ```ball_bearing(BB6808)``` | Ball bearing 6808-2RS 40mm x 52mm x 7mm |
|
||||
| 5 | ``` bearing_ball(3)``` | Steel ball 3mm |
|
||||
| 1 | ```ball_bearing(BBSMR95)``` | Ball bearing SMR95ZZ 5mm x 9mm x 2.5mm |
|
||||
| 6 | ``` bearing_ball(3)``` | Steel ball 3mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@@ -235,7 +236,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
|
||||
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
|
||||
|
||||

|
||||
|
||||
@@ -430,6 +431,45 @@ When the sides are constrained then a circular model is more accurate.
|
||||
| 3 | ```cable_strip(20, 25, 100, 30)``` | Polypropylene strip 189mm x 24mm x 0.8mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Cameras"></a>
|
||||
## Cameras
|
||||
PCB cameras.
|
||||
|
||||
|
||||
[vitamins/cameras.scad](vitamins/cameras.scad) Object definitions.
|
||||
|
||||
[vitamins/camera.scad](vitamins/camera.scad) Implementation.
|
||||
|
||||
[tests/cameras.scad](tests/cameras.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```camera_connector_pos(type)``` | The flex connector block for the camera itself's position |
|
||||
| ```camera_connector_size(type)``` | The flex connector block for the camera itself's size |
|
||||
| ```camera_lens(type)``` | Stack of lens parts, can be round, rectanular or rounded rectangular, with optional tapered aperture |
|
||||
| ```camera_lens_offset(type)``` | Offset of the lens center from the PCB centre |
|
||||
| ```camera_pcb(type)``` | The PCB part of the camera |
|
||||
|
||||
### 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 |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 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 |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -1554,9 +1594,10 @@ The `light_strip_clip()` module makes a clip to go around the light that can be
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```light_strip_clip_depth(light)``` | Depth of the clip |
|
||||
| ```light_strip_clip_length(light)``` | Outside length |
|
||||
| ```light_strip_clip_length(light)``` | Outside length of clip |
|
||||
| ```light_strip_clip_slot(light)``` | Clip slot size |
|
||||
| ```light_strip_clip_width(light)``` | Outside width |
|
||||
| ```light_strip_clip_wall()``` | Clip wall thickness |
|
||||
| ```light_strip_clip_width(light)``` | Outside width of clip |
|
||||
| ```light_strip_cut_length(type, segs)``` | Calculate cut length given segments |
|
||||
| ```light_strip_segments(type, max_length)``` | Calculate the maximum number of segments that fit in max_length |
|
||||
|
||||
@@ -2033,6 +2074,10 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```ff_back(type)``` | Flat flex back section size |
|
||||
| ```ff_latch(type)``` | Flat flex latch size |
|
||||
| ```ff_mid(type)``` | Flat flex middle section size |
|
||||
| ```ff_slot(type)``` | Flat flex slot size |
|
||||
| ```hdmi_depth(type)``` | Front to back depth |
|
||||
| ```hdmi_height(type)``` | Outside height above the PCB |
|
||||
| ```hdmi_height1(type)``` | Inside height at the sides |
|
||||
@@ -2062,6 +2107,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
|
||||
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
|
||||
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
|
||||
| ```pcb_size(type)``` | Length, width and thickness in a vector |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
@@ -2070,7 +2116,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| ```block(size, colour, makes_cutout, cutouts)``` | Draw a coloured cube to represent a random PCB component |
|
||||
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and colour |
|
||||
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
|
||||
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
|
||||
| ```flat_flex(type, cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
|
||||
| ```flex(cutout = false)``` | Draw flexistrip connector |
|
||||
| ```hdmi(type, cutout = false)``` | Draw HDMI socket |
|
||||
| ```jack(cutout = false)``` | Draw 3.5mm jack |
|
||||
@@ -2125,7 +2171,11 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | ```ax_res(res1_4, 10000)``` | Resistor 10000 Ohms 5% 0.25W |
|
||||
| 1 | ```ax_res(res1_2, 100000)``` | Resistor 100000 Ohms 5% 0.5W |
|
||||
| 1 | ```ax_res(res1_8, 1e+6, tol = 1)``` | Resistor 1e+6 Ohms 1% 0.125W |
|
||||
| 1 | ```smd_led(LED0603, orange)``` | SMD LED 0603 orange |
|
||||
| 1 | ```smd_led(LED0805, red)``` | SMD LED 0805 red |
|
||||
| 1 | ```smd_resistor(RES0603, 1K)``` | SMD resistor 0603 1K 0.1W |
|
||||
| 1 | ```smd_resistor(RES0805, 1K)``` | SMD resistor 0805 1K 0.125W |
|
||||
| 1 | ```smd_resistor(RES1206, 1K)``` | SMD resistor 1206 1K 0.25W |
|
||||
| 1 | ```square_button(button_6mm)``` | Square button 6mm |
|
||||
| 1 | ```pcb(TMC2130)``` | TMC2130 |
|
||||
| 1 | ```green_terminal(gt_5p08, 2)``` | Terminal block 2 way 0.2" |
|
||||
@@ -2157,6 +2207,10 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```ff_back(type)``` | Flat flex back section size |
|
||||
| ```ff_latch(type)``` | Flat flex latch size |
|
||||
| ```ff_mid(type)``` | Flat flex middle section size |
|
||||
| ```ff_slot(type)``` | Flat flex slot size |
|
||||
| ```hdmi_depth(type)``` | Front to back depth |
|
||||
| ```hdmi_height(type)``` | Outside height above the PCB |
|
||||
| ```hdmi_height1(type)``` | Inside height at the sides |
|
||||
@@ -2186,6 +2240,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
|
||||
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
|
||||
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
|
||||
| ```pcb_size(type)``` | Length, width and thickness in a vector |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
@@ -2194,7 +2249,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| ```block(size, colour, makes_cutout, cutouts)``` | Draw a coloured cube to represent a random PCB component |
|
||||
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and colour |
|
||||
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
|
||||
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
|
||||
| ```flat_flex(type, cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
|
||||
| ```flex(cutout = false)``` | Draw flexistrip connector |
|
||||
| ```hdmi(type, cutout = false)``` | Draw HDMI socket |
|
||||
| ```jack(cutout = false)``` | Draw 3.5mm jack |
|
||||
@@ -2591,10 +2646,10 @@ Linear rails with carriages.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```carriage(type, rail, end_colour = grey20, wiper_colour = grey20)``` | Draw the specified carriage |
|
||||
| ```carriage(type, rail, end_colour = grey(20)``` | Draw the specified carriage |
|
||||
| ```carriage_hole_positions(type)``` | Position children over screw holes |
|
||||
| ```rail(type, length)``` | Draw the specified rail |
|
||||
| ```rail_assembly(type, length, pos, carriage_end_colour = grey20, carriage_wiper_colour = grey20)``` | Rail and carriage assembly |
|
||||
| ```rail_assembly(type, length, pos, carriage_end_colour = grey(20)``` | Rail and carriage assembly |
|
||||
| ```rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true)``` | Position children over screw holes |
|
||||
| ```rail_screws(type, length, thickness, screws = 100)``` | Place screws in the rail |
|
||||
|
||||
@@ -2603,24 +2658,27 @@ Linear rails with carriages.
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```rail(MGN15, 260)``` | Linear rail MGN15 x 260mm |
|
||||
| 1 | ```rail(MGN12, 200)``` | Linear rail MGN12 x 200mm |
|
||||
| 1 | ```rail(MGN12H, 200)``` | Linear rail MGN12H x 200mm |
|
||||
| 1 | ```rail(MGN15, 200)``` | Linear rail MGN15 x 200mm |
|
||||
| 1 | ```rail(MGN5, 200)``` | Linear rail MGN5 x 200mm |
|
||||
| 1 | ```rail(MGN7, 200)``` | Linear rail MGN7 x 200mm |
|
||||
| 1 | ```rail(MGN9, 200)``` | Linear rail MGN9 x 200mm |
|
||||
| 1 | ```rail(SSR15, 200)``` | Linear rail SSR15 x 200mm |
|
||||
| 26 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
|
||||
| 17 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 31 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 4 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
|
||||
| 11 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
|
||||
| 15 | ```screw(M2_cs_cap_screw, 10)``` | Screw M2 cs cap x 10mm |
|
||||
| 8 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
|
||||
| 5 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
|
||||
| 12 | ```screw(M3_cap_screw, 12)``` | Screw M3 cap x 12mm |
|
||||
| 3 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
|
||||
| 2 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
|
||||
| 2 | ```screw(M3_cs_cap_screw, 16)``` | Screw M3 cs cap x 16mm |
|
||||
| 6 | ```screw(M3_cs_cap_screw, 16)``` | Screw M3 cs cap x 16mm |
|
||||
| 2 | ```screw(M4_cap_screw, 16)``` | Screw M4 cap x 16mm |
|
||||
| 2 | ```screw(M4_cs_cap_screw, 20)``` | Screw M4 cs cap x 20mm |
|
||||
| 26 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
|
||||
| 17 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 31 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 4 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
|
||||
|
||||
|
||||
@@ -3080,11 +3138,14 @@ Surface mount components for PCBs.
|
||||
|:--- |:--- |
|
||||
| ```smd_led_lens(type)``` | Lens length width and height |
|
||||
| ```smd_led_size(type)``` | Body length, width and height |
|
||||
| ```smd_res_end_cap(type)``` | End cap width |
|
||||
| ```smd_res_power(type)``` | Power rating in Watts |
|
||||
| ```smd_res_size(type)``` | Body length, width and height |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```smd_100th(x)``` | Convert dimesion to 1/100" notation |
|
||||
| ```smd_100th(x)``` | Convert dimension to 1/100" notation |
|
||||
| ```smd_led_height(type)``` | Total height |
|
||||
| ```smd_size(size)``` | Convert size to 1/100" notation |
|
||||
|
||||
@@ -3092,13 +3153,18 @@ Surface mount components for PCBs.
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```smd_led(type, colour, cutout)``` | Draw an SMD LED with specified ```colour``` |
|
||||
| ```smd_resistor(type, value)``` | Draw an SMD resistor with specified value |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```smd_led(LED0805, green)``` | SMD LED 0805 green |
|
||||
| 1 | ```smd_led(LED0603, green)``` | SMD LED 0603 green |
|
||||
| 1 | ```smd_led(LED0805, blue)``` | SMD LED 0805 blue |
|
||||
| 1 | ```smd_resistor(RES0603, 1R0)``` | SMD resistor 0603 1R0 0.1W |
|
||||
| 1 | ```smd_resistor(RES0805, 10M)``` | SMD resistor 0805 10M 0.125W |
|
||||
| 1 | ```smd_resistor(RES1206, 100K)``` | SMD resistor 1206 100K 0.25W |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@@ -3872,6 +3938,7 @@ Normally the side sheets are the same type but they can be overridden individual
|
||||
| ```box_height(type)``` | Internal height |
|
||||
| ```box_screw(type)``` | Screw type to be used at the corners |
|
||||
| ```box_sheets(type)``` | Sheet type used for the sides |
|
||||
| ```box_shelf_screw(type)``` | Screw type to hold a shelf |
|
||||
| ```box_top_sheet(type)``` | Sheet type for the top |
|
||||
| ```box_wall(type)``` | Wall thickness of 3D parts |
|
||||
| ```box_width(type)``` | Internal width |
|
||||
@@ -3879,7 +3946,7 @@ Normally the side sheets are the same type but they can be overridden individual
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false)``` | Construct a property list for a box. |
|
||||
| ```box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false, shelf_screw = M3_dome_screw)``` | Construct a property list for a box. |
|
||||
| ```box_bezel_height(type, bottom)``` | Bezel height for top or bottom |
|
||||
| ```box_corner_gap(type)``` | Gap between box_sheets at the corners to connect inside and outside profiles |
|
||||
| ```box_inset(type)``` | How much the bezel intrudes on the specified width and length, away from the corners |
|
||||
@@ -3899,6 +3966,7 @@ Normally the side sheets are the same type but they can be overridden individual
|
||||
| ```box_corner_profile(type)``` | Generates the corner profile STL for 3D printing. |
|
||||
| ```box_corner_profile_2D(type)``` | The 2D shape of the corner profile. |
|
||||
| ```box_corner_profile_section(type, section, sections)``` | Generates interlocking sections of the corner profile to allow it to be taller than the printer |
|
||||
| ```box_corner_profile_sections(type, section, sections)``` | Generate four copies of a corner profile section |
|
||||
| ```box_front(type)``` | Default front, can be overridden to customise |
|
||||
| ```box_front_blank(type, sheet = false)``` | Generates a 2D template for the front sheet, ```sheet``` can be set to override the type |
|
||||
| ```box_left(type)``` | Default left side, can be overridden to customise |
|
||||
@@ -3906,6 +3974,9 @@ Normally the side sheets are the same type but they can be overridden individual
|
||||
| ```box_right(type)``` | Default right side, can be overridden to customise |
|
||||
| ```box_right_blank(type, sheet = false)``` | Generates a 2D template for the right sheet, ```sheet``` can be set to override the type |
|
||||
| ```box_shelf_blank(type, sheet = false)``` | Generates a 2D template for a shelf sheet |
|
||||
| ```box_shelf_bracket(type, screw_positions, wall = undef)``` | Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts |
|
||||
| ```box_shelf_bracket_section(type, rows, cols, x, y)``` | Generates sections of the shelf bracket to allow it to be bigger than the printer |
|
||||
| ```box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = undef)``` | Place children at the shelf screw positions |
|
||||
| ```box_top(type)``` | Default top, can be overridden to customise |
|
||||
| ```box_top_blank(type)``` | Generates a 2D template for the top sheet |
|
||||
| ```grill(width, height, r = 1000, poly = false, h = 0)``` | A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling. |
|
||||
@@ -5150,6 +5221,53 @@ Rounded fillet for adding to corners.
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Gears"></a>
|
||||
## Gears
|
||||
Utilities for making involute gears.
|
||||
|
||||
Formulas from <https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html>
|
||||
<https://khkgears.net/new/gear_knowledge/gear_technical_reference/calculation_gear_dimensions.html>
|
||||
and <https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/>
|
||||
|
||||
```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
|
||||
Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```.
|
||||
|
||||
Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered
|
||||
the practical minimum.
|
||||
|
||||
The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter.
|
||||
|
||||
The origin of the rack is the left end of the pitch line and its width is below the pitch line. I.e. it does not include the addendum.
|
||||
|
||||
```involute_worm_profile()``` returns a tooth profile that can be passed to ```thread()``` to make worms.
|
||||
|
||||
|
||||
[utils/gears.scad](utils/gears.scad) Implementation.
|
||||
|
||||
[tests/gears.scad](tests/gears.scad) Code for this example.
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```centre_distance(m, z1, z2, pa = 20)``` | Calculate distance between centres taking profile shift into account |
|
||||
| ```involute(r, u)``` | Involute of circle radius r at angle u in radians |
|
||||
| ```involute_gear_od(m, z, pa = 20)``` | involute gear outside diameter given modulus, tooth count and pressure angle |
|
||||
| ```involute_rack_tooth_profile(m, pa = 20, clearance = undef)``` | Calculate rack tooth profile given module and pressure angle |
|
||||
| ```involute_worm_profile(m, pa = 20, clearance = undef)``` | Calculate worm profile suitable for passing to thread() |
|
||||
| ```profile_shift(z, pa)``` | Calculate profile shift for small gears |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20)``` | Calculate gear profile given module, number of teeth and pressure angle |
|
||||
| ```involute_rack_profile(m, z, w, pa = 20, clearance = undef)``` | Calculate rack profile given module, number of teeth and pressure angle |
|
||||
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -5170,6 +5288,31 @@ Method to print holes in mid air. See <https://hydraraptor.blogspot.com/2014/03/
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Horiholes"></a>
|
||||
## Horiholes
|
||||
Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops), see <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
|
||||
|
||||
[utils/horiholes.scad](utils/horiholes.scad) Implementation.
|
||||
|
||||
[tests/horiholes.scad](tests/horiholes.scad) Code for this example.
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```teardrop_plus_x(r, y, h)``` | Calculate the ordinate of a compensated teardrop given y and layer height. |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```horihole(r, z, h = 0, center = true)``` | For making horizontal holes that don't need support material and are correct dimensions |
|
||||
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -5211,12 +5354,22 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```angle_between(v1, v2)``` | Return the angle between two vectors |
|
||||
| ```augment(m)``` | Augment a matrix by adding an identity matrix to the right |
|
||||
| ```degrees(radians)``` | Convert degrees to radians |
|
||||
| ```euler(R)``` | Convert a rotation matrix to a Euler rotation vector. |
|
||||
| ```identity(n, x = 1)``` | Construct an arbitrary size identity matrix |
|
||||
| ```invert(m)``` | Invert a matrix |
|
||||
| ```nearly_zero(x)``` | True if x is close to zero |
|
||||
| ```radians(degrees)``` | Convert radians to degrees |
|
||||
| ```reverse(v)``` | Reverse a vector |
|
||||
| ```rot2_z(a)``` | Generate a 2x2 matrix to rotate around z |
|
||||
| ```rot3_z(a)``` | Generate a 3x3 matrix to rotate around z |
|
||||
| ```rotate(a, v)``` | Generate a 4x4 rotation matrix, ```a``` can be a vector of three angles or a single angle around ```z```, or around axis ```v``` |
|
||||
| ```rowswap(m, i, j)``` | Swap two rows of a matrix |
|
||||
| ```scale(v)``` | Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally |
|
||||
| ```solve(m, i = 0, j = 0)``` | Solve each row ensuring diagonal is not zero |
|
||||
| ```solve_row(m, i)``` | Make diagonal one by dividing the row by it and subtract from other rows to make column zero |
|
||||
| ```sqr(x)``` | Square x |
|
||||
| ```transform(v, m)``` | Apply 4x4 transform to a 3 vector by extending it and cropping it again |
|
||||
| ```transform_points(path, m)``` | Apply transform to a path |
|
||||
| ```translate(v)``` | Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z``` |
|
||||
@@ -5225,6 +5378,11 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| ```vec3(v)``` | Return a 3 vector with the first three elements of ```v``` |
|
||||
| ```vec4(v)``` | Return a 4 vector with the first three elements of ```v``` |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```position_children(list, t)``` | Position children if they are on the Z = 0 plane when transformed by t |
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -5419,6 +5577,8 @@ specify a chamfer angle.
|
||||
Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
|
||||
example to make a printed pot with a screw top lid.
|
||||
|
||||
A left hand thread can be made by using mirror([0,1]).
|
||||
|
||||
Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
|
||||
a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
|
||||
|
||||
@@ -5445,7 +5605,7 @@ Threads obey the $fn, $fa, $fs variables.
|
||||
|:--- |:--- |
|
||||
| ```female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, colour = undef)``` | Create female thread with metric profile |
|
||||
| ```male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef)``` | Create male thread with metric profile |
|
||||
| ```thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef)``` | Create male or femail thread, ends can be tapered, chamfered or square |
|
||||
| ```thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef)``` | Create male or female thread, ends can be tapered, chamfered or square |
|
||||
|
||||

|
||||
|
||||
@@ -5725,6 +5885,9 @@ This ensures `hull` and `minkowski` results have the correct dimensions when sph
|
||||
For making horizontal holes that don't need support material.
|
||||
Small holes can get away without it, but they print better with truncated teardrops.
|
||||
|
||||
Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips
|
||||
do not intrude into the circle. See <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
|
||||
|
||||
[utils/core/teardrops.scad](utils/core/teardrops.scad) Implementation.
|
||||
|
||||
@@ -5733,12 +5896,12 @@ Small holes can get away without it, but they print better with truncated teardr
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```semi_teardrop(h, r, d = undef, center = true, chamfer = 0)``` | A semi teardrop in the positive Y domain |
|
||||
| ```teardrop(h, r, center = true, truncate = true, chamfer = 0)``` | For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging |
|
||||
| ```semi_teardrop(h, r, d = undef, center = true, chamfer = 0, plus = false)``` | A semi teardrop in the positive Y domain |
|
||||
| ```teardrop(h, r, center = true, truncate = true, chamfer = 0, plus = false)``` | For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging |
|
||||
| ```teardrop_chamfer(h, center, chamfer)``` | Helper module for adding chamfer to a teardrop |
|
||||
| ```teardrop_plus(h, r, center = true, truncate = true, chamfer = 0)``` | Slightly bigger teardrop to allow for the 3D printing staircase effect |
|
||||
| ```tearslot(h, r, w, center = true, chamfer = 0)``` | A horizontal slot that doesn't need support material |
|
||||
| ```vertical_tearslot(h, r, l, center = true, chamfer = 0)``` | A vertical slot that doesn't need support material |
|
||||
| ```teardrop_plus(h, r, center = true, truncate = true, chamfer = 0)``` | Slightly elongated teardrop to allow for the 3D printing staircase effect |
|
||||
| ```tearslot(h, r, w, center = true, chamfer = 0, plus = false)``` | A horizontal slot that doesn't need support material |
|
||||
| ```vertical_tearslot(h, r, l, center = true, chamfer = 0, plus = false)``` | A vertical slot that doesn't need support material |
|
||||
|
||||

|
||||
|
||||
|
@@ -27,6 +27,7 @@ import c14n_stl
|
||||
from set_config import *
|
||||
from deps import *
|
||||
from shutil import copyfile
|
||||
import re
|
||||
|
||||
source_dirs = { "stl" : "platters", "dxf" : "panels" }
|
||||
target_dirs = { "stl" : "printed", "dxf" : "routed" }
|
||||
@@ -38,43 +39,54 @@ def plateup(target, part_type, usage = None):
|
||||
top_dir = set_config(target, usage)
|
||||
parts_dir = top_dir + part_type + 's'
|
||||
target_dir = parts_dir + '/' + target_dirs[part_type]
|
||||
source_dir = top_dir + source_dirs[part_type]
|
||||
deps_dir = source_dir + "/deps"
|
||||
if not os.path.isdir(source_dir):
|
||||
return
|
||||
if not os.path.isdir(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
if not os.path.isdir(deps_dir):
|
||||
os.makedirs(deps_dir)
|
||||
source_dir1 = source_dirs[part_type]
|
||||
source_dir2 = top_dir + source_dirs[part_type]
|
||||
#
|
||||
# Decide which files to make
|
||||
#
|
||||
sources = [file for file in os.listdir(source_dir) if file.endswith('.scad')]
|
||||
#
|
||||
# Run OpenSCAD on the source files to make the targets
|
||||
# Loop through source directories
|
||||
#
|
||||
used = []
|
||||
for src in sources:
|
||||
src_file = source_dir + '/' + src
|
||||
part_file = target_dir + '/' + src[:-4] + part_type
|
||||
dname = deps_name(deps_dir, src)
|
||||
changed = check_deps(part_file, dname)
|
||||
if changed:
|
||||
print(changed)
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
|
||||
if part_type == 'stl':
|
||||
c14n_stl.canonicalise(part_file)
|
||||
log_name = 'openscad.log'
|
||||
else:
|
||||
log_name = 'openscad.echo'
|
||||
openscad.run_silent("-D$bom=1", "-o", log_name, src_file)
|
||||
all_sources = []
|
||||
for dir in [source_dir1, source_dir2]:
|
||||
if not os.path.isdir(dir):
|
||||
continue
|
||||
if not os.path.isdir(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
#
|
||||
# Add the files on the BOM to the used list
|
||||
# Make the deps dir
|
||||
#
|
||||
with open(log_name) as file:
|
||||
for line in file.readlines():
|
||||
if line.startswith('ECHO: "~') and line.endswith('.' + part_type + '"\n'):
|
||||
used.append(line[8:-2])
|
||||
deps_dir = dir + "/deps"
|
||||
if not os.path.isdir(deps_dir):
|
||||
os.makedirs(deps_dir)
|
||||
#
|
||||
# Decide which files to make
|
||||
#
|
||||
sources = [file for file in os.listdir(dir) if file.endswith('.scad')]
|
||||
all_sources += sources
|
||||
#
|
||||
# Run OpenSCAD on the source files to make the targets
|
||||
#
|
||||
for src in sources:
|
||||
src_file = dir + '/' + src
|
||||
part_file = target_dir + '/' + src[:-4] + part_type
|
||||
dname = deps_name(deps_dir, src)
|
||||
changed = check_deps(part_file, dname)
|
||||
if changed:
|
||||
print(changed)
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
|
||||
if part_type == 'stl':
|
||||
c14n_stl.canonicalise(part_file)
|
||||
log_name = 'openscad.log'
|
||||
else:
|
||||
log_name = 'openscad.echo'
|
||||
openscad.run_silent("-D$bom=1", "-o", log_name, src_file)
|
||||
#
|
||||
# Add the files on the BOM to the used list
|
||||
#
|
||||
with open(log_name) as file:
|
||||
for line in file.readlines():
|
||||
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
|
||||
if match:
|
||||
used.append(match.group(1))
|
||||
#
|
||||
# Copy file that are not included
|
||||
#
|
||||
@@ -90,7 +102,7 @@ def plateup(target, part_type, usage = None):
|
||||
#
|
||||
# Remove any cruft
|
||||
#
|
||||
targets = [file[:-4] + part_type for file in sources]
|
||||
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:
|
||||
|
@@ -58,8 +58,12 @@ test_pcb = ["TestPCB", "Test PCB",
|
||||
// components
|
||||
[
|
||||
[ 20, -5, 180, "trimpot10"],
|
||||
[ 20, -15, 0, "trimpot10", true],
|
||||
[ 10, 2, 0, "smd_led", LED0805, "red"],
|
||||
[ 20, -15, 90, "trimpot10", true],
|
||||
[ 10, 2, 90, "smd_led", LED0805, "red"],
|
||||
[ 13, 2, 90, "smd_led", LED0603, "orange"],
|
||||
[ 16, 2, 90, "smd_res", RES1206, "1K"],
|
||||
[ 19, 2, 90, "smd_res", RES0805, "1K"],
|
||||
[ 22, 2, 90, "smd_res", RES0603, "1K"],
|
||||
[ 10, 10, 0, "2p54header", 4, 1],
|
||||
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
|
||||
[ 10, 20, 0, "2p54boxhdr", 4, 2],
|
||||
@@ -91,7 +95,8 @@ test_pcb = ["TestPCB", "Test PCB",
|
||||
[ 80, 22, 0, "ax_res", res1_2, 10, 10, inch(0.2)],
|
||||
|
||||
[ 60, 3, 0, "flex"],
|
||||
[ 50, 15, 0, "flat_flex"],
|
||||
[ 50, 15, -90, "flat_flex"],
|
||||
[ 40, 15, -90, "flat_flex", true],
|
||||
[ 60, 35, 0, "D_plug", DCONN9],
|
||||
|
||||
[ 50, 50, 0, "molex_hdr", 2],
|
||||
|
@@ -21,9 +21,14 @@ use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/smds.scad>
|
||||
|
||||
module smds()
|
||||
layout([for(l = smd_leds) smd_led_size(l).x], 1)
|
||||
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
|
||||
module smds() {
|
||||
layout([for(r = smd_resistors) smd_res_size(r).x], 1)
|
||||
smd_resistor(smd_resistors[$i], ["1R0", "10M", "100K"][$i % 3]);
|
||||
|
||||
translate([0, 3])
|
||||
layout([for(l = smd_leds) smd_led_size(l).x], 1)
|
||||
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
smds();
|
||||
|
31
tests/cameras.scad
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// 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>
|
||||
|
||||
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])
|
||||
camera(c);
|
||||
|
||||
if($preview)
|
||||
cameras();
|
66
tests/gears.scad
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/gears.scad>
|
||||
|
||||
// left gear teeth
|
||||
z1 = 39; // [7 : 1 : 99]
|
||||
|
||||
// Right gear teeth
|
||||
z2 = 7; // [7 : 1 : 99]
|
||||
|
||||
// Modulus
|
||||
m = 2.0; // [0.1 : 0.1 : 5.0]
|
||||
|
||||
// Pressure angle
|
||||
pa = 20; // [14.5, 20, 22.5, 25]
|
||||
|
||||
$show_numbers = false;
|
||||
|
||||
module gears() {
|
||||
color(pp1_colour)
|
||||
rotate(-$t * 360)
|
||||
linear_extrude(eps, center = true, convexity = z1)
|
||||
difference() {
|
||||
involute_gear_profile(m, z1, pa);
|
||||
|
||||
circle(r = m * z1 / 10);
|
||||
}
|
||||
|
||||
color(pp2_colour)
|
||||
translate([centre_distance(m, z1, z2, pa), 0])
|
||||
rotate(180 + 180 / z2 + $t * 360 * z1 / z2)
|
||||
linear_extrude(eps, center = true, convexity = z2)
|
||||
difference() {
|
||||
involute_gear_profile(m, z2, pa);
|
||||
|
||||
circle(r = m * z2 / 10);
|
||||
}
|
||||
|
||||
z3 = floor((z1 + z2) / PI);
|
||||
angle = -$t * 360 + 90 - floor(z1 / 4) * 360 / z1; // Line up the rack 1/4 turn around the gear
|
||||
pitch = m * PI;
|
||||
color(pp3_colour)
|
||||
translate([(angle % ((z3 / z1) * 360)) / 360 * z1 * pitch, -centre_distance(m, z1, 0, pa)])
|
||||
linear_extrude(eps, center = true)
|
||||
involute_rack_profile(m, z3, 3 * m, pa);
|
||||
}
|
||||
|
||||
rotate(is_undef($bom) ? 0 : [70, 0, 315])
|
||||
gears();
|
90
tests/horiholes.scad
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
$layer_height = 0.25;
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/horiholes.scad>
|
||||
|
||||
show_disc = true;
|
||||
use_horihole = true;
|
||||
thickness = 6;
|
||||
length = 60;
|
||||
height = 20;
|
||||
overlap_x = 15;
|
||||
overlap_y = 10;
|
||||
|
||||
module hole_positions() {
|
||||
x0 = (length - 40) / 2;
|
||||
for($i = [0 : 4], $z = 5 + $i * layer_height / 5, $r = 3)
|
||||
translate([x0 + $i * 10, $z])
|
||||
children();
|
||||
|
||||
for($i = [0 : 4], $z = 15 + $i * layer_height / 5, $r = 0.5 + $i / 2)
|
||||
translate([x0 + $i * 10, $z])
|
||||
children();
|
||||
}
|
||||
|
||||
module horiholes_stl(t = thickness) {
|
||||
rotate([90, 0, 0])
|
||||
difference() {
|
||||
linear_extrude(t, center = true) {
|
||||
difference() {
|
||||
square([length, height]);
|
||||
|
||||
hole_positions()
|
||||
if(use_horihole)
|
||||
horihole($r, $z);
|
||||
else
|
||||
teardrop_plus(h = 0, r = $r);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(t == thickness)
|
||||
translate([length / 2, 0])
|
||||
rounded_rectangle([length + 2 * overlap_x, thickness + 2 * overlap_y, 2], 5);
|
||||
}
|
||||
|
||||
module horiholes() {
|
||||
stl_colour(pp1_colour)
|
||||
rotate([-90, 0, 0])
|
||||
horiholes_stl(eps);
|
||||
|
||||
if(show_disc)
|
||||
hole_positions()
|
||||
color(silver)
|
||||
cylinder(r = $r, h = eps, center = true, $fn = 360);
|
||||
|
||||
hole_positions()
|
||||
color("red")
|
||||
linear_extrude(2 * eps, center = true)
|
||||
intersection() {
|
||||
difference() {
|
||||
square(8, center = true);
|
||||
|
||||
horihole($r, $z);
|
||||
}
|
||||
|
||||
circle($r, $fn = 360);
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
rotate(is_undef($bom) ? 0 : [70, 0, 315])
|
||||
horiholes();
|
||||
else
|
||||
horiholes_stl();
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 95 KiB |
BIN
tests/png/cameras.png
Normal file
After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 148 KiB |
BIN
tests/png/gears.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
tests/png/horiholes.png
Normal file
After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 172 KiB |
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 219 KiB After Width: | Height: | Size: 219 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 72 KiB |
@@ -67,7 +67,7 @@ module box1_external_additions() {
|
||||
|
||||
module box1_holes() {
|
||||
box1_feet_positions()
|
||||
teardrop(r = screw_pilot_hole(foot_screw(foot)), h = 10, center = true);
|
||||
teardrop_plus(r = screw_pilot_hole(foot_screw(foot)), h = 10, center = true);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -25,10 +25,10 @@ use <../vitamins/nut.scad>
|
||||
sheet = 3;
|
||||
|
||||
module rails()
|
||||
layout([for(l = rails) carriage_width(rail_carriage(l))], 25)
|
||||
layout([for(l = rails) carriage_width(rail_carriage(l))], 20)
|
||||
rotate(-90) {
|
||||
rail = rails[$i];
|
||||
length = rail == MGN15 ? 260 : 200;
|
||||
length = 200;
|
||||
screw = rail_screw(rail);
|
||||
nut = screw_nut(screw);
|
||||
washer = screw_washer(screw);
|
||||
|
@@ -41,7 +41,10 @@ module teardrops() {
|
||||
|
||||
translate([20, 10])
|
||||
semi_teardrop(h = 0, r = 3);
|
||||
}
|
||||
|
||||
translate([20, 20])
|
||||
teardrop(h = 0, r = 3, truncate = false, plus = true);
|
||||
}
|
||||
}
|
||||
translate([40, 0, 1.5]) {
|
||||
h = 3 + eps;
|
||||
@@ -61,6 +64,9 @@ module teardrops() {
|
||||
|
||||
translate([20, 10])
|
||||
semi_teardrop(h = h, r = 3, chamfer = chamfer);
|
||||
|
||||
translate([20, 20])
|
||||
teardrop(h = h, r = 3, truncate = false, plus = false, chamfer = chamfer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -26,27 +26,27 @@ profile = thread_profile(pitch / 2, pitch * 0.366, 30);
|
||||
|
||||
module threads()
|
||||
for(female = [false, true]) translate([0, female ? -20 : 0]) {
|
||||
length = female ? 8 : 40;
|
||||
dia = female ? 8 : 8 - pitch;
|
||||
colour = female ? brass : silver;
|
||||
length = female ? 8 : 40;
|
||||
dia = female ? 8 : 8 - pitch;
|
||||
colour = female ? brass : silver;
|
||||
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour);
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour);
|
||||
|
||||
color(colour)
|
||||
translate([20, 0])
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female);
|
||||
color(colour)
|
||||
translate([20, 0])
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female);
|
||||
|
||||
translate([40, 0])
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour);
|
||||
translate([40, 0])
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour);
|
||||
|
||||
color(colour)
|
||||
translate([60, 0])
|
||||
thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female);
|
||||
color(colour)
|
||||
translate([60, 0])
|
||||
thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female);
|
||||
|
||||
color(colour)
|
||||
translate([80, 0])
|
||||
thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female);
|
||||
}
|
||||
color(colour)
|
||||
translate([80, 0])
|
||||
thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female);
|
||||
}
|
||||
|
||||
let($show_threads = true)
|
||||
threads();
|
||||
|
@@ -28,12 +28,12 @@ use <global.scad>
|
||||
|
||||
module use_stl(name) { //! Import an STL to make a build platter
|
||||
stl(name);
|
||||
|
||||
import(str("../stls/", name, ".stl"));
|
||||
path = is_undef($target) ? "../stls/" : str("../", $target, "/stls/");
|
||||
import(str(path, name, ".stl"));
|
||||
}
|
||||
|
||||
module use_dxf(name) { //! Import a DXF to make a build panel
|
||||
dxf(name);
|
||||
|
||||
import(str("../dxfs/", name, ".dxf"));
|
||||
path = is_undef($target) ? "../dxfs/" : str("../", $target, "/dxfs/");
|
||||
import(str(path, name, ".dxf"));
|
||||
}
|
||||
|
@@ -20,17 +20,32 @@
|
||||
//
|
||||
//! For making horizontal holes that don't need support material.
|
||||
//! Small holes can get away without it, but they print better with truncated teardrops.
|
||||
//!
|
||||
//! Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips
|
||||
//! do not intrude into the circle. See <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
//
|
||||
module teardrop(h, r, center = true, truncate = true, chamfer = 0) { //! For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging
|
||||
module teardrop(h, r, center = true, truncate = true, chamfer = 0, plus = false) { //! For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging
|
||||
module teardrop_2d(r, truncate) {
|
||||
hull() {
|
||||
circle4n(r);
|
||||
if(truncate)
|
||||
translate([0, r / 2])
|
||||
square([2 * r * (sqrt(2) - 1), r], center = true);
|
||||
else
|
||||
polygon([[0, 0], [eps, 0], [0, r * sqrt(2)]]);
|
||||
}
|
||||
er = layer_height / 2 - eps; // Extrustion edge radius
|
||||
R = plus ? r + er : r; // Corrected radius
|
||||
offset = plus ? -er : 0; // Offset inwards
|
||||
hull()
|
||||
for(side = [0 : 1])
|
||||
mirror([side, 0, 0])
|
||||
intersection() {
|
||||
hull()
|
||||
translate([offset, 0]) {
|
||||
circle4n(R);
|
||||
|
||||
if(truncate)
|
||||
translate([0, R / 2])
|
||||
square([2 * R * (sqrt(2) - 1), R], center = true);
|
||||
else
|
||||
polygon([[0, 0], [eps, 0], [0, R * sqrt(2)]]);
|
||||
}
|
||||
translate([0, -2 * R])
|
||||
square([R, 4 * R]);
|
||||
}
|
||||
}
|
||||
|
||||
render(convexity = 5)
|
||||
@@ -40,23 +55,23 @@ module teardrop(h, r, center = true, truncate = true, chamfer = 0) { //! For mak
|
||||
teardrop_chamfer(h, center, chamfer) {
|
||||
linear_extrude(eps, center = true)
|
||||
teardrop_2d(r + chamfer / 2, truncate);
|
||||
|
||||
translate_z(-chamfer / 2)
|
||||
linear_extrude(eps, center = true)
|
||||
teardrop_2d(r, truncate);
|
||||
}
|
||||
}
|
||||
|
||||
module semi_teardrop(h, r, d = undef, center = true, chamfer = 0) { //! A semi teardrop in the positive Y domain
|
||||
module semi_teardrop_2d(r, d) {
|
||||
module semi_teardrop(h, r, d = undef, center = true, chamfer = 0, plus = false) { //! A semi teardrop in the positive Y domain
|
||||
module semi_teardrop_2d(r, d)
|
||||
intersection() {
|
||||
R = is_undef(d) ? r : d / 2;
|
||||
teardrop(r = R, h = 0);
|
||||
teardrop(r = R, h = 0, plus = plus);
|
||||
|
||||
sq = R + 1;
|
||||
translate([-sq, 0])
|
||||
square([2 * sq, sq]);
|
||||
}
|
||||
}
|
||||
|
||||
render(convexity = 5)
|
||||
extrude_if(h, center)
|
||||
@@ -65,22 +80,21 @@ module semi_teardrop(h, r, d = undef, center = true, chamfer = 0) { //! A semi t
|
||||
teardrop_chamfer(h, center, chamfer) {
|
||||
linear_extrude(eps, center = true)
|
||||
semi_teardrop_2d(r + chamfer / 2, d);
|
||||
|
||||
translate_z(-chamfer / 2)
|
||||
linear_extrude(eps, center = true)
|
||||
semi_teardrop_2d(r, d);
|
||||
}
|
||||
}
|
||||
|
||||
module teardrop_plus(h, r, center = true, truncate = true, chamfer = 0) //! Slightly bigger teardrop to allow for the 3D printing staircase effect
|
||||
teardrop(h, r + layer_height / 4, center, truncate, chamfer);
|
||||
module teardrop_plus(h, r, center = true, truncate = true, chamfer = 0) //! Slightly elongated teardrop to allow for the 3D printing staircase effect
|
||||
teardrop(h, r, center, truncate, chamfer, plus = true);
|
||||
|
||||
module tearslot(h, r, w, center = true, chamfer = 0) { //! A horizontal slot that doesn't need support material
|
||||
module tearslot_2d(r, w) {
|
||||
hull() {
|
||||
translate([-w / 2, 0]) teardrop(r = r, h = 0);
|
||||
translate([w / 2, 0]) teardrop(r = r, h = 0);
|
||||
}
|
||||
}
|
||||
module tearslot(h, r, w, center = true, chamfer = 0, plus = false) { //! A horizontal slot that doesn't need support material
|
||||
module tearslot_2d(r, w)
|
||||
hull()
|
||||
for(x = [-1, 1])
|
||||
translate([x * w / 2, 0]) teardrop(r = r, h = 0, plus = plus);
|
||||
|
||||
extrude_if(h, center)
|
||||
tearslot_2d(r, w);
|
||||
@@ -88,19 +102,19 @@ module tearslot(h, r, w, center = true, chamfer = 0) { //! A horizontal slot tha
|
||||
teardrop_chamfer(h, center, chamfer) {
|
||||
linear_extrude(eps, center = true)
|
||||
tearslot_2d(r + chamfer / 2, w);
|
||||
|
||||
translate_z(-chamfer / 2)
|
||||
linear_extrude(eps, center = true)
|
||||
tearslot_2d(r, w);
|
||||
}
|
||||
}
|
||||
|
||||
module vertical_tearslot(h, r, l, center = true, chamfer = 0) { //! A vertical slot that doesn't need support material
|
||||
module vertical_tearslot_2d(r, l) {
|
||||
hull() {
|
||||
translate([0, l / 2]) teardrop(0, r, true);
|
||||
translate([0, -l / 2]) circle4n(r);
|
||||
}
|
||||
}
|
||||
module vertical_tearslot(h, r, l, center = true, chamfer = 0, plus = false) { //! A vertical slot that doesn't need support material
|
||||
module vertical_tearslot_2d(r, l)
|
||||
hull()
|
||||
for(y = [-1, 1])
|
||||
translate([0, y * l / 2])
|
||||
teardrop(0, r, true, plus = plus);
|
||||
|
||||
extrude_if(h, center)
|
||||
vertical_tearslot_2d(r, l);
|
||||
@@ -108,6 +122,7 @@ module vertical_tearslot(h, r, l, center = true, chamfer = 0) { //! A vertical s
|
||||
teardrop_chamfer(h, center, chamfer) {
|
||||
linear_extrude(eps, center = true)
|
||||
vertical_tearslot_2d(r + chamfer / 2, l);
|
||||
|
||||
translate_z(-chamfer / 2)
|
||||
linear_extrude(eps, center = true)
|
||||
vertical_tearslot_2d(r, l);
|
||||
@@ -123,4 +138,3 @@ module teardrop_chamfer(h, center, chamfer) { //! Helper module for adding chamf
|
||||
hull()
|
||||
children();
|
||||
}
|
||||
|
||||
|
138
utils/gears.scad
Normal file
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Utilities for making involute gears.
|
||||
//!
|
||||
//! Formulas from <https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html>
|
||||
//! <https://khkgears.net/new/gear_knowledge/gear_technical_reference/calculation_gear_dimensions.html>
|
||||
//! and <https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/>
|
||||
//!
|
||||
//! ```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
|
||||
//! Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```.
|
||||
//!
|
||||
//! Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered
|
||||
//! the practical minimum.
|
||||
//!
|
||||
//! The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter.
|
||||
//!
|
||||
//! The origin of the rack is the left end of the pitch line and its width is below the pitch line. I.e. it does not include the addendum.
|
||||
//!
|
||||
//! ```involute_worm_profile()``` returns a tooth profile that can be passed to ```thread()``` to make worms.
|
||||
//
|
||||
include <core/core.scad>
|
||||
use <maths.scad>
|
||||
|
||||
function involute(r, u) = let(a = degrees(u), c = cos(a), s = sin(a)) r * [c + u * s, s - u * c]; //! Involute of circle radius r at angle u in radians
|
||||
|
||||
function profile_shift(z, pa) = z ? max(1 - z * sqr(sin(pa)) / 2, 0) : 0; //! Calculate profile shift for small gears
|
||||
|
||||
function centre_distance(m, z1, z2, pa = 20) = //! Calculate distance between centres taking profile shift into account
|
||||
let(x1 = profile_shift(z1, pa), x2 = profile_shift(z2, pa)) m * (z1/2 + z2/2 + x1 + x2);
|
||||
|
||||
function involute_gear_od(m, z, pa = 20) = //! involute gear outside diameter given modulus, tooth count and pressure angle
|
||||
m * (z + 2 * profile_shift(z, pa) + 2);
|
||||
|
||||
module involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20) { //! Calculate gear profile given module, number of teeth and pressure angle
|
||||
assert(z >= 7, "Gears must have at least 7 teeth.");
|
||||
d = m * z; // Reference pitch circle diameter
|
||||
x = profile_shift(z, pa); // Profile shift
|
||||
c = is_undef(clearance) ? m / 6 : clearance; // Clearance from tip to root
|
||||
|
||||
base_d = d * cos(pa); // Base diameter
|
||||
root_r = d / 2 + m * (x - 1) - c; // Root radius (dedendum circle radius)
|
||||
tip_d = d + 2 * m * (1 + x); // Tip diameter (addendum circle diameter)
|
||||
tpa = acos(base_d / tip_d); // Tip pressure angle
|
||||
inva = tan(pa) - radians(pa); // Involute alpha
|
||||
invaa = tan(tpa) - radians(tpa); // Involute alphaa
|
||||
ta = PI / (2 * z) + 2 * x * tan(pa) / z + inva - invaa; // Tooth tip thickness angle, radians
|
||||
crest_w = ta * tip_d; // Crest width
|
||||
umax = sqrt(sqr(tip_d / base_d) - 1); // Max value of the involute parameter
|
||||
|
||||
base_r = base_d / 2;
|
||||
p1 = involute(base_r, 0);
|
||||
p2 = involute(base_r, umax);
|
||||
dist = norm(p2 - p1); // distance between beginning and end of the involute curve
|
||||
|
||||
base_angle = 2 * acos((sqr(base_r) + sqr(tip_d / 2) - sqr(dist)) / base_r / tip_d) + degrees(2 * ta);
|
||||
root_angle = 360 / z - base_angle;
|
||||
root_circle_r = base_r * sin(root_angle / 2);
|
||||
|
||||
if(!is_undef($show_numbers) && $show_numbers) {
|
||||
echo(d=d);
|
||||
echo(base_d=base_d);
|
||||
echo(tip_d=tip_d);
|
||||
echo(tpa = tpa);
|
||||
echo(inva=inva);
|
||||
echo(invaa=invaa);
|
||||
echo(x=x);
|
||||
echo(ta=ta);
|
||||
echo(crest_w=crest_w);
|
||||
echo(umax = umax);
|
||||
echo(base_angle=base_angle);
|
||||
echo(root_angle=root_angle);
|
||||
}
|
||||
involute = [for(i = [0 : steps], u = umax * i / steps) involute(base_r, u)]; // involute for the bottom side of the tooth
|
||||
truncated = [for(p = involute) if((rot2_z(-base_angle / 2) * p).y <= 0) p]; // removed any above the centreline to prevent overlap
|
||||
reflection = reverse([for(p = truncated) rot2_z(base_angle) * [p.x, -p.y] ]); // reflect and rotate to make the top edge
|
||||
|
||||
root = reverse([for(a = [90 : 180 / steps : 270]) rot2_z(base_angle + root_angle / 2) * ([base_r, 0] + root_circle_r * [cos(a), sin(a)]) ]);
|
||||
tooth = concat(truncated, reflection, root);
|
||||
gear = concat([for(i = [0 : z - 1], p = tooth) rot2_z(i * 360 / z) * p]);
|
||||
rotate(-base_angle / 2)
|
||||
union() {
|
||||
polygon(gear);
|
||||
|
||||
circle(root_r);
|
||||
}
|
||||
}
|
||||
|
||||
function involute_rack_tooth_profile(m, pa = 20, clearance = undef) = //! Calculate rack tooth profile given module and pressure angle
|
||||
let(p = PI * m, // Pitch
|
||||
ha = m, // Addendum
|
||||
c = is_undef(clearance) ? m / 4 : clearance, // Tip root clearance
|
||||
hf = m + c, // Dedendum
|
||||
hw = 2 * m, // Working depth
|
||||
h = ha + hf, // Tooth depth
|
||||
crest_w = p / 2 - 2 * ha * tan(pa), // Crest width
|
||||
base_w = crest_w + 2 * hw * tan(pa), // Base width
|
||||
root_w = p - base_w, // Root width
|
||||
clearance_w = root_w - 2 * c * tan(pa), // Width of clearance without fillet
|
||||
kx = tan(pa / 2 + 45), // Fillet ratio of radius and xoffset
|
||||
pf = min(0.38 * m, kx * clearance_w / 2), // Dedendum fillet radius
|
||||
x = pf / kx, // Fillet centre x offset from corner
|
||||
sides = ceil(r2sides(pf) * (90 - pa) / 360), // Fillet facets taking $fa, $fs and $fn into account
|
||||
fillet = [ for(i = [0 : sides - 1], a = i * (90 - pa) / sides + 270) [clearance_w / 2 - x, -hf + pf] + pf * [cos(a), sin(a)] ],
|
||||
reflection = reverse([for(pt = fillet) [p - pt.x, pt.y] ]) // reflect for trailing edge
|
||||
) concat(fillet, [ [root_w / 2, -hw / 2], [p / 2 - crest_w / 2, ha], [p / 2 + crest_w / 2, ha], [p - root_w / 2, -hw / 2] ], reflection);
|
||||
|
||||
module involute_rack_profile(m, z, w, pa = 20, clearance = undef) { //! Calculate rack profile given module, number of teeth and pressure angle
|
||||
p = PI * m; // Pitch
|
||||
hf = 1.25 * m; // Dedendum
|
||||
tooth = involute_rack_tooth_profile(m, pa, clearance);
|
||||
teeth = [for(i = [0 : z - 1], pt = tooth) [pt.x + i * p, pt.y] ];
|
||||
|
||||
polygon(concat([[0, -w], [0, -hf]], teeth, [[z * p, -hf ], [z * p, -w]])); // Add the corners
|
||||
}
|
||||
|
||||
function involute_worm_profile(m, pa = 20, clearance = undef) = //! Calculate worm profile suitable for passing to thread()
|
||||
let(tooth = involute_rack_tooth_profile(m),
|
||||
pitch = PI * m,
|
||||
y_min = min([for(p = tooth) p.y])
|
||||
) [for(p = tooth) [p.x - pitch / 2, p.y - y_min, 0]]; // Offset to be positive in y, centred in x and add 0 z ordintate
|
55
utils/horiholes.scad
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops), see <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
function teardrop_plus_x(r, y, h) = //! Calculate the ordinate of a compensated teardrop given y and layer height.
|
||||
let(fr = h / 2,
|
||||
hpot = r + fr,
|
||||
x2 = sqr(hpot) - sqr(y),
|
||||
x = x2 > 0 ? sqrt(x2) : 0
|
||||
)
|
||||
max(0,
|
||||
y < hpot / sqrt(2) ? x - fr :
|
||||
y < hpot ? hpot * sqrt(2) - y - fr :
|
||||
0);
|
||||
|
||||
module horihole(r, z, h = 0, center = true) { //! For making horizontal holes that don't need support material and are correct dimensions
|
||||
bot_layer = floor((z - r) / layer_height);
|
||||
top_layer = ceil((z + r) / layer_height);
|
||||
render(convexity = 5)
|
||||
extrude_if(h, center)
|
||||
for(i = [bot_layer : top_layer]) {
|
||||
Z = i * layer_height;
|
||||
y = Z - z + layer_height / 2;
|
||||
x = teardrop_plus_x(r, y, layer_height);
|
||||
if(x > 0)
|
||||
translate([0, y])
|
||||
difference() {
|
||||
square([2 * x + layer_height, layer_height], center = true);
|
||||
|
||||
for(end = [-1, 1])
|
||||
translate([end * (x + layer_height / 2), 0])
|
||||
circle(d = layer_height, $fn = 32);
|
||||
}
|
||||
}
|
||||
}
|
@@ -28,6 +28,6 @@ function layout_offset(widths, i, gap = 2) = //! Calculate the offset for the ``
|
||||
|
||||
module layout(widths, gap = 2, no_offset = false) //! Layout children passing ```$i```
|
||||
translate([no_offset ? -widths[0] / 2 : 0, 0])
|
||||
for($i = [0 : len(widths) - 1])
|
||||
for($i = [0 : 1 : len(widths) - 1])
|
||||
translate([layout_offset(widths, $i, gap), 0])
|
||||
children();
|
||||
|
@@ -20,7 +20,10 @@
|
||||
//
|
||||
//! Maths utilities for manipulating vectors and matrices.
|
||||
//
|
||||
function sqr(x) = x * x;
|
||||
function sqr(x) = x * x; //! Square x
|
||||
function radians(degrees) = degrees * PI / 180; //! Convert radians to degrees
|
||||
function degrees(radians) = radians * 180 / PI; //! Convert degrees to radians
|
||||
|
||||
|
||||
function translate(v) = let(u = is_list(v) ? len(v) == 2 ? [v.x, v.y, 0] //! Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z```
|
||||
: v
|
||||
@@ -63,6 +66,12 @@ function rot3_z(a) = //! Generate a 3x3 matrix to rotate around z
|
||||
[ s, c, 0],
|
||||
[ 0, 0, 1] ];
|
||||
|
||||
function rot2_z(a) = //! Generate a 2x2 matrix to rotate around z
|
||||
let(c = cos(a),
|
||||
s = sin(a))
|
||||
[ [ c, -s],
|
||||
[ s, c] ];
|
||||
|
||||
function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally
|
||||
[
|
||||
[s.x, 0, 0, 0],
|
||||
@@ -90,3 +99,42 @@ function euler(R) = let(ay = asin(-R[2][0]), cy = cos(ay)) //! Convert a rotatio
|
||||
cy ? [ atan2(R[2][1] / cy, R[2][2] / cy), ay, atan2(R[1][0] / cy, R[0][0] / cy) ]
|
||||
: R[2][0] < 0 ? [atan2( R[0][1], R[0][2]), 180, 0]
|
||||
: [atan2(-R[0][1], -R[0][2]), -180, 0];
|
||||
|
||||
module position_children(list, t) //! Position children if they are on the Z = 0 plane when transformed by t
|
||||
for(p = list)
|
||||
let(q = t * p)
|
||||
if(abs(transform([0, 0, 0], q).z) < 0.01)
|
||||
multmatrix(q)
|
||||
children();
|
||||
|
||||
// Matrix inversion: https://www.mathsisfun.com/algebra/matrix-inverse-row-operations-gauss-jordan.html
|
||||
|
||||
function augment(m) = let(l = len(m), n = identity(l)) [ //! Augment a matrix by adding an identity matrix to the right
|
||||
for(i = [0 : l - 1])
|
||||
concat(m[i], n[i])
|
||||
];
|
||||
|
||||
function rowswap(m, i, j) = [ //! Swap two rows of a matrix
|
||||
for(k = [0 : len(m) - 1])
|
||||
k == i ? m[j] : k == j ? m[i] : m[k]
|
||||
];
|
||||
|
||||
function solve_row(m, i) = let(diag = m[i][i]) [ //! Make diagonal one by dividing the row by it and subtract from other rows to make column zero
|
||||
for(j = [0 : len(m) - 1])
|
||||
i == j ? m[j] / diag : m[j] - m[i] * m[j][i] / diag
|
||||
];
|
||||
|
||||
function nearly_zero(x) = abs(x) < 1e-5; //! True if x is close to zero
|
||||
|
||||
function solve(m, i = 0, j = 0) = //! Solve each row ensuring diagonal is not zero
|
||||
i < len(m) ?
|
||||
assert(i + j < len(m), "matrix is singular")
|
||||
solve(!nearly_zero(m[i + j][i]) ? solve_row(j ? rowswap(m, i, i + j) : m, i) : solve(m, i, j + 1), i + 1)
|
||||
: m;
|
||||
|
||||
function invert(m) = let(n =len(m), m = solve(augment(m))) [ //! Invert a matrix
|
||||
for(i = [0 : n - 1]) [
|
||||
for(j = [n : 2 * n - 1])
|
||||
each m[i][j]
|
||||
]
|
||||
];
|
||||
|
@@ -26,6 +26,8 @@
|
||||
//! Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
|
||||
//! example to make a printed pot with a screw top lid.
|
||||
//!
|
||||
//! A left hand thread can be made by using mirror([0,1]).
|
||||
//!
|
||||
//! Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
|
||||
//! a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
|
||||
//!
|
||||
@@ -47,7 +49,7 @@ function thread_profile(h, crest, angle, overlap = 0.1) = //! Create thread prof
|
||||
let(base = crest + 2 * (h + overlap) * tan(angle / 2))
|
||||
[[-base / 2, -overlap, 0], [-crest / 2, h, 0], [crest / 2, h, 0], [base / 2, -overlap, 0]];
|
||||
|
||||
module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef) { //! Create male or femail thread, ends can be tapered, chamfered or square
|
||||
module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef) { //! Create male or female thread, ends can be tapered, chamfered or square
|
||||
//
|
||||
// Apply colour if defined
|
||||
//
|
||||
@@ -61,10 +63,12 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
|
||||
// Extract some properties from the profile, perhaps they should be stored in it.
|
||||
//
|
||||
h = max([for(p = sprofile) p.y]);
|
||||
maxx = max([for(p = sprofile) p.x]);
|
||||
minx = min([for(p = sprofile) p.x]);
|
||||
crest_xmax = max([for(p = sprofile) if(p.x != maxx) p.x]);
|
||||
crest_xmin = min([for(p = sprofile) if(p.x != minx) p.x]);
|
||||
xs = [for(p = sprofile) p.x];
|
||||
maxx = max(xs);
|
||||
minx = min(xs);
|
||||
crest_xs = [for(p = sprofile) if(p.y == h) p.x];
|
||||
crest_xmax = max(crest_xs);
|
||||
crest_xmin = min(crest_xs);
|
||||
//
|
||||
// If the ends don't taper we need an extra half turn past the ends to be cropped horizontally.
|
||||
//
|
||||
@@ -129,11 +133,13 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
|
||||
render() intersection() {
|
||||
polyhedron(points, ends_faces);
|
||||
|
||||
len = length - 2 * eps;
|
||||
shorten = !is_undef(colour);
|
||||
len = shorten ? length - 2 * eps : length;
|
||||
offset = shorten ? eps : 0;
|
||||
rotate_extrude()
|
||||
if(female) {
|
||||
difference() {
|
||||
translate([0, eps])
|
||||
translate([0, offset])
|
||||
square([r + h + overlap, len]);
|
||||
|
||||
if(top_chamfer_h)
|
||||
@@ -146,7 +152,7 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
|
||||
else
|
||||
difference() {
|
||||
hull() {
|
||||
translate([0, eps])
|
||||
translate([0, offset])
|
||||
square([r, len]);
|
||||
|
||||
translate([0, bot_chamfer_h])
|
||||
|
@@ -52,21 +52,21 @@ module ball_bearing(type) { //! Draw a ball bearing
|
||||
rim_chamfer = rim / 6;
|
||||
rotate_extrude()
|
||||
hull() {
|
||||
translate([or - rim / 2, 0])
|
||||
square([rim, h - 2 * rim_chamfer], center = true);
|
||||
translate([or - rim, -h / 2 + rim_chamfer])
|
||||
square([rim, h - 2 * rim_chamfer]);
|
||||
|
||||
translate([or - rim / 2 - rim_chamfer, 0])
|
||||
square([rim - rim_chamfer, h], center = true);
|
||||
translate([or - rim, -h / 2])
|
||||
square([rim - rim_chamfer, h]);
|
||||
}
|
||||
|
||||
hub_chamfer = hub / 6;
|
||||
rotate_extrude()
|
||||
hull() {
|
||||
translate([ir + hub / 2, 0])
|
||||
square([hub, h - 2 * hub_chamfer], center = true);
|
||||
translate([ir, -h / 2 + hub_chamfer])
|
||||
square([hub, h - 2 * hub_chamfer]);
|
||||
|
||||
translate([ir + hub / 2 + hub_chamfer, 0])
|
||||
square([hub - hub_chamfer, h], center = true);
|
||||
translate([ir + hub_chamfer, -h / 2])
|
||||
square([hub - hub_chamfer, h]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,11 +16,12 @@
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
BB624 = ["624", 4, 13, 5, "blue", 1.2, 1.2]; // 624 ball bearing for idlers
|
||||
BB608 = ["608", 8, 22, 7, "OrangeRed", 1.4, 2.0]; // 608 bearings for wades
|
||||
BB6200 = ["6200", 10, 30, 9, "black", 2.3, 3.6]; // 6200 bearings for KP pillow blocks
|
||||
BB6201 = ["6201", 12, 32, 10, "black", 2.4, 3.7]; // 6201 bearings for KP pillow blocks
|
||||
BB6808 = ["6808", 40, 52, 7, "black", 1.5, 1.6];
|
||||
ball_bearings = [BB624, BB608, BB6200, BB6201, BB6808];
|
||||
BBSMR95 = ["SMR95", 5, 9, 2.5, "silver", 0.5, 0.7]; // SMR95 ball bearing for FlexDrive extruder
|
||||
BB624 = ["624", 4, 13, 5, "blue", 1.2, 1.2]; // 624 ball bearing for idlers
|
||||
BB608 = ["608", 8, 22, 7, "OrangeRed", 1.4, 2.0]; // 608 bearings for wades
|
||||
BB6200 = ["6200", 10, 30, 9, "black", 2.3, 3.6]; // 6200 bearings for KP pillow blocks
|
||||
BB6201 = ["6201", 12, 32, 10, "black", 2.4, 3.7]; // 6201 bearings for KP pillow blocks
|
||||
BB6808 = ["6808", 40, 52, 7, "black", 1.5, 1.6];
|
||||
ball_bearings = [BBSMR95, BB624, BB608, BB6200, BB6201, BB6808];
|
||||
|
||||
use <ball_bearing.scad>
|
||||
|
89
vitamins/camera.scad
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! PCB cameras.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
use <pcb.scad>
|
||||
|
||||
function camera_pcb(type) = type[2]; //! The PCB part of the camera
|
||||
function camera_lens_offset(type) = type[3]; //! Offset of the lens center from the PCB centre
|
||||
function camera_lens(type) = type[4]; //! Stack of lens parts, can be round, rectanular or rounded rectangular, with optional tapered aperture
|
||||
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
|
||||
color(grey(20))
|
||||
translate(camera_lens_offset(type))
|
||||
for(p = camera_lens(type)) {
|
||||
size = p[0];
|
||||
r = p[1] + offset;
|
||||
app = p[2];
|
||||
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(app)
|
||||
translate([0, size.z])
|
||||
hull() {
|
||||
translate([0, -eps])
|
||||
square([app.y, eps * 2]);
|
||||
|
||||
translate([0, -app.z])
|
||||
square([app.x, app.z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module camera(type) { //! Draw specified PCB camera
|
||||
vitamin(str("camera(", type[0], "): ", type[1]));
|
||||
pcb = camera_pcb(type);
|
||||
|
||||
not_on_bom()
|
||||
pcb(pcb);
|
||||
|
||||
translate_z(pcb_thickness(pcb)) {
|
||||
camera_lens(type);
|
||||
|
||||
conn = camera_connector_size(type);
|
||||
if(conn) {
|
||||
pos = camera_connector_pos(type);
|
||||
color(grey(20))
|
||||
translate(pos)
|
||||
rounded_rectangle(conn, 0.5, center = false);
|
||||
|
||||
flex = [5, 0.1];
|
||||
color("orange")
|
||||
hull() {
|
||||
translate_z(flex.y /2)
|
||||
translate(camera_lens_offset(type) + [0, camera_lens(type)[0][0].y / 2])
|
||||
cube([flex.x, eps, flex.y], center = true);
|
||||
|
||||
translate_z(conn.z - flex.y)
|
||||
translate([camera_lens_offset(type).x, pos.y] - [0, conn.y / 2])
|
||||
cube([flex.x, eps, flex.y], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
73
vitamins/cameras.scad
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// 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 <smds.scad>
|
||||
|
||||
rpi_camera_v1_pcb = ["", "", 25, 24, 1, 0, 2.1, 0, "green", false, [[2, -2], [-2, -2], [2, 9.6], [-2, 9.6]],
|
||||
[
|
||||
[12, 3.25, 0, "-flat_flex", true],
|
||||
[-4.5, -5, 0, "smd_led", LED0603, "red"],
|
||||
[-5.5, -4, 0, "smd_res", RES0603, "1K2"],
|
||||
],
|
||||
[]];
|
||||
|
||||
rpi_camera_v1 = ["rpi_camera_v1", "Raspberry Pi camera V1", rpi_camera_v1_pcb, [0, 9.6 - 12],
|
||||
[
|
||||
[[8, 8, 3], 0],
|
||||
[[0, 0, 4], 7.5 / 2],
|
||||
[[0, 0, 5], 5.5 / 2, [1.5/2, 2/2, 0.5]],
|
||||
],
|
||||
[0, 12 - 1.5 - 2.5], [8, 5, 1]
|
||||
];
|
||||
|
||||
rpi_camera_v2_pcb = ["", "", 25, 23.862, 1, 2, 2.2, 0, "green", false, [[2, -2], [-2, -2], [2, -14.5], [-2, -14.5]],
|
||||
[
|
||||
[12.5, 2.75, 0, "-flat_flex", true],
|
||||
],
|
||||
[]];
|
||||
|
||||
rpi_camera_v2 = ["rpi_camera_v2", "Raspberry Pi camera V2", rpi_camera_v2_pcb, [0, 9.6 - 12],
|
||||
[
|
||||
[[8.5, 8.5, 3], 0],
|
||||
[[0, 0, 4], 7.5 / 2],
|
||||
[[0, 0, 5], 5.5 / 2, [1.5/2, 2/2, 0.5]],
|
||||
],
|
||||
[-13.8 + 12.5, 23.862 / 2 - 4.7], [8.5, 4, 1]
|
||||
];
|
||||
|
||||
rpi_camera_pcb = ["", "", 36, 36, 1.6, 0, 3.2, 0, "green", false, [[3.5, -3.5], [-3.5, -3.5], [3.5, 3.5], [-3.5, 3.5]],
|
||||
[
|
||||
[18, 4.25, 0, "-flat_flex", true],
|
||||
[-3.8, -7.8, 0, "smd_led", LED0805, "red"],
|
||||
],
|
||||
[]];
|
||||
|
||||
rpi_camera = ["rpi_camera", "Raspberry Pi focusable camera", rpi_camera_pcb, [0, 0],
|
||||
[
|
||||
[[13, 13, 3], 0],
|
||||
[[22, 4, 3], 2 - eps],
|
||||
[[0, 0, 8.5], 7],
|
||||
[[0, 0, 12], 6],
|
||||
[[0, 11, 4.3], 14 / 2, [8/2, 11/2, 1]],
|
||||
],
|
||||
[0, 18 - 1.5 - 2.5], [8, 5, 1.6]
|
||||
];
|
||||
|
||||
cameras = [rpi_camera_v1, rpi_camera, rpi_camera_v2];
|
||||
|
||||
use <camera.scad>
|
@@ -137,7 +137,6 @@ module light_strip(type, segs = undef) { //! Draw specified light strip, segs ca
|
||||
linear_extrude(0.55 + eps)
|
||||
resistor_positions()
|
||||
square([2.1, 1.5 + 2 * eps], center = true);
|
||||
|
||||
}
|
||||
|
||||
if(show_rays)
|
||||
@@ -148,8 +147,9 @@ wall = 1.8;
|
||||
clearance = 0.2;
|
||||
function light_strip_clip_slot(light) = light_strip_width(light) + clearance; //! Clip slot size
|
||||
function light_strip_clip_depth(light) = 10; //! Depth of the clip
|
||||
function light_strip_clip_length(light) = light_strip_clip_slot(light) + 2 * wall; //! Outside length
|
||||
function light_strip_clip_width(light) = light_strip_depth(light) + 2 * wall; //! Outside width
|
||||
function light_strip_clip_length(light) = light_strip_clip_slot(light) + 2 * wall; //! Outside length of clip
|
||||
function light_strip_clip_width(light) = light_strip_depth(light) + 2 * wall; //! Outside width of clip
|
||||
function light_strip_clip_wall() = wall; //! Clip wall thickness
|
||||
|
||||
module light_strip_clip(light) { //! Make a clip to go over the strip to be incorporated into a bracket
|
||||
linear_extrude(light_strip_clip_depth(light), convexity = 2)
|
||||
|
@@ -26,7 +26,7 @@
|
||||
// e s c
|
||||
// s k
|
||||
Rigid5050 = ["Rigid5050", "rigid SMD5050 low profile", 500, 36, 3, 14.4, 7, 10.4, 0.9, 1.2];
|
||||
RIGID5050 = ["RIGID5050", "rigid SMD5050" , 500, 36, 3, 14.4, 8.6, 10.4, 0.9, 1.6];
|
||||
RIGID5050 = ["RIGID5050", "rigid SMD5050" , 500, 36, 3, 14.4, 8.6, 9.8, 0.8, 1.6];
|
||||
|
||||
light_strips = [Rigid5050, RIGID5050,];
|
||||
|
||||
|
@@ -53,6 +53,8 @@ function pcb_accessories(type) = type[12]; //! List of accessories to go on the
|
||||
function pcb_grid(type) = type[13]; //! Grid if a perfboard
|
||||
function pcb_polygon(type) = type[14]; //! Optional outline polygon for odd shaped boards
|
||||
function pcb_screw(type, cap = hs_cap) = Len(type[15]) ? type[15] : find_screw(cap, screw_smaller_than(pcb_hole_d(type))); //! Mounting screw type
|
||||
function pcb_size(type) = [pcb_length(type), pcb_width(type), pcb_thickness(type)]; //! Length, width and thickness in a vector
|
||||
|
||||
|
||||
function pcb_grid_pos(type, x, y, z = 0) = //! Returns a pcb grid position
|
||||
[-pcb_length(type) / 2 + pcb_grid(type).x + 2.54 * x,
|
||||
@@ -636,56 +638,52 @@ module flex(cutout = false) { //! Draw flexistrip connector
|
||||
|
||||
translate([0, -w / 2 + slot_offset + slot_w / 2])
|
||||
square([slot_l, slot_w], center = true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module flat_flex(cutout = false) { //! Draw flat flexistrip connector as used on RPI0
|
||||
l1 = 17;
|
||||
w1 = 1.4;
|
||||
h1 = 1.2;
|
||||
small_ff = [[11.8, 0.9], [17, 1.4, 1.2], [12, 1.6, 1.2], [16, 1.1, 1.2]];
|
||||
large_ff = [[16, 1.25], [22, 1.5, 2.5], [16, 4.0, 2.5], [21, 0, 2.5]];
|
||||
|
||||
l2 = 15.4;
|
||||
w2 = 1.6;
|
||||
h2 = 1.0;
|
||||
function ff_slot(type) = type[0]; //! Flat flex slot size
|
||||
function ff_latch(type) = type[1]; //! Flat flex latch size
|
||||
function ff_mid(type) = type[2]; //! Flat flex middle section size
|
||||
function ff_back(type) = type[3]; //! Flat flex back section size
|
||||
|
||||
l3 = 16;
|
||||
w3 = 1.1;
|
||||
h3 = 1.2;
|
||||
module flat_flex(type, cutout = false) { //! Draw flat flexistrip connector as used on RPI0
|
||||
slot = ff_slot(type);
|
||||
latch = ff_latch(type);
|
||||
mid = ff_mid(type);
|
||||
back = ff_back(type);
|
||||
|
||||
l4 = 12;
|
||||
|
||||
slot_l = 11.8;
|
||||
slot_h = 0.9;
|
||||
|
||||
w = w1 + w2 + w3;
|
||||
w = latch.y + mid.y + back.y;
|
||||
if(cutout)
|
||||
;
|
||||
else {
|
||||
color(grey(30)) {
|
||||
translate([w / 2 - w1, 0, h1 / 2])
|
||||
rotate([90, 0, 90])
|
||||
linear_extrude(w1)
|
||||
color(grey(30))
|
||||
translate([0, w / 2 - latch.y])
|
||||
rotate([90, 0, 180])
|
||||
linear_extrude(latch.y)
|
||||
difference() {
|
||||
square([l1, h1], center = true);
|
||||
translate([-latch.x / 2, 0])
|
||||
square([latch.x, latch.z]);
|
||||
|
||||
translate([0, -h1 / 2])
|
||||
square([slot_l, slot_h * 2], center = true);
|
||||
square([slot.x, slot.y * 2], center = true);
|
||||
}
|
||||
|
||||
}
|
||||
color(grey(90)) {
|
||||
translate([-w / 2 + w3 / 2, 0, h3 / 2])
|
||||
cube([w3, l3, h3], center = true);
|
||||
color("ivory") {
|
||||
translate([-back.x / 2, -w / 2])
|
||||
if(back.y)
|
||||
cube(back);
|
||||
|
||||
translate([-w / 2 + w3 + w2 / 2, 0, h2 / 2])
|
||||
cube([w2, l2, h2], center = true);
|
||||
|
||||
translate([-w / 2 + w3 + w2 / 2, 0, h3 / 2])
|
||||
cube([w2, l4, h3], center = true);
|
||||
translate([-mid.x / 2, -w / 2 + back.y])
|
||||
cube(mid);
|
||||
}
|
||||
|
||||
color(grey(80))
|
||||
translate([-back.x / 2, -w / 2 + back.y + eps])
|
||||
cube([back.x, mid.y - 2 * eps, mid.z - eps]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,7 +895,7 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
|
||||
if(show(comp, "hdmi")) hdmi(hdmi_full, cutouts);
|
||||
if(show(comp, "mini_hdmi")) hdmi(hdmi_mini, cutouts);
|
||||
if(show(comp, "flex")) flex(cutouts);
|
||||
if(show(comp, "flat_flex")) flat_flex(cutouts);
|
||||
if(show(comp, "flat_flex")) flat_flex(param(4, false) ? large_ff : small_ff, cutouts);
|
||||
if(show(comp, "uSD")) uSD(comp[4], cutouts);
|
||||
if(show(comp, "trimpot10")) trimpot10(param(4, false), cutouts);
|
||||
if(show(comp, "molex_usb_Ax2")) molex_usb_Ax2(cutouts);
|
||||
@@ -924,6 +922,7 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
|
||||
if(show(comp, "jst_xh")) jst_xh_header(jst_xh_header, comp[4], param(5, false), param(6, "white"), param(7, undef));
|
||||
if(show(comp, "potentiometer")) potentiometer(param(4, 5), param(5, 9));
|
||||
if(show(comp, "buzzer")) buzzer(param(4, 9), param(5, 12), param(6, grey(20)));
|
||||
if(show(comp, "smd_res")) smd_resistor(comp[4], comp[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -224,7 +224,7 @@ RPI0 = ["RPI0", "Raspberry Pi Zero", 65, 30, 1.4, 3, 2.75, 6, "gre
|
||||
[54, 2, -90, "usb_uA"],
|
||||
[41.4, 2, -90, "usb_uA"],
|
||||
[7.25, 16.7, 180, "uSD", [12, 11.5, 1.4]],
|
||||
[-1.3, 15, 0, "flat_flex"],
|
||||
[-1.3, 15, -90, "flat_flex"],
|
||||
],
|
||||
[": Micro SD card"],
|
||||
[32.5 - 9.5 * 2.54, 26.5 - 1.27, 20, 2]];
|
||||
|
@@ -25,6 +25,7 @@ MGN5_carriage = [ 16, 9.6, 12, 6, 1.5, 0, 8 , M2_cap_screw ];
|
||||
MGN7_carriage = [ 23, 14.3, 17, 8, 1.5, 8, 12, M2_cap_screw ];
|
||||
MGN9_carriage = [ 29.7, 20.8, 20, 10, 2, 10, 15, M3_cap_screw ];
|
||||
MGN12_carriage = [ 34.7, 21.7, 27, 13, 3, 15, 20, M3_cap_screw ];
|
||||
MGN12H_carriage= [ 45.4, 32.4, 27, 13, 3, 20, 20, M3_cap_screw ];
|
||||
MGN15_carriage = [ 43.3, 27.7, 32, 16, 4, 20, 25, M3_cap_screw ];
|
||||
SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw ];
|
||||
//
|
||||
@@ -36,9 +37,10 @@ MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.5, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriag
|
||||
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 ];
|
||||
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 ];
|
||||
|
||||
rails = [MGN5, MGN7, MGN9, MGN15, SSR15];
|
||||
rails = [MGN5, MGN7, MGN9, MGN12, MGN12H, MGN15, SSR15];
|
||||
|
||||
use <rail.scad>
|
||||
|
@@ -29,7 +29,7 @@ function smd_led_lens(type) = type[2]; //! Lens length width and height
|
||||
function smd_led_height(type) = //! Total height
|
||||
smd_led_size(type).z + smd_led_lens(type).z;
|
||||
|
||||
function smd_100th(x) = //! Convert dimesion to 1/100" notation
|
||||
function smd_100th(x) = //! Convert dimension to 1/100" notation
|
||||
let(s = str(round(x / inch(0.01))))
|
||||
len(s) < 2 ? str("0", s) : s;
|
||||
|
||||
@@ -78,3 +78,33 @@ module smd_led(type, colour, cutout) { //! Draw an SMD LED with specified ```col
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function smd_res_size(type) = type[1]; //! Body length, width and height
|
||||
function smd_res_end_cap(type) = type[2]; //! End cap width
|
||||
function smd_res_power(type) = type[3]; //! Power rating in Watts
|
||||
|
||||
module smd_resistor(type, value) { //! Draw an SMD resistor with specified value
|
||||
size = smd_res_size(type);
|
||||
vitamin(str("smd_resistor(", type[0], ", ", value, "): SMD resistor ", smd_size(size), " ", value, " ", smd_res_power(type), "W"));
|
||||
|
||||
t = 0.04;
|
||||
cap = smd_res_end_cap(type);
|
||||
color("white")
|
||||
translate_z(size.z / 2)
|
||||
cube([size.x - 2 * t, size.y, size.z - 2 * t], center = true);
|
||||
|
||||
color(grey(20))
|
||||
translate_z(size.z - t)
|
||||
cube([size.x - 2 * cap, size.y, eps], center = true);
|
||||
|
||||
color(silver)
|
||||
for(end = [-1, 1])
|
||||
translate([end * (size.x / 2 - cap / 2), 0, size.z / 2])
|
||||
cube([cap, size.y - 2 * eps, size.z], center = true);
|
||||
|
||||
color("white")
|
||||
translate([0, 0, size.z])
|
||||
linear_extrude(eps)
|
||||
resize([(size.x - 2 * cap) * 0.75, size.y / 2])
|
||||
text(value, halign = "center", valign = "center");
|
||||
}
|
||||
|
@@ -18,11 +18,18 @@
|
||||
//
|
||||
|
||||
//
|
||||
//! Axial components
|
||||
//! SMD components
|
||||
//
|
||||
|
||||
LED0805 = ["LED0805", [2, 1.25, 0.46], [1.4, 1.25, 0.54]];
|
||||
LED0603 = ["LED0603", [1.6, 0.8, 0.18], [1.0, 0.8, 0.42]];
|
||||
LED0805 = ["LED0805", [2.0, 1.25, 0.46], [1.4, 1.25, 0.54]];
|
||||
|
||||
smd_leds = [LED0805];
|
||||
smd_leds = [LED0603, LED0805];
|
||||
|
||||
RES0603 = ["RES0603", [1.6, 0.8, 0.45], 0.3, 1/10];
|
||||
RES0805 = ["RES0805", [2.0, 1.2, 0.45], 0.4, 1/8];
|
||||
RES1206 = ["RES1206", [3.1, 1.6, 0.6], 0.5, 1/4];
|
||||
|
||||
smd_resistors = [RES0603, RES0805, RES1206];
|
||||
|
||||
use <smd.scad>
|
||||
|
@@ -50,7 +50,7 @@ module mouse_hole(cable, h = 100, teardrop = false) { //! A mouse hole to allow
|
||||
r = wire_hole_radius(cable);
|
||||
|
||||
if(teardrop)
|
||||
vertical_tearslot(r = r, l = 2 * r, h = h);
|
||||
vertical_tearslot(r = r, l = 2 * r, h = h, plus = true);
|
||||
else
|
||||
rotate(90)
|
||||
slot(r, 2 * r, h = h);
|
||||
|