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

Compare commits

...

48 Commits

Author SHA1 Message Date
Chris Palmer
aeded1b807 Added a hygrometer module. 2019-08-21 18:50:15 +01:00
Chris Palmer
79f1c95136 Insert lug made more flexible and insert_boss made faster.
Both added to the insert test.
2019-08-21 17:31:23 +01:00
Chris Palmer
9bb84593be Added two more projects to the gallery. 2019-08-21 16:50:00 +01:00
Chris Palmer
ab91defcd2 Added Arduino Leonardo 2019-08-21 16:28:32 +01:00
Chris Palmer
7c1ff5ecd5 Added comment to belts about using negative pitch radius for outside pulleys. 2019-08-21 11:36:48 +01:00
Chris Palmer
e35fb695a2 Ziptie width added to BOM description. 2019-08-18 18:39:56 +01:00
Chris Palmer
61bec656d7 Fixed box header BOM descripion. 2019-08-18 18:32:22 +01:00
Chris Palmer
854adab665 Fix for Python 2 2019-08-18 15:21:01 +01:00
Chris Palmer
b7654f0384 Fixed readme index order for Python 2.
Fixed index order being different on Linux due to os.listdir order being
inconsistent with Windows.
2019-08-18 14:26:14 +01:00
Chris Palmer
312f12dfd0 Butt_box made more flexible with extra parameters. 2019-08-18 14:18:21 +01:00
Chris Palmer
be3999ed3e Added documentation for the last change. 2019-08-18 12:52:17 +01:00
Chris Palmer
566cbce98f Corrner block and fixing block assemblies now more flexible.
Can split the fasteners between assemblies and omit the star washers.
2019-08-18 12:36:13 +01:00
Chris Palmer
b8dba626d2 Can now flip the fasteners in a foot_assembly. 2019-08-18 12:32:29 +01:00
Chris Palmer
2adb936f41 Fixed toggle switch part number typo. 2019-08-18 12:27:41 +01:00
Chris Palmer
017ec480c0 Added tesrdrop option to mouse_hole. 2019-08-18 12:26:25 +01:00
Chris Palmer
e3a500e9c6 Added pcb_component_position(). 2019-08-18 12:19:48 +01:00
Chris Palmer
4ac48c9603 Added studding. 2019-08-18 12:18:12 +01:00
Chris Palmer
78ce316b86 Added 2mm acrylic sheets. 2019-08-18 12:04:58 +01:00
Chris Palmer
ec274fdca1 Update readme for last change. 2019-08-18 11:56:05 +01:00
Chris Palmer
3640963da1 Added small geared stepper and driver board. 2019-08-18 11:46:33 +01:00
Chris Palmer
466a7a667d Added platters.py and panels.py to aggregate parts for printing / routing. 2019-08-18 11:08:44 +01:00
Chris Palmer
be324c31da Missing targets now named when dependency checking. 2019-08-18 10:53:22 +01:00
Chris Palmer
49c3b6be2c Fixed Microview stl suffix case for Linux. 2019-08-17 14:39:45 +01:00
Chris Palmer
8583f5472d Would help to include the code! 2019-07-29 20:43:03 +01:00
Chris Palmer
645ff21d3d Added right_triangle. 2019-07-29 19:30:07 +01:00
Chris Palmer
4ff12b1d8b LDRs thicker 2019-07-29 16:39:09 +01:00
Chris Palmer
847dba544f Fixed fillet back to front 2019-07-28 22:08:21 +01:00
Chris Palmer
13c654a10e Fixed nut child placement when it is a nyloc 2019-07-27 21:50:04 +01:00
Chris Palmer
49ee92db8e Fixed tapered PCB spacers. 2019-07-25 21:20:41 +01:00
Chris Palmer
be14a52c21 Fixed LDR comment 2019-07-25 19:31:16 +01:00
Chris Palmer
af4c5e2b3e Added missing image 2019-07-25 11:05:58 +01:00
Chris Palmer
f85a7e85be Added LDR models 2019-07-25 11:00:04 +01:00
Chris Palmer
c68f879d13 Added insert_lug() to make flying insert lugs. 2019-07-25 10:39:31 +01:00
Chris Palmer
3d4653fc0f Added insert_boss_radius(). 2019-07-24 13:48:44 +01:00
Chris Palmer
b40c076d23 Removed extraneous echo. 2019-07-21 19:10:15 +01:00
Chris Palmer
5ae040079e Now shows the CNC routed parts in the master BOM and total parts count. 2019-07-21 18:58:38 +01:00
Chris Palmer
881a032aa3 Typo 2019-07-21 17:39:42 +01:00
Chris Palmer
4b1d6298e4 Typo 2019-07-21 17:39:23 +01:00
Chris Palmer
b4cc6f6c37 Added semi_teardrop.
mouse_grommets now teardropped.
2019-07-19 11:10:44 +01:00
Chris Palmer
6238f82bf0 Added poly_tube(), an extruded poly_ring().
Added missing hinge image.
2019-07-19 11:03:26 +01:00
Chris Palmer
fbc688c81f Vitamins now sorted alphabetically in build instructions. 2019-07-19 10:57:14 +01:00
Chris Palmer
7b2b239a8b Can now override the screw type for a fan assembly. 2019-07-19 10:51:59 +01:00
Chris Palmer
de8eb594a7 Reduced the number of waves on a screw_knob to make it more comfortable.
Added build instructions to the screw_knob assemblies.
2019-07-19 10:50:08 +01:00
Chris Palmer
f061b0a2f8 Added alternative ring_terminal earth assembly with cap screw. 2019-07-19 10:46:38 +01:00
Chris Palmer
43b17c6f0b Added spool_pitch() function and more modern 300mm filament spool. 2019-07-19 10:39:05 +01:00
Chris Palmer
886319a6e4 Added pose_vflip() and pose_hflip() to make posing assembly views easier. 2019-07-19 10:37:10 +01:00
Chris Palmer
723be7ac64 Fixed round_grommet_hole() size.
Added more grommet stls.
2019-07-19 10:34:38 +01:00
Chris Palmer
3a5e027bbb Added parametric printed hinges. 2019-07-19 10:30:02 +01:00
80 changed files with 1675 additions and 472 deletions

View File

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

View File

@@ -31,6 +31,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
## Parts list
| <span style="writing-mode: vertical-rl; text-orientation: mixed;">Base</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Feet</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Mains&nbsp;In</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Main</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |
|--:|--:|--:|--:|--:|:--|
| | | | | | **Vitamins** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; 4mm shielded jack socket blue |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; 4mm shielded jack socket brown |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; 4mm shielded jack socket green |
@@ -47,9 +48,11 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Wire blue 30/0.25mm strands, length 150mm - not shown |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Wire brown 30/0.25mm strands, length 150mm - not shown |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Wire green & yellow 30/0.25mm strands, length 150mm - not shown |
| | | | | | **3D Printed parts** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;&nbsp;foot.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;&nbsp;socket_box.stl |
| &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;16&nbsp; | &nbsp;&nbsp;14&nbsp; | &nbsp;&nbsp;18&nbsp; | &nbsp;&nbsp;50&nbsp; | &nbsp;&nbsp;Total vitamins count |
| | | | | | **3D printed parts** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;foot.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;socket_box.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;5&nbsp; | &nbsp;&nbsp;Total 3D printed parts count |
[Top](#TOP)
@@ -86,9 +89,9 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
### Vitamins
|Qty|Description|
|--:|:----------|
|8| Washer M3 x 7mm x 0.5mm|
|4| Screw M3 dome x 10mm|
|4| Nut M3 x 2.4mm nyloc|
|4| Screw M3 dome x 10mm|
|8| Washer M3 x 7mm x 0.5mm|
### 3D Printed parts
@@ -122,14 +125,14 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
### Vitamins
|Qty|Description|
|--:|:----------|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|2| Wire brown 30/0.25mm strands, length 150mm - not shown|
|3| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|1| IEC inlet for ATX|
|2| Nut M3 x 2.4mm nyloc|
|2| Screw M3 cs cap x 12mm|
|2| Washer M3 x 7mm x 0.5mm|
|2| Nut M3 x 2.4mm nyloc|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|2| Wire brown 30/0.25mm strands, length 150mm - not shown|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
### Sub-assemblies
@@ -161,15 +164,15 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
### Vitamins
|Qty|Description|
|--:|:----------|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|5| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|3| Ferrule for 1.5mm^2 wire - not shown|
|1| Mains socket 13A|
|2| Screw M3 cs cap x 20mm|
|2| 4mm shielded jack socket blue|
|1| 4mm shielded jack socket brown|
|2| 4mm shielded jack socket green|
|3| Ferrule for 1.5mm^2 wire - not shown|
|5| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|1| Mains socket 13A|
|2| Screw M3 cs cap x 20mm|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
### Sub-assemblies

BIN
gallery/FilamentDryBox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
gallery/SunBot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

View File

@@ -6,6 +6,13 @@ Arduino thermostat to control a beer fridge to use it as an environmental chambe
![](ArduinoThermostat.png)
<a name="TOP"></a>
## FilamentDryBox
A small fan oven with a spool holder to keep the filament warm and dry.
![](FilamentDryBox.png)
<a name="TOP"></a>
## HydraBot
Current state of HydraRaptor after being modified for laser engraving.
@@ -68,6 +75,13 @@ Mains isolated and variable supply with metering.
![](Mains_Box.png)
<a name="TOP"></a>
## SunBot
A solar tracker to keep solar powerbanks pointing at the sun.
![](SunBot.png)
<a name="TOP"></a>
## Turntable
WiFi enabled remote control turntable for photography

View File

@@ -60,10 +60,13 @@ include <vitamins/ball_bearings.scad>
include <vitamins/light_strips.scad>
include <vitamins/spools.scad>
include <vitamins/mains_sockets.scad>
include <vitamins/ldrs.scad>
include <vitamins/geared_steppers.scad>
use <vitamins/jack.scad>
use <vitamins/meter.scad>
use <vitamins/fuseholder.scad>
use <vitamins/hygrometer.scad>
use <vitamins/opengrab.scad>
use <vitamins/wire.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 KiB

After

Width:  |  Height:  |  Size: 716 KiB

View File

@@ -34,12 +34,14 @@ use <tests/d_connectors.scad>
use <tests/displays.scad>
use <tests/fans.scad>
use <tests/fuseholder.scad>
use <tests/geared_steppers.scad>
use <tests/hot_ends.scad>
use <tests/iecs.scad>
use <tests/inserts.scad>
use <tests/jack.scad>
use <tests/leadnuts.scad>
use <tests/leds.scad>
use <tests/ldrs.scad>
use <tests/light_strips.scad>
use <tests/linear_bearings.scad>
use <tests/meter.scad>
@@ -88,6 +90,7 @@ use <tests/socket_box.scad>
use <tests/strap_handle.scad>
use <tests/ssr_shroud.scad>
use <tests/psu_shroud.scad>
use <tests/flat_hinge.scad>
x5 = 800;
@@ -114,6 +117,9 @@ translate([x5 + 70, cable_grommets_y + 150])
translate([x5, cable_grommets_y + 470]) {
door_hinges()
door_latches();
translate([120, 0])
flat_hinges();
}
translate([x5, cable_grommets_y + 370])
@@ -152,7 +158,7 @@ fans_y = displays_y + 100;
transformers_y = fans_y + 120;
psus_y = transformers_y + 190;
translate([x0 + 20, inserts_y])
translate([x0 + 30, inserts_y])
inserts();
translate([x0, inserts_y])
@@ -248,6 +254,9 @@ components_y = toggles_y + 40;
translate([x2, leds_y])
leds();
translate([x2 + 40, leds_y])
ldrs();
translate([x2 + 8, carriers_y])
carriers();
@@ -292,6 +301,9 @@ steppers_y = batteries_y + 70;
translate([x3, veroboard_y])
veroboard_test();
translate([x3 + 70, veroboard_y + 30])
geared_steppers();
translate([x3, d_connectors_y])
d_connectors();
@@ -301,7 +313,10 @@ translate([x3, iecs_y])
translate([x3 + 15, modules_y])
microview();
translate([x3 + 40, modules_y])
translate([x3 + 60, modules_y])
hygrometer();
translate([x3 + 90, modules_y])
modules();
translate([x3, ssrs_y]) {

View File

@@ -27,6 +27,10 @@
//! A list specifies the internal dimensions, screw type, top, bottom and side sheet types and the block
//! maximum spacing.
//!
//! * An optional name can be specified to allow more then one box in a project.
//! * An optional list of fixing blocks to be omitted can be given.
//! * Star washers can be omitted by setting the 11th parameter to false.
//!
//! Uses [fixing blocks](#fixing_block) and [corner blocks](#corner_block).
//
@@ -34,17 +38,20 @@ use <fixing_block.scad>
use <corner_block.scad>
use <../utils/maths.scad>
function bbox_screw(type) = type[0]; //! Screw type for corner blocks
function bbox_sheets(type) = type[1]; //! Sheet type for the sides
function bbox_base_sheet(type)= type[2]; //! Sheet type for the base
function bbox_top_sheet(type) = type[3]; //! Sheet type for the top
function bbox_span(type) = type[4]; //! Maximum span between fixing blocks
function bbox_width(type) = type[5]; //! Internal width
function bbox_depth(type) = type[6]; //! Internal depth
function bbox_height(type) = type[7]; //! Internal height
function bbox_screw(type) = type[0]; //! Screw type for corner blocks
function bbox_sheets(type) = type[1]; //! Sheet type for the sides
function bbox_base_sheet(type) = type[2]; //! Sheet type for the base
function bbox_top_sheet(type) = type[3]; //! Sheet type for the top
function bbox_span(type) = type[4]; //! Maximum span between fixing blocks
function bbox_width(type) = type[5]; //! Internal width
function bbox_depth(type) = type[6]; //! Internal depth
function bbox_height(type) = type[7]; //! Internal height
function bbox_name(type) = type[8] ? type[8] : "bbox"; //! Optional name if there is more than one box in a project
function bbox_skip_blocks(type)= type[9] ? type[9] : []; //! List of fixing blocks to skip, used to allow a hinged panel for example
function star_washers(type) = type[10] ? type[10] : is_undef(type[10]); //! Set to false to remove star washers.
module bbox_shelf_blank(type) { //! 2D template for a shelf
dxf("bbox_shelf");
dxf(str(bbox_name(type), "_shelf"));
sheet_2D(bbox_sheets(type), bbox_width(type), bbox_depth(type), 1);
}
@@ -60,18 +67,8 @@ function corner_block_positions(type) = let(
y = [-1,-1,1,1][corner]
) translate([x * (width / 2), y * (depth / 2), z * height / 2]) *
rotate([z > 0 ? 180 : 0, 0, corner * 90 + (z > 0 ? 90 : 0)])
];
module corner_block_positions(type) {
bt = sheet_thickness(bbox_base_sheet(type));
tt = sheet_thickness(bbox_top_sheet(type));
for(p = corner_block_positions(type))
let($thickness = transform([0, 0, 0], p).z > 0 ? tt : bt)
multmatrix(p)
children();
}
function corner_holes(type) = [for(p = corner_block_positions(type), q = corner_block_holes(bbox_screw(type))) p * q];
function fixing_block_positions(type) = let(
@@ -84,36 +81,28 @@ function fixing_block_positions(type) = let(
dspans = floor(depth / span),
dspan = depth / (dspans + 1),
hspans = floor(height / span),
hspan = height / (hspans + 1)
hspan = height / (hspans + 1),
skips = bbox_skip_blocks(type)
)
[
for(i = [0 : 1 : wspans - 1], y = [-1, 1], z = [-1, 1])
translate([(i - (wspans - 1) / 2) * wspan, y * depth / 2, z * height / 2]) *
rotate([0, z * 90 + 90, y * 90 + 90]),
if(!in(skips, [0, y, z]))
translate([(i - (wspans - 1) / 2) * wspan, y * depth / 2, z * height / 2]) *
rotate([0, z * 90 + 90, y * 90 + 90]),
for(i = [0 : 1 : dspans - 1], x = [-1, 1], z = [-1, 1])
translate([x * width / 2, (i - (dspans - 1) / 2) * dspan, z * height / 2]) *
rotate([0, z * 90 + 90, x * 90]),
if(!in(skips, [x, 0, z]))
translate([x * width / 2, (i - (dspans - 1) / 2) * dspan, z * height / 2]) *
rotate([0, z * 90 + 90, x * 90]),
for(i = [0 : 1 : hspans - 1], x = [-1, 1], y = [-1, 1])
translate([x * width / 2, y * depth / 2, (i - (hspans - 1) / 2) * hspan]) *
rotate([y > 0 ? 180 : 0, x * y * 90, 0]),
if(!in(skips, [x, y, 0]))
translate([x * width / 2, y * depth / 2, (i - (hspans - 1) / 2) * hspan]) *
rotate([y > 0 ? 180 : 0, x * y * 90, 0]),
];
function side_holes(type) = [for(p = fixing_block_positions(type), q = fixing_block_holes(bbox_screw(type))) p * q];
module fixing_block_positions(type) {
t = sheet_thickness(bbox_sheets(type));
bt = sheet_thickness(bbox_base_sheet(type));
tt = sheet_thickness(bbox_top_sheet(type));
h = bbox_height(type) / 2 - 1;
for(p = fixing_block_positions(type))
let(z = transform([0, 0, 0], p).z, $thickness = z > h ? tt : z < -h ? bt : t)
multmatrix(p)
children();
}
module drill_holes(type, t)
for(list = [corner_holes(type), side_holes(type)], p = list)
let(q = t * p)
@@ -122,7 +111,7 @@ module drill_holes(type, t)
drill(screw_clearance_radius(bbox_screw(type)), 0);
module bbox_base_blank(type) { //! 2D template for the base
dxf("bbox_base");
dxf(str(bbox_name(type), "_base"));
difference() {
sheet_2D(bbox_base_sheet(type), bbox_width(type), bbox_depth(type), 1);
@@ -132,7 +121,7 @@ module bbox_base_blank(type) { //! 2D template for the base
}
module bbox_top_blank(type) { //! 2D template for the top
dxf("bbox_top");
dxf(str(bbox_name(type), "_top"));
t = sheet_thickness(bbox_sheets(type));
@@ -144,36 +133,40 @@ module bbox_top_blank(type) { //! 2D template for the top
}
}
module bbox_left_blank(type) { //! 2D template for the left side
dxf("bbox_left");
function subst_sheet(type, sheet) =
let(s = bbox_sheets(type))
sheet ? assert(sheet_thickness(sheet) == sheet_thickness(s)) sheet : s;
module bbox_left_blank(type, sheet = false) { //! 2D template for the left side
dxf(str(bbox_name(type), "_left"));
t = sheet_thickness(bbox_sheets(type));
bb = sheet_thickness(bbox_base_sheet(type));
difference() {
translate([-t / 2, -bb / 2])
sheet_2D(bbox_sheets(type), bbox_depth(type) + t, bbox_height(type) + bb);
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]));
}
}
module bbox_right_blank(type) { //! 2D template for the right side
dxf("bbox_right");
module bbox_right_blank(type, sheet = false) { //! 2D template for the right side
dxf(str(bbox_name(type), "_right"));
t = sheet_thickness(bbox_sheets(type));
bb = sheet_thickness(bbox_base_sheet(type));
difference() {
translate([t / 2, -bb / 2])
sheet_2D(bbox_sheets(type), bbox_depth(type) + t, bbox_height(type) + bb);
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]));
drill_holes(type, rotate([0, 90, 90]) * translate([-bbox_width(type) / 2, 0]));
}
}
module bbox_front_blank(type) { //! 2D template for the front
dxf("bbox_front");
module bbox_front_blank(type, sheet = false) { //! 2D template for the front
dxf(str(bbox_name(type), "_front"));
t = sheet_thickness(bbox_sheets(type));
bb = sheet_thickness(bbox_base_sheet(type));
@@ -181,23 +174,23 @@ module bbox_front_blank(type) { //! 2D template for the front
difference() {
translate([0, (bt - bb) / 2])
sheet_2D(bbox_sheets(type), bbox_width(type) + 2 * t, bbox_height(type) + bb + bt);
sheet_2D(subst_sheet(type, sheet), bbox_width(type) + 2 * t, bbox_height(type) + bb + bt);
drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
}
}
module bbox_back_blank(type) { //! 2D template for the back
dxf("bbox_back");
module bbox_back_blank(type, sheet = false) { //! 2D template for the back
dxf(str(bbox_name(type), "_back"));
bb = sheet_thickness(bbox_base_sheet(type));
t = sheet_thickness(bbox_sheets(type));
difference() {
translate([0, -bb / 2])
sheet_2D(bbox_sheets(type), bbox_width(type), bbox_height(type) + bb);
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]));
drill_holes(type, rotate([-90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
}
}
@@ -208,8 +201,7 @@ module bbox_front(type) render_2D_sheet(bbox_sheets(type)) bbox_front_blank(type
module bbox_left(type) render_2D_sheet(bbox_sheets(type)) bbox_left_blank(type); //! Default left side, can be overridden to customise
module bbox_right(type) render_2D_sheet(bbox_sheets(type)) bbox_right_blank(type); //! Default right side, can be overridden to customise
module _bbox_assembly(type, top = true, base = true, left = true, right = true, back = true, front = true) //! The box assembly, wrap with a local copy without parameters
assembly("bbox") {
module _bbox_assembly(type, top = true, base = true, left = true, right = true, back = true, front = true) { //! The box assembly, wrap with a local copy without parameters
width = bbox_width(type);
depth = bbox_depth(type);
height = bbox_height(type);
@@ -219,43 +211,54 @@ assembly("bbox") {
bt = sheet_thickness(bbox_base_sheet(type));
tt = sheet_thickness(bbox_top_sheet(type));
corner_block_positions(type)
fastened_corner_block_assembly(t, bbox_screw(type), $thickness);
function is_missing_screw(p) = p.y > depth / 2 - 1 ? !back : false;
fixing_block_positions(type)
fastened_fixing_block_assembly(t, bbox_screw(type), thickness2 = $thickness);
assembly(bbox_name(type)) {
for(x = [-1, 1])
translate([x * (width / 2 + t / 2 + eps + 25 * exploded()), 0])
rotate([90, 0, x * 90])
if(x > 0) {
if(right)
bbox_right(type);
for(p = corner_block_positions(type))
let(q = transform([0, 0, 0], p), thickness = q.z > 0 ? tt : bt)
multmatrix(p)
fastened_corner_block_assembly(is_missing_screw(q) && ((q.z > 0) != (q.x > 0)) ? 0 : t, bbox_screw(type), thickness,
is_missing_screw(q) && ((q.z > 0) == (q.x > 0)) ? 0 : t, star_washers = star_washers(type));
h = height / 2 - 1;
for(p = fixing_block_positions(type))
let(q = transform([0, 0, 0], p), thickness = q.z > h ? tt : q.z < -h ? bt : t)
multmatrix(p)
fastened_fixing_block_assembly(is_missing_screw(q) ? 0 : t, bbox_screw(type), thickness2 = thickness, star_washers = star_washers(type));
for(x = [-1, 1])
translate([x * (width / 2 + t / 2 + eps + 25 * exploded()), 0])
rotate([90, 0, x * 90])
if(x > 0) {
if(right)
bbox_right(type);
}
else
if(left)
bbox_left(type);
for(y = [1, -1])
translate([0, y * (depth / 2 + t / 2 + eps + 25 * exploded())])
rotate([90, 0, y * 90 + 90])
if(y < 0) {
if(front)
bbox_front(type);
}
else
if(back)
bbox_back(type);
for(z = [-1, 1]) {
sheet_thickness = z > 0 ? tt : bt;
translate_z(z * (height / 2 + sheet_thickness / 2 + eps + 100 * exploded()))
if(z > 0) {
if(top)
bbox_top(type);
}
else
if(left)
bbox_left(type);
for(y = [-1, 1])
translate([0, y * (depth / 2 + t / 2 + eps + 25 * exploded())])
rotate([90, 0, y * 90 + 90])
if(y < 0) {
if(front)
bbox_front(type);
}
else
if(back)
bbox_back(type);
for(z = [-1, 1]) {
sheet_thickness = z > 0 ? tt : bt;
translate_z(z * (height / 2 + sheet_thickness / 2 + eps + 100 * exploded()))
if(z > 0) {
if(top)
bbox_top(type);
}
else
if(base)
bbox_base(type);
if(base)
bbox_base(type);
}
}
}

View File

@@ -130,7 +130,7 @@ module round_grommet_bottom(diameter, od = undef) { //! Generate the STL for a r
}
module round_grommet_hole(diameter, h = 100) //! Make a hole for a round grommet
drill(diameter / 2 + wall + clearance, h);
drill(corrected_radius(diameter / 2) + wall + clearance, h);
module round_grommet_assembly(diameter, thickness, od = undef) {
color(pp1_colour)
@@ -149,12 +149,17 @@ module mouse_grommet_hole(r, h = 50, z = undef, expand = wall + clearance) //! M
hull(){
R = r + expand;
translate([0, z == undef ? R : z])
semi_circle(R);
if(expand)
semi_circle(R);
else
semi_teardrop(r = R, h = 0);
translate([-R, 0])
square([2 * R, eps]);
}
function mouse_grommet_offset(r) = r + wall;
module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
stl(str("mouse_grommet_", r * 10, "_", thickness));
@@ -167,7 +172,7 @@ module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
translate_z(side * (width - wall) / 2)
linear_extrude(height = wall, center = true)
difference() {
mouse_grommet_hole(r + wall + overlap, z = r + wall, h = 0, expand = 0);
mouse_grommet_hole(r, z = r + wall, h = 0, expand = wall + overlap);
translate([0, wall])
mouse_grommet_hole(r, h = 0, expand = 0);
@@ -182,6 +187,20 @@ module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
}
}
module mouse_grommet_assembly(r, thickness)
color(pp1_colour)
rotate([-90, 0, 0])
mouse_grommet(r, thickness);
module ribbon_grommet_20_3_stl() ribbon_grommet(20, 3);
module mouse_grommet_20_3_stl() mouse_grommet(2,3);
module mouse_grommet_30_3_stl() mouse_grommet(3,3);
module mouse_grommet_15_3_stl() mouse_grommet(1.5, 3);
module mouse_grommet_20_3_stl() mouse_grommet(2, 3);
module mouse_grommet_30_3_stl() mouse_grommet(3, 3);
module round_grommet_bottom_30_stl() round_grommet_bottom(3);
module round_grommet_bottom_40_stl() round_grommet_bottom(4);
module round_grommet_bottom_60_stl() round_grommet_bottom(6);
module round_grommet_top_30_3_stl() round_grommet_top(3, 3);
module round_grommet_top_40_3_stl() round_grommet_top(4, 3);
module round_grommet_top_60_3_stl() round_grommet_top(6, 3);

View File

@@ -24,6 +24,11 @@
//! See [butt_box](#Butt_box) for an example of usage.
//!
//! Note that the block with its inserts is defined as a sub assembly, but its fasteners get added to the parent assembly.
//!
//! Specific fasteners can be omitted by setting a side's thickness to 0 and the block omitted by setting ```show_block``` to false.
//! This allows the block and one set of fasteners to be on one assembly and the other fasteners on the mating assemblies.
//!
//! Star washers can be omitted by setting ```star_washers``` to false.
//
include <../core.scad>
include <../vitamins/screws.scad>
@@ -57,8 +62,8 @@ module corner_block_v_hole(screw = def_screw) //! Place children at the bottom s
multmatrix(corner_block_v_hole(screw))
children();
module corner_block_h_holes(screw = def_screw) //! Place children at the side screw holes
for(p = corner_block_h_holes(screw))
module corner_block_h_holes(screw = def_screw, index = undef) //! Place children at the side screw holes
for(p = !is_undef(index) ? [corner_block_h_holes(screw)[index]] : corner_block_h_holes(screw))
multmatrix(p)
children();
@@ -126,22 +131,33 @@ assembly(str("corner_block_M", 20 * screw_radius(screw))) {
insert(insert);
}
module fastened_corner_block_assembly(thickness, screw = def_screw, thickness_below = undef, name = false) { //! Printed block with all fasteners
module fastened_corner_block_assembly(thickness, screw = def_screw, thickness_below = undef, thickness_side2 = undef, name = false, show_block = true, star_washers = true) { //! Printed block with all fasteners
thickness2 = !is_undef(thickness_below) ? thickness_below : thickness;
thickness3 = !is_undef(thickness_side2) ? thickness_side2 : thickness;
washer = screw_washer(screw);
insert = screw_insert(screw);
screw_length = screw_shorter_than(2 * washer_thickness(washer) + thickness + insert_length(insert) + overshoot);
function screw_length(t) = screw_shorter_than((star_washers ? 2 : 1) * washer_thickness(washer) + t + insert_length(insert) + overshoot);
screw_length = screw_length(thickness);
screw_length2 = screw_length(thickness2);
screw_length3 = screw_length(thickness3);
corner_block_assembly(screw, name) children();
if(show_block)
corner_block_assembly(screw, name) children();
corner_block_h_holes(screw)
translate_z(thickness)
screw_and_washer(screw, screw_length, true);
if(thickness)
corner_block_h_holes(screw, 0)
translate_z(thickness)
screw_and_washer(screw, screw_length, star_washers);
thickness2 = thickness_below ? thickness_below : thickness;
screw_length2 = screw_shorter_than(2 * washer_thickness(washer) + thickness2 + insert_length(insert) + overshoot);
corner_block_v_hole(screw)
translate_z(thickness2)
screw_and_washer(screw, screw_length2, true);
if(thickness3)
corner_block_h_holes(screw, 1)
translate_z(thickness3)
screw_and_washer(screw, screw_length3, star_washers);
if(thickness2)
corner_block_v_hole(screw)
translate_z(thickness2)
screw_and_washer(screw, screw_length2, star_washers);
}
module corner_block_M20_stl() corner_block(M2_cap_screw);

View File

@@ -24,6 +24,11 @@
//! See [butt_box](#Butt_box) for an example of usage.
//!
//! Note that the block with its inserts is defined as a sub assembly, but its fasteners get added to the parent assembly.
//!
//! Specific fasteners can be omitted by setting a side's thickness to 0 and the block omitted by setting ```show_block``` to false.
//! This allows the block and one set of fasteners to be on one assembly and the other fasteners on the mating assemblies.
//!
//! Star washers can be omitted by setting ```star_washers``` to false.
//
include <../core.scad>
include <../vitamins/screws.scad>
@@ -116,20 +121,24 @@ assembly(str("fixing_block_M", 20 * screw_radius(screw))) {
insert(insert);
}
module fastened_fixing_block_assembly(thickness, screw = def_screw, screw2 = undef, thickness2 = undef) { //! Assembly with fasteners in place
module fastened_fixing_block_assembly(thickness, screw = def_screw, screw2 = undef, thickness2 = undef, show_block = true, star_washers = true) { //! Assembly with fasteners in place
module fb_screw(screw, thickness) {
washer = screw_washer(screw);
insert = screw_insert(screw);
screw_length = screw_longer_than(2 * washer_thickness(washer) + thickness + insert_length(insert));
screw_length = screw_longer_than((star_washers ? 2 : 1) * washer_thickness(washer) + thickness + insert_length(insert));
translate_z(thickness)
screw_and_washer(screw, screw_length, true);
if(thickness)
translate_z(thickness)
screw_and_washer(screw, screw_length, star_washers);
}
no_pose() fixing_block_assembly(screw);
if(show_block)
no_pose()
fixing_block_assembly(screw);
t2 = !is_undef(thickness2) ? thickness2 : thickness;
fixing_block_v_holes(screw)
fb_screw(screw, thickness2 ? thickness2 : thickness);
fb_screw(screw, t2);
fixing_block_h_hole(screw)
fb_screw(screw2 ? screw2 : screw, thickness);

180
printed/flat_hinge.scad Normal file
View File

@@ -0,0 +1,180 @@
//
// 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/>.
//
//
//! A parametric flat hinge. A piece of filament can be used for the hinge pin.
//!
//! The width, depth, thickness, number and type of screws, number of knuckles, knuckle diameter, pin diameter and clearance can all be varied.
//! A margin between the screws and the knuckle edge can be enforced to allow the hinge to bend all the way back to 270&deg; from closed.
//!
//! Opening the test in OpenSCAD with its customiser enabled allows these parameters to be played with.
//!
//! Note setting ```thickness1``` or ```thickness2``` to zero in the ```hinge_fastened_assembly()``` removes the screws from one side or the other and
//! setting ```show_hinge``` to false removes the hinge.
//! This allows the hinges and one set of screws to belong to one assembly and the other set of screws to another assembly.
//
include <../core.scad>
include <../vitamins/screws.scad>
function hinge_width(type) = type[1]; //! Width
function hinge_depth(type) = type[2]; //! Depth of each leaf
function hinge_thickness(type) = type[3]; //! Thickness of the leaves
function hinge_pin_dia(type) = type[4]; //! The pin diameter
function hinge_knuckle_dia(type) = type[5]; //! The knuckle diameter
function hinge_knuckles(type) = type[6]; //! How many knuckles
function hinge_screw(type) = type[7]; //! Screw type to mount it
function hinge_screws(type) = type[8]; //! How many screws
function hinge_clearance(type) = type[9]; //! Clearance between knuckles
function hinge_margin(type) = type[10]; //! How far to keep the screws from the knuckes
function hinge_radius(type) = washer_radius(screw_washer(hinge_screw(type))) + 1;
module hinge_screw_positions(type) { //! Place children at the screw positions
screws = hinge_screws(type);
w = hinge_width(type);
d = hinge_depth(type);
r = hinge_radius(type);
m = hinge_margin(type);
assert(screws > 1, "must be at least two screws");
w_pitch = (w - 2 * r) / (screws - 1);
d_pitch = d - 2 * r - m;
wr = washer_radius(screw_washer(hinge_screw(type)));
assert(w_pitch >= wr && norm([w_pitch, d_pitch]) >= 2 * wr && d_pitch >= 0, "not enough room for screws");
for(i = [0 : screws - 1])
translate([-w / 2 + r + i * w_pitch, r + m + (i % 2) * d_pitch])
children();
}
module hinge_male(type, female = false) { //! The half with the stationary pin
stl(str("hinge_", female ? "fe": "", "male_", type[0]));
r = hinge_radius(type);
w = hinge_width(type);
t = hinge_thickness(type);
kr = hinge_knuckle_dia(type) / 2;
pr = hinge_pin_dia(type) / 2;
assert(kr > pr, "knuckle diameter must be bigger than the pin diameter");
n = hinge_knuckles(type);
assert(n >= 3, "must be at least three knuckes");
mn = ceil(n / 2); // Male knuckles
fn = floor(n / 2); // Female knuckles
gap = hinge_clearance(type);
mw = (w - (n - 1) * gap) / 2 / mn; // Male knuckle width
fw = (w - (n - 1) * gap) / 2 / fn; // Female knuckle width
teardrop_r = kr / cos(22.5); // The corner on the teardrop
inset = sqrt(sqr(teardrop_r + gap) - sqr(kr - t)) - kr;
linear_extrude(height =t)
difference() {
hull() {
for(side = [-1, 1])
translate([side * (w / 2 - r), hinge_depth(type) - r])
circle4n(r);
translate([-w / 2, inset])
square([w, eps]);
}
hinge_screw_positions(type)
poly_circle(screw_clearance_radius(hinge_screw(type)));
}
pitch = mw + gap + fw + gap;
dir = female ? -1 : 1;
translate([0, -kr, kr])
rotate([90, 0, -90])
for(z = [0 : (female ? fn : mn) - 1])
translate_z(-dir * w / 2 + z * dir * pitch + (female ? -fw - mw - gap : 0))
linear_extrude(height = female ? fw : mw)
difference() {
hull() {
rotate(180)
teardrop(r = kr, h = 0);
translate([-kr - 1, -kr])
square(1);
}
teardrop_plus(r = pr + (female ? gap : 0), h = 0);
}
}
module hinge_female(type) hinge_male(type, true);
module hinge_both(type) { //! Both parts together for printing
hinge_male(type);
translate([0, -hinge_knuckle_dia(type)])
rotate(180)
hinge_female(type);
}
module hinge_assembly(type, angle = 0)
assembly(str("hinge_", type[0])) { //! Assembled hinge
kr = hinge_knuckle_dia(type) / 2;
hr = hinge_pin_dia(type) / 2;
w = hinge_width(type);
vitamin(str(": Hinge pin ", w, " x ", 2 * hr, "mm"));
color(pp1_colour) hinge_male(type);
translate([0, -kr, kr]) {
rotate([0, 90, 0])
explode(w + 10)
color("silver") cylinder(r = hr , h = w, center = true);
rotate([-angle, 0, 0])
translate([0, -kr, -kr])
rotate(180)
color(pp2_colour) hinge_female(type);
}
}
module hinge_fastened_assembly(type, thickness1, thickness2, angle, show_hinge = true) { //! Assembled hinge with its fasteners
if(show_hinge)
hinge_assembly(type, angle);
screw = hinge_screw(type);
washer_t = 2 * washer_thickness(screw_washer(screw));
nut = screw_nut(screw);
nut_t = nut_thickness(nut, true);
t = hinge_thickness(type);
kr = hinge_knuckle_dia(type) / 2;
module fasteners(thickness)
if(thickness)
hinge_screw_positions(type) {
translate_z(t)
screw_and_washer(screw, screw_longer_than(t + thickness + washer_t + nut_t));
translate_z(-thickness)
vflip()
nut_and_washer(nut, true);
}
fasteners(thickness1);
translate([0, -kr, kr])
rotate([-angle, 0, 0])
translate([0, -kr, - kr])
rotate(180)
fasteners(thickness2);
}

View File

@@ -66,7 +66,7 @@ module foot(type = foot) { //! Generate STL
}
}
module foot_assembly(t = 0, type = foot) { //! Assembly with fasteners in place for specified sheet thickness
module foot_assembly(t = 0, type = foot, flip = false) { //! Assembly with fasteners in place for specified sheet thickness
screw = foot_screw(type);
washer = screw_washer(screw);
nut = screw_nut(screw);
@@ -79,11 +79,17 @@ module foot_assembly(t = 0, type = foot) { //! Assembly with fasteners in place
if(t)
explode(15, true)
translate_z(foot_thickness(type))
screw_and_washer(screw, screw_length);
if(flip)
nut_and_washer(nut, true);
else
screw_and_washer(screw, screw_length);
}
if(t)
translate_z(t)
nut_and_washer(nut, true);
if(flip)
screw_and_washer(screw, screw_length);
else
nut_and_washer(nut, true);
}
module insert_foot(type = insert_foot) { //! Generate STL for foot with insert

View File

@@ -33,10 +33,8 @@ wall = 1.8;
top = 1.5;
screw = M3_cap_screw;
insert = screw_insert(screw);
boss_r = wall + corrected_radius(insert_hole_radius(insert));
boss_h = insert_hole_length(insert);
boss_r = insert_boss_radius(insert, wall);
counter_bore = 2;
boss_h2 = boss_h + counter_bore;
rad = 2;
clearance = layer_height;
overlap = 6;
@@ -137,49 +135,13 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
mirror([0, 1, 0]) {
// insert boss
translate_z(height - boss_h)
linear_extrude(height = boss_h)
psu_shroud_hole_positions(type)
difference() {
hull() {
circle(boss_r);
translate([0, $side * (boss_r - 1)])
square([2 * boss_r, eps], center = true);
}
poly_circle(insert_hole_radius(insert));
}
// insert boss counter_bore
translate_z(height - boss_h2)
linear_extrude(height = counter_bore + eps)
psu_shroud_hole_positions(type)
difference() {
hull() {
circle(boss_r);
translate([0, $side * (boss_r - 1)])
square([2 * boss_r, eps], center = true);
}
poly_circle(insert_screw_diameter(insert) / 2 + 0.1);
}
// support cones
translate_z(height - boss_h2)
psu_shroud_hole_positions(type)
hull() {
cylinder(h = eps, r = boss_r - eps);
translate([0, $side * (boss_r - 1)])
cube([2 * boss_r, eps, eps], center = true);
translate([0, $side * (boss_r - wall), - (2 * boss_r - wall)])
cube(eps);
}
}
}
// insert lugs
mirror([0, 1, 0])
psu_shroud_hole_positions(type)
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
module psu_shroud_assembly(type, cable_d, name, cables = 1) //! The printed parts with inserts fitted
assembly(str("psu_shroud_", name)) {

View File

@@ -30,7 +30,7 @@ knob_stem_h = 6;
knob_thickness = 4;
knob_r = 8;
knob_wave = 1;
knob_waves = 9;
knob_waves = 5;
knob_height = knob_stem_h + knob_thickness;
function knob_height() = knob_height;
@@ -73,5 +73,8 @@ assembly(str("screw_knob_M", 20 * screw_radius(screw), "_", length)) {
module screw_knob_M30_stl() screw_knob(M3_hex_screw);
module screw_knob_M40_stl() screw_knob(M4_hex_screw);
//! * Press the M3 x 16 hex screw into the knob
module screw_knob_M30_16_assembly() screw_knob_assembly(M3_hex_screw, 16);
//! * Press the M4 x 16 hex screw into the knob
module screw_knob_M40_16_assembly() screw_knob_assembly(M4_hex_screw, 16);

View File

@@ -33,10 +33,8 @@ wall = 1.8;
top = 1.5;
screw = M3_cap_screw;
insert = screw_insert(screw);
boss_r = wall + corrected_radius(insert_hole_radius(insert));
boss_h = insert_hole_length(insert);
boss_r = insert_boss_radius(insert, wall);
counter_bore = 2;
boss_h2 = boss_h + counter_bore;
rad = 3;
clearance = layer_height;
@@ -61,7 +59,6 @@ module ssr_shroud_holes(type, cable_d) { //! Drill the screw and ziptie holes
translate([ssr_shroud_cable_x(type, cable_d), side * (ssr_width(type) / 2 - 2 * boss_r)])
rotate(-90)
cable_tie_holes(cable_d / 2, h = 0);
}
module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a specified ssr and cable
@@ -103,45 +100,11 @@ module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a spec
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
// insert boss
translate_z(height - boss_h)
linear_extrude(height = boss_h)
ssr_shroud_hole_positions(type)
difference() {
hull() {
circle(boss_r);
translate([0, -$side * (boss_r - 1)])
square([2 * boss_r, eps], center = true);
}
poly_circle(insert_hole_radius(insert));
}
// insert boss counter_bore
translate_z(height - boss_h2)
linear_extrude(height = counter_bore + eps)
ssr_shroud_hole_positions(type)
difference() {
hull() {
circle(boss_r);
translate([0, -$side * (boss_r - 1)])
square([2 * boss_r, eps], center = true);
}
poly_circle(insert_screw_diameter(insert) / 2 + 0.1);
}
// support cones
ssr_shroud_hole_positions(type)
hull() {
translate_z(-height + boss_h2) {
cylinder(h = eps, r = boss_r - eps);
translate([0, -$side * (boss_r - 1)])
cube([2 * boss_r, eps, eps], center = true);
}
translate([0, -$side * (boss_r - wall), -height + boss_h2 + (2 * boss_r - wall)])
cube(eps);
}
vflip()
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
module ssr_shroud_assembly(type, cable_d, name) //! The printed parts with inserts fitted
@@ -153,7 +116,6 @@ assembly(str("ssr_shroud_", name)) {
ssr_shroud_hole_positions(type)
insert(insert);
}
module ssr_shroud_fastened_assembly(type, cable_d, thickness, name) //! Assembly with screws in place
@@ -177,6 +139,4 @@ module ssr_shroud_fastened_assembly(type, cable_d, thickness, name) //! Assembly
color(grey20)
cylinder(d = cable_d, h = 20, center = true);
}
}

534
readme.md
View File

@@ -17,34 +17,36 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
## Table of Contents<a name="top"/>
<table><tr>
<th align="left"> Vitamins A-N </th><th align="left"> Vitamins O-Z </th><th align="left"> Printed </th><th align="left"> Utilities </th><th align="left"> Core Utilities </th></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#Bom">Bom</a> </td></tr>
<th align="left"> Vitamins A-M </th><th align="left"> Vitamins N-Z </th><th align="left"> Printed </th><th align="left"> Utilities </th><th align="left"> Core Utilities </th></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#Nuts">Nuts</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 = "#Batteries">Batteries</a> </td><td> <a href = "#O_ring">O_ring</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 = "#Belts">Belts</a> </td><td> <a href = "#Pcbs">Pcbs</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 = "#Blowers">Blowers</a> </td><td> <a href = "#Pillars">Pillars</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 = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Pin_headers">Pin_headers</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 = "#Buttons">Buttons</a> </td><td> <a href = "#Psus">Psus</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 = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Pulleys">Pulleys</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 = "#Components">Components</a> </td><td> <a href = "#Rails">Rails</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 = "#Displays">Displays</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</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 = "#D_connectors">D_connectors</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Screws">Screws</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 = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</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 = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Iecs">Iecs</a> </td><td> <a href = "#Spades">Spades</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 = "#Inserts">Inserts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Ssr_shroud">Ssr_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#Ssrs">Ssrs</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leds">Leds</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Meter">Meter</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Nuts">Nuts</a> </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 = "#Opengrab">Opengrab</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 = "#Blowers">Blowers</a> </td><td> <a href = "#Pcbs">Pcbs</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 = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Pillars">Pillars</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 = "#Buttons">Buttons</a> </td><td> <a href = "#Pin_headers">Pin_headers</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 = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Psus">Psus</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 = "#Components">Components</a> </td><td> <a href = "#Pulleys">Pulleys</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 = "#D_connectors">D_connectors</a> </td><td> <a href = "#Rails">Rails</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 = "#Displays">Displays</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</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 = "#Fans">Fans</a> </td><td> <a href = "#Rockers">Rockers</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 = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Rod">Rod</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 = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Psu_shroud">Psu_shroud</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</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 = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Sheets">Sheets</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 = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Iecs">Iecs</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Ssr_shroud">Ssr_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Ssrs">Ssrs</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Ldrs">Ldrs</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leds">Leds</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Meter">Meter</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Modules">Modules</a> </td><td></td><td></td><td></td><td></td></tr>
</table>
---
@@ -163,6 +165,8 @@ exposing enough information to make a battery box.
Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
Only models 2D paths, so not 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.
By default the path is a closed loop but a gap length and position can be specified to make open loops.
Individual teeth are not drawn, instead they are represented by a lighter colour.
@@ -475,55 +479,6 @@ Various electronic components used in hot ends and heated beds.
| 1 | ```resistor(Honewell)``` | Thermistor Honeywell 135-104LAC-J01 100K 1% |
<a href="#top">Top</a>
---
<a name="Displays"></a>
## Displays
LCD dispays.
[vitamins/displays.scad](vitamins/displays.scad) Object definitions.
[vitamins/display.scad](vitamins/display.scad) Implementation.
[tests/displays.scad](tests/displays.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```display_aperture(type)``` | Size of the aperture including its depth |
| ```display_height(type)``` | Depth of the metal part |
| ```display_pcb(type)``` | PCB mounted on the back |
| ```display_pcb_offset(type)``` | 3D offset of the PCB centre |
| ```display_ribbon(type)``` | Keep out region for ribbon cable |
| ```display_thickness(type)``` | Height of the metal part |
| ```display_threads(type)``` | Length that studs protrude from the PCB holes |
| ```display_touch_screen(type)``` | Touch screen position and size |
| ```display_width(type)``` | Width of the metal part |
### Functions
| Function | Description |
|:--- |:--- |
| ```display_depth(type)``` | Total thickness including touch screen and PCB |
| ```display_ts_thickness(type)``` | Touch screen thickness or 0 |
### Modules
| Module | Description |
|:--- |:--- |
| ```display(type)``` | Draw specified display |
| ```display_aperture(type, clearance, clear_pcb = false)``` | Make aperture cutout |
![displays](tests/png/displays.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```display(HDMI5)``` | HDMI display 5" |
| 1 | ```display(LCD1602A)``` | LCD display 1602A |
| 1 | ```display(SSD1963_4p3)``` | LCD display SSD1963 4.3" |
<a href="#top">Top</a>
---
@@ -580,6 +535,55 @@ D-connectors. Can be any number of ways, male or female, solder buckets, PCB mou
| 6 | ```d_pillar()``` | D-type connector pillar |
<a href="#top">Top</a>
---
<a name="Displays"></a>
## Displays
LCD dispays.
[vitamins/displays.scad](vitamins/displays.scad) Object definitions.
[vitamins/display.scad](vitamins/display.scad) Implementation.
[tests/displays.scad](tests/displays.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```display_aperture(type)``` | Size of the aperture including its depth |
| ```display_height(type)``` | Depth of the metal part |
| ```display_pcb(type)``` | PCB mounted on the back |
| ```display_pcb_offset(type)``` | 3D offset of the PCB centre |
| ```display_ribbon(type)``` | Keep out region for ribbon cable |
| ```display_thickness(type)``` | Height of the metal part |
| ```display_threads(type)``` | Length that studs protrude from the PCB holes |
| ```display_touch_screen(type)``` | Touch screen position and size |
| ```display_width(type)``` | Width of the metal part |
### Functions
| Function | Description |
|:--- |:--- |
| ```display_depth(type)``` | Total thickness including touch screen and PCB |
| ```display_ts_thickness(type)``` | Touch screen thickness or 0 |
### Modules
| Module | Description |
|:--- |:--- |
| ```display(type)``` | Draw specified display |
| ```display_aperture(type, clearance, clear_pcb = false)``` | Make aperture cutout |
![displays](tests/png/displays.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```display(HDMI5)``` | HDMI display 5" |
| 1 | ```display(LCD1602A)``` | LCD display 1602A |
| 1 | ```display(SSD1963_4p3)``` | LCD display SSD1963 4.3" |
<a href="#top">Top</a>
---
@@ -620,7 +624,7 @@ Can draw three styles: solid, open frame and open frame with screw bosses.
| Module | Description |
|:--- |:--- |
| ```fan(type)``` | Draw specified fan, origin in the centre |
| ```fan_assembly(type, thickness, include_fan = true)``` | Fan with its fasteners |
| ```fan_assembly(type, thickness, include_fan = true, screw = false)``` | Fan with its fasteners |
| ```fan_hole_positions(type, z = undef)``` | Position children at the screw hole positions |
| ```fan_holes(type, poly = false, screws = true, h = 100)``` | Make all the holes for the fan, or just the aperture if ```screws``` is false. Set ```poly``` true for poly_holes. |
@@ -683,6 +687,57 @@ Can draw three styles: solid, open frame and open frame with screw bosses.
| 1 | ```fuseholder(6)``` | Fuse holder 20mm |
<a href="#top">Top</a>
---
<a name="Geared_steppers"></a>
## Geared_steppers
Geared tin can steppers
[vitamins/geared_steppers.scad](vitamins/geared_steppers.scad) Object definitions.
[vitamins/geared_stepper.scad](vitamins/geared_stepper.scad) Implementation.
[tests/geared_steppers.scad](tests/geared_steppers.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```gs_boss_d(type)``` | Boss around the shaft diameter |
| ```gs_boss_h(type)``` | Boss around the shaft height |
| ```gs_bulge2_d(type)``` | Plastic rear bulge depth from centre |
| ```gs_bulge2_h(type)``` | Plastic rear bulge height |
| ```gs_bulge2_w(type)``` | Plastic rear bulge width |
| ```gs_bulge_d(type)``` | Plastic bulge depth from centre |
| ```gs_bulge_h(type)``` | Plastic bulge height |
| ```gs_bulge_w(type)``` | Plastic bulge width |
| ```gs_diameter(type)``` | Can diameter |
| ```gs_flat_length(type)``` | Shaft flat length |
| ```gs_height(type)``` | Can height |
| ```gs_hole_d(type)``` | Screw hole diameter |
| ```gs_lug_t(type)``` | Screw lug thickness |
| ```gs_lug_w(type)``` | Screw lug width |
| ```gs_offset(type)``` | Offset of the shaft from the centre of the can |
| ```gs_pitch(type)``` | Screw pitch |
| ```gs_shaft_d(type)``` | Shaft diameter |
| ```gs_shaft_flat(type)``` | Shaft width across the flats |
| ```gs_shaft_length(type)``` | Shaft length |
### Modules
| Module | Description |
|:--- |:--- |
| ```geared_stepper(type)``` | Draw the specified geared stepper |
| ```geared_stepper_screw_positions(type)``` | Place children at the screw positions |
![geared_steppers](tests/png/geared_steppers.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```geared_stepper(28BYJ_48)``` | Geared stepper - 28BYJ-48 5V |
<a href="#top">Top</a>
---
@@ -793,7 +848,38 @@ Needs updating as mostly obsolete versions.
| 1 | | Tape self amalgamating silicone 110mm x 25mm |
| 1 | ```resistor(Epcos)``` | Thermistor Epcos B57560G104F 100K 1% |
| 2 | | Wire Red PTFE 16/0.2mm strands, length 170mm |
| 4 | ```ziptie(small_ziptie, 8)``` | Ziptie 100mm min length |
| 4 | ```ziptie(small_ziptie, 8)``` | Ziptie 2.5mm x 100mm min length |
<a href="#top">Top</a>
---
<a name="Hygrometer"></a>
## Hygrometer
Mini LCD Celsius Digital Thermometer Hygrometer Temperature Humidity Meter Gauge on eBay
[vitamins/hygrometer.scad](vitamins/hygrometer.scad) Implementation.
[tests/hygrometer.scad](tests/hygrometer.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| ```hygrometer_or()``` | The outside radius of a hygrometer |
### Modules
| Module | Description |
|:--- |:--- |
| ```hygrometer()``` | Draw a hygrometer |
| ```hygrometer_hole(h = 0)``` | Drill the hole for a hygrometer |
![hygrometer](tests/png/hygrometer.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```hygrometer()``` | Mini LCD Digital Thermometer / Hygrometer |
<a href="#top">Top</a>
@@ -889,12 +975,18 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
| ```insert_ring3_d(type)``` | Diameter of the bottom ring |
| ```insert_screw_diameter(type)``` | Screw size |
### Functions
| Function | Description |
|:--- |:--- |
| ```insert_boss_radius(type, wall)``` | Compute the outer radius of an insert boss |
### Modules
| Module | Description |
|:--- |:--- |
| ```insert(type)``` | Draw specified insert |
| ```insert_boss(type, z, wall = 2 * extrusion_width)``` | Make a boss to take an insert |
| ```insert_hole(type, counterbore = 0, horizontal = false)``` | Make a hole to take an insert, ```counterbore``` is the extra length for the screw |
| ```insert_lug(insert, wall, counter_bore = 0, extension = 0, corner_r = 0, flying = true)``` | Make a flying insert lug, see [ssr_shroud](#Ssr_shroud) |
![inserts](tests/png/inserts.png)
@@ -945,6 +1037,47 @@ E.g. a "brown" socket for mains live needs to be displayed as "sienna" to look r
| 1 | ```jack_4mm_shielded("brown", 3, "sienna")``` | 4mm shielded jack socket brown |
<a href="#top">Top</a>
---
<a name="Ldrs"></a>
## Ldrs
Light dependent resistors.
Larger ones seem to have both a higher dark resistance and a lower bright light resistance.
[vitamins/ldrs.scad](vitamins/ldrs.scad) Object definitions.
[vitamins/ldr.scad](vitamins/ldr.scad) Implementation.
[tests/ldrs.scad](tests/ldrs.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```ldr_active(type)``` | The active width |
| ```ldr_description(type)``` | Description |
| ```ldr_diameter(type)``` | The diameter of the round bit |
| ```ldr_lead_d(type)``` | The lead diameter |
| ```ldr_pitch(type)``` | Pitch between the leads |
| ```ldr_thickness(type)``` | Thickness |
| ```ldr_width(type)``` | Across the flats |
### Modules
| Module | Description |
|:--- |:--- |
| ```LDR(type, lead_length = 3)``` | Draw an LDR, can specify the lead length |
![ldrs](tests/png/ldrs.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```ldr(large_ldr)``` | Light dependent resistor - large |
| 1 | ```ldr(small_ldr)``` | Light dependent resistor - small |
<a href="#top">Top</a>
---
@@ -1442,6 +1575,34 @@ If a nut is given a child then it gets placed on its top surface.
| 1 | ```wingnut(M4_wingnut)``` | Wingnut M4 |
<a href="#top">Top</a>
---
<a name="O_ring"></a>
## O_ring
Nitrile rubber O-rings.
Just a black torus specified by internal diameter, ```id``` and ```minor_d``` plus a BOM entry.
Can be shown stretched by specifying the ```actual_id```.
[vitamins/o_ring.scad](vitamins/o_ring.scad) Implementation.
[tests/o_ring.scad](tests/o_ring.scad) Code for this example.
### Modules
| Module | Description |
|:--- |:--- |
| ```O_ring(id, minor_d, actual_id = 0)``` | Draw O-ring with specified internal diameter and minor diameter. ```actual_id``` can be used to stretch it around something. |
![o_ring](tests/png/o_ring.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```O_ring(2.5, 1.6)``` | O-ring nitrile 2.5mm x 1.6mm |
<a href="#top">Top</a>
---
@@ -1479,34 +1640,6 @@ A permanent magnet that can be magnatized and de-magnatized electronically.
| 1 | ```opengrab()``` | OpenGrab V3 electro permanent magnet |
<a href="#top">Top</a>
---
<a name="O_ring"></a>
## O_ring
Nitrile rubber O-rings.
Just a black torus specified by internal diameter, ```id``` and ```minor_d``` plus a BOM entry.
Can be shown stretched by specifying the ```actual_id```.
[vitamins/o_ring.scad](vitamins/o_ring.scad) Implementation.
[tests/o_ring.scad](tests/o_ring.scad) Code for this example.
### Modules
| Module | Description |
|:--- |:--- |
| ```O_ring(id, minor_d, actual_id = 0)``` | Draw O-ring with specified internal diameter and minor diameter. ```actual_id``` can be used to stretch it around something. |
![o_ring](tests/png/o_ring.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```O_ring(2.5, 1.6)``` | O-ring nitrile 2.5mm x 1.6mm |
<a href="#top">Top</a>
---
@@ -1558,11 +1691,12 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```pcb_assembly(type, height, thickness)``` | Draw PCB assembly with spaces and fasteners in place |
| ```pcb_base(type, height, thickness, wall = 2)``` | Generate STL for a base with PCB spacers |
| ```pcb_component(comp, cutouts = false, angle = undef)``` | Draw pcb component from description |
| ```pcb_component_position(type, name)``` | Position child at the specified component position |
| ```pcb_components(type, cutouts = false, angle = undef)``` | Draw list of PCB components on the PCB |
| ```pcb_cutouts(type, angle = undef)``` | Make cut outs to clear components on a PCB |
| ```pcb_grid(type, x, y, z = 0)``` | Positions children at specified grid positions |
| ```pcb_screw_positions(type)``` | Positions children at the mounting hole positions |
| ```pcb_spacer(screw, height, wall = 1.8)``` | Generate STL for PCB spacer |
| ```pcb_spacer(screw, height, wall = 1.8, taper = 0)``` | Generate STL for PCB spacer |
| ```rj45(cutout = false)``` | Draw RJ45 Ethernet connector |
| ```terminal_35(ways)``` | Draw 3.5mm terminal block |
| ```uSD(size, cutout = false)``` | Draw uSD socket |
@@ -1575,6 +1709,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```pcb(ArduinoLeonardo)``` | Arduino Leonardo |
| 1 | ```pcb(ArduinoUno3)``` | Arduino Uno R3 |
| 1 | | Cat 5 patch cable 300mm |
| 1 | ```d_plug(DCONN15, pcb = true)``` | D-type 15 way PCB mount plug |
@@ -1588,7 +1723,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```molex_254(2)``` | Molex KK header 2 way |
| 1 | ```molex_254(3)``` | Molex KK header 3 way |
| 16 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 12 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 20 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 12 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 1 | ```pcb(PI_IO)``` | PI_IO V2 |
@@ -1600,38 +1735,41 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```pcb(PERF80x20)``` | Perfboard 80 x 20mm |
| 1 | ```pin_socket(2p54header, 13, 2, right_angle = true)``` | Pin socket 13 x 2 right_angle |
| 1 | ```pcb(RPI3)``` | Raspberry Pi 3 |
| 12 | ```screw(M2_cap_screw, 20)``` | Screw M2 cap x 20mm |
| 4 | ```screw(M2_cap_screw, 25)``` | Screw M2 cap x 25mm |
| 8 | ```screw(M2_cap_screw, 20)``` | Screw M2 cap x 20mm |
| 8 | ```screw(M2_cap_screw, 25)``` | Screw M2 cap x 25mm |
| 4 | ```screw(M2p5_cap_screw, 16)``` | Screw M2.5 cap x 16mm |
| 8 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
| 8 | ```screw(M3_cap_screw, 25)``` | Screw M3 cap x 25mm |
| 4 | ```screw(M3_cap_screw, 30)``` | Screw M3 cap x 30mm |
| 12 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
| 4 | ```screw(M2p5_pan_screw, 30)``` | Screw M2.5 pan x 30mm |
| 4 | ```screw(M3_cap_screw, 25)``` | Screw M3 cap x 25mm |
| 8 | ```screw(M3_cap_screw, 30)``` | Screw M3 cap x 30mm |
| 12 | ```screw(M4_cap_screw, 30)``` | Screw M4 cap x 30mm |
| 3 | ```terminal_35(2)``` | Terminal block 2 way 3.5mm |
| 2 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
| 1 | | USB A to Mini B lead |
| 16 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 12 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 20 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 12 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
| 1 | ```pcb(ZC_A0591)``` | ZC-A0591 ULN2003 driver PCB |
### Printed
| Qty | Filename |
| ---:|:--- |
| 4 | pcb_spacer20100.stl |
| 4 | pcb_spacer20110.stl |
| 4 | pcb_spacer20120.stl |
| 4 | pcb_spacer20130.stl |
| 4 | pcb_spacer2560.stl |
| 8 | pcb_spacer2570.stl |
| 4 | pcb_spacer2580.stl |
| 4 | pcb_spacer2590.stl |
| 4 | pcb_spacer30140.stl |
| 4 | pcb_spacer20140.stl |
| 4 | pcb_spacer25100_2.stl |
| 4 | pcb_spacer25210.stl |
| 4 | pcb_spacer2570.stl |
| 4 | pcb_spacer2580_2.stl |
| 4 | pcb_spacer2590_2.stl |
| 4 | pcb_spacer30150.stl |
| 4 | pcb_spacer30190.stl |
| 4 | pcb_spacer40160.stl |
| 4 | pcb_spacer30160.stl |
| 4 | pcb_spacer30200.stl |
| 4 | pcb_spacer40170.stl |
| 4 | pcb_spacer40180.stl |
| 4 | pcb_spacer40190.stl |
<a href="#top">Top</a>
@@ -1721,9 +1859,9 @@ Pin headers and sockets, etc.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```box_header(2p54header102)``` | Box header 10 x 2 |
| 1 | ```idc_transition(2p54header, 10)``` | IDC transition header 10 x 2 |
| 1 | ```pin_header(2p54header102)``` | Pin header 10 x 2 |
| 1 | ```box_header(2p54header102)``` | Pin header 10 x 2 |
| 1 | ```pin_socket(2p54header, 10, 2)``` | Pin socket 10 x 2 |
| 1 | ```pin_socket(2p54header, 10, 2, right_angle = true)``` | Pin socket 10 x 2 right_angle |
@@ -1994,10 +2132,12 @@ Ring terminals and earth assemblies for DiBond panels.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 2 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 1 | ```ring_terminal(M3_ringterm)``` | Ring terminal 3mm |
| 1 | ```ring_terminal(M3_ringterm_cs)``` | Ring terminal 3mm |
| 1 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
| 1 | ```screw(M3_dome_screw, 10)``` | Screw M3 dome x 10mm |
| 2 | ```star_washer(M3_washer)``` | Washer star M3 x 0.5mm |
| 4 | ```star_washer(M3_washer)``` | Washer star M3 x 0.5mm |
<a href="#top">Top</a>
@@ -2051,13 +2191,19 @@ Rocket switch. Also used for neon indicator in the same form factor.
---
<a name="Rod"></a>
## Rod
Steel rods, with optional chamfer.
Steel rods and studding with chamfered ends.
[vitamins/rod.scad](vitamins/rod.scad) Implementation.
[tests/rod.scad](tests/rod.scad) Code for this example.
### Modules
| Module | Description |
|:--- |:--- |
| ```rod(d , l)``` | Draw a smooth rod with specified length and diameter |
| ```studding(d , l)``` | Draw a threaded rod with specified length and diameter |
![rod](tests/png/rod.png)
### Vitamins
@@ -2070,6 +2216,13 @@ Steel rods, with optional chamfer.
| 1 | ```rod(5, 80)``` | Smooth rod 5mm x 80mm |
| 1 | ```rod(6, 80)``` | Smooth rod 6mm x 80mm |
| 1 | ```rod(8, 80)``` | Smooth rod 8mm x 80mm |
| 1 | ```studding(10, 80)``` | Threaded rod M10 x 80mm |
| 1 | ```studding(12, 80)``` | Threaded rod M12 x 80mm |
| 1 | ```studding(3, 80)``` | Threaded rod M3 x 80mm |
| 1 | ```studding(4, 80)``` | Threaded rod M4 x 80mm |
| 1 | ```studding(5, 80)``` | Threaded rod M5 x 80mm |
| 1 | ```studding(6, 80)``` | Threaded rod M6 x 80mm |
| 1 | ```studding(8, 80)``` | Threaded rod M8 x 80mm |
<a href="#top">Top</a>
@@ -2215,7 +2368,7 @@ Note that modules that drill holes will return a 2D object if ```h``` is set to
|:--- |:--- |
| ```render_2D_sheet(type, color = false)``` | Extrude a 2D sheet template and give it the correct colour |
| ```render_sheet(type, color = false)``` | Render a sheet in the correct colour after holes have been subtracted |
| ```sheet(type, w, d, corners = [0, 0, 0, 0])``` | Draw speified sheet |
| ```sheet(type, w, d, corners = [0, 0, 0, 0])``` | Draw specified sheet |
| ```sheet_2D(type, w, d, corners = [0, 0, 0, 0])``` | 2D sheet template with specified size and optionally rounded corners |
![sheets](tests/png/sheets.png)
@@ -2235,6 +2388,7 @@ Note that modules that drill holes will return a 2D object if ```h``` is set to
| 1 | ```sheet(MDF19, 30, 30, 2)``` | Sheet MDF 30mm x 30mm x 19mm |
| 1 | ```sheet(MDF6, 30, 30, 2)``` | Sheet MDF 30mm x 30mm x 6mm |
| 1 | ```sheet(PMMA10, 30, 30, 2)``` | Sheet acrylic 30mm x 30mm x 10mm |
| 1 | ```sheet(PMMA2, 30, 30, 2)``` | Sheet acrylic 30mm x 30mm x 2mm |
| 1 | ```sheet(PMMA3, 30, 30, 2)``` | Sheet acrylic 30mm x 30mm x 3mm |
| 1 | ```sheet(PMMA6, 30, 30, 2)``` | Sheet acrylic 30mm x 30mm x 6mm |
| 1 | ```sheet(PMMA8, 30, 30, 2)``` | Sheet acrylic 30mm x 30mm x 8mm |
@@ -2303,6 +2457,7 @@ Filament spool models
| Function | Description |
|:--- |:--- |
| ```spool_height(type)``` | Outside width |
| ```spool_pitch(type)``` | Spacing of the rims |
### Modules
| Module | Description |
@@ -2316,6 +2471,7 @@ Filament spool models
| ---:|:--- |:---|
| 1 | ```spool(spool_200x55)``` | Filament spool 200 x 55 |
| 1 | ```spool(spool_300x85)``` | Filament spool 300 x 85 |
| 1 | ```spool(spool_300x88)``` | Filament spool 300 x 88 |
<a href="#top">Top</a>
@@ -2527,7 +2683,7 @@ Toggle switches
| ---:|:--- |:---|
| 1 | ```toggle(AP5236, 3)``` | Toggle switch AP5236 |
| 1 | ```toggle(CK7101, 3)``` | Toggle switch CK7101 |
| 1 | ```toggle(CK7105, 3)``` | Toggle switch CK7101 |
| 1 | ```toggle(CK7105, 3)``` | Toggle switch CK7105 |
| 1 | ```toggle(MS332F, 3)``` | Toggle switch MS332F |
@@ -2869,7 +3025,7 @@ Just a BOM entry at the moment and cable bundle size functions for holes, plus c
|:--- |:--- |
| ```cable_tie(cable_r, thickness)``` | A ziptie threaded around cable radius ```cable_r``` and through a panel with specified ```thickness```. |
| ```cable_tie_holes(cable_r, h = 100)``` | Holes to thread a ziptie through a panel to make a cable tie. |
| ```mouse_hole(cable, h = 100)``` | A mouse hole to allow a panel to go over a wire bundle. |
| ```mouse_hole(cable, h = 100, teardrop = false)``` | A mouse hole to allow a panel to go over a wire bundle. |
| ```ribbon_cable(ways, length)``` | Add ribbon cable to the BOM |
| ```wire(color, strands, length, strand = 0.2)``` | Add stranded wire to the BOM |
@@ -2885,7 +3041,7 @@ Just a BOM entry at the moment and cable bundle size functions for holes, plus c
| 1 | | Wire orange 7/0.2mm strands, length 90mm |
| 1 | | Wire red 7/0.2mm strands, length 90mm |
| 1 | | Wire yellow 7/0.2mm strands, length 90mm |
| 1 | ```ziptie(small_ziptie, 2.1)``` | Ziptie 100mm min length |
| 1 | ```ziptie(small_ziptie, 2.1)``` | Ziptie 2.5mm x 100mm min length |
<a href="#top">Top</a>
@@ -2921,9 +3077,9 @@ Cable zipties.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```ziptie(small_ziptie, 5)``` | Ziptie 100mm min length |
| 1 | ```ziptie(ziptie_3mm, 5)``` | Ziptie 100mm min length |
| 1 | ```ziptie(ziptie_3p6mm, 5)``` | Ziptie 100mm min length |
| 1 | ```ziptie(small_ziptie, 5)``` | Ziptie 2.5mm x 100mm min length |
| 1 | ```ziptie(ziptie_3p6mm, 5)``` | Ziptie 3.6mm x 100mm min length |
| 1 | ```ziptie(ziptie_3mm, 5)``` | Ziptie 3mm x 100mm min length |
<a href="#top">Top</a>
@@ -3047,6 +3203,10 @@ and mounted components.
A list specifies the internal dimensions, screw type, top, bottom and side sheet types and the block
maximum spacing.
* An optional name can be specified to allow more then one box in a project.
* An optional list of fixing blocks to be omitted can be given.
* Star washers can be omitted by setting the 11th parameter to false.
Uses [fixing blocks](#fixing_block) and [corner blocks](#corner_block).
@@ -3060,26 +3220,29 @@ Uses [fixing blocks](#fixing_block) and [corner blocks](#corner_block).
| ```bbox_base_sheet(type)``` | Sheet type for the base |
| ```bbox_depth(type)``` | Internal depth |
| ```bbox_height(type)``` | Internal height |
| ```bbox_name(type)``` | Optional name if there is more than one box in a project |
| ```bbox_screw(type)``` | Screw type for corner blocks |
| ```bbox_sheets(type)``` | Sheet type for the sides |
| ```bbox_skip_blocks(type)``` | List of fixing blocks to skip, used to allow a hinged panel for example |
| ```bbox_span(type)``` | Maximum span between fixing blocks |
| ```bbox_top_sheet(type)``` | Sheet type for the top |
| ```bbox_width(type)``` | Internal width |
| ```star_washers(type)``` | Set to false to remove star washers. |
### Modules
| Module | Description |
|:--- |:--- |
| ```_bbox_assembly(type, top = true, base = true, left = true, right = true, back = true, front = true)``` | The box assembly, wrap with a local copy without parameters |
| ```bbox_back(type)``` | Default back, can be overridden to customise |
| ```bbox_back_blank(type)``` | 2D template for the back |
| ```bbox_back_blank(type, sheet = false)``` | 2D template for the back |
| ```bbox_base(type)``` | Default base, can be overridden to customise |
| ```bbox_base_blank(type)``` | 2D template for the base |
| ```bbox_front(type)``` | Default front, can be overridden to customise |
| ```bbox_front_blank(type)``` | 2D template for the front |
| ```bbox_front_blank(type, sheet = false)``` | 2D template for the front |
| ```bbox_left(type)``` | Default left side, can be overridden to customise |
| ```bbox_left_blank(type)``` | 2D template for the left side |
| ```bbox_left_blank(type, sheet = false)``` | 2D template for the left side |
| ```bbox_right(type)``` | Default right side, can be overridden to customise |
| ```bbox_right_blank(type)``` | 2D template for the right side |
| ```bbox_right_blank(type, sheet = false)``` | 2D template for the right side |
| ```bbox_shelf_blank(type)``` | 2D template for a shelf |
| ```bbox_top(type)``` | Default top, can be overridden to customise |
| ```bbox_top_blank(type)``` | 2D template for the top |
@@ -3197,6 +3360,11 @@ See [butt_box](#Butt_box) for an example of usage.
Note that the block with its inserts is defined as a sub assembly, but its fasteners get added to the parent assembly.
Specific fasteners can be omitted by setting a side's thickness to 0 and the block omitted by setting ```show_block``` to false.
This allows the block and one set of fasteners to be on one assembly and the other fasteners on the mating assemblies.
Star washers can be omitted by setting ```star_washers``` to false.
[printed/corner_block.scad](printed/corner_block.scad) Implementation.
@@ -3217,10 +3385,10 @@ Note that the block with its inserts is defined as a sub assembly, but its faste
|:--- |:--- |
| ```corner_block(screw = def_screw, name = false)``` | Generate the STL for a printed corner block |
| ```corner_block_assembly(screw = def_screw, name = false)``` | The printed block with inserts |
| ```corner_block_h_holes(screw = def_screw)``` | Place children at the side screw holes |
| ```corner_block_h_holes(screw = def_screw, index = undef)``` | Place children at the side screw holes |
| ```corner_block_holes(screw = def_screw)``` | Place children at all the holes |
| ```corner_block_v_hole(screw = def_screw)``` | Place children at the bottom screw hole |
| ```fastened_corner_block_assembly(thickness, screw = def_screw, thickness_below = undef, name = false)``` | Printed block with all fasteners |
| ```fastened_corner_block_assembly(thickness, screw = def_screw, thickness_below = undef, thickness_side2 = undef, name = false, show_block = true, star_washers = true)``` | Printed block with all fasteners |
![corner_block](tests/png/corner_block.png)
@@ -3409,6 +3577,11 @@ See [butt_box](#Butt_box) for an example of usage.
Note that the block with its inserts is defined as a sub assembly, but its fasteners get added to the parent assembly.
Specific fasteners can be omitted by setting a side's thickness to 0 and the block omitted by setting ```show_block``` to false.
This allows the block and one set of fasteners to be on one assembly and the other fasteners on the mating assemblies.
Star washers can be omitted by setting ```star_washers``` to false.
[printed/fixing_block.scad](printed/fixing_block.scad) Implementation.
@@ -3428,7 +3601,7 @@ Note that the block with its inserts is defined as a sub assembly, but its faste
### Modules
| Module | Description |
|:--- |:--- |
| ```fastened_fixing_block_assembly(thickness, screw = def_screw, screw2 = undef, thickness2 = undef)``` | Assembly with fasteners in place |
| ```fastened_fixing_block_assembly(thickness, screw = def_screw, screw2 = undef, thickness2 = undef, show_block = true, star_washers = true)``` | Assembly with fasteners in place |
| ```fixing_block(screw = def_screw)``` | Generate the STL |
| ```fixing_block_assembly(screw = def_screw)``` | Printed part with the inserts inserted |
| ```fixing_block_h_hole(screw = def_screw)``` | Position children on the horizontal hole |
@@ -3475,6 +3648,76 @@ Note that the block with its inserts is defined as a sub assembly, but its faste
| 1 | fixing_block_M40_assembly |
<a href="#top">Top</a>
---
<a name="Flat_hinge"></a>
## Flat_hinge
A parametric flat hinge. A piece of filament can be used for the hinge pin.
The width, depth, thickness, number and type of screws, number of knuckles, knuckle diameter, pin diameter and clearance can all be varied.
A margin between the screws and the knuckle edge can be enforced to allow the hinge to bend all the way back to 270&deg; from closed.
Opening the test in OpenSCAD with its customiser enabled allows these parameters to be played with.
Note setting ```thickness1``` or ```thickness2``` to zero in the ```hinge_fastened_assembly()``` removes the screws from one side or the other and
setting ```show_hinge``` to false removes the hinge.
This allows the hinges and one set of screws to belong to one assembly and the other set of screws to another assembly.
[printed/flat_hinge.scad](printed/flat_hinge.scad) Implementation.
[tests/flat_hinge.scad](tests/flat_hinge.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```hinge_clearance(type)``` | Clearance between knuckles |
| ```hinge_depth(type)``` | Depth of each leaf |
| ```hinge_knuckle_dia(type)``` | The knuckle diameter |
| ```hinge_knuckles(type)``` | How many knuckles |
| ```hinge_margin(type)``` | How far to keep the screws from the knuckes |
| ```hinge_pin_dia(type)``` | The pin diameter |
| ```hinge_screw(type)``` | Screw type to mount it |
| ```hinge_screws(type)``` | How many screws |
| ```hinge_thickness(type)``` | Thickness of the leaves |
| ```hinge_width(type)``` | Width |
### Modules
| Module | Description |
|:--- |:--- |
| ```hinge_both(type)``` | Both parts together for printing |
| ```hinge_fastened_assembly(type, thickness1, thickness2, angle, show_hinge = true)``` | Assembled hinge with its fasteners |
| ```hinge_male(type, female = false)``` | The half with the stationary pin |
| ```hinge_screw_positions(type)``` | Place children at the screw positions |
![flat_hinge](tests/png/flat_hinge.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | | Hinge pin 20 x 2.85mm |
| 1 | | Hinge pin 50 x 4mm |
| 14 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 4 | ```screw(M3_dome_screw, 10)``` | Screw M3 dome x 10mm |
| 10 | ```screw(M3_dome_screw, 12)``` | Screw M3 dome x 12mm |
| 28 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
### Printed
| Qty | Filename |
| ---:|:--- |
| 1 | hinge_female_big.stl |
| 1 | hinge_female_small.stl |
| 1 | hinge_male_big.stl |
| 1 | hinge_male_small.stl |
### Assemblies
| Qty | Name |
| ---:|:--- |
| 1 | hinge_big_assembly |
| 1 | hinge_small_assembly |
<a href="#top">Top</a>
---
@@ -3508,7 +3751,7 @@ inserts don't grip well in rubber.
|:--- |:--- |
| ```fastened_insert_foot_assembly(t = 3, type = insert_foot)``` | Assembly with fasteners in place for specified sheet thickness |
| ```foot(type = foot)``` | Generate STL |
| ```foot_assembly(t = 0, type = foot)``` | Assembly with fasteners in place for specified sheet thickness |
| ```foot_assembly(t = 0, type = foot, flip = false)``` | Assembly with fasteners in place for specified sheet thickness |
| ```insert_foot(type = insert_foot)``` | Generate STL for foot with insert |
| ```insert_foot_assembly(type = insert_foot)``` | Printed part with insert in place |
@@ -3630,7 +3873,7 @@ The stl and assembly must be given a name and parameterless wrappers for the stl
| 4 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
| 4 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 4 | ```star_washer(M3_washer)``` | Washer star M3 x 0.5mm |
| 2 | ```ziptie(small_ziptie, 3)``` | Ziptie 100mm min length |
| 2 | ```ziptie(small_ziptie, 3)``` | Ziptie 2.5mm x 100mm min length |
### Printed
| Qty | Filename |
@@ -3827,7 +4070,7 @@ The stl and assembly must be given a name and parameterless wrappers for the stl
| 4 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
| 4 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 4 | ```star_washer(M3_washer)``` | Washer star M3 x 0.5mm |
| 4 | ```ziptie(small_ziptie, 3)``` | Ziptie 100mm min length |
| 4 | ```ziptie(small_ziptie, 3)``` | Ziptie 2.5mm x 100mm min length |
### Printed
| Qty | Filename |
@@ -4296,6 +4539,8 @@ heirachical BOMs are also generated for real projects.
| ```no_pose()``` | Force children not to be posed even if parent is |
| ```not_on_bom(on = false)``` | Specify the following child parts are not on the BOM, for example when they are on a PCB that comes assembled |
| ```pose(a = [55, 0, 25], t = [0, 0, 0], exploded = undef)``` | Pose an STL or assembly for rendering to png by specifying rotation ```a``` and translation ```t```, ```exploded = true for``` just the exploded view or ```false``` for unexploded only. |
| ```pose_hflip(exploded = undef)``` | Pose an STL or assembly for rendering to png by flipping around the Y axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only. |
| ```pose_vflip(exploded = undef)``` | Pose an STL or assembly for rendering to png by flipping around the X axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only. |
| ```stl(name)``` | Name an stl that will appear on the BOM, there needs to a module named ```<name>_stl``` to make it |
| ```vitamin(description)``` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "wigit(42): Type 42 widget" |
@@ -4387,6 +4632,7 @@ Global constants, functions and modules. This file is used directly or indirectl
| ```ellipse(xr, yr)``` | Draw an ellipse |
| ```extrude_if(h, center = true)``` | Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D |
| ```hflip()``` | Invert children by doing a 180&deg; flip around the Y axis |
| ```right_triangle(width, height, h, center = true)``` | A right angled triangle with the 90&deg; corner at the origin. 3D when ```h``` is nonzero, otherwise 2D |
| ```semi_circle(r, d = undef)``` | A semi circle in the positive Y domain |
| ```translate_z(z)``` | Shortcut for Z only translations |
| ```vflip()``` | Invert children by doing a 180&deg; flip around the X axis |
@@ -4423,6 +4669,7 @@ The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is
| ```poly_circle(r, sides = 0)``` | Make a circle adjusted to print the correct size |
| ```poly_cylinder(r, h, center = false, sides = 0)``` | Make a cylinder adjusted to print the correct size |
| ```poly_ring(or, ir)``` | Make a 2D ring adjusted to have the correct internal radius |
| ```poly_tube(or, ir, h, center = false)``` | Make a tube adjusted to have the correct internal radius |
| ```slot(r, l, h = 100)``` | Make a horizontal slot suitable for CNC routing, set h = 0 for 2D version |
![polyholes](tests/png/polyholes.png)
@@ -4512,6 +4759,7 @@ 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)``` | A semi teardrop in the positive Y domain |
| ```teardrop(h, r, center = true, truncate = true)``` | 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_plus(h, r, center = true, truncate = true)``` | Slightly bigger teardrop to allow for the 3D printing staircase effect |
| ```tearslot(h, r, w, center = true)``` | A horizontal slot that doesn't need support material |

View File

@@ -37,9 +37,10 @@ def read_deps(dname):
deps.append(dep)
return deps
def check_deps(target_mtime, dname):
def check_deps(target, dname):
target_mtime = mtime(target)
if not target_mtime:
return "target missing"
return target + " missing"
if not os.path.isfile(dname):
return "no deps"
deps = read_deps(dname)

View File

@@ -84,7 +84,6 @@ def make_parts(target, part_type, parts = None):
# Find all the scad files
#
lib_dir = os.environ['OPENSCADPATH'] + '/NopSCADlib/printed'
used = []
module_suffix = '_dxf' if part_type == 'svg' else '_' + part_type
for dir in [source_dir, lib_dir]:
for filename in os.listdir(dir):
@@ -113,7 +112,7 @@ def make_parts(target, part_type, parts = None):
#
part_file = target_dir + "/" + part
dname = deps_name(deps_dir, filename)
changed = check_deps(mtime(part_file), dname)
changed = check_deps(part_file, dname)
changed = times.check_have_time(changed, part)
if part_type == 'stl' and not changed and not part in bounds_map:
changed = "No bounds"
@@ -125,14 +124,9 @@ def make_parts(target, part_type, parts = None):
if part_type == 'stl':
bounds = c14n_stl.canonicalise(part_file)
bounds_map[part] = bounds
targets.remove(part)
os.remove(part_maker_name)
#
# Add the files on the BOM to the used list for plates.py
#
for line in open("openscad.log"):
if line[:7] == 'ECHO: "' and line[-6:] == '.' + part_type + '"\n':
used.append(line[7:-2])
#
# Write new bounds file
#
@@ -150,4 +144,3 @@ def make_parts(target, part_type, parts = None):
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
sys.exit(1)
times.print_times()
return used

View File

@@ -26,6 +26,7 @@ from exports import make_parts
from bom import boms
from render import render
from views import views
from plateup import plateup
if __name__ == '__main__':
target = None if len(sys.argv) == 1 else sys.argv[1]
@@ -33,4 +34,6 @@ if __name__ == '__main__':
for part in ['stl', 'dxf']:
make_parts(target, part)
render(target, part)
plateup(target, part)
views(target)

View File

@@ -24,11 +24,12 @@ from __future__ import print_function
import subprocess, sys
def run(*args):
cmd = ["openscad"] + list(args)
for arg in cmd:
print(arg, end=" ")
print()
def _run(args, silent):
cmd = ["openscad"] + args
if not silent:
for arg in cmd:
print(arg, end=" ")
print()
with open("openscad.log", "w") as log:
rc = subprocess.call(cmd, stdout = log, stderr = log)
for line in open("openscad.log", "rt"):
@@ -36,3 +37,9 @@ def run(*args):
print(line[:-1])
if rc:
sys.exit(rc)
def run(*args):
_run(list(args), False)
def run_silent(*args):
_run(list(args), True);

33
scripts/panels.py Normal file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env python
#
# 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/>.
#
#! Panelises DXF files so they can be routed together by running scad files found in the ```panels``` directory.
from __future__ import print_function
import sys
from plateup import plateup
if __name__ == '__main__':
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = None
plateup(target, 'dxf')

98
scripts/plateup.py Normal file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/env python
#
# 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/>.
#
from __future__ import print_function
import os
import openscad
import sys
import c14n_stl
from set_config import *
from deps import *
from shutil import copyfile
source_dirs = { "stl" : "platters", "dxf" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed" }
def plateup(target, part_type):
#
# Make the target directory
#
top_dir = set_config(target)
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)
#
# 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
#
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)
#
# Add the files on the BOM to the used list
#
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])
#
# 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 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)

33
scripts/platters.py Normal file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env python
#
# 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/>.
#
#! Generates build plates of STL files for efficient printing by running scad files found in the ```platters``` directory.
from __future__ import print_function
import sys
from plateup import plateup
if __name__ == '__main__':
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = None
plateup(target, 'stl')

View File

@@ -12,6 +12,8 @@ They should work with both Python 2 and Python 3.
| ```dxfs.py``` | Generates DXF files for all the routed parts listed on the BOM or a specified list. |
| ```gallery.py``` | Finds projects and adds them to the gallery. |
| ```make_all.py``` | Generates all the files for a project by running ```bom.py```, ```stls.py```, ```dxfs.py```, ```render.py``` and ```views.py```. |
| ```panels.py``` | Panelises DXF files so they can be routed together by running scad files found in the ```panels``` directory. |
| ```platters.py``` | Generates build plates of STL files for efficient printing by running scad files found in the ```platters``` directory. |
| ```render.py``` | Renders STL and DXF files to PNG for inclusion in the build instructions. |
| ```set_config.py``` | Sets the target configuration for multi-target projects that have variable configurations. |
| ```stls.py``` | Generates STL files for all the printed parts listed on the BOM or a specified list. |

View File

@@ -107,7 +107,7 @@ def tests(tests):
#
# List of individual part files
#
scads = [i for i in os.listdir(scad_dir) if i[-5:] == ".scad"]
scads = [i for i in sorted(os.listdir(scad_dir)) if i[-5:] == ".scad"]
for scad in scads:
base_name = scad[:-5]
@@ -138,7 +138,7 @@ def tests(tests):
print("Can't find implementation!")
continue
vsplit = "N"
vsplit = "M"
vtype = locations[0][1]
types = [vtype + ' A-' + vsplit[0], vtype + ' ' + chr(ord(vsplit) + 1) + '-Z'] + [loc[1] for loc in locations[1 :]]
if type == vtype:
@@ -187,7 +187,7 @@ def tests(tests):
body += ["![%s](%s)\n" %(base_name, png_name)]
dname = deps_name(deps_dir, scad)
oldest = min(mtime(png_name), mtime(bom_name))
oldest = png_name if mtime(png_name) < mtime(bom_name) else bom_name
changed = check_deps(oldest, dname)
changed = times.check_have_time(changed, scad_name)
if changed:
@@ -257,7 +257,7 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
print('<tr>', file = doc_file, end = '')
for type in types:
if i < len(index[type]):
name = index[type][i]
name = sorted(index[type])[i]
print('<td> <a href = "#' + name + '">' + name + '</a> </td>', file = doc_file, end = '')
else:
print('<td></td>', file = doc_file, end = '')

View File

@@ -154,14 +154,14 @@ def views(target, do_assemblies = None):
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
#
# Run openscad on the created file
# Run openscad on th created file
#
dname = deps_name(deps_dir, filename)
for explode in [0, 1]:
png_name = target_dir + '/' + module + '.png'
if not explode:
png_name = png_name.replace('_assembly', '_assembled')
changed = check_deps(mtime(png_name), dname)
changed = check_deps(png_name, dname)
changed = times.check_have_time(changed, png_name)
tmp_name = 'tmp.png'
if changed:
@@ -219,36 +219,49 @@ def views(target, do_assemblies = None):
# Global BOM
#
print('<a name="Parts_list"></a>\n## Parts list', file = doc_file)
vitamins = {}
printed = {}
routed = {}
types = ["vitamins", "printed", "routed"]
headings = {"vitamins" : "vitamins", "printed" : "3D printed parts", "routed" : "CNC routed parts"}
things = {}
for t in types:
things[t] = {}
for ass in flat_bom:
for v in ass["vitamins"]:
if v in vitamins:
vitamins[v] += ass["vitamins"][v]
else:
vitamins[v] = ass["vitamins"][v]
for p in ass["printed"]:
if p in printed:
printed[p] += ass["printed"][p]
else:
printed[p] = ass["printed"][p]
for t in types:
for thing in ass[t]:
if thing in things[t]:
things[t][thing] += ass[t][thing]
else:
things[t][thing] = ass[t][thing]
for ass in flat_bom:
name = ass["name"][:-9].replace('_', ' ').title().replace(' ','&nbsp;')
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">%s</span> ' % name, file = doc_file, end = '')
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |', file = doc_file)
print(('|--:' * len(flat_bom) + '|--:|:--|'), file = doc_file)
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
for ass in flat_bom:
count = ass["vitamins"][v] if v in ass["vitamins"] else '.'
print('| %s ' % pad(count, 2, 1), file = doc_file, end = '')
print('| %s | %s |' % (pad(vitamins[v], 2, 1), pad(v.split(":")[1], 2)), file = doc_file)
print(('| ' * len(flat_bom) + '| | **3D Printed parts** |'), file = doc_file)
for p in sorted(printed):
for ass in flat_bom:
count = ass["printed"][p] if p in ass["printed"] else '.'
print('| %s ' % pad(count, 2, 1), file = doc_file, end = '')
print('| %s | %s |' % (pad(printed[p], 2, 1), pad(p, 3)), file = doc_file)
for t in types:
if things[t]:
totals = {}
heading = headings[t][0:1].upper() + headings[t][1:]
print(('| ' * len(flat_bom) + '| | **%s** |') % heading, file = doc_file)
for thing in sorted(things[t], key = lambda s: s.split(":")[-1]):
for ass in flat_bom:
count = ass[t][thing] if thing in ass[t] else 0
print('| %s ' % pad(count if count else '.', 2, 1), file = doc_file, end = '')
name = ass["name"]
if name in totals:
totals[name] += count
else:
totals[name] = count
print('| %s | %s |' % (pad(things[t][thing], 2, 1), pad(thing.split(":")[-1], 2)), file = doc_file)
grand_total = 0
for ass in flat_bom:
name = ass["name"]
total = totals[name] if name in totals else 0
print('| %s ' % pad(total if total else '.', 2, 1), file = doc_file, end = '')
grand_total += total
print("| %s | %s |" % (pad(grand_total, 2, 1), pad('Total %s count' % headings[t], 2)), file = doc_file)
print(file = doc_file)
eop(print_mode, doc_file)
#
@@ -267,7 +280,7 @@ def views(target, do_assemblies = None):
print("### Vitamins", file = doc_file)
print("|Qty|Description|", file = doc_file)
print("|--:|:----------|", file = doc_file)
for v in vitamins:
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
print("|%d|%s|" % (vitamins[v], v.split(":")[1]), file = doc_file)
print("\n", file = doc_file)

View File

@@ -20,7 +20,8 @@ include <../global_defs.scad>
use <../utils/fillet.scad>
module fillets() {
fillet(3, 25);
rotate(180)
fillet(3, 10);
}
fillets();

48
tests/flat_hinge.scad Normal file
View File

@@ -0,0 +1,48 @@
//
// 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/screws.scad>
use <../utils/layout.scad>
use <../printed/flat_hinge.scad>
width = 50; // [20 : 100]
depth = 20; // [8 : 50]
thickness = 4; //[1 : 10]
screws = 5; // [1 : 20]
knuckles = 5; // [3 : 10]
pin_diameter = 4; // [1: 10]
knuckle_diameter = 9; //[4 : 15]
margin = 0; // [0 : 10]
clearance = 0.2;
angle = 0; // [-90 : 180]
big_hinge = ["big", width, depth, thickness, pin_diameter, knuckle_diameter, knuckles, M3_dome_screw, screws, clearance, margin];
small_hinge = ["small", 20, 16, 2, 2.85, 7, 3, M3_dome_screw, 2, 0.2, 0];
hinges = [small_hinge, big_hinge];
module flat_hinges()
layout([for(h = hinges) hinge_width(h)], 10)
if($preview)
hinge_fastened_assembly(hinges[$i], 3, 3, angle);
else
hinge_male(hinges[$i]);
flat_hinges();

View File

@@ -0,0 +1,27 @@
//
// NopSCADlib Copyright Chris Palmer 2019
// 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 <../vitamins/geared_steppers.scad>
use <../utils/layout.scad>
module geared_steppers()
layout([for(g = geared_steppers) gs_diameter(g)], 5)
geared_stepper(geared_steppers[$i]);
geared_steppers();

View File

@@ -25,6 +25,9 @@ module globals() {
translate([30, 0])
ellipse(15, 7);
translate([50, 0])
right_triangle(10, 20, 0);
}
}

View File

@@ -21,10 +21,20 @@ use <../utils/layout.scad>
include <../vitamins/inserts.scad>
module inserts()
module inserts() {
for(i = [0: len(inserts) -1])
translate([10 * i, 0])
insert(inserts[i]);
color(pp1_colour)
translate([len(inserts) * 10, 0]) {
insert_lug(inserts[0], 2, 1);
translate([10, 0])
insert_boss(inserts[0], z = 10, wall = 2);
}
}
if($preview)
inserts();

27
tests/ldrs.scad Normal file
View File

@@ -0,0 +1,27 @@
//
// 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 <../vitamins/ldrs.scad>
use <../utils/layout.scad>
module ldrs()
layout([for(l = ldrs) ldr_diameter(l)], 5)
LDR(ldrs[$i]);
ldrs();

View File

@@ -23,7 +23,7 @@ include <../vitamins/d_connectors.scad>
include <../vitamins/pcbs.scad>
module pcbs()
layout([for(p = pcbs) pcb_width(p)], 15)
layout([for(p = pcbs) pcb_width(p)], 10)
translate([0, pcb_length(pcbs[$i]) / 2])
rotate(90)
pcb_assembly(pcbs[$i], 5 + $i, 3);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 19 KiB

BIN
tests/png/flat_hinge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 78 KiB

BIN
tests/png/ldrs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

@@ -52,8 +52,8 @@ module polyholes() {
sizes = [1.5, 2, 3, 4];
for(i = [0 : len(sizes) - 1])
translate([i * 10, -10]) {
color(pp1_colour) linear_extrude(height = 1)
poly_ring(ir = ir, or = cir + sizes[i] * extrusion_width);
color(pp1_colour)
poly_tube(ir = ir, or = cir + sizes[i] * extrusion_width, h = 1);
rod(2 * ir, 3);
}

View File

@@ -24,8 +24,13 @@ include <../vitamins/linear_bearings.scad>
use <../vitamins/rod.scad>
module rods()
layout([for(b = linear_bearings) 2 * bearing_radius(b)])
layout([for(b = linear_bearings) 2 * bearing_radius(b)]) {
rod(bearing_rod_dia(linear_bearings[$i]), 80);
translate([0, 20])
studding(bearing_rod_dia(linear_bearings[$i]), 80);
}
if($preview)
rods();

View File

@@ -36,7 +36,10 @@ module teardrops() {
tearslot(h = 0, r = 3, w = 10);
translate([30, 15])
vertical_tearslot(h = 0, r =3, l = 10);
vertical_tearslot(h = 0, r =3, l = 10);
translate([20, 10])
semi_teardrop(h = 0, r = 3);
}
}

View File

@@ -61,7 +61,7 @@ module wires() {
translate([-w / 2, 0])
square([w, h]);
mouse_hole(bundle, 0);
mouse_hole(bundle, 0, true);
}
translate_z(-thickness)

View File

@@ -63,6 +63,22 @@ module pose(a = [55, 0, 25], t = [0, 0, 0], exploded = undef) //! Pose an
translate(-t)
children();
module pose_hflip(exploded = undef) //! Pose an STL or assembly for rendering to png by flipping around the Y axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only.
if(is_undef($pose) || !is_undef($posed) || (!is_undef(exploded) && exploded != !!exploded()))
children();
else
let($posed = true) // only pose the top level
hflip()
children();
module pose_vflip(exploded = undef) //! Pose an STL or assembly for rendering to png by flipping around the X axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only.
if(is_undef($pose) || !is_undef($posed) || (!is_undef(exploded) && exploded != !!exploded()))
children();
else
let($posed = true) // only pose the top level
vflip()
children();
module assembly(name) { //! Name an assembly that will appear on the BOM, there needs to a module named ```<name>_assembly``` to make it
if(bom_mode())

View File

@@ -63,6 +63,10 @@ module semi_circle(r, d = undef) //! A semi circle in the pos
square([2 * sq, sq]);
}
module right_triangle(width, height, h, center = true) //! A right angled triangle with the 90&deg; corner at the origin. 3D when ```h``` is nonzero, otherwise 2D
extrude_if(h, center = center)
polygon(points = [[0,0], [width, 0], [0, height]]);
include <sphere.scad>
include <bom.scad>
include <polyholes.scad>

View File

@@ -62,6 +62,10 @@ module poly_ring(or, ir) { //! Make a 2D ring adjusted to have the correct inter
}
}
module poly_tube(or, ir, h, center = false) //! Make a tube adjusted to have the correct internal radius
extrude_if(h, center)
poly_ring(or, ir);
module drill(r, h = 100) //! Make a cylinder for drilling holes suitable for CNC routing, set h = 0 for circle
extrude_if(h)
circle(r = corrected_radius(r, r2sides(r)));

View File

@@ -34,6 +34,18 @@ module teardrop(h, r, center = true, truncate = true) //! For making horizontal
polygon([[0, 0], [eps, 0], [0, r * sqrt(2)]]);
}
module semi_teardrop(h, r, d = undef, center = true) //! A semi teardrop in the positive Y domain
render(convexity = 5)
extrude_if(h, center)
intersection() {
R = is_undef(d) ? r : d / 2;
teardrop(r = R, h = 0);
sq = R + 1;
translate([-sq, 0])
square([2 * sq, sq]);
}
module teardrop_plus(h, r, center = true, truncate = true) //! Slightly bigger teardrop to allow for the 3D printing staircase effect
teardrop(h, r + layer_height / 4, center, truncate);

View File

@@ -28,5 +28,6 @@ module fillet(r, h, center = false) //! Fillet with specified radius and height
translate([-eps, -eps, 0])
square(r + eps);
circle(r + eps);
translate([r, r])
circle(r + eps);
}

View File

@@ -21,6 +21,8 @@
//! Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
//! Only models 2D paths, so not 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.
//!
//! By default the path is a closed loop but a gap length and position can be specified to make open loops.
//!
//! Individual teeth are not drawn, instead they are represented by a lighter colour.

View File

@@ -151,16 +151,16 @@ function nut_and_washer_thickness(screw, nyloc) = washer_thickness(screw_washer(
function fan_screw_depth(type) = fan_boss_d(type) ? fan_depth(type) : fan_thickness(type);
function fan_screw_length(type, thickness) = screw_longer_than(thickness + fan_screw_depth(type) + nut_and_washer_thickness(fan_screw(type), true)); //! Screw length required
module fan_assembly(type, thickness, include_fan = true) { //! Fan with its fasteners
module fan_assembly(type, thickness, include_fan = true, screw = false) { //! Fan with its fasteners
translate_z(-fan_depth(type) / 2) {
if(include_fan)
fan(type);
screw = fan_screw(type);
nut = screw_nut(screw);
Screw = screw ? screw : fan_screw(type);
nut = screw_nut(Screw);
fan_hole_positions(type) {
translate_z(thickness)
screw_and_washer(screw, fan_screw_length(type, thickness));
screw_and_washer(Screw, fan_screw_length(type, thickness));
translate_z(include_fan ? -fan_screw_depth(type) : 0)
vflip()

View File

@@ -0,0 +1,114 @@
//
// NopSCADlib Copyright Chris Palmer 2019
// 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/>.
//
//
//! Geared tin can steppers
//
include <../core.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/round.scad>
function gs_diameter(type) = type[2]; //! Can diameter
function gs_height(type) = type[3]; //! Can height
function gs_pitch(type) = type[4]; //! Screw pitch
function gs_lug_w(type) = type[5]; //! Screw lug width
function gs_lug_t(type) = type[6]; //! Screw lug thickness
function gs_hole_d(type) = type[7]; //! Screw hole diameter
function gs_offset(type) = type[8]; //! Offset of the shaft from the centre of the can
function gs_boss_d(type) = type[9]; //! Boss around the shaft diameter
function gs_boss_h(type) = type[10]; //! Boss around the shaft height
function gs_shaft_d(type) = type[11]; //! Shaft diameter
function gs_shaft_flat(type) = type[12]; //! Shaft width across the flats
function gs_shaft_length(type) = type[13]; //! Shaft length
function gs_flat_length(type) = type[14]; //! Shaft flat length
function gs_bulge_w(type) = type[15]; //! Plastic bulge width
function gs_bulge_d(type) = type[16]; //! Plastic bulge depth from centre
function gs_bulge_h(type) = type[17]; //! Plastic bulge height
function gs_bulge2_w(type) = type[18]; //! Plastic rear bulge width
function gs_bulge2_d(type) = type[19]; //! Plastic rear bulge depth from centre
function gs_bulge2_h(type) = type[20]; //! Plastic rear bulge height
module geared_stepper_screw_positions(type) //! Place children at the screw positions
for(side = [-1, 1])
translate([side * gs_pitch(type) / 2, -gs_offset(type)])
children();
module geared_stepper(type) { //! Draw the specified geared stepper
vitamin(str("geared_stepper(", type[0], "): Geared stepper - ", type[1]));
radius = gs_diameter(type) / 2;
height = gs_height(type);
offset = gs_offset(type);
color("silver") {
translate([0, -offset])
rounded_cylinder(r = radius, h = height, r2 = 1);
cylinder(d = gs_boss_d(type), h = 2 * gs_boss_h(type), center = true);
linear_extrude(height = gs_lug_t(type))
difference() {
hull()
geared_stepper_screw_positions(type)
circle(d = gs_lug_w(type));
geared_stepper_screw_positions(type)
circle(d = gs_hole_d(type));
}
translate([0, -offset - radius, eps])
cube([gs_bulge_w(type) - 2, 2 * (gs_bulge_d(type) - radius) - 2, 2 * eps], center = true);
}
vflip()
color(brass) {
d = gs_shaft_d(type);
h = gs_shaft_length(type);
linear_extrude(height = h)
intersection() {
circle(d = d);
square([d + 1, gs_shaft_flat(type)], center = true);
}
cylinder(d = d, h = h - gs_flat_length(type));
}
color("skyblue") {
h1 = gs_bulge_h(type);
translate([0, - offset - radius, eps])
rounded_rectangle([gs_bulge_w(type), 2 * (gs_bulge_d(type) - radius), h1], 0.5, center = false);
h2 = gs_bulge2_h(type);
translate([0, - offset, h1 + 1 - h2])
linear_extrude(height = h2)
round(0.5)
intersection() {
circle(gs_bulge2_d(type));
translate([0, -50])
square([gs_bulge2_w(type), 100], center = true);
}
}
translate_z(2.5)
for(i = [0 : 4])
translate([i - 2.5, 0])
rotate([90, 0, 0])
color(["yellow", "orange", "red", "pink", "blue"][i])
cylinder(d = 1, h = radius + offset + 10);
}

View File

@@ -0,0 +1,27 @@
//
// NopSCADlib Copyright Chris Palmer 2019
// 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/>.
//
//
//! Geared tin can steppers
//
28BYJ_48 = ["28BYJ_48", "28BYJ-48 5V", 28, 19, 35, 7, 0.85, 4.2, 8, 9, 1.5, 5, 3, 10, 6, 14.7, 17, 16.5, 17.7, 15.5, 13.8 ];
geared_steppers = [28BYJ_48];
use <geared_stepper.scad>

View File

@@ -21,6 +21,7 @@
//! Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering iron with a conical bit set to 200&deg;C.
//
include <../core.scad>
use <../utils/quadrant.scad>
function insert_length(type) = type[1]; //! Length
function insert_outer_d(type) = type[2]; //! Outer diameter at the top
@@ -93,15 +94,75 @@ module insert_hole(type, counterbore = 0, horizontal = false) { //! Make a hole
}
}
module insert_boss(type, z, wall = 2 * extrusion_width) { //! Make a boss to take an insert
render(convexity = 3)
difference() {
ir = insert_hole_radius(type);
linear_extrude(height = z)
hull()
poly_ring(corrected_radius(ir) + wall, ir);
function insert_boss_radius(type, wall) = corrected_radius(insert_hole_radius(type)) + wall; //! Compute the outer radius of an insert boss
translate_z(z)
insert_hole(type, max(0, z - insert_hole_length(type) - 2 * layer_height));
module insert_boss(type, z, wall = 2 * extrusion_width) { //! Make a boss to take an insert
ir = insert_hole_radius(type);
or = corrected_radius(ir) + wall;
module shape()
hull()
poly_ring(or, ir);
linear_extrude(height = z)
poly_ring(or, ir);
linear_extrude(height = z - insert_hole_length(type))
difference() {
shape();
poly_circle(insert_screw_diameter(type) / 2 + 0.1);
}
if(z > insert_hole_length(type) + 2 * layer_height)
linear_extrude(height = 2 * layer_height) // cap the end if room
shape();
}
module insert_lug(insert, wall, counter_bore = 0, extension = 0, corner_r = 0, flying = true) { //! Make a flying insert lug, see [ssr_shroud](#Ssr_shroud)
boss_r = insert_boss_radius(insert, wall);
boss_h = insert_hole_length(insert);
boss_h2 = boss_h + counter_bore;
module shape()
intersection() {
hull() {
circle(boss_r);
translate([boss_r + extension - eps, 0])
square([eps, 2 * boss_r], center = true);
}
if(corner_r)
translate([boss_r + extension - corner_r, 0])
rotate(-45)
quadrant(w = 100, r = corner_r - eps, center = true);
}
translate_z(-boss_h)
linear_extrude(height = boss_h)
difference() {
shape();
poly_circle(insert_hole_radius(insert));
}
// insert boss counter_bore
translate_z(-boss_h2) {
linear_extrude(height = counter_bore + eps)
difference() {
shape();
poly_circle(insert_screw_diameter(insert) / 2 + 0.1);
}
// support cone
if(flying)
hull() {
linear_extrude(height = eps)
shape();
translate([boss_r + extension - wall - eps, 0, - (2 * boss_r + extension - wall)])
cube(eps, center = true);
}
}
}

105
vitamins/ldr.scad Normal file
View File

@@ -0,0 +1,105 @@
//
// 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/>.
//
//
//! Light dependent resistors.
//!
//! Larger ones seem to have both a higher dark resistance and a lower bright light resistance.
//
include <../core.scad>
function ldr_description(type) = type[1]; //! Description
function ldr_diameter(type) = type[2]; //! The diameter of the round bit
function ldr_width(type) = type[3]; //! Across the flats
function ldr_thickness(type) = type[4]; //! Thickness
function ldr_pitch(type) = type[5]; //! Pitch between the leads
function ldr_active(type) = type[6]; //! The active width
function ldr_lead_d(type) = type[7]; //! The lead diameter
module LDR(type, lead_length = 3) { //! Draw an LDR, can specify the lead length
vitamin(str("ldr(", type[0], "): Light dependent resistor - ", ldr_description(type)));
module shape()
intersection() {
circle(d = ldr_diameter(type));
square([100, ldr_width(type)], center = true);
}
function serpentine_t() = let(w = ldr_width(type), n = floor(w / 0.5) + 0.5) w / (n * 2);
module serpentine() {
w = ldr_width(type);
t = serpentine_t();
pitch = 2 * t;
l = ldr_active(type);
lines = ceil(w / pitch);
for(i = [0 : lines - 1])
translate([0, i * pitch - w / 2 + t / 2]) {
square([l - 3 * t, t], center = true);
end = i % 2 ? 1 : -1;
$fn = 16;
translate([end * (l / 2 - 1.5 * t), t])
rotate(-end * 90)
difference() {
semi_circle(1.5 * t);
semi_circle(t / 2);
}
}
}
t = ldr_thickness(type);
color("white")
linear_extrude(height = t - 0.4)
shape();
color("orange")
translate_z(t - 0.4)
linear_extrude(height = 0.1)
shape();
color([0.9, 0.9, 0.9])
translate_z(t - 0.3)
linear_extrude(height = 0.1)
difference() {
offset(-serpentine_t())
shape();
serpentine();
}
color("silver")
for(side = [-1, 1])
translate([side * ldr_pitch(type) / 2, 0]) {
translate_z(-lead_length)
cylinder(d = ldr_lead_d(type), h = lead_length, $fn = 16);
translate_z(t - 0.3)
cylinder(d = 1.5 * ldr_lead_d(type), h = 0.2, $fn = 16);
}
color([1, 1, 1, 0.25])
translate_z(t - 0.3 + eps)
linear_extrude(height = 0.3)
shape();
}

28
vitamins/ldrs.scad Normal file
View File

@@ -0,0 +1,28 @@
//
// 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/>.
//
//
// Light dependent resistors.
//
small_ldr = ["small_ldr", "small", 5, 4.2, 2.0, 3.2, 2.5, 0.4];
large_ldr = ["large_ldr", "large", 9.2, 7.9, 2.0, 6.8, 4.5, 0.5];
ldrs = [small_ldr, large_ldr];
use <ldr.scad>

View File

@@ -43,14 +43,14 @@ module microview(cutout = false) { //! Draw microview or generate a panel cutou
translate_z(8.35) {
color("black")
import("microview/GKM-002_R05_CHIP_UPPER_HOUSING-1.stl", convexity = 2);
import("microview/GKM-002_R05_CHIP_UPPER_HOUSING-1.STL", convexity = 2);
translate([-2, 0, 0])
color("dimgray")
cube([12.5, 15.5, 4.41], center = true);
}
color("dimgray")
import("microview/GKM-003_R05_CHIP_LOWER_HOUSING.stl", convexity = 2);
import("microview/GKM-003_R05_CHIP_LOWER_HOUSING.STL", convexity = 2);
for(side = [-1, 1], i = [0 : 7])
translate([side * inch(0.35), (i - 3.5) * inch(0.1)])

View File

@@ -58,7 +58,7 @@ module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specifi
rounded_cylinder(r = outer_rad * cos(30) , h = nyloc_thickness, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
}
if($children)
translate_z(thickness)
translate_z(nut_thickness(type, nyloc))
children();
}

View File

@@ -667,6 +667,22 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
}
}
module pcb_component_position(type, name) { //! Position child at the specified component position
for(comp = pcb_components(type)) {
p = pcb_coord(type, [comp.x, comp.y]);
if(comp[3][0] == "-") {
if(comp[3] == str("-", name))
translate([p.x, p.y])
vflip()
children();
}
else
if(comp[3] == name)
translate([p.x, p.y, pcb_thickness(type)])
children();
}
}
module pcb_components(type, cutouts = false, angle = undef) { //! Draw list of PCB components on the PCB
not_on_bom(pcb_parts_on_bom(type))
for(comp = pcb_components(type)) {
@@ -750,14 +766,19 @@ module pcb(type) { //! Draw specified PCB
}
}
module pcb_spacer(screw, height, wall = 1.8) { //! Generate STL for PCB spacer
stl(str("pcb_spacer", round(screw_radius(screw) * 20), round(height * 10)));
module pcb_spacer(screw, height, wall = 1.8, taper = 0) { //! Generate STL for PCB spacer
stl(str("pcb_spacer", round(screw_radius(screw) * 20), round(height * 10), taper ? str("_", taper) : ""));
ir = screw_clearance_radius(screw);
or = corrected_radius(ir) + wall;
linear_extrude(height = height)
poly_ring(or, ir);
if(height > taper)
linear_extrude(height = height - taper)
poly_ring(or, ir);
if(taper)
linear_extrude(height = height)
poly_ring(ir + 2 * extrusion_width, ir);
}
module pcb_base(type, height, thickness, wall = 2) { //! Generate STL for a base with PCB spacers
@@ -798,12 +819,8 @@ module pcb_assembly(type, height, thickness) { //! Draw PCB assembly with spaces
screw(screw, screw_length);
color(pp1_colour)
if(taper) {
h2 = max(0, height - 2);
if(h2)
pcb_spacer(screw, h2);
pcb_spacer(screw, height, 2 * extrusion_width); // Thin as can be at the top because there is no clearance around the holes.
}
if(taper)
pcb_spacer(screw, height, taper = 2);
else
pcb_spacer(screw, height);

View File

@@ -237,6 +237,32 @@ ArduinoUno3 = ["ArduinoUno3", "Arduino Uno R3", 68.58, 53.34, 1.6, 0, 3.3, 0, "#
M2p5_pan_screw
];
ArduinoLeonardo = ["ArduinoLeonardo", "Arduino Leonardo", 68.58, 53.34, 1.6, 0, 3.3, 0, "#2140BE", false, [[15.24, 50.8],[66.04, 35.56],[66.04, 7.62],[13.97, 2.54]],
[[30.226, -2.54, 0, "2p54socket", 10, 1],
[54.61, -2.54, 0, "2p54socket", 8, 1],
[36.83, 2.54, 0, "2p54socket", 8, 1],
[57.15, 2.54, 0, "2p54socket", 6, 1],
[64.91, 27.89, 0, "2p54header", 2, 3],
[ 6.5, -3.5, 0, "button_6mm"],
[4.7625, 7.62, 180, "barrel_jack"],
[1.5875, 38.1, 180,"usb_uA"],
],
[],[],
inch([
[-1.35, -1.05],
[-1.35, 1.05],
[ 1.19, 1.05],
[ 1.25, 0.99],
[ 1.25, 0.54],
[ 1.35, 0.44],
[ 1.35, -0.85],
[ 1.25, -0.95],
[ 1.25, -1.05],
]),
M2p5_pan_screw
];
Keyes5p1 = ["Keyes5p1", "Keyes5.1 Arduino Uno expansion board", 68.58, 53.34, 1.6, 0, 3.3, 0, "#2140BE", false, [[15.24, 50.8],[66.04, 35.56],[66.04, 7.62],[13.97, 2.54]],
[[30.226, -2.54, 0, "-2p54header", 10, 1],
[54.61, -2.54, 0, "-2p54header", 8, 1],
@@ -275,6 +301,10 @@ PI_IO = ["PI_IO", "PI_IO V2", 35.56, 25.4, 1.6, 0, 0, 0, "green", tru
[(3.4 - 2.7) * 25.4, (4.5 - 4.15) * 25.4, 0, "2p54socket", 13, 2, true],
], []];
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] ],
[], [], [], [], M2p5_pan_screw];
PERF80x20 = ["PERF80x20", "Perfboard 80 x 20mm", 80, 20, 1.6, 0, 2.3, 0, "green", true, [[2,2],[-2,2],[2,-2],[-2,-2]], [], [], [5.87, 3.49]];
PERF70x50 = ["PERF70x50", "Perfboard 70 x 50mm", 70, 50, 1.6, 0, 2.3, 0, "green", true, [[2,2],[-2,2],[2,-2],[-2,-2]], [], [], [5.87, 3.49]];
@@ -287,6 +317,6 @@ PERF74x51 = ["PERF74x51", "Perfboard 74 x 51mm", 74, 51, 1.0, 0, 3.0, 0, "sienna
PSU12V1A = ["PSU12V1A", "PSU 12V 1A", 67, 31, 1.7, 0, 3.9, 0, "green", true, [[3.5, 3.5], [-3.5, 3.5], [-3.5, -3.5], [3.5, -3.5]], [], []];
pcbs = [ExtruderPCB, PI_IO, RPI3, ArduinoUno3, Keyes5p1, PERF80x20, PERF70x50, PERF70x30, PERF60x40, PERF74x51, PSU12V1A, DuetE, Duex2, Duex5, Melzi];
pcbs = [ExtruderPCB, PI_IO, RPI3, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PERF80x20, PERF70x50, PERF70x30, PERF60x40, PERF74x51, PSU12V1A, DuetE, Duex2, Duex5, Melzi, ZC_A0591];
use <pcb.scad>

View File

@@ -80,7 +80,7 @@ module box_header(type, cols = 1, rows = 1, smt = false, cutout = false) { //! D
if(cutout)
dogbone_rectangle([cols * pitch + 2 * panel_clearance, rows * pitch + 2 * panel_clearance, 100], center = false);
else
vitamin(str("box_header(", type[0], cols, rows, arg(smt, false, "smt"), "): Pin header ", cols, " x ", rows));
vitamin(str("box_header(", type[0], cols, rows, arg(smt, false, "smt"), "): Box header ", cols, " x ", rows));
translate_z(smt ? 3.5 - h : 0) {
for(x = [0 : cols - 1], y = [0 : rows - 1])

View File

@@ -20,15 +20,16 @@
//
// Ring terminals
//
// o i l w h t s
// d d e i o h c
// n d l i r
// g t e c e
// t h k w
// h
// o i l w h t s
// d d e i o h c
// n d l i r
// g t e c e
// t h k w
// h
//
M3_ringterm = ["M3_ringterm", 6, 3, 12, 3, 1.5, 0.2, M3_dome_screw];
M3_ringterm = ["M3_ringterm", 6, 3, 12, 3, 1.5, 0.2, M3_dome_screw];
M3_ringterm_cs = ["M3_ringterm_cs", 6, 3, 12, 3, 1.5, 0.2, M3_cap_screw];
ring_terminals = [M3_ringterm];
ring_terminals = [M3_ringterm, M3_ringterm_cs];
use <ring_terminal.scad>

View File

@@ -18,13 +18,14 @@
//
//
//! Steel rods, with optional chamfer.
//! Steel rods and studding with chamfered ends.
//
include <../core.scad>
rod_colour = grey80;
studding_colour = grey70;
module rod(d , l) {
module rod(d , l) { //! Draw a smooth rod with specified length and diameter
vitamin(str("rod(", d, ", ", l, "): Smooth rod ", d, "mm x ", l, "mm"));
chamfer = d / 10;
@@ -35,3 +36,15 @@ module rod(d , l) {
cylinder(d = d - 2 * chamfer, h = l, center = true);
}
}
module studding(d , l) { //! Draw a threaded rod with specified length and diameter
vitamin(str("studding(", d, ", ", l,"): Threaded rod M", d, " x ", l, "mm"));
chamfer = d / 20;
color(studding_colour)
hull() {
cylinder(d = d, h = l - 2 * chamfer, center = true);
cylinder(d = d - 2 * chamfer, h = l, center = true);
}
}

View File

@@ -74,7 +74,7 @@ module sheet_2D(type, w, d, corners = [0, 0, 0, 0]) { //! 2D sheet template with
}
}
module sheet(type, w, d, corners = [0, 0, 0, 0]) //! Draw speified sheet
module sheet(type, w, d, corners = [0, 0, 0, 0]) //! Draw specified sheet
linear_extrude(height = sheet_thickness(type), center = true)
sheet_2D(type, w, d, corners);

View File

@@ -31,6 +31,7 @@ MDF10 = [ "MDF10", "Sheet MDF", 10, mdf_colour,
MDF12 = [ "MDF12", "Sheet MDF", 12, mdf_colour, true]; // ~1/2"
MDF18 = [ "MDF18", "Sheet MDF", 18, mdf_colour, true];
MDF19 = [ "MDF19", "Sheet MDF", 19, mdf_colour, true]; // ~3/4"
PMMA2 = [ "PMMA2", "Sheet acrylic", 2, [1, 1, 1, 0.5 ], false];
PMMA3 = [ "PMMA3", "Sheet acrylic", 3, [1, 1, 1, 0.5 ], false]; // ~1/8"
PMMA6 = [ "PMMA6", "Sheet acrylic", 6, [1, 1, 1, 0.5 ], false]; // ~1/4"
PMMA8 = [ "PMMA8", "Sheet acrylic", 8, [1, 1, 1, 0.5 ], false]; // ~5/16"
@@ -45,6 +46,6 @@ AL6 = [ "AL6", "Aluminium tooling plate", 6, [0.9, 0.9, 0.9, 1 ],
AL8 = [ "AL8", "Aluminium tooling plate", 8, [0.9, 0.9, 0.9, 1 ], false];
Steel06 = [ "Steel06", "Sheet mild steel", 0.6,"silver" , false];
sheets = [MDF6, MDF10, MDF12, MDF19, PMMA3, PMMA6, PMMA8, PMMA10, glass2, DiBond, DiBond6, Cardboard, FoilTape, Foam20, AL6, AL8, Steel06];
sheets = [MDF6, MDF10, MDF12, MDF19, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10, glass2, DiBond, DiBond6, Cardboard, FoilTape, Foam20, AL6, AL8, Steel06];
use <sheet.scad>

View File

@@ -30,6 +30,7 @@ function spool_hub_bore(type) = type[6]; //! Bore through the hub
function spool_hub_diameter(type) = type[7]; //! Diameter of the thicker hub
function spool_hub_taper(type) = type[8]; //! Diameter at which it tapers down to rim thickness
function spool_height(type) = spool_width(type) + 2 * spool_hub_thickness(type); //! Outside width
function spool_pitch(type) = spool_width(type) + spool_rim_thickness(type); //! Spacing of the rims
module spool(type) { //! Draw specified spool
vitamin(str("spool(", type[0], "): Filament spool ", spool_diameter(type), " x ", spool_width(type)));

View File

@@ -23,10 +23,11 @@
// i i e i u o u u
// a d p m b r b b
// t t e
// h h t t d t
// h h t t d taper_d
spool_300x88 = ["spool_300x88", 300, 88, 43, 6, 8, 52, 214, 300];
spool_300x85 = ["spool_300x85", 300, 85, 60, 4, 8, 52, 250, 280];
spool_200x55 = ["spool_200x55", 200, 55, 40, 5, 5, 52, 200, 200];
spools = [spool_200x55, spool_300x85];
spools = [spool_200x55, spool_300x85, spool_300x88];
use <spool.scad>

View File

@@ -33,7 +33,7 @@ MS332F_pin = [4.0 , 1.0, 1.0, 4.7, 4.83];
// w l d t i c od id thread pv a tl pd pw
CK7101 = ["CK7101", "CK7101", 6.86, 12.7, 8.89, 0.4, 1.7, "red", 6.1, 4, 8.89, 0, 0, 4.45, 25/2, 10.67, 2.92, 0, toggle_nut, toggle_washer, 3, CK7000_tag];
CK7105 = ["CK7105", "CK7101", 6.86, 12.7, 8.89, 0.4, 1.7, "red", 6.1, 4, 8.89, 0, 0, 4.45,-25/2, 21.33, 5.08, 2.54,toggle_nut, toggle_washer, 3, CK7000_pin];
CK7105 = ["CK7105", "CK7105", 6.86, 12.7, 8.89, 0.4, 1.7, "red", 6.1, 4, 8.89, 0, 0, 4.45,-25/2, 21.33, 5.08, 2.54,toggle_nut, toggle_washer, 3, CK7000_pin];
AP5236 = ["AP5236", "AP5236", 7.0, 13.6, 11, 0.4, 1.7, "blue",6.1, 4, 8.0 , 8, 1, 3.0 , 25/2, 22.2, 4.90, 2.50,toggle_nut, toggle_washer, 3, AP5236_pin];
MS332F = ["MS332F", "MS332F", 12.6, 13.1, 9.5, 0.4, 1.7, "blue",6.1, 4, 8.0 , 8, 1, 4.0 , 25/2, 14.4, 5.0, 2.2 ,toggle_nut, toggle_washer, 6, MS332F_pin];

View File

@@ -46,10 +46,14 @@ function cable_bundle(cable) = //! Arrangement of a bundle in a flat cable clip
function cable_width(cable) = cable_bundle(cable)[0] * cable_wire_size(cable); //! Width in flat clip
function cable_height(cable) = cable_bundle(cable)[1] * cable_wire_size(cable); //! Height in flat clip
module mouse_hole(cable, h = 100) { //! A mouse hole to allow a panel to go over a wire bundle.
module mouse_hole(cable, h = 100, teardrop = false) { //! A mouse hole to allow a panel to go over a wire bundle.
r = wire_hole_radius(cable);
rotate(90) slot(r, 2 * r, h = h);
if(teardrop)
vertical_tearslot(r = r, l = 2 * r, h = h);
else
rotate(90)
slot(r, 2 * r, h = h);
}
module cable_tie_holes(cable_r, h = 100) { //! Holes to thread a ziptie through a panel to make a cable tie.

View File

@@ -48,11 +48,12 @@ module ziptie(type, r, t = 0) //! Draw specified ziptie wrapped around radius ``
tangents = rounded_polygon_tangents(outside_path);
length = ceil(rounded_polygon_length(outside_path, tangents) + ziptie_tail(type) + latch.z + 1);
len = length <= 100 ? 100 : length;
width = ziptie_width(type);
vitamin(str("ziptie(", type[0], ", ", r, "): Ziptie ", len, "mm min length"));
vitamin(str("ziptie(", type[0], ", ", r, "): Ziptie ", width, "mm x ", len, "mm min length"));
color(ziptie_colour(type)){
linear_extrude(height = ziptie_width(type), center = true)
linear_extrude(height = width, center = true)
difference() {
rounded_polygon(outside_path, tangents);
rounded_polygon(inside_path);