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

Compare commits

...

46 Commits

Author SHA1 Message Date
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
Chris Palmer
5be14f5e89 Fixed bug updating the times file when case changes.
First column split of vitamins now at J.
2020-04-13 18:02:03 +01:00
Chris Palmer
efff17dfc7 Ball bearing chamfer less and 6808 hub corrected. 2020-04-11 23:46:37 +01:00
Chris Palmer
ac4a5500a9 Added chamfers and made hub and rim properties of ball_bearings. 2020-04-11 17:29:02 +01:00
Chris
6b90a7aac8 Merge pull request #72 from ledvinap/patch-1
nut_radius is needed for screw_boss_diameter
2020-04-10 12:51:39 +01:00
Chris Palmer
3c3d72f366 Merge branch 'master' of https://github.com/nophead/NopSCADlib 2020-04-10 12:41:41 +01:00
Chris Palmer
dbcab8377f LEDs can now be placed on PCBs. 2020-04-10 12:41:05 +01:00
Chris Palmer
11d96d37e1 LEDs can not be placed on PCBs. 2020-04-10 12:39:46 +01:00
Petr Ledvina
40843b421f nut_radius is needed for screw_boss_diameter
using `include <NopSCADlib/lib.scad>` in main file fails in `screw_boss_diameter`:
`WARNING: Ignoring unknown function 'nut_radius', in file ../../../sw/OpenSCAD/libraries/NopSCADlib/vitamins/screw.scad, line 41.`

Maybe my library usage is wrong, I did not investigate further ...
2020-04-09 20:33:59 +02:00
Chris Palmer
cc8f4d3bd3 Tweaked test PCB layout 2020-04-09 18:33:59 +01:00
Chris Palmer
69d6fc8bf0 PCB test now shorter and wider for better view. 2020-04-09 17:35:49 +01:00
Chris Palmer
01b1e2e84d Added WD2002SJ Buck Boost DC-DC converter PCB 2020-04-08 20:53:19 +01:00
Chris Palmer
cb64cadb92 Added gterm508. 2020-04-08 19:52:35 +01:00
Chris Palmer
b57b50d2b0 Added yet another type of green terminal that is blue. 2020-04-08 19:38:52 +01:00
Chris Palmer
8f282775a4 Fixed green terminal pin centering. 2020-04-08 19:15:38 +01:00
Chris Palmer
bf833b0452 Fixed some typos 2020-04-08 19:13:06 +01:00
Chris Palmer
52011fd6f7 Renders of dxfs now use the sheet colour. 2020-04-07 22:07:28 +01:00
Chris Palmer
9da8634769 Bom generation now calls openscad with --hardwarnings to stop ASAP. 2020-04-07 19:36:38 +01:00
Chris Palmer
147ff9b24f Added alpha parameter to stl_colour() 2020-04-07 17:02:10 +01:00
Chris Palmer
b4379907a2 Updated gallery 2020-04-06 16:21:58 +01:00
Chris Palmer
3be88f6517 Some more stl_colours. 2020-04-06 15:02:50 +01:00
Chris Palmer
d42f99e437 stl_colour() now used in tests and examples. 2020-04-06 10:27:17 +01:00
Chris Palmer
65455930f8 Reverted incorrect use of stl_colour(). 2020-04-05 18:51:21 +01:00
Chris Palmer
7e0c5fdb6e Renders of STLs are now the correct colour. Fixes #71 2020-04-05 16:18:24 +01:00
Chris Palmer
bc4e18d788 The assembly module now has a big parameter to force large or small views. 2020-04-04 12:06:14 +01:00
100 changed files with 2232 additions and 623 deletions

View File

@@ -164,7 +164,7 @@ This is achieved by having a pair of modules: -
module handle_assembly() pose([225, 0, 150], [0, 0, 14]) //! Printed part with inserts in place
assembly("handle") {
translate_z(handle_height())
color(pp1_colour) vflip() handle_stl();
stl_colour(pp1_colour) vflip() handle_stl();
handle_screw_positions()
vflip()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View File

@@ -1,67 +1,119 @@
[
{
"name": "base_assembly",
"big": null,
"count": 1,
"assemblies": {},
"vitamins": {
"insert(F1BM3): Heatfit insert M3": 2
"insert(F1BM3): Heatfit insert M3": {
"count": 2
}
},
"printed": {
"socket_box.stl": 1
"socket_box.stl": {
"count": 1,
"colour": "dimgrey"
}
},
"routed": {}
},
{
"name": "feet_assembly",
"big": null,
"count": 1,
"assemblies": {
"base_assembly": 1
},
"vitamins": {
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 8,
"screw(M3_dome_screw, 10): Screw M3 dome x 10mm": 4,
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 4
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": {
"count": 8
},
"screw(M3_dome_screw, 10): Screw M3 dome x 10mm": {
"count": 4
},
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": {
"count": 4
}
},
"printed": {
"foot.stl": 4
"foot.stl": {
"count": 4,
"colour": "darkorange"
}
},
"routed": {}
},
{
"name": "mains_in_assembly",
"big": null,
"count": 1,
"assemblies": {
"feet_assembly": 1
},
"vitamins": {
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
": Wire brown 30/0.25mm strands, length 150mm - not shown": 2,
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 3,
"iec(IEC_inlet_atx): IEC inlet for ATX": 1,
"screw(M3_cs_cap_screw, 12): Screw M3 cs cap x 12mm": 2,
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 2,
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 2
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
": Wire blue 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
": Wire brown 30/0.25mm strands, length 150mm - not shown": {
"count": 2
},
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": {
"count": 3
},
"iec(IEC_inlet_atx): IEC inlet for ATX": {
"count": 1
},
"screw(M3_cs_cap_screw, 12): Screw M3 cs cap x 12mm": {
"count": 2
},
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": {
"count": 2
},
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": {
"count": 2
}
},
"printed": {},
"routed": {}
},
{
"name": "main_assembly",
"big": null,
"count": 1,
"assemblies": {
"mains_in_assembly": 1
},
"vitamins": {
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 5,
": Ferrule for 1.5mm^2 wire - not shown": 3,
"mains_socket(Contactum): Mains socket 13A": 1,
"screw(M3_cs_cap_screw, 20): Screw M3 cs cap x 20mm": 2,
"jack_4mm_shielded(\"blue\", 3, \"royalblue\"): 4mm shielded jack socket blue": 2,
"jack_4mm_shielded(\"brown\", 3, \"sienna\"): 4mm shielded jack socket brown": 1,
"jack_4mm_shielded(\"green\", 3): 4mm shielded jack socket green": 2
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
": Wire blue 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": {
"count": 5
},
": Ferrule for 1.5mm^2 wire - not shown": {
"count": 3
},
"mains_socket(Contactum): Mains socket 13A": {
"count": 1
},
"screw(M3_cs_cap_screw, 20): Screw M3 cs cap x 20mm": {
"count": 2
},
"jack_4mm_shielded(\"blue\", 3, \"royalblue\"): 4mm shielded jack socket blue": {
"count": 2
},
"jack_4mm_shielded(\"brown\", 3, \"sienna\"): 4mm shielded jack socket brown": {
"count": 1
},
"jack_4mm_shielded(\"green\", 3): 4mm shielded jack socket green": {
"count": 2
}
},
"printed": {},
"routed": {}

View File

@@ -173,7 +173,7 @@ module socket_box_stl() {
//
module base_assembly()
assembly("base") {
color(pp1_colour) render() /*clip(ymax = 0)*/ socket_box_stl();
stl_colour(pp1_colour) render() /*clip(ymax = 0)*/ socket_box_stl();
mains_socket_hole_positions(socket)
translate_z(height)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 KiB

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -84,7 +84,7 @@ Mains isolated and variable supply with metering.
<a name="TOP"></a>
## SunBot
A solar tracker to keep solar powerbanks pointing at the sun.
A solar tracker to keep a solar panel pointing at the sun.
![](SunBot.png)

View File

@@ -40,10 +40,11 @@ include <vitamins/inserts.scad>
include <vitamins/kp_pillow_blocks.scad>
include <vitamins/ldrs.scad>
include <vitamins/leadnuts.scad>
include <vitamins/leds.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>
@@ -56,6 +57,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>
@@ -63,7 +65,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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 KiB

After

Width:  |  Height:  |  Size: 794 KiB

View File

@@ -48,12 +48,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 +72,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 +103,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;
@@ -165,8 +167,8 @@ o_rings_y = springs_y;
sealing_strip_y = springs_y + 20;
tubings_y = sealing_strip_y + 20;
pillars_y = tubings_y + 20;
leadnuts_y = pillars_y + 40;
pulleys_y = leadnuts_y +40;
ball_bearings_y = pillars_y + 40;
pulleys_y = ball_bearings_y +40;
hot_ends_y = pulleys_y + 60;
linear_bearings_y = hot_ends_y + 50;
sheets_y = linear_bearings_y + 100;
@@ -176,7 +178,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])
@@ -209,10 +211,7 @@ translate([x0, tubings_y])
translate([x0, pillars_y])
pillars();
translate([x0, leadnuts_y ])
leadnuts();
translate([x0 + 60, leadnuts_y])
translate([x0, ball_bearings_y])
ball_bearings();
translate([x0, pulleys_y])
@@ -252,7 +251,9 @@ translate([x0, psus_y]) {
}
zipties_y = 0;
bulldogs_y = zipties_y + 40;
bulldogs_y = zipties_y + 30;
swiss_clips_y = bulldogs_y + 35;
leadnuts_y = swiss_clips_y + 50;
translate([x1, zipties_y])
zipties();
@@ -260,6 +261,13 @@ translate([x1, zipties_y])
translate([x1, bulldogs_y])
bulldogs();
translate([x1, swiss_clips_y])
swiss_clips();
translate([x1, leadnuts_y])
leadnuts();
leds_y = 0;
carriers_y = leds_y + 40;
spades_y = carriers_y + 40;
@@ -273,16 +281,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])
@@ -314,7 +322,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();
@@ -355,9 +364,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();

View File

@@ -33,7 +33,7 @@ assembly("box") {
y = [-1,-1,1,1][corner];
translate([x * (box_width(type) / 2 + 25 * exploded()), y * (box_depth(type) / 2 + 25 * exploded())])
rotate(corner * 90) {
color(pp2_colour) render()
stl_colour(pp2_colour) render()
box_corner_profile(type);
translate([box_hole_inset(type), box_hole_inset(type)])
@@ -50,7 +50,7 @@ assembly("box") {
translate_z(z * (box_height(type) / 2 - box_corner_gap(type) + 50 * exploded()))
rotate([z * 90 - 90, 0, 0])
if(bezels && (z > 0 ? top : base))
color(pp1_colour) render() box_bezel(type, z < 0);
stl_colour(pp1_colour) render() box_bezel(type, z < 0);
translate_z(z * (box_height(type) / 2 + sheet_thickness + 50 * exploded()))
box_screw_hole_positions(type)

View File

@@ -133,12 +133,12 @@ module round_grommet_hole(diameter, h = 100) //! Make a hole for a round grommet
drill(corrected_radius(diameter / 2) + wall + clearance, h);
module round_grommet_assembly(diameter, thickness, od = undef) {
color(pp1_colour)
stl_colour(pp1_colour)
translate_z(wall)
vflip()
round_grommet_top(diameter, thickness, od);
color(pp2_colour)
stl_colour(pp2_colour)
translate_z(-thickness)
vflip()
round_grommet_bottom(diameter, od);
@@ -188,7 +188,7 @@ module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
}
module mouse_grommet_assembly(r, thickness)
color(pp1_colour)
stl_colour(pp1_colour)
rotate([-90, 0, 0])
mouse_grommet(r, thickness);

View File

@@ -120,7 +120,7 @@ module corner_block_assembly(screw = def_screw, name = false) //! The printed bl
assembly(str("corner_block_M", 20 * screw_radius(screw))) {
insert = screw_insert(screw);
color(name ? pp2_colour : pp1_colour)
stl_colour(name ? pp2_colour : pp1_colour)
render() corner_block(screw, name) children();
corner_block_h_holes(screw)

View File

@@ -141,7 +141,7 @@ module door_hinge_assembly(top, door_thickness = 6) { //! The moving assembly th
translate([0, pin_y - (thickness + door_thickness / 2), dir * width / 2]) {
rotate([90, 0, 180])
color(pp2_colour) door_hinge(door_thickness);
stl_colour(pp2_colour) door_hinge(door_thickness);
rotate([90, 0, 0])
door_hinge_hole_positions()
@@ -165,7 +165,7 @@ module door_hinge_static_assembly(top, sheet_thickness = 3) { //! The stationary
translate([pin_x, 0, -dir * (stat_width / 2 + washer_thickness(screw_washer(pin_screw)))])
rotate([90, 0, 0]) {
color(pp1_colour) door_hinge_stat_stl();
stl_colour(pp1_colour) door_hinge_stat_stl();
door_hinge_stat_hole_positions() {
screw_and_washer(stat_screw, stat_screw_length);

View File

@@ -65,7 +65,7 @@ module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specifi
translate([0, -height - washer_thickness(washer)])
rotate([-90, 0, 0]) {
color(pp1_colour) render() door_latch_stl();
stl_colour(pp1_colour) render() door_latch_stl();
translate_z(nut_trap_depth)
vflip()

View File

@@ -109,7 +109,7 @@ module fixing_block_assembly(screw = def_screw) pose([55, 180, 25], [0, 4.8, 4.8
assembly(str("fixing_block_M", 20 * screw_radius(screw))) {
translate_z(fixing_block_height(screw))
rotate([0, 180, 0])
color(pp1_colour) render() fixing_block(screw);
stl_colour(pp1_colour) render() fixing_block(screw);
insert = screw_insert(screw);

View File

@@ -133,17 +133,17 @@ assembly(str("hinge_", type[0])) { //! Assembled hinge
vitamin(str(": Hinge pin ", w, " x ", 2 * hr, "mm"));
color(pp1_colour) hinge_male(type);
stl_colour(pp1_colour) hinge_male(type);
translate([0, -kr, kr]) {
rotate([0, 90, 0])
explode(w + 10)
color("silver") cylinder(r = hr , h = w, center = true);
stl_colour("silver") cylinder(r = hr , h = w, center = true);
rotate([-angle, 0, 0])
translate([0, -kr, -kr])
rotate(180)
color(pp2_colour) hinge_female(type);
stl_colour(pp2_colour) hinge_female(type);
}
}

View File

@@ -73,7 +73,7 @@ module foot_assembly(t = 0, type = foot, flip = false) { //! Assembly with faste
screw_length = screw_longer_than(foot_thickness(type) + t + 2 * washer_thickness(washer) + nut_thickness(nut, true) - squeeze);
vflip() explode(15, true) {
color(pp4_colour) foot(type);
stl_colour(pp4_colour) foot(type);
if(t)
explode(15, true)
@@ -136,7 +136,7 @@ assembly("insert_foot") {
insert = screw_insert(screw);
vflip()
color(pp1_colour) insert_foot(type);
stl_colour(pp4_colour) insert_foot(type);
translate_z(-foot_thickness(type))
insert(insert);

View File

@@ -83,7 +83,7 @@ module handle_stl() { //! generate the STL
module handle_assembly() pose([225, 0, 150], [0, 0, 14]) //! Printed part with inserts in place
assembly("handle") {
translate_z(handle_height())
color(pp1_colour) vflip() handle_stl();
stl_colour(pp1_colour) vflip() handle_stl();
handle_screw_positions()
vflip()

View File

@@ -101,7 +101,7 @@ module pcb_mount_assembly(pcb, thickness, height = 5) { //! A PCB mount assembly
translate_z(height)
pcb(pcb);
color(pp1_colour) pcb_mount(pcb, washers = false);
stl_colour(pp1_colour) pcb_mount(pcb, washers = false);
washer = screw_washer(screw);
nut = screw_nut(screw);
@@ -110,7 +110,7 @@ module pcb_mount_assembly(pcb, thickness, height = 5) { //! A PCB mount assembly
pcb_mount_screw_positions(pcb) {
translate_z(height + t) {
color(pp2_colour) pcb_mount_washer_stl();
stl_colour(pp2_colour) pcb_mount_washer_stl();
translate_z(washer_thickness)
screw(screw, screw_length);

View File

@@ -71,7 +71,7 @@ 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));
@@ -221,7 +221,7 @@ module pbox_base_screws(type, thickness = 0) //! Place the screws and
pbox_screw_positions(type) {
foot = pbox_foot(type);
if(foot)
color(pp4_colour)
stl_colour(pp4_colour)
foot(foot);
translate_z(foot ? foot_thickness(foot) : thickness)

View File

@@ -147,7 +147,7 @@ assembly(str("PSU_shroud_", name)) {
translate_z(psu_shroud_height(type))
vflip()
color(pp1_colour) psu_shroud(type, cable_d, name, cables);
stl_colour(pp1_colour) psu_shroud(type, cable_d, name, cables);
psu_shroud_hole_positions(type)
vflip()

View File

@@ -83,7 +83,7 @@ module ribbon_clamp_assembly(ways) pose([55, 180, 25]) //! Printed part with in
assembly(str("ribbon_clamp_", ways)) {
h = ribbon_clamp_height();
color(pp1_colour) render()
stl_colour(pp1_colour) render()
translate_z(h) vflip() ribbon_clamp(ways);
ribbon_clamp_hole_positions(ways)

View File

@@ -62,7 +62,7 @@ module screw_knob_assembly(screw, length) //! Assembly with the screw in place
assembly(str("screw_knob_M", 20 * screw_radius(screw), "_", length)) {
translate_z(knob_height)
vflip()
color(pp1_colour) screw_knob(screw);
stl_colour(pp1_colour) screw_knob(screw);
translate_z(knob_height - knob_nut_trap_depth(screw))
rotate(-45)

View File

@@ -92,7 +92,7 @@ assembly(str("socket_box_", type[0])) {
screw = mains_socket_screw(type);
insert = screw_insert(screw);
color(pp1_colour) render() socket_box(type);
stl_colour(pp1_colour) render() socket_box(type);
mains_socket_hole_positions(type)
translate_z(height)

View File

@@ -111,7 +111,7 @@ assembly(str("SSR_shroud_", name)) {
translate_z(ssr_shroud_height(type))
vflip()
color(pp1_colour) ssr_shroud(type, cable_d, name);
stl_colour(pp1_colour) ssr_shroud(type, cable_d, name);
ssr_shroud_hole_positions(type)
insert(insert);
@@ -135,7 +135,7 @@ module ssr_shroud_fastened_assembly(type, cable_d, thickness, name) //! Assembly
*translate_z(cable_d / 2)
rotate([90, 0, 0])
color(grey20)
stl_colour(grey20)
cylinder(d = cable_d, h = 20, center = true);
}
}

View File

@@ -160,7 +160,7 @@ module strap_end(type = strap) { //! Generate the STL for end piece
//
module strap_end_assembly(type = strap)
assembly("strap_end") {
color(pp1_colour)
stl_colour(pp1_colour)
strap_end(type);
translate_z(strap_height(type) + strap_key(type))
@@ -175,7 +175,7 @@ module strap_assembly(length, type = strap) { //! Assembly with screws in place
screw_length = screw_shorter_than(washer_thickness(washer) + washer_thickness(penny) + insert_length(insert) + panel_clearance + counterbore);
color(pp4_colour) strap(length, type);
stl_colour(pp4_colour) strap(length, type);
strap_screw_positions(length, type)
translate_z(strap_height(type))

501
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>
<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 = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Layout">Layout</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Maths">Maths</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Jack">Jack</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
</table>
---
<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
@@ -65,14 +112,11 @@ Also single bearing balls are modelled as just a silver sphere and a BOM entry.
| ```bb_bore(type)``` | Internal diameter |
| ```bb_colour(type)``` | Shield colour, "silver" for metal |
| ```bb_diameter(type)``` | External diameter |
| ```bb_hub(type)``` | Inner rim thickness guesstimate |
| ```bb_name(type)``` | Part code without shield type suffix |
| ```bb_rim(type)``` | Outer rim thickness guesstimate |
| ```bb_width(type)``` | Width |
### Functions
| Function | Description |
|:--- |:--- |
| ```bb_rim(type)``` | Inner and outer rim thickness |
### Modules
| Module | Description |
|:--- |:--- |
@@ -88,7 +132,8 @@ Also single bearing balls are modelled as just a silver sphere and a BOM entry.
| 1 | ```ball_bearing(BB6200)``` | Ball bearing 6200-2RS 10mm x 30mm x 9mm |
| 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 |
| 4 | ``` bearing_ball(3)``` | Steel ball 3mm |
| 1 | ```ball_bearing(BB6808)``` | Ball bearing 6808-2RS 40mm x 52mm x 7mm |
| 5 | ``` bearing_ball(3)``` | Steel ball 3mm |
<a href="#top">Top</a>
@@ -572,6 +617,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>
---
@@ -892,6 +981,7 @@ Parametric green terminal blocks
| ```gt_back_depth(type)``` | Back ledge depth |
| ```gt_back_height(type)``` | Height at the back |
| ```gt_box_h(type)``` | Height of the cable entry box |
| ```gt_box_setback(type)``` | How far the contact box is set back from the front |
| ```gt_box_w(type)``` | Width inside the cable entry box |
| ```gt_depth(type)``` | Total front to back depth |
| ```gt_front_depth(type)``` | Front ledge depth |
@@ -903,7 +993,7 @@ Parametric green terminal blocks
| ```gt_top(type)``` | Depth at the top |
| ```gt_tube_h(type)``` | Height of optional tubes around the screws |
| ```gt_y_offset(type)``` | Offset of the pins from centre of the depth |
| ```gt_y_offset2(type)``` | Offset of the pins screws from the screws |
| ```gt_y_offset2(type)``` | Offset of the pins from the screws |
### Modules
| Module | Description |
@@ -916,8 +1006,9 @@ Parametric green terminal blocks
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```green_terminal(gt_6p35, 2)``` | Terminal block 2 way 0.25" |
| 1 | ```green_terminal(gt_3p5, 3)``` | Terminal block 3 way 3.5mm |
| 1 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
| 1 | ```green_terminal(gt_5p08, 3)``` | Terminal block 3 way 0.2" |
| 1 | ```green_terminal(gt_3p5, 4)``` | Terminal block 4 way 3.5mm |
| 1 | ```green_terminal(gt_2p54, 5)``` | Terminal block 5 way 0.1" |
<a href="#top">Top</a>
@@ -1315,6 +1406,68 @@ 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)``` | Ampmeter 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 |
### 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>
---
@@ -1521,68 +1674,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 +1947,60 @@ 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 |
| ```pmeter_bezel(type)``` | Bezel size |
| ```pmeter_bezel_r(type)``` | Bezel radius |
| ```pmeter_pcb(type)``` | Optional PCB for open types |
| ```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_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 |
<a href="#top">Top</a>
---
@@ -1905,6 +2050,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 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 |
@@ -1912,6 +2058,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```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,6 +2084,43 @@ 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 | ```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 |
| 1 | ```led(LED5mm, "orange")``` | LED 5 mm orange |
| 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_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 |
| 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(LED0805, red)``` | SMD LED 0805 red |
| 1 | ```square_button(button_6mm)``` | Square button 6mm |
| 1 | ```pcb(TMC2130)``` | TMC2130 |
| 1 | ```green_terminal(gt_5p08, 2)``` | Terminal block 2 way 0.2" |
| 2 | ```green_terminal(gt_6p35, 2)``` | Terminal block 2 way 0.25" |
| 1 | ```green_terminal(gt_5x17, 2)``` | Terminal block 2 way 5mm |
| 2 | ```green_terminal(gt_2p54, 3)``` | Terminal block 3 way 0.1" |
| 1 | ```terminal_35(3)``` | Terminal block 3 way 3.5mm |
| 1 | ```green_terminal(gt_5x11, 3)``` | Terminal block 3 way 5mm |
| 1 | ```green_terminal(gt_5x17, 3)``` | Terminal block 3 way 5mm |
| 2 | ```green_terminal(gt_3p5, 4)``` | Terminal block 4 way 3.5mm |
| 1 | ```terminal_35(4)``` | Terminal block 4 way 3.5mm |
| 1 | ```pcb(TestPCB)``` | Test PCB |
@@ -1991,6 +2175,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 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 |
@@ -1998,6 +2183,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```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 |
@@ -2029,7 +2215,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```d_plug(DCONN15, pcb = true)``` | D-type 15 way PCB mount plug |
| 1 | ```pcb(DuetE)``` | Duet 2 Ethernet electronics |
| 1 | ```pcb(Duex2)``` | Duex2 expansion board |
| 1 | ```pcb(Duex5)``` | Duex5 expasnion board |
| 1 | ```pcb(Duex5)``` | Duex5 expansion board |
| 1 | ```pcb(EnviroPlus)``` | Enviro+ |
| 1 | ```pcb(ExtruderPCB)``` | Extruder connection PCB |
| 1 | ```pcb(Keyes5p1)``` | Keyes5.1 Arduino Uno expansion board |
@@ -2040,7 +2226,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```molex_254(3)``` | Molex KK header 3 way |
| 16 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 30 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 16 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 12 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 1 | ```pcb(PI_IO)``` | PI_IO V2 |
| 1 | ```pcb(PSU12V1A)``` | PSU 12V 1A |
@@ -2062,17 +2248,18 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 4 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
| 12 | ```screw(M2p5_pan_screw, 25)``` | Screw M2.5 pan x 25mm |
| 4 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 4 | ```screw(M3_cap_screw, 30)``` | Screw M3 cap x 30mm |
| 8 | ```screw(M3_cap_screw, 30)``` | Screw M3 cap x 30mm |
| 4 | ```screw(M3_cap_screw, 35)``` | Screw M3 cap x 35mm |
| 8 | ```screw(M4_cap_screw, 30)``` | Screw M4 cap x 30mm |
| 4 | ```screw(M4_cap_screw, 35)``` | Screw M4 cap x 35mm |
| 4 | ```screw(M4_cap_screw, 30)``` | Screw M4 cap x 30mm |
| 8 | ```screw(M4_cap_screw, 35)``` | Screw M4 cap x 35mm |
| 1 | ```pcb(TP4056)``` | TP4056 Li-lon Battery charger module |
| 3 | ```terminal_35(2)``` | Terminal block 2 way 3.5mm |
| 2 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
| 1 | | USB A to Mini B lead |
| 1 | ```pcb(WD2002SJ)``` | WD2002SJ Buck Boost DC-DC converter |
| 16 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 30 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 16 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 12 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
| 1 | ```pcb(ZC_A0591)``` | ZC-A0591 ULN2003 driver PCB |
@@ -2089,14 +2276,15 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 4 | pcb_spacer25130_2.stl |
| 4 | pcb_spacer25140_2.stl |
| 4 | pcb_spacer25150_2.stl |
| 4 | pcb_spacer25170.stl |
| 4 | pcb_spacer25180.stl |
| 2 | pcb_spacer2570.stl |
| 4 | pcb_spacer30160.stl |
| 4 | pcb_spacer30210.stl |
| 4 | pcb_spacer30170.stl |
| 4 | pcb_spacer30220.stl |
| 4 | pcb_spacer3050.stl |
| 4 | pcb_spacer40180.stl |
| 4 | pcb_spacer40190.stl |
| 4 | pcb_spacer40200.stl |
| 4 | pcb_spacer40210.stl |
<a href="#top">Top</a>
@@ -2857,6 +3045,46 @@ 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 |
### Functions
| Function | Description |
|:--- |:--- |
| ```smd_100th(x)``` | Convert dimesion 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``` |
![smds](tests/png/smds.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```smd_led(LED0805, green)``` | SMD LED 0805 green |
<a href="#top">Top</a>
---
@@ -3087,6 +3315,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>
---
@@ -5171,11 +5448,15 @@ Simple tube or ring
---
<a name="BOM"></a>
## BOM
Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing. Assembly instructions can precede the module
definition that makes the assembly.
Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing.
Assembly instructions can precede the module definition that makes the assembly.
The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view. The resulting flat BOM is shown but
heirachical BOMs are also generated for real projects.
Assembly views shown in the instructions can be large or small and this is deduced by looking at the size of the printed parts involved and if any routed
parts are used.
This heuristic isn't always correct, so the default can be overridden by setting the ```big``` parameter of ```assembly``` to ```true``` or ```false```.
The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
[utils/core/bom.scad](utils/core/bom.scad) Implementation.
@@ -5194,7 +5475,7 @@ heirachical BOMs are also generated for real projects.
### Modules
| Module | Description |
|:--- |:--- |
| ```assembly(name)``` | Name an assembly that will appear on the BOM, there needs to a module named ```<name>_assembly``` to make it |
| ```assembly(name, big = undef)``` | Name an assembly that will appear on the BOM, there needs to a module named ```<name>_assembly``` to make it. ```big``` can force big or small assembly diagrams. |
| ```dxf(name)``` | Name a dxf that will appear on the BOM, there needs to a module named ```<name>_dxf``` to make it |
| ```explode(d, explode_children = false, offset = [0,0,0])``` | Explode children by specified Z distance or vector ```d```, option to explode grand children |
| ```hidden()``` | Make item invisible, except on the BOM |
@@ -5205,6 +5486,7 @@ heirachical BOMs are also generated for real projects.
| ```pose_hflip(exploded = undef)``` | Pose an STL or assembly for rendering to png by flipping around the Y axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only. |
| ```pose_vflip(exploded = undef)``` | Pose an STL or assembly for rendering to png by flipping around the X axis, ```exploded = true for``` just the exploded view or ```false``` for unexploded only. |
| ```stl(name)``` | Name an stl that will appear on the BOM, there needs to a module named ```<name>_stl``` to make it |
| ```stl_colour(colour = pp1_colour, alpha = 1)``` | Colour an stl where it is placed in an assembly. ```alpha``` can be used to make it appear transparent. |
| ```vitamin(description)``` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "wigit(42): Type 42 widget" |
![bom](tests/png/bom.png)
@@ -5328,10 +5610,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

@@ -29,6 +29,7 @@ import openscad
from time import *
from set_config import *
import json
import re
def find_scad_file(mname):
for filename in os.listdir(source_dir):
@@ -45,9 +46,20 @@ def find_scad_file(mname):
return filename
return None
class Part:
def __init__(self, args):
self.count = 1
for arg in args:
arg = arg.replace('true', 'True').replace('false', 'False').replace('undef', 'None')
exec('self.' + arg)
def data(self):
return self.__dict__
class BOM:
def __init__(self, name):
self.name = name
self.big = None
self.count = 1
self.vitamins = {}
self.printed = {}
@@ -60,14 +72,20 @@ class BOM:
assemblies[ass] = self.assemblies[ass].count
return {
"name" : self.name,
"big" : self.big,
"count" : self.count,
"assemblies" : assemblies,
"vitamins" : self.vitamins,
"printed" : self.printed,
"routed" : self.routed
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
"printed" : {p : self.printed[p].data() for p in self.printed},
"routed" : {r : self.routed[r].data() for r in self.routed}
}
def add_part(self, s):
args = []
match = re.match(r'^(.*?\.stl|.*?\.dxf)\((.*)\)$', s) #look for name.stl(...) or name.dxf(...)
if match:
s = match.group(1)
args = [match.group(2)]
if s[-4:] == ".stl":
parts = self.printed
else:
@@ -76,15 +94,19 @@ class BOM:
else:
parts = self.vitamins
if s in parts:
parts[s] += 1
parts[s].count += 1
else:
parts[s] = 1
parts[s] = Part(args)
def add_assembly(self, ass):
def add_assembly(self, ass, args = []):
if ass in self.assemblies:
self.assemblies[ass].count += 1
else:
self.assemblies[ass] = BOM(ass)
bom = BOM(ass)
for arg in args:
arg = arg.replace('true', 'True').replace('false', 'False').replace('undef', 'None')
exec('bom.' + arg, locals())
self.assemblies[ass] = bom
def make_name(self, ass):
if self.count == 1:
@@ -119,10 +141,10 @@ class BOM:
for ass in sorted(self.assemblies):
bom = self.assemblies[ass]
if part in bom.vitamins:
file.write("%2d|" % bom.vitamins[part])
file.write("%2d|" % bom.vitamins[part].count)
else:
file.write(" |")
print("%3d" % self.vitamins[part], description, file=file)
print("%3d" % self.vitamins[part].count, description, file=file)
if self.printed:
if self.vitamins:
@@ -133,10 +155,10 @@ class BOM:
for ass in sorted(self.assemblies):
bom = self.assemblies[ass]
if part in bom.printed:
file.write("%2d|" % bom.printed[part])
file.write("%2d|" % bom.printed[part].count)
else:
file.write(" |")
print("%3d" % self.printed[part], part, file=file)
print("%3d" % self.printed[part].count, part, file=file)
if self.routed:
print(file=file)
@@ -146,10 +168,10 @@ class BOM:
for ass in sorted(self.assemblies):
bom = self.assemblies[ass]
if part in bom.routed:
file.write("%2d|" % bom.routed[part])
file.write("%2d|" % bom.routed[part].count)
else:
file.write(" |")
print("%3d" % self.routed[part], part, file=file)
print("%3d" % self.routed[part].count, part, file=file)
if self.assemblies:
print(file=file)
@@ -161,17 +183,22 @@ def parse_bom(file = "openscad.log", name = None):
main = BOM(name)
main.ordered_assemblies = []
stack = []
prog = re.compile(r'^(.*)\((.*)\)$')
for line in open(file):
pos = line.find('ECHO: "~')
if pos > -1:
s = line[pos + 8 : line.rfind('"')]
if s[-1] == '{':
ass = s[:-1]
args = []
match = prog.match(ass) #look for (...)
if match:
ass = match.group(1)
args = match.group(2).split(',')
if stack:
main.assemblies[stack[-1]].add_assembly(ass) #add to nested BOM
stack.append(ass)
main.add_assembly(ass) #add to flat BOM
main.add_assembly(ass, args) #add to flat BOM
if ass in main.ordered_assemblies:
main.ordered_assemblies.remove(ass)
main.ordered_assemblies.insert(0, ass)
@@ -186,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():
@@ -194,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","-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()
@@ -259,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

@@ -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]

View File

@@ -29,6 +29,7 @@ import openscad
from tests import do_cmd, update_image, colour_scheme, background
from deps import mtime
from colorama import init
import json
def usage():
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
@@ -48,6 +49,20 @@ def render(target, type):
#
parts = bom_to_parts(bom_dir, type)
#
# Read the json bom to get the colours
#
bom_file = bom_dir + "/bom.json"
with open(bom_file) as json_file:
flat_bom = json.load(json_file)
things = { 'stl' : 'printed', 'dxf' : 'routed' }[type]
colours = {}
for ass in flat_bom:
for part in ass[things]:
obj = ass[things][part]
if "colour" in obj:
colours[part] = obj["colour"]
#
# Remove unused png files
#
for file in os.listdir(target_dir):
@@ -55,7 +70,9 @@ def render(target, type):
if not file[:-4] + '.' + type in parts:
print("Removing %s" % file)
os.remove(target_dir + '/' + file)
#
# Render the parts
#
for part in parts:
part_file = target_dir + '/' + part
png_name = target_dir + '/' + part[:-4] + '.png'
@@ -64,10 +81,16 @@ def render(target, type):
#
if mtime(part_file) > mtime(png_name):
png_maker_name = "png.scad"
pp1 = [0, 146/255, 0]
colour = pp1
if part in colours:
colour = colours[part]
if not '[' in colour:
colour = '"' + colour + '"'
with open(png_maker_name, "w") as f:
f.write('color([0, 146/255, 0]) import("%s");\n' % part_file)
f.write('color(%s) import("%s");\n' % (colour, part_file))
cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500"
render = "--preview" if type == 'stl' else "--render"
render = "--preview" if type == 'stl' or colour != pp1 else "--render"
tmp_name = 'tmp.png'
openscad.run(colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-o", tmp_name, png_maker_name);
do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s"

View File

@@ -147,7 +147,7 @@ def tests(tests):
print("Can't find implementation!")
continue
vsplit = "AKR" + chr(ord('Z') + 1)
vsplit = "AJR" + chr(ord('Z') + 1)
vtype = locations[0][1]
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
if type == vtype:
@@ -201,7 +201,7 @@ def tests(tests):
dname = deps_name(deps_dir, scad.lower())
oldest = png_name if mtime(png_name) < mtime(bom_name) else bom_name
changed = check_deps(oldest, dname)
changed = times.check_have_time(changed, scad_name.lower())
changed = times.check_have_time(changed, scad_name)
changed = options.have_changed(changed, oldest)
if changed:
print(changed)
@@ -232,9 +232,10 @@ def tests(tests):
j = name.find(']]') + 2
name = name.replace(name[i : j], '[ ... ]')
desc = vit[1]
body += ['| %3d | %s | %s |' % (things[item], name, desc)]
body += ['| %3d | %s | %s |' % (things[item]["count"], name, desc)]
else:
body += ['| %3d | %s |' % (things[item], name)]
count = things[item] if thing == 'assemblies' else things[item]["count"]
body += ['| %3d | %s |' % (count, name)]
body += ['']
body += ['\n<a href="#top">Top</a>']

View File

@@ -48,6 +48,8 @@ def check_have_time(changed, name):
return changed
def add_time(name, start):
if name.lower() in times:
del times[name.lower()]
times[name] = round(time.time() - start, 3)
def print_times():

View File

@@ -52,22 +52,23 @@ def bom_to_assemblies(bom_dir, bounds_map):
# Decide if we need big or small assembly pictures
#
for bom in flat_bom:
big = False
for ass in bom["assemblies"]:
for b in flat_bom:
if b["name"] == ass:
if b["big"]:
if bom["big"] == None:
big = False
for ass in bom["assemblies"]:
for b in flat_bom:
if b["name"] == ass:
if b["big"]:
big = True
break
if not big:
for stl in bom["printed"]:
bounds = bounds_map[stl]
width = bounds[1][0] - bounds[0][0]
depth = bounds[1][1] - bounds[0][1]
if max(width, depth) > 80:
big = True
break
if not big:
for stl in bom["printed"]:
bounds = bounds_map[stl]
width = bounds[1][0] - bounds[0][0]
depth = bounds[1][1] - bounds[0][1]
if max(width, depth) > 80:
big = True
break
bom["big"] = big or bom["routed"]
break
bom["big"] = big or bom["routed"]
#
# Remove the main assembly if it is a shell
#
@@ -247,9 +248,9 @@ def views(target, do_assemblies = None):
for t in types:
for thing in ass[t]:
if thing in things[t]:
things[t][thing] += ass[t][thing]
things[t][thing] += ass[t][thing]["count"]
else:
things[t][thing] = ass[t][thing]
things[t][thing] = ass[t][thing]["count"]
for ass in flat_bom:
name = titalise(ass["name"][:-9]).replace(' ','&nbsp;')
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">%s</span> ' % name, file = doc_file, end = '')
@@ -264,7 +265,7 @@ def views(target, do_assemblies = None):
print(('| ' * len(flat_bom) + '| | **%s** |') % heading, file = doc_file)
for thing in sorted(things[t], key = lambda s: s.split(":")[-1]):
for ass in flat_bom:
count = ass[t][thing] if thing in ass[t] else 0
count = ass[t][thing]["count"] if thing in ass[t] else 0
print('| %s ' % pad(count if count else '.', 2, 1), file = doc_file, end = '')
name = ass["name"]
if name in totals:
@@ -300,7 +301,7 @@ def views(target, do_assemblies = None):
print("|Qty|Description|", file = doc_file)
print("|---:|:----------|", file = doc_file)
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
print("|%d|%s|" % (vitamins[v], v.split(":")[1]), file = doc_file)
print("|%d|%s|" % (vitamins[v]["count"], v.split(":")[1]), file = doc_file)
print("\n", file = doc_file)
printed = ass["printed"]
@@ -309,7 +310,7 @@ def views(target, do_assemblies = None):
keys = sorted(list(printed.keys()))
for i in range(len(keys)):
p = keys[i]
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p], p), file = doc_file, end = '')
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p]["count"], p), file = doc_file, end = '')
if (i % 3) == 2 or i == len(printed) - 1:
n = (i % 3) + 1
print('\n|%s' % ('---|' * n), file = doc_file)
@@ -325,7 +326,7 @@ def views(target, do_assemblies = None):
keys = sorted(list(routed.keys()))
for i in range(len(keys)):
r = keys[i]
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r], r), file = doc_file, end = '')
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r]["count"], r), file = doc_file, end = '')
if (i % 3) == 2 or i == len(routed) - 1:
n = (i % 3) + 1
print('\n|%s' % ('---|' * n), file = doc_file)

View File

@@ -67,7 +67,7 @@ module widgit_dxf() {
//! * Push the insert into the base with a soldering iron heated to 200&deg;C
module widgit_base_assembly()
assembly("widgit_base") {
color(pp1_colour)
stl_colour(pp1_colour)
widgit_stl();
translate_z(height)

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

@@ -19,11 +19,14 @@
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>
gt_5x17 = ["gt_5x17", 5, 10, 17, 5, 11, 0.4, 9, 2,1.5, 1, 3, 6, 0, 0, 0];
gt_5x11 = ["gt_5x11", 5, 8, 11, 5, 7, 0.4, 7, 1.5,1.5, 1,2.5, 6, 0, 0, 0];
gt_5x17 = ["gt_5x17", 5, 10, 17, 5, 11, 0.4, 9, 2,1.5, 1, 3, 6, 0.5, 0, 0, 0];
gt_5x11 = ["gt_5x11", 5, 8, 11, 5, 7, 0.4, 7, 1.5,1.5, 1,2.5, 6, 0.5, 0, 0, 0];
TMC2130HeatSinkColor = "DeepSkyBlue";
TMC2130 = ["TMC2130", "TMC2130",
@@ -44,62 +47,82 @@ TMC2130 = ["TMC2130", "TMC2130",
];
test_pcb = ["TestPCB", "Test PCB",
50, 500, 1.6, // length, width, thickness
100, 250, 1.6, // length, width, thickness
3, // Corner radius
2.75, // Mounting hole diameter
6, // Pad around mounting hole
5.5, // Pad around mounting hole
"green",// Color
false, // True if the parts should be separate BOM items
true, // True if the parts should be separate BOM items
// hole offsets
[ [3, 3], [3, -3], [-3, 3], [-3, -3] ],
// components
[
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 0, "trimpot10", true],
[ 10, 2, 0, "smd_led", LED0805, "red"],
[ 10, 10, 0, "2p54header", 4, 1],
[ 25, 10, 0, "2p54header", 5, 1, undef, "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],
[ 10, 60, 180, "rj45"],
[ 8, 80, 180, "usb_A"],
[ 8, 100, 180, "usb_Ax2"],
[ 3, 120, 180, "usb_uA"],
[ 8, 140, 180, "usb_B"],
[ 10, 160, 0, "buzzer"],
[ 25, 160, 0, "buzzer", 4.5, 8.5],
[ 10, 175, 0, "potentiometer"],
[ 30, 175, 0, "potentiometer", 7, 8],
[ 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, 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, 220, 180, "hdmi"],
[ 3, 240, 180, "mini_hdmi"],
[ 10, 250, 0, "flex"],
[ 10, 265, 0, "flat_flex"],
[ 10, 280, 0, "D_plug", DCONN9],
[ 10, 300, 0, "molex_hdr", 2],
[ 10, 310, 0, "jst_xh", 2],
[ 10, 320, 180, "term254", 3],
[ 20, 320, 180, "term254", 3, undef, grey20],
[ 10, 340, 180, "gterm35", 4, [1,2]],
[ 20, 340, 180, "gterm35", 4, [1,2], "red"],
[ 30, 340, 180, "gterm", gt_5x11, 3],
[ 10, 360, 180, "gterm635", 2],
[ 25, 360, 180, "gterm635", 2, undef, "blue"],
[ 40, 360, 180, "gterm", gt_5x17, 2, undef, grey20],
[ 40, 340, 180, "gterm", gt_5x17, 3, [1], "red"],
[ 10, 380, 180, "term35", 4],
[ 20, 380, 180, "term35", 3, "lime"],
[ 10, 400, 0, "transition", 5],
[ 10, 410, 0, "block", 10, 5, 8, "orange"],
[ 10, 420, 0, "button_6mm"],
[ 10, 435, 0, "microswitch", small_microswitch],
[ 12, 450, 0, "pcb", 11, TMC2130 ],
[ 12, 456, 0, "2p54socket", 8, 1 ],
[ 12, 444, 0, "2p54socket", 8, 1, undef, undef, undef, "red" ],
[ 10, 470, 0, "standoff", 5, 4.5, 12.5, 2.54],
[ 6, 480, 180, "uSD", [12, 11.5, 1.4]],
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 0, "trimpot10", true],
[ 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"],
[ 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],
[ 75, 70, 180, "gterm508",2, undef, "blue"],
[ 50, 90, 180, "gterm35", 4, [1,2]],
[ 63, 90, 180, "gterm35", 4, [1,2], "red"],
[ 75, 90, 180, "gterm", gt_5x11, 3],
[ 90, 90, 180, "gterm", gt_5x17, 3, [1], "red"],
[ 55, 110, 180, "gterm635", 2],
[ 75, 110, 180, "gterm635", 2, undef, "blue"],
[ 90, 110, 180, "gterm", gt_5x17, 2, undef, grey20],
[ 50, 130, 180, "term35", 4],
[ 70, 130, 180, "term35", 3, "lime"],
[ 50, 150, 0, "transition", 5],
[ 50, 160, 0, "block", 10, 5, 8, "orange"],
[ 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" ],
[ 50, 220, 0, "standoff", 5, 4.5, 12.5, 2.54],
[ 50, 240, 0, "potentiometer"],
[ 75, 240, 0, "potentiometer", 7, 8],
],
// accessories
[]

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,13 @@
// 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(l = smd_leds) smd_led_size(l).x], 1)
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
translate([0, meter_bezel_width() + 5])
vflip()
meter_assembly();
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

@@ -22,14 +22,14 @@ use <../printed/cable_grommets.scad>
module cable_grommets() {
rotate(90)
color(pp1_colour) ribbon_grommet(20, 3);
stl_colour(pp1_colour) ribbon_grommet(20, 3);
translate([20, 0])
round_grommet_assembly(6, 3);
translate([40, 0])
rotate(90)
color(pp1_colour) mouse_grommet(5, 3);
stl_colour(pp1_colour) mouse_grommet(5, 3);
}
if($preview)

View File

@@ -20,15 +20,15 @@ include <../utils/core/core.scad>
use <../printed/carriers.scad>
module carriers() {
color(pp1_colour) ESP12F_carrier_stl();
stl_colour(pp1_colour) ESP12F_carrier_stl();
translate([0, 15])
rotate(90)
color(pp1_colour) TP4056_carrier_stl();
stl_colour(pp1_colour) TP4056_carrier_stl();
translate([0, 25])
rotate(90)
color(pp1_colour) MT3608_carrier_stl();
stl_colour(pp1_colour) MT3608_carrier_stl();
}
carriers();

View File

@@ -24,6 +24,6 @@ use <../utils/layout.scad>
module fan_guards()
layout([for(f = fans) fan_width(f)], 10)
color(pp1_colour) fan_guard(fans[$i], spokes = fan_width(fans[$i]) > 60 ? 8 : 4);
stl_colour(pp1_colour) fan_guard(fans[$i], spokes = fan_width(fans[$i]) > 60 ? 8 : 4);
fan_guards();

View File

@@ -27,7 +27,7 @@ module inserts() {
translate([10 * i, 0])
insert(inserts[i]);
color(pp1_colour)
stl_colour(pp1_colour)
translate([len(inserts) * 10, 0]) {
insert_lug(inserts[0], 2, 1);

View File

@@ -29,7 +29,7 @@ module light_strips()
for(end = [-1, 1])
translate([end * (light_strip_cut_length(light, segs) / 2 - d / 2), 0])
rotate([90, 0, 90])
color(pp1_colour) render()
stl_colour(pp1_colour) render()
translate_z(-d / 2)
light_strip_clip(light);
}

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_size(p).x], 20)
panel_meter(panel_meters[$i]);
if($preview)
panel_meters();

BIN
tests/png/axial.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 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: 86 KiB

After

Width:  |  Height:  |  Size: 98 KiB

BIN
tests/png/dip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

BIN
tests/png/led_meters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

BIN
tests/png/panel_meters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 161 KiB

BIN
tests/png/smds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
tests/png/swiss_clips.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 150 KiB

View File

@@ -34,7 +34,7 @@ module polyholes() {
children();
}
color(pp1_colour) linear_extrude(3, center = true)
stl_colour(pp1_colour) linear_extrude(3, center = true)
difference() {
square([100, 27]);
@@ -52,7 +52,7 @@ module polyholes() {
sizes = [1.5, 2, 3, 4];
for(i = [0 : len(sizes) - 1])
translate([i * 10, -10]) {
color(pp1_colour)
stl_colour(pp1_colour)
poly_tube(ir = ir, or = cir + sizes[i] * extrusion_width, h = 1);
rod(2 * ir, 3);

View File

@@ -93,7 +93,7 @@ module box1_base_stl()
module box1_assembly()
assembly("box1") {
color(pp1_colour) render() box1_case_stl();
stl_colour(pp1_colour) render() box1_case_stl();
pbox_inserts(box1);
@@ -142,7 +142,7 @@ module box2_base_stl()
module box2_assembly()
assembly("box2") {
color(pp1_colour) render() box2_case_stl();
stl_colour(pp1_colour) render() box2_case_stl();
pbox_inserts(box2);

View File

@@ -20,7 +20,7 @@
include <../utils/core/core.scad>
module teardrops() {
color(pp1_colour)
stl_colour(pp1_colour)
rotate([90, 0, -45])
difference() {
linear_extrude(3) {

View File

@@ -54,7 +54,7 @@ module wires() {
%cylinder(r = bundle_r, h = wire_l - 10, center = true);
}
color(pp1_colour) {
stl_colour(pp1_colour) {
rotate([90, 0, 90])
linear_extrude(thickness)
difference() {

View File

@@ -18,11 +18,15 @@
//
//
//! Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing. Assembly instructions can precede the module
//! definition that makes the assembly.
//! Bill Of Materials generation via echo and the ```bom.py``` script. Also handles exploded assembly views and posing.
//! Assembly instructions can precede the module definition that makes the assembly.
//!
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view. The resulting flat BOM is shown but
//! heirachical BOMs are also generated for real projects.
//! Assembly views shown in the instructions can be large or small and this is deduced by looking at the size of the printed parts involved and if any routed
//! parts are used.
//! This heuristic isn't always correct, so the default can be overridden by setting the ```big``` parameter of ```assembly``` to ```true``` or ```false```.
//!
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
//! The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
//
function bom_mode(n = 1) = $_bom >= n && (is_undef($on_bom) || $on_bom); //! Current BOM mode, 0 = none, 1 = printed and routed parts and assemblies, 2 includes vitamins as well
function exploded() = is_undef($exploded_parent) ? $exploded : 0; //! Returns the value of ```$exploded``` if it is defined, else ```0```
@@ -80,10 +84,11 @@ module pose_vflip(exploded = undef) //! Pose an STL or assembly for render
children();
module assembly(name) { //! Name an assembly that will appear on the BOM, there needs to a module named ```<name>_assembly``` to make it
if(bom_mode())
echo(str("~", name, "_assembly{"));
module assembly(name, big = undef) { //! Name an assembly that will appear on the BOM, there needs to a module named ```<name>_assembly``` to make it. ```big``` can force big or small assembly diagrams.
if(bom_mode()) {
args = is_undef(big) ? "" : str("(big=", big, ")");
echo(str("~", name, "_assembly", args, "{"));
}
no_pose()
if(is_undef($child_assembly))
let($child_assembly = true)
@@ -96,14 +101,26 @@ module assembly(name) { //! Name an assembly that will appear on
echo(str("~}", name, "_assembly"));
}
module stl_colour(colour = pp1_colour, alpha = 1) { //! Colour an stl where it is placed in an assembly. ```alpha``` can be used to make it appear transparent.
$stl_colour = colour;
color(colour, alpha)
children();
}
module stl(name) { //! Name an stl that will appear on the BOM, there needs to a module named ```<name>_stl``` to make it
if(bom_mode())
echo(str("~", name, ".stl"));
if(bom_mode()) {
colour = is_undef($stl_colour) ? pp1_colour : $stl_colour;
echo(str("~", name, ".stl(colour='", colour, "')"));
}
}
module dxf(name) { //! Name a dxf that will appear on the BOM, there needs to a module named ```<name>_dxf``` to make it
if(bom_mode())
echo(str("~", name, ".dxf"));
if(bom_mode()) {
if(is_undef($dxf_colour))
echo(str("~", name, ".dxf"));
else
echo(str("~", name, ".dxf(colour='", $dxf_colour, "')"));
}
}
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert ```value``` to a string or quote it if it is already a string

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
//

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

@@ -26,36 +26,51 @@
//! Also single bearing balls are modelled as just a silver sphere and a BOM entry.
//
include <../utils/core/core.scad>
include <../utils/tube.scad>
function bb_name(type) = type[0]; //! Part code without shield type suffix
function bb_bore(type) = type[1]; //! Internal diameter
function bb_diameter(type) = type[2]; //! External diameter
function bb_width(type) = type[3]; //! Width
function bb_colour(type) = type[4]; //! Shield colour, "silver" for metal
function bb_rim(type) = bb_diameter(type) / 10; //! Inner and outer rim thickness
function bb_rim(type) = type[5]; //! Outer rim thickness guesstimate
function bb_hub(type) = type[6]; //! Inner rim thickness guesstimate
module ball_bearing(type) { //! Draw a ball bearing
shield = bb_colour(type);
suffix = shield == "silver" ? "ZZ " : "-2RS ";
vitamin(str("ball_bearing(BB", bb_name(type), "): Ball bearing ", bb_name(type), suffix, bb_bore(type), "mm x ", bb_diameter(type), "mm x ", bb_width(type), "mm"));
rim = bb_rim(type);
hub = bb_hub(type);
h = bb_width(type);
od = bb_diameter(type);
id = bb_bore(type);
module tube(od, id, h)
linear_extrude(h, center = true, convexity = 5)
difference() {
circle(d = od);
circle(d = id);
}
or = bb_diameter(type) / 2;
ir = bb_bore(type) / 2;
color("silver") {
tube(od, od - rim, h);
tube(id + rim, id, h);
$fn = 360;
rim_chamfer = rim / 6;
rotate_extrude()
hull() {
translate([or - rim / 2, 0])
square([rim, h - 2 * rim_chamfer], center = true);
translate([or - rim / 2 - rim_chamfer, 0])
square([rim - rim_chamfer, h], center = true);
}
hub_chamfer = hub / 6;
rotate_extrude()
hull() {
translate([ir + hub / 2, 0])
square([hub, h - 2 * hub_chamfer], center = true);
translate([ir + hub / 2 + hub_chamfer, 0])
square([hub - hub_chamfer, h], center = true);
}
}
color(shield) tube(od - rim, id + rim, h - 1);
color(shield) tube(or - rim - eps, ir + hub + eps, h - 1);
if($children)
translate_z(bb_width(type) / 2)

View File

@@ -16,11 +16,11 @@
// 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"]; // 624 ball bearing for idlers
BB608 = ["608", 8, 22, 7, "OrangeRed"]; // 608 bearings for wades
BB6200 = ["6200", 10, 30, 9, "black"]; // 6200 bearings for KP pillow blocks
BB6201 = ["6201", 12, 32, 10, "black"]; // 6201 bearings for KP pillow blocks
ball_bearings = [BB624, BB608, BB6200, BB6201];
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];
use <ball_bearing.scad>

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(grey20) {
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(grey20) {
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

@@ -35,9 +35,10 @@ function gt_screw_r(type) = type[9]; //! Screw head radius
function gt_front_t(type) = type[10]; //! Thickness of frame around the front aperture
function gt_box_w(type) = type[11]; //! Width inside the cable entry box
function gt_box_h(type) = type[12]; //! Height of the cable entry box
function gt_y_offset(type) = type[13]; //! Offset of the pins from centre of the depth
function gt_y_offset2(type) = type[14]; //! Offset of the pins screws from the screws
function gt_tube_h(type) = type[15]; //! Height of optional tubes around the screws
function gt_box_setback(type) = type[13]; //! How far the contact box is set back from the front
function gt_y_offset(type) = type[14]; //! Offset of the pins from centre of the depth
function gt_y_offset2(type) = type[15]; //! Offset of the pins from the screws
function gt_tube_h(type) = type[16]; //! Height of optional tubes around the screws
module green_terminal(type, ways, skip = [], colour = "lime") { //! Draw green terminal blocks, skip can be used to remove pins.
pitch = gt_pitch(type);
@@ -60,7 +61,7 @@ module green_terminal(type, ways, skip = [], colour = "lime") { //! Draw green t
box_h2 = gt_box_h(type);
y = gt_y_offset(type);
y2 = gt_y_offset2(type);
box_front = y + depth / 2 - 2;
box_front = y + depth / 2 - gt_box_setback(type);
box_back = y - depth / 2 + 1;
module horizontal_section()
@@ -141,37 +142,37 @@ module green_terminal(type, ways, skip = [], colour = "lime") { //! Draw green t
}
if(!skip)
color("silver") {
slot_depth = 1;
screw_top = height - 0.5;
pin_l = 3.3;
translate([y2, 0]) {
translate_z(screw_top - 2 * slot_depth) // screw head
cylinder(r = screw_r, h = slot_depth);
slot_depth = 1;
screw_top = height - 0.5;
pin_l = 3.3;
translate([y2, 0]) {
translate_z(screw_top - 2 * slot_depth) // screw head
cylinder(r = screw_r, h = slot_depth);
translate_z(screw_top - slot_depth) // screw head
linear_extrude(slot_depth)
difference() {
circle(screw_r);
translate_z(screw_top - slot_depth) // screw head
linear_extrude(slot_depth)
difference() {
circle(screw_r);
square([10, screw_r / 4], center = true);
}
}
translate([box_back, 0, ledge_height / 2]) {
rotate([0, 90, 0])
linear_extrude(box_front - box_back)
difference() {
square([box_h2, box_w2], center = true);
square([box_h2 - 0.1, box_w2 - 0.1], center = true);
}
cube([1, box_w2, box_h2], center = true); // terminal back
}
translate_z(-pin_l)
cube([0.44, 0.75, pin_l]); // pin
square([10, screw_r / 4], center = true);
}
}
translate([box_back, 0, ledge_height / 2]) {
rotate([0, 90, 0])
linear_extrude(box_front - box_back)
difference() {
square([box_h2, box_w2], center = true);
square([box_h2 - 0.1, box_w2 - 0.1], center = true);
}
cube([1, box_w2, box_h2], center = true); // terminal back
}
translate_z(-pin_l / 2)
cube([0.44, 0.75, pin_l], center = true); // pin
}
}
for(i = [0: ways - 1])
translate([0, i * pitch - width / 2 + pitch / 2])

View File

@@ -19,17 +19,19 @@
// Green terminal blocks
//
// f b y y
// h h f h b s f o o
// p d e e d e d c r f f t
// i e i i e i e r o b b f f u
// t p g t g p g p e n o o s s b
// c t h o h t h t w t x x e t e
// h h t p t h t h r t w h t 2 h
gt_2p54 = ["gt_2p54", 2.54, 6.6, 10, 3, 6, 0.4, 6.4, 1, 1, 0.2, 2, 2, 0, 0, 0];
gt_3p5 = ["gt_3p5", 3.5, 7.3, 8.5, 4, 5, 0.4, 4, 0, 1.35, 0.4, 1.8, 2, 0, 0, 0];
gt_6p35 = ["gt_6p35", 6.35, 12.6, 17.4, 6.8, 12, 0.4, 11, 2, 2.7, 0.8, 3.4, 4.2, 1.8, 1.1, 21.4];
// f b b y y
// h h f h b s f o o o
// p d e e d e d c r x f f t
// i e i i e i e r o b b f f u
// t p g t g p g p e n o o s s s b
// c t h o h t h t w t x x b e t e
// h h t p t h t h r t w h t 2 h
//
gt_2p54 = ["gt_2p54", 2.54, 6.6, 10, 3, 6, 0.4, 6.4, 1, 1, 0.2, 2, 2, 2, 0, 0, 0];
gt_3p5 = ["gt_3p5", 3.5, 7.3, 8.5, 4, 5, 0.4, 4, 0, 1.35, 0.4, 1.8, 2, 2, 0, 0, 0];
gt_5p08 = ["gt_5p08", 5.08, 7.9, 10, 5.0, 7, 0.0, 6.8, 1.45, 1.95, 0.5, 4.0, 5.4, 0.5, 0, 0, 0];
gt_6p35 = ["gt_6p35", 6.35, 12.6, 17.4, 6.8, 12, 0.4, 11, 2, 2.7, 0.8, 3.4, 4.2, 2, 1.8, 1.1, 21.4];
green_terminals = [gt_2p54, gt_3p5, gt_6p35];
green_terminals = [gt_2p54, gt_3p5, gt_5p08, gt_6p35];
use <green_terminal.scad>

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;
@@ -55,8 +55,8 @@ module hygrometer() { //! Draw a hygrometer
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

@@ -49,7 +49,7 @@ module led(type, colour = "red", lead = 5) { //! Draw specified LED with desired
}
}
color("silver")
for(side = [-1, 1], len = lead - side)
for(side = [-1, 1], len = lead - (lead < 3 ? 0 : side))
translate([side * led_pitch(type) / 2, 0, -len / 2])
vflip()
cube([led_lead_t(type), led_lead_t(type), len], center = true);

146
vitamins/led_meter.scad Normal file
View File

@@ -0,0 +1,146 @@
//
// 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]; //! Ampmeter 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();
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_pcb_size(type).y / 2 + meter_pos(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

@@ -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);
}
}

110
vitamins/panel_meter.scad Normal file
View File

@@ -0,0 +1,110 @@
//
// 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 <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
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_pcb(type) = type[10]; //! Optional PCB for open types
function pmeter_pcb_z(type) = type[11]; //! Distance of PCB from the back
function pmeter_depth(type) = pmeter_size(type).z - pmeter_bezel(type).z; //! Depth below bezel
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;
app = pmeter_aperture(type);
tab = pmeter_tab(type);
tab_z = pmeter_tab_z(type);
pcb = pmeter_pcb(type);
color("#94A7AB")
cube([app.x, app.y, 3 * eps], center = true);
color(grey30) union() {
difference() {
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);
}
hull() {
translate_z(bezel.z + eps) {
cube([app.x + app.z, app.y + app.z, eps], center = true);
cube([app.x, app.y, bezel.z * 2], center = true);
}
}
}
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);
}
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(pcb)
vflip()
translate_z(h - pcb_thickness(pcb) - pmeter_pcb_z(type))
pcb(pcb);
}
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,38 @@
//
// 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
//
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], 1.5, [1, 1], [36, 36, 0], [1.2, 10, 6], 15.5, 0];
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,
DSN_VC288PCB, 5];
panel_meters = [DSN_VC288, PZEM021, PZEM001];
use <panel_meter.scad>

View File

@@ -33,6 +33,10 @@ use <../utils/dogbones.scad>
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
@@ -82,6 +86,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);
}
@@ -104,7 +125,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() {
@@ -127,7 +148,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
@@ -755,7 +841,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])
@@ -781,45 +867,64 @@ 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, "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);
// Components that have a cutout parameter go in this section
if(show(comp, "2p54header")) pin_header(2p54header, comp[4], comp[5], param(6), false, 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, "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, "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, grey20));
}
}
}
@@ -988,7 +1093,7 @@ module pcb_assembly(type, height, thickness) { //! Draw PCB assembly with spaces
translate_z(height + pcb_thickness(type))
screw(screw, screw_length);
color(pp1_colour)
stl_colour(pp1_colour)
if(taper)
pcb_spacer(screw, height, taper = 2);
else

View File

@@ -18,6 +18,10 @@
//
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
// e i h a o a o o o
@@ -177,7 +181,7 @@ Duex2 = ["Duex2", "Duex2 expansion board",
],
[]];
Duex5 = ["Duex5", "Duex5 expasnion board",
Duex5 = ["Duex5", "Duex5 expansion board",
123, 100, 1.6, 0, 4.2, 0, "#2140BE", false, [[-4, 4], [-4, -4], [4, -4],[4, 4]],
concat(Duex2[11], [
[ 61.5, -81.2, 0, "chip", 10, 10, 2],
@@ -242,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([
@@ -324,7 +329,17 @@ 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] ],
[], [], [], [], M2p5_pan_screw];
[ [ 12.25, 8.3, -90, "jst_xh", 5],
[ -6.5, 10, 0, "2p54header", 1, 4],
[ 20.4, -4.5, 0, "2p54header", 4, 1],
[ 20.4, 11, 180, "pdip", 16, "ULN2803AN", true],
[ 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];
MT3608 = ["MT3608", "MT3608 boost converter module", 37, 17, 1.2, 2, 1.5, [5, 3], "#2140BE", false, [[3.0725, 5.095], [3.0725, -5.095], [-3.0725, 5.095], [-3.0725, -5.095]],
@@ -334,9 +349,23 @@ 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, 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"],
],
[]];
PERF80x20 = ["PERF80x20", "Perfboard 80 x 20mm", 80, 20, 1.6, 0, 2.3, 0, "green", true, [[2,2],[-2,2],[2,-2],[-2,-2]], [], [], [5.87, 3.49]];
PERF70x50 = ["PERF70x50", "Perfboard 70 x 50mm", 70, 50, 1.6, 0, 2.3, 0, "green", true, [[2,2],[-2,2],[2,-2],[-2,-2]], [], [], [5.87, 3.49]];
@@ -362,7 +391,7 @@ RAMPSEndstop = ["RAMPSEndstop", "RAMPS Endstop Switch",
[]];
pcbs = [TP4056, MT3608, RAMPSEndstop, ExtruderPCB, PI_IO, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PSU12V1A, RPI3, DuetE, Duex2, Duex5, Melzi];
pcbs = [TP4056, MT3608, RAMPSEndstop, ExtruderPCB, PI_IO, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PSU12V1A, WD2002SJ, RPI3, DuetE, Duex2, Duex5, Melzi];
perfboards = [PERF74x51, PERF70x50, PERF60x40, PERF70x30, PERF80x20];

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

View File

@@ -23,6 +23,7 @@
include <../utils/core/core.scad>
use <washer.scad>
use <nut.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/thread.scad>
include <inserts.scad>

View File

@@ -83,6 +83,7 @@ module render_sheet(type, colour = false) //! Render a sheet in the correct colo
render() children();
module render_2D_sheet(type, colour = false) //! Extrude a 2D sheet template and give it the correct colour
color(colour ? colour : sheet_colour(type))
linear_extrude(sheet_thickness(type), center = true)
children();
let($dxf_colour = colour ? colour : sheet_colour(type))
color($dxf_colour)
linear_extrude(sheet_thickness(type), center = true)
children();

80
vitamins/smd.scad Normal file
View File

@@ -0,0 +1,80 @@
//
// 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/>.
//
//
//! Surface mount components for PCBs.
//
include <../utils/core/core.scad>
use <../utils/tube.scad>
function smd_led_size(type) = type[1]; //! Body length, width and height
function smd_led_lens(type) = type[2]; //! Lens length width and height
function smd_led_height(type) = //! Total height
smd_led_size(type).z + smd_led_lens(type).z;
function smd_100th(x) = //! Convert dimesion to 1/100" notation
let(s = str(round(x / inch(0.01))))
len(s) < 2 ? str("0", s) : s;
function smd_size(size) = //! Convert size to 1/100" notation
str(smd_100th(size.x), smd_100th(size.y));
module smd_led(type, colour, cutout) { //! Draw an SMD LED with specified ```colour```
size = smd_led_size(type);
vitamin(str("smd_led(", type[0], ", ", colour, "): SMD LED ", smd_size(size), " ", colour));
lens = smd_led_lens(type);
r = size.y * 0.32;
$fn = 32;
if(cutout)
poly_drill(r = 2.85 / 2, h = 100, center = false); // For lightguide made from transparent PLA filament
else {
color("white")
linear_extrude(size.z)
difference() {
square([size.x, size.y], center = true);
for(end = [-1, 1])
translate([end * size.x / 2, 0])
circle(r);
}
color(gold)
linear_extrude(size.z)
intersection() {
square([size.x, size.y], center = true);
for(end = [-1, 1])
translate([end * size.x / 2, 0])
ring(or = r, ir = r / 2);
}
color(colour, 0.9)
translate_z(size.z)
hull() {
cube([lens.x, lens.y, eps], center = true);
slant = lens.z * tan(15);
translate_z(lens.z / 2)
cube([lens.x - slant, lens.y - slant, lens.z], center = true);
}
}
}

28
vitamins/smds.scad Normal file
View File

@@ -0,0 +1,28 @@
//
// 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
//
LED0805 = ["LED0805", [2, 1.25, 0.46], [1.4, 1.25, 0.54]];
smd_leds = [LED0805];
use <smd.scad>

148
vitamins/swiss_clip.scad Normal file
View File

@@ -0,0 +1,148 @@
//
// 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/>.
//
//
//! 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.
//
include <../utils/core/core.scad>
function sclip_length(type) = type[1]; //! Total external length
function sclip_height(type) = type[2]; //! External height
function sclip_width(type) = type[3]; //! Width
function sclip_thickness(type) = type[4]; //! Thickness of the metal
function sclip_radius(type) = type[5]; //! Bend radius
function sclip_arm_width(type) = type[6]; //! Width of spring arms
function sclip_spigot(type) = type[7]; //! Spigot length, width, height
function sclip_hook(type) = type[8]; //! hook, length, width
function sclip_hinge_offset(type) = type[9]; //! Offset of hinge
function sclip_arm_length(type) = type[10]; //! Length of arms
function sclip_max_gap(type) = type[11]; //! Maximum opening
function arm_angle(type, open) = asin((sclip_height(type) - 2 * sclip_thickness(type) - open) / sclip_arm_length(type));
function spigot_angle(type, open) =
let(arm_w = sclip_arm_width(type), w = sclip_width(type) - 2 * arm_w)
(arm_angle(type, 0) - arm_angle(type, open)) * 2 * arm_w / w;
module swiss_clip_hole(type, open, h = 0) { //! Drill hole for spigot
spigot = sclip_spigot(type);
angle = spigot_angle(type, open);
t = sclip_thickness(type);
or = sclip_radius(type);
ir = or - t;
shadow = (spigot.z - or) * sin(angle) - or * cos(angle) + or + t * cos(angle);
r = sqrt(sqr(shadow) + sqr(spigot.y)) / 2;
offset = sclip_hinge_offset(type);
hpot = offset - t;
translate([sclip_length(type) - t - ir - offset + hpot * cos(angle) - (spigot.z - t) * sin(angle) + shadow / 2, 0])
drill(r + 0.1, h);
}
module swiss_clip(type, open = 0.9) { //! Draw a Swiss clip open by specified amount
vitamin(str("swiss_clip(", type[0], "): Swiss picture clip ", type[0], " ", sclip_max_gap(type),"mm"));
length = sclip_length(type);
width = sclip_width(type);
height = sclip_height(type);
spigot = sclip_spigot(type);
hook = sclip_hook(type);
offset = sclip_hinge_offset(type);
t = sclip_thickness(type);
arm_l = sclip_arm_length(type);
arm_w = sclip_arm_width(type);
w = width - 2 * arm_w;
or = sclip_radius(type);
ir = or - t;
angle = arm_angle(type, open);
angle2 = spigot_angle(type, open);
$fn = 360;
color("silver") translate([-t - ir, 0, -height + t]) {
translate([length - offset - arm_l, -w / 2]) // Narrow part of base
cube([arm_l, w, t]);
translate([length - offset, 0, t])
rotate([0, -angle2, 0])
translate([offset - length, 0, -t]) {
translate([length - offset, -width / 2]) // Wide part of base
cube([offset - spigot.x, width, t]);
translate([length - spigot.x, -spigot.y / 2]) // Spigot base
cube([spigot.x - or, spigot.y, t]);
translate([length - t, -spigot.y / 2, or]) // Spigot stem
cube([t, spigot.y, spigot.z - or]);
translate([length - or, -spigot.y / 2, or]) // Spigot bend
rotate([-90, 0, 0])
rotate_extrude(angle = 90)
translate([ir, 0])
square([t, spigot.y]);
}
translate([or, -hook.y / 2]) // Hook base
cube([hook.x, hook.y, t]);
translate([0, -hook.y / 2, or]) // Hook stem
cube([t, hook.y, height - 2 * or]);
translate([or, -hook.y / 2, or]) // Hook lower bend
rotate([0, 90, 90])
rotate_extrude(angle = 90)
translate([ir, 0])
square([t, hook.y]);
translate([or, -hook.y / 2, height - t]) // Hook top
cube([hook.x - or, hook.y, t]);
translate([or, hook.y / 2, height - or]) // Hook top bend
rotate([0, -90, 90])
rotate_extrude(angle = 90)
translate([ir, 0])
square([t, hook.y]);
translate([length - offset, 0, t]) // Arms
rotate([0, angle, 0])
for(side = [-1, 1])
translate([-arm_l, side * (arm_w + w) / 2 - arm_w / 2, -t])
cube([arm_l, arm_w, t]);
translate([length - offset, -w / 2, t]) // Central gusset
rotate([-90, 0, 0])
rotate(90 - angle2)
rotate_extrude(angle = angle2)
translate([0, 0])
square([t, w]);
for(side = [-1, 1]) // Arm gussets
translate([length - offset, side * (arm_w + w) / 2 - arm_w / 2, t])
rotate([-90, 0, 0])
rotate(90 - angle2)
rotate_extrude(angle = angle + angle2)
translate([0, 0])
square([t, arm_w]);
}
}

29
vitamins/swiss_clips.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/>.
//
//
//! Swiss picture clip.
//! Used for holding glass on 3D printer beds.
//
UKPFS1008_10 = ["UKPFS1008_10", 39, 13, 13, 0.75, 1.5, 4, [3.5, 2.2, 4.4], [5.25, 4.12], 9, 37 - 9, 11];
swiss_clips = [ UKPFS1008_10 ];
use <swiss_clip.scad>

View File

@@ -162,7 +162,7 @@ assembly(vero_assembly(type)) {
else
screw_and_washer(screw, screw_length);
color(pp1_colour) pcb_spacer(screw, height);
stl_colour(pp1_colour) pcb_spacer(screw, height);
translate_z(-thickness)
vflip()

View File

@@ -122,7 +122,7 @@ module printed_washer(type, name = false) { //! Create printed washer
t = round_to_layer(washer_thickness(type));
or = washer_radius(type);
ir = washer_id(type) / 2;
color(pp1_colour)
stl_colour(pp1_colour)
linear_extrude(t, center = false, convexity = 2)
poly_ring(or, ir);