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

Compare commits

...

21 Commits

Author SHA1 Message Date
Chris Palmer
42fccc1afb Added bezier_join().
Moved path_length() from sweep.scad to maths.scad.
2022-02-23 11:53:02 +00:00
Chris Palmer
76aa613093 Updated changelog. 2022-02-15 22:20:46 +00:00
Chris Palmer
0e2778e13d Cables can now have a list of wire colours.
Added a constructor for cables.
2022-02-15 21:51:09 +00:00
Chris Palmer
50e23e5f81 Added silkscreen text to PCBs. 2022-02-15 21:49:25 +00:00
Chris Palmer
59eeb2c5d4 Trimmed the ribbon clamp tape. 2022-02-15 10:52:38 +00:00
Chris Palmer
7ea4dbe6cb Fixed double application of r2sides() in rounded_path().
Added check for radius too big for corner in rounded_path().
Spiral paths can now have 0 twists.
2022-02-15 10:44:13 +00:00
Chris Palmer
0d062c24fa Updated changelog. 2022-02-11 09:11:05 +00:00
Chris Palmer
95b6771811 Added printed cable clips. 2022-02-11 09:08:51 +00:00
Chris Palmer
ed46cbb147 Fixed cable_bundle() bugs and added test.
Added cable_bundle_positions().
Can now mark cables as ribbon to force a flat layout.
2022-02-11 09:07:34 +00:00
Chris Palmer
14ba135169 Updated changelog. 2022-02-09 22:05:58 +00:00
Chris Palmer
2a2b7d8bd6 Added a second example project. 2022-02-09 21:57:56 +00:00
Chris Palmer
055b4e7102 Added SOT23 and SOT223 SMD packages.
smd_capacitors can now have a value.
Wire links can now have zero length to create a vertical wire.
2022-02-09 21:50:10 +00:00
Chris Palmer
00d6efc315 Added veroboard constructor.
Documented solder_meniscus and made it parametric.
2022-02-09 21:42:20 +00:00
Chris Palmer
985b6c08d2 Updated changelog. 2022-02-08 19:19:17 +00:00
Chris Palmer
1f55097bdd Support for twisted cables.
Sweep now distbutes twists in proportion to segments lengths.
Added  spiral_paths(), segmented_path() and rounded_path_vertices() functions.
Added show_path(path) module.
2022-02-08 19:08:10 +00:00
Chris Palmer
136584d086 Updated changelog. 2022-02-06 23:46:41 +00:00
Chris Palmer
225ea9b451 Added rounded_path() function to sweep.scad. 2022-02-06 23:44:23 +00:00
Chris Palmer
d341ce499e Added render() to pocket_handle(). 2022-02-06 23:43:40 +00:00
Chris Palmer
e7376e28c4 Fixed corner block assembly names when overridden. 2022-02-06 23:42:54 +00:00
Chris Palmer
e238eaa473 Removed unused, undocumented function. 2022-02-06 23:40:19 +00:00
Chris Palmer
28d8cba98c Updated changelog. 2022-02-01 23:30:05 +00:00
120 changed files with 141896 additions and 111 deletions

View File

@@ -3,6 +3,59 @@
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
### [v19.20.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.20.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.9.1...v19.20.0 "diff with v19.9.1")
* 2022-02-15 [`0e2778e`](https://github.com/nophead/NopSCADlib/commit/0e2778e13de2e68fc21a7b4c706aada27a17842c "show commit") [C.P.](# "Chris Palmer") Cables can now have a list of wire colours.
Added a constructor for cables.
* 2022-02-15 [`50e23e5`](https://github.com/nophead/NopSCADlib/commit/50e23e5f818077e3661e25852dc959c34e6c8b4a "show commit") [C.P.](# "Chris Palmer") Added silkscreen text to PCBs.
#### [v19.9.1](https://github.com/nophead/NopSCADlib/releases/tag/v19.9.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v19.9.0...v19.9.1 "diff with v19.9.0")
* 2022-02-15 [`59eeb2c`](https://github.com/nophead/NopSCADlib/commit/59eeb2c5d4c7cf9da1f219c2b01fabcf450085f3 "show commit") [C.P.](# "Chris Palmer") Trimmed the ribbon clamp tape.
* 2022-02-15 [`7ea4dbe`](https://github.com/nophead/NopSCADlib/commit/7ea4dbe6cbbc23256d23f7aea87e8aac8d1000a9 "show commit") [C.P.](# "Chris Palmer") Fixed double application of `r2sides()` in `rounded_path()`.
Added check for radius too big for corner in `rounded_path()`.
Spiral paths can now have 0 twists.
### [v19.9.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.9.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.8.1...v19.9.0 "diff with v19.8.1")
* 2022-02-11 [`95b6771`](https://github.com/nophead/NopSCADlib/commit/95b6771811fd48af46b5c2d426c42c04cd8e5af3 "show commit") [C.P.](# "Chris Palmer") Added printed cable clips.
* 2022-02-11 [`ed46cbb`](https://github.com/nophead/NopSCADlib/commit/ed46cbb1470587d4fa3ee4e0e8e0513c82693b1b "show commit") [C.P.](# "Chris Palmer") Fixed `cable_bundle()` bugs and added test.
Added `cable_bundle_positions()`.
Can now mark cables as ribbon to force a flat layout.
#### [v19.8.1](https://github.com/nophead/NopSCADlib/releases/tag/v19.8.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v19.8.0...v19.8.1 "diff with v19.8.0")
* 2022-02-09 [`2a2b7d8`](https://github.com/nophead/NopSCADlib/commit/2a2b7d8bd60f0ea8ad2c428593e7aea1dfa06e9c "show commit") [C.P.](# "Chris Palmer") Added a second example project.
### [v19.8.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.8.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.7.0...v19.8.0 "diff with v19.7.0")
* 2022-02-09 [`055b4e7`](https://github.com/nophead/NopSCADlib/commit/055b4e7102ffcc39dc376330636efa79739a6555 "show commit") [C.P.](# "Chris Palmer") Added SOT23 and SOT223 SMD packages.
`smd_capacitors` can now have a value.
Wire links can now have zero length to create a vertical wire.
* 2022-02-09 [`00d6efc`](https://github.com/nophead/NopSCADlib/commit/00d6efc3154bbd5597a3336bc8bdaf550e42f56a "show commit") [C.P.](# "Chris Palmer") Added veroboard constructor.
Documented `solder_meniscus` and made it parametric.
### [v19.7.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.7.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.6.0...v19.7.0 "diff with v19.6.0")
* 2022-02-08 [`1f55097`](https://github.com/nophead/NopSCADlib/commit/1f55097bdd3e4d0164a48dd7ebb3fc5370250ac4 "show commit") [C.P.](# "Chris Palmer") Support for twisted cables.
Sweep now distbutes twists in proportion to segments lengths.
Added `spiral_paths(),` `segmented_path()` and `rounded_path_vertices()` functions.
Added `show_path(path)` module.
### [v19.6.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.6.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.5.1...v19.6.0 "diff with v19.5.1")
* 2022-02-06 [`225ea9b`](https://github.com/nophead/NopSCADlib/commit/225ea9b45160195bdf316e7ffdb383a63f898d3c "show commit") [C.P.](# "Chris Palmer") Added `rounded_path()` function to `sweep.scad`.
#### [v19.5.1](https://github.com/nophead/NopSCADlib/releases/tag/v19.5.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v19.5.0...v19.5.1 "diff with v19.5.0")
* 2022-02-06 [`d341ce4`](https://github.com/nophead/NopSCADlib/commit/d341ce499e56972ff5267d3187387fe7df9d4130 "show commit") [C.P.](# "Chris Palmer") Added `render()` to `pocket_handle()`.
* 2022-02-06 [`e7376e2`](https://github.com/nophead/NopSCADlib/commit/e7376e28c44355efa425b98aa0511ccdf0b63301 "show commit") [C.P.](# "Chris Palmer") Fixed corner block assembly names when overridden.
* 2022-02-06 [`e238eaa`](https://github.com/nophead/NopSCADlib/commit/e238eaa473bac72136507d15c57f6156560d6cfe "show commit") [C.P.](# "Chris Palmer") Removed unused, undocumented function.
### [v19.5.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.5.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.4.1...v19.5.0 "diff with v19.4.1")
* 2022-02-01 [`04e94a8`](https://github.com/nophead/NopSCADlib/commit/04e94a859aa0d21f840c992b487a901f096790a4 "show commit") [C.P.](# "Chris Palmer") Added `earth_rot` parameter to `NEMA_screws()`.
#### [v19.4.1](https://github.com/nophead/NopSCADlib/releases/tag/v19.4.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v19.4.0...v19.4.1 "diff with v19.4.0")
* 2022-02-01 [`e696dc4`](https://github.com/nophead/NopSCADlib/commit/e696dc471845550eb94e1b648d8b109cc11a9bf1 "show commit") [C.P.](# "Chris Palmer") Fixed stupid bug in `euler()`.
### [v19.4.0](https://github.com/nophead/NopSCADlib/releases/tag/v19.4.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v19.3.0...v19.4.0 "diff with v19.3.0")
* 2022-01-29 [`f33a067`](https://github.com/nophead/NopSCADlib/commit/f33a0675f5b9f6a5ebe1c4b9755e894d1e2b7994 "show commit") [C.P.](# "Chris Palmer") Updated images and readme.

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,5 @@
RPI_assembly:
Vitamins:
1 Micro SD card
1 Raspberry Pi Zero
1 Pin header 20 x 2 right_angle

View File

@@ -0,0 +1,7 @@
RPI_case_assembly:
Vitamins:
2 Screw M2.5 pan x 6.4mm
Assemblies:
1 RPI_assembly
1 enviro_case_assembly

View File

@@ -0,0 +1,8 @@
back_assembly:
Vitamins:
1 Fan 17mm x 8mm
1 PMS5003 particle detector
Printed:
1 enviro_plus_case_base.stl
1 fan_duct.stl

View File

@@ -0,0 +1,21 @@
'Micro SD card', 1
'Fan 17mm x 8mm', 1
'Heatfit insert M2', 4
'Nut M2.5 x 2.2mm nyloc', 4
'Enviro+', 1
'Raspberry Pi Zero', 1
'Pin header 20 x 2 right_angle', 1
'PMS5003 particle detector', 1
'Screw M2 cap x 6mm', 4
'Screw M2.5 pan x 6.4mm', 2
'Screw M2.5 pan x 8mm', 4
'Screw M3 pan x 6mm', 3
'SMD capacitor 1206 10uF', 1
'SMD resistor 0805 3K3 0.125W', 1
'SOT223 package FZT851', 1
'Veroboard 6 holes x 6strips', 1
'Washer M2 x 5mm x 0.3mm', 4
'Washer M2.5 x 5.9mm x 0.5mm', 4
'Washer M3 x 7mm x 0.5mm', 3
'Wire link 0.8mm x 6.5mm', 3
'Wire link 0.8mm x 0.4"', 1
Can't render this file because it contains an unexpected character in line 21 and column 23.

View File

@@ -0,0 +1,194 @@
[
{
"name": "back_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {},
"vitamins": {
"pms5003(): PMS5003 particle detector": {
"count": 1
},
"fan(fan17x8): Fan 17mm x 8mm": {
"count": 1
}
},
"printed": {
"fan_duct.stl": {
"count": 1,
"colour": "darkorange"
},
"enviro_plus_case_base.stl": {
"count": 1,
"colour": "grey"
}
},
"routed": {}
},
{
"name": "RPI_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {},
"vitamins": {
"pcb(RPI0): Raspberry Pi Zero": {
"count": 1
},
": Micro SD card": {
"count": 1
},
"pin_header(2p54header, 20, 2, right_angle = true): Pin header 20 x 2 right_angle": {
"count": 1
}
},
"printed": {},
"routed": {}
},
{
"name": "fan_controller_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {},
"vitamins": {
"veroboard(fan_vb): Veroboard 6 holes x 6strips": {
"count": 1
},
"wire_link(0.8, 10.16, tail = 2.5): Wire link 0.8mm x 0.4\"": {
"count": 1
},
"wire_link(0.8, 0, h = 4, tail = 2.5): Wire link 0.8mm x 6.5mm": {
"count": 3
},
"smd_resistor(RES0805, 3K3): SMD resistor 0805 3K3 0.125W": {
"count": 1
},
"smd_capacitor(CAP1206): SMD capacitor 1206 10uF": {
"count": 1
},
"smd_sot(SOT223): SOT223 package FZT851": {
"count": 1
}
},
"printed": {},
"routed": {}
},
{
"name": "enviro_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {
"fan_controller_assembly": 1
},
"vitamins": {
"pcb(EnviroPlus): Enviro+": {
"count": 1
}
},
"printed": {},
"routed": {}
},
{
"name": "case_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {},
"vitamins": {
"insert(F1BM2): Heatfit insert M2": {
"count": 4
},
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": {
"count": 3
},
"screw(M3_pan_screw, 6): Screw M3 pan x 6mm": {
"count": 3
}
},
"printed": {
"enviro_plus_case.stl": {
"count": 1,
"colour": "grey"
},
"bulkhead.stl": {
"count": 1,
"colour": "[0.862745, 0.0784314, 0.235294]"
},
"foot.stl": {
"count": 3,
"colour": "darkorange"
}
},
"routed": {}
},
{
"name": "enviro_case_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {
"case_assembly": 1,
"enviro_assembly": 1
},
"vitamins": {
"screw(M2p5_pan_screw, 8): Screw M2.5 pan x 8mm": {
"count": 4
},
"washer(M2p5_washer): Washer M2.5 x 5.9mm x 0.5mm": {
"count": 4
},
"nut(M2p5_nut, nyloc = true): Nut M2.5 x 2.2mm nyloc": {
"count": 4
}
},
"printed": {},
"routed": {}
},
{
"name": "RPI_case_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {
"enviro_case_assembly": 1,
"RPI_assembly": 1
},
"vitamins": {
"screw(M2p5_pan_screw, 6.4): Screw M2.5 pan x 6.4mm": {
"count": 2
}
},
"printed": {},
"routed": {}
},
{
"name": "main_assembly",
"big": null,
"ngb": false,
"zoomed": 0,
"count": 1,
"assemblies": {
"RPI_case_assembly": 1,
"back_assembly": 1
},
"vitamins": {
"washer(M2_washer): Washer M2 x 5mm x 0.3mm": {
"count": 4
},
"screw(M2_cap_screw, 6): Screw M2 cap x 6mm": {
"count": 4
}
},
"printed": {},
"routed": {}
}
]

View File

@@ -0,0 +1,53 @@
Vitamins:
F
a
n
E
n c
v o
R i n
p r t
i E o r
n o
c B C v c l M
R a a a i a l a
p s c s r s e i
i e k e o e r n
1| | | | | | | | 1 Micro SD card
| | 1| | | | | | 1 Fan 17mm x 8mm
| | | 4| | | | | 4 Heatfit insert M2
| | | | | 4| | | 4 Nut M2.5 x 2.2mm nyloc
| | | | 1| | | | 1 Enviro+
1| | | | | | | | 1 Raspberry Pi Zero
1| | | | | | | | 1 Pin header 20 x 2 right_angle
| | 1| | | | | | 1 PMS5003 particle detector
| | | | | | | 4| 4 Screw M2 cap x 6mm
| 2| | | | | | | 2 Screw M2.5 pan x 6.4mm
| | | | | 4| | | 4 Screw M2.5 pan x 8mm
| | | 3| | | | | 3 Screw M3 pan x 6mm
| | | | | | 1| | 1 SMD capacitor 1206 10uF
| | | | | | 1| | 1 SMD resistor 0805 3K3 0.125W
| | | | | | 1| | 1 SOT223 package FZT851
| | | | | | 1| | 1 Veroboard 6 holes x 6strips
| | | | | | | 4| 4 Washer M2 x 5mm x 0.3mm
| | | | | 4| | | 4 Washer M2.5 x 5.9mm x 0.5mm
| | | 3| | | | | 3 Washer M3 x 7mm x 0.5mm
| | | | | | 3| | 3 Wire link 0.8mm x 6.5mm
| | | | | | 1| | 1 Wire link 0.8mm x 0.4"
Printed:
| | | 1| | | | | 1 bulkhead.stl
| | | 1| | | | | 1 enviro_plus_case.stl
| | 1| | | | | | 1 enviro_plus_case_base.stl
| | 1| | | | | | 1 fan_duct.stl
| | | 3| | | | | 3 foot.stl
Assemblies:
1 RPI_assembly
1 RPI_case_assembly
1 back_assembly
1 case_assembly
1 enviro_assembly
1 enviro_case_assembly
1 fan_controller_assembly
1 main_assembly

View File

@@ -0,0 +1,10 @@
case_assembly:
Vitamins:
4 Heatfit insert M2
3 Screw M3 pan x 6mm
3 Washer M3 x 7mm x 0.5mm
Printed:
1 bulkhead.stl
1 enviro_plus_case.stl
3 foot.stl

View File

@@ -0,0 +1,6 @@
enviro_assembly:
Vitamins:
1 Enviro+
Assemblies:
1 fan_controller_assembly

View File

@@ -0,0 +1,9 @@
enviro_case_assembly:
Vitamins:
4 Nut M2.5 x 2.2mm nyloc
4 Screw M2.5 pan x 8mm
4 Washer M2.5 x 5.9mm x 0.5mm
Assemblies:
1 case_assembly
1 enviro_assembly

View File

@@ -0,0 +1,8 @@
fan_controller_assembly:
Vitamins:
1 SMD capacitor 1206 10uF
1 SMD resistor 0805 3K3 0.125W
1 SOT223 package FZT851
1 Veroboard 6 holes x 6strips
3 Wire link 0.8mm x 6.5mm
1 Wire link 0.8mm x 0.4"

View File

@@ -0,0 +1,8 @@
main_assembly:
Vitamins:
4 Screw M2 cap x 6mm
4 Washer M2 x 5mm x 0.3mm
Assemblies:
1 RPI_case_assembly
1 back_assembly

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

View File

@@ -0,0 +1,298 @@
<a name="TOP"></a>
# EnviroPlus
Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero.
![Main Assembly](assemblies/main_assembled.png)
<span></span>
---
## Table of Contents
1. [Parts list](#Parts_list)
1. [Back Assembly](#back_assembly)
1. [RPI Assembly](#RPI_assembly)
1. [Fan Controller Assembly](#fan_controller_assembly)
1. [Enviro Assembly](#enviro_assembly)
1. [Case Assembly](#case_assembly)
1. [Enviro Case Assembly](#enviro_case_assembly)
1. [RPI Case Assembly](#RPI_case_assembly)
1. [Main Assembly](#main_assembly)
<span></span>
[Top](#TOP)
---
<a name="Parts_list"></a>
## Parts list
| <span style="writing-mode: vertical-rl; text-orientation: mixed;">Back</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">RPI</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Fan&nbsp;Controller</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Enviro</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Case</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Enviro&nbsp;Case</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">RPI&nbsp;Case</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Main</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |
|---:|---:|---:|---:|---:|---:|---:|---:|---:|:---|
| | | | | | | | | | **Vitamins** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Enviro+ |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Fan 17mm x 8mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp; Heatfit insert M2 |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Micro SD card |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp; Nut M2.5 x 2.2mm nyloc |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; PMS5003 particle detector |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Pin header 20 x 2 right_angle |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Raspberry Pi Zero |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; SMD capacitor 1206 10uF |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; SMD resistor 0805 3K3 0.125W |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; SOT223 package FZT851 |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp; Screw M2 cap x 6mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Screw M2.5 pan x 6.4mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp; Screw M2.5 pan x 8mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp; Screw M3 pan x 6mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Veroboard 6 holes x 6strips |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp; Washer M2 x 5mm x 0.3mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp; Washer M2.5 x 5.9mm x 0.5mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp; Washer M3 x 7mm x 0.5mm |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; Wire link 0.8mm x 0.4" |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp; Wire link 0.8mm x 6.5mm |
| &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp;8&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;10&nbsp; | &nbsp;&nbsp;12&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;8&nbsp; | &nbsp;&nbsp;46&nbsp; | &nbsp;&nbsp;Total vitamins count |
| | | | | | | | | | **3D printed parts** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;bulkhead.stl |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;enviro_plus_case.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;enviro_plus_case_base.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;fan_duct.stl |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;3&nbsp; | &nbsp;&nbsp;foot.stl |
| &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;5&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;7&nbsp; | &nbsp;&nbsp;Total 3D printed parts count |
<span></span>
[Top](#TOP)
---
<a name="back_assembly"></a>
## Back Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|1| Fan 17mm x 8mm|
|1| PMS5003 particle detector|
### 3D Printed parts
| 1 x enviro_plus_case_base.stl | 1 x fan_duct.stl |
|---|---|
| ![enviro_plus_case_base.stl](stls/enviro_plus_case_base.png) | ![fan_duct.stl](stls/fan_duct.png)
### Assembly instructions
![back_assembly](assemblies/back_assembly.png)
1. Print the fan duct in flexible TPE with low infill.
1. Slide the pms5003 into the printed receptacle with the fan to the outside. Secure with tape if it is loose.
1. Slide the fan into the fan duct.
1. Slide the fan duct into the printed recepacle.
![back_assembled](assemblies/back_assembled.png)
<span></span>
[Top](#TOP)
---
<a name="RPI_assembly"></a>
## RPI Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|1| Micro SD card|
|1| Pin header 20 x 2 right_angle|
|1| Raspberry Pi Zero|
### Assembly instructions
![RPI_assembly](assemblies/RPI_assembly_tn.png)
* Solder a right angle connector to the Raspberry Pi Zero.
![RPI_assembled](assemblies/RPI_assembled_tn.png)
<span></span>
[Top](#TOP)
---
<a name="fan_controller_assembly"></a>
## Fan Controller Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|1| SMD capacitor 1206 10uF|
|1| SMD resistor 0805 3K3 0.125W|
|1| SOT223 package FZT851|
|1| Veroboard 6 holes x 6strips|
|1| Wire link 0.8mm x 0.4"|
|3| Wire link 0.8mm x 6.5mm|
### Assembly instructions
![fan_controller_assembly](assemblies/fan_controller_assembly_tn.png)
The fan controller is a single transistor wired as a Miller integrator that effectively multiplies the capacitor value by the gain of the transistor.
It converts the PWM signal on GPI4 to a stead DC voltage so that the fan doesn't whine, or stutter.
![Schematic](docs/fan_controller.jpg)
***
* Make two track cuts as shown, one wide and the other narrow.
![TrackCuts](docs/cuts.jpg)
1. Add the SMT compeonents and then the wire links.
1. Add more solder around the transistor to act as a heatsink.
![SMT](docs/smt.jpg)
![fan_controller_assembled](assemblies/fan_controller_assembled_tn.png)
<span></span>
[Top](#TOP)
---
<a name="enviro_assembly"></a>
## Enviro Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|1| Enviro+|
### Sub-assemblies
| 1 x fan_controller_assembly |
|---|
| ![fan_controller_assembled](assemblies/fan_controller_assembled_tn.png)
### Assembly instructions
![enviro_assembly](assemblies/enviro_assembly_tn.png)
* Solder the fan_controller to the Enviro+ expansion connector at the 5V, GND and #4 pins.
![enviro_assembled](assemblies/enviro_assembled_tn.png)
<span></span>
[Top](#TOP)
---
<a name="case_assembly"></a>
## Case Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|4| Heatfit insert M2|
|3| Screw M3 pan x 6mm|
|3| Washer M3 x 7mm x 0.5mm|
### 3D Printed parts
| 1 x bulkhead.stl | 1 x enviro_plus_case.stl | 3 x foot.stl |
|---|---|---|
| ![bulkhead.stl](stls/bulkhead.png) | ![enviro_plus_case.stl](stls/enviro_plus_case.png) | ![foot.stl](stls/foot.png)
### Assembly instructions
![case_assembly](assemblies/case_assembly.png)
1. Solvent weld or glue the bulkhead into the recess in the bottom of the case.
1. Fit the heatfit inserts with a soldering iron with a conical bit heated to about 200&deg;C.
1. Tap the three holes for the feet with an M3 tap.
1. Screw on the three feet with M3 x 6mm pan screws and washers.
![case_assembled](assemblies/case_assembled.png)
<span></span>
[Top](#TOP)
---
<a name="enviro_case_assembly"></a>
## Enviro Case Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|4| Nut M2.5 x 2.2mm nyloc|
|4| Screw M2.5 pan x 8mm|
|4| Washer M2.5 x 5.9mm x 0.5mm|
### Sub-assemblies
| 1 x case_assembly | 1 x enviro_assembly |
|---|---|
| ![case_assembled](assemblies/case_assembled_tn.png) | ![enviro_assembled](assemblies/enviro_assembled_tn.png)
### Assembly instructions
![enviro_case_assembly](assemblies/enviro_case_assembly.png)
* Screw the Enviro+ PCB to the front of the case using M2.5 x 8mm pan screws with washer and nuts on the inside.
![enviro_case_assembled](assemblies/enviro_case_assembled.png)
<span></span>
[Top](#TOP)
---
<a name="RPI_case_assembly"></a>
## RPI Case Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|2| Screw M2.5 pan x 6.4mm|
### Sub-assemblies
| 1 x RPI_assembly | 1 x enviro_case_assembly |
|---|---|
| ![RPI_assembled](assemblies/RPI_assembled_tn.png) | ![enviro_case_assembled](assemblies/enviro_case_assembled_tn.png)
### Assembly instructions
![RPI_case_assembly](assemblies/RPI_case_assembly.png)
* Plug the RPi into the Enviro+ socket and secure with two screws self tapped into the bosses in the case.
![RPI_case_assembled](assemblies/RPI_case_assembled.png)
<span></span>
[Top](#TOP)
---
<a name="main_assembly"></a>
## Main Assembly
### Vitamins
|Qty|Description|
|---:|:----------|
|4| Screw M2 cap x 6mm|
|4| Washer M2 x 5mm x 0.3mm|
### Sub-assemblies
| 1 x RPI_case_assembly | 1 x back_assembly |
|---|---|
| ![RPI_case_assembled](assemblies/RPI_case_assembled_tn.png) | ![back_assembled](assemblies/back_assembled_tn.png)
### Assembly instructions
![main_assembly](assemblies/main_assembly.png)
* Solder the fan wires to the veroboard assembly
![FanWires](docs/fan_connection.jpg)
* Slide the back assembly into the case and secure with four M2 x 6mm cap screws and washers.
![main_assembled](assemblies/main_assembled.png)
<span></span>
[Top](#TOP)

View File

@@ -0,0 +1,45 @@
//
//! Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero.
//
// GNU GPL v2
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// Top level model
//
include <NopSCADlib/core.scad>
use <NopSCADlib/vitamins/veroboard.scad>
include <NopSCADlib/vitamins/smds.scad>
fan_vb = vero("fan_vb", "fan_controller", 6, 6, breaks = [[2, 1], [2 + eps, 5]],
components = [
[5, 3, 90, "link", inch(0.4), undef, undef, 2.5],
[0, 5, 0, "link", 0, 4, undef, 2.5],
[0, 1, 0, "link", 0, 4, undef, 2.5],
[0, 0, 0, "link", 0, 4, undef, 2.5],
[2, 5, 0, "-smd_res", RES0805, "3K3"],
[4, 4.7, 90, "-smd_cap", CAP1206, 1.2, "10uF"],
[2, 2.5, 180, "-smd_sot", SOT223, "FZT851"],
],
joints = [[5, 1], [5, 5], [0, [0, 1, 5]]]
);
//! The fan controller is a single transistor wired as a Miller integrator that effectively multiplies the capacitor value by the gain of the transistor.
//! It converts the PWM signal on GPI4 to a stead DC voltage so that the fan doesn't whine, or stutter.
//!
//! ![Schematic](docs/fan_controller.jpg)
//!
//! ***
//! * Make two track cuts as shown, one wide and the other narrow.
//!
//! ![TrackCuts](docs/cuts.jpg)
//!
//! 1. Add the SMT compeonents and then the wire links.
//! 1. Add more solder around the transistor to act as a heatsink.
//!
//! ![SMT](docs/smt.jpg)
//!
module fan_controller_assembly() rotate(90) vflip(!exploded()) veroboard_assembly(fan_vb, -vero_thickness(fan_vb) - 1.4, 0);
fan_controller_assembly();

View File

@@ -0,0 +1,518 @@
//
//! Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero.
//
// GNU GPL v2
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// Top level model
//
$explode = 0; // [0, 1]
assembly = "main"; // [main, back, RPI, case, enviro_case, RPI_case]
/* [Hidden] */
show_box = true;
show_enviroplus = true;
$pp1_colour = "grey";
$extrusion_width = 0.5;
include <NopSCADlib/core.scad>
include <NopSCADlib/vitamins/pin_headers.scad>
include <NopSCADlib/vitamins/pcbs.scad>
include <NopSCADlib/vitamins/fans.scad>
use <NopSCADlib/vitamins/insert.scad>
use <NopSCADlib/vitamins/veroboard.scad>
use <NopSCADlib/utils/round.scad>
use <NopSCADlib/printed/foot.scad>
use <NopSCADlib/printed/printed_box.scad>
use <fan_controller.scad>
rpi = RPI0;
pcb = EnviroPlus;
fan = fan17x8;
foot = Foot(d = 13, h = 5, t = 2, r = 1, screw = M3_pan_screw);
module foot_stl() foot(foot);
rpi_offset = [0, -pcb_width(pcb) / 2 + 0.5, pcb_width(rpi) / 2 + 8.6];
rpi_holes = [0, 1];
wall = 2;
top_thickness = 2;
base_thickness = 2;
case_inner_rad = 8;
width = pcb_length(pcb) + 9 + 10;
pcb_x = -(width - pcb_length(pcb) - 9) / 2;
depth = pcb_width(pcb) + 9;
height = pcb_width(rpi) / 2 + rpi_offset.z + 9;
bulkhead_outset = 2;
bulkhead_inset = 0.5;
bulkhead_t = 2;
clearance = 0.1;
pcb_screw = alternate_screw(hs_pan, pcb_screw(pcb));
box = pbox(name = "enviro_plus_case", wall = wall, top_t = top_thickness, base_t = base_thickness, screw = M2_cap_screw, radius = case_inner_rad, ridges = [8, 1],
size = [width, depth, height]);
pms5003 = [50, 38, 21];
pms5003_wall = 1;
pms5003_pos = [width / 2 - pms5003.x / 2 - pms5003_wall - pbox_screw_inset(box) - insert_boss_radius(screw_insert(pbox_screw(box)), wall) - 0.5,
depth / 2 - pms5003.z / 2 - wall - 1,
height + top_thickness - pms5003.y / 2];
fan_duct_t = 1.7;
foam_t = 0;
fan_pos = [pms5003_pos.x - pms5003.x / 2 - pms5003_wall - fan_width(fan) / 2 - fan_duct_t, 1 + foam_t, 12 + top_thickness + fan_depth(fan) / 2];
fan_socket = 8;
module fan_shape() {
w = fan_width(fan);
p = fan_hole_pitch(fan);
r = w / 2 - p;
rounded_square([w, w], r);
}
module fan_duct_stl() {
module frame(z, offset, y = -fan_pos.y)
translate([0, y, z])
linear_extrude(height = eps)
offset(offset)
fan_shape();
z = height + top_thickness - fan_pos.z + fan_depth(fan) / 2 - fan_socket;
translate([0, -fan_pos.y, z])
linear_extrude(height = fan_socket)
difference() {
fan_shape();
round(1)
offset(-fan_duct_t)
fan_shape();
}
stl("fan_duct") union() {
difference() {
hull() {
frame(z, 0);
frame(fan_depth(fan), fan_duct_t + foam_t, 0);
}
hull() {
frame(z, -fan_duct_t);
frame(fan_depth(fan), foam_t -extrusion_width / 2, 0);
}
}
linear_extrude(height = fan_depth(fan))
difference() {
offset(fan_duct_t + foam_t)
fan_shape();
offset(foam_t)
fan_shape();
}
}
}
module pms5003() {
vitamin("pms5003(): PMS5003 particle detector");
w = pms5003.x;
d = pms5003.y;
h = pms5003.z;
t = 0.1;
color("silver")
difference() {
linear_extrude(height = h, center = true)
difference() {
square([w, d], center = true);
for(x = [-1, 1], y = [-1, 1])
translate([x * w / 2, y * d / 2])
square(2, center = true);
}
cube([w + 2 * eps, d + 2 * eps, t * 2], center = true);
}
color("black")
rounded_rectangle([w - 2 * t, d - 2 * t, h - 2 * t], r = 1, center = true);
}
module pcb_shape(offset)
rounded_square([pcb_length(pcb) + 2 * offset, pcb_width(pcb) + 2 * offset], pcb_radius(pcb) + offset);
module gap() {
gap = pcb_component_position(pcb, "-chip");
translate([gap.x, -gap.y])
square([17.5, 20], center = true);
}
module rpi_holes()
for(i = rpi_holes) {
hole = pcb_coord(rpi, pcb_holes(rpi)[i]);
translate([hole.x, rpi_offset.y, -hole.y + rpi_offset.z + top_thickness])
rotate([90, 0, 0])
children();
}
module feet_positions() {
clearance = 2;
foot_r = foot_diameter(foot) / 2;
x_inset = case_inner_rad + foot_r - pbox_ridges(box).y;
z_inset = foot_r + clearance;
h = height + base_thickness;
for(p = [[-1, -1], [1, -1], [0, 1]])
translate([p.x * (width / 2 - x_inset), depth / 2 + wall + pbox_ridges(box).y, top_thickness + h / 2 + p.y * (h / 2 - z_inset)])
rotate([90, 0, 0])
children();
}
module slots(h = 10, expand = 0) {
for(comp = [["uSD", 2, 11, 0.7], ["flat_flex", 1, 12, 0.5]]) {
p = pcb_component_position(rpi, comp[0]);
translate([sign(p.x) * (width / 2 + wall / 2 + pbox_ridges(box).y / 2), rpi_offset.y + pcb_thickness(rpi) + comp[3], top_thickness + rpi_offset.z - p.y])
rotate([90, 0, 90])
hull() {
vertical_tearslot(r = comp[1] + expand, l = comp[2], h = h);
if(expand)
vertical_tearslot(r = comp[1] + expand + h / 2, l = comp[2], h = eps);
}
}
}
module box_internal_additions() {
translate([pcb_x, 0]) {
linear_extrude(height = top_thickness + bulkhead_t)
difference() {
pcb_shape(bulkhead_outset + wall + pbox_ridges(box).y + eps);
gap();
pcb_shape(bulkhead_outset + clearance);
}
rpi_holes()
hull() {
wall = 1.8;
r = screw_radius(pcb_screw) + wall;
z = depth / 2 + rpi_offset.y + pbox_ridges(box).y + eps;
offset = max(r, z);
cylinder(r =r, h = z);
translate([0, -offset - r, z])
cube(eps);
}
}
d = washer_diameter(screw_washer(foot_screw(foot))) + 1;
h = pbox_ridges(box).y;
feet_positions()
translate_z(wall - eps)
cylinder(d2 = d, d1 = d + 2 * h, h = h);
slots(wall + pbox_ridges(box).y + eps, 1);
}
module box_external_additions() {
amp = pbox_ridges(box).y + eps;
d = foot_diameter(foot) + 1;
feet_positions()
cylinder(d1 = d, d2 = d + 2 * amp, h = amp);
slots(wall + pbox_ridges(box).y + eps, 1);
}
module box_holes() {
translate([pcb_x, 0]) {
linear_extrude(height = top_thickness + eps)
pcb_shape(clearance);
rpi_holes()
teardrop_plus(r = screw_pilot_hole(pcb_screw), h = 7 - 1.6, center = false);
}
feet_positions()
teardrop(r = screw_pilot_hole(foot_screw(foot)), h = 10, center = true);
grills = 7;
bar = 1.6;
x = pcb_x + pcb_length(pcb) / 2 + 2 * wall + pbox_ridges(box).y + 2 * eps;
w = width / 2 - x;
d = depth - case_inner_rad;
pitch = d / (grills - 1);
for(i = [0 : grills -1])
let(w = i == 0 || i == grills -1 ? w - 1 : w)
translate([x + w / 2, -d / 2 + i * pitch])
rounded_rectangle([w, pitch - bar, 10], 1);
slots();
}
module bulkhead_stl() {
holes = pcb_holes(pcb);
pitch = max([for(h = holes) pcb_coord(pcb, h).x]) - min([for(h = holes) pcb_coord(pcb, h).x]);
boss_r = (pitch - 51.4) / 2;
stl("bulkhead")
linear_extrude(height = bulkhead_t)
difference() {
pcb_shape(bulkhead_outset);
gap();
difference() {
pcb_shape(-bulkhead_inset);
pcb_screw_positions(pcb)
rotate($i * 90)
hull() {
circle(boss_r);
translate([boss_r - eps, -boss_r])
square([eps, boss_r]);
translate([-boss_r, boss_r - eps])
square([boss_r, eps]);
translate([-boss_r, -boss_r])
square(eps);
}
}
pcb_screw_positions(pcb)
poly_circle(screw_clearance_radius(pcb_screw));
}
}
module enviro_plus_case_stl() {
pbox(box) {
box_internal_additions();
box_holes();
box_external_additions();
}
}
module base_additions() {
w = pms5003.x + clearance;
d = pms5003.z + clearance;
wall = pms5003_wall;
translate([pms5003_pos.x, -pms5003_pos.y])
linear_extrude(height = base_thickness + pms5003.y)
difference() {
square([w + 2 * wall, d + 2 * wall], center = true);
square([w, d], center = true);
}
translate([fan_pos.x, 0])
linear_extrude(height = top_thickness + fan_socket)
difference() {
offset(wall)
fan_shape();
fan_shape();
}
}
module base_holes() {
for(i = [0 : 1]) {
p = pcb_component_position(rpi, "usb_uA", i);
translate([p.x + pcb_x, -rpi_offset.y - pcb_thickness(rpi) - 1.3])
rounded_rectangle([11,7, 100], 0.5, true);
}
translate([pms5003_pos.x, -pms5003_pos.y])
rounded_rectangle([pms5003.x - 2 ,pms5003.z - 2, 100], 2, true);
translate([fan_pos.x, 0])
linear_extrude(height = 2 * base_thickness + eps, center = true)
round(1)
offset(-fan_duct_t)
fan_shape();
}
module enviro_plus_case_base_stl()
pbox_base(box) {
base_additions();
base_holes();
}
//! * Solder a right angle connector to the Raspberry Pi Zero.
module RPI_assembly()
assembly("RPI") {
pcb(rpi);
pcb_grid(rpi, 9.5, 0.5, -0.6)
rotate(180)
explode(20)
pin_header(2p54header, 20, 2, right_angle = true);
}
//! 1. Solvent weld or glue the bulkhead into the recess in the bottom of the case.
//! 1. Fit the heatfit inserts with a soldering iron with a conical bit heated to about 200&deg;C.
//! 1. Tap the three holes for the feet with an M3 tap.
//! 1. Screw on the three feet with M3 x 6mm pan screws and washers.
module case_assembly() pose([ 29.60, 0.00, 158.00 ], exploded = true) pose([ 198.00, 0.00, 352.80 ], exploded = false)
assembly("case") {
if(show_box)
stl_colour(pp1_colour) render() enviro_plus_case_stl();
else
render() difference() {
enviro_plus_case_stl();
translate_z(height / 2)
cube([100, 100, height - 20], center = true);
}
pbox_inserts(box);
translate([pcb_x, 0, top_thickness])
explode(20)
stl_colour(pp2_colour) render() bulkhead_stl();
feet_positions() {
foot_assembly(0, foot);
vflip()
explode(20, explode_children = true)
translate_z(foot_thickness(foot))
screw_and_washer(foot_screw(foot), 6);
}
}
//! * Solder the fan_controller to the Enviro+ expansion connector at the 5V, GND and #4 pins.
module enviro_assembly() hflip(exploded())
assembly("enviro") {
if(show_enviroplus)
pcb(pcb);
pcb_grid(pcb, 5.5, 2.5, -pcb_thickness(pcb)) {
hflip()
explode(15)
fan_controller_assembly();
}
if(!exploded())
for(x = [8, 7, 3])
pcb_grid(pcb, x, 0, 0.05)
solder_meniscus(pcb, 0.39, 1);
}
//! * Screw the Enviro+ PCB to the front of the case using M2.5 x 8mm pan screws with washer and nuts on the inside.
module enviro_case_assembly() pose([ 231.40, 0.00, 1.20 ])
assembly("enviro_case") {
case_assembly();
translate([pcb_x, 0, top_thickness])
vflip() explode(20, explode_children = true) {
t = pcb_thickness(pcb);
nut = screw_nut(pcb_screw);
washer = screw_washer(pcb_screw);
no_explode() enviro_assembly();
pcb_screw_positions(pcb) {
translate_z(t)
screw(pcb_screw, screw_longer_than(t + bulkhead_t + nut_thickness(nut, true) + washer_thickness(washer)));
translate_z(-bulkhead_t)
vflip()
explode(20, explode_children = true)
nut_and_washer(nut, true);
}
}
}
//! * Plug the RPi into the Enviro+ socket and secure with two screws self tapped into the bosses in the case.
module RPI_case_assembly() pose([ 20.50, 0.00, 153.30 ])
assembly("RPI_case") {
enviro_case_assembly();
translate([pcb_x, 0]) {
translate_z(top_thickness) {
translate(rpi_offset)
rotate([-90, 0, 0])
RPI_assembly();
}
rpi_holes()
vflip()
translate_z(pcb_thickness(rpi))
screw(pcb_screw, 6.4);
}
}
//! 1. Print the fan duct in flexible TPE with low infill.
//! 1. Slide the pms5003 into the printed receptacle with the fan to the outside. Secure with tape if it is loose.
//! 1. Slide the fan into the fan duct.
//! 1. Slide the fan duct into the printed recepacle.
module back_assembly() pose([ 228.60, 0.00, 24.30 ])
assembly("back") {
translate(pms5003_pos)
explode(-50)
rotate([90, 0, 0])
pms5003();
explode(-20, explode_children = true)
translate(fan_pos) {
explode(-20)
fan(fan);
translate_z(-fan_depth(fan) / 2)
stl_colour(pp4_colour)
render()
fan_duct_stl();
}
translate_z(height + top_thickness + base_thickness + eps) vflip()
stl_colour(show_box ? pp1_colour : pp2_colour) render() enviro_plus_case_base_stl();
}
//! * Solder the fan wires to the veroboard assembly
//!
//! ![FanWires](docs/fan_connection.jpg)
//!
//! * Slide the back assembly into the case and secure with four M2 x 6mm cap screws and washers.
module main_assembly() pose([170, 335, 0], exploded = false) pose([ 42.20, 0.00, 159.60 ], exploded = true)
assembly("main") {
RPI_case_assembly();
explode(20, explode_children = true) {
pbox_base_screws(box);
back_assembly();
}
}
if($preview) {
if(assembly == "main")
main_assembly();
else if(assembly == "case")
case_assembly();
else if(assembly == "back")
back_assembly();
else if(assembly == "RPI")
RPI_assembly();
else if(assembly == "RPI_case")
RPI_case_assembly();
else if(assembly == "enviro_case")
enviro_case_assembly();
}
else {
gap = 5;
enviro_plus_case_stl();
translate([0, -depth - gap])
enviro_plus_case_base_stl();
translate([0, -2 * (depth + gap)])
bulkhead_stl();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 979 KiB

After

Width:  |  Height:  |  Size: 982 KiB

View File

@@ -51,6 +51,7 @@ use <tests/blowers.scad>
use <tests/box_sections.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_clip.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/camera_housing.scad>
@@ -154,19 +155,46 @@ translate([x5 + 50, cable_grommets_y])
translate([x5 + 95, cable_grommets_y])
press_fits();
translate([x5, cable_grommets_y + 60])
fixing_blocks_y = cable_grommets_y + 60;
translate([x5, fixing_blocks_y])
fixing_blocks();
translate([x5, cable_grommets_y + 90])
corner_blocks_y = fixing_blocks_y + 30;
translate([x5, corner_blocks_y])
corner_blocks();
translate([x5, cable_grommets_y + 160])
feet_y = corner_blocks_y + 70;
translate([x5, feet_y])
feet();
translate([x5 + 70, cable_grommets_y + 160])
translate([x5 + 70, feet_y])
screw_knobs();
translate([x5, cable_grommets_y + 470]) {
knobs_y = feet_y + 40;
translate([640, knobs_y])
printed_pulley_test();
translate([x5, knobs_y])
knobs();
clips_y = knobs_y + 50;
translate([x5, clips_y])
cable_clips();
strap_y = clips_y + 50;
translate([x5 + 60, strap_y])
strap_handles();
handle_y = strap_y + 50;
translate([x5, handle_y])
handle();
pocket_y = handle_y + 70;
translate([x5 + 65, pocket_y])
pocket_handles();
hinge_y = pocket_y + 100;
translate([x5, hinge_y]) {
door_hinges()
door_latches();
@@ -174,29 +202,14 @@ translate([x5, cable_grommets_y + 470]) {
flat_hinges();
}
translate([x5, cable_grommets_y + 380])
no_explode() socket_boxes();
pbox_y = hinge_y + 70;
translate([900, pbox_y])
printed_boxes();
translate([640, cable_grommets_y + 200])
printed_pulley_test();
translate([x5, cable_grommets_y + 200])
knobs();
translate([x5 + 60, cable_grommets_y + 250])
strap_handles();
translate([x5, cable_grommets_y + 300])
handle();
translate([950, 600])
box_y = pbox_y + 150;
translate([950, box_y])
box_test();
translate([900, 750])
pocket_handles();
translate([900, 850])
printed_boxes();
translate([950, 1400])
rotate(-90)
@@ -427,6 +440,9 @@ translate([x2, extrusions_y])
translate([400, transformers_y])
transformers();
translate([x4 + 50, transformers_y])
no_explode() socket_boxes();
belts_y = 0;
rails_y = belts_y + 200;

View File

@@ -86,7 +86,6 @@ function box_screw_length(type, top) =
let(s = top ? box_top_sheet(type) : box_base_sheet(type))
screw_length(box_screw(type), sheet_thickness(s) + box_corner_gap(type) + box_profile_overlap(type) - 1, washers = 2, insert = true, longer = true);
function box_wall_clearance(type) = box_sheet_slot(type) / 2 - sheet_thickness(box_sheets(type)) / 2;
function box_margin(type) = box_profile_overlap(type) + box_corner_gap(type); //! How much the bezel intrudes on the specified height
function box_intrusion(type) = box_hole_inset(type) + box_boss_r(type); //! Corner profile intrusion
function sheet_reduction(type) = 2 * box_corner_gap(type) + sheet_end_clearance;

117
printed/cable_clip.scad Normal file
View File

@@ -0,0 +1,117 @@
//
// NopSCADlib Copyright Chris Palmer 2022
// 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/>.
//
//
//! Cable clips to order. Can be for one or two cables of different sizes.
//
include <../core.scad>
use <../vitamins/wire.scad>
use <../utils/fillet.scad>
wall = 2;
function cable_clip_width(screw) = max(wall + 2 * screw_clearance_radius(screw) + wall, washer_diameter(screw_washer(screw))); //! Width given the `screw`.
function cable_clip_height(cable) = cable_height(cable) + wall; //! Height given the `cable`.
function cable_clip_extent(screw, cable) = screw_clearance_radius(screw) + wall + cable_width(cable) + wall; //! How far it extends from the screw.
function cable_clip_offset(screw, cable) = screw_clearance_radius(screw) + wall + cable_width(cable) / 2; //! The offset of the cable from the screw
module single_cable_clip(screw, cable, h = 0) {
screw_dia = 2 * screw_clearance_radius(screw);
height = cable_clip_width(screw);
depth = h ? h : cable_height(cable) + wall;
w = cable_width(cable);
width = wall + w + wall + screw_dia + wall;
hole_x = wall + w + wall + screw_dia / 2;
rad = min(wall + cable_wire_size(cable) / 2, depth / 2);
r = extrusion_width - eps;
translate([-hole_x, 0]) difference() {
linear_extrude(height)
difference() {
hull() {
rounded_square([width, 1], r, center = false);
translate([width - 1, 0])
rounded_square([1, depth], r, center = false);
translate([rad, depth - rad])
circle(r = rad);
}
translate([wall + cable_width(cable) / 2, 0]) {
hull() {
for(p = cable_bundle_positions(cable))
translate(p)
circle(d = cable_wire_size(cable));
square([w, eps], center = true);
}
for(side = [-1, 1])
translate([side * w / 2, 0])
hflip(side < 0)
fillet(r = r, h = 0);
}
}
translate([hole_x, depth / 2, height / 2])
rotate([90,0,0])
teardrop_plus(h = depth + 1, r = screw_dia / 2, center = true);
}
}
module double_cable_clip(screw, cable1, cable2) {
h = max(cable_clip_height(cable1), cable_clip_height(cable2));
union() {
single_cable_clip(screw, cable1, h);
mirror([1,0,0]) single_cable_clip(screw, cable2, h);
}
}
module cable_clip(screw, cable1, cable2 = 0) { //! Create the STL for a single cable or two cable clip
function clip_str(screw) = str("cable_clip_", screw_radius(screw) * 20);
function cable_str(cable) = str("_", cable_wires(cable), "_", round(cable_wire_size(cable) * 10));
if(cable2) {
stl(str(clip_str(screw), cable_str(cable1), cable_str(cable2)));
double_cable_clip(screw, cable1, cable2);
}
else {
stl(str(clip_str(screw), cable_str(cable1)));
single_cable_clip(screw, cable1);
}
}
module cable_clip_assembly(screw, thickness, cable1, cable2 = 0) { //! Cable clip with the fasteners
height = max(cable_clip_height(cable1), cable2 ? cable_clip_height(cable2) : 0);
stl_colour(pp1_colour) render()
translate([0, cable_clip_width(screw) / 2]) rotate([90, 0, 0])
cable_clip(screw, cable1, cable2);
translate_z(height)
screw_and_washer(screw, screw_length(screw, height + thickness, 2, nyloc = true));
translate_z(-thickness)
vflip()
nut_and_washer(screw_nut(screw), true);
}

View File

@@ -121,7 +121,7 @@ module corner_block(screw = def_screw, name = false) { //! Generate the STL for
}
module corner_block_assembly(screw = def_screw, name = false) //! The printed block with inserts
assembly(str("corner_block_M", 20 * screw_radius(screw)), ngb = true) {
assembly(name ? name : str("corner_block_M", 20 * screw_radius(screw)), ngb = true) {
insert = screw_insert(screw);
stl_colour(name ? pp2_colour : pp1_colour)
@@ -256,7 +256,7 @@ module 2screw_block(screw = def_screw, name = false) { //! Generate the STL for
}
module 2screw_block_assembly(screw = def_screw, name = false) //! The printed block with inserts
assembly(str("2screw_block_M", 20 * screw_radius(screw)), ngb = true) {
assembly(name ? name : str("2screw_block_M", 20 * screw_radius(screw)), ngb = true) {
insert = screw_insert(screw);
stl_colour(name ? pp2_colour : pp1_colour)

View File

@@ -137,7 +137,7 @@ module pocket_handle_assembly(type) { //! Assembly with fasteners in place
translate_z(f.z + t / 2) hflip() {
stl_colour(pp1_colour)
pocket_handle(type);
render() pocket_handle(type);
pocket_handle_hole_positions(type) {
translate_z(f.z + t)

View File

@@ -105,7 +105,7 @@ assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", str_ways(way
module ribbon_clamp_fastened_assembly(ways, thickness, screw = screw) { //! Clamp with fasteners in place
tape_l = floor(ribbon_clamp_slot(ways));
tape_width = 25;
tape_width = ribbon_clamp_width(screw) + 2;
tape_thickness = 0.5;
vitamin(str(": Tape self amalgamating silicone ",tape_l," x 25mm"));

136
readme.md
View File

@@ -23,30 +23,31 @@ A list of changes classified as breaking, additions or fixes is maintained in [C
<th align="left"> Vitamins A-H </th><th align="left"> Vitamins I-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 = "#7_segments">7_segments</a> </td><td> <a href = "#IECs">IECs</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 = "#Axials">Axials</a> </td><td> <a href = "#Inserts">Inserts</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 = "#BLDC_motors">BLDC_motors</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Core_xy">Core_xy</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bearing_blocks">Bearing_blocks</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td></td></tr>
<tr><td> <a href = "#Box_sections">Box_sections</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Servo_motors">Servo_motors</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Knob">Knob</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_triangle">Rounded_triangle</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Terminals">Terminals</a> </td><td> <a href = "#Pocket_handle">Pocket_handle</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 = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</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 = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Printed_pulleys">Printed_pulleys</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Potentiometers">Potentiometers</a> </td><td> <a href = "#Wire">Wire</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#BLDC_motors">BLDC_motors</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_clip">Cable_clip</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Core_xy">Core_xy</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bearing_blocks">Bearing_blocks</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td></td></tr>
<tr><td> <a href = "#Box_sections">Box_sections</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Servo_motors">Servo_motors</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Knob">Knob</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_triangle">Rounded_triangle</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Terminals">Terminals</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Pocket_handle">Pocket_handle</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Printed_pulleys">Printed_pulleys</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</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 = "#Potentiometers">Potentiometers</a> </td><td> <a href = "#Wire">Wire</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 = "#Pulleys">Pulleys</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
</table>
---
@@ -108,7 +109,7 @@ Axial components for PCBs.
| 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. |
| `wire_link(d, l, h = 1, tail = 3)` | Draw a wire jumper link. If `l` is zero then a vertical wire is drawn. |
![axials](tests/png/axials.png)
@@ -123,6 +124,7 @@ Axial components for PCBs.
| 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 |
| 1 | `wire_link(0.8, 10.16)` | Wire link 0.8mm x 0.4" |
| 1 | `wire_link(0.8, 0, h = 5)` | Wire link 0.8mm x 8mm |
<a href="#top">Top</a>
@@ -2441,6 +2443,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `smd_resistor(RES0603, 1K)` | SMD resistor 0603 1K 0.1W |
| 1 | `smd_resistor(RES0805, 1K)` | SMD resistor 0805 1K 0.125W |
| 1 | `smd_resistor(RES1206, 1K)` | SMD resistor 1206 1K 0.25W |
| 1 | `smd_sot(SOT223)` | SOT223 package LM117 |
| 1 | `smd_sot(SOT23)` | SOT23 package 2N7000 |
| 1 | `square_button(button_4p5mm)` | Square button 4.5mm |
| 1 | `square_button(button_6mm)` | Square button 6mm |
| 1 | `pcb(TMC2130)` | TMC2130 |
@@ -2457,6 +2461,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 2 | `vero_pin()` | Vero board pin |
| 1 | `wire_link(0.8, 5.08, h = 10.16)` | Wire link 0.8mm x 0.2" |
| 1 | `wire_link(0.8, 10.16)` | Wire link 0.8mm x 0.4" |
| 1 | `wire_link(0.8, 0, h = 5)` | Wire link 0.8mm x 8mm |
<a href="#top">Top</a>
@@ -3634,6 +3639,13 @@ Surface mount components for PCBs.
| `smd_res_end_cap(type)` | End cap width |
| `smd_res_power(type)` | Power rating in Watts |
| `smd_res_size(type)` | Body length, width and height |
| `smd_sot_lead_pitch(type)` | Lead pitch |
| `smd_sot_lead_size(type)` | Lead width, foot depth, lead thickness |
| `smd_sot_lead_span(type)` | Total span of leads |
| `smd_sot_lead_z(type)` | Top of lead frame from top |
| `smd_sot_size(type)` | Body length, width and height |
| `smd_sot_tab_width(type)` | The wide lead at the top |
| `smd_sot_z(type)` | Height above PCB surface |
### Functions
| Function | Description |
@@ -3645,9 +3657,10 @@ Surface mount components for PCBs.
### Modules
| Module | Description |
|:--- |:--- |
| `smd_capacitor(type, height)` | Draw an SMD capacitor with specified height |
| `smd_capacitor(type, height, value = undef)` | Draw an SMD capacitor with specified height |
| `smd_led(type, colour, cutout)` | Draw an SMD LED with specified `colour` |
| `smd_resistor(type, value)` | Draw an SMD resistor with specified value |
| `smd_sot(type, value)` | Draw an SMD transistor |
![smds](tests/png/smds.png)
@@ -3662,6 +3675,8 @@ Surface mount components for PCBs.
| 1 | `smd_resistor(RES0603, 1R0)` | SMD resistor 0603 1R0 0.1W |
| 1 | `smd_resistor(RES0805, 10M)` | SMD resistor 0805 10M 0.125W |
| 1 | `smd_resistor(RES1206, 100K)` | SMD resistor 1206 100K 0.25W |
| 1 | `smd_sot(SOT223)` | SOT223 package FZT851 |
| 1 | `smd_sot(SOT23)` | SOT23 package 2N7000 |
<a href="#top">Top</a>
@@ -4227,6 +4242,7 @@ Veroboard with mounting holes, track breaks, removed tracks, solder points and c
### Functions
| Function | Description |
|:--- |:--- |
| `vero(name, assembly, holes, strips, pitch = inch(0.1)` | Constructor |
| `vero_length(type)` | Length of the board |
| `vero_size(type)` | Board size |
| `vero_thickness(type)` | Thickness of the substrate |
@@ -4237,6 +4253,7 @@ Veroboard with mounting holes, track breaks, removed tracks, solder points and c
### Modules
| Module | Description |
|:--- |:--- |
| `solder_meniscus(type, ir = 0.3, r = undef)` | Draw a solder meniscus |
| `vero_cutouts(type, angle = undef)` | Make cutouts to clear components |
| `vero_grid_pos(type, x, y)` | Convert grid position to offset from the centre |
| `vero_mounting_hole_positions(type)` | Positions children at the mounting holes |
@@ -4374,10 +4391,14 @@ Just a BOM entry at the moment and cable bundle size functions for holes, plus c
### Functions
| Function | Description |
|:--- |:--- |
| `cable(wires, size, colours, ribbon = false)` | Cable constructor |
| `cable_bundle(cable)` | Arrangement of a bundle in a flat cable clip |
| `cable_bundle_positions(cable)` | Positions of wires in a bundle to go through a cable strip |
| `cable_height(cable)` | Height in flat clip |
| `cable_is_ribbon(cable)` | Is a ribbon cable? |
| `cable_radius(cable)` | Radius of a bundle of wires, see <http://mathworld.wolfram.com/CirclePacking.html>. |
| `cable_width(cable)` | Width in flat clip |
| `cable_wire_colours(cable)` | Individual wire colours |
| `cable_wire_size(cable)` | Size of each wire in a bundle |
| `cable_wires(cable)` | Number of wires in a bundle |
| `wire_hole_radius(cable)` | Radius of a hole to accept a bundle of wires, rounded up to standard metric drill size |
@@ -4668,6 +4689,51 @@ fixing_blocks along the sides.
| 12 | fixing_block_M30_assembly |
<a href="#top">Top</a>
---
<a name="Cable_clip"></a>
## Cable_clip
Cable clips to order. Can be for one or two cables of different sizes.
[printed/cable_clip.scad](printed/cable_clip.scad) Implementation.
[tests/cable_clip.scad](tests/cable_clip.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| `cable_clip_extent(screw, cable)` | How far it extends from the screw. |
| `cable_clip_height(cable)` | Height given the `cable`. |
| `cable_clip_offset(screw, cable)` | The offset of the cable from the screw |
| `cable_clip_width(screw)` | Width given the `screw`. |
### Modules
| Module | Description |
|:--- |:--- |
| `cable_clip(screw, cable1, cable2 = 0)` | Create the STL for a single cable or two cable clip |
| `cable_clip_assembly(screw, thickness, cable1, cable2 = 0)` | Cable clip with the fasteners |
![cable_clip](tests/png/cable_clip.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 5 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 2 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm |
| 3 | `screw(M3_dome_screw, 16)` | Screw M3 dome x 16mm |
| 10 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
### Printed
| Qty | Filename |
| ---:|:--- |
| 1 | cable_clip_30_10_13.stl |
| 1 | cable_clip_30_1_14_2_14.stl |
| 1 | cable_clip_30_1_60.stl |
| 1 | cable_clip_30_3_14_4_14.stl |
| 1 | cable_clip_30_5_14_6_14.stl |
<a href="#top">Top</a>
---
@@ -6064,6 +6130,10 @@ Annotation used in this documentation
## Bezier
Bezier curves and function to get and adjust the length or minimum z point.
`bezier_join()` joins two paths with a Bezier curve that starts tangential to the end of `path1` and ends tangential to the end of `path2`.
To do this the outer control points are the path ends and the inner two control points are along the tangents to the path ends.
The only degree of freedom is how far along those tangents, which are the `d` and optional `d2` parameters.
[utils/bezier.scad](utils/bezier.scad) Implementation.
[tests/bezier.scad](tests/bezier.scad) Code for this example.
@@ -6074,6 +6144,7 @@ Bezier curves and function to get and adjust the length or minimum z point.
| `adjust_bezier_length(v, l, eps = 0.001, r1 = 1.0, r2 = 1.5, l1, l2)` | Adjust Bezier control points `v` to get the required curve length `l` |
| `adjust_bezier_z(v, z, eps = 0.001, r1 = 1, r2 = 1.5, z1, z2)` | Adjust Bezier control points `v` to get the required minimum `z` |
| `bezier(t, v)` | Returns a point at distance `t` [0 - 1] along the curve with control points `v` |
| `bezier_join(path1, path2, d, d2 = undef)` | Join two paths with a Bezier curve, control points are the path ends are `d` and `d2` from the ends in the same direction. |
| `bezier_length(v, delta = 0.01, t = 0, length = 0)` | Calculate the length of a Bezier curve from control points `v` |
| `bezier_min_z(v, steps = 100, z = inf, i = 0)` | Calculate the minimum z coordinate of a Bezier curve from control points `v` |
| `bezier_path(v, steps = 100)` | Returns a Bezier path from control points `v` with `steps` segments |
@@ -6364,6 +6435,7 @@ Maths utilities for manipulating vectors and matrices.
| `map(v, func)` | make a new vector where the func function argument is applied to each element of the vector v |
| `mapi(v, func)` | make a new vector where the func function argument is applied to each element of the vector v. The func will get the index number as first argument, and the element as second argument. |
| `nearly_zero(x)` | True if x is close to zero |
| `path_length(path, i = 0, length = 0)` | Calculated the length along a path |
| `quadratic_real_roots(a, b, c)` | Returns real roots of a quadratic equation, biggest first. Returns empty list if no real roots |
| `radians(degrees)` | Convert radians to degrees |
| `reduce(v, func, unity)` | reduce a vector v to a single entity by applying the func function recursively to the reduced value so far and the next element, starting with unity as the initial reduced value |
@@ -6565,6 +6637,12 @@ Subsequent rotations use the minimum rotation method.
The path can be open or closed. If closed sweep ensures that the start and end have the same rotation to line up.
An additional twist around the path can be specified. If the path is closed this should be a multiple of 360.
`rounded_path()` can be used to generate a path of lines connected by arcs, useful for wire runs, etc.
The vertices specify where the the path would be without any rounding.
Each vertex, apart from the first and the last, has an associated radius and the path shortcuts the vertex with an arc specified by the radius.
`spiral_paths()` makes a list of new paths that spiral around a given path. It can be used to make twisted wires that follow a rounded_path, for example.
[utils/sweep.scad](utils/sweep.scad) Implementation.
[tests/sweep.scad](tests/sweep.scad) Code for this example.
@@ -6578,14 +6656,18 @@ An additional twist around the path can be specified. If the path is closed this
| `cap(facets, segment = 0, end)` | Create the mesh for an end cap |
| `circle_points(r = 1, z = 0, dir = -1)` | Generate the points of a circle, setting z makes a single turn spiral |
| `helical_twist_per_segment(r, pitch, sides)` | Calculate the twist around Z that rotate_from_to() introduces |
| `path_length(path, i = 0, length = 0)` | Calculated the length along a path |
| `rectangle_points(w, h)` | Generate the points of a rectangle |
| `rounded_path(path)` | Convert a rounded_path, consisting of a start coordinate, vertex / radius pairs and then an end coordinate, to a path of points for sweep. |
| `rounded_path_vertices(path)` | Show the unrounded version of a rounded_path for debug |
| `segmented_path(path, min_segment)` | Add points to a path to enforce a minimum segment length |
| `skin_faces(points, npoints, facets, loop, offset = 0)` | Create the mesh for the swept volume without end caps |
| `spiral_paths(path, n, r, twists, start_angle)` | Create a new paths which sprial around the given path. Use for making twisted cables |
| `sweep(path, profile, loop = false, twist = 0)` | Generate the point list and face list of the swept volume |
### Modules
| Module | Description |
|:--- |:--- |
| `show_path(path)` | Show a path using a chain of hulls for debugging, duplicate points are highlighted. |
| `sweep(path, profile, loop = false, twist = 0, convexity = 1)` | Draw a polyhedron that is the swept volume |
![sweep](tests/png/sweep.png)

View File

@@ -59,7 +59,7 @@ test_pcb = ["test_pcb", "Test PCB",
[ [3, 3], [3, -3], [-3, 3], [-3, -3] ],
// components
[
[ 20, -5, 180, "trimpot10"],
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 90, "trimpot10", true],
[ 10, 2, 90, "smd_led", LED0805, "red"],
[ 13, 2, 90, "smd_led", LED0603, "orange"],
@@ -69,6 +69,8 @@ test_pcb = ["test_pcb", "Test PCB",
[ 25, 2, 90, "smd_cap", CAP1206, 1.5],
[ 28, 2, 90, "smd_cap", CAP0805, 1.0],
[ 31, 2, 90, "smd_cap", CAP0603, 0.7],
[ 16, 6, -90, "smd_sot", SOT23, "2N7000"],
[ 28, 20, -90, "smd_sot", SOT223, "LM117"],
[ 10, 10, 0, "2p54header", 4, 1],
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
@@ -87,6 +89,7 @@ test_pcb = ["test_pcb", "Test PCB",
[ 8, 155, 180, "usb_B"],
[ 25, 200, 0, "buzzer", 4.5, 8.5],
[ 25, 218, 0, "buzzer"],
[ 38, 190, -90, "text", 25, 4, "Silkscreen", "Liberation Sans:style=Bold"],
[ 8, 190, 180, "jack"],
[ 6, 200, 180, "barrel_jack"],
[ 5, 218, 180, "hdmi"],
@@ -99,6 +102,7 @@ test_pcb = ["test_pcb", "Test PCB",
[ 65, 22, 0, "ax_res", res1_2, 100000],
[ 55, 22, 0, "vero_pin"],
[ 55, 17, 0, "vero_pin", true],
[ 55, 9, 0, "link", 0, 5],
[ 80, 9, 0, "link", inch(0.2), inch(0.4)],
[ 80, 12, 0, "ax_res", res1_8, 1000000, 1, inch(0.1)],

View File

@@ -33,6 +33,11 @@ module smds() {
layout([for(c = smd_capacitors) smd_cap_size(c).x], 1)
let(c = smd_capacitors[$i])
smd_capacitor(c, smd_cap_size(c).y * 0.8);
translate([0, 12])
layout([for(s = smd_sots) smd_sot_size(s).x], 1)
let(s = smd_sots[$i])
smd_sot(s, ["2N7000", "FZT851"][$i]);
}
if($preview)

View File

@@ -28,6 +28,9 @@ module axials() {
rotate(90)
wire_link(0.8, inch(0.4));
pcb_grid(pcb, 0, 7)
wire_link(0.8, 0, 5);
for(i = [0 : len(ax_resistors) - 1]) {
pcb_grid(pcb, 2 * i + 2, 1 + [0, 0.5, 1.5][i])
rotate(90)

View File

@@ -77,6 +77,17 @@ module beziers() {
translate(control_points[1] - [0, 0, 2])
label(str("bezier_length = ", length, ", bezier_min_z = ", bezier_min_z(curve)), valign = "top");
path1 = [[20, 20, 0], [40, 20, 0]];
path2 = [[70, 40, -5], [60, 40, 0]];
color("green")
for(p = concat(path1, path2))
translate(p)
sphere(1);
color("orange")
sweep(bezier_join(path1, path2, 10), circle_points(0.5, $fn = 64));
}
if($preview)

59
tests/cable_clip.scad Normal file
View File

@@ -0,0 +1,59 @@
//
// NopSCADlib Copyright Chris Palmer 2022
// 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 <../printed/cable_clip.scad>
use <../vitamins/wire.scad>
sheet_thickness = 3;
cables = [
for(i = [1 : 6]) [i, 1.4], [1, 6], 0, [10, inch(0.05), true], 0
];
screw = M3_dome_screw;
module cable_clips() {
for(i = [0 : ceil(len(cables) / 2) - 1])
translate([i * 25, 0]) {
cable1 = cables[2 * i];
cable2 = cables[2 * i + 1];
if($preview) {
cable_clip_assembly(screw, sheet_thickness, cable1, cable2);
for(j = [0 : 1])
let(cable = cables[2 * i + j])
if(cable)
let(positions = cable_bundle_positions(cable))
for(i = [0 : len(positions) - 1])
let(p = positions[i])
translate([p.x + [-1, 1][j] * cable_clip_offset(screw, cable), 0, p.y])
rotate([90, 0, 0])
color([grey(20), "blue", "red", "orange", "yellow", "green", "brown", "purple", "grey", "white"][i])
cylinder(d = cable_wire_size(cable), h = 30, center = true);
}
else
cable_clip(screw, cable1, cable2);
}
}
cable_clips();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

BIN
tests/png/cable_clip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

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