1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-03 20:32:35 +02:00

Compare commits

...

46 Commits

Author SHA1 Message Date
Chris Palmer
eb9bcf0ada Fixed recent bug in plateup when no platters / panels. 2020-11-15 16:29:50 +00:00
Chris Palmer
fc7fd5482e Corrected core XY comment. 2020-11-14 17:40:20 +00:00
Chris Palmer
cee1202fd9 Merge branch 'martinbudden-belt_test_corexy' 2020-11-14 17:20:18 +00:00
Chris Palmer
6e342441c6 Added images and readme. 2020-11-14 17:19:18 +00:00
Chris Palmer
072c38f955 Enabled the two belt version. 2020-11-14 17:18:08 +00:00
Chris Palmer
b342549d74 Merge branch 'belt_test_corexy' of https://github.com/martinbudden/NopSCADlib into martinbudden-belt_test_corexy 2020-11-14 17:00:11 +00:00
Chris Palmer
2b83a15e5d Merge branch 'martinbudden-BTT_TFT35v3' 2020-11-14 14:44:01 +00:00
Chris Palmer
ab81c6538c Updated images and readme. 2020-11-14 14:41:27 +00:00
Chris Palmer
27b0a442e4 Changed the order to avoid a clash with fans. 2020-11-14 14:32:23 +00:00
Martin Budden
5415beb80d Added BigTreeTech TFT35 v 3.0 display. 2020-11-14 14:13:53 +00:00
Martin Budden
040985c0db Converted belts test to coreXY. 2020-11-14 09:40:37 +00:00
Chris Palmer
0216093a68 Added printed camera housings. 2020-11-13 22:43:55 +00:00
Chris
30302431c0 Merge pull request #94 from martinbudden/carbon_tube_fix
Fix to centering of carbon fiber tubing.
2020-11-13 19:35:14 +00:00
Chris Palmer
1fb429e9a5 Merge branch 'martinbudden-shaft_couplings' 2020-11-13 19:32:03 +00:00
Chris Palmer
9571e68629 Updated lib.scad, images and readme. 2020-11-13 19:31:49 +00:00
Chris Palmer
b01e6a673c type[0] should be the name of the constant. 2020-11-13 19:30:46 +00:00
Martin Budden
9239c6da3c Fix to centering of carbon fiber tubing. 2020-11-13 19:27:02 +00:00
Chris Palmer
ba5e5fa390 Used tube.scad to shorten code. 2020-11-13 18:55:26 +00:00
Chris Palmer
c7dfdd0fb9 Merge branch 'shaft_couplings' of https://github.com/martinbudden/NopSCADlib into martinbudden-shaft_couplings 2020-11-13 18:11:29 +00:00
Chris Palmer
814ce4f15d Merge branch 'martinbudden-bowden_connector' 2020-11-13 17:59:17 +00:00
Chris Palmer
f661cf6934 Updated images and readme 2020-11-13 17:57:13 +00:00
Chris Palmer
305d2146f2 Colours passed to thread need to be numeric, not strings. 2020-11-13 17:51:30 +00:00
Chris Palmer
e39ee1797d Merge branch 'bowden_connector' of https://github.com/martinbudden/NopSCADlib into martinbudden-bowden_connector 2020-11-13 17:45:47 +00:00
Chris Palmer
520569cb30 Made small idler pulley 6.5mm by default and added a 7mm one. 2020-11-13 13:55:15 +00:00
Chris Palmer
f73a7b46a2 Merge branch 'martinbudden-carbon_fiber_tube' 2020-11-13 10:51:24 +00:00
Chris Palmer
fb9eca85c6 Updated images and readme. 2020-11-13 10:50:29 +00:00
Martin Budden
166ed05d4a Add optional bowden connector to E3D hotends. 2020-11-13 10:21:38 +00:00
Chris Palmer
ce6aec428d Merge branch 'carbon_fiber_tube' of https://github.com/martinbudden/NopSCADlib into martinbudden-carbon_fiber_tube 2020-11-13 10:03:15 +00:00
Chris Palmer
4e9d169c31 Updated cover pic 2020-11-13 09:57:17 +00:00
Martin Budden
1810160103 Added carbon fiber tubing with woven pattern. 2020-11-13 09:35:56 +00:00
Chris Palmer
0c9ae8d60c PCBs now drawn before components so that transparent LEDs draw correctly. 2020-11-13 09:24:15 +00:00
Chris Palmer
9a0bad4e61 Made stepper motor encap paramatric.
Made connector position based on encap height and added PCB.
2020-11-12 23:36:35 +00:00
Chris Palmer
90047815b0 Added JST PH connectors.
Made jst_xh_header() more parametric and corrected pin positions.
2020-11-12 23:34:59 +00:00
Martin Budden
b583202fb7 Added hole for grub screw to shaft coupling. 2020-11-10 14:49:11 +00:00
Chris Palmer
eac0086199 tests.py now allows parts of projects to be tested without finding an implementation. 2020-11-10 12:01:57 +00:00
Martin Budden
03beaec470 Initial submission of shaft couplings vitamin. 2020-11-10 09:11:30 +00:00
Chris Palmer
51c649cc53 Merge branch 'martinbudden-tests_script' 2020-11-09 16:19:45 +00:00
Chris Palmer
5fa33d7c4d Tests.py now works in projects and makes tests.md and tests.html.
NopSCADlib blurb now scraped from libtest.scad.
libtest.scad no longer required and lack of it is used to detect a project.
2020-11-09 16:17:02 +00:00
Chris Palmer
78ce51d045 Merge branch 'tests_script' of https://github.com/martinbudden/NopSCADlib into martinbudden-tests_script 2020-11-08 21:36:56 +00:00
Chris Palmer
23cbadf6df Merge branch 'martinbudden-stepper_motor_jst_connector' 2020-11-08 21:29:03 +00:00
Chris Palmer
c9c2ffafba Fixed connector position, fixed missing wires, updated images.
Reverted the jst header pin position change.
2020-11-08 21:28:08 +00:00
Martin Budden
2e0e833d40 Made jst_connector a parameter to NEMA. 2020-11-08 15:14:19 +00:00
Martin Budden
6c51f8726c Updated tests.py to better support generic testing. 2020-11-08 14:56:52 +00:00
Martin Budden
0b035dbd15 Added optional jst connector to stepper motors. 2020-11-08 12:20:15 +00:00
Chris Palmer
34b58e3b64 Added convexity parameter to sweep. 2020-11-04 22:27:31 +00:00
Chris Palmer
df43fe7dc6 Added list and string slicing. 2020-11-04 21:44:07 +00:00
48 changed files with 1168 additions and 242 deletions

View File

@@ -54,6 +54,7 @@ include <vitamins/ring_terminals.scad>
include <vitamins/rails.scad>
include <vitamins/rod.scad>
include <vitamins/scs_bearing_blocks.scad>
include <vitamins/shaft_couplings.scad>
include <vitamins/sheets.scad>
include <vitamins/sk_brackets.scad>
include <vitamins/spools.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 818 KiB

After

Width:  |  Height:  |  Size: 839 KiB

View File

@@ -17,6 +17,23 @@
// If not, see <https://www.gnu.org/licenses/>.
//
//!# NopSCADlib
//! An ever expanding library of parts modelled in OpenSCAD useful for 3D printers and enclosures for electronics, etc.
//!
//! It contains lots of vitamins (the RepRap term for non-printed parts), some general purpose printed parts and some utilities.
//! There are also Python scripts to generate Bills of Materials (BOMs),
//! STL files for all the printed parts, DXF files for CNC routed parts in a project and a manual containing assembly
//! instructions and exploded views by scraping markdown embedded in OpenSCAD comments, [see scripts](scripts/readme.md).
//!
//! A simple example project can be found [here](examples/MainsBreakOutBox/readme.md).
//!
//! For more examples of what it can make see the [gallery](gallery/readme.md).
//!
//! The license is GNU General Public License v3.0, see [COPYING](COPYING).
//!
//! See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
//!
//! <img src="libtest.png" width="100%"/>
//
// This file shows all the parts in the library.
//
@@ -30,6 +47,7 @@ use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/camera_housing.scad>
use <tests/circlips.scad>
use <tests/components.scad>
use <tests/d_connectors.scad>
@@ -68,6 +86,7 @@ use <tests/rod.scad>
use <tests/screws.scad>
use <tests/SCS_bearing_blocks.scad>
use <tests/sealing_strip.scad>
use <tests/shaft_couplings.scad>
use <tests/sheets.scad>
use <tests/SK_brackets.scad>
use <tests/spades.scad>
@@ -346,6 +365,9 @@ translate([x3 + 170, veroboard_y + 16])
translate([x3, d_connectors_y])
d_connectors();
translate([x3 + 170, d_connectors_y - 10])
camera_housings();
translate([x3, iecs_y])
iecs();
@@ -412,6 +434,9 @@ translate([x4, sk_brackets_y])
translate([x4, extrusion_brackets_y])
extrusion_brackets();
translate([x4 + 120, extrusion_brackets_y])
shaft_couplings();
translate([x4, scs_bearing_blocks_y])
scs_bearing_blocks();

392
printed/camera_housing.scad Normal file
View File

@@ -0,0 +1,392 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Housings for PCB cameras.
//
include <../core.scad>
include <../vitamins/cameras.scad>
use <../vitamins/pcb.scad>
use <../vitamins/insert.scad>
wall = 1.75;
min_wall = 2 * extrusion_width;
clearance = 0.2;
connector_size = [23, 6, 2.65]; // Worst case size of flat flex connector
cam_back_clearance = round_to_layer(1.5); // Clearance for components on the back of the pcb
cam_back_overlap = 1; // How much the back overlaps the edge of the pcb
cam_back_wall = min_wall;
function cam_front_clearance(cam) = round_to_layer(camera_connector_size(cam).z + clearance);
function cam_back_size(cam) = let(
pcb = camera_pcb(cam),
pcb_size = pcb_size(pcb),
nut = screw_nut(pcb_screw(pcb)),
holes = [for(h = pcb_holes(pcb)) pcb_coord(pcb, h).x],
pitch = max(holes) - min(holes),
length = pitch + 2 * (nut_radius(nut) + min_wall),
width = pcb_size.y + (length - pcb_size.x) * cos(30)
) [length, width, wall + max(connector_size.z, cam_back_clearance + nut_trap_depth(nut))];
function cam_front_size(cam) = cam_back_size(cam) + [ //! Outside dimensions of the case
2 * (wall + clearance),
2 * (wall + clearance),
pcb_thickness(camera_pcb(cam)) + cam_front_clearance(cam) + wall
];
hinge_screw = M2_cap_screw;
hinge_nut = screw_nut(hinge_screw);
hinge_screw_length = 12;
hinge_r = nut_trap_radius(hinge_nut) + 3 * extrusion_width;
hinge_h = wall + nut_trap_depth(hinge_nut);
hinge_offset = hinge_r + 1;
bracket_screw = M3_dome_screw;
function cam_screw_length(cam) = let(
front = cam_front_size(cam),
screw = pcb_screw(camera_pcb(cam)),
nut = screw_nut(screw)
) screw_longer_than(front.z + washer_thickness(screw_washer(screw)) - nut_trap_depth(nut) + nut_thickness(nut, true));
function hinge_z(cam) = cam_screw_length(cam) - hinge_r;
module cam_holes(cam) {
pcb = camera_pcb(cam);
lens_y = camera_lens_offset(cam).y;
two_holes = !!len([for (h = pcb_holes(pcb)) if(abs(pcb_coord(pcb, h).y - lens_y) < 1) true]);
pcb_screw_positions(pcb) // screw holes
if($i > 1 || !two_holes)
children();
}
module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
stl("rpi_camera_focus_ring");
rad = 15 / 2;
hole_r1 = 2.5 / 2;
hole_r2 = 5 / 2;
thickness = 3;
flutes = 8;
angle = 180 / flutes;
x = rad / (sin(angle / 2) + cos(angle / 2));
r = x * sin(angle / 2);
difference() {
linear_extrude(height = thickness, convexity = 5)
difference() {
union() {
circle(x);
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i])
translate([x, 0])
circle(r);
}
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i + angle])
translate([x, 0])
circle(r);
}
hull() {
poly_cylinder(r = hole_r1, h = 0.1, center = true);
translate([0, 0, thickness])
poly_cylinder(r = hole_r2, h = 0.1, center = true);
}
}
}
module camera_back(cam) { //! Make the STL for a camera case back
stl(str("camera_back_", cam[0]));
pcb = camera_pcb(cam);
back = cam_back_size(cam);
screw = pcb_screw(pcb);
nut = screw_nut(screw);
translate_z(back.z)
hflip()
difference() {
translate_z(back.z / 2)
cube(back, center = true);
translate([0, -cam_back_overlap])
cube([pcb_length(pcb) - 2 * cam_back_overlap, pcb_width(pcb), 2 * cam_back_clearance], center = true);
translate([0, -pcb_width(pcb) / 2])
cube([connector_size.x + 2 * clearance, 2 * connector_size.y + 1, 2 * round_to_layer(connector_size.z + clearance)], center = true);
translate_z(back.z)
cam_holes(cam)
hflip()
nut_trap(screw, nut, supported = true);
}
}
module camera_front(cam, hinge = 0) { //! Make the STL for a camera case front
stl(str("camera_front_", cam[0]));
front = cam_front_size(cam);
back = cam_back_size(cam);
pcb = camera_pcb(cam);
pcb_size = pcb_size(pcb);
lens_offset = camera_lens_offset(cam);
screw = pcb_screw(pcb);
shelf = front.z - back.z;
connector_slot = connector_size + 2 * [clearance, 0, layer_height];
rad = wall;
led_hole_r = 1;
led_clearance = [5, 2, 1 * 2];
res_clearance = [3.5, 2, 1 * 2];
conn_pos = camera_connector_pos(cam);
conn = camera_connector_size(cam);
sensor_length = conn_pos.y + conn.y / 2 - lens_offset.y + clearance;
module hinge_pos()
if(!is_undef(hinge))
rotate(hinge * 90)
translate([0, (hinge ? front.x * hinge : front.y) / 2 + hinge_offset, hinge_r])
children();
difference() {
union() {
hull()
for(x = [-1, 1], y = [-1, 1])
translate([x * (front.x / 2 - rad), y * (front.y / 2 - rad)])
hull() { // 3D truncated teardrop gives radiused edges without exceeding 45 degree overhang
translate_z(front.z - 1)
cylinder(r = rad, h = 1);
translate_z(rad)
sphere(rad);
cylinder(r = rad * (sqrt(2) - 1), h = eps);
}
hinge_pos()
hull() {
rotate([-90, 0, -90])
teardrop(r = hinge_r, h = hinge_h, center = false);
translate([0, -10, -hinge_r])
cube([hinge_h, eps, 2 * hinge_r]);
}
}
hinge_pos()
rotate([90, 0, 90])
teardrop_plus(r = screw_clearance_radius(hinge_screw), h = 100, center = true);
translate_z(front.z / 2 + shelf - layer_height) // recess for the back
cube([back.x + 2 * clearance, back.y + 2 * clearance, front.z], center = true);
translate_z(front.z / 2 + shelf - pcb_size.z) // recess for PCB
cube([pcb_size.x + 2 * clearance, pcb_size.y + 2 * clearance, front.z], center = true);
translate_z(shelf)
hflip() {
pcb_component_position(pcb, "smd_led") // clearance for LED
cube(led_clearance, center = true);
pcb_component_position(pcb, "smd_res") // clearance for resistor
cube(res_clearance, center = true);
}
translate([conn_pos.x, lens_offset.y + sensor_length / 2, shelf - pcb_size.z]) // clearance for sensor connector
cube([conn.x + 2 * clearance, sensor_length, 2 * cam_front_clearance(cam)], center = true);
translate([0, -front.y / 2, shelf + front.z / 2]) // slot for connector
cube([connector_slot.x, connector_slot.y, front.z], center = true);
translate_z(cam_back_clearance + layer_height)
cam_holes(cam)
rotate(90)
poly_cylinder(r = screw_clearance_radius(screw), h = 100, center = true);
translate_z(shelf - pcb_size.z)
hflip()
camera_lens(cam, clearance);
hflip()
pcb_component_position(pcb, "smd_led")
rotate(45)
poly_cylinder(r = led_hole_r, h = 100, center = true); // hole for led
}
}
function bracket_thickness(cam) = max(wall, min(3.5, hinge_z(cam) - hinge_r - 1));
module camera_bracket_screw_positions(cam) { //! Position children at the bracket screw positions
r = washer_radius(screw_washer(bracket_screw)) + 0.5;
wide = bracket_thickness(cam) == wall;
pitch = wide ? cam_front_size(cam).x / 2 - r : hinge_h + 1 + r;
for(side = [-1, 1])
translate([side * pitch, 0])
children();
}
module camera_bracket_position(cam) //! Position children at the bracket position
translate([0, cam_front_size(cam).y / 2 + hinge_offset])
children();
module camera_bracket(cam) { //! Make the STL for the camera bracket
stl(str("camera_bracket_", cam[0]));
t = bracket_thickness(cam);
z = hinge_z(cam);
translate([hinge_h / 2, 0])
difference() {
hull() {
translate_z(eps / 2)
cube([hinge_h, 2 * hinge_r, eps], center = true);
translate_z(z)
rotate([0, 90, 0])
cylinder(r = hinge_r, h = hinge_h, center = true);
}
translate([hinge_h / 2, 0, z])
rotate([90, 0, 90])
nut_trap(hinge_screw, screw_nut(hinge_screw), horizontal = true);
}
linear_extrude(t)
difference() {
hull()
camera_bracket_screw_positions(cam)
circle(washer_radius(screw_washer(bracket_screw)) + 0.5);
camera_bracket_screw_positions(cam)
poly_circle(screw_clearance_radius(bracket_screw));
}
}
module camera_assembly(cam, angle = 0) //! Camera case assembly
assembly(str("camera_", cam[0])) {
front = cam_front_size(cam);
screw = pcb_screw(camera_pcb(cam));
nut = screw_nut(screw);
screw_length = cam_screw_length(cam);
hinge_z = hinge_z(cam);
hinge_pos = [0, front.y / 2 + hinge_offset, -hinge_r];
camera_bracket_position(cam) {
nut = screw_nut(hinge_screw);
stl_colour(pp1_colour) render()
camera_bracket(cam);
translate([-hinge_h, 0, hinge_z(cam)])
rotate([-90, 0, 90]) {
vflip()
translate_z(2 * hinge_h - nut_trap_depth(nut))
nut(nut, true);
screw_and_washer(hinge_screw, screw_longer_than(2 * hinge_h));
}
}
translate_z(hinge_z(cam) + hinge_r)
translate(hinge_pos)
rotate([-angle, 0, 0])
translate(-hinge_pos) {
translate_z(cam_back_size(cam).z - front.z)
camera(cam);
stl_colour(pp1_colour) render()
translate_z(-front.z)
camera_back(cam);
cam_holes(cam) {
screw_and_washer(screw, screw_length);
translate_z(-front.z + nut_trap_depth(nut))
vflip()
nut(nut, true);
}
*translate(camera_lens_offset(cam))
translate_z(1.5)
stl_colour(pp1_colour) render()
rpi_camera_focus_ring_stl();
stl_colour(pp2_colour) render()
hflip()
camera_front(cam, 0);
}
}
module camera_fastened_assembly(cam, thickness, angle = 0) {
camera_assembly(cam, angle);
camera_bracket_position(cam)
camera_bracket_screw_positions(cam) {
nut = screw_nut(bracket_screw);
washer = screw_washer(bracket_screw);
t = bracket_thickness(cam);
screw_length = screw_longer_than(thickness + t + nut_thickness(nut, true) + 2 * washer_thickness(washer));
vflip()
translate_z(thickness)
screw_and_washer(bracket_screw, screw_length);
translate_z(t)
nut_and_washer(nut, true);
}
}
module camera_back_rpi_camera_stl() camera_back(rpi_camera);
module camera_back_rpi_camera_v1_stl() camera_back(rpi_camera_v1);
module camera_back_rpi_camera_v2_stl() camera_back(rpi_camera_v2);
module camera_front_rpi_camera_stl() camera_front(rpi_camera);
module camera_front_rpi_camera_v1_stl() camera_front(rpi_camera_v1);
module camera_front_rpi_camera_v2_stl() camera_front(rpi_camera_v2);
module camera_bracket_rpi_camera_stl() camera_bracket(rpi_camera);
module camera_bracket_rpi_camera_v1_stl() camera_bracket(rpi_camera_v1);
module camera_bracket_rpi_camera_v2_stl() camera_bracket(rpi_camera_v2);
module camera_rpi_camera_assembly() camera_assembly(rpi_camera);
module camera_rpi_camera_v1_assembly() camera_assembly(rpi_camera_v1);
module camera_rpi_camera_v2_assembly() camera_assembly(rpi_camera_v2);
module camera_housing(cam) {
front = cam_front_size(cam);
camera_front(cam, 0);
translate([front.x, 0])
camera_back(cam);
translate([-front.x / 2 - 2 - hinge_r, 0])
rotate(90)
camera_bracket(cam);
}
cam = rpi_camera_v2;
if($preview)
camera_fastened_assembly(cam, 3);
else
camera_housing(cam);

183
readme.md
View File

@@ -1,10 +1,12 @@
# NopSCADlib
An ever expanding library of parts modelled in OpenSCAD useful for 3D printers and enclosures for electronics, etc.
It contains lots of vitamins (the RepRap term for non-printed parts), some general purpose printed parts and
some utilities. There are also Python scripts to generate Bills of Materials (BOMs),
STL files for all the printed parts, DXF files for CNC routed parts in a project and a manual containing assembly
instructions and exploded views by scraping markdown embedded in OpenSCAD comments, [see scripts](scripts/readme.md). A simple example project can be found [here](examples/MainsBreakOutBox/readme.md).
It contains lots of vitamins (the RepRap term for non-printed parts), some general purpose printed parts and some utilities.
There are also Python scripts to generate Bills of Materials (BOMs),
STL files for all the printed parts, DXF files for CNC routed parts in a project and a manual containing assembly
instructions and exploded views by scraping markdown embedded in OpenSCAD comments, [see scripts](scripts/readme.md).
A simple example project can be found [here](examples/MainsBreakOutBox/readme.md).
For more examples of what it can make see the [gallery](gallery/readme.md).
@@ -21,27 +23,28 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
<tr><td> <a href = "#Axials">Axials</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#KP_pillow_blocks">KP_pillow_blocks</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#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>
</table>
---
@@ -205,7 +208,7 @@ exposing enough information to make a battery box.
<a name="Belts"></a>
## Belts
Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
Only models 2D paths, so not core XY!
Only models 2D paths, so not crossed belt core XY!
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
@@ -247,15 +250,16 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```belt(GT2x6, [ ... ])``` | Belt GT2 x 6mm x 128mm |
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 696mm |
| 2 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 572mm |
| 1 | ```belt(T2p5x6, [ ... ])``` | Belt T2.5 x 6mm x 130mm |
| 1 | ```belt(T5x10, [ ... ])``` | Belt T5 x 10mm x 130mm |
| 1 | ```belt(T5x6, [ ... ])``` | Belt T5 x 6mm x 130mm |
| 1 | ```insert(F1BM3)``` | Heatfit insert M3 |
| 2 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
| 2 | ```insert(F1BM3)``` | Heatfit insert M3 |
| 2 | ```pulley(GT2x16_toothed_idler)``` | Pulley GT2 idler 16 teeth |
| 4 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
| 2 | ```pulley(GT2x16_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
| 2 | ```pulley(GT2x20ob_pulley)``` | Pulley GT2OB 20 teeth |
| 1 | ```screw(M3_cs_cap_screw, 20)``` | Screw M3 cs cap x 20mm |
| 2 | ```screw(M3_cs_cap_screw, 20)``` | Screw M3 cs cap x 20mm |
| 4 | ```screw(M3_grub_screw, 6)``` | Screw M3 grub x 6mm |
@@ -754,6 +758,7 @@ LCD dispays.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```display(BigTreeTech_TFT35v3_0)``` | BigTreeTech TFT35 v3.0 |
| 1 | ```display(HDMI5)``` | HDMI display 5" |
| 1 | ```display(LCD1602A)``` | LCD display 1602A |
| 1 | ```display(LCDS7282B)``` | LCD display S-7282B |
@@ -1102,7 +1107,7 @@ Needs updating as mostly obsolete versions.
### Modules
| Module | Description |
|:--- |:--- |
| ```hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0])``` | Draw specified hot end |
| ```hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false)``` | Draw specified hot end |
![hot_ends](tests/png/hot_ends.png)
@@ -2463,12 +2468,17 @@ Pin headers and sockets, etc.
| Function | Description |
|:--- |:--- |
| ```hdr_base_colour(type)``` | Header insulator colour |
| ```hdr_box_size(type)``` | Box header outside dimensions |
| ```hdr_box_wall(type)``` | Box header wall thickness |
| ```hdr_pin_below(type)``` | Header pin length underneath |
| ```hdr_pin_colour(type)``` | Header pin colour |
| ```hdr_pin_length(type)``` | Header pin length |
| ```hdr_pin_width(type)``` | Header pin size |
| ```hdr_pitch(type)``` | Header pitch |
| ```hdr_ra_box_offset(type)``` | Offset between back of the box and the pins |
| ```hdr_ra_height(type)``` | Height of right angle connector |
| ```hdr_socket_depth(type)``` | Socket depth for female housing |
| ```hdr_y_offset(type)``` | Y offset of pins from center of the box |
### Modules
| Module | Description |
@@ -2635,6 +2645,7 @@ Timing belt pulleys, both toothed and plain with internal bearings for idlers.
| 1 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
| 1 | ```pulley(GT2x20_plain_idler)``` | Pulley GT2 idler smooth 12mm |
| 1 | ```pulley(GT2x16_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
| 1 | ```pulley(GT2x16x7_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
| 1 | ```pulley(GT2x20ob_pulley)``` | Pulley GT2OB 20 teeth |
| 1 | ```pulley(GT2x12_pulley)``` | Pulley GT2RD 12 teeth |
| 1 | ```pulley(GT2x20um_pulley)``` | Pulley GT2UM 20 teeth |
@@ -3046,6 +3057,41 @@ Sealing strip from B&Q used to seal around the door of 3D printers.
| 1 | ```sealing_strip(100)``` | Sealing strip 10mm x 4mm x 100mm |
<a href="#top">Top</a>
---
<a name="Shaft_couplings"></a>
## Shaft_couplings
Shaft couplings
[vitamins/shaft_couplings.scad](vitamins/shaft_couplings.scad) Object definitions.
[vitamins/shaft_coupling.scad](vitamins/shaft_coupling.scad) Implementation.
[tests/shaft_couplings.scad](tests/shaft_couplings.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```sc_diameter(type)``` | Coupling outer diameter |
| ```sc_diameter1(type)``` | Diameter of smaller shaft |
| ```sc_diameter2(type)``` | Diameter of larger shaft |
| ```sc_length(type)``` | Coupling length |
### Modules
| Module | Description |
|:--- |:--- |
| ```shaft_coupling(type, colour = "silver")``` | Draw the shaft coupling |
![shaft_couplings](tests/png/shaft_couplings.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```shaft_coupling(SC_5x8_rigid)``` | Shaft coupling SC_5x8_rigid |
<a href="#top">Top</a>
---
@@ -3406,6 +3452,7 @@ NEMA stepper motor model.
| ```NEMA_body_radius(type)``` | Body radius |
| ```NEMA_boss_height(type)``` | Boss height |
| ```NEMA_boss_radius(type)``` | Boss around the spindle radius |
| ```NEMA_cap_heights(type)``` | Height of the end cap at the corner and the side |
| ```NEMA_hole_pitch(type)``` | Screw hole pitch |
| ```NEMA_length(type)``` | Body length |
| ```NEMA_radius(type)``` | End cap radius |
@@ -3422,7 +3469,7 @@ NEMA stepper motor model.
### Modules
| Module | Description |
|:--- |:--- |
| ```NEMA(type, shaft_angle = 0)``` | Draw specified NEMA stepper motor |
| ```NEMA(type, shaft_angle = 0, jst_connector = false)``` | Draw specified NEMA stepper motor |
| ```NEMA_outline(type)``` | 2D outline |
| ```NEMA_screw_positions(type, n = 4)``` | Positions children at the screw holes |
| ```NEMA_screws(type, screw, n = 4, screw_length = 8, earth = undef)``` | Place screws and optional earth tag |
@@ -3644,6 +3691,7 @@ Tubing and sleeving. The internal diameter can be forced to stretch it over some
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```tubing(CBNFIB10)``` | Carbon fiber OD 10mm ID 8mm x 15mm |
| 1 | ```tubing(HSHRNK16)``` | Heatshrink sleeving ID 1.6mm x 15mm |
| 1 | ```tubing(HSHRNK100)``` | Heatshrink sleeving ID 10mm x 15mm |
| 1 | ```tubing(HSHRNK24)``` | Heatshrink sleeving ID 2.4mm x 15mm |
@@ -4215,6 +4263,72 @@ of conductive panels, an extra layer of insulation.
| 1 | round_grommet_top_60_3.stl |
<a href="#top">Top</a>
---
<a name="Camera_housing"></a>
## Camera_housing
Housings for PCB cameras.
[printed/camera_housing.scad](printed/camera_housing.scad) Implementation.
[tests/camera_housing.scad](tests/camera_housing.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| ```cam_front_size(cam)``` | Outside dimensions of the case |
### Modules
| Module | Description |
|:--- |:--- |
| ```camera_assembly(cam, angle = 0)``` | Camera case assembly |
| ```camera_back(cam)``` | Make the STL for a camera case back |
| ```camera_bracket(cam)``` | Make the STL for the camera bracket |
| ```camera_bracket_position(cam)``` | Position children at the bracket position |
| ```camera_bracket_screw_positions(cam)``` | Position children at the bracket screw positions |
| ```camera_front(cam, hinge = 0)``` | Make the STL for a camera case front |
| ```rpi_camera_focus_ring_stl()``` | Focus ring the glue onto RPI lens |
![camera_housing](tests/png/camera_housing.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 7 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 10 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 1 | ```camera(rpi_camera_v1)``` | Raspberry Pi camera V1 |
| 1 | ```camera(rpi_camera_v2)``` | Raspberry Pi camera V2 |
| 1 | ```camera(rpi_camera)``` | Raspberry Pi focusable camera |
| 7 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
| 4 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 4 | ```screw(M3_dome_screw, 10)``` | Screw M3 dome x 10mm |
| 2 | ```screw(M3_dome_screw, 12)``` | Screw M3 dome x 12mm |
| 7 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 16 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
### Printed
| Qty | Filename |
| ---:|:--- |
| 1 | camera_back_rpi_camera.stl |
| 1 | camera_back_rpi_camera_v1.stl |
| 1 | camera_back_rpi_camera_v2.stl |
| 1 | camera_bracket_rpi_camera.stl |
| 1 | camera_bracket_rpi_camera_v1.stl |
| 1 | camera_bracket_rpi_camera_v2.stl |
| 1 | camera_front_rpi_camera.stl |
| 1 | camera_front_rpi_camera_v1.stl |
| 1 | camera_front_rpi_camera_v2.stl |
### Assemblies
| Qty | Name |
| ---:|:--- |
| 1 | camera_rpi_camera_assembly |
| 1 | camera_rpi_camera_v1_assembly |
| 1 | camera_rpi_camera_v2_assembly |
<a href="#top">Top</a>
---
@@ -5664,7 +5778,7 @@ An additional twist around the path can be specified. If the path is closed this
### Modules
| Module | Description |
|:--- |:--- |
| ```sweep(path, profile, loop = false, twist = 0)``` | Draw a polyhedron that is the swept volume |
| ```sweep(path, profile, loop = false, twist = 0, convexity = 1)``` | Draw a polyhedron that is the swept volume |
![sweep](tests/png/sweep.png)
@@ -5732,6 +5846,7 @@ Simple tube or ring
|:--- |:--- |
| ```ring(or, ir)``` | Create a ring with specified external and internal radii |
| ```tube(or, ir, h, center = true)``` | Create a tube with specified external and internal radii and height ```h``` |
| ```woven_tube(or, ir, h, center= true, colour = grey(30)``` | Create a woven tube with specified external and internal radii, height ```h```, colours, warp and weft |
![tube](tests/png/tube.png)
@@ -5856,11 +5971,13 @@ Global constants, functions and modules. This file is used directly or indirectl
| ```foot(x)``` | Foot to mm conversion |
| ```in(list, x)``` | Returns true if ```x``` is an element in the ```list``` |
| ```inch(x)``` | Inch to mm conversion (For fractional inches, 'inch(1 + 7/8)' will work as expected.) |
| ```limit(x, min, max)``` | Force x in range min <= x <= max |
| ```m(x)``` | m to mm conversion |
| ```mm(x)``` | Explicit mm specified |
| ```no_point(str)``` | Replace decimal point in string with 'p' |
| ```r2sides(r)``` | Replicates the OpenSCAD logic to calculate the number of sides from the radius |
| ```r2sides4n(r)``` | Round up the number of sides to a multiple of 4 to ensure points land on all axes |
| ```slice(list, start = 0, end = undef)``` | Slice a list or string with Python type semantics |
| ```sqr(x)``` | Returns the square of ```x``` |
| ```yard(x)``` | Yard to mm conversion |

View File

@@ -87,24 +87,25 @@ def plateup(target, part_type, usage = None):
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
if match:
used.append(match.group(1))
#
# Copy file that are not included
#
copied = []
for file in os.listdir(parts_dir):
if file.endswith('.' + part_type) and not file in used:
src = parts_dir + '/' + file
dst = target_dir + '/' + file
if mtime(src) > mtime(dst):
print("Copying %s to %s" % (src, dst))
copyfile(src, dst)
copied.append(file)
#
# Remove any cruft
#
targets = [file[:-4] + part_type for file in all_sources]
for file in os.listdir(target_dir):
if file.endswith('.' + part_type):
if not file in targets and not file in copied:
print("Removing %s" % file)
os.remove(target_dir + '/' + file)
if all_sources:
#
# Copy files that are not included
#
for file in os.listdir(parts_dir):
if file.endswith('.' + part_type) and not file in used:
src = parts_dir + '/' + file
dst = target_dir + '/' + file
if mtime(src) > mtime(dst):
print("Copying %s to %s" % (src, dst))
copyfile(src, dst)
copied.append(file)
#
# Remove any cruft
#
targets = [file[:-4] + part_type for file in all_sources]
for file in os.listdir(target_dir):
if file.endswith('.' + part_type):
if not file in targets and not file in copied:
print("Removing %s" % file)
os.remove(target_dir + '/' + file)

View File

@@ -97,7 +97,6 @@ def tests(tests):
for dir in [deps_dir, png_dir, bom_dir]:
if not os.path.isdir(dir):
os.makedirs(dir)
doc_name = "readme.md"
index = {}
bodies = {}
done = []
@@ -108,19 +107,33 @@ def tests(tests):
#
png_name = "libtest.png"
scad_name = "libtest.scad"
if not os.path.isfile(png_name):
openscad.run(colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall", "-o", png_name, scad_name);
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
if os.path.isfile(scad_name):
libtest = True
lib_blurb = scrape_blurb(scad_name)
if not os.path.isfile(png_name):
openscad.run(colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall", "-o", png_name, scad_name);
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
else:
#
# Project tests so just a title
#
libtest = False
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
lib_blurb = '#' + project + ' Tests\n'
doc_base_name = "readme" if libtest else "tests"
doc_name = doc_base_name + ".md"
#
# List of individual part files
#
scads = [i for i in sorted(os.listdir(scad_dir), key = lambda s: s.lower()) if i[-5:] == ".scad"]
scads = [i for i in sorted(os.listdir(scad_dir), key = lambda s: s.lower()) if i[-5:] == ".scad"]
types = []
for scad in scads:
base_name = scad[:-5]
if not tests or base_name in tests:
done.append(base_name)
print(base_name)
print('\n'+base_name)
cap_name = base_name[0].capitalize() + base_name[1:]
base_name = base_name.lower()
scad_name = scad_dir + '/' + scad
@@ -132,29 +145,42 @@ def tests(tests):
if is_plural(base_name) and os.path.isfile(vits_name):
objects_name = vits_name
locations = [
('vitamins/' + depluralise(base_name) + '.scad', 'Vitamins'),
('printed/' + base_name + '.scad', 'Printed'),
('utils/' + base_name + '.scad', 'Utilities'),
('utils/core/' + base_name + '.scad', 'Core Utilities'),
]
locations = []
if os.path.isdir('vitamins'):
locations.append(('vitamins/' + depluralise(base_name) + '.scad', 'Vitamins'))
if os.path.isdir('printed'):
locations.append(('printed/' + base_name + '.scad', 'Printed'))
if os.path.isdir('utils'):
locations.append(('utils/' + base_name + '.scad', 'Utilities'))
if libtest and os.path.isdir('utils/core'):
locations.append(('utils/core/' + base_name + '.scad', 'Core Utilities'))
for name, type in locations:
if os.path.isfile(name):
impl_name = name
break
else:
print("Can't find implementation!")
continue
if libtest:
print("Can't find implementation!")
continue
else:
type = 'Tests' # OK when testing part of a project
impl_name = None
vsplit = "AJR" + chr(ord('Z') + 1)
vtype = locations[0][1]
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
if type == vtype:
for i in range(1, len(vsplit)):
if cap_name[0] < vsplit[i]:
type = types[i - 1]
break
if libtest:
vsplit = "AJR" + chr(ord('Z') + 1)
vtype = locations[0][1]
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
if type == vtype:
for i in range(1, len(vsplit)):
if cap_name[0] < vsplit[i]:
type = types[i - 1]
break
else:
if not types:
types = [loc[1] for loc in locations] # No need to split up the vitamin list
if not type in types: # Will happen when implementation is not found and type is set to Tests
types.append(type)
for t in types:
if not t in bodies:
@@ -250,24 +276,7 @@ def tests(tests):
usage()
with open(doc_name, "wt") as doc_file:
print('# NopSCADlib', file = doc_file)
print('''\
An ever expanding library of parts modelled in OpenSCAD useful for 3D printers and enclosures for electronics, etc.
It contains lots of vitamins (the RepRap term for non-printed parts), some general purpose printed parts and
some utilities. There are also Python scripts to generate Bills of Materials (BOMs),
STL files for all the printed parts, DXF files for CNC routed parts in a project and a manual containing assembly
instructions and exploded views by scraping markdown embedded in OpenSCAD comments, [see scripts](scripts/readme.md). A simple example project can be found [here](examples/MainsBreakOutBox/readme.md).
For more examples of what it can make see the [gallery](gallery/readme.md).
The license is GNU General Public License v3.0, see [COPYING](COPYING).
See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
<img src="libtest.png" width="100%"/>\n
''', file = doc_file)
print(lib_blurb, file = doc_file)
print('## Table of Contents<a name="top"/>', file = doc_file)
print('<table><tr>', file = doc_file)
n = 0
@@ -288,10 +297,10 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
for type in types:
for line in bodies[type]:
print(line, file = doc_file)
with open("readme.html", "wt") as html_file:
do_cmd("python -m markdown -x tables readme.md".split(), html_file)
with open(doc_base_name + ".html", "wt") as html_file:
do_cmd(("python -m markdown -x tables " + doc_name).split(), html_file)
times.print_times()
do_cmd('codespell -L od readme.md'.split())
do_cmd(('codespell -L od ' + doc_name).split())
if __name__ == '__main__':
for arg in sys.argv[1:]:

View File

@@ -23,46 +23,52 @@ use <../vitamins/insert.scad>
use <../utils/layout.scad>
module belt_test() {
p1 = [75, -50];
p2 = [-75, -50];
p3 = [-75, 100];
p4 = [75, 100];
p5 = [75 - pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
translate(p1) pulley_assembly(GT2x20ob_pulley);
translate(p2) pulley_assembly(GT2x20ob_pulley);
translate(p3) pulley_assembly(GT2x20_toothed_idler);
translate(p4) pulley_assembly(GT2x20_toothed_idler);
module pulleys(flip = false) {
translate(p2) rotate([0, flip ? 180 : 0, 0]) pulley_assembly(GT2x20ob_pulley);
translate(p3) pulley_assembly(GT2x20_toothed_idler);
translate(p4) pulley_assembly(GT2x20_toothed_idler);
translate(p5) {
pulley = GT2x16_toothed_idler;
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
insert = screw_insert(screw);
translate(p5) {
pulley = GT2x16_plain_idler;
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
insert = screw_insert(screw);
pulley_assembly(pulley);
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
screw(screw, 20);
translate_z(pulley_offset(pulley) - insert_length(insert))
vflip()
insert(insert);
rotate([0, flip ? 180 : 0, 0]) {
pulley_assembly(pulley);
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
screw(screw, 20);
translate_z(pulley_offset(pulley) - insert_length(insert))
vflip()
insert(insert);
}
}
translate(p6) pulley_assembly(GT2x16_plain_idler);
}
translate(p6) pulley_assembly(GT2x16_plain_idler);
path = [ [p1.x, p1.y, pulley_pr(GT2x20ob_pulley)],
[p5.x, p5.y, -pulley_pr(GT2x16_plain_idler)],
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
];
belt = GT2x6;
belt(belt, path, 80, [0, 0]);
pulleys();
translate_z(20)
hflip() {
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
pulleys(flip=true);
}
translate([-25, 0])
translate([-25, 0, 10])
layout([for(b = belts) belt_width(b)], 10)
rotate([0, 90, 0])
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));

33
tests/camera_housing.scad Normal file
View File

@@ -0,0 +1,33 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
use <../printed/camera_housing.scad>
include <../vitamins/cameras.scad>
use <../vitamins/pcb.scad>
module camera_housings()
layout([for(c = cameras) pcb_length(camera_pcb(c))], 15, false) let(c = cameras[$i])
camera_fastened_assembly(c, 3);
if($preview)
camera_housings();

View File

@@ -24,7 +24,7 @@ include <../vitamins/cameras.scad>
use <../vitamins/pcb.scad>
module cameras()
layout([for(c = cameras) pcb_length(camera_pcb(c))], 10, false) let(c = cameras[$i])
layout([for(c = cameras) pcb_length(camera_pcb(c))], 15, false) let(c = cameras[$i])
camera(c);
if($preview)

View File

@@ -29,6 +29,23 @@ module globals() {
translate([50, 0])
right_triangle(10, 20, 0);
}
assert(slice("ABCD") == "ABCD");
assert(slice("ABCD", 1) == "BCD");
assert(slice("ABCD", 2) == "CD");
assert(slice("ABCD", 3) == "D");
assert(slice("ABCD", 4) == "");
assert(slice("ABCD", 1, -1) == "BC");
assert(slice("ABCD", 2, -1) == "C");
assert(slice("ABCD", 3, -1) == "");
assert(slice("ABCD", 4, -1) == "");
assert(slice("ABCD", 0, -1) == "ABC");
assert(slice("ABCD", 0, -2) == "AB");
assert(slice("ABCD", 0, -3) == "A");
assert(slice("ABCD", 0, -4) == "");
assert(slice("ABCD", 0, 0) == "");
assert(slice("ABCD", 0, 1) == "A");
assert(slice("ABCD", 0, 2) == "AB");
assert(slice("ABCD", 0, 3) == "ABC");
}
rotate([70, 0, 315]) globals();

View File

@@ -25,7 +25,7 @@ module hot_ends()
layout([for(h = hot_ends) 40])
translate([-20, 0])
rotate(90)
hot_end(hot_ends[$i], 3);
hot_end(hot_ends[$i], 3, bowden = $i == 3);
if($preview)
hot_ends();

View File

@@ -64,11 +64,14 @@ module pin_headers() {
pin_socket(pin_headers[$i], 3, 3, right_angle = true);
}
translate([-20, 0])
jst_xh_header(jst_xh_header, 5);
for(i = [0, 1], p = [5, 2][i], j = [0 , 1]) {
h = [jst_ph_header, jst_xh_header][j];
translate([-20 * (i + 1), 0 + j * 40])
jst_xh_header(h, p);
translate([-20, 20])
jst_xh_header(jst_xh_header, 5, true);
translate([-20 * (i + 1), 20 + j * 40])
jst_xh_header(h, p, true);
}
}
if($preview)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/shaft_couplings.scad>
use <../utils/layout.scad>
module shaft_couplings()
layout([for(s = shaft_couplings) sc_diameter(s)],5)
shaft_coupling(shaft_couplings[$i]);
if($preview)
shaft_couplings();

View File

@@ -22,12 +22,12 @@ include <../vitamins/stepper_motors.scad>
use <../utils/layout.scad>
module stepper_motors()
layout([for(s = stepper_motors) NEMA_width(s)], 5) {
layout([for(s = stepper_motors) NEMA_width(s)], 5) let(m = stepper_motors[$i]) {
rotate(180)
NEMA(stepper_motors[$i]);
NEMA(m, 0, m == NEMA17M || m == NEMA17M8);
translate_z(4)
NEMA_screws(stepper_motors[$i], M3_pan_screw, n = $i, earth = $i > 4 ? undef : $i - 1);
NEMA_screws(m, M3_pan_screw, n = $i, earth = $i > 4 ? undef : $i - 1);
}
if($preview)

View File

@@ -22,7 +22,7 @@ use <../utils/layout.scad>
include <../vitamins/tubings.scad>
module tubings()
layout([for(t = tubings) tubing_od(t)], 10)
layout([for(t = tubings) tubing_od(t)], 8)
tubing(tubings[$i]);
if($preview)

View File

@@ -36,12 +36,22 @@ function in(list, x) = !!len([for(v = list) if(v == x) true]);
function Len(x) = is_list(x) ? len(x) : 0; //! Returns the length of a list or 0 if ```x``` is not a list
function r2sides(r) = $fn ? $fn : ceil(max(min(360/ $fa, r * 2 * PI / $fs), 5)); //! Replicates the OpenSCAD logic to calculate the number of sides from the radius
function r2sides4n(r) = floor((r2sides(r) + 3) / 4) * 4; //! Round up the number of sides to a multiple of 4 to ensure points land on all axes
function limit(x, min, max) = max(min(x, max), min); //! Force x in range min <= x <= max
module translate_z(z) translate([0, 0, z]) children(); //! Shortcut for Z only translations
module vflip() rotate([180, 0, 0]) children(); //! Invert children by doing a 180&deg; flip around the X axis
module hflip() rotate([0, 180, 0]) children(); //! Invert children by doing a 180&deg; flip around the Y axis
module ellipse(xr, yr) scale([1, yr / xr]) circle4n(xr); //! Draw an ellipse
function slice_str(str, start, end, s ="") = start >= end ? s : slice_str(str, start + 1, end, str(s, str[start])); // Helper for slice()
function slice(list, start = 0, end = undef) = let( //! Slice a list or string with Python type semantics
len = len(list),
start = limit(start < 0 ? len + start : start, 0, len),
end = is_undef(end) ? len : limit(end < 0 ? len + end : end, 0, len)
) is_string(list) ? slice_str(list, start, end) : [for(i = [start : 1 : end - 1]) list[i]];
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D
if(h)
linear_extrude(h, center = center, convexity = 2) // 3D

View File

@@ -152,10 +152,10 @@ function sweep(path, profile, loop = false, twist = 0) = //! Generate the point
faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, npoints - 1)])
) [points, faces];
module sweep(path, profile, loop = false, twist = 0) { //! Draw a polyhedron that is the swept volume
module sweep(path, profile, loop = false, twist = 0, convexity = 1) { //! Draw a polyhedron that is the swept volume
mesh = sweep(path, profile, loop, twist);
polyhedron(points = mesh[0], faces = mesh[1]);
polyhedron(points = mesh[0], faces = mesh[1], convexity = convexity);
}
function path_length(path, i = 0, length = 0) = //! Calculated the length along a path

View File

@@ -31,3 +31,41 @@ module ring(or, ir) //! Create a ring with specified external and internal radii
module tube(or, ir, h, center = true) //! Create a tube with specified external and internal radii and height ```h```
linear_extrude(h, center = center, convexity = 5)
ring(or, ir);
module woven_tube(or, ir, h, center= true, colour = grey(30), colour2, warp = 2, weft) {//! Create a woven tube with specified external and internal radii, height ```h```, colours, warp and weft
colour2 = colour2 ? colour2 : colour * 0.8;
weft = weft ? weft : warp;
warp_count = max(floor(PI * or / warp), 0.5);
angle = 360 / (2 * warp_count);
module layer(weft) {
points = [[ir, weft / 2], [or, weft / 2], [or, -weft / 2], [ir, -weft / 2]];
color(colour)
for (i = [0 : warp_count])
rotate(2 * i * angle)
rotate_extrude(angle = angle)
polygon(points);
color(colour2)
for (i = [0 : warp_count])
rotate((2 * i + 1) * angle)
rotate_extrude(angle = angle)
polygon(points);
}
translate_z(center ? -h / 2 : 0) {
weft_count = floor(h / weft);
if (weft_count > 0)
for (i = [0 : weft_count - 1]) {
translate_z(i * weft + weft / 2)
rotate(i * angle)
layer(weft);
}
remainder = h - weft * weft_count;
if (remainder) {
translate_z(weft_count * weft + remainder / 2)
rotate(weft_count * angle)
layer(remainder);
}
}
}

View File

@@ -19,7 +19,7 @@
//
//! Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
//! Only models 2D paths, so not core XY!
//! Only models 2D paths, so not crossed belt core XY!
//!
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
//!

View File

@@ -68,6 +68,6 @@ rpi_camera = ["rpi_camera", "Raspberry Pi focusable camera", rpi_camera_pcb, [0,
[0, 18 - 1.5 - 2.5], [8, 5, 1.6]
];
cameras = [rpi_camera_v1, rpi_camera, rpi_camera_v2];
cameras = [rpi_camera_v1, rpi_camera_v2, rpi_camera];
use <camera.scad>

View File

@@ -73,6 +73,42 @@ SSD1963_4p3 = ["SSD1963_4p3", "LCD display SSD1963 4.3\"", 105.5, 67.2, 3.4, SSD
[[0, -34.5], [12, -31.5]],
];
displays = [HDMI5, SSD1963_4p3, LCD1602A, LCDS7282B];
BigTreeTech_TFT35v3_0_PCB = ["", "",
110, 55.77, 1.6, 0, 3, 0, "green", false,
[ [-3.12, 3.17], [-3.12, -3.17], [3.12, -3.17], [3.12, 3.17] ],
[
[ 10, 7.5, 0, "-button_6mm" ],
[ 9, 43, 0, "-buzzer", 5, 9 ],
[ 9, 27, 0, "-potentiometer" ],
[ 102,28.82, 0, "uSD", [26.5, 16, 3] ],
[16.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
[36.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
[56.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
[82.5, 4, 0, "jst_xh", 5 ],
[26.5, 52.8, 180, "jst_xh", 2 ],
[39.5, 52.8, 180, "jst_xh", 3 ],
[52.5, 52.8, 180, "jst_xh", 3 ],
[65.5, 52.8, 180, "jst_xh", 3 ],
[78.5, 52.8, 180, "jst_xh", 3 ],
[94.5, 52.8, 180, "jst_xh", 5 ],
[ 8, 43, 180, "usb_A" ],
[ 97, 4, 0, "chip", 9, 3.5, 1, grey(20) ],
// ESP-8266
[ 23, 28, 90, "2p54socket", 4, 2 ],
],
[]
];
BigTreeTech_TFT35v3_0 = ["BigTreeTech_TFT35v3_0", "BigTreeTech TFT35 v3.0",
84.5, 54.5, 4, BigTreeTech_TFT35v3_0_PCB,
[-6, 0, 0], // pcb offset
[[-40, -26.5], [41.5, 26.5, 0.5]], // aperture
[], // touch screen
0, // thread length
[], // clearance need for the ts ribbon
];
displays = [HDMI5, SSD1963_4p3, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B];
use <display.scad>

View File

@@ -26,6 +26,8 @@ include <tubings.scad>
include <zipties.scad>
include <fans.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/thread.scad>
use <../utils/tube.scad>
rad_dia = 22; // Diam of the part with ailettes
@@ -94,7 +96,34 @@ module heater_block(type, naked = false, resistor_wire_rotate = [0,0,0]) {
}
}
module bowden_connector(cap_colour = grey(20)) {
ir = 4.25 / 2;
body_colour = silver;
color(body_colour) {
translate_z(-4.5) {
tube(or = 2.5, ir = ir, h = 4.5, center = false);
male_metric_thread(6, metric_coarse_pitch(5), length = 4.5, center = false, solid = false, colour = body_colour);
}
tube(or = 7.7 / 2, ir = ir, h = 2, center = false);
translate_z(2)
linear_extrude(6.5)
difference() {
circle(d = 11.55, $fn = 6);
circle(r = ir);
}
translate_z(8.5)
rounded_cylinder(r = 9.8 / 2, h = 2, r2 = 1.5, ir = ir);
translate_z(10.5)
tube(or = 3.5, ir = ir, h = 0.5, center = false);
}
color(cap_colour) {
translate_z(11)
tube(or = 3, ir = ir, h = 1, center = false);
translate_z(12)
tube(or = 5.5, ir = ir, h = 1.75, center = false);
}
}
module e3d_fan_duct(type) {
color("DeepSkyBlue")
@@ -123,7 +152,7 @@ module e3d_fan(type) {
fan(fan30x10);
}
module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) {
module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false) {
insulator_length = hot_end_insulator_length(type);
inset = hot_end_inset(type);
h_ailettes = rad_len / (2 * rad_nb_ailettes - 1);
@@ -150,6 +179,10 @@ module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]
square([100, hot_end_groove(type)]);
}
if(bowden)
translate_z(inset)
bowden_connector();
rotate(90)
heater_block(type, naked, resistor_wire_rotate);
@@ -158,10 +191,10 @@ module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]
e3d_fan();
}
module e3d_hot_end_assembly(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) {
module e3d_hot_end_assembly(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false) {
bundle = 3.2;
e3d_hot_end(type, filament, naked, resistor_wire_rotate);
e3d_hot_end(type, filament, naked, resistor_wire_rotate, bowden);
// Wire and ziptie
if(!naked)

View File

@@ -44,10 +44,10 @@ function hot_end_length(type) = hot_end_total_length(type) - hot_end_inset(type)
use <jhead.scad>
use <e3d.scad>
module hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) { //! Draw specified hot end
module hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0], bowden = false) { //! Draw specified hot end
if(hot_end_style(type) == jhead)
jhead_hot_end_assembly(type, filament, naked);
if(hot_end_style(type) == e3d)
e3d_hot_end_assembly(type, filament, naked, resistor_wire_rotate);
e3d_hot_end_assembly(type, filament, naked, resistor_wire_rotate, bowden);
}

View File

@@ -41,7 +41,7 @@ DSP5005 = ["DSP5005", "Ruideng DSP5005 Power supply module", [7
[[-25, 9, 0], [ 6.5, 4.5, 1], 0.5, "yellow"],
]];
DSN_VC288PCB = ["", "", 41, 21, 1, 0, 0, 0, "green", false, [], [[ 5, -3, 0, "jst_xh", 3], ], []];
DSN_VC288PCB = ["", "", 41, 21, 1, 0, 0, 0, "green", false, [], [[ 5, -3.525, 0, "jst_xh", 3], ], []];
DSN_VC288 = ["DSN_VC288","DSN-VC288 DC 100V 10A Voltmeter ammeter", [45.3, 26, 17.4], [47.8, 28.8, 2.5], 0, [1, 1.8], [36, 18, 2.5], [], 0, 2,
[], 0, DSN_VC288PCB, 5, 0];

View File

@@ -1021,8 +1021,6 @@ module pcb(type) { //! Draw specified PCB
for(part = pcb_accessories(type))
vitamin(part);
pcb_components(type);
color(pcb_colour(type)) linear_extrude(t) difference() {
if(Len(pcb_polygon(type)))
polygon(pcb_polygon(type));
@@ -1076,6 +1074,8 @@ module pcb(type) { //! Draw specified PCB
circle(d = 2);
}
}
pcb_components(type);
}
module pcb_spacer(screw, height, wall = 1.8, taper = 0) { //! Generate STL for PCB spacer

View File

@@ -348,7 +348,7 @@ PI_IO = ["PI_IO", "PI_IO V2", 35.56, 25.4, 1.6, 0, 0, 0, "green", tru
], []];
ZC_A0591 = ["ZC_A0591", "ZC-A0591 ULN2003 driver PCB", 35, 32, 1.6, 0, 2.5, 0, "green", false, [[2.25, 3.25], [-2.25, 3.25], [2.25, -3.25], [-2.25, -3.25] ],
[ [ 12.25, 8.3, -90, "jst_xh", 5],
[ [ 11.725, 8.3, -90, "jst_xh", 5],
[ -6.5, 10, 0, "2p54header", 1, 4],
[ 20.4, -4.5, 0, "2p54header", 4, 1],
[ 20.4, 11, 180, "pdip", 16, "ULN2803AN", true],
@@ -408,7 +408,7 @@ RAMPSEndstop = ["RAMPSEndstop", "RAMPS Endstop Switch",
[2, 2, false], [2, 13.5, false], [17, 13.5], [36, 13.5]
],
[
[ 12, 8, -90, "jst_xh", 3, true, "white", "silver"],
[ 11.6, 8, -90, "jst_xh", 3, true, "white", "silver"],
[ 26.5, 12.75, 0, "microswitch", small_microswitch],
[ 27.5, 17.5, 15, "chip", 15, 0.5, 4.5, "silver"],
],

View File

@@ -29,13 +29,18 @@ function hdr_pin_width(type) = type[4]; //! Header pin size
function hdr_pin_colour(type) = type[5]; //! Header pin colour
function hdr_base_colour(type) = type[6]; //! Header insulator colour
function hdr_socket_depth(type) = type[7]; //! Socket depth for female housing
function hdr_box_size(type) = type[8]; //! Box header outside dimensions
function hdr_box_wall(type) = type[9]; //! Box header wall thickness
function hdr_y_offset(type) = type[10]; //! Y offset of pins from center of the box
function hdr_ra_box_offset(type)= type[11]; //! Offset between back of the box and the pins
function hdr_ra_height(type) = type[12]; //! Height of right angle connector
module pin(type, length = undef) { //! Draw a header pin
w = hdr_pin_width(type);
l = length == undef ? hdr_pin_length(type) : length;
chamfer = w / 2;
color(hdr_pin_colour(type))
translate_z(l / 2 -hdr_pin_below(type))
translate_z(l / 2 - hdr_pin_below(type))
hull() {
cube([w, w, l - 2 * chamfer], center = true);
@@ -108,9 +113,11 @@ module pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cu
module box_header(type, cols = 1, rows = 1, smt = false, cutout = false) { //! Draw box header
pitch = hdr_pitch(type);
size = hdr_box_size(type);
w = cols * pitch + 7.62;
l = rows * pitch + 3.52;
h = 8.7;
h = size.z;
t = hdr_box_wall(type);
base = h - 6.4;
if(cutout)
@@ -131,7 +138,7 @@ module box_header(type, cols = 1, rows = 1, smt = false, cutout = false) { //! D
difference() {
square([w, l], center = true);
square([w - 2.4, l - 2.4], center = true);
square([w - t, l - t], center = true);
translate([0, -l / 2])
square([4.5, 4.5], center = true);
@@ -225,65 +232,95 @@ module pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt
module jst_xh_header(type, pin_count, right_angle = false, colour = false, pin_colour = false) { //! Draw JST XH connector
colour = colour ? colour : hdr_base_colour(type);
pin_colour = pin_colour ? pin_colour : hdr_pin_colour(type);
sizeY = 5.75;
pitch = hdr_pitch(type);
size = hdr_box_size(type) + [(pin_count - 1) * pitch, 0, 0];
pinOffsetX = hdr_box_size(type).x / 2; // Offset from last pin to box edge
wallThickness = hdr_box_wall(type);
y_offset = hdr_y_offset(type);
ra_box_offset = hdr_ra_box_offset(type);
ra_h = hdr_ra_height(type);
ra_z = ra_h - size.y / 2;
ra_extra = ra_h - size.y; // thicker base for right angle version
pinWidth = hdr_pin_width(type);
module jst_xh_socket(type, pin_count) {
socketSizeZ = hdr_socket_depth(type);
pinOffsetX = 2.45;
sizeY = 5.75;
wallThickness = 0.8;
size = [pinOffsetX * 2 + (pin_count - 1) * pitch, sizeY, socketSizeZ];
translate([-size[0] / 2, -size[1] / 2, 0]) {
// the base
cube([size[0], size[1], wallThickness]);
// the three full sides
translate([0, size[1] - wallThickness, 0])
cube([size[0], wallThickness, size[2]]);
cube([wallThickness, size[1], size[2]]);
translate([size[0] - wallThickness, 0, 0])
cube([wallThickness, size[1], size[2]]);
// the sides with cutouts
cube([size[0], wallThickness, 2]);
cutoutWidth = 1;
cutoutOffset = pinOffsetX - cutoutWidth / 2;
cube([cutoutOffset, wallThickness, size[2]]);
translate([size[0] - cutoutOffset, 0, 0])
cube([cutoutOffset, wallThickness, size[2]]);
cube([cutoutOffset, wallThickness, size[2]]);
translate([size[0]-cutoutOffset, 0, 0])
cube([cutoutOffset, wallThickness, size[2]]);
translate([cutoutOffset + cutoutWidth, 0, 0])
cube([size[0] - 2 * (cutoutWidth + cutoutOffset), wallThickness, size[2]]);
module jst_xh_socket(type, pin_count, ra = false) {
module wall() {
difference() {
square([size.x, size.y], center = true);
offset(-wallThickness)
square([size.x, size.y], center = true);
}
if(right_angle)
translate([0, size.y / 2 + ra_extra / 2])
square([size.x, ra_extra], center = true);
}
} // end module
module slots() {
cutoutWidth = 1.3;
cutoutOffset = pinOffsetX + cutoutWidth / 2 - hdr_pin_width(type) / 2;
for(side = [-1, 1])
translate([side * (size.x / 2 - cutoutOffset), -size.y / 2 + wallThickness / 2])
square([cutoutWidth, 2 * wallThickness], center = true);
}
linear_extrude(wallThickness)
square([size.x, size.y], center = true); // the base
linear_extrude(size.z / 2) // full walls up to the slots
wall();
linear_extrude(size.z) // slotted walls to the top
difference() {
wall();
if(type[0] == "jst_xh_header") {
if(pin_count > 2)
slots();
else
hull()
slots();
translate([0, -size.y / 2 + 3 * wallThickness / 2])
square([size.x + 1, wallThickness], center = true);
}
if(type[0] == "jst_ph_header") {
translate([0, -size.y / 2 + wallThickness / 2])
square([max((pin_count - 2) * pitch, 1), 2 * wallThickness], center = true);
translate([0, -y_offset / 2 - pinWidth / 4])
square([size.x + 1, y_offset + pinWidth / 2], center = true);
}
}
} // end module
color(colour)
if(right_angle)
translate([0, -1, sizeY / 2])
translate([0, -ra_box_offset, ra_z])
rotate([-90, 0, 180])
jst_xh_socket(type, pin_count);
jst_xh_socket(type, pin_count, true);
else
jst_xh_socket(type, pin_count);
translate([0, y_offset])
jst_xh_socket(type, pin_count);
color(pin_colour)
for(x = [0 : pin_count - 1]) {
pinWidth = hdr_pin_width(type);
verticalPinLength = right_angle ? hdr_pin_below(type) + sizeY / 2 : hdr_pin_length(type);
translate([pitch * (x - (pin_count - 1) / 2), 0, 0]) {
verticalPinLength = right_angle ? hdr_pin_below(type) + ra_z + y_offset : hdr_pin_length(type);
horizontalPinLength = hdr_pin_length(type) - hdr_pin_below(type) + ra_box_offset;
translate([pitch * (x - (pin_count - 1) / 2), 0]) {
pin(type, verticalPinLength);
if(right_angle) {
translate([0, -pinWidth / 2, sizeY / 2 - pinWidth / 2])
translate([0, -pinWidth / 2, ra_z - pinWidth / 2 + y_offset])
rotate([0, -90, 0])
rotate_extrude(angle = 90, $fn = 32)
translate([0, -pinWidth / 2])
square(pinWidth);
translate([0, -sizeY / 2 - 3 * pinWidth / 4, sizeY / 2])
rotate([90,0,0])
pin(type, hdr_pin_length(type) - hdr_pin_below(type));
translate([0, -hdr_pin_below(type), ra_z + y_offset])
rotate([90, 0, 0])
pin(type, horizontalPinLength);
}
}
}

View File

@@ -17,15 +17,16 @@
// If not, see <https://www.gnu.org/licenses/>.
//
// p p b p p b Socket depth
// i i e i i a
// t n l n n s
// c o e
// h l w w c
// c
//
2p54header = ["2p54header", 2.54, 11.6, 3.2, 0.66, "gold", grey(20), 8.5];
jst_xh_header = ["JST XH header",2.5, 10, 3.4, 0.64, "gold", grey(90), 7];
// p p b p p b s b b p r r
// i i e i i a o o o i a a
// t n l n n s c x x n
// c o e k b h
// h l w w c s t y
// c h z o
// f
2p54header = ["2p54header", 2.54, 11.6, 3.2, 0.66, "gold", grey(20), 8.5, [0, 0, 8.7], 2.4, 0, 0, 0 ];
jst_xh_header = ["jst_xh_header",2.5, 10, 3.4, 0.64, "gold", grey(90), 0, [4.9, 5.75, 7], 0.8, 0.525, 0.6, 6.1];
jst_ph_header = ["jst_ph_header",2.0, 9, 3.4, 0.64, silver, grey(90), 0, [3.9, 4.5, 6], 0.6, 0.55, 0.25, 4.8];
pin_headers = [ 2p54header ];

View File

@@ -35,7 +35,8 @@ GT2x12_pulley = ["GT2x12_pulley", "GT2RD", 12, 7.15, GT2x6, 6.5,
GT2x20_toothed_idler = ["GT2x20_toothed_idler", "GT2", 20, 12.22, GT2x6, 6.5, 18, 0, 4, 18.0, 1.0, 0, 0, false, 0];
GT2x20_plain_idler = ["GT2x20_plain_idler", "GT2", 0, 12.0, GT2x6, 6.5, 18, 0, 4, 18.0, 1.0, 0, 0, false, 0];
GT2x16_toothed_idler = ["GT2x16_toothed_idler", "GT2", 16, 9.75, GT2x6, 6.5, 14, 0, 3, 14.0, 1.0, 0, 0, false, 0];
GT2x16_plain_idler = ["GT2x16_plain_idler", "GT2", 0, 9.63, GT2x6, 7.0, 13, 0, 3, 13.0, 1.0, 0, 0, false, 0];
GT2x16_plain_idler = ["GT2x16_plain_idler", "GT2", 0, 9.63, GT2x6, 6.5, 13, 0, 3, 13.0, 1.0, 0, 0, false, 0];
GT2x16x7_plain_idler = ["GT2x16x7_plain_idler", "GT2", 0, 9.63, GT2x6, 7.0, 13, 0, 3, 13.0, 1.0, 0, 0, false, 0];
pulleys = [T5x10_pulley,
T2p5x16_pulley,
@@ -45,6 +46,7 @@ pulleys = [T5x10_pulley,
GT2x20_toothed_idler,
GT2x20_plain_idler,
GT2x16_toothed_idler,
GT2x16_plain_idler];
GT2x16_plain_idler,
GT2x16x7_plain_idler];
use <pulley.scad>

View File

@@ -0,0 +1,65 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//! Shaft couplings
//
include <../core.scad>
use <../utils/tube.scad>
function sc_length(type) = type[1]; //! Coupling length
function sc_diameter(type) = type[2]; //! Coupling outer diameter
function sc_diameter1(type) = type[3]; //! Diameter of smaller shaft
function sc_diameter2(type) = type[4]; //! Diameter of larger shaft
module shaft_coupling(type, colour = "silver") { //! Draw the shaft coupling
vitamin(str("shaft_coupling(", type[0], "): Shaft coupling ", type[0]));
length = sc_length(type);
radius = sc_diameter(type) / 2;
r1 = sc_diameter1(type) / 2;
r2 = sc_diameter2(type) / 2;
grub_length = 3;
module grub_screw_positions() {
grub_offset_z = 5;
for(z = [-length / 2 + grub_offset_z, length / 2 - grub_offset_z])
translate_z(z)
for(a = [0, 90])
rotate([-90, 0, a])
translate_z(radius + 1)
children();
}
color(colour) {
render(convexity=2) difference() {
union() {
translate_z(-length / 2)
tube(radius, r1, length / 2, false);
tube(radius, r2, length / 2, false);
}
grub_screw_positions()
rotate([180, 0, 0])
cylinder(r = screw_radius(M3_grub_screw), h = 5);
}
}
grub_screw_positions()
not_on_bom() screw(M3_grub_screw, grub_length);
}

View File

@@ -0,0 +1,29 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Shaft couplings
//
// L D d1 d2
SC_5x8_rigid = [ "SC_5x8_rigid", 25, 12.5, 5, 8 ];
shaft_couplings = [SC_5x8_rigid];
use <shaft_coupling.scad>

View File

@@ -23,8 +23,10 @@
include <../core.scad>
include <ring_terminals.scad>
include <../vitamins/pin_headers.scad>
use <../utils/tube.scad>
use <../utils/thread.scad>
use <../utils/round.scad>
use <washer.scad>
use <rod.scad>
@@ -37,9 +39,10 @@ function NEMA_boss_height(type) = type[6]; //! Boss height
function NEMA_shaft_dia(type) = type[7]; //! Shaft diameter
function NEMA_shaft_length(type)= type[8]; //! Shaft length above the face, if a list then a leadscrew: length, lead, starts
function NEMA_hole_pitch(type) = type[9]; //! Screw hole pitch
function NEMA_cap_heights(type) = type[10]; //! Height of the end cap at the corner and the side
function NEMA_holes(type) = [-NEMA_hole_pitch(type) / 2, NEMA_hole_pitch(type) / 2]; //! Screw positions for for loop
function NEMA_big_hole(type) = NEMA_boss_radius(type) + 0.2; //! Clearance hole for the big boss
stepper_body_colour = "black";
stepper_cap_colour = grey(50);
stepper_machined_colour = grey(90);
@@ -52,19 +55,20 @@ module NEMA_outline(type) //! 2D outline
circle(NEMA_radius(type));
}
module NEMA(type, shaft_angle = 0) { //! Draw specified NEMA stepper motor
module NEMA(type, shaft_angle = 0, jst_connector = false) { //! Draw specified NEMA stepper motor
side = NEMA_width(type);
length = NEMA_length(type);
body_rad = NEMA_body_radius(type);
boss_rad = NEMA_boss_radius(type);
boss_height =NEMA_boss_height(type);
shaft_rad = NEMA_shaft_dia(type) / 2;
cap = 8;
cap = NEMA_cap_heights(type)[1];
cap2 = NEMA_cap_heights(type)[0];
vitamin(str("NEMA(", type[0], "): Stepper motor NEMA", round(NEMA_width(type) / 2.54), " x ", length, "mm"));
thread_d = 3; // Is this always the case?
thread_d = 3; // Is this always the case?
module cap_shape(end)
difference() {
round(0.5, $fn = 32) difference() {
intersection() {
square([side, side], center = true);
@@ -92,12 +96,41 @@ module NEMA(type, shaft_angle = 0) { //! Draw specified NEMA stepper motor
cap_shape(1);
}
color(stepper_cap_colour) // aluminium end caps
for(end = [-1, 1])
pcb_thickness = 1.6;
header = jst_ph_header;
socket_size = hdr_box_size(header);
tabSize = [16, 4, cap - hdr_ra_height(header) - pcb_thickness];
color(stepper_cap_colour) { // aluminium end caps
for(end = [-1, 1]) {
translate_z(-length / 2 + end * (length - cap) / 2)
linear_extrude(cap, center = true)
cap_shape(end);
translate_z(-length / 2 + end * (length - cap2) / 2)
linear_extrude(cap2, center = true)
difference() {
cap_shape(end);
circle(body_rad);
}
}
if(jst_connector)
translate([-tabSize.x / 2, side / 2, -length])
cube(tabSize);
}
if(jst_connector)
translate([0, side / 2, -length + cap - hdr_ra_height(header)]) {
rotate(180)
not_on_bom()
jst_xh_header(header, 6, true);
translate_z(-pcb_thickness / 2)
color("green")
cube([socket_size.x + 5 * 2, tabSize.y * 2, pcb_thickness], true);
}
if(show_threads)
for(x = NEMA_holes(type), y = NEMA_holes(type))
translate([x, y, -cap / 2])
@@ -111,15 +144,16 @@ module NEMA(type, shaft_angle = 0) { //! Draw specified NEMA stepper motor
cylinder(r = shaft_rad, h = shaft + 5); // shaft
else
not_on_bom()
leadscrew(shaft_rad * 2, shaft.x + 5, shaft.y, shaft.z, center = false)
leadscrew(shaft_rad * 2, shaft.x + 5, shaft.y, shaft.z, center = false);
translate([0, side / 2, -length + cap / 2])
rotate([90, 0, 0])
for(i = [0 : 3])
rotate(225 + i * 90)
color(["red", "blue","green","black"][i])
translate([1, 0, 0])
cylinder(r = 1.5 / 2, h = 12, center = true);
if(!jst_connector)
translate([0, side / 2, -length + cap / 2])
rotate([90, 0, 0])
for(i = [0 : 3])
rotate(225 + i * 90)
color(["red", "blue","green","black"][i])
translate([1, 0, 0])
cylinder(r = 1.5 / 2, h = 12, center = true);
}
module NEMA_screw_positions(type, n = 4) { //! Positions children at the screw holes

View File

@@ -22,14 +22,14 @@
//
// corner body boss boss shaft
// side, length, radius, radius, radius, depth, shaft, length, holes
NEMA17 = ["NEMA17", 42.3, 47, 53.6/2, 25, 11, 2, 5, 24, 31 ];
NEMA17M = ["NEMA17M", 42.3, 40, 53.6/2, 25, 11, 2, 5, 20, 31 ];
NEMA17M8= ["NEMA17M8", 42.3, 40, 53.6/2, 25, 11, 2, 8, [280, 8, 4], 31 ];
NEMA17S = ["NEMA17S", 42.3, 34, 53.6/2, 25, 11, 2, 5, 24, 31 ];
NEMA16 = ["NEMA16", 39.5, 19.2, 50.6/2, 50.6/2, 11, 2, 5, 12, 31 ];
NEMA14 = ["NEMA14", 35.2, 36, 46.4/2, 21, 11, 2, 5, 21, 26 ];
NEMA23 = ["NEMA23", 56.4, 51.2, 75.7/2, 35, 38.1/2, 1.6, 6.35, 24, 47.1 ];
// side, length, radius, radius, radius, depth, shaft, length, holes, cap heights
NEMA17 = ["NEMA17", 42.3, 47, 53.6/2, 25, 11, 2, 5, 24, 31, [11.5, 9]];
NEMA17M = ["NEMA17M", 42.3, 40, 53.6/2, 25, 11, 2, 5, 20, 31, [12.5, 11]];
NEMA17M8= ["NEMA17M8", 42.3, 40, 53.6/2, 25, 11, 2, 8, [280, 8, 4], 31, [12.5, 11]];
NEMA17S = ["NEMA17S", 42.3, 34, 53.6/2, 25, 11, 2, 5, 24, 31, [8, 8]];
NEMA16 = ["NEMA16", 39.5, 19.2, 50.6/2, 50.6/2, 11, 2, 5, 12, 31, [8, 8]];
NEMA14 = ["NEMA14", 35.2, 36, 46.4/2, 21, 11, 2, 5, 21, 26, [8, 8]];
NEMA23 = ["NEMA23", 56.4, 51.2, 75.7/2, 35, 38.1/2, 1.6, 6.35, 24, 47.1, [8, 8]];
stepper_motors = [NEMA14, NEMA16, NEMA17S, NEMA17M, NEMA17, NEMA23];

View File

@@ -21,6 +21,7 @@
//! Tubing and sleeving. The internal diameter can be forced to stretch it over something.
//
include <../utils/core/core.scad>
include <../utils/tube.scad>
function tubing_material(type) = type[1]; //! Material description
function tubing_od(type) = type[2]; //! Outside diameter
@@ -38,10 +39,15 @@ module tubing(type, length = 15, forced_id = 0, center = true) { //! Draw specif
vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " ID ", original_id, "mm x ",length, "mm"));
else
vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " OD ", original_od, "mm ID ", original_id,"mm x ",length, "mm"));
color(tubing_colour(type))
linear_extrude(length, center = center, convexity = 4)
difference() {
circle(d = od);
circle(d = id);
}
if(tubing_material(type) == "Carbon fiber")
woven_tube(od / 2, id /2, center = center, length, colour = tubing_colour(type));
else
color(tubing_colour(type))
linear_extrude(length, center = center, convexity = 4)
difference() {
circle(d = od);
circle(d = id);
}
}

View File

@@ -19,22 +19,23 @@
//
// Tubing and sleeving
//
PVC64 = ["PVC64", "PVC aquarium tubing", 6, 4, [0.8, 0.8, 0.8, 0.75 ]];
PVC85 = ["PVC85", "PVC aquarium tubing", 8, 5, [0.8, 0.8, 0.8, 0.75 ]];
NEOP85 = ["NEOP85", "Neoprene tubing", 8, 5, [0.2,0.2,0.2]];
PTFE07 = ["PTFE07", "PTFE sleeving", 1.2, 0.71, [0.95, 0.95, 0.95, 0.9]];
PTFE20 = ["PTFE20", "PTFE sleeving", 2.6, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE2_4 = ["PTFE2_4", "PTFE tubing", 4, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE2_3 = ["PTFE2_3", "PTFE tubing", 3, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE4_6 = ["PTFE4_6", "PTFE tubing", 6, 4, [0.95, 0.95, 0.95, 0.9]];
PF7 = ["PF7", "PTFE tubing", 46/10, 3.84, [0.95, 0.95, 0.95, 0.9]];
HSHRNK16 = ["HSHRNK16", "Heatshrink sleeving", 2.0, 1.6, "grey"];
HSHRNK24 = ["HSHRNK24", "Heatshrink sleeving", 2.8, 2.4, "grey"];
HSHRNK32 = ["HSHRNK32", "Heatshrink sleeving", 3.6, 3.2, "grey"];
HSHRNK64 = ["HSHRNK64", "Heatshrink sleeving", 6.8, 6.4, "grey"];
HSHRNK100 = ["HSHRNK100", "Heatshrink sleeving",10.4, 10.0, [0.2,0.2,0.2]];
// Description OD ID Colour
PVC64 = ["PVC64", "PVC aquarium tubing", 6, 4, [0.8, 0.8, 0.8, 0.75 ]];
PVC85 = ["PVC85", "PVC aquarium tubing", 8, 5, [0.8, 0.8, 0.8, 0.75 ]];
NEOP85 = ["NEOP85", "Neoprene tubing", 8, 5, [0.2,0.2,0.2]];
PTFE07 = ["PTFE07", "PTFE sleeving", 1.2, 0.71, [0.95, 0.95, 0.95, 0.9]];
PTFE20 = ["PTFE20", "PTFE sleeving", 2.6, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE2_4 = ["PTFE2_4", "PTFE tubing", 4, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE2_3 = ["PTFE2_3", "PTFE tubing", 3, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE4_6 = ["PTFE4_6", "PTFE tubing", 6, 4, [0.95, 0.95, 0.95, 0.9]];
PF7 = ["PF7", "PTFE tubing", 46/10, 3.84, [0.95, 0.95, 0.95, 0.9]];
HSHRNK16 = ["HSHRNK16", "Heatshrink sleeving", 2.0, 1.6, "grey"];
HSHRNK24 = ["HSHRNK24", "Heatshrink sleeving", 2.8, 2.4, "grey"];
HSHRNK32 = ["HSHRNK32", "Heatshrink sleeving", 3.6, 3.2, "grey"];
HSHRNK64 = ["HSHRNK64", "Heatshrink sleeving", 6.8, 6.4, "grey"];
HSHRNK100 = ["HSHRNK100", "Heatshrink sleeving",10.4, 10.0, [0.2,0.2,0.2]];
CARBONFIBER10 = ["CBNFIB10", "Carbon fiber", 10.0, 8.0, [0.3,0.3,0.3]];
tubings = [PVC64, PVC85, NEOP85, PTFE07, PTFE20, PF7, PTFE2_3, PTFE2_4, PTFE4_6, HSHRNK16, HSHRNK24, HSHRNK64, HSHRNK100];
tubings = [PVC64, PVC85, NEOP85, PTFE07, PTFE20, PF7, PTFE2_3, PTFE2_4, PTFE4_6, HSHRNK16, HSHRNK24, HSHRNK64, HSHRNK100, CARBONFIBER10];
use <tubing.scad>