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

Compare commits

...

60 Commits

Author SHA1 Message Date
Chris Palmer
71ac571346 Added a utility for making involute spur gears 2020-07-06 23:22:11 +01:00
Chris Palmer
e4d93366fa Added degrees, radians and rot2_z() to maths.scad. 2020-07-06 12:43:24 +01:00
Chris Palmer
f047ac27f7 Added SMR95 ball bearing 2020-07-04 17:30:26 +01:00
Chris Palmer
a9e479d971 Documented camera lens module. 2020-07-04 14:57:01 +01:00
Chris Palmer
47b01af1ea Added RPI camera V2
Add cameras to lib.scad
2020-07-04 14:54:19 +01:00
Chris Palmer
fe19eba237 Tweaked flat_flex connectors. 2020-07-04 14:14:25 +01:00
Chris Palmer
235f7b86e3 Camera connector position and size separated.
Camera_lens() module added.
2020-07-04 09:55:38 +01:00
Chris Palmer
92d7e18b16 Added pcb_size() function. 2020-07-04 09:53:09 +01:00
Chris Palmer
6a7226120f Fixed RPI camera component positions. 2020-06-30 18:57:14 +01:00
Chris Palmer
8aa00cd041 Added MGN12H rail and included MGN12 in the test. 2020-06-30 09:28:32 +01:00
Chris Palmer
f6b512da1f Added a couple of Raspberry Pi cameras. 2020-06-29 23:03:54 +01:00
Chris Palmer
c7ea0939b9 Made flat_flex parametric and changed default orientation. 2020-06-29 23:01:34 +01:00
Chris Palmer
265b5ab555 Fixed layout to work with an empty list. 2020-06-27 20:00:47 +01:00
Chris Palmer
186dbbfd08 Added SMT resistors and 0603 LED. 2020-06-27 19:59:49 +01:00
Chris Palmer
60659a43f8 Added light_strip_clip_wall(). 2020-06-24 16:42:17 +01:00
Chris Palmer
f412cb1736 Tweaked lightstrip dimensions. 2020-06-21 20:35:13 +01:00
Chris Palmer
2b878556fc Bug fix to platters.scad for last change. 2020-06-21 16:00:26 +01:00
Chris Palmer
1f1a360b7c Mods to allow panels and platters to be target specific or not. 2020-06-21 12:53:14 +01:00
Chris Palmer
a547c98995 Added shelf bracket to printed/box.scad. 2020-06-20 15:12:09 +01:00
Chris Palmer
d9fa8c8668 Added position children used for drilling holes on sheets. 2020-06-20 15:04:03 +01:00
Chris Palmer
bf5b6d7c30 Added matrix inversion 2020-06-20 15:01:01 +01:00
Chris Palmer
9cfde7f524 Updated readme for grey() change. 2020-06-20 14:56:38 +01:00
Chris Palmer
184f19ef04 Replaced grey constants with a function grey().
Done to reduced the number of global constants.
2020-06-20 10:17:29 +01:00
Chris Palmer
c88472121e Replaced hard coded number with constant. 2020-06-01 13:46:11 +01:00
Chris Palmer
a74bf094aa Added TUK FACK2SPM Cat5E RJ45 shielded panel mount coupler. 2020-05-30 15:29:28 +01:00
Chris Palmer
5a06f79466 Updated gallery pic. 2020-05-26 18:24:04 +01:00
Chris Palmer
98e17080d8 Added meter_shunt_y() function to led_meter. 2020-05-26 15:19:38 +01:00
Chris Palmer
d3f308a45e Pixel differences in images due to OpenSCAD version update. 2020-05-20 21:58:07 +01:00
Chris Palmer
fe454884e0 Fixed Ampmeter typo. 2020-05-20 21:41:54 +01:00
Chris Palmer
c019448dd3 Unused imaged removed. 2020-05-20 21:40:13 +01:00
Chris Palmer
eadc541e8f Screw_and_washer() no longer adds washers for countersunk screws. 2020-05-18 15:29:19 +01:00
Chris Palmer
02791c40ac pbox_outer_shape() added and pbox_screw_positions() documented. 2020-05-18 15:28:26 +01:00
Chris Palmer
85b8ffbbc3 Fixed pin header parameter values passed from PCBs. 2020-05-18 15:27:22 +01:00
Chris Palmer
dd5d3869ad Removed old file 2020-05-18 15:04:41 +01:00
Chris Palmer
b84eb3cf31 Updated big picture 2020-05-02 21:38:53 +01:00
Chris Palmer
0ec7aabcfb Modelled DSP5005 power supply module as a panel_meter.
Panel_meters can now have inner apertures and buttons.
2020-05-02 20:42:26 +01:00
Chris Palmer
baa737c4d8 Updated example to use Foot contructor. 2020-05-02 20:28:55 +01:00
Chris Palmer
70b13d2f27 Added functions to create property lists that are created by the client.
Foot, box, bbox, pbox, flat_hinge and strap_handle.
2020-05-02 20:27:32 +01:00
Chris Palmer
c9aad0178e Fixed typo 2020-05-02 11:50:01 +01:00
Chris Palmer
df96551b11 Fixed PCB cutouts bugs, i.e. components drawn instead of cutouts. 2020-04-30 13:31:20 +01:00
Chris Palmer
a5a360e0d1 Updated images. 2020-04-29 15:19:39 +01:00
Chris Palmer
828e5ad36e make_all.py now terminates early if there are any errors in bom generation. 2020-04-29 15:19:10 +01:00
Chris Palmer
cedaafed3d More precise led positions on WD2002SJ pcb. 2020-04-25 19:39:16 +01:00
Chris Palmer
0d38d82416 led_ammeter size tweaks. 2020-04-25 19:38:43 +01:00
Chris Palmer
041341b946 Fixed indentation in platters.py. 2020-04-24 12:05:10 +01:00
Chris Palmer
70622ba8de Gallery update 2020-04-24 10:17:55 +01:00
Chris Palmer
4ab0a981ef Added panel_meters for panel mount digital meters. 2020-04-23 23:45:25 +01:00
Chris Palmer
bb7dd51270 Added poly_drill() and used it for LED and trimpot cutouts.
Uses drill if cnc_bit_r is non-zero else poly_cylinder.
2020-04-23 23:13:10 +01:00
Chris Palmer
48293b9abd Poly_ring now can have specified number of sides. 2020-04-23 10:52:34 +01:00
Chris Palmer
c9d10eeb8b Renamed meters to LED_meters and added ammeter version. 2020-04-21 21:50:38 +01:00
Chris Palmer
192460c0fa Added SMD 0805 LEDs. 2020-04-21 11:02:48 +01:00
Chris Palmer
d4402c6713 Corrected Molex USB tab length 2020-04-20 18:51:26 +01:00
Chris Palmer
b9890ca589 Reduced printed box screw inset when top_thickness is zero. 2020-04-20 17:53:26 +01:00
Chris Palmer
026b9daf59 Added molex_usb_Ax2 connector. 2020-04-20 17:52:37 +01:00
Chris Palmer
2afc00cfa9 Added tongues to USB A connectors 2020-04-20 17:51:02 +01:00
Chris Palmer
84b5686af6 Corrected WD2002SJ heatsink thickness 2020-04-20 17:47:37 +01:00
Chris Palmer
71af8f98ed Added Swiss clip. 2020-04-16 00:59:27 +01:00
Chris Palmer
6cecb4d466 Added missing comment 2020-04-14 18:21:42 +01:00
Chris Palmer
4ef926a18f Added axial PCB mounted resistors. 2020-04-14 18:09:58 +01:00
Chris Palmer
5afc4f816c Added PDIP ICS and sockets. 2020-04-13 18:06:09 +01:00
115 changed files with 2904 additions and 614 deletions

View File

@@ -52,7 +52,7 @@ iec = IEC_inlet_atx;
socket = Contactum;
foot = [20, 8, 3, 1, M3_dome_screw, 10];
foot = Foot(d = 20, h = 8, t = 3, r = 1, screw = M3_dome_screw);
module foot_stl() foot(foot);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -52,14 +52,7 @@ $fs = extrusion_width / 2;
function round_to_layer(z) = ceil(z / layer_height) * layer_height;
// Some additional named colours
grey20 = [0.2, 0.2, 0.2];
grey30 = [0.3, 0.3, 0.3];
grey40 = [0.4, 0.4, 0.4];
grey50 = [0.5, 0.5, 0.5];
grey60 = [0.6, 0.6, 0.6];
grey70 = [0.7, 0.7, 0.7];
grey80 = [0.8, 0.8, 0.8];
grey90 = [0.9, 0.9, 0.9];
function grey(n) = [0.01, 0.01, 0.01] * n; //! Generate a shade of grey to pass to color().
gold = [255/255, 215/255, 0/255];
brass = [255/255, 220/255, 100/255];
silver = [0.75, 0.75, 0.75];

View File

@@ -29,6 +29,7 @@ include <vitamins/batteries.scad>
include <vitamins/blowers.scad>
include <vitamins/bulldogs.scad>
include <vitamins/buttons.scad>
include <vitamins/cameras.scad>
include <vitamins/components.scad>
include <vitamins/displays.scad>
include <vitamins/extrusions.scad>
@@ -40,9 +41,11 @@ include <vitamins/inserts.scad>
include <vitamins/kp_pillow_blocks.scad>
include <vitamins/ldrs.scad>
include <vitamins/leadnuts.scad>
include <vitamins/led_meter.scad>
include <vitamins/light_strips.scad>
include <vitamins/mains_sockets.scad>
include <vitamins/modules.scad>
include <vitamins/panel_meters.scad>
include <vitamins/pillars.scad>
include <vitamins/pin_headers.scad>
include <vitamins/pulleys.scad>
@@ -55,6 +58,7 @@ include <vitamins/sk_brackets.scad>
include <vitamins/spools.scad>
include <vitamins/ssrs.scad>
include <vitamins/stepper_motors.scad>
include <vitamins/swiss_clips.scad>
include <vitamins/toggles.scad>
include <vitamins/transformers.scad>
include <vitamins/tubings.scad>
@@ -62,7 +66,6 @@ include <vitamins/variacs.scad>
include <vitamins/zipties.scad>
use <vitamins/jack.scad>
use <vitamins/meter.scad>
use <vitamins/fuseholder.scad>
use <vitamins/hygrometer.scad>
@@ -81,6 +84,7 @@ use <utils/rounded_cylinder.scad>
use <utils/dogbones.scad>
use <utils/tube.scad>
use <utils/quadrant.scad>
use <utils/gears.scad>
use <utils/hanging_hole.scad>
use <utils/fillet.scad>
use <utils/rounded_polygon.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 KiB

After

Width:  |  Height:  |  Size: 813 KiB

View File

@@ -29,6 +29,7 @@ use <tests/blowers.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/circlips.scad>
use <tests/components.scad>
use <tests/d_connectors.scad>
@@ -48,12 +49,13 @@ use <tests/LDRs.scad>
use <tests/LEDs.scad>
use <tests/light_strips.scad>
use <tests/linear_bearings.scad>
use <tests/meter.scad>
use <tests/LED_meters.scad>
use <tests/microswitches.scad>
use <tests/modules.scad>
use <tests/nuts.scad>
use <tests/o_ring.scad>
use <tests/opengrab.scad>
use <tests/panel_meters.scad>
use <tests/PCBs.scad>
use <tests/pillars.scad>
use <tests/PSUs.scad>
@@ -71,6 +73,7 @@ use <tests/spades.scad>
use <tests/springs.scad>
use <tests/SSRs.scad>
use <tests/stepper_motors.scad>
use <tests/swiss_clips.scad>
use <tests/toggles.scad>
use <tests/transformers.scad>
use <tests/tubings.scad>
@@ -101,7 +104,7 @@ use <tests/SSR_shroud.scad>
use <tests/PSU_shroud.scad>
x0 = 0;
x1 = x0 + 100;
x1 = x0 + 110;
x2 = x1 + 90;
x3 = x2 + 130;
x4 = x3 + 200;
@@ -176,7 +179,7 @@ fans_y = displays_y + 80;
transformers_y = fans_y + 120;
psus_y = transformers_y + 190;
translate([x0 + 30, inserts_y])
translate([x0 + 35, inserts_y])
inserts();
translate([x0, inserts_y])
@@ -250,7 +253,8 @@ translate([x0, psus_y]) {
zipties_y = 0;
bulldogs_y = zipties_y + 30;
leadnuts_y = bulldogs_y + 50;
swiss_clips_y = bulldogs_y + 35;
leadnuts_y = swiss_clips_y + 50;
translate([x1, zipties_y])
zipties();
@@ -258,6 +262,9 @@ translate([x1, zipties_y])
translate([x1, bulldogs_y])
bulldogs();
translate([x1, swiss_clips_y])
swiss_clips();
translate([x1, leadnuts_y])
leadnuts();
@@ -275,16 +282,16 @@ components_y = toggles_y + 40;
translate([x2, leds_y])
leds();
translate([x2 + 40, leds_y])
translate([x2 + 35, leds_y])
ldrs();
translate([x2 + 8, carriers_y])
carriers();
translate([x2+ 38, carriers_y])
meters();
translate([x2 + 20, carriers_y])
led_meters();
translate([x2 + 68, carriers_y])
translate([x2 + 70, leds_y])
fuseholders();
translate([x2, spades_y])
@@ -316,7 +323,8 @@ ssrs_y = modules_y + 80;
blowers_y = ssrs_y + 60;
batteries_y = blowers_y + 100;
steppers_y = batteries_y + 70;
extrusions_y = steppers_y + 100;
panel_meters_y = steppers_y + 70;
extrusions_y = panel_meters_y + 80;
translate([x3, veroboard_y])
veroboard_test();
@@ -327,6 +335,9 @@ translate([x3 + 70, veroboard_y + 30])
translate([x3 + 140, veroboard_y + 20])
pcb_mounts();
translate([x3 + 170, veroboard_y + 16])
cameras();
translate([x3, d_connectors_y])
d_connectors();
@@ -357,9 +368,11 @@ translate([x3, batteries_y])
translate([x2, steppers_y]) // interloper
stepper_motors();
translate([x2, extrusions_y]) {
translate([x2, panel_meters_y])
panel_meters();
translate([x2, extrusions_y])
extrusions();
}
translate([x3, transformers_y])
transformers();
@@ -372,7 +385,7 @@ sk_brackets_y = extrusion_brackets_y + 80;
kp_pillow_blocks_y = sk_brackets_y + 50;
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
translate([x4 + 150, belts_y + 58]) {
translate([x4 + 200, belts_y + 58]) {
belt_test();
translate([0, 60])

View File

@@ -31,26 +31,29 @@
//!
//! Normally the side sheets are the same type but they can be overridden individually as long as the substitute has the same thickness.
//
include <../utils/core/core.scad>
include <../core.scad>
use <../vitamins/sheet.scad>
use <../vitamins/screw.scad>
use <../vitamins/washer.scad>
use <../vitamins/insert.scad>
use <../utils/quadrant.scad>
use <../utils/round.scad>
bezel_clearance = 0.2;
sheet_end_clearance = 1;
sheet_slot_clearance = 0.2;
function box_screw(type) = type[0]; //! Screw type to be used at the corners
function box_wall(type) = type[1]; //! Wall thickness of 3D parts
function box_sheets(type) = type[2]; //! Sheet type used for the sides
function box_top_sheet(type) = type[3]; //! Sheet type for the top
function box_base_sheet(type)= type[4]; //! Sheet type for the bottom
function box_feet(type) = type[5]; //! True to enable feet on the bottom bezel
function box_width(type) = type[6]; //! Internal width
function box_depth(type) = type[7]; //! Internal depth
function box_height(type) = type[8]; //! Internal height
function box_screw(type) = type[0]; //! Screw type to be used at the corners
function box_shelf_screw(type) = type[1]; //! Screw type to hold a shelf
function box_wall(type) = type[2]; //! Wall thickness of 3D parts
function box_sheets(type) = type[3]; //! Sheet type used for the sides
function box_top_sheet(type) = type[4]; //! Sheet type for the top
function box_base_sheet(type) = type[5]; //! Sheet type for the bottom
function box_feet(type) = type[6]; //! True to enable feet on the bottom bezel
function box_width(type) = type[7]; //! Internal width
function box_depth(type) = type[8]; //! Internal depth
function box_height(type) = type[9]; //! Internal height
function box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false, shelf_screw = M3_dome_screw) = //! Construct a property list for a box.
concat([screw, shelf_screw, wall, sheets, top_sheet, base_sheet, feet], size);
function box_bezel_clearance(type) = bezel_clearance;
@@ -59,6 +62,7 @@ function box_profile_overlap(type) = 3 + sheet_end_clearance / 2;
function box_washer(type) = screw_washer(box_screw(type));
function box_insert(type) = screw_insert(box_screw(type));
function box_shelf_insert(type) = screw_insert(box_shelf_screw(type));
function box_hole_inset(type) = washer_radius(box_washer(type)) + 1;
function box_insert_r(type) = insert_hole_radius(box_insert(type));
@@ -87,23 +91,32 @@ function box_bezel_height(type, bottom) = //! Bezel height for top or bottom
grill_hole = 5;
grill_gap = 1.9;
module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling.
function box_grill_hole_r() = grill_hole / 2;
module grill_hole_positions(width, height, r = 1000) {
nx = floor(width / (grill_hole + grill_gap));
xpitch = width / nx;
ny = floor(height / ((grill_hole + grill_gap) * cos(30)));
ypitch = height / ny;
for(y = [0 : ny - 1], x = [0 : nx - 1 - (y % 2)]) {
$x = -width / 2 + (x + 0.5 + (y % 2) / 2) * xpitch;
$y = -height / 2 + (y + 0.5) * ypitch;
if(sqrt(sqr($x) + sqr($y)) + grill_hole / 2 <= r)
translate([$x, $y])
children();
}
}
module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling.
extrude_if(h)
for(y = [0 : ny - 1], x = [0 : nx - 1 - (y % 2)]) {
x = -width / 2 + (x + 0.5 + (y % 2) / 2) * xpitch;
y = -height / 2 + (y + 0.5) * ypitch;
if(sqrt(sqr(x) + sqr(y)) + grill_hole / 2 <= r)
translate([x, y])
if(poly)
poly_circle(r = grill_hole / 2);
else
circle(d = grill_hole);
}
if(poly)
grill_hole_positions(width, height, r)
poly_circle(r = grill_hole / 2);
else
grill_hole_positions(width, height, r)
circle(d = grill_hole);
}
module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
@@ -175,6 +188,15 @@ module box_corner_profile_section(type, section, sections) { //! Generates inter
}
}
module box_corner_profile_sections(type, section, sections) { //! Generate four copies of a corner profile section
stl("box_corner_profile");
offset = box_boss_r(type) + 1;
for(i = [0 : 3])
rotate(i * 90)
translate([offset, offset])
box_corner_profile_section(type, section, sections);
}
module box_corner_quadrants(type, width, depth)
for(corner = [0:3]) {
x = [-1,1,1,-1][corner];
@@ -258,10 +280,11 @@ dowel_length = 20;
dowel_wall = extrusion_width * 3;
dowel_h_wall = layer_height * 6;
module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlocking sections of the bezel to allow it to be bigger than the printer
w = (box_width(type) + 2 * box_outset(type)) / cols;
h = (box_depth(type) + 2 * box_outset(type)) / rows;
tw = box_width(type) + 2 * box_outset(type);
w = tw / cols;
th = box_depth(type) + 2 * box_outset(type);
h = th / rows;
bw = box_outset(type) - bezel_clearance / 2;
bw2 = box_outset(type) + box_inset(type);
@@ -336,7 +359,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
render() difference() {
union() {
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
translate([box_width(type) / 2 + box_outset(type) - x * w, box_depth(type) / 2 + box_outset(type) - y * h, box_profile_overlap(type)])
translate([tw / 2 - x * w, th / 2 - y * h, box_profile_overlap(type)])
box_bezel(type, bottom);
if(x < cols - 1 && y == 0)
@@ -396,7 +419,6 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
}
}
module box_screw_hole_positions(type)
for(x = [-1, 1], y = [-1, 1])
translate([x * (box_width(type) / 2 - box_hole_inset(type)), y * (box_depth(type) / 2 - box_hole_inset(type))])
@@ -439,6 +461,96 @@ module box_shelf_blank(type, sheet = false) { //! Generates a 2D template for a
}
}
module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = undef) { //! Place children at the shelf screw positions
w = is_undef(wall) ? box_wall(type) : wall;
insert = box_shelf_insert(type);
translate_z(-insert_boss_radius(insert, w))
for(p = screw_positions)
multmatrix(p)
translate_z(thickness)
children();
}
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts
stl("shelf_bracket");
w = is_undef(wall) ? box_wall(type) : wall;
insert = box_shelf_insert(type);
lip = 2 * insert_boss_radius(insert, w);
width = insert_length(insert) + w;
module shape()
difference() {
square([box_width(type), box_depth(type)], center = true);
offset(bezel_clearance / 2)
box_corner_quadrants(type, box_width(type), box_depth(type));
if($children)
hflip()
children();
}
module boss()
translate_z(-width + eps)
linear_extrude(width - 2 * eps)
hull() {
circle4n(r = lip / 2 - eps);
translate([-lip / 2, -lip / 2 + eps])
square([lip, eps]);
}
difference() {
union() {
linear_extrude(w)
difference() {
shape()
if($children)
children(0);
round(2) offset(-width)
shape()
if($children)
children(0);
}
linear_extrude(lip)
difference() {
shape()
if($children)
children(0);
offset(-w)
shape()
if($children)
children(0);
}
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
boss();
}
if($children > 1)
hflip()
children(1);
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
insert_hole(insert, counterbore = 1, horizontal = true);
}
}
module box_shelf_bracket_section(type, rows, cols, x, y) { //! Generates sections of the shelf bracket to allow it to be bigger than the printer
tw = box_width(type);
w = tw / cols;
th = box_depth(type);
h = th / rows;
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
translate([tw / 2 - x * w, th / 2 - y * h])
children();
}
module box_left_blank(type, sheet = false) { //! Generates a 2D template for the left sheet, ```sheet``` can be set to override the type
dxf("box_left");

View File

@@ -50,6 +50,9 @@ function bbox_name(type) = type[8] ? type[8] : "bbox"; //! Optional name i
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.
function bbox(screw, sheets, base_sheet, top_sheet, span, size, name = "bbox", skip_blocks = [], star_washers = true) = //! Construct the property list for a butt_box
[ screw, sheets, base_sheet, top_sheet, span, size.x, size.y, size.z, name, skip_blocks, star_washers ];
function bbox_volume(type) = bbox_width(type) * bbox_depth(type) * bbox_height(type) / 1000000; //! Internal volume in litres
function bbox_area(type) = let(w = bbox_width(type), d = bbox_depth(type), h = bbox_height(type)) //! Internal surdface area in m^2
2 * (w * d + w * h + d * h) / 1000000;
@@ -107,12 +110,9 @@ function fixing_block_positions(type) = let(
function side_holes(type) = [for(p = fixing_block_positions(type), q = fixing_block_holes(bbox_screw(type))) p * q];
module drill_holes(type, t)
for(list = [corner_holes(type), side_holes(type)], p = list)
let(q = t * p)
if(abs(transform([0, 0, 0], q).z) < eps)
multmatrix(q)
drill(screw_clearance_radius(bbox_screw(type)), 0);
module bbox_drill_holes(type, t)
position_children(concat(corner_holes(type), side_holes(type)), t)
drill(screw_clearance_radius(bbox_screw(type)), 0);
module bbox_base_blank(type) { //! 2D template for the base
dxf(str(bbox_name(type), "_base"));
@@ -120,7 +120,7 @@ module bbox_base_blank(type) { //! 2D template for the base
difference() {
sheet_2D(bbox_base_sheet(type), bbox_width(type), bbox_depth(type), 1);
drill_holes(type, translate(bbox_height(type) / 2));
bbox_drill_holes(type, translate(bbox_height(type) / 2));
}
}
@@ -133,7 +133,7 @@ module bbox_top_blank(type) { //! 2D template for the top
translate([0, t / 2])
sheet_2D(bbox_top_sheet(type), bbox_width(type) + 2 * t, bbox_depth(type) + t);
drill_holes(type, translate(-bbox_height(type) / 2));
bbox_drill_holes(type, translate(-bbox_height(type) / 2));
}
}
@@ -151,7 +151,7 @@ module bbox_left_blank(type, sheet = false) { //! 2D template for the left side
translate([-t / 2, -bb / 2])
sheet_2D(subst_sheet(type, sheet), bbox_depth(type) + t, bbox_height(type) + bb);
drill_holes(type, rotate([0, 90, 90]) * translate([bbox_width(type) / 2, 0]));
bbox_drill_holes(type, rotate([0, 90, 90]) * translate([bbox_width(type) / 2, 0]));
}
}
@@ -165,7 +165,7 @@ module bbox_right_blank(type, sheet = false) { //! 2D template for the right sid
translate([t / 2, -bb / 2])
sheet_2D(subst_sheet(type, sheet), bbox_depth(type) + t, bbox_height(type) + bb);
drill_holes(type, rotate([0, 90, 90]) * translate([-bbox_width(type) / 2, 0]));
bbox_drill_holes(type, rotate([0, 90, 90]) * translate([-bbox_width(type) / 2, 0]));
}
}
@@ -180,7 +180,7 @@ module bbox_front_blank(type, sheet = false, width = 0) { //! 2D template for th
translate([0, (bt - bb) / 2])
sheet_2D(subst_sheet(type, sheet), max(bbox_width(type) + 2 * t, width), bbox_height(type) + bb + bt);
drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
bbox_drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
}
}
@@ -194,7 +194,7 @@ module bbox_back_blank(type, sheet = false) { //! 2D template for the back
translate([0, -bb / 2])
sheet_2D(subst_sheet(type, sheet), bbox_width(type), bbox_height(type) + bb);
drill_holes(type, rotate([-90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
bbox_drill_holes(type, rotate([-90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
}
}

View File

@@ -42,6 +42,9 @@ 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 flat_hinge(name, size, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin) = //! Construct the property list for a flat hinge.
[name, size.x, size.y, size.z, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin];
function hinge_radius(type) = washer_radius(screw_washer(hinge_screw(type))) + 1;
module hinge_screw_positions(type) { //! Place children at the screw positions

View File

@@ -24,8 +24,10 @@
include <../core.scad>
use <../vitamins/insert.scad>
foot = [25, 12, 3, 2, M4_cap_screw, 10];
insert_foot = [20, 10, 0, 2, M3_cap_screw, 10];
function Foot(d, h, t, r, screw, slant = 10) = [d, h, t, r, screw, slant]; //! Construct a foot property list
foot = Foot(25, 12, 3, 2, M4_cap_screw);
insert_foot = Foot(20, 10, 0, 2, M3_cap_screw);
function insert_foot() = insert_foot; //! Default foot with insert

View File

@@ -30,6 +30,9 @@ include <../core.scad>
use <../vitamins/insert.scad>
use <foot.scad>
function pbox(name, wall, top_t, base_t, radius, size, foot = false, screw = false, ridges = [0, 0]) //! Construct a printed box property list
= concat([name, wall, top_t, base_t, foot, screw, radius, ridges], size);
function pbox_name(type) = type[0]; //! Name to allow more than one box in a project
function pbox_wall(type) = type[1]; //! Wall thickness
function pbox_top(type) = type[2]; //! Top thickness
@@ -71,11 +74,11 @@ function pbox_mid_offset(type) = pbox_ridges(type).y + pbox_wall(type) / 2; // O
function pbox_screw_inset(type) = //! How far the base screws are inset
let(foot = pbox_foot(type),
r = foot ? foot_diameter(foot) / 2 : washer_radius(pbox_washer(type)),
r = foot ? foot_diameter(foot) / 2 : pbox_base(type) ? washer_radius(pbox_washer(type)) : insert_hole_radius(pbox_insert(type)),
R = pbox_radius(type)
) max(r, R - (R - r) / sqrt(2));
module pbox_screw_positions(type) {
module pbox_screw_positions(type) { //! Place children at base screw positions
foot = pbox_foot(type);
inset = pbox_screw_inset(type);
for(x = [-1, 1], y = [-1, 1])
@@ -124,6 +127,9 @@ module pbox_inner_shape(type) {
rounded_square([w, d], rad, center = true);
}
module pbox_outer_shape(type) //! 2D outer shape of the box
offset(pbox_wall(type) / 2) pbox_mid_shape(type);
module pbox_base(type) { //! Generate the STL for the base
stl(str(pbox_name(type),"_base"));
t = pbox_base(type);
@@ -158,7 +164,7 @@ module pbox(type) { //! Generate the STL for the main case
difference() {
union() {
linear_extrude(total_height)
offset(wall / 2) pbox_mid_shape(type);
pbox_outer_shape(type);
if($children > 2)
children(2);

View File

@@ -31,7 +31,7 @@ insert = screw_insert(screw);
screw_depth = insert_length(insert) + 1;
function ribbon_clamp_hole_pitch(ways) = ribbon_clamp_slot(ways) + 2 * min_wall + 2 * corrected_radius(insert_hole_radius(insert)); //! Hole pitch
function ribbon_clamp_width() = 2 * (insert_hole_radius(insert) + 2); //! Width
function ribbon_clamp_width() = 2 * (insert_hole_radius(insert) + wall); //! Width
function ribbon_clamp_length(ways) = ribbon_clamp_hole_pitch(ways) + ribbon_clamp_width(); //! Length given ways
function ribbon_clamp_height() = screw_depth + 1; //! Height

View File

@@ -135,7 +135,7 @@ module ssr_shroud_fastened_assembly(type, cable_d, thickness, name) //! Assembly
*translate_z(cable_d / 2)
rotate([90, 0, 0])
stl_colour(grey20)
stl_colour(grey(20))
cylinder(d = cable_d, h = 20, center = true);
}
}

View File

@@ -24,8 +24,7 @@
include <../core.scad>
use <../vitamins/insert.scad>
strap = [18, 2, M3_pan_screw, 3, 25];
function strap() = strap;
strap = strap();
wall = 2;
clearance = 0.5;
@@ -40,6 +39,10 @@ function strap_screw(type = strap) = type[2]; //! Screw type
function strap_panel(type = strap) = type[3]; //! Panel thickness
function strap_extension(type = strap) = type[4]; //! How much length of the strap that can pull out
function strap(width = 18, thickness = 2, screw = M3_pan_screw, panel_thickness = 3, extension = 25) = //! Construct a property list for a strap
[ width, thickness, screw, panel_thickness, extension ];
function strap_insert(type) = screw_insert(strap_screw(type)); //! The insert type
function strap_key(type) = strap_panel(type) - panel_clearance;
function strap_height(type) = wall + max(insert_length(strap_insert(type)) - strap_key(type), strap_thickness(type) + clearance); //! Height of the ends

613
readme.md
View File

@@ -17,31 +17,78 @@ 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-J </th><th align="left"> Vitamins K-Q </th><th align="left"> Vitamins R-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 = "#KP_pillow_blocks">KP_pillow_blocks</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Layout">Layout</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#SSRs">SSRs</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 = "#Circlips">Circlips</a> </td><td> <a href = "#Meter">Meter</a> </td><td> <a href = "#Screws">Screws</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 = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</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 = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</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 = "#Displays">Displays</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Jack">Jack</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<th align="left"> Vitamins A-I </th><th align="left"> Vitamins J-Q </th><th align="left"> Vitamins R-Z </th><th align="left"> Printed </th><th align="left"> Utilities </th><th align="left"> Core Utilities </th></tr>
<tr><td> <a href = "#Axials">Axials</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#KP_pillow_blocks">KP_pillow_blocks</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Layout">Layout</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#IECs">IECs</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
</table>
---
<a name="Axials"></a>
## Axials
Axial components for PCBs.
[vitamins/axials.scad](vitamins/axials.scad) Object definitions.
[vitamins/axial.scad](vitamins/axial.scad) Implementation.
[tests/axials.scad](tests/axials.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```ax_res_colour(type)``` | Body colour |
| ```ax_res_diameter(type)``` | Body diameter |
| ```ax_res_end_d(type)``` | End cap diameter |
| ```ax_res_end_l(type)``` | End cap length |
| ```ax_res_length(type)``` | Body length |
| ```ax_res_wattage(type)``` | Power rating |
| ```ax_res_wire(type)``` | Wire diameter |
### Modules
| Module | Description |
|:--- |:--- |
| ```ax_res(type, value, tol = 5, pitch = 0)``` | Through hole axial resistor. If ```pitch``` is zero the minimum is used. If below the minimum the resistor is placed vertical. |
| ```wire_link(d, l, h = 1, tail = 3)``` | Draw a wire jumper link. |
![axials](tests/png/axials.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```pcb(PERF60x40)``` | Perfboard 60 x 40mm |
| 1 | ```ax_res(res1_8, 1000)``` | Resistor 1000 Ohms 5% 0.125W |
| 1 | ```ax_res(res1_8, 2200, tol = 1)``` | Resistor 2200 Ohms 1% 0.125W |
| 1 | ```ax_res(res1_4, 39000, tol = 1)``` | Resistor 39000 Ohms 1% 0.25W |
| 1 | ```ax_res(res1_4, 47000)``` | Resistor 47000 Ohms 5% 0.25W |
| 1 | ```ax_res(res1_2, 8200)``` | Resistor 8200 Ohms 5% 0.5W |
| 1 | ```ax_res(res1_2, 8250, tol = 1)``` | Resistor 8250 Ohms 1% 0.5W |
<a href="#top">Top</a>
---
<a name="Ball_bearings"></a>
## Ball_bearings
@@ -86,7 +133,8 @@ Also single bearing balls are modelled as just a silver sphere and a BOM entry.
| 1 | ```ball_bearing(BB6201)``` | Ball bearing 6201-2RS 12mm x 32mm x 10mm |
| 1 | ```ball_bearing(BB624)``` | Ball bearing 624-2RS 4mm x 13mm x 5mm |
| 1 | ```ball_bearing(BB6808)``` | Ball bearing 6808-2RS 40mm x 52mm x 7mm |
| 5 | ``` bearing_ball(3)``` | Steel ball 3mm |
| 1 | ```ball_bearing(BBSMR95)``` | Ball bearing SMR95ZZ 5mm x 9mm x 2.5mm |
| 6 | ``` bearing_ball(3)``` | Steel ball 3mm |
<a href="#top">Top</a>
@@ -188,7 +236,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
### Modules
| Module | Description |
|:--- |:--- |
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
![belts](tests/png/belts.png)
@@ -383,6 +431,45 @@ When the sides are constrained then a circular model is more accurate.
| 3 | ```cable_strip(20, 25, 100, 30)``` | Polypropylene strip 189mm x 24mm x 0.8mm |
<a href="#top">Top</a>
---
<a name="Cameras"></a>
## Cameras
PCB cameras.
[vitamins/cameras.scad](vitamins/cameras.scad) Object definitions.
[vitamins/camera.scad](vitamins/camera.scad) Implementation.
[tests/cameras.scad](tests/cameras.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```camera_connector_pos(type)``` | The flex connector block for the camera itself's position |
| ```camera_connector_size(type)``` | The flex connector block for the camera itself's size |
| ```camera_lens(type)``` | Stack of lens parts, can be round, rectanular or rounded rectangular, with optional tapered aperture |
| ```camera_lens_offset(type)``` | Offset of the lens center from the PCB centre |
| ```camera_pcb(type)``` | The PCB part of the camera |
### Modules
| Module | Description |
|:--- |:--- |
| ```camera(type)``` | Draw specified PCB camera |
| ```camera_lens(type, offset = 0)``` | Draw the lens stack, with optional offset for making a clearance hole |
![cameras](tests/png/cameras.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```camera(rpi_camera_v1)``` | Raspberry Pi camera V1 |
| 1 | ```camera(rpi_camera_v2)``` | Raspberry Pi camera V2 |
| 1 | ```camera(rpi_camera)``` | Raspberry Pi focusable camera |
<a href="#top">Top</a>
---
@@ -476,6 +563,8 @@ Various electronic components used in hot ends and heated beds.
| Function | Description |
|:--- |:--- |
| ```TO220_thickness()``` | Thickness of the tab of a TO220 |
| ```fack2spm_bezel_size()``` | FACK2SPM Bezel dimensions |
| ```fack2spm_screw()``` | Screw type for FACK2SPM |
### Modules
| Module | Description |
@@ -484,6 +573,9 @@ Various electronic components used in hot ends and heated beds.
| ```al_clad_resistor(type, value, leads = true)``` | Draw an aluminium clad resistor |
| ```al_clad_resistor_hole_positions(type)``` | Position children at the screw holes of an aluminium clad resistor |
| ```al_clad_resistor_holes(type, h = 100)``` | Drill screw holes for an aluminium clad resistor |
| ```fack2spm()``` | Draw a FACK2SPM Cat5E RJ45 shielded panel mount coupler |
| ```fack2spm_hole_positions()``` | Place children at the FACK2SPM mounting hole positions |
| ```fack2spm_holes(h = 0)``` | Cut the holes for a FACK2SPM |
| ```panel_USBA()``` | Draw a panel mount USBA connector |
| ```panel_USBA_hole_positions()``` | Place children at hole positions |
| ```panel_USBA_holes(h = 100)``` | Make holes for USBA connector |
@@ -508,6 +600,7 @@ Various electronic components used in hot ends and heated beds.
| 4 | ```screw(M2p5_pan_screw, 16)``` | Screw M2.5 pan x 16mm |
| 4 | ```screw(M3_pan_screw, 16)``` | Screw M3 pan x 16mm |
| 1 | ```panel_USBA()``` | Socket USB A panel mount |
| 1 | ```tuk_fack2spm()``` | TUK FACK2SPM Cat5E RJ45 shielded panel mount coupler |
| 1 | ```thermal_cutout(TC)``` | Thermal cutout TC |
| 1 | ```resistor(Epcos)``` | Thermistor Epcos B57560G104F 100K 1% |
| 1 | ```resistor(EpcosBlue)``` | Thermistor Epcos B57861S104F40 100K 1% |
@@ -570,6 +663,50 @@ 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="DIP"></a>
## DIP
Dual inline IC packages and sockets
[vitamins/dip.scad](vitamins/dip.scad) Implementation.
[tests/DIP.scad](tests/DIP.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```pdip_pin_W(type)``` | Pin shoulder width |
| ```pdip_pin_h(type)``` | Pin height |
| ```pdip_pin_n(type)``` | Pin neck |
| ```pdip_pin_s(type)``` | Height above seating plane |
| ```pdip_pin_t(type)``` | Pin thickness |
| ```pdip_pin_w(type)``` | Pin width |
### Modules
| Module | Description |
|:--- |:--- |
| ```dip(n, part, size, w, pitch, pin)``` | Draw DIP package |
| ```pdip(pins, part, socketed, w = inch(0.3)``` | Draw standard 0.1" PDIP IC package |
| ```pdip_pin(type, l, end)``` | Draw a pin |
![dip](tests/png/dip.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```dil_socket(14, 7.62)``` | DIL socket 28 x 0.3" |
| 1 | ```pdip(14, 74HC00)``` | IC 74HC00 PDIP14 |
| 1 | ```pdip(20, 74HC245)``` | IC 74HC245 PDIP20 |
| 1 | ```pdip(28, ATMEGA328)``` | IC ATMEGA328 PDIP28 |
| 1 | ```pdip(8, NE555)``` | IC NE555 PDIP8 |
| 1 | ```pdip(6, OPTO)``` | IC OPTO PDIP6 |
| 1 | ```pdip(16, ULN2003)``` | IC ULN2003 PDIP16 |
| 1 | ```pdip(18, ULN2803)``` | IC ULN2803 PDIP18 |
<a href="#top">Top</a>
---
@@ -1315,6 +1452,69 @@ Nuts for leadscrews.
| 1 | ```leadnut(LSN8x8)``` | Leadscrew nut 8 x 8 RobotDigg |
<a href="#top">Top</a>
---
<a name="LED_meters"></a>
## LED_meters
LED voltmeter and ammeter modules available from China and a printed bezel that allows the voltmeter to be mounted into a
CNC cut panel. The meter is held in the bezel by melting the stakes with a soldering iron set to 200&deg;C. The
bezel is fixed in the panel with hot glue.
The 7 SEGMENT.TTF font from the [docs](docs) directory needs to be installed to get realistic digits.
[vitamins/led_meters.scad](vitamins/led_meters.scad) Object definitions.
[vitamins/led_meter.scad](vitamins/led_meter.scad) Implementation.
[tests/LED_meters.scad](tests/LED_meters.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```meter_hole_pitch(type)``` | Lug hole pitch |
| ```meter_hole_radius(type)``` | Lug hole radius |
| ```meter_lug_offset(type)``` | Lug position, 0 = center, +1 = top |
| ```meter_lug_size(type)``` | Lug length and width |
| ```meter_offset(type)``` | Display position, 0 = center, +1 = top |
| ```meter_pcb_size(type)``` | PCB size excluding lugs |
| ```meter_shunt(type)``` | Ammeter shunt wire |
| ```meter_size(type)``` | Size of display |
### Functions
| Function | Description |
|:--- |:--- |
| ```meter_bezel_length(type)``` | Printed bezel length |
| ```meter_bezel_rad(type)``` | Printed bezel corner radius |
| ```meter_bezel_wall(type)``` | Printed bezel wall thickness |
| ```meter_bezel_width(type)``` | Printed bezel width |
| ```meter_shunt_y(type)``` | Shunt y coordinate |
### Modules
| Module | Description |
|:--- |:--- |
| ```meter(type, colour = "red", value = "888", display_colour = false)``` | Draw a meter with optional colour and display value |
| ```meter_assembly(type, colour = "red", value = "888", display_colour = false)``` | Meter assembled into the bezel |
| ```meter_bezel(type)``` | Generate the STL for the meter bezel |
| ```meter_bezel_hole(type, h = 100)``` | Make a hole to fit the meter Bezel |
| ```meter_hole_positions(type)``` | Position children over the holes |
![led_meters](tests/png/led_meters.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```meter(led_ameter, colour = "blue")``` | LED ammeter blue |
| 1 | ```meter(led_meter, colour = "blue")``` | LED voltmeter blue |
| 1 | ```meter(led_meter)``` | LED voltmeter red |
### Printed
| Qty | Filename |
| ---:|:--- |
| 1 | meter_bezel.stl |
<a href="#top">Top</a>
---
@@ -1394,9 +1594,10 @@ The `light_strip_clip()` module makes a clip to go around the light that can be
| Function | Description |
|:--- |:--- |
| ```light_strip_clip_depth(light)``` | Depth of the clip |
| ```light_strip_clip_length(light)``` | Outside length |
| ```light_strip_clip_length(light)``` | Outside length of clip |
| ```light_strip_clip_slot(light)``` | Clip slot size |
| ```light_strip_clip_width(light)``` | Outside width |
| ```light_strip_clip_wall()``` | Clip wall thickness |
| ```light_strip_clip_width(light)``` | Outside width of clip |
| ```light_strip_cut_length(type, segs)``` | Calculate cut length given segments |
| ```light_strip_segments(type, max_length)``` | Calculate the maximum number of segments that fit in max_length |
@@ -1521,68 +1722,6 @@ UK 13A sockets at the moment.
| 1 | ```mains_socket(MKLOGIC)``` | Mains socket 13A, switched |
<a href="#top">Top</a>
---
<a name="Meter"></a>
## Meter
LED volt meter modules available from China and a printed bezel that allows them to be mounted into a
CNC cut panel. The meter is held in the bezel by melting the stakes with a soldering iron set to 200&deg;C. The
bezel is fixed in the panel with hot glue.
The 7 SEGMENT.TTF font from the [docs](docs) directory needs to be installed to get realistic digits.
[vitamins/meter.scad](vitamins/meter.scad) Implementation.
[tests/meter.scad](tests/meter.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```meter_height(type = led_meter)``` | Height of body excluding PCB |
| ```meter_hole_pitch(type = led_meter)``` | Lug hole pitch |
| ```meter_hole_radius(type = led_meter)``` | Lug hole radius |
| ```meter_length(type = led_meter)``` | Length of body |
| ```meter_lug_length(type = led_meter)``` | PCB length including lugs |
| ```meter_lug_width(type = led_meter)``` | Lug width |
| ```meter_pcb_length(type = led_meter)``` | PCB length excluding lugs |
| ```meter_pcb_thickness(type = led_meter)``` | PCB thickness |
| ```meter_pcb_width(type = led_meter)``` | PCB width |
| ```meter_width(type = led_meter)``` | Width of body |
### Functions
| Function | Description |
|:--- |:--- |
| ```meter()``` | Default meter type |
| ```meter_bezel_length(type = led_meter)``` | Printed bezel length |
| ```meter_bezel_rad(type = led_meter)``` | Printed bezel corner radius |
| ```meter_bezel_wall(type = led_meter)``` | Printed bezel wall thickness |
| ```meter_bezel_width(type = led_meter)``` | Printed bezel width |
### Modules
| Module | Description |
|:--- |:--- |
| ```meter(type = led_meter, colour = "red", value = "888", display_colour = false)``` | Draw a meter with optional colour and display value |
| ```meter_assembly(type = led_meter, colour = "red", value = "888", display_colour = false)``` | Meter assembled into the bezel |
| ```meter_bezel(type = led_meter)``` | Generate the STL for the meter bezel |
| ```meter_bezel_hole(type = led_meter, h = 100)``` | Make a hole to fit the meter Bezel |
| ```meter_hole_positions(type = led_meter)``` | Position children over the holes |
![meter](tests/png/meter.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```meter(led_meter, colour = "blue")``` | LED meter blue |
| 2 | ```meter(led_meter)``` | LED meter red |
### Printed
| Qty | Filename |
| ---:|:--- |
| 2 | meter_bezel.stl |
<a href="#top">Top</a>
---
@@ -1856,6 +1995,70 @@ 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="Panel_meters"></a>
## Panel_meters
Panel mounted digital meter modules
Notes on the DSN_VC288:
* The tabs aren't modelled because they can be fully retracted if the PCB is removed.
* The current connector isn't moddelled as it is awkwardly tall. I remove it and solder wires instead.
[vitamins/panel_meters.scad](vitamins/panel_meters.scad) Object definitions.
[vitamins/panel_meter.scad](vitamins/panel_meter.scad) Implementation.
[tests/panel_meters.scad](tests/panel_meters.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```pmeter_aperture(type)``` | Aperture length, width and bevel |
| ```pmeter_bevel(type)``` | Bezel bevel inset and start height or a radius |
| ```pmeter_bezel(type)``` | Bezel size |
| ```pmeter_bezel_r(type)``` | Bezel radius |
| ```pmeter_button_colour(type)``` | Button colour |
| ```pmeter_button_pos(type)``` | Button position |
| ```pmeter_button_r(type)``` | Button radius |
| ```pmeter_button_size(type)``` | Button size |
| ```pmeter_buttons(type)``` | List of buttons |
| ```pmeter_inner_ap(type)``` | Inner aperture |
| ```pmeter_inner_ap_o(type)``` | Inner aperture offset |
| ```pmeter_pcb(type)``` | Optional PCB for open types |
| ```pmeter_pcb_h(type)``` | Component height from the front |
| ```pmeter_pcb_z(type)``` | Distance of PCB from the back |
| ```pmeter_size(type)``` | Body size including bezel height |
| ```pmeter_tab(type)``` | Tab size |
| ```pmeter_tab_z(type)``` | Tab vertical position |
| ```pmeter_thickness(type)``` | Wall thickness if not closed |
### Functions
| Function | Description |
|:--- |:--- |
| ```pmeter_depth(type)``` | Depth below bezel |
### Modules
| Module | Description |
|:--- |:--- |
| ```panel_meter(type)``` | Draw panel mounted LCD meter module |
| ```panel_meter_button(type)``` | Draw panel meter button |
| ```panel_meter_cutout(type, h = 0)``` | Make panel cutout |
![panel_meters](tests/png/panel_meters.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```panel_meter(DSN_VC288)``` | DSN-VC288 DC 100V 10A Voltmeter ammeter |
| 1 | ```panel_meter(PZEM001)``` | Peacefair PZEM-001 AC digital multi-function meter |
| 1 | ```panel_meter(PZEM021)``` | Peacefair PZEM-021 AC digital multi-function meter |
| 1 | ```panel_meter(DSP5005)``` | Ruideng DSP5005 Power supply module |
<a href="#top">Top</a>
---
@@ -1871,6 +2074,10 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Properties
| Function | Description |
|:--- |:--- |
| ```ff_back(type)``` | Flat flex back section size |
| ```ff_latch(type)``` | Flat flex latch size |
| ```ff_mid(type)``` | Flat flex middle section size |
| ```ff_slot(type)``` | Flat flex slot size |
| ```hdmi_depth(type)``` | Front to back depth |
| ```hdmi_height(type)``` | Outside height above the PCB |
| ```hdmi_height1(type)``` | Inside height at the sides |
@@ -1900,18 +2107,21 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
| ```pcb_size(type)``` | Length, width and thickness in a vector |
### Modules
| Module | Description |
|:--- |:--- |
| ```barrel_jack(cutout = false)``` | Draw barrel power jack |
| ```block(size, colour, makes_cutout, cutouts)``` | Draw a coloured cube to represent a random PCB component |
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and colour |
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flat_flex(type, cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flex(cutout = false)``` | Draw flexistrip connector |
| ```hdmi(type, cutout = false)``` | Draw HDMI socket |
| ```jack(cutout = false)``` | Draw 3.5mm jack |
| ```molex_254(ways)``` | Draw molex header |
| ```molex_usb_Ax2(cutout)``` | Draw Molex USB connector suitable for perf board |
| ```pcb(type)``` | Draw specified PCB |
| ```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 |
@@ -1937,9 +2147,12 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```box_header(2p54header, 4, 2, smt = 0)``` | Box header 4 x 2 |
| 1 | ```box_header(2p54header, 4, 2)``` | Box header 4 x 2 |
| 1 | ```d_plug(DCONN9, pcb = true)``` | D-type 9 way PCB mount plug |
| 1 | ```dil_socket(12, 15.24)``` | DIL socket 24 x 0.6" |
| 1 | ```hdmi(hdmi_full)``` | HDMI socket |
| 1 | ```pdip(24, 27C32, w = 15.24)``` | IC 27C32 PDIP24 |
| 1 | ```pdip(8, NE555)``` | IC NE555 PDIP8 |
| 1 | ```idc_transition(2p54header, 5)``` | IDC transition header 5 x 2 |
| 1 | ```led(LED10mm, "yellow")``` | LED 10 mm yellow |
| 1 | ```led(LED3mm)``` | LED 3 mm red |
@@ -1947,12 +2160,22 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```microswitch(small_microswitch)``` | Microswitch DM1-00P-110-3 |
| 1 | ```hdmi(hdmi_mini)``` | Mini HDMI socket |
| 1 | ```molex_254(2)``` | Molex KK header 2 way |
| 1 | ```pin_header(2p54header, 4, 1, smt = 0)``` | Pin header 4 x 1 |
| 1 | ```pin_header(2p54header, 5, 1, smt = undef)``` | Pin header 5 x 1 |
| 1 | ```pin_socket(2p54header, 4, 1, right_angle = undef, height = undef, smt = undef)``` | Pin socket 4 x 1 |
| 1 | ```pin_header(2p54header, 4, 1)``` | Pin header 4 x 1 |
| 1 | ```pin_header(2p54header, 5, 1)``` | Pin header 5 x 1 |
| 1 | ```pin_socket(2p54header, 4, 1)``` | Pin socket 4 x 1 |
| 1 | ```pin_socket(2p54header, 6, 1)``` | Pin socket 6 x 1 |
| 1 | ```pin_socket(2p54header, 8, 1)``` | Pin socket 8 x 1 |
| 1 | ```pin_socket(2p54header, 8, 1, right_angle = undef, height = undef, smt = undef)``` | Pin socket 8 x 1 |
| 2 | ```pin_socket(2p54header, 8, 1)``` | Pin socket 8 x 1 |
| 1 | ```ax_res(res1_2, 10, tol = 10)``` | Resistor 10 Ohms 10% 0.5W |
| 1 | ```ax_res(res1_4, 100, tol = 2)``` | Resistor 100 Ohms 2% 0.25W |
| 1 | ```ax_res(res1_8, 1000)``` | Resistor 1000 Ohms 5% 0.125W |
| 1 | ```ax_res(res1_4, 10000)``` | Resistor 10000 Ohms 5% 0.25W |
| 1 | ```ax_res(res1_2, 100000)``` | Resistor 100000 Ohms 5% 0.5W |
| 1 | ```ax_res(res1_8, 1e+6, tol = 1)``` | Resistor 1e+6 Ohms 1% 0.125W |
| 1 | ```smd_led(LED0603, orange)``` | SMD LED 0603 orange |
| 1 | ```smd_led(LED0805, red)``` | SMD LED 0805 red |
| 1 | ```smd_resistor(RES0603, 1K)``` | SMD resistor 0603 1K 0.1W |
| 1 | ```smd_resistor(RES0805, 1K)``` | SMD resistor 0805 1K 0.125W |
| 1 | ```smd_resistor(RES1206, 1K)``` | SMD resistor 1206 1K 0.25W |
| 1 | ```square_button(button_6mm)``` | Square button 6mm |
| 1 | ```pcb(TMC2130)``` | TMC2130 |
| 1 | ```green_terminal(gt_5p08, 2)``` | Terminal block 2 way 0.2" |
@@ -1984,6 +2207,10 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Properties
| Function | Description |
|:--- |:--- |
| ```ff_back(type)``` | Flat flex back section size |
| ```ff_latch(type)``` | Flat flex latch size |
| ```ff_mid(type)``` | Flat flex middle section size |
| ```ff_slot(type)``` | Flat flex slot size |
| ```hdmi_depth(type)``` | Front to back depth |
| ```hdmi_height(type)``` | Outside height above the PCB |
| ```hdmi_height1(type)``` | Inside height at the sides |
@@ -2013,18 +2240,21 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
| ```pcb_size(type)``` | Length, width and thickness in a vector |
### Modules
| Module | Description |
|:--- |:--- |
| ```barrel_jack(cutout = false)``` | Draw barrel power jack |
| ```block(size, colour, makes_cutout, cutouts)``` | Draw a coloured cube to represent a random PCB component |
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and colour |
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flat_flex(type, cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flex(cutout = false)``` | Draw flexistrip connector |
| ```hdmi(type, cutout = false)``` | Draw HDMI socket |
| ```jack(cutout = false)``` | Draw 3.5mm jack |
| ```molex_254(ways)``` | Draw molex header |
| ```molex_usb_Ax2(cutout)``` | Draw Molex USB connector suitable for perf board |
| ```pcb(type)``` | Draw specified PCB |
| ```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 |
@@ -2416,10 +2646,10 @@ Linear rails with carriages.
### Modules
| Module | Description |
|:--- |:--- |
| ```carriage(type, rail, end_colour = grey20, wiper_colour = grey20)``` | Draw the specified carriage |
| ```carriage(type, rail, end_colour = grey(20)``` | Draw the specified carriage |
| ```carriage_hole_positions(type)``` | Position children over screw holes |
| ```rail(type, length)``` | Draw the specified rail |
| ```rail_assembly(type, length, pos, carriage_end_colour = grey20, carriage_wiper_colour = grey20)``` | Rail and carriage assembly |
| ```rail_assembly(type, length, pos, carriage_end_colour = grey(20)``` | Rail and carriage assembly |
| ```rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true)``` | Position children over screw holes |
| ```rail_screws(type, length, thickness, screws = 100)``` | Place screws in the rail |
@@ -2428,24 +2658,27 @@ Linear rails with carriages.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```rail(MGN15, 260)``` | Linear rail MGN15 x 260mm |
| 1 | ```rail(MGN12, 200)``` | Linear rail MGN12 x 200mm |
| 1 | ```rail(MGN12H, 200)``` | Linear rail MGN12H x 200mm |
| 1 | ```rail(MGN15, 200)``` | Linear rail MGN15 x 200mm |
| 1 | ```rail(MGN5, 200)``` | Linear rail MGN5 x 200mm |
| 1 | ```rail(MGN7, 200)``` | Linear rail MGN7 x 200mm |
| 1 | ```rail(MGN9, 200)``` | Linear rail MGN9 x 200mm |
| 1 | ```rail(SSR15, 200)``` | Linear rail SSR15 x 200mm |
| 26 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 17 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 31 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 4 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 11 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
| 15 | ```screw(M2_cs_cap_screw, 10)``` | Screw M2 cs cap x 10mm |
| 8 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
| 5 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 12 | ```screw(M3_cap_screw, 12)``` | Screw M3 cap x 12mm |
| 3 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 2 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
| 2 | ```screw(M3_cs_cap_screw, 16)``` | Screw M3 cs cap x 16mm |
| 6 | ```screw(M3_cs_cap_screw, 16)``` | Screw M3 cs cap x 16mm |
| 2 | ```screw(M4_cap_screw, 16)``` | Screw M4 cap x 16mm |
| 2 | ```screw(M4_cs_cap_screw, 20)``` | Screw M4 cs cap x 20mm |
| 26 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 17 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 31 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 4 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
@@ -2886,6 +3119,54 @@ SK shaft support brackets
| 6 | ```washer(M5_washer)``` | Washer M5 x 10mm x 1mm |
<a href="#top">Top</a>
---
<a name="SMDs"></a>
## SMDs
Surface mount components for PCBs.
[vitamins/smds.scad](vitamins/smds.scad) Object definitions.
[vitamins/smd.scad](vitamins/smd.scad) Implementation.
[tests/SMDs.scad](tests/SMDs.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```smd_led_lens(type)``` | Lens length width and height |
| ```smd_led_size(type)``` | Body length, width and height |
| ```smd_res_end_cap(type)``` | End cap width |
| ```smd_res_power(type)``` | Power rating in Watts |
| ```smd_res_size(type)``` | Body length, width and height |
### Functions
| Function | Description |
|:--- |:--- |
| ```smd_100th(x)``` | Convert dimension to 1/100" notation |
| ```smd_led_height(type)``` | Total height |
| ```smd_size(size)``` | Convert size to 1/100" notation |
### Modules
| Module | Description |
|:--- |:--- |
| ```smd_led(type, colour, cutout)``` | Draw an SMD LED with specified ```colour``` |
| ```smd_resistor(type, value)``` | Draw an SMD resistor with specified value |
![smds](tests/png/smds.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```smd_led(LED0603, green)``` | SMD LED 0603 green |
| 1 | ```smd_led(LED0805, blue)``` | SMD LED 0805 blue |
| 1 | ```smd_resistor(RES0603, 1R0)``` | SMD resistor 0603 1R0 0.1W |
| 1 | ```smd_resistor(RES0805, 10M)``` | SMD resistor 0805 10M 0.125W |
| 1 | ```smd_resistor(RES1206, 100K)``` | SMD resistor 1206 100K 0.25W |
<a href="#top">Top</a>
---
@@ -3116,6 +3397,55 @@ NEMA stepper motor model.
| 15 | ```star_washer(M3_washer)``` | Washer star M3 x 0.5mm |
<a href="#top">Top</a>
---
<a name="Swiss_clips"></a>
## Swiss_clips
Swiss picture clip.
Used for holding glass on 3D printer beds.
The bending model is an approximation because in real life the arms bend.
Should be reasonably accurate if not close to fully open.
[vitamins/swiss_clips.scad](vitamins/swiss_clips.scad) Object definitions.
[vitamins/swiss_clip.scad](vitamins/swiss_clip.scad) Implementation.
[tests/Swiss_clips.scad](tests/Swiss_clips.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```sclip_arm_length(type)``` | Length of arms |
| ```sclip_arm_width(type)``` | Width of spring arms |
| ```sclip_height(type)``` | External height |
| ```sclip_hinge_offset(type)``` | Offset of hinge |
| ```sclip_hook(type)``` | hook, length, width |
| ```sclip_length(type)``` | Total external length |
| ```sclip_max_gap(type)``` | Maximum opening |
| ```sclip_radius(type)``` | Bend radius |
| ```sclip_spigot(type)``` | Spigot length, width, height |
| ```sclip_thickness(type)``` | Thickness of the metal |
| ```sclip_width(type)``` | Width |
### Modules
| Module | Description |
|:--- |:--- |
| ```swiss_clip(type, open = 0.9)``` | Draw a Swiss clip open by specified amount |
| ```swiss_clip_hole(type, open, h = 0)``` | Drill hole for spigot |
![swiss_clips](tests/png/swiss_clips.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```sheet(AL6, 40, 20, 1)``` | Aluminium tooling plate 40mm x 20mm x 6mm |
| 1 | ```sheet(glass2, 40, 20, 1)``` | Sheet glass 40mm x 20mm x 2mm |
| 2 | ```swiss_clip(UKPFS1008_10)``` | Swiss picture clip UKPFS1008_10 11mm |
<a href="#top">Top</a>
---
@@ -3608,6 +3938,7 @@ Normally the side sheets are the same type but they can be overridden individual
| ```box_height(type)``` | Internal height |
| ```box_screw(type)``` | Screw type to be used at the corners |
| ```box_sheets(type)``` | Sheet type used for the sides |
| ```box_shelf_screw(type)``` | Screw type to hold a shelf |
| ```box_top_sheet(type)``` | Sheet type for the top |
| ```box_wall(type)``` | Wall thickness of 3D parts |
| ```box_width(type)``` | Internal width |
@@ -3615,6 +3946,7 @@ Normally the side sheets are the same type but they can be overridden individual
### Functions
| Function | Description |
|:--- |:--- |
| ```box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false, shelf_screw = M3_dome_screw)``` | Construct a property list for a box. |
| ```box_bezel_height(type, bottom)``` | Bezel height for top or bottom |
| ```box_corner_gap(type)``` | Gap between box_sheets at the corners to connect inside and outside profiles |
| ```box_inset(type)``` | How much the bezel intrudes on the specified width and length, away from the corners |
@@ -3634,6 +3966,7 @@ Normally the side sheets are the same type but they can be overridden individual
| ```box_corner_profile(type)``` | Generates the corner profile STL for 3D printing. |
| ```box_corner_profile_2D(type)``` | The 2D shape of the corner profile. |
| ```box_corner_profile_section(type, section, sections)``` | Generates interlocking sections of the corner profile to allow it to be taller than the printer |
| ```box_corner_profile_sections(type, section, sections)``` | Generate four copies of a corner profile section |
| ```box_front(type)``` | Default front, can be overridden to customise |
| ```box_front_blank(type, sheet = false)``` | Generates a 2D template for the front sheet, ```sheet``` can be set to override the type |
| ```box_left(type)``` | Default left side, can be overridden to customise |
@@ -3641,6 +3974,9 @@ Normally the side sheets are the same type but they can be overridden individual
| ```box_right(type)``` | Default right side, can be overridden to customise |
| ```box_right_blank(type, sheet = false)``` | Generates a 2D template for the right sheet, ```sheet``` can be set to override the type |
| ```box_shelf_blank(type, sheet = false)``` | Generates a 2D template for a shelf sheet |
| ```box_shelf_bracket(type, screw_positions, wall = undef)``` | Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts |
| ```box_shelf_bracket_section(type, rows, cols, x, y)``` | Generates sections of the shelf bracket to allow it to be bigger than the printer |
| ```box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = undef)``` | Place children at the shelf screw positions |
| ```box_top(type)``` | Default top, can be overridden to customise |
| ```box_top_blank(type)``` | Generates a 2D template for the top sheet |
| ```grill(width, height, r = 1000, poly = false, h = 0)``` | A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling. |
@@ -3726,6 +4062,7 @@ Uses [fixing blocks](#fixing_block) and [corner blocks](#corner_block).
### Functions
| Function | Description |
|:--- |:--- |
| ```bbox(screw, sheets, base_sheet, top_sheet, span, size, name = "bbox", skip_blocks = [], star_washers = true)``` | Construct the property list for a butt_box |
| ```bbox_area(type)``` | Internal surdface area in m^2 |
| ```bbox_volume(type)``` | Internal volume in litres |
@@ -4193,6 +4530,11 @@ This allows the hinges and one set of screws to belong to one assembly and the o
| ```hinge_thickness(type)``` | Thickness of the leaves |
| ```hinge_width(type)``` | Width |
### Functions
| Function | Description |
|:--- |:--- |
| ```flat_hinge(name, size, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin)``` | Construct the property list for a flat hinge. |
### Modules
| Module | Description |
|:--- |:--- |
@@ -4254,6 +4596,7 @@ inserts don't grip well in rubber.
### Functions
| Function | Description |
|:--- |:--- |
| ```Foot(d, h, t, r, screw, slant = 10)``` | Construct a foot property list |
| ```insert_foot()``` | Default foot with insert |
### Modules
@@ -4424,6 +4767,7 @@ It can also have printed feet on the base with the screws doubling up to hold th
### Functions
| Function | Description |
|:--- |:--- |
| ```pbox(name, wall, top_t, base_t, radius, size, foot = false, screw = false, ridges = [0, 0])``` | Construct a printed box property list |
| ```pbox_inclusion(type)``` | How far the ledge for the base extends inwards |
| ```pbox_insert(type)``` | The insert for the base screws |
| ```pbox_screw(type)``` | Foot screw if got feet else base_screw |
@@ -4439,6 +4783,8 @@ It can also have printed feet on the base with the screws doubling up to hold th
| ```pbox_base(type)``` | Generate the STL for the base |
| ```pbox_base_screws(type, thickness = 0)``` | Place the screws and feet |
| ```pbox_inserts(type)``` | Place the inserts for the base screws |
| ```pbox_outer_shape(type)``` | 2D outer shape of the box |
| ```pbox_screw_positions(type)``` | Place children at base screw positions |
![printed_box](tests/png/printed_box.png)
@@ -4751,6 +5097,7 @@ be fully customised by passing a list of properties.
### Functions
| Function | Description |
|:--- |:--- |
| ```strap(width = 18, thickness = 2, screw = M3_pan_screw, panel_thickness = 3, extension = 25)``` | Construct a property list for a strap |
| ```strap_end_width(type = strap)``` | Width of the ends |
| ```strap_height(type)``` | Height of the ends |
| ```strap_insert(type)``` | The insert type |
@@ -4874,6 +5221,44 @@ Rounded fillet for adding to corners.
![fillet](tests/png/fillet.png)
<a href="#top">Top</a>
---
<a name="Gears"></a>
## Gears
Utilities for making involute gears.
Formulas from <https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html>
and <https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/>
```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```.
Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered
the practical minimum.
The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter.
[utils/gears.scad](utils/gears.scad) Implementation.
[tests/gears.scad](tests/gears.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| ```centre_distance(m, z1, z2, pa)``` | Calculate distance between centres taking profile shift into account |
| ```involute(r, u)``` | Involute of circle radius r at angle u in radians |
| ```profile_shift(z, pa)``` | Calculate profile shift for small gears |
### Modules
| Module | Description |
|:--- |:--- |
| ```involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20)``` | Calculate profile given module, number of teeth and pressure angle |
![gears](tests/png/gears.png)
<a href="#top">Top</a>
---
@@ -4935,12 +5320,22 @@ Maths utilities for manipulating vectors and matrices.
| Function | Description |
|:--- |:--- |
| ```angle_between(v1, v2)``` | Return the angle between two vectors |
| ```augment(m)``` | Augment a matrix by adding an identity matrix to the right |
| ```degrees(radians)``` | Convert degrees to radians |
| ```euler(R)``` | Convert a rotation matrix to a Euler rotation vector. |
| ```identity(n, x = 1)``` | Construct an arbitrary size identity matrix |
| ```invert(m)``` | Invert a matrix |
| ```nearly_zero(x)``` | True if x is close to zero |
| ```radians(degrees)``` | Convert radians to degrees |
| ```reverse(v)``` | Reverse a vector |
| ```rot2_z(a)``` | Generate a 2x2 matrix to rotate around z |
| ```rot3_z(a)``` | Generate a 3x3 matrix to rotate around z |
| ```rotate(a, v)``` | Generate a 4x4 rotation matrix, ```a``` can be a vector of three angles or a single angle around ```z```, or around axis ```v``` |
| ```rowswap(m, i, j)``` | Swap two rows of a matrix |
| ```scale(v)``` | Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally |
| ```solve(m, i = 0, j = 0)``` | Solve each row ensuring diagonal is not zero |
| ```solve_row(m, i)``` | Make diagonal one by dividing the row by it and subtract from other rows to make column zero |
| ```sqr(x)``` | Square x |
| ```transform(v, m)``` | Apply 4x4 transform to a 3 vector by extending it and cropping it again |
| ```transform_points(path, m)``` | Apply transform to a path |
| ```translate(v)``` | Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z``` |
@@ -4949,6 +5344,11 @@ Maths utilities for manipulating vectors and matrices.
| ```vec3(v)``` | Return a 3 vector with the first three elements of ```v``` |
| ```vec4(v)``` | Return a 4 vector with the first three elements of ```v``` |
### Modules
| Module | Description |
|:--- |:--- |
| ```position_children(list, t)``` | Position children if they are on the Z = 0 plane when transformed by t |
![maths](tests/png/maths.png)
@@ -5362,10 +5762,11 @@ The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is
### Modules
| Module | Description |
|:--- |:--- |
| ```drill(r, h = 100)``` | Make a cylinder for drilling holes suitable for CNC routing, set h = 0 for circle |
| ```drill(r, h = 100, center = true)``` | Make a cylinder for drilling holes suitable for CNC routing, set h = 0 for circle |
| ```poly_circle(r, sides = 0)``` | Make a circle adjusted to print the correct size |
| ```poly_cylinder(r, h, center = false, sides = 0)``` | 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_drill(r, h = 100, center = true)``` | Make a cylinder for drilling holes suitable for CNC routing if cnc_bit_r is non zero, otherwise a poly_cylinder. |
| ```poly_ring(or, ir, sides = 0)``` | Make a 2D ring adjusted to have the correct internal radius |
| ```poly_tube(or, ir, h, center = false)``` | Make a tube adjusted to have the correct internal radius |
| ```slot(r, l, h = 100)``` | Make a horizontal slot suitable for CNC routing, set h = 0 for 2D version |

View File

@@ -213,7 +213,7 @@ def parse_bom(file = "openscad.log", name = None):
main.assemblies[stack[-1]].add_part(s)
else:
if 'ERROR:' in line or 'WARNING:' in line:
print(line[:-1])
raise Exception(line[:-1])
return main
def usage():
@@ -221,53 +221,57 @@ def usage():
sys.exit(1)
def boms(target = None, assembly = None):
bom_dir = set_config(target, usage) + "bom"
if assembly:
bom_dir += "/accessories"
if not os.path.isdir(bom_dir):
try:
bom_dir = set_config(target, usage) + "bom"
if assembly:
bom_dir += "/accessories"
if not os.path.isdir(bom_dir):
os.makedirs(bom_dir)
else:
assembly = "main_assembly"
if os.path.isdir(bom_dir):
shutil.rmtree(bom_dir)
sleep(0.1)
os.makedirs(bom_dir)
else:
assembly = "main_assembly"
if os.path.isdir(bom_dir):
shutil.rmtree(bom_dir)
sleep(0.1)
os.makedirs(bom_dir)
#
# Find the scad file that makes the module
#
scad_file = find_scad_file(assembly)
if not scad_file:
raise Exception("can't find source for " + assembly)
#
# make a file to use the module
#
bom_maker_name = source_dir + "/bom.scad"
with open(bom_maker_name, "w") as f:
f.write("use <%s>\n" % scad_file)
f.write("%s();\n" % assembly);
#
# Run openscad
#
openscad.run("-D", "$bom=2", "-D", "$preview=true", "--hardwarnings", "-o", "openscad.echo", "-d", bom_dir + "/bom.deps", bom_maker_name)
os.remove(bom_maker_name)
print("Generating bom ...", end=" ")
#
# Find the scad file that makes the module
#
scad_file = find_scad_file(assembly)
if not scad_file:
raise Exception("can't find source for " + assembly)
#
# make a file to use the module
#
bom_maker_name = source_dir + "/bom.scad"
with open(bom_maker_name, "w") as f:
f.write("use <%s>\n" % scad_file)
f.write("%s();\n" % assembly);
#
# Run openscad
#
openscad.run("-D", "$bom=2", "-D", "$preview=true", "--hardwarnings", "-o", "openscad.echo", "-d", bom_dir + "/bom.deps", bom_maker_name)
os.remove(bom_maker_name)
print("Generating bom ...", end=" ")
main = parse_bom("openscad.echo", assembly)
main = parse_bom("openscad.echo", assembly)
if assembly == "main_assembly":
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
if assembly == "main_assembly":
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
for ass in main.assemblies:
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
bom = main.assemblies[ass]
print(bom.make_name(ass) + ":", file=f)
bom.print_bom(False, f)
for ass in main.assemblies:
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
bom = main.assemblies[ass]
print(bom.make_name(ass) + ":", file=f)
bom.print_bom(False, f)
data = [main.assemblies[ass].flat_data() for ass in main.ordered_assemblies]
with open(bom_dir + "/bom.json", 'w') as outfile:
json.dump(data, outfile, indent = 4)
data = [main.assemblies[ass].flat_data() for ass in main.ordered_assemblies]
with open(bom_dir + "/bom.json", 'w') as outfile:
json.dump(data, outfile, indent = 4)
print("done")
print("done")
except Exception as e:
print(str(e))
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 3: usage()
@@ -286,8 +290,4 @@ if __name__ == '__main__':
if assembly:
if assembly[-9:] != "_assembly": usage()
try:
boms(target, assembly)
except Exception as e:
print(str(e))
sys.exit(1)
boms(target, assembly)

View File

@@ -27,6 +27,7 @@ import c14n_stl
from set_config import *
from deps import *
from shutil import copyfile
import re
source_dirs = { "stl" : "platters", "dxf" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed" }
@@ -38,43 +39,54 @@ def plateup(target, part_type, usage = None):
top_dir = set_config(target, usage)
parts_dir = top_dir + part_type + 's'
target_dir = parts_dir + '/' + target_dirs[part_type]
source_dir = top_dir + source_dirs[part_type]
deps_dir = source_dir + "/deps"
if not os.path.isdir(source_dir):
return
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
if not os.path.isdir(deps_dir):
os.makedirs(deps_dir)
source_dir1 = source_dirs[part_type]
source_dir2 = top_dir + source_dirs[part_type]
#
# Decide which files to make
#
sources = [file for file in os.listdir(source_dir) if file.endswith('.scad')]
#
# Run OpenSCAD on the source files to make the targets
# Loop through source directories
#
used = []
for src in sources:
src_file = source_dir + '/' + src
part_file = target_dir + '/' + src[:-4] + part_type
dname = deps_name(deps_dir, src)
changed = check_deps(part_file, dname)
if changed:
print(changed)
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
if part_type == 'stl':
c14n_stl.canonicalise(part_file)
log_name = 'openscad.log'
else:
log_name = 'openscad.echo'
openscad.run_silent("-D$bom=1", "-o", log_name, src_file)
all_sources = []
for dir in [source_dir1, source_dir2]:
if not os.path.isdir(dir):
continue
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
#
# Add the files on the BOM to the used list
# Make the deps dir
#
with open(log_name) as file:
for line in file.readlines():
if line.startswith('ECHO: "~') and line.endswith('.' + part_type + '"\n'):
used.append(line[8:-2])
deps_dir = dir + "/deps"
if not os.path.isdir(deps_dir):
os.makedirs(deps_dir)
#
# Decide which files to make
#
sources = [file for file in os.listdir(dir) if file.endswith('.scad')]
all_sources += sources
#
# Run OpenSCAD on the source files to make the targets
#
for src in sources:
src_file = dir + '/' + src
part_file = target_dir + '/' + src[:-4] + part_type
dname = deps_name(deps_dir, src)
changed = check_deps(part_file, dname)
if changed:
print(changed)
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
if part_type == 'stl':
c14n_stl.canonicalise(part_file)
log_name = 'openscad.log'
else:
log_name = 'openscad.echo'
openscad.run_silent("-D$bom=1", "-o", log_name, src_file)
#
# Add the files on the BOM to the used list
#
with open(log_name) as file:
for line in file.readlines():
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
if match:
used.append(match.group(1))
#
# Copy file that are not included
#
@@ -90,7 +102,7 @@ def plateup(target, part_type, usage = None):
#
# Remove any cruft
#
targets = [file[:-4] + part_type for file in sources]
targets = [file[:-4] + part_type for file in all_sources]
for file in os.listdir(target_dir):
if file.endswith('.' + part_type):
if not file in targets and not file in copied:

View File

@@ -30,7 +30,7 @@ def usage():
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 2: usage()
if len(sys.argv) > 2: usage()
if len(sys.argv) > 1:
target = sys.argv[1]

30
tests/DIP.scad Normal file
View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../vitamins/dip.scad>
dips = [[6, "OPTO"], [8, "NE555"], [14, "74HC00"], [16, "ULN2003"], [18, "ULN2803"], [20, "74HC245"], [28, "ATMEGA328"]];
module dips()
for(i = [0 : len(dips) - 1]) let(dip = dips[i])
translate([i * inch(0.5), 0])
pdip(dip[0], dip[1], dip[0] > 20);
if($preview)
dips();

37
tests/LED_meters.scad Normal file
View File

@@ -0,0 +1,37 @@
//
// 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 <../utils/core/core.scad>
include <../utils/layout.scad>
include <../vitamins/led_meters.scad>
module led_meters()
layout([for(m = led_meters) meter_bezel_length(m)], 5) let(m = led_meters[$i])
if($preview) {
hflip()
meter(m, colour = "blue", value = "123");
if(!$i)
translate([0, meter_bezel_width(m)])
meter_assembly(m, value = "123");
}
else
meter_bezel(m);
led_meters();

View File

@@ -20,6 +20,8 @@ include <../core.scad>
include <../vitamins/microswitches.scad>
include <../vitamins/d_connectors.scad>
include <../vitamins/leds.scad>
include <../vitamins/axials.scad>
include <../vitamins/smds.scad>
use <../vitamins/pcb.scad>
@@ -32,7 +34,7 @@ TMC2130 = ["TMC2130", "TMC2130",
[
[ 10, 1, 0, "-2p54header", 8, 1 ,undef, "blue" ],
[ 10, 13, 0, "-2p54header", 8, 1],
[ 12, 7, 0, "-chip", 6, 4, 1, grey20 ],
[ 12, 7, 0, "-chip", 6, 4, 1, grey(20) ],
// mock up a heat sink
[ 10, 7, 0, "block", 9, 9, 2, TMC2130HeatSinkColor ],
[ 10, 11, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
@@ -56,38 +58,51 @@ test_pcb = ["TestPCB", "Test PCB",
// components
[
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 0, "trimpot10", true],
[ 20, -15, 90, "trimpot10", true],
[ 10, 2, 90, "smd_led", LED0805, "red"],
[ 13, 2, 90, "smd_led", LED0603, "orange"],
[ 16, 2, 90, "smd_res", RES1206, "1K"],
[ 19, 2, 90, "smd_res", RES0805, "1K"],
[ 22, 2, 90, "smd_res", RES0603, "1K"],
[ 10, 10, 0, "2p54header", 4, 1],
[ 25, 10, 0, "2p54header", 5, 1, undef, "blue" ],
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
[ 10, 20, 0, "2p54boxhdr", 4, 2],
[ 10, 30, 0, "2p54socket", 6, 1],
[ 25, 30, 0, "2p54socket", 4, 1, undef, undef, undef, "red" ],
[ 10, 40, 0, "chip", 10, 5, 1, grey20],
[ 25, 30, 0, "2p54socket", 4, 1, false, 0, false, "red" ],
[ 10, 40, 0, "chip", 10, 5, 1, grey(20)],
[ 5, 50, 0, "led", LED3mm, "red"],
[ 12, 50, 0, "led", LED5mm, "orange"],
[ 25, 50, 0, "led", LED10mm, "yellow"],
[ 10, 65, 180, "rj45"],
[ 8, 85, 180, "usb_A"],
[ 8, 105, 180, "usb_Ax2"],
[ 3, 125, 180, "usb_uA"],
[ 8, 140, 180, "usb_B"],
[ 5, 160, 0, "buzzer", 4.5, 8.5],
[ 20, 160, 0, "buzzer"],
[ 3, 140, 180, "usb_uA"],
[ 8, 155, 180, "usb_B"],
[ 8.5, 125, 180, "molex_usb_Ax2"],
[ 25, 200, 0, "buzzer", 4.5, 8.5],
[ 25, 218, 0, "buzzer"],
[ 8, 190, 180, "jack"],
[ 6, 200, 180, "barrel_jack"],
[ 5, 218, 180, "hdmi"],
[ 3, 235, 180, "mini_hdmi"],
[ 6, 175, 180, "uSD", [12, 11.5, 1.4]],
[ 65, 12, 0, "ax_res", res1_8, 1000],
[ 65, 17, 0, "ax_res", res1_4, 10000],
[ 65, 22, 0, "ax_res", res1_2, 100000],
[ 80, 12, 0, "ax_res", res1_8, 1000000, 1, inch(0.1)],
[ 80, 17, 0, "ax_res", res1_4, 100, 2, inch(0.1)],
[ 80, 22, 0, "ax_res", res1_2, 10, 10, inch(0.2)],
[ 60, 3, 0, "flex"],
[ 50, 15, 0, "flat_flex"],
[ 50, 15, -90, "flat_flex"],
[ 40, 15, -90, "flat_flex", true],
[ 60, 35, 0, "D_plug", DCONN9],
[ 50, 50, 0, "molex_hdr", 2],
[ 50, 60, 0, "jst_xh", 2],
[ 50, 70, 180, "term254", 3],
[ 63, 70, 180, "term254", 3, undef, grey20],
[ 63, 70, 180, "term254", 3, undef, grey(20)],
[ 75, 70, 180, "gterm508",2, undef, "blue"],
[ 50, 90, 180, "gterm35", 4, [1,2]],
@@ -97,7 +112,7 @@ test_pcb = ["TestPCB", "Test PCB",
[ 55, 110, 180, "gterm635", 2],
[ 75, 110, 180, "gterm635", 2, undef, "blue"],
[ 90, 110, 180, "gterm", gt_5x17, 2, undef, grey20],
[ 90, 110, 180, "gterm", gt_5x17, 2, undef, grey(20)],
[ 50, 130, 180, "term35", 4],
[ 70, 130, 180, "term35", 3, "lime"],
@@ -106,8 +121,10 @@ test_pcb = ["TestPCB", "Test PCB",
[ 50, 170, 0, "button_6mm"],
[ 50, 185, 0, "microswitch", small_microswitch],
[ 52, 200, 0, "pcb", 11, TMC2130 ],
[ 80, 200, 0, "pdip", 24, "27C32", true, inch(0.6) ],
[ 80, 170, 0, "pdip", 8, "NE555" ],
[ 52, 206, 0, "2p54socket", 8, 1 ],
[ 52, 194, 0, "2p54socket", 8, 1, undef, undef, undef, "red" ],
[ 52, 194, 0, "2p54socket", 8, 1, false, 0, false, "red" ],
[ 50, 220, 0, "standoff", 5, 4.5, 12.5, 2.54],
[ 50, 240, 0, "potentiometer"],
[ 75, 240, 0, "potentiometer", 7, 8],

View File

@@ -1,5 +1,5 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
@@ -17,23 +17,18 @@
// If not, see <https://www.gnu.org/licenses/>.
//
include <../utils/core/core.scad>
use <../utils/layout.scad>
use <../vitamins/meter.scad>
include <../vitamins/smds.scad>
module meters()
if($preview) {
meter_assembly();
module smds() {
layout([for(r = smd_resistors) smd_res_size(r).x], 1)
smd_resistor(smd_resistors[$i], ["1R0", "10M", "100K"][$i % 3]);
translate([0, meter_bezel_width() + 5])
vflip()
meter_assembly();
translate([0, 3])
layout([for(l = smd_leds) smd_led_size(l).x], 1)
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
}
translate([0, -meter_bezel_width()])
rotate([0, 180, 0])
meter(colour = "blue", value = "123");
}
else
meter_bezel();
meters();
if($preview)
smds();

52
tests/Swiss_clips.scad Normal file
View File

@@ -0,0 +1,52 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../utils/core/core.scad>
use <../utils/layout.scad>
include <../vitamins/swiss_clips.scad>
include <../vitamins/sheets.scad>
glass = glass2;
bed = AL6;
gap = sheet_thickness(bed) + sheet_thickness(glass);
module swiss_clips()
layout([for(s = swiss_clips) sclip_length(s)], 5, true)
let(s = swiss_clips[$i]) {
swiss_clip(s);
translate([0, 20]) {
swiss_clip(s, gap);
translate([20, 0, -5])
render_2D_sheet(bed)
difference() {
sheet_2D(bed, 40, 20, 1);
translate([-20, 0])
swiss_clip_hole(s, gap);
}
translate([20, 0, -1 + eps])
render_sheet(glass) sheet(glass, 40, 20, 1);
}
}
if($preview)
swiss_clips();

43
tests/axials.scad Normal file
View File

@@ -0,0 +1,43 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/pcbs.scad>
module axials() {
pcb = PERF60x40;
pcb(pcb);
pcb_grid(pcb, 0, 2)
rotate(90)
wire_link(0.8, inch(0.4));
for(i = [0 : len(ax_resistors) - 1]) {
pcb_grid(pcb, 2 * i + 2, 1 + [0, 0.5, 1.5][i])
rotate(90)
ax_res(ax_resistors[i], [1000, 47000, 8200][i], 5);
pcb_grid(pcb, 2 * i + 2, 6.5)
rotate(-90)
ax_res(ax_resistors[i], [2200, 39000, 8250][i], 1, inch(0.1));
}
}
if($preview)
axials();

View File

@@ -65,7 +65,7 @@ module belt_test() {
translate([-25, 0])
layout([for(b = belts) belt_width(b)], 10)
rotate([0, 90, 0])
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey90 : grey20, tooth_colour = $i%2==0 ? grey70 : grey50);
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
}
if($preview)

View File

@@ -23,7 +23,7 @@ use <../vitamins/insert.scad>
use <../printed/box.scad>
box = [M3_dome_screw, 3, DiBond, PMMA3, DiBond6, true, 150, 100, 70];
box = box(screw = M3_dome_screw, wall = 3, sheets = DiBond, top_sheet = PMMA3, base_sheet = DiBond6, feet = true, size = [150, 100, 70]);
include <../printed/box_assembly.scad>

View File

@@ -25,7 +25,7 @@ include <../printed/butt_box.scad>
$explode = 0;
box = [M3_dome_screw, DiBond, DiBond6, PMMA3, 250, 400, 300, 120];
box = bbox(screw = M3_dome_screw, sheets = DiBond, base_sheet = DiBond6, top_sheet = PMMA3, span = 250, size = [400, 300, 120]);
module bbox_assembly() _bbox_assembly(box);

31
tests/cameras.scad Normal file
View File

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

View File

@@ -41,9 +41,12 @@ module components() {
translate([0, 50])
TO220("Generic TO220 package");
translate([50, 50])
translate([40, 50])
panel_USBA();
translate([80, 50])
fack2spm();
translate([0,80])
thermal_cutouts();

View File

@@ -32,8 +32,8 @@ 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];
big_hinge = flat_hinge(name = "big", size = [width, depth, thickness], pin_d = pin_diameter, knuckle_d = knuckle_diameter, knuckles = knuckles, screw = M3_dome_screw, screws = screws, clearance = clearance, margin = margin);
small_hinge = flat_hinge(name = "small", size =[ 20, 16, 2], pin_d = 2.85, knuckle_d = 7, knuckles = 3, screw = M3_dome_screw, screws = 2, clearance = 0.2, margin = 0);
hinges = [small_hinge, big_hinge];

58
tests/gears.scad Normal file
View File

@@ -0,0 +1,58 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../utils/core/core.scad>
use <../utils/gears.scad>
// left gear teeth
z1 = 39; // [7 : 1 : 99]
// Right gear teeth
z2 = 7; // [7 : 1 : 99]
// Modulus
m = 2.0; // [0.1 : 0.1 : 5.0]
// Pressure angle
pa = 20; // [14.5, 20, 22.5, 25]
$show_numbers = false;
module gears() {
color(pp1_colour)
rotate($t * 360)
linear_extrude(eps, center = true, convexity = z1)
difference() {
involute_gear_profile(m, z1, pa);
circle(r = m * z1 / 10);
}
color(pp2_colour)
translate([centre_distance(m, z1, z2, pa), 0])
rotate(180 + 180 / z2 + -$t * 360 * z1 / z2)
linear_extrude(eps, center = true, convexity = z2)
difference() {
involute_gear_profile(m, z2, pa);
circle(r = m * z2 / 10);
}
}
rotate(is_undef($bom) ? 0 : [70, 0, 315])
gears();

29
tests/panel_meters.scad Normal file
View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
tests/png/axials.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

BIN
tests/png/cameras.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 108 KiB

BIN
tests/png/dip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
tests/png/gears.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 72 KiB

BIN
tests/png/led_meters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

BIN
tests/png/panel_meters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

BIN
tests/png/smds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

BIN
tests/png/swiss_clips.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -21,25 +21,25 @@ include <../core.scad>
use <../printed/foot.scad>
use <../printed/printed_box.scad>
foot = [13, 5, 2, 1, M3_pan_screw, 10];
foot = Foot(d = 13, h = 5, t = 2, r = 1, screw = M3_pan_screw);
module foot_stl() foot(foot);
wall = 2;
top_thickness = 2;
base_thickness = 2;
case_inner_rad = 8;
inner_rad = 8;
width = 80;
depth = 45;
height = 40;
box1 = ["box1", wall, top_thickness, base_thickness, false, M2_cap_screw, case_inner_rad, [8, 1], width, depth, height];
box2 = ["smooth_box", wall, top_thickness, base_thickness, foot, false, case_inner_rad, [0, 0], width, depth, height];
box1 = pbox(name = "box1", wall = wall, top_t = top_thickness, base_t = base_thickness, radius = inner_rad, size = [width, depth, height], screw = M2_cap_screw, ridges = [8, 1]);
box2 = pbox(name = "smooth_box", wall = wall, top_t = top_thickness, base_t = base_thickness, radius = inner_rad, size = [width, depth, height], foot = foot);
module box1_feet_positions() {
clearance = 2;
foot_r = foot_diameter(foot) / 2;
x_inset = case_inner_rad + foot_r - pbox_ridges(box1).y;
x_inset = inner_rad + foot_r - pbox_ridges(box1).y;
z_inset = foot_r + clearance;
h = height + base_thickness;

View File

@@ -25,15 +25,15 @@ use <../vitamins/nut.scad>
sheet = 3;
module rails()
layout([for(l = rails) carriage_width(rail_carriage(l))], 25)
layout([for(l = rails) carriage_width(rail_carriage(l))], 20)
rotate(-90) {
rail = rails[$i];
length = rail == MGN15 ? 260 : 200;
length = 200;
screw = rail_screw(rail);
nut = screw_nut(screw);
washer = screw_washer(screw);
rail_assembly(rail, length, rail_travel(rail, length) / 2, $i<2 ? grey20 : "green", $i<2 ? grey20 : "red");
rail_assembly(rail, length, rail_travel(rail, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));

View File

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

View File

@@ -36,29 +36,29 @@ module poly_cylinder(r, h, center = false, sides = 0) //! Make a cylinder adjust
extrude_if(h, center)
poly_circle(r, sides);
module poly_ring(or, ir) { //! Make a 2D ring adjusted to have the correct internal radius
cir = corrected_radius(ir);
module poly_ring(or, ir, sides = 0) { //! Make a 2D ring adjusted to have the correct internal radius
cir = corrected_radius(ir, sides);
filaments = (or - cir) / extrusion_width;
if(filaments > 3 + eps)
difference() {
circle(or);
poly_circle(ir);
poly_circle(ir, sides);
}
else
if(filaments >= 2)
difference() {
offset(or - cir)
poly_circle(ir);
poly_circle(ir, sides);
poly_circle(ir);
poly_circle(ir, sides);
}
else
difference() {
poly_circle(or);
poly_circle(or, sides);
offset(-squeezed_wall)
poly_circle(or);
poly_circle(or, sides);
}
}
@@ -66,9 +66,16 @@ module poly_tube(or, ir, h, center = false) //! Make a tube adjusted to have the
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)
module drill(r, h = 100, center = true) //! Make a cylinder for drilling holes suitable for CNC routing, set h = 0 for circle
extrude_if(h, center)
circle(r = corrected_radius(r, r2sides(r)));
module poly_drill(r, h = 100, center = true) //! Make a cylinder for drilling holes suitable for CNC routing if cnc_bit_r is non zero, otherwise a poly_cylinder.
if(cnc_bit_r)
drill(r, h, center = true);
else
poly_cylinder(r, h, center);
//
// Horizontal slot
//

96
utils/gears.scad Normal file
View File

@@ -0,0 +1,96 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Utilities for making involute gears.
//!
//! Formulas from <https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html>
//! and <https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/>
//!
//! ```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
//! Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```.
//!
//! Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered
//! the practical minimum.
//!
//! The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter.
//
include <core/core.scad>
use <maths.scad>
function involute(r, u) = let(a = degrees(u), c = cos(a), s = sin(a)) r * [c + u * s, s - u * c]; //! Involute of circle radius r at angle u in radians
function profile_shift(z, pa) = max(1 - z * sqr(sin(pa)) / 2, 0); //! Calculate profile shift for small gears
function centre_distance(m, z1, z2, pa) = //! Calculate distance between centres taking profile shift into account
let(x1 = profile_shift(z1, pa), x2 = profile_shift(z2, pa)) m * (z1/2 + z2/2 + x1 + x2);
module involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20) { //! Calculate profile given module, number of teeth and pressure angle
assert(z >= 7, "Gears must have at least 7 teeth.");
d = m * z; // Reference pitch circle diameter
x = profile_shift(z, pa); // Profile shift
c = is_undef(clearance) ? m / 6 : clearance; // Clearance from tip to root
base_d = d * cos(pa); // Base diameter
root_r = d / 2 + m * (x - 1) - c; // Root radius (dedendum circle radius)
tip_d = d + 2 * m * (1 + x); // Tip diameter (addendum circle diameter)
tpa = acos(base_d / tip_d); // Tip pressure angle
inva = tan(pa) - radians(pa); // Involute alpha
invaa = tan(tpa) - radians(tpa); // Involute alphaa
ta = PI / (2 * z) + 2 * x * tan(pa) / z + inva - invaa; // Tooth tip thickness angle, radians
crest_w = ta * tip_d; // Crest width
umax = sqrt(sqr(tip_d / base_d) - 1); // Max value of the involute parameter
base_r = base_d / 2;
p1 = involute(base_r, 0);
p2 = involute(base_r, umax);
dist = norm(p2 - p1); // distance between beginning and end of the involute curve
base_angle = 2 * acos((sqr(base_r) + sqr(tip_d / 2) - sqr(dist)) / base_r / tip_d) + degrees(2 * ta);
root_angle = 360 / z - base_angle;
root_circle_r = base_r * sin(root_angle / 2);
if(!is_undef($show_numbers) && $show_numbers) {
echo(d=d);
echo(base_d=base_d);
echo(tip_d=tip_d);
echo(tpa = tpa);
echo(inva=inva);
echo(invaa=invaa);
echo(x=x);
echo(ta=ta);
echo(crest_w=crest_w);
echo(umax = umax);
echo(base_angle=base_angle);
echo(root_angle=root_angle);
}
involute = [for(i = [0 : steps], u = umax * i / steps) involute(base_r, u)]; // involute for the bottom side of the tooth
truncated = [for(p = involute) if((rot2_z(-base_angle / 2) * p).y <= 0) p]; // removed any above the centreline to prevent overlap
reflection = reverse([for(p = truncated) rot2_z(base_angle) * [p.x, -p.y] ]); // reflect and rotate to make the top edge
root = reverse([for(a = [90 : 180 / steps : 270]) rot2_z(base_angle + root_angle / 2) * ([base_r, 0] + root_circle_r * [cos(a), sin(a)]) ]);
tooth = concat(truncated, reflection, root);
gear = concat([for(i = [0 : z - 1], p = tooth) rot2_z(i * 360 / z) * p]);
rotate(-base_angle / 2)
union() {
polygon(gear);
circle(root_r);
}
}

View File

@@ -28,6 +28,6 @@ function layout_offset(widths, i, gap = 2) = //! Calculate the offset for the ``
module layout(widths, gap = 2, no_offset = false) //! Layout children passing ```$i```
translate([no_offset ? -widths[0] / 2 : 0, 0])
for($i = [0 : len(widths) - 1])
for($i = [0 : 1 : len(widths) - 1])
translate([layout_offset(widths, $i, gap), 0])
children();

View File

@@ -20,7 +20,10 @@
//
//! Maths utilities for manipulating vectors and matrices.
//
function sqr(x) = x * x;
function sqr(x) = x * x; //! Square x
function radians(degrees) = degrees * PI / 180; //! Convert radians to degrees
function degrees(radians) = radians * 180 / PI; //! Convert degrees to radians
function translate(v) = let(u = is_list(v) ? len(v) == 2 ? [v.x, v.y, 0] //! Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z```
: v
@@ -63,6 +66,12 @@ function rot3_z(a) = //! Generate a 3x3 matrix to rotate around z
[ s, c, 0],
[ 0, 0, 1] ];
function rot2_z(a) = //! Generate a 2x2 matrix to rotate around z
let(c = cos(a),
s = sin(a))
[ [ c, -s],
[ s, c] ];
function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally
[
[s.x, 0, 0, 0],
@@ -90,3 +99,42 @@ function euler(R) = let(ay = asin(-R[2][0]), cy = cos(ay)) //! Convert a rotatio
cy ? [ atan2(R[2][1] / cy, R[2][2] / cy), ay, atan2(R[1][0] / cy, R[0][0] / cy) ]
: R[2][0] < 0 ? [atan2( R[0][1], R[0][2]), 180, 0]
: [atan2(-R[0][1], -R[0][2]), -180, 0];
module position_children(list, t) //! Position children if they are on the Z = 0 plane when transformed by t
for(p = list)
let(q = t * p)
if(abs(transform([0, 0, 0], q).z) < 0.01)
multmatrix(q)
children();
// Matrix inversion: https://www.mathsisfun.com/algebra/matrix-inverse-row-operations-gauss-jordan.html
function augment(m) = let(l = len(m), n = identity(l)) [ //! Augment a matrix by adding an identity matrix to the right
for(i = [0 : l - 1])
concat(m[i], n[i])
];
function rowswap(m, i, j) = [ //! Swap two rows of a matrix
for(k = [0 : len(m) - 1])
k == i ? m[j] : k == j ? m[i] : m[k]
];
function solve_row(m, i) = let(diag = m[i][i]) [ //! Make diagonal one by dividing the row by it and subtract from other rows to make column zero
for(j = [0 : len(m) - 1])
i == j ? m[j] / diag : m[j] - m[i] * m[j][i] / diag
];
function nearly_zero(x) = abs(x) < 1e-5; //! True if x is close to zero
function solve(m, i = 0, j = 0) = //! Solve each row ensuring diagonal is not zero
i < len(m) ?
assert(i + j < len(m), "matrix is singular")
solve(!nearly_zero(m[i + j][i]) ? solve_row(j ? rowswap(m, i, i + j) : m, i) : solve(m, i, j + 1), i + 1)
: m;
function invert(m) = let(n =len(m), m = solve(augment(m))) [ //! Invert a matrix
for(i = [0 : n - 1]) [
for(j = [n : 2 * n - 1])
each m[i][j]
]
];

138
vitamins/axial.scad Normal file
View File

@@ -0,0 +1,138 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Axial components for PCBs.
//
include <../utils/core/core.scad>
include <../utils/round.scad>
module wire_link(d, l, h = 1, tail = 3) { //! Draw a wire jumper link.
r = d;
$fn = 32;
color("silver") {
for(side = [-1, 1]) {
translate([side * l / 2, 0, -tail])
cylinder(d = d, h = tail + h - r);
translate([side * (l / 2 - r), 0, h - r])
rotate([90, 0, side * 90 - 90])
rotate_extrude(angle = 90)
translate([r, 0])
circle(d = d);
}
translate_z(h)
rotate([0, 90, 0])
cylinder(d = d, h = l - 2 * r, center = true);
}
}
function ax_res_wattage(type) = type[1]; //! Power rating
function ax_res_length(type) = type[2]; //! Body length
function ax_res_diameter(type)= type[3]; //! Body diameter
function ax_res_end_d(type) = type[4]; //! End cap diameter
function ax_res_end_l(type) = type[5]; //! End cap length
function ax_res_wire(type) = type[6]; //! Wire diameter
function ax_res_colour(type) = type[7]; //! Body colour
module orientate_axial(length, height, pitch, wire_d) { // Orient horizontal or vertical and add the wires
min_pitch = ceil((length + 1) / inch(0.1)) * inch(0.1);
lead_pitch = pitch ? pitch : min_pitch;
if(lead_pitch >= min_pitch) {
wire_link(wire_d, lead_pitch, height);
translate_z(height)
rotate([0, 90, 0])
children();
}
else {
wire_link(wire_d, lead_pitch, length + 0.7 + wire_d);
translate([-pitch / 2, 0, length / 2 + 0.2])
children();
}
}
module ax_res(type, value, tol = 5, pitch = 0) { //! Through hole axial resistor. If ```pitch``` is zero the minimum is used. If below the minimum the resistor is placed vertical.
vitamin(str("ax_res(", type[0], ", ", value, arg(tol, 5, "tol"), "): Resistor ", value, " Ohms ", tol, "% ",ax_res_wattage(type), "W"));
wire_d = ax_res_wire(type);
end_d = ax_res_end_d(type);
end_l = ax_res_end_l(type);
body_d = ax_res_diameter(type);
length = ax_res_length(type);
h = end_d / 2;
$fn = 32;
r = 0.3;
colours = ["gold", "silver", "black", "brown", "red", "orange", "yellow", "green", "blue", "violet", "grey", "white"];
exp = floor(log(value) + eps);
mult = exp - (len(str(value / pow(10, exp - 1))) > 2 ? 2 : 1);
digits = str(value / pow(10, mult));
bands = [
for(d = digits)
colours[ord(d) - ord("0") + 2],
colours[mult + 2],
tol == 1 ? "brown" :
tol == 2 ? "red" :
tol == 5 ? "gold" :
tol == 10 ? "silver" : "error"
];
module profile(o = 0)
intersection() {
offset(o) round(r)
union(){
translate([0, -length / 2])
square([body_d / 2, length]);
for(end = [-1, 1])
hull() {
translate([0, end * (length - end_l) / 2 - end_l / 2])
square([end_d / 2, end_l]);
translate([0, end * length / 2])
square([wire_d, 2 * r], center = true);
}
translate([-5, 0])
square([10 + wire_d, length + 4 * r], center = true);
}
translate([0, -50])
square([50, 100]);
}
orientate_axial(length, h, pitch, wire_d) {
color(ax_res_colour(type))
rotate_extrude()
profile();
for(i = [0 : len(bands) - 1])
color(bands[i])
rotate_extrude()
intersection() {
profile(eps);
translate([0, length / 2 - end_l / 2 - i * (length - end_l) / (len(bands) - 1)])
square([end_d + 1, (length - end_l) / len(bands) / 2], center = true);
}
}
}

30
vitamins/axials.scad Normal file
View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Axial components
//
res1_8 = ["res1_8", 0.125, 3.3, 1.35, 1.7, 1, 0.33, "#FAE3AC"];
res1_4 = ["res1_4", 0.25, 5.7, 1.85, 2.3, 1.5, 0.55, "#FAE3AC"];
res1_2 = ["res1_2", 0.5, 10, 3.25, 3.7, 1.8, 0.70, "#FAE3AC"];
ax_resistors = [res1_8, res1_4, res1_2];
use <axial.scad>

View File

@@ -16,11 +16,12 @@
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
BB624 = ["624", 4, 13, 5, "blue", 1.2, 1.2]; // 624 ball bearing for idlers
BB608 = ["608", 8, 22, 7, "OrangeRed", 1.4, 2.0]; // 608 bearings for wades
BB6200 = ["6200", 10, 30, 9, "black", 2.3, 3.6]; // 6200 bearings for KP pillow blocks
BB6201 = ["6201", 12, 32, 10, "black", 2.4, 3.7]; // 6201 bearings for KP pillow blocks
BB6808 = ["6808", 40, 52, 7, "black", 1.5, 1.6];
ball_bearings = [BB624, BB608, BB6200, BB6201, BB6808];
BBSMR95 = ["SMR95", 5, 9, 2.5, "silver", 0.5, 0.7]; // SMR95 ball bearing for FlexDrive extruder
BB624 = ["624", 4, 13, 5, "blue", 1.2, 1.2]; // 624 ball bearing for idlers
BB608 = ["608", 8, 22, 7, "OrangeRed", 1.4, 2.0]; // 608 bearings for wades
BB6200 = ["6200", 10, 30, 9, "black", 2.3, 3.6]; // 6200 bearings for KP pillow blocks
BB6201 = ["6201", 12, 32, 10, "black", 2.4, 3.7]; // 6201 bearings for KP pillow blocks
BB6808 = ["6808", 40, 52, 7, "black", 1.5, 1.6];
ball_bearings = [BBSMR95, BB624, BB608, BB6200, BB6201, BB6808];
use <ball_bearing.scad>

View File

@@ -41,7 +41,7 @@ function no_point(str) = chr([for(c = str) if(c == ".") ord("p") else ord(c)]);
// We model the belt path at the pitch radius of the pulleys and the pitch line of the belt to get an accurate length.
// The belt is then drawn by offseting each side from the pitch line.
//
module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20), tooth_colour = grey(50)) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
width = belt_width(type);
pitch = belt_pitch(type);
thickness = belt_thickness(type);

View File

@@ -39,7 +39,7 @@ function blower_top(type) = type[14]; //! Thickness of the top
function blower_wall(type) = type[15]; //! Side wall thickness
function blower_lug(type) = type[16]; //! Height of the lugs
fan_colour = grey20;
fan_colour = grey(20);
module blower(type) { //! Draw specified blower
length = blower_length(type);

View File

@@ -46,7 +46,7 @@ module square_button(type, colour = "yellow") { //! Draw square button with spec
pitch = (w/ 2 - wall - rivit * 0.75);
stem = square_button_cap_stem(type);
color(grey20) {
color(grey(20)) {
rounded_rectangle([w, w, h - 0.5], r = wall, center = false);
for(x = [-1, 1], y = [-1, 1])

89
vitamins/camera.scad Normal file
View File

@@ -0,0 +1,89 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! PCB cameras.
//
include <../utils/core/core.scad>
use <pcb.scad>
function camera_pcb(type) = type[2]; //! The PCB part of the camera
function camera_lens_offset(type) = type[3]; //! Offset of the lens center from the PCB centre
function camera_lens(type) = type[4]; //! Stack of lens parts, can be round, rectanular or rounded rectangular, with optional tapered aperture
function camera_connector_pos(type) = type[5]; //! The flex connector block for the camera itself's position
function camera_connector_size(type)= type[6]; //! The flex connector block for the camera itself's size
module camera_lens(type, offset = 0) //! Draw the lens stack, with optional offset for making a clearance hole
color(grey(20))
translate(camera_lens_offset(type))
for(p = camera_lens(type)) {
size = p[0];
r = p[1] + offset;
app = p[2];
if(size.x)
rounded_rectangle(size + [2 * offset, 2 * offset, round_to_layer(offset)], r, center = false);
else
translate_z(size.y)
rotate_extrude()
difference() {
square([r, size.z + round_to_layer(offset)]);
if(app)
translate([0, size.z])
hull() {
translate([0, -eps])
square([app.y, eps * 2]);
translate([0, -app.z])
square([app.x, app.z]);
}
}
}
module camera(type) { //! Draw specified PCB camera
vitamin(str("camera(", type[0], "): ", type[1]));
pcb = camera_pcb(type);
not_on_bom()
pcb(pcb);
translate_z(pcb_thickness(pcb)) {
camera_lens(type);
conn = camera_connector_size(type);
if(conn) {
pos = camera_connector_pos(type);
color(grey(20))
translate(pos)
rounded_rectangle(conn, 0.5, center = false);
flex = [5, 0.1];
color("orange")
hull() {
translate_z(flex.y /2)
translate(camera_lens_offset(type) + [0, camera_lens(type)[0][0].y / 2])
cube([flex.x, eps, flex.y], center = true);
translate_z(conn.z - flex.y)
translate([camera_lens_offset(type).x, pos.y] - [0, conn.y / 2])
cube([flex.x, eps, flex.y], center = true);
}
}
}
}

73
vitamins/cameras.scad Normal file
View File

@@ -0,0 +1,73 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <smds.scad>
rpi_camera_v1_pcb = ["", "", 25, 24, 1, 0, 2.1, 0, "green", false, [[2, -2], [-2, -2], [2, 9.6], [-2, 9.6]],
[
[12, 3.25, 0, "-flat_flex", true],
[-4.5, -5, 0, "smd_led", LED0603, "red"],
[-5.5, -4, 0, "smd_res", RES0603, "1K2"],
],
[]];
rpi_camera_v1 = ["rpi_camera_v1", "Raspberry Pi camera V1", rpi_camera_v1_pcb, [0, 9.6 - 12],
[
[[8, 8, 3], 0],
[[0, 0, 4], 7.5 / 2],
[[0, 0, 5], 5.5 / 2, [1.5/2, 2/2, 0.5]],
],
[0, 12 - 1.5 - 2.5], [8, 5, 1]
];
rpi_camera_v2_pcb = ["", "", 25, 23.862, 1, 2, 2.2, 0, "green", false, [[2, -2], [-2, -2], [2, -14.5], [-2, -14.5]],
[
[12.5, 2.75, 0, "-flat_flex", true],
],
[]];
rpi_camera_v2 = ["rpi_camera_v2", "Raspberry Pi camera V2", rpi_camera_v2_pcb, [0, 9.6 - 12],
[
[[8.5, 8.5, 3], 0],
[[0, 0, 4], 7.5 / 2],
[[0, 0, 5], 5.5 / 2, [1.5/2, 2/2, 0.5]],
],
[-13.8 + 12.5, 23.862 / 2 - 4.7], [8.5, 4, 1]
];
rpi_camera_pcb = ["", "", 36, 36, 1.6, 0, 3.2, 0, "green", false, [[3.5, -3.5], [-3.5, -3.5], [3.5, 3.5], [-3.5, 3.5]],
[
[18, 4.25, 0, "-flat_flex", true],
[-3.8, -7.8, 0, "smd_led", LED0805, "red"],
],
[]];
rpi_camera = ["rpi_camera", "Raspberry Pi focusable camera", rpi_camera_pcb, [0, 0],
[
[[13, 13, 3], 0],
[[22, 4, 3], 2 - eps],
[[0, 0, 8.5], 7],
[[0, 0, 12], 6],
[[0, 11, 4.3], 14 / 2, [8/2, 11/2, 1]],
],
[0, 18 - 1.5 - 2.5], [8, 5, 1.6]
];
cameras = [rpi_camera_v1, rpi_camera, rpi_camera_v2];
use <camera.scad>

View File

@@ -33,7 +33,7 @@ function circlip_a(type) = type[5]; //! Size of the lugs
function circlip_b(type) = type[6]; //! Widest part of the taper
function circlip_d5(type) = type[7]; //! Plier hole diameter
circlip_colour = grey20;
circlip_colour = grey(20);
closed_angle = 25;
module internal_circlip(type, open = 0) { //! Draw specified internal circlip, open = 0, for nominal size installed, 1 for relaxed uninstalled, -1 for squeezed to install

View File

@@ -28,6 +28,7 @@ include <../core.scad>
include <tubings.scad>
include <spades.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/dogbones.scad>
function resistor_length(type) = type[2]; //! Body length
function resistor_diameter(type) = type[3]; //! Body diameter
@@ -447,3 +448,75 @@ module thermal_cutout(type) { //! Draw specified thermal cutout
thermal_cutout_hole_positions(type)
children();
}
function fack2spm_bezel_size() = [19.2, 35.5, 2.6, 2]; //! FACK2SPM Bezel dimensions
module fack2spm_hole_positions() //! Place children at the FACK2SPM mounting hole positions
for(end = [-1, 1])
translate([0, end * 28.96 / 2])
children();
function fack2spm_screw() = M3_dome_screw; //! Screw type for FACK2SPM
module fack2spm_holes(h = 0) { //! Cut the holes for a FACK2SPM
fack2spm_hole_positions()
drill(screw_clearance_radius(fack2spm_screw()), h);
dogbone_rectangle([17.15, 22.86, h]);
}
module fack2spm() { //! Draw a FACK2SPM Cat5E RJ45 shielded panel mount coupler
vitamin("tuk_fack2spm(): TUK FACK2SPM Cat5E RJ45 shielded panel mount coupler");
bezel = fack2spm_bezel_size();
body = [16.8, 22.8, 9.8];
socket = [14.5, 16.1, 29.6];
y_offset = -(19.45 - 16.3) / 2;
plug = [12, 6.8, 10];
plug_y = y_offset - socket.y / 2 + 4 + plug.y / 2;
tab1 = [4, 3];
tab2 = [6.3, 1.6];
module socket()
translate([0, y_offset])
square([socket.x, socket.y], center = true);
color("silver") {
linear_extrude(bezel.z)
difference() {
rounded_square([bezel.x, bezel.y], bezel[3]);
fack2spm_hole_positions()
circle(d = 3.15);
socket();
}
translate_z(bezel.z - body.z)
linear_extrude(body.z - eps)
difference() {
square([body.x, body.y], center = true);
socket();
}
translate_z(bezel.z - socket.z)
linear_extrude(socket.z - 0.1)
difference() {
offset(-0.1) socket();
translate([0, plug_y]) {
square([plug.x, plug.y], center = true);
translate([0, -plug.y / 2]) {
square([tab1.x, 2 * tab1.y], center = true);
square([tab2.x, 2 * tab2.y], center = true);
}
}
}
translate([0, plug_y, -socket.z / 2])
cube([plug.x, plug.y, socket.z - 2 * plug.z], center = true);
}
}

View File

@@ -23,9 +23,9 @@
include <../utils/core/core.scad>
use <../utils/thread.scad>
d_pillar_colour = grey90;
d_plug_shell_colour = grey80;
d_plug_insulator_colour = grey20;
d_pillar_colour = grey(90);
d_plug_shell_colour = grey(80);
d_plug_insulator_colour = grey(20);
function d_flange_length(type) = type[1]; //! Length of the flange
function d_lengths(type) = type[2]; //! Lengths of the D for plug and socket

181
vitamins/dip.scad Normal file
View File

@@ -0,0 +1,181 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Dual inline IC packages and sockets
//
include <../utils/core/core.scad>
pdip_pin = [0.25, 2.54, 0.5, 3.0, 1.524, 1];
function pdip_pin_t(type) = type[0]; //! Pin thickness
function pdip_pin_s(type) = type[1]; //! Height above seating plane
function pdip_pin_w(type) = type[2]; //! Pin width
function pdip_pin_h(type) = type[3]; //! Pin height
function pdip_pin_W(type) = type[4]; //! Pin shoulder width
function pdip_pin_n(type) = type[5]; //! Pin neck
module pdip_pin(type, l, end) { //! Draw a pin
w = pdip_pin_w(type);
t = pdip_pin_t(type);
h = pdip_pin_h(type);
W = pdip_pin_W(type);
s = pdip_pin_s(type);
n = pdip_pin_n(type);
slope = (W - n);
r = t;
x0 = end < 0 ? -w / 2 : -W / 2;
n0 = end < 0 ? -w / 2 : -n / 2;
W1 = end != 0 ? W / 2 + w / 2 : W;
n1 = end != 0 ? n / 2 + w / 2 : n;
color("silver") {
translate([x0, -r - t / 2 - l, s - t / 2])
cube([W1, l, t]);
translate([x0, -r - t / 2, s - r - t / 2])
rotate([90, 0, 90])
rotate_extrude(angle = 90, $fn = 32)
translate([r, 0])
square([t, W1]);
translate_z(-h)
rotate([90, 0, 0])
linear_extrude(t, center = true) {
translate([-w / 2, 0])
square([w, h]);
hull() {
translate([x0, h + slope])
square([W1, s - t / 2 - r - slope]);
translate([n0, h])
square([n1, eps]);
}
}
}
}
module dil_pin_positions(rows, w, pitch)
for(i = [0 : rows - 1], $side = [-1, 1], $x = i * pitch - (rows - 1) * pitch / 2)
translate([0, $x])
rotate($side * 90)
translate([0, w / 2])
children();
module dil_socket(rows, w, pitch = inch(0.1)) {
vitamin(str("dil_socket(", rows, ", ", w, arg(pitch, inch(0.1), "pitch"), "): DIL socket ", rows * 2, " x ", w / inch(1), "\""));
h = 4;
h2 = 6;
t = 0.8;
length = rows * pitch;
width = w + pitch;
hole = [0.8, 0.5];
pin_l = 3;
color(grey(20)) {
linear_extrude(h)
difference() {
square([width, length], center = true);
square([w - pitch, length - 2 * pitch], center = true);
dil_pin_positions(rows, w, pitch)
square(hole, center = true);
translate([0, rows * pitch / 2])
circle(d = 1.5);
}
rotate([90, 0, 0])
linear_extrude(length, center = true)
for(side = [-1, 1])
hull() {
t2 = pitch / 2 - hole.y / 2;
translate([side * (width / 2 - t / 2) - t / 2, 0])
square([t, h2]);
translate([side * (width / 2 - t2 / 2) - t2 / 2, 0])
square([t2, h]);
}
}
color("silver")
dil_pin_positions(rows, w, pitch)
translate_z(-pin_l / 2)
cube([0.5, 0.25, pin_l], center = true);
translate_z(h)
children();
}
module dip(n, part, size, w, pitch, pin) { //! Draw DIP package
D = [3, 0.6];
translate_z(pdip_pin_s(pin)) {
color(grey(20)) {
rotate([90, 0, 0])
linear_extrude(size.x, center = true)
difference() {
hull() {
square([size.y, pdip_pin_t(pin)], center = true);
square([size.y - 1, size.z], center = true);
}
square([D.x + 1, size.z + 1], center = true);
}
translate_z(-D.y / 2)
cube([D.x + 1 + eps, size.x, size.z - D.y], center = true);
linear_extrude(size.z / 2)
difference() {
square([D.x + 1 + eps, size.x], center = true);
translate([0, size.x / 2])
circle(d = D.x);
}
}
color("white")
translate([0, -D.x / 4, size.z / 2])
rotate(-90)
linear_extrude(eps)
resize([(size.x - D.x / 2) * 0.75, size.y / 3])
text(part, halign = "center", valign = "center");
}
l = size.x / 2 - pdip_pin_W(pin) / 2;
dil_pin_positions(n, w, pitch)
pdip_pin(pin, w / 2, $side * (abs($x) > l ? sign($x) : 0));
}
module pdip(pins, part, socketed, w = inch(0.3), pitch = inch(0.1)) { //! Draw standard 0.1" PDIP IC package
vitamin(str("pdip(", pins, ", ", part, arg(w, inch(0.3), "w"), arg(pitch, inch(0.1), "pitch"),"): IC ", part, " PDIP", pins));
n = ceil(pins / 2);
k = in([4, 8], n) ? n - 1 : n;
length = k * pitch + pitch / 2;
width = w - pitch / 2;
height = 3;
if(socketed)
dil_socket(n, w, pitch)
dip(n, part, [length, width, height], w, pitch, pdip_pin);
else
dip(n, part, [length, width, height], w, pitch, pdip_pin);
}

View File

@@ -122,7 +122,7 @@ module extrusion(type, length, center = true, cornerHole = false) { //! Draw the
vitamin(str("extrusion(", type[0], ", ", length, arg(cornerHole, false, "cornerHole"), "): Extrusion ", type[0], " x ", length, "mm"));
color(grey90)
color(grey(90))
linear_extrude(length, center = center)
extrusion_cross_section(type, cornerHole);
}

View File

@@ -28,7 +28,7 @@ use <nut.scad>
use <washer.scad>
use <../utils/tube.scad>
fan_colour = grey20;
fan_colour = grey(20);
function fan_width(type) = type[0]; //! Width of square
function fan_depth(type) = type[1]; //! Depth of fan

View File

@@ -61,7 +61,7 @@ module fuseholder(thickness) { //! Fuseholder with nut in place for specified pa
//
// Nut
//
colour = grey40;
colour = grey(40);
vflip()
translate_z(thickness)
explode(height) {

View File

@@ -33,8 +33,8 @@
// h t s t t t
// h
//
JHeadMk4 = ["JHeadMk4", jhead, "JHead MK4", 64, 5.1, 16, 50, grey20, 12, 4.64, 14, [0, 2.94, -5], 20, 20];
JHeadMk5 = ["JHeadMk5", jhead, "JHead MK5", 51.2, 5.1, 16, 40, grey20, 12, 4.64, 13, [0, 2.38, -5], 20, 20];
JHeadMk4 = ["JHeadMk4", jhead, "JHead MK4", 64, 5.1, 16, 50, grey(20), 12, 4.64, 14, [0, 2.94, -5], 20, 20];
JHeadMk5 = ["JHeadMk5", jhead, "JHead MK5", 51.2, 5.1, 16, 40, grey(20), 12, 4.64, 13, [0, 2.38, -5], 20, 20];
E3Dv5 = ["E3Dv5", e3d, "E3D V5 direct", 70, 3.7, 16, 50.1, "silver", 12, 6, 15, [1, 5, -4.5], 14.5, 28];
E3Dv6 = ["E3Dv6", e3d, "E3D V6 direct", 62, 3.7, 16, 42.7, "silver", 12, 6, 15, [1, 5, -4.5], 14, 21];
E3D_clone = ["E3D_clone", e3d, "E3D clone aliexpress",66, 6.8, 16, 46, "silver", 12, 5.6, 15, [1, 5, -4.5], 14.5, 21];

View File

@@ -29,7 +29,7 @@ flange_d = 45.5;
flange_t = 1.5;
flange_d2 = 32;
flange_t2 = 2;
apperture_d = 24.7;
aperture_d = 24.7;
hygrometer_hole_r = 21.3;
slot_w = 5.5;
@@ -51,12 +51,12 @@ module hygrometer() { //! Draw a hygrometer
vitamin("hygrometer(): Mini LCD Digital Thermometer / Hygrometer");
explode(40) {
color(grey30)
color(grey(30))
rotate_extrude()
polygon([
[0, 0],
[apperture_d / 2, 0],
[apperture_d / 2, flange_t],
[aperture_d / 2, 0],
[aperture_d / 2, flange_t],
[flange_d2 / 2, flange_t2],
[flange_d / 2, flange_t],
[flange_d / 2, 0],
@@ -66,21 +66,21 @@ module hygrometer() { //! Draw a hygrometer
]);
color("#94A7AB")
cylinder(d = apperture_d, h = eps);
cylinder(d = aperture_d, h = eps);
color("black")
linear_extrude(0.2, center = true) {
translate([0, 3])
text("20_4", font = "7 segment", valign = "bottom", halign = "center", size = apperture_d / 6);
text("20_4", font = "7 segment", valign = "bottom", halign = "center", size = aperture_d / 6);
translate([7, 3])
text("C", font = "7 segment", valign = "bottom", halign = "center", size = apperture_d / 8);
text("C", font = "7 segment", valign = "bottom", halign = "center", size = aperture_d / 8);
translate([-1.9, 0.5])
text("50", font = "7 segment", valign = "top", halign = "center", size = apperture_d / 2.7);
text("50", font = "7 segment", valign = "top", halign = "center", size = aperture_d / 2.7);
translate([0, -apperture_d / 6])
text(" %", font = "Arial", valign = "center", halign = "center", size = apperture_d / 6);
translate([0, -aperture_d / 6])
text(" %", font = "Arial", valign = "center", halign = "center", size = aperture_d / 6);
}
}

View File

@@ -134,7 +134,7 @@ module iec(type) { //! Draw specified IEC connector
}
}
color(grey20) {
color(grey(20)) {
// Flange
flange_t = iec_flange_t(type);
linear_extrude(flange_t)

View File

@@ -25,7 +25,7 @@ use <../utils/tube.scad>
use <washer.scad>
use <ball_bearing.scad>
kp_pillow_block_colour = grey70;
kp_pillow_block_colour = grey(70);
function kp_diameter(type) = type[1]; //! Rod hole diameter
function kp_hole_offset(type) = type[2]; //! Rod hole offset

148
vitamins/led_meter.scad Normal file
View File

@@ -0,0 +1,148 @@
//
// 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/>.
//
//
//! LED voltmeter and ammeter modules available from China and a printed bezel that allows the voltmeter to be mounted into a
//! CNC cut panel. The meter is held in the bezel by melting the stakes with a soldering iron set to 200&deg;C. The
//! bezel is fixed in the panel with hot glue.
//!
//! The 7 SEGMENT.TTF font from the [docs](docs) directory needs to be installed to get realistic digits.
//
include <../utils/core/core.scad>
use <axial.scad>
function meter_size(type) = type[1]; //! Size of display
function meter_offset(type) = type[2]; //! Display position, 0 = center, +1 = top
function meter_pcb_size(type) = type[3]; //! PCB size excluding lugs
function meter_lug_size(type) = type[4]; //! Lug length and width
function meter_lug_offset(type) = type[5]; //! Lug position, 0 = center, +1 = top
function meter_hole_pitch(type) = type[6]; //! Lug hole pitch
function meter_hole_radius(type) = type[7]; //! Lug hole radius
function meter_shunt(type) = type[8]; //! Ammeter shunt wire
function meter_pos(type) = (meter_pcb_size(type).y - meter_size(type).y) * meter_offset(type) / 2;
function meter_lug_pos(type) = (meter_pcb_size(type).y - meter_lug_size(type).y) * meter_lug_offset(type) / 2;
module meter_hole_positions(type) //! Position children over the holes
for(side = [-1, 1])
translate([side * meter_hole_pitch(type) / 2, meter_lug_pos(type)])
children();
function meter_shunt_y(type) = meter_pos(type) - meter_pcb_size(type).y / 2; //! Shunt y coordinate
module meter(type, colour = "red", value = "888", display_colour = false) //! Draw a meter with optional colour and display value
{
vitamin(str("meter(", type[0], arg(colour, "red", "colour"), "): LED ", meter_shunt(type) ? "am" : "volt", "meter ", colour));
size = meter_size(type);
color("grey")
translate([0, meter_pos(type), size.z / 2])
cube(size, center = true);
color("green")
translate_z(meter_size(type).z)
linear_extrude(meter_pcb_size(type).z)
difference() {
union() {
square([meter_pcb_size(type).x, meter_pcb_size(type).y], center = true);
translate([0, meter_lug_pos(type)])
square([meter_lug_size(type).x, meter_lug_size(type).y], center = true);
}
meter_hole_positions(type)
circle(meter_hole_radius(type));
}
color(display_colour ? display_colour : colour)
linear_extrude(0.2, center = true)
mirror([1, 0, 0])
translate([-size.x / 2 + 1, meter_pos(type)])
resize([size.x - 2, size.y - 2]) {
text(value, font = "7 segment", valign = "center");
square(eps); // Tiny invisible pixel at the origin so numbers starting with 1 scale correctly.
}
shunt = meter_shunt(type);
if(shunt)
translate([0, meter_shunt_y(type), size.z])
vflip()
color("#b87333")
wire_link(shunt.y, shunt.x, shunt.z, tail = 2);
}
clearance = 0.1;
overlap = 1;
flange_t = 1;
function meter_bezel_wall(type) = (meter_lug_size(type).x - meter_size(type).x) / 2; //! Printed bezel wall thickness
function meter_bezel_rad(type) = meter_bezel_wall(type); //! Printed bezel corner radius
function meter_bezel_length(type) = meter_size(type).x + 2 * (meter_bezel_wall(type) + overlap); //! Printed bezel length
function meter_bezel_width(type) = meter_size(type).y + 2 * (meter_bezel_wall(type) + overlap); //! Printed bezel width
module meter_bezel_hole(type, h = 100) { //! Make a hole to fit the meter Bezel
wall = meter_bezel_wall(type) + clearance;
rad = meter_bezel_rad(type) + clearance;
l = meter_size(type).x;
w = meter_size(type).y;
extrude_if(h)
rounded_square([l + 2 * wall, w + 2 * wall], rad);
}
module meter_bezel(type) { //! Generate the STL for the meter bezel
stl("meter_bezel");
wall = meter_bezel_wall(type);
rad = meter_bezel_rad(type);
l = meter_size(type).x;
w = meter_size(type).y;
h = meter_size(type).z;
union() {
linear_extrude(h)
difference() {
rounded_square([l + 2 * wall, w + 2 * wall], rad);
square([l + 2 * clearance, w + 2 * clearance], center = true);
}
linear_extrude(flange_t)
difference() {
rounded_square([l + 2 * wall + 2 * overlap, w + 2 * wall + 2 * overlap], rad + overlap);
square([l + 2 * clearance, w + 2 * clearance], center = true);
}
translate([0, -meter_pos(type)])
meter_hole_positions(type)
cylinder(r = meter_hole_radius(type), h = h + meter_pcb_size(type).z * 2);
}
}
module meter_assembly(type, colour = "red", value = "888", display_colour = false) { //! Meter assembled into the bezel
hflip()
translate_z(-flange_t) {
color("dimgrey") meter_bezel(type);
translate([0, -meter_pos(type)])
meter(type, colour, value, display_colour);
}
}

26
vitamins/led_meters.scad Normal file
View File

@@ -0,0 +1,26 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
// display size offset pcb size lug size offset hole pitch and size
led_meter = ["led_meter", [22.72, 10.14, 6.3], 0, [22.72, 11.04, 0.96], [30, 4.2], 0, 26, 2.2 / 2, false];
led_ameter = ["led_ameter", [22.72, 14.05, 7.3], 1, [27.5, 18.6, 1.2], [35, 6.25], 1, 29, 3.0 / 2, [15.5, 1.5, 7.75]];
led_meters = [led_meter, led_ameter];
use <led_meter.scad>

View File

@@ -137,7 +137,6 @@ module light_strip(type, segs = undef) { //! Draw specified light strip, segs ca
linear_extrude(0.55 + eps)
resistor_positions()
square([2.1, 1.5 + 2 * eps], center = true);
}
if(show_rays)
@@ -148,8 +147,9 @@ wall = 1.8;
clearance = 0.2;
function light_strip_clip_slot(light) = light_strip_width(light) + clearance; //! Clip slot size
function light_strip_clip_depth(light) = 10; //! Depth of the clip
function light_strip_clip_length(light) = light_strip_clip_slot(light) + 2 * wall; //! Outside length
function light_strip_clip_width(light) = light_strip_depth(light) + 2 * wall; //! Outside width
function light_strip_clip_length(light) = light_strip_clip_slot(light) + 2 * wall; //! Outside length of clip
function light_strip_clip_width(light) = light_strip_depth(light) + 2 * wall; //! Outside width of clip
function light_strip_clip_wall() = wall; //! Clip wall thickness
module light_strip_clip(light) { //! Make a clip to go over the strip to be incorporated into a bracket
linear_extrude(light_strip_clip_depth(light), convexity = 2)

View File

@@ -26,7 +26,7 @@
// e s c
// s k
Rigid5050 = ["Rigid5050", "rigid SMD5050 low profile", 500, 36, 3, 14.4, 7, 10.4, 0.9, 1.2];
RIGID5050 = ["RIGID5050", "rigid SMD5050" , 500, 36, 3, 14.4, 8.6, 10.4, 0.9, 1.6];
RIGID5050 = ["RIGID5050", "rigid SMD5050" , 500, 36, 3, 14.4, 8.6, 9.8, 0.8, 1.6];
light_strips = [Rigid5050, RIGID5050,];

View File

@@ -24,9 +24,9 @@ include <../utils/core/core.scad>
use <../utils/tube.scad>
bearing_colour = grey70;
groove_colour = grey60;
seal_colour = grey30;
bearing_colour = grey(70);
groove_colour = grey(60);
seal_colour = grey(30);
function bearing_length(type) = type[1]; //! Total length

View File

@@ -1,130 +0,0 @@
//
// 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/>.
//
//
//! LED volt meter modules available from China and a printed bezel that allows them to be mounted into a
//! CNC cut panel. The meter is held in the bezel by melting the stakes with a soldering iron set to 200&deg;C. The
//! bezel is fixed in the panel with hot glue.
//!
//! The 7 SEGMENT.TTF font from the [docs](docs) directory needs to be installed to get realistic digits.
//
include <../utils/core/core.scad>
led_meter = ["led_meter", 22.72, 10.14, 6.3, 22.72, 11.04, 0.96, 30, 4.2, 26, 2.2 / 2];
function meter() = led_meter; //! Default meter type
function meter_length(type = led_meter) = type[1]; //! Length of body
function meter_width(type = led_meter) = type[2]; //! Width of body
function meter_height(type = led_meter) = type[3]; //! Height of body excluding PCB
function meter_pcb_length(type = led_meter) = type[4]; //! PCB length excluding lugs
function meter_pcb_width(type = led_meter) = type[5]; //! PCB width
function meter_pcb_thickness(type = led_meter) = type[6]; //! PCB thickness
function meter_lug_length(type = led_meter) = type[7]; //! PCB length including lugs
function meter_lug_width(type = led_meter) = type[8]; //! Lug width
function meter_hole_pitch(type = led_meter) = type[9]; //! Lug hole pitch
function meter_hole_radius(type = led_meter) = type[10]; //! Lug hole radius
module meter_hole_positions(type = led_meter) //! Position children over the holes
for(side = [-1, 1])
translate([side * meter_hole_pitch(type) / 2, 0])
children();
module meter(type = led_meter, colour = "red", value = "888", display_colour = false) //! Draw a meter with optional colour and display value
{
vitamin(str("meter(", type[0], arg(colour, "red", "colour"), "): LED meter ", colour));
color("grey")
translate_z(meter_height(type) / 2)
cube([meter_length(type), meter_width(type), meter_height(type)], center = true);
color("green")
translate_z(meter_height(type))
linear_extrude(meter_pcb_thickness(type))
difference() {
union() {
square([meter_pcb_length(type), meter_pcb_width(type)], center = true);
square([meter_lug_length(type), meter_lug_width(type)], center = true);
}
meter_hole_positions(type)
circle(meter_hole_radius(type));
}
color(display_colour ? display_colour : colour)
linear_extrude(0.2, center = true)
mirror([1,0,0])
text(value, font = "7 segment", valign = "center", halign = "center", size = meter_width(type) - 2, spacing = 1.2);
}
clearance = 0.1;
overlap = 1;
flange_t = 1;
function meter_bezel_wall(type = led_meter) = (meter_lug_length(type) - meter_length(type)) / 2; //! Printed bezel wall thickness
function meter_bezel_rad(type = led_meter) = meter_bezel_wall(type); //! Printed bezel corner radius
function meter_bezel_length(type = led_meter) = meter_length(type) + 2 * (meter_bezel_wall(type) + overlap); //! Printed bezel length
function meter_bezel_width(type = led_meter) = meter_width(type) + 2 * (meter_bezel_wall(type) + overlap); //! Printed bezel width
module meter_bezel_hole(type = led_meter, h = 100) { //! Make a hole to fit the meter Bezel
wall = meter_bezel_wall(type) + clearance;
rad = meter_bezel_rad(type) + clearance;
l = meter_length(type);
w = meter_width(type);
extrude_if(h)
rounded_square([l + 2 * wall, w + 2 * wall], rad);
}
module meter_bezel(type = led_meter) { //! Generate the STL for the meter bezel
stl("meter_bezel");
wall = meter_bezel_wall(type);
rad = meter_bezel_rad(type);
l = meter_length(type);
w = meter_width(type);
h = meter_height(type);
union() {
linear_extrude(h)
difference() {
rounded_square([l + 2 * wall, w + 2 * wall], rad);
square([l + 2 * clearance, w + 2 * clearance], center = true);
}
linear_extrude(flange_t)
difference() {
rounded_square([l + 2 * wall + 2 * overlap, w + 2 * wall + 2 * overlap], rad + overlap);
square([l + 2 * clearance, w + 2 * clearance], center = true);
}
meter_hole_positions(type)
cylinder(r = meter_hole_radius(type), h = h + meter_pcb_thickness(type) * 2);
}
}
module meter_assembly(type = led_meter, colour = "red", value = "888", display_colour = false) { //! Meter assembled into the bezel
vflip()
translate_z(-flange_t) {
color("dimgrey") meter_bezel(type);
meter(type, colour, value, display_colour);
}
}

View File

@@ -24,8 +24,8 @@ small_leg = [0.9, 3.3, 0.4, 0];
medium_leg = [0.5, 3.9, 3.2, 1.6, [0, -0.5]];
large_leg = [11.4, 0.8, 6.3, 1.8, [1.7, 0]];
small_microswitch = ["small_microswitch", "DM1-00P-110-3", 5.8, 6.5, 12.8, 0, 2, [[-3.25, -1.65], [3.25, -1.65]], 2.9, 1.2, [-1.95, 3.75], [[-5.08, -4.95], [0, -4.9], [5.08, -4.9] ], small_leg, grey20, "white" ];
medium_microswitch = ["medium_microswitch","SS-01 or SS-5GL", 6.4, 10.2, 19.8, 1, 2.35, [[-4.8, -2.6 ], [4.7, -2.6 ]], 3.2, 2, [-2.8, 5.8 ], [[-8.05, -7.05], [0.75, -7.05], [8.05, -7.05] ], medium_leg, grey20, "burlywood" ];
small_microswitch = ["small_microswitch", "DM1-00P-110-3", 5.8, 6.5, 12.8, 0, 2, [[-3.25, -1.65], [3.25, -1.65]], 2.9, 1.2, [-1.95, 3.75], [[-5.08, -4.95], [0, -4.9], [5.08, -4.9] ], small_leg, grey(20), "white" ];
medium_microswitch = ["medium_microswitch","SS-01 or SS-5GL", 6.4, 10.2, 19.8, 1, 2.35, [[-4.8, -2.6 ], [4.7, -2.6 ]], 3.2, 2, [-2.8, 5.8 ], [[-8.05, -7.05], [0.75, -7.05], [8.05, -7.05] ], medium_leg, grey(20), "burlywood" ];
large_microswitch = ["large_microswitch", "Saia G3 low force", 10.4, 15.9, 28.0, 2, 3.1, [[-11.1, -5.15], [11.2, 5.15]], 4, 2.75,[-9.1, 9.55], [[19.7, 2.19], [19.7, -3.45], [8.3, -10.45] ], large_leg, "ivory", "white" ];
microswitches = [small_microswitch, medium_microswitch, large_microswitch];

View File

@@ -87,7 +87,7 @@ module mod(type) { //! Draw specified module
linear_extrude(body_l, center = true)
profile();
color(grey20)
color(grey(20))
for(end = [-1, 1])
translate([end * body_l / 2, 0, 0])
rotate([90, 0, end * 90])

View File

@@ -55,7 +55,7 @@ module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specifi
vitamin(str("nut(", type[0], arg(nyloc, false, "nyloc"), arg(brass, false, "brass"), arg(nylon, false, "nylon"),
"): Nut M", nut_size(type), " x ", thickness, "mm ", desc));
colour = brass ? brass_colour : nylon ? grey30: grey70;
colour = brass ? brass_colour : nylon ? grey(30): grey(70);
explode(nyloc ? 10 : 0) {
color(colour) {
linear_extrude(thickness)
@@ -147,7 +147,7 @@ module sliding_t_nut(type) {
tabSizeZ = nut_thickness(type);
holeRadius = nut_size(type) / 2;
color(grey80)
color(grey(80))
extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius, 0, hammerNut);
}
@@ -204,7 +204,7 @@ module nut_square(type, brass = false, nylon = false) { //! Draw specified squar
vitamin(str("nut(", type[0], arg(brass, false, "brass"), arg(nylon, false, "nylon"),
"): Nut M", nut_size(type), "nS ", width, " x ", thickness, "mm ", desc));
colour = brass ? brass_colour : nylon ? grey30 : grey70;
colour = brass ? brass_colour : nylon ? grey(30) : grey(70);
color(colour)
difference() {
linear_extrude(thickness) {

View File

@@ -53,7 +53,7 @@ module opengrab() { //! Draw OpenGrab module
translate_z(magnet / 2 + eps)
cube([width, width, magnet - eps], center = true);
color(grey80) {
color(grey(80)) {
gap = (width - poles * pole_w + 3 * eps) / (poles - 1);
pitch = pole_w + gap;
for(i = [0 : poles - 1])
@@ -84,7 +84,7 @@ module opengrab() { //! Draw OpenGrab module
module opengrab_target() { //! Draw OpenGrab target
vitamin("opengrab_target(): OpenGrab silicon steel target plate");
color(grey80)
color(grey(80))
linear_extrude(target)
difference() {
square([width, width], center = true);

173
vitamins/panel_meter.scad Normal file
View File

@@ -0,0 +1,173 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Panel mounted digital meter modules
//!
//! Notes on the DSN_VC288:
//!
//! * The tabs aren't modelled because they can be fully retracted if the PCB is removed.
//! * The current connector isn't moddelled as it is awkwardly tall. I remove it and solder wires instead.
//
include <../utils/core/core.scad>
use <../utils/dogbones.scad>
use <../utils/rounded_cylinder.scad>
use <pcb.scad>
function pmeter_size(type) = type[2]; //! Body size including bezel height
function pmeter_bezel(type) = type[3]; //! Bezel size
function pmeter_bezel_r(type) = type[4]; //! Bezel radius
function pmeter_bevel(type) = type[5]; //! Bezel bevel inset and start height or a radius
function pmeter_aperture(type) = type[6]; //! Aperture length, width and bevel
function pmeter_tab(type) = type[7]; //! Tab size
function pmeter_tab_z(type) = type[8]; //! Tab vertical position
function pmeter_thickness(type) = type[9]; //! Wall thickness if not closed
function pmeter_inner_ap(type) = type[10]; //! Inner aperture
function pmeter_inner_ap_o(type) = type[11]; //! Inner aperture offset
function pmeter_pcb(type) = type[12]; //! Optional PCB for open types
function pmeter_pcb_z(type) = type[13]; //! Distance of PCB from the back
function pmeter_pcb_h(type) = type[14]; //! Component height from the front
function pmeter_buttons(type) = type[15]; //! List of buttons
function pmeter_button_pos(type) = type[0]; //! Button position
function pmeter_button_size(type) = type[1]; //! Button size
function pmeter_button_r(type) = type[2]; //! Button radius
function pmeter_button_colour(type) = type[3]; //! Button colour
function pmeter_depth(type) = pmeter_size(type).z - pmeter_bezel(type).z; //! Depth below bezel
module panel_meter_button(type) { //! Draw panel meter button
size = pmeter_button_size(type);
r = pmeter_button_r(type);
color(pmeter_button_colour(type))
translate(pmeter_button_pos(type))
if(size.x)
rounded_rectangle(pmeter_button_size(type), r, center = false);
else
cylinder(r = r, h = size.z);
}
module panel_meter(type) { //! Draw panel mounted LCD meter module
vitamin(str("panel_meter(", type[0], "): ", type[1]));
size = pmeter_size(type);
bezel = pmeter_bezel(type);
bevel = pmeter_bevel(type);
t = pmeter_thickness(type);
r = pmeter_bezel_r(type);
h = size.z - bezel.z;
ap = pmeter_aperture(type);
tab = pmeter_tab(type);
tab_z = pmeter_tab_z(type);
pcb = pmeter_pcb(type);
ap2 = pmeter_inner_ap(type);
pcb_h = pmeter_pcb_h(type) - bezel.z;
buttons = pmeter_buttons(type);
color("#94A7AB")
cube([ap.x, ap.y, 3 * eps], center = true);
module corner(x, y)
translate([x * (bezel.x / 2 - bevel), y * (bezel.y / 2 - bevel)])
rounded_cylinder(r = r, r2 = bevel, h = bezel.z);
color(grey(30)) union() {
//
// Bezel and aperture
//
difference() {
if(is_list(bevel))
hull() {
rounded_rectangle([bezel.x - 2 * bevel.x, bezel.y - 2 * bevel.x, bezel.z], r - bevel.x, center = false);
rounded_rectangle([bezel.x, bezel.y, bevel[1]], r, center = false);
}
else
hull() {
corner(-1, -1);
corner(-1, 1);
corner( 1, -1);
corner( 1, 1);
}
hull() {
r = max(0, -ap.z);
if(ap.z > 0)
translate_z(bezel.z + eps)
cube([ap.x + ap.z, ap.y + ap.z, eps], center = true);
translate_z(bezel.z + eps)
rounded_rectangle([ap.x, ap.y, bezel.z * 2], r, center = true);
}
}
//
// Body
//
translate_z(-h)
linear_extrude(h)
difference() {
square([size.x, size.y], center = true);
if(t)
square([size.x - 2 * t, size.y - 2 * t], center = true);
}
//
// tabs
//
if(tab)
for(end = [-1, 1])
translate([end * (size.x / 2 + tab.x / 2), 0, -size.z + tab_z])
rotate([0, end * 10, 0])
translate_z(tab.z / 2)
cube([tab.x, tab.y, tab.z], center = true);
}
if(ap2)
color("grey")
linear_extrude(ap2.z)
difference() {
square([ap.x, ap.y], center = true);
translate(pmeter_inner_ap_o(type))
square([ap2.x, ap2.y], center = true);
}
if(pcb)
vflip()
translate_z(h - pcb_thickness(pcb) - pmeter_pcb_z(type))
pcb(pcb);
if(pcb_h > 0)
%translate_z(-pcb_h / 2 - eps)
cube([size.x - 2 * t - eps, size.y - 2 * t - eps, pcb_h], center = true);
if(buttons)
for(b = buttons)
panel_meter_button(b);
}
module panel_meter_cutout(type, h = 0) { //! Make panel cutout
size = pmeter_size(type);
tab = pmeter_tab(type);
extrude_if(h)
offset(0.2) {
dogbone_square([size.x, size.y]);
if(tab)
rounded_square([size.x + 2 * tab.x, tab.y + 2 * cnc_bit_r], r = cnc_bit_r, center = true);
}
}

View File

@@ -0,0 +1,51 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Panel mounted digital meter modules
//
// body size bezel size, radius, bevel aperture tab tab_z t
// inner aperture offset pcb pcb z h
PZEM021 = ["PZEM021", "Peacefair PZEM-021 AC digital multi-function meter", [84.6, 44.7, 24.4], [89.6, 49.6, 2.3], 1.5, [1, 1], [51, 30, 5], [1.3, 10, 6], 15.5, 0];
PZEM001 = ["PZEM001", "Peacefair PZEM-001 AC digital multi-function meter", [62 , 52.5, 24.4], [67, 57.5, 2.0], 2.0, [1, 1], [61, 46,-3], [1.2, 10, 6], 15.5, 0,
[36, 36, 1.9], [0, 0], false, 0, 0, [
[[25, 8, 0], [0, 0, 2], 4, grey(90)],
[[25, -8, 0], [0, 0, 2], 4, grey(90)],
]];
DSP5004PCB = ["", "", 68, 36, 1.6, 0, 0, 0, "green", false, [], [], []];
DSP5005 = ["DSP5005", "Ruideng DSP5005 Power supply module", [71.6, 39.8, 25.0], [79, 43.0, 2.3], 2.0, 1, [67, 32,-1], [2.0, 12, 9], 13.5, 1.5,
[28, 27, 0.7], [-4.5, 0], DSP5004PCB, 10, 36, [
[[ 22, 4, 2], [ 0, 0, 11], 6, "silver"],
[[ 22, 4, 5], [ 0, 0, 6], 6.5, "silver"],
[[ 22, -9, 0], [ 8, 6, 1], 2.99, "yellow"],
[[-25, -9, 0], [ 6.5, 4.5, 1], 0.5, "yellow"],
[[-25, 0, 0], [ 6.5, 4.5, 1], 0.5, "yellow"],
[[-25, 9, 0], [ 6.5, 4.5, 1], 0.5, "yellow"],
]];
DSN_VC288PCB = ["", "", 41, 21, 1, 0, 0, 0, "green", false, [], [[ 5, -3, 0, "jst_xh", 3], ], []];
DSN_VC288 = ["DSN_VC288","DSN-VC288 DC 100V 10A Voltmeter ammeter", [45.3, 26, 17.4], [47.8, 28.8, 2.5], 0, [1, 1.8], [36, 18, 2.5], [], 0, 2,
[], 0, DSN_VC288PCB, 5];
panel_meters = [DSN_VC288, PZEM021, PZEM001, DSP5005];
use <panel_meter.scad>

View File

@@ -34,6 +34,9 @@ use <../utils/thread.scad>
use <../utils/tube.scad>
use <d_connector.scad>
use <led.scad>
use <dip.scad>
use <axial.scad>
use <smd.scad>
function pcb_name(type) = type[1]; //! Description
function pcb_length(type) = type[2]; //! Length
@@ -50,6 +53,8 @@ function pcb_accessories(type) = type[12]; //! List of accessories to go on the
function pcb_grid(type) = type[13]; //! Grid if a perfboard
function pcb_polygon(type) = type[14]; //! Optional outline polygon for odd shaped boards
function pcb_screw(type, cap = hs_cap) = Len(type[15]) ? type[15] : find_screw(cap, screw_smaller_than(pcb_hole_d(type))); //! Mounting screw type
function pcb_size(type) = [pcb_length(type), pcb_width(type), pcb_thickness(type)]; //! Length, width and thickness in a vector
function pcb_grid_pos(type, x, y, z = 0) = //! Returns a pcb grid position
[-pcb_length(type) / 2 + pcb_grid(type).x + 2.54 * x,
@@ -83,6 +88,23 @@ module chip(length, width, thickness, colour, cutout = false) //! Draw a coloure
color(colour)
translate_z(thickness / 2) cube([length, width, thickness], center = true);
module usb_A_tongue() {
l = 9;
w = 12;
h = 2;
color("white")
translate([-1, 0 , h / 2])
rotate([90, 0, 90])
hull() {
linear_extrude(l - 2)
square([w, h], center = true);
linear_extrude(l)
square([w - 1, h - 1], center = true);
}
}
module usb_Ax1(cutout = false) { //! Draw USB type A single socket
usb_A(h = 6.5, v_flange_l = 4.5, bar = 0, cutout = cutout);
}
@@ -105,7 +127,7 @@ module usb_A(h, v_flange_l, bar, cutout) {
rotate([90, 0, 90])
rounded_rectangle([w + 2 * v_flange_h + 2 * panel_clearance,
h + 2 * h_flange_h + 2 * panel_clearance, 100], r = cnc_bit_r, center = false);
else
else {
color("silver") rotate([0, 90, 0]) {
linear_extrude(l, center = true)
difference() {
@@ -128,7 +150,72 @@ module usb_A(h, v_flange_l, bar, cutout) {
}
square([h - eps, w - eps], center = true);
}
}
}
for(z = bar ? [-1, 1] : [0])
translate_z(z * (bar / 2 + socket_h / 2))
usb_A_tongue();
}
}
module molex_usb_Ax2(cutout) { //! Draw Molex USB connector suitable for perf board
w = 15.9;
h = 16.6;
l = 17;
pin_l = 2.8;
clearance = 0.2;
tag_l = 4.4;
tag_r = 0.5;
tag_w = 1.5;
tag_t = 0.3;
tag_p = 5.65;
if(cutout)
translate([0, -w / 2 - clearance, -clearance])
cube([100, w + 2 * clearance, h + 2 * clearance]);
else {
color(silver)
translate([-l / 2, 0])
rotate([90, 0, 90])
translate([-w / 2, 0]) {
cube([w, h, l - 9]);
linear_extrude(l)
difference() {
square([w, h]);
for(z = [-1, 1])
translate([w / 2, h / 2 + z * 8.5 / 2])
square([12.6, 5.08], center = true);
}
}
for(z = [-1, 1])
translate_z(h / 2 + z * 8.5 / 2)
usb_A_tongue();
color(silver)
rotate(-90) {
for(x = [-1.5 : 1 : 1.5], y = [0.5 : 1 : 1.5])
translate([inch(x / 10), -l / 2 + inch(y / 10)])
hull() {
cube([0.6, 0.3, 2 * pin_l - 2], center = true);
cube([0.4, 0.3, 2 * pin_l], center = true);
}
for(side = [-1, 1], end = [0, 1])
translate([side * w / 2, -l / 2 + tag_w / 2 + end * tag_p])
rotate(-side * 90)
hull() {
translate([0, tag_l - tag_r])
cylinder(r = tag_r, h = tag_t);
translate([-tag_w / 2, 0])
cube([tag_w, eps, tag_t]);
}
}
}
}
module rj45(cutout = false) { //! Draw RJ45 Ethernet connector
@@ -163,7 +250,7 @@ module rj45(cutout = false) { //! Draw RJ45 Ethernet connector
cube([h, w, eps], center = true);
}
color(grey30) {
color(grey(30)) {
linear_extrude(l - 0.2, center = true)
difference() {
square([h - 0.1, w - 0.1], center = true);
@@ -194,7 +281,7 @@ module jack(cutout = false) { //! Draw 3.5mm jack
rotate([0, 90, 0])
cylinder(d = d + 2 * panel_clearance, h = 100);
else
color(grey20)
color(grey(20))
rotate([0, 90, 0]) {
linear_extrude(l / 2)
difference() {
@@ -423,7 +510,7 @@ module barrel_jack(cutout = false) { //! Draw barrel power jack
if(cutout)
;
else {
color(grey20) rotate([0, 90, 0]) {
color(grey(20)) rotate([0, 90, 0]) {
linear_extrude(l, center = true) {
difference() {
translate([-h / 2, 0])
@@ -495,7 +582,7 @@ module uSD(size, cutout = false) { //! Draw uSD socket
cube([size.x, size.z, t], center = true);
}
if(w > 0)
color(grey20)
color(grey(20))
rotate([90, 0, 90])
translate_z(t)
linear_extrude(size.y - t, center = true)
@@ -523,7 +610,7 @@ module flex(cutout = false) { //! Draw flexistrip connector
if(cutout)
;
else {
color(grey30) {
color(grey(30)) {
translate_z(0.5)
cube([l, w, 1], center = true);
@@ -551,56 +638,52 @@ module flex(cutout = false) { //! Draw flexistrip connector
translate([0, -w / 2 + slot_offset + slot_w / 2])
square([slot_l, slot_w], center = true);
}
}
}
}
module flat_flex(cutout = false) { //! Draw flat flexistrip connector as used on RPI0
l1 = 17;
w1 = 1.4;
h1 = 1.2;
small_ff = [[11.8, 0.9], [17, 1.4, 1.2], [12, 1.6, 1.2], [16, 1.1, 1.2]];
large_ff = [[16, 1.25], [22, 1.5, 2.5], [16, 4.0, 2.5], [21, 0, 2.5]];
l2 = 15.4;
w2 = 1.6;
h2 = 1.0;
function ff_slot(type) = type[0]; //! Flat flex slot size
function ff_latch(type) = type[1]; //! Flat flex latch size
function ff_mid(type) = type[2]; //! Flat flex middle section size
function ff_back(type) = type[3]; //! Flat flex back section size
l3 = 16;
w3 = 1.1;
h3 = 1.2;
module flat_flex(type, cutout = false) { //! Draw flat flexistrip connector as used on RPI0
slot = ff_slot(type);
latch = ff_latch(type);
mid = ff_mid(type);
back = ff_back(type);
l4 = 12;
slot_l = 11.8;
slot_h = 0.9;
w = w1 + w2 + w3;
w = latch.y + mid.y + back.y;
if(cutout)
;
else {
color(grey30) {
translate([w / 2 - w1, 0, h1 / 2])
rotate([90, 0, 90])
linear_extrude(w1)
color(grey(30))
translate([0, w / 2 - latch.y])
rotate([90, 0, 180])
linear_extrude(latch.y)
difference() {
square([l1, h1], center = true);
translate([-latch.x / 2, 0])
square([latch.x, latch.z]);
translate([0, -h1 / 2])
square([slot_l, slot_h * 2], center = true);
square([slot.x, slot.y * 2], center = true);
}
}
color(grey90) {
translate([-w / 2 + w3 / 2, 0, h3 / 2])
cube([w3, l3, h3], center = true);
color("ivory") {
translate([-back.x / 2, -w / 2])
if(back.y)
cube(back);
translate([-w / 2 + w3 + w2 / 2, 0, h2 / 2])
cube([w2, l2, h2], center = true);
translate([-w / 2 + w3 + w2 / 2, 0, h3 / 2])
cube([w2, l4, h3], center = true);
translate([-mid.x / 2, -w / 2 + back.y])
cube(mid);
}
color(grey(80))
translate([-back.x / 2, -w / 2 + back.y + eps])
cube([back.x, mid.y - 2 * eps, mid.z - eps]);
}
}
@@ -756,7 +839,7 @@ module trimpot10(vertical, cutout = false) { //! Draw a ten turn trimpot
rotate([vertical ? -90 : 0, 0, 0]) {
if(cutout)
screw_pos()
cylinder(d = screw_d + 1, h = 100);
poly_drill(r = (screw_d + 1) / 2, h = 100, center = false);
else
color("#2CA1FD") {
translate([0, -foot_h / 2, foot_h / 2 + h / 2])
@@ -782,47 +865,65 @@ module trimpot10(vertical, cutout = false) { //! Draw a ten turn trimpot
}
}
module block(size, colour, makes_cutout, cutouts) //! Draw a coloured cube to represent a random PCB component
if(cutouts) {
if(makes_cutout)
translate([-50, 0, size.z / 2 - panel_clearance])
cube([100, size.y + 2 * panel_clearance, size.z + 2 * panel_clearance], center = true);
}
else
color(colour)
translate_z(size.z / 2)
cube(size, center = true);
module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb component from description
function show(comp, part) = (comp[3] == part || comp[3] == str("-",part)) && (!cutouts || angle == undef || angle == comp.z);
function param(n, default = 0) = len(comp) > n ? comp[n] : default;
rotate(comp.z) {
if(show(comp, "2p54header")) pin_header(2p54header, comp[4], comp[5], param(6), cutouts, colour = param(7, undef));
if(show(comp, "2p54boxhdr")) box_header(2p54header, comp[4], comp[5], param(6), cutouts);
if(show(comp, "2p54socket")) pin_socket(2p54header, comp[4], comp[5], param(6, false), param(7), param(8, false), cutouts, param(9, undef));
if(show(comp, "chip")) chip(comp[4], comp[5], comp[6], param(7, grey30), cutouts);
if(show(comp, "rj45")) rj45(cutouts);
if(show(comp, "usb_A")) usb_Ax1(cutouts);
if(show(comp, "usb_Ax2")) usb_Ax2(cutouts);
if(show(comp, "usb_uA")) usb_uA(cutouts);
if(show(comp, "usb_B")) usb_B(cutouts);
if(show(comp, "buzzer")) buzzer(param(4, 9), param(5, 12), param(6, grey20));
if(show(comp, "potentiometer")) potentiometer(param(4, 5), param(5, 9));
if(show(comp, "jack")) jack(cutouts);
if(show(comp, "barrel_jack")) barrel_jack(cutouts);
if(show(comp, "hdmi")) hdmi(hdmi_full, cutouts);
if(show(comp, "mini_hdmi")) hdmi(hdmi_mini, cutouts);
if(show(comp, "flex")) flex(cutouts);
if(show(comp, "flat_flex")) flat_flex(cutouts);
if(show(comp, "D_plug")) if(!cutouts) translate_z(d_pcb_offset(comp[4])) d_plug(comp[4], pcb = true);
if(show(comp, "molex_hdr")) if(!cutouts) molex_254(comp[4]);
if(show(comp, "jst_xh")) if(!cutouts) jst_xh_header(jst_xh_header, comp[4], param(5, false), param(6, "white"), param(7, undef));
if(show(comp, "term254")) if(!cutouts) green_terminal(gt_2p54,comp[4], comp[5], param(6,"lime"));
if(show(comp, "gterm")) if(!cutouts) green_terminal(comp[4], comp[5], comp[6], param(7,"lime"));
if(show(comp, "gterm35")) if(!cutouts) green_terminal(gt_3p5, comp[4], comp[5], param(6,"lime"));
if(show(comp, "gterm508")) if(!cutouts) green_terminal(gt_5p08, comp[4], comp[5], param(6,"lime"));
if(show(comp, "gterm635")) if(!cutouts) green_terminal(gt_6p35, comp[4], comp[5], param(6,"lime"));
if(show(comp, "term35")) if(!cutouts) terminal_35(comp[4], param(5,"blue"));
if(show(comp, "transition")) if(!cutouts) idc_transition(2p54header, comp[4], comp[5]);
if(show(comp, "block"))
color(comp[7]) if(!cutouts) translate_z(comp[6] / 2) cube([comp[4], comp[5], comp[6]], center = true);
else if(comp[8]) translate([-50, 0, comp[6] / 2 - panel_clearance]) cube([100, comp[5] + 2 * panel_clearance, comp[6] + 2 * panel_clearance], center = true);
if(show(comp, "button_6mm")) square_button(button_6mm);
if(show(comp, "microswitch")) translate_z(microswitch_thickness(comp[4])/2) microswitch(comp[4]);
if(show(comp, "pcb")) if(!cutouts) translate_z(comp[4]) pcb(comp[5]);
if(show(comp, "standoff")) if(!cutouts) standoff(comp[4], comp[5], comp[6], comp[7]);
if(show(comp, "uSD")) uSD(comp[4], cutouts);
if(show(comp, "trimpot10")) trimpot10(param(4, false), cutouts);
if(show(comp, "led")) led(comp[4], comp[5], 2.6);
// Components that have a cutout parameter go in this section
if(show(comp, "2p54header")) pin_header(2p54header, comp[4], comp[5], param(6, false), false, cutouts, colour = param(7, undef));
if(show(comp, "2p54boxhdr")) box_header(2p54header, comp[4], comp[5], param(6, false), cutouts);
if(show(comp, "2p54socket")) pin_socket(2p54header, comp[4], comp[5], param(6, false), param(7, 0), param(8, false), cutouts, param(9, undef));
if(show(comp, "chip")) chip(comp[4], comp[5], comp[6], param(7, grey(30)), cutouts);
if(show(comp, "rj45")) rj45(cutouts);
if(show(comp, "usb_A")) usb_Ax1(cutouts);
if(show(comp, "usb_Ax2")) usb_Ax2(cutouts);
if(show(comp, "usb_uA")) usb_uA(cutouts);
if(show(comp, "usb_B")) usb_B(cutouts);
if(show(comp, "jack")) jack(cutouts);
if(show(comp, "barrel_jack")) barrel_jack(cutouts);
if(show(comp, "hdmi")) hdmi(hdmi_full, cutouts);
if(show(comp, "mini_hdmi")) hdmi(hdmi_mini, cutouts);
if(show(comp, "flex")) flex(cutouts);
if(show(comp, "flat_flex")) flat_flex(param(4, false) ? large_ff : small_ff, cutouts);
if(show(comp, "uSD")) uSD(comp[4], cutouts);
if(show(comp, "trimpot10")) trimpot10(param(4, false), cutouts);
if(show(comp, "molex_usb_Ax2")) molex_usb_Ax2(cutouts);
if(show(comp, "smd_led")) smd_led(comp[4], comp[5], cutouts);
if(show(comp, "block")) block(size = [comp[4], comp[5], comp[6]], colour = comp[7], makes_cutout = param(8));
if(!cutouts) {
// Components that don't have a cutout parameter go in this section
if(show(comp, "button_6mm")) square_button(button_6mm);
if(show(comp, "microswitch")) translate_z(microswitch_thickness(comp[4])/2) microswitch(comp[4]);
if(show(comp, "pcb")) translate_z(comp[4]) pcb(comp[5]);
if(show(comp, "standoff")) standoff(comp[4], comp[5], comp[6], comp[7]);
if(show(comp, "term254")) green_terminal(gt_2p54,comp[4], comp[5], param(6,"lime"));
if(show(comp, "gterm")) green_terminal(comp[4], comp[5], comp[6], param(7,"lime"));
if(show(comp, "gterm35")) green_terminal(gt_3p5, comp[4], comp[5], param(6,"lime"));
if(show(comp, "gterm508")) green_terminal(gt_5p08, comp[4], comp[5], param(6,"lime"));
if(show(comp, "gterm635")) green_terminal(gt_6p35, comp[4], comp[5], param(6,"lime"));
if(show(comp, "term35")) terminal_35(comp[4], param(5,"blue"));
if(show(comp, "transition")) idc_transition(2p54header, comp[4], comp[5]);
if(show(comp, "led")) led(comp[4], comp[5], 2.6);
if(show(comp, "pdip")) pdip(comp[4], comp[5], param(6, false), param(7, inch(0.3)));
if(show(comp, "ax_res")) ax_res(comp[4], comp[5], param(6, 5), param(7, 0));
if(show(comp, "D_plug")) translate_z(d_pcb_offset(comp[4])) d_plug(comp[4], pcb = true);
if(show(comp, "molex_hdr")) molex_254(comp[4]);
if(show(comp, "jst_xh")) jst_xh_header(jst_xh_header, comp[4], param(5, false), param(6, "white"), param(7, undef));
if(show(comp, "potentiometer")) potentiometer(param(4, 5), param(5, 9));
if(show(comp, "buzzer")) buzzer(param(4, 9), param(5, 12), param(6, grey(20)));
if(show(comp, "smd_res")) smd_resistor(comp[4], comp[5]);
}
}
}

View File

@@ -19,6 +19,8 @@
include <microswitches.scad>
include <d_connectors.scad>
include <leds.scad>
include <axials.scad>
include <smds.scad>
//
// l w t r h l c b h
@@ -110,7 +112,7 @@ DuetE = ["DuetE", "Duet 2 Ethernet electronics",
[109.8, -58.8, 0, "chip", inch(0.03), inch(0.06), 1, "red"], // Bed heater
[ 2.3, -37.2, 0, "chip", 3.6, 4.8, 2.0, "silver"], // Reset switch
[ 0.0, -37.2, 0, "chip", 2.0, 2.6, 1.4, grey20], // Reset button
[ 0.0, -37.2, 0, "chip", 2.0, 2.6, 1.4, grey(20)], // Reset button
],
[": Micro SD card", ": Cat 5 patch cable 300mm"]];
@@ -222,7 +224,7 @@ RPI0 = ["RPI0", "Raspberry Pi Zero", 65, 30, 1.4, 3, 2.75, 6, "gre
[54, 2, -90, "usb_uA"],
[41.4, 2, -90, "usb_uA"],
[7.25, 16.7, 180, "uSD", [12, 11.5, 1.4]],
[-1.3, 15, 0, "flat_flex"],
[-1.3, 15, -90, "flat_flex"],
],
[": Micro SD card"],
[32.5 - 9.5 * 2.54, 26.5 - 1.27, 20, 2]];
@@ -244,8 +246,9 @@ ArduinoUno3 = ["ArduinoUno3", "Arduino Uno R3", 68.58, 53.34, 1.6, 0, 3.3, 0, "#
[64.91, 27.89, 0, "2p54header", 2, 3],
[18.796, -7.00, 0, "2p54header", 3, 2],
[ 6.5, -3.5, 0, "button_6mm"],
[4.7625, 7.62, 180, "barrel_jack"],
[1.5875, 37.7825,180,"usb_B"],
[4.7625, 7.62, 180,"barrel_jack"],
[1.5875, 37.78, 180,"usb_B"],
[46.99, 17, 270,"pdip", 28, "ATMEGA328", true],
],
[],[],
inch([
@@ -328,11 +331,13 @@ PI_IO = ["PI_IO", "PI_IO V2", 35.56, 25.4, 1.6, 0, 0, 0, "green", tru
ZC_A0591 = ["ZC_A0591", "ZC-A0591 ULN2003 driver PCB", 35, 32, 1.6, 0, 2.5, 0, "green", false, [[2.25, 3.25], [-2.25, 3.25], [2.25, -3.25], [-2.25, -3.25] ],
[ [ 12.25, 8.3, -90, "jst_xh", 5],
[ -6.5, 10, 0, "2p54header", 1, 4],
[-14, -4.5, 0, "2p54header", 4, 1],
[ 20.4, -4.5, 0, "2p54header", 4, 1],
[ 20.4, 11, 180, "pdip", 16, "ULN2803AN", true],
[ 5.5, 6, 0, "led", LED3mm, [1,1,1, 0.5]],
[ 5.5, 10.5, 0, "led", LED3mm, [1,1,1, 0.5]],
[ 5.5, 15, 0, "led", LED3mm, [1,1,1, 0.5]],
[ 5.5, 19.5, 0, "led", LED3mm, [1,1,1, 0.5]],
for(i = [0 : 3]) [5.5 + inch(0.1) * i, -5.5, -90, "ax_res", res1_8, 510, 5, 5.5]
], [], [], [], M2p5_pan_screw];
@@ -344,16 +349,20 @@ MT3608 = ["MT3608", "MT3608 boost converter module", 37, 17, 1.2, 2, 1.5,
TP4056 = ["TP4056", "TP4056 Li-lon Battery charger module", 26.2, 17.5, 1.0, 0, 1.0, [2.4, 2.4], "#2140BE", false,
[[1.67, 1.8], [1.67, -1.8], [-1.67, 1.8], [-1.67, -1.8], [-1.67, -4.98], [-1.67, 4.98]],
[ [ 2, 17.5 / 2, 180, "usb_uA"],
[ 7, -2 , 0, "smd_led", LED0805, "red"],
[ 11, -2 , 0, "smd_led", LED0805, "blue"],
]];
WD2002SJ = ["WD2002SJ", "WD2002SJ Buck Boost DC-DC converter", 78, 47, 1.6, 0, 3.2, 0, "#2140BE", false, [[4,4], [-4,4], [-4,-4], [4,-4]],
[ [ 39, -20.5, 0, "-chip", 63, 41, 4, "silver"],
[ [ 39, -20.5, 0, "-chip", 63, 41, 3.4, "silver"],
[ -4, 12, 0, "gterm508", 2, [], "blue"],
[ 4, 12, 180, "gterm508", 2, [], "blue"],
[ -25.5, 3.1, 0, "trimpot10", true],
[ 30.5, 3.1, 0, "trimpot10", true],
[ 41.5, 3.1, 0, "trimpot10", true],
[ -10.4, 1.4, 0, "smd_led", LED0805, "blue"],
[ 15.7, 2.7, 0, "smd_led", LED0805, "red"],
],
[]];

View File

@@ -34,8 +34,8 @@ M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -8, 8];
M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey20, grey20, -6, 6];
M3x10_nylon_hex_pillar = ["M3x10_nylon_hex_pillar", "hex nylon", 3, 10,5.5/cos(30),5.5/cos(30),6, 6, grey20, grey20, -6, 6];
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey(20), grey(20), -6, 6];
M3x10_nylon_hex_pillar = ["M3x10_nylon_hex_pillar", "hex nylon", 3, 10,5.5/cos(30),5.5/cos(30),6, 6, grey(20), grey(20), -6, 6];
pillars = [M2x16_brass_pillar, M3x13_hex_pillar, M3x20_hex_pillar, M3x20_nylon_pillar, M4x17_nylon_pillar, M3x10_nylon_hex_pillar, M3x20_nylon_hex_pillar];

View File

@@ -52,7 +52,7 @@ module pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cu
if(cutout)
dogbone_rectangle([cols * pitch + 2 * panel_clearance, rows * pitch + 2 * panel_clearance, 100], center = false);
else
else {
vitamin(str("pin_header(", type[0], ", ", cols, ", ", rows,
arg(smt, false, "smt"), arg(right_angle, false, "right_angle"), "): Pin header ", cols, " x ", rows, right_angle ? " right_angle" : ""));
@@ -91,6 +91,7 @@ module pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cu
square([pitch - chamfer, pitch + eps], center = true);
}
}
}
}
module box_header(type, cols = 1, rows = 1, smt = false, cutout = false) { //! Draw box header
@@ -102,7 +103,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
else {
vitamin(str("box_header(", type[0], ", ", cols, ", ", rows, arg(smt, false, "smt"), "): Box header ", cols, " x ", rows));
translate_z(smt ? 3.5 - h : 0) {
@@ -125,6 +126,7 @@ module box_header(type, cols = 1, rows = 1, smt = false, cutout = false) { //! D
}
}
}
}
}
module idc_transition(type, cols = 5, skip = [], cutout = false) { //! Draw IDC transition header

Some files were not shown because too many files have changed in this diff Show More