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

Compare commits

...

156 Commits

Author SHA1 Message Date
Chris Palmer
2166a9be6a extrusion_corner_bracket_assembly() and extrusion_inner_corner_bracket() can now be passed the extrusion type.
E2020t and E4040t thinner extrusions added to work with the brackets.
Extrusions can now have recessed channels, round or square centre sections and holes.
Fixed the shape of extrusion centre section spars.
T-nuts now have 45 degree chamfers instead of a fixed 1mm minimum thickness.
2021-09-05 10:24:42 +01:00
Chris Palmer
511729008d Added missing documentation for sliding_t_nut(). 2021-09-03 15:47:15 +01:00
Chris Palmer
5111ec04bc E40_corner_bracket, E40_corner_bracket and M8_sliding_ball_t_nut added.
Inner corner brackets now show the long arm with chamfered ridges rather
than a normal T-nut and the grub screws are inserted to meet the extrusion.
2021-09-03 09:23:24 +01:00
Chris Palmer
cef3a620a6 Updated changelog 2021-08-31 23:41:34 +01:00
Chris Palmer
da5191e52c Merge branch 'martinbudden-M2p5_dome_screw' 2021-08-31 23:40:51 +01:00
Chris Palmer
d9af5b7f70 Updated images and readme. 2021-08-31 23:38:34 +01:00
Chris Palmer
c30d7f1ad9 Merge branch 'M2p5_dome_screw' of https://github.com/martinbudden/NopSCADlib into martinbudden-M2p5_dome_screw 2021-08-31 23:15:56 +01:00
Chris Palmer
a5382cbe04 Updated changelog. 2021-08-31 23:03:22 +01:00
Chris Palmer
00c5c90a5e Updated big picture 2021-08-31 23:00:58 +01:00
Chris Palmer
01c26d8a34 Added Lichuan servo motors contributed by Niclas Hedhman. 2021-08-31 22:51:24 +01:00
Chris Palmer
ef2102420b Added NEMA8 and NEMA8BH stepper motors.
Steppers can now have dual shafts, hollow shafts and black end caps.
2021-08-31 22:43:37 +01:00
Chris Palmer
540f841163 Added crude representation of JST ZH connectors. 2021-08-31 22:25:31 +01:00
Chris Palmer
1045502efb Added more aluminium sheet thickness 2021-08-31 22:12:30 +01:00
Chris Palmer
485184f092 Added HGH15CA and HGH20CA rails. 2021-08-31 22:04:12 +01:00
Chris Palmer
b893c9069a Added SFU1610 ballscrew nut 2021-08-31 21:56:20 +01:00
Chris Palmer
69f4ced29d Added M8_cs_cap_screw, M5_grub_screw and M6_grub_screw.
Fixed M6_cs_cap_screw and M4_grub_screw socket sizes.
2021-08-31 21:50:43 +01:00
Chris Palmer
5c1aa849fe New layout for big picture. 2021-08-31 21:34:28 +01:00
Martin Budden
9d65f69bf3 Added M2p5_dome_screw. 2021-08-31 20:05:47 +01:00
Chris Palmer
515b99fdc0 Merge branch 'martinbudden-rpi_pico' 2021-08-27 16:18:22 +01:00
Chris Palmer
631d052c68 Updated changelog 2021-08-27 16:18:04 +01:00
Chris Palmer
1247303cb9 Updated images and readme. 2021-08-27 16:15:42 +01:00
Chris Palmer
290be4beb6 Merge branch 'rpi_pico' of https://github.com/martinbudden/NopSCADlib into martinbudden-rpi_pico 2021-08-27 15:04:23 +01:00
Chris Palmer
24e941799d Udpated changelog. 2021-08-27 14:27:29 +01:00
Chris Palmer
6a556c5879 Merge branch 'martinbudden-bldc_propshaft_fix' 2021-08-27 14:20:14 +01:00
Martin Budden
14ab1bb8b6 Added Raspberry Pi Pico. 2021-08-13 10:05:27 +01:00
Martin Budden
be53547728 Fixed display of BLDC prop shaft when thread lengh = 0. 2021-08-09 15:17:30 +01:00
Chris Palmer
ba7d7d32ad Updated chnagelog. 2021-07-04 08:39:47 +01:00
Chris Palmer
d3049bc81b Merge branch 'martinbudden-pcb_plating_colour' 2021-07-04 08:38:20 +01:00
Martin Budden
df35e14fc7 Improved handling of pcb plating colour. 2021-07-01 22:49:35 +01:00
Chris Palmer
21c2aa5d62 Updated changelog. 2021-06-29 11:44:48 +01:00
Chris Palmer
c982876ebc Can now specify the screw used for PSU shrouds and get the wall thickness. 2021-06-29 11:42:20 +01:00
Chris Palmer
5ccda42e5b Updated changelog. 2021-06-17 16:17:09 +01:00
Chris Palmer
92d0444e5f Changelog now runs codespell to fix the spellings in the commit comments. 2021-06-17 16:15:46 +01:00
Chris Palmer
b239c1462e Updated changelog. 2021-06-17 16:01:31 +01:00
Chris Palmer
6413b7b2a0 Merge branch 'martinbudden-spelling_corrections' 2021-06-17 15:58:32 +01:00
Chris Palmer
0b0ce66c85 Updated changelog. 2021-06-17 15:56:09 +01:00
Chris Palmer
d38055c15c Updated readme. 2021-06-17 15:53:59 +01:00
Chris Palmer
cf99418a19 Merge branch 'spelling_corrections' of https://github.com/martinbudden/NopSCADlib into martinbudden-spelling_corrections 2021-06-17 15:15:37 +01:00
Chris Palmer
0cd0e72d92 Merge branch 'martinbudden-typos' 2021-06-17 15:15:04 +01:00
Chris Palmer
2c4a498a7a Merge branch 'typos' of https://github.com/martinbudden/NopSCADlib into martinbudden-typos 2021-06-17 15:12:31 +01:00
Chris Palmer
451101fcd6 Updated changelog. 2021-06-17 15:11:03 +01:00
Chris Palmer
c7a6d8164f Added molex_usb_Ax1() and now shows SMT caps in the PCB test. 2021-06-17 15:08:53 +01:00
Martin Budden
8d7c44b80d Spelling corrections. 2021-06-15 10:01:32 +01:00
Martin Budden
dcfe4262c5 Fixed typos. 2021-06-11 20:39:01 +01:00
Chris Palmer
fe3b84f672 Updated changelog 2021-06-08 08:17:37 +01:00
Chris Palmer
d1a17bd4ac Added LIPO fuel gauge PCB. 2021-06-08 08:09:08 +01:00
Chris Palmer
b8efa11fd9 Added SMD capacitors. 2021-06-08 08:08:35 +01:00
Chris Palmer
3bc8f35e37 Can now put jst_ph connectors on PCBs 2021-06-07 17:32:23 +01:00
Chris Palmer
39c11ef3b2 Added 2p54joiner to represent cropped headers joining PCBs. 2021-06-07 17:31:44 +01:00
Chris Palmer
5a8a1da880 Added Seeeduino XIAO.
Tiny PCBs now shown in a third line.
2021-06-07 12:23:29 +01:00
Chris Palmer
3147862212 PCB lands can be rounded and can specify colour.
Holes can be positioned on the edge to make surface mountable connections.
2021-06-07 10:59:47 +01:00
Chris Palmer
4fc8a7f47d Fixed z-fighting between transparent LEDs and PCB. 2021-06-07 10:56:32 +01:00
Chris Palmer
a9ed9944c3 Added PERF70x51. 2021-06-06 17:18:37 +01:00
Chris Palmer
9cd2dbc316 Added copper colour constant.
Copper PCB pads and veroboard tracks now use copper colour.
2021-06-06 17:17:33 +01:00
Chris Palmer
f3bfbbfcf2 Fixed Python error when top level assembly is empty. 2021-06-06 16:53:06 +01:00
Chris Palmer
baaa85ffed Updated readme. 2021-06-06 16:51:32 +01:00
Chris Palmer
f1a49d4e28 Better description of pcb_grid(). 2021-06-06 16:49:33 +01:00
Chris Palmer
0eed0673b0 Updated changelog. 2021-06-04 18:48:38 +01:00
Chris Palmer
9a4cc7ec42 Ziptie BOM entries no longer segregated by radius wrapped around. 2021-06-04 18:46:31 +01:00
Chris Palmer
2fb1185edf Updated changelog. 2021-06-04 17:49:17 +01:00
Chris Palmer
a782d43e67 bom.py now generates bom.csv to allow costed BOMs to be made using a spreadsheet. 2021-06-04 17:47:29 +01:00
Chris Palmer
ae934d47c7 Updated changelog. 2021-06-03 11:59:54 +01:00
Chris Palmer
823f3b936e Add the ability to have a target specific top level module in place of main_assembly(). 2021-06-03 11:58:10 +01:00
Chris Palmer
3027b942a6 Updated changelog. 2021-06-02 16:07:19 +01:00
Chris Palmer
749a1f0648 Fixed male thread z-fighting bug. 2021-06-02 16:05:51 +01:00
Chris Palmer
5c898df217 More readable code in rounded_polygon. 2021-06-01 09:53:46 +01:00
Chris Palmer
7a566cc856 Updated changelog. 2021-06-01 08:20:44 +01:00
Chris Palmer
20d799a3c1 IEC_320_C14_switched_fused_inlet now shows the correct object name in the example. 2021-06-01 08:18:57 +01:00
Chris Palmer
2ee95bba65 Updated changelog. 2021-05-31 17:24:31 +01:00
Chris Palmer
f49bb63266 Merge branch 'martinbudden-bldc_motors' 2021-05-31 17:22:43 +01:00
Chris Palmer
258109811b Added uppercase version of BLCD_motors.scad. 2021-05-31 17:21:49 +01:00
Chris Palmer
b39fd536c2 Removed lower case version of bldc_motors.scad. 2021-05-31 17:21:03 +01:00
Chris Palmer
a5a87d260d Updated images and readme. 2021-05-31 17:19:56 +01:00
Chris Palmer
b09efb10e0 Merge branch 'bldc_motors' of https://github.com/martinbudden/NopSCADlib into martinbudden-bldc_motors 2021-05-31 16:25:23 +01:00
Chris Palmer
53acaac379 Updated changelog 2021-05-31 16:22:52 +01:00
Chris Palmer
9b40e0dcef Merge branch 'martinbudden-thread_colour_assert' 2021-05-31 16:20:29 +01:00
Martin Budden
00ca412441 Added BLDC3548 motor. 2021-05-30 18:58:55 +01:00
Martin Budden
1e6d7f5dd6 Brushless DC motors. 2021-05-30 18:55:32 +01:00
Martin Budden
ec07d95657 Added assertion to check colour format in module thread. 2021-05-30 16:00:13 +01:00
Chris Palmer
0dab0dca08 Added missing includes core.scad which generates warnings with latest OpenSCAD snapshots.
Note, however, NopSCADlib does not work with the current OpenSCAD snapshot.
2021-05-19 17:54:31 +01:00
Chris Palmer
6e6cd45295 Updated changelog 2021-05-18 23:21:40 +01:00
Chris Palmer
3a7fde6c56 Merge branch 'master' of https://github.com/nophead/NopSCADlib.git 2021-05-18 23:18:18 +01:00
Chris Palmer
c5bb898856 Updated changelog. 2021-05-18 23:16:15 +01:00
Chris Palmer
11ebe2225d Removed spurious convexity in difference from rounded_polygon(). 2021-05-18 23:14:34 +01:00
Chris
a1e25bb878 Merge pull request #180 from martinbudden/global_defs_typo
Typo in global_defs.
2021-05-15 14:36:58 +01:00
Martin Budden
9689683b7e Typo in global_defs. 2021-05-15 11:42:24 +01:00
Chris Palmer
08946e3d70 Updated changelog. 2021-05-02 17:16:21 +01:00
Chris Palmer
15c2946e91 Merge branch 'martinbudden-blower_size' 2021-05-02 17:14:28 +01:00
Chris Palmer
34019196cd Updated readme 2021-05-02 17:14:14 +01:00
Martin Budden
436fc71cf3 Added blower_size function. 2021-05-02 15:27:44 +01:00
Chris Palmer
fd67c166f7 Updated changelog 2021-04-26 00:02:59 +01:00
Chris Palmer
634deab911 Merge branch 'martinbudden-core_xy_orientation' 2021-04-26 00:01:40 +01:00
Chris Palmer
e2feceb608 Updated readme 2021-04-26 00:00:41 +01:00
Chris Palmer
d1258e0b0c Merge branch 'core_xy_orientation' of https://github.com/martinbudden/NopSCADlib into martinbudden-core_xy_orientation 2021-04-25 23:57:44 +01:00
Chris Palmer
bd61a1dc55 Updated changelog 2021-04-25 23:56:47 +01:00
Chris Palmer
055e83902f Merge branch 'martinbudden-leadnut_typo' 2021-04-25 23:38:27 +01:00
Chris Palmer
feec1e7ae5 Updated readme. 2021-04-25 23:37:48 +01:00
Martin Budden
be76af2fc4 Fixed typo in leadnut.scad. 2021-04-25 18:31:51 +01:00
Martin Budden
9c1a9bf357 Add facility to orient core_xy with left motor being lower or upper motor. 2021-04-25 17:56:24 +01:00
Chris Palmer
9647fb474b Updated changelog 2021-04-25 00:08:57 +01:00
Chris Palmer
49fdfea792 Added 35BYGHJ75 geared stepper. 2021-04-25 00:07:22 +01:00
Chris Palmer
ac0bacfeda Removed echo in rails test. 2021-04-25 00:02:05 +01:00
Chris Palmer
6288059d99 Updated changelog. 2021-04-13 15:07:09 +01:00
Chris Palmer
0f1dff230a Merge branch 'martinbudden-pcb_component' 2021-04-13 15:05:18 +01:00
Chris Palmer
e379fa8ada Updated readme. 2021-04-13 15:05:12 +01:00
Chris Palmer
313d7508df Merge branch 'pcb_component' of https://github.com/martinbudden/NopSCADlib into martinbudden-pcb_component 2021-04-13 15:01:27 +01:00
Chris Palmer
083caca4e8 Updated changelog. 2021-04-13 15:00:37 +01:00
Chris Palmer
49329df00c Merge branch 'martinbudden-box_section' 2021-04-13 14:57:35 +01:00
Chris Palmer
edc0b86bb1 Updated images and readme. 2021-04-13 14:56:08 +01:00
Martin Budden
5fbff060b0 Added a pcb_component function. 2021-04-13 14:42:00 +01:00
Chris Palmer
b94ca4ad3a Merge branch 'box_section' of https://github.com/martinbudden/NopSCADlib into martinbudden-box_section 2021-04-12 22:35:01 +01:00
Chris Palmer
bc5515d35e Updated changelog. 2021-04-12 22:31:23 +01:00
Chris Palmer
44d213deaa Merge branch 'martinbudden-psu_size' 2021-04-12 22:29:41 +01:00
Chris Palmer
145c5d9b1a Updated readme. 2021-04-12 22:29:20 +01:00
Chris Palmer
7abbbd9b96 Merge branch 'psu_size' of https://github.com/martinbudden/NopSCADlib into martinbudden-psu_size 2021-04-12 22:26:25 +01:00
Chris Palmer
5b160cee88 Updated changelog. 2021-04-12 22:23:58 +01:00
Chris Palmer
3f31607840 Added No8 screws. 2021-04-12 22:22:25 +01:00
Martin Budden
1efed649cf Added PSU size function. 2021-04-12 17:52:57 +01:00
Martin Budden
b70c2f993c Added box sections. 2021-04-12 17:47:35 +01:00
Chris Palmer
56e252f3dc Updated changelog 2021-04-05 16:54:31 +01:00
Chris Palmer
f12b36ea04 Corrected MGN12 rail end value.
Added assert for rail end value too big.
2021-04-05 16:45:23 +01:00
Chris Palmer
bd5811e69b Updated changelog 2021-04-03 12:17:54 +01:00
Chris Palmer
ede4da6f1d Merge branch 'martinbudden-MGN7Hand9H_carriages' 2021-04-03 12:16:07 +01:00
Chris Palmer
51cc2fd679 Carriages now appear on the BOM and both variants are shown in the rail test. 2021-04-03 12:14:36 +01:00
Chris Palmer
4ce2f53e20 Merge branch 'MGN7Hand9H_carriages' of https://github.com/martinbudden/NopSCADlib into martinbudden-MGN7Hand9H_carriages 2021-04-02 19:53:41 +01:00
Chris Palmer
e338c47e73 Updated changelog 2021-04-02 19:52:15 +01:00
Chris Palmer
8328a70f42 Merge branch 'martinbudden-pulley_children' 2021-04-02 19:49:27 +01:00
Chris Palmer
cc794cd7c3 Updated readme. 2021-04-02 19:48:35 +01:00
Chris Palmer
df28bd5116 Merge branch 'pulley_children' of https://github.com/martinbudden/NopSCADlib into martinbudden-pulley_children 2021-04-02 19:39:28 +01:00
Chris Palmer
61de6041d8 Updated changelog. 2021-04-02 19:31:33 +01:00
Chris Palmer
b2d712bca9 Added quadratic_real_roots() and cubic_real_roots(). 2021-04-02 19:30:38 +01:00
Chris Palmer
f3376edaf1 Documented xor() function. 2021-04-02 19:28:49 +01:00
Chris Palmer
c073419c0b Added opengrab_screw_depth() function. 2021-04-02 19:25:42 +01:00
Martin Budden
608168de8e Added MGN7H and MGN9H carriages. 2021-03-31 01:46:18 +01:00
Martin Budden
fc45a40bd3 Added translated children to pulley. 2021-03-31 01:40:06 +01:00
Chris Palmer
52e9c1d7fd Updated changelog 2021-03-22 16:15:09 +00:00
Chris Palmer
ca1b34e9ca Added sink parameter to screw_polysink() to recess the head. 2021-03-22 16:11:51 +00:00
Chris Palmer
cbab9cea02 Fixed M6_cs_cap_screw. 2021-03-22 12:27:11 +00:00
Chris Palmer
69cf998862 Updated changelog 2021-03-21 18:50:14 +00:00
Chris Palmer
08bce9ec03 Updated changelog 2021-03-21 18:45:01 +00:00
Chris Palmer
4aa7dbb416 Added M6_cs_cap_screw. 2021-03-21 18:37:17 +00:00
Chris Palmer
7c7c2e5d3f Pixel changes due to switch to summer computer. 2021-03-21 17:57:46 +00:00
Chris Palmer
f6f6664c0d Updated OpenSCAD version required. 2021-03-15 00:24:14 +00:00
Chris Palmer
2fd2e118a0 Updated changelog 2021-03-14 19:04:00 +00:00
Chris Palmer
22c6fef113 Updated changelog 2021-03-14 18:56:50 +00:00
Chris Palmer
dcf0c949b9 Merge branch 'SmoothieAq-open_belt' 2021-03-14 18:54:28 +00:00
Chris Palmer
9ded315801 Removed the belt gap options and changed the tests to use open loops instead.
Note previous belt lengths were incorrect with negative turns.
Fixed spelling typos.
_belt_length() no longer needs belt type.
Uptated images and readme.
2021-03-14 18:53:37 +00:00
Chris Palmer
42e03679b4 Merge branch 'open_belt' of https://github.com/SmoothieAq/NopSCADlib into SmoothieAq-open_belt 2021-03-14 14:39:05 +00:00
SmoothieAq
d2c795f5f5 fix nan angle (hopefully) 2021-03-14 14:18:05 +01:00
Chris Palmer
83b4ab2374 Merge branch 'open_belt' of https://github.com/SmoothieAq/NopSCADlib into SmoothieAq-open_belt 2021-03-14 12:33:46 +00:00
SmoothieAq
573c50774b changes after review 2021-03-14 12:48:14 +01:00
Chris Palmer
4b93623492 changelog.py now omits "Updated changelog" commits. 2021-03-13 11:19:59 +00:00
Chris Palmer
d496898c80 Updated changelog 2021-03-13 10:46:30 +00:00
Chris Palmer
544e69c71b pulley_pr() now has an optional belt type for non-standard belt over smooth pulleys. 2021-03-13 10:45:54 +00:00
SmoothieAq
240334784d Extension to belt.scad
Can now:
- render open loops
- twist the belt
- use pulleys instead of radius in the points list

Fixes some precision a few places
Breaking change in belt_length(); now requires a type argument
2021-03-11 13:40:17 +01:00
SmoothieAq
516b225275 Merge pull request #1 from nophead/master
update fork
2021-03-10 09:11:48 +01:00
138 changed files with 2706 additions and 754 deletions

View File

@@ -3,9 +3,244 @@
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
### [v15.24.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.24.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.23.0...v15.24.0 "diff with v15.23.0")
* 2021-08-31 [`d9af5b7`](https://github.com/nophead/NopSCADlib/commit/d9af5b7f705791ca8ef230ecd1b831c042587002 "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
* 2021-08-31 [`9d65f69`](https://github.com/nophead/NopSCADlib/commit/9d65f69bf3e7cd325d24bc5410a4763bb7164b8f "show commit") [M.B.](# "Martin Budden") Added `M2p5_dome_screw`.
### [v15.23.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.23.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.22.0...v15.23.0 "diff with v15.22.0")
* 2021-08-31 [`00c5c90`](https://github.com/nophead/NopSCADlib/commit/00c5c90a5e74f47f0e6f5e3a7996f70fa34f0833 "show commit") [C.P.](# "Chris Palmer") Updated big picture
* 2021-08-31 [`01c26d8`](https://github.com/nophead/NopSCADlib/commit/01c26d8a349e802738a8b0d06575a3e6915bf070 "show commit") [C.P.](# "Chris Palmer") Added Lichuan servo motors contributed by Niclas Hedhman.
* 2021-08-31 [`ef21024`](https://github.com/nophead/NopSCADlib/commit/ef2102420b15e5be4008a6a3cecf5416857265f9 "show commit") [C.P.](# "Chris Palmer") Added NEMA8 and NEMA8BH stepper motors.
Steppers can now have dual shafts, hollow shafts and black end caps.
* 2021-08-31 [`540f841`](https://github.com/nophead/NopSCADlib/commit/540f84116355e7f44a9b5796816d1e3422128ff3 "show commit") [C.P.](# "Chris Palmer") Added crude representation of JST ZH connectors.
* 2021-08-31 [`1045502`](https://github.com/nophead/NopSCADlib/commit/1045502efb1cb94fb7bcc11fd4483b425a880926 "show commit") [C.P.](# "Chris Palmer") Added more aluminium sheet thickness
* 2021-08-31 [`485184f`](https://github.com/nophead/NopSCADlib/commit/485184f09213ff0b191d5c8339471cd24ba3cc90 "show commit") [C.P.](# "Chris Palmer") Added HGH15CA and HGH20CA rails.
* 2021-08-31 [`b893c90`](https://github.com/nophead/NopSCADlib/commit/b893c9069a6bae762733cf1e139d49bab28ad792 "show commit") [C.P.](# "Chris Palmer") Added SFU1610 ballscrew nut
* 2021-08-31 [`69f4ced`](https://github.com/nophead/NopSCADlib/commit/69f4ced29da7e37c88ca24b924c6430144eec849 "show commit") [C.P.](# "Chris Palmer") Added `M8_cs_cap_screw,` `M5_grub_screw` and `M6_grub_screw`.
Fixed `M6_cs_cap_screw` and `M4_grub_screw` socket sizes.
* 2021-08-31 [`5c1aa84`](https://github.com/nophead/NopSCADlib/commit/5c1aa849fe5992617c3128c47dfc969504cbfd2f "show commit") [C.P.](# "Chris Palmer") New layout for big picture.
### [v15.22.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.22.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.21.1...v15.22.0 "diff with v15.21.1")
* 2021-08-27 [`1247303`](https://github.com/nophead/NopSCADlib/commit/1247303cb9dc2694994993b5dc046683becb7fde "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
* 2021-08-13 [`14ab1bb`](https://github.com/nophead/NopSCADlib/commit/14ab1bb8b614055e0bf4ad33799276b0017ca13e "show commit") [M.B.](# "Martin Budden") Added Raspberry Pi Pico.
#### [v15.21.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.21.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.21.0...v15.21.1 "diff with v15.21.0")
* 2021-08-09 [`be53547`](https://github.com/nophead/NopSCADlib/commit/be53547728834d8e786ad4cb5637c768320a3105 "show commit") [M.B.](# "Martin Budden") Fixed display of BLDC prop shaft when thread length `=` 0.
* 2021-07-04 [`ba7d7d3`](https://github.com/nophead/NopSCADlib/commit/ba7d7d32adf554d163143c0ae1707565340bb35b "show commit") [C.P.](# "Chris Palmer") Updated chnagelog.
### [v15.21.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.21.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.20.0...v15.21.0 "diff with v15.20.0")
* 2021-07-01 [`df35e14`](https://github.com/nophead/NopSCADlib/commit/df35e14fc71794c3826d6c99ce3cab93a4cfa5fe "show commit") [M.B.](# "Martin Budden") Improved handling of pcb plating colour.
### [v15.20.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.20.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.19.3...v15.20.0 "diff with v15.19.3")
* 2021-06-29 [`c982876`](https://github.com/nophead/NopSCADlib/commit/c982876ebc0f95b466de1af3c80642dfd88800e6 "show commit") [C.P.](# "Chris Palmer") Can now specify the screw used for PSU shrouds and get the wall thickness.
#### [v15.19.3](https://github.com/nophead/NopSCADlib/releases/tag/v15.19.3 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.19.2...v15.19.3 "diff with v15.19.2")
* 2021-06-17 [`92d0444`](https://github.com/nophead/NopSCADlib/commit/92d0444e5f96c8f4768afb3d014044d7e66c6e69 "show commit") [C.P.](# "Chris Palmer") Changelog now runs codespell to fix the spellings in the commit comments.
#### [v15.19.2](https://github.com/nophead/NopSCADlib/releases/tag/v15.19.2 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.19.1...v15.19.2 "diff with v15.19.1")
* 2021-06-15 [`8d7c44b`](https://github.com/nophead/NopSCADlib/commit/8d7c44b80deffcc8c6b84c7a6485c959826cb381 "show commit") [M.B.](# "Martin Budden") Spelling corrections.
#### [v15.19.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.19.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.19.0...v15.19.1 "diff with v15.19.0")
* 2021-06-17 [`d38055c`](https://github.com/nophead/NopSCADlib/commit/d38055c15c8b00f91f9c5a4749264acc9b123aad "show commit") [C.P.](# "Chris Palmer") Updated readme.
* 2021-06-11 [`dcfe426`](https://github.com/nophead/NopSCADlib/commit/dcfe4262c519fb750702564309b790cda5b1c090 "show commit") [M.B.](# "Martin Budden") Fixed typos.
### [v15.19.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.19.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.18.0...v15.19.0 "diff with v15.18.0")
* 2021-06-17 [`c7a6d81`](https://github.com/nophead/NopSCADlib/commit/c7a6d8164f545e83c4d871080ac63b7d903829df "show commit") [C.P.](# "Chris Palmer") Added `molex_usb_Ax1()` and now shows SMT caps in the PCB test.
### [v15.18.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.18.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.17.1...v15.18.0 "diff with v15.17.1")
* 2021-06-08 [`d1a17bd`](https://github.com/nophead/NopSCADlib/commit/d1a17bd4ac90a7d3d6de7c4d4d032e8198c48647 "show commit") [C.P.](# "Chris Palmer") Added LIPO fuel gauge PCB.
* 2021-06-08 [`b8efa11`](https://github.com/nophead/NopSCADlib/commit/b8efa11fd9504f4b837be663190d238c6227941e "show commit") [C.P.](# "Chris Palmer") Added SMD capacitors.
* 2021-06-07 [`3bc8f35`](https://github.com/nophead/NopSCADlib/commit/3bc8f35e37741ef12d45951546059902b472b34a "show commit") [C.P.](# "Chris Palmer") Can now put `jst_ph` connectors on PCBs
* 2021-06-07 [`39c11ef`](https://github.com/nophead/NopSCADlib/commit/39c11ef3b209256be393b3b211fef72c8ac793a1 "show commit") [C.P.](# "Chris Palmer") Added 2p54joiner to represent cropped headers joining PCBs.
* 2021-06-07 [`5a8a1da`](https://github.com/nophead/NopSCADlib/commit/5a8a1da8801e3d799b7e322b397b236685552f97 "show commit") [C.P.](# "Chris Palmer") Added Seeeduino XIAO.
Tiny PCBs now shown in a third line.
* 2021-06-07 [`3147862`](https://github.com/nophead/NopSCADlib/commit/3147862212d6d1277a5e164909e4004e3e321f10 "show commit") [C.P.](# "Chris Palmer") PCB lands can be rounded and can specify colour.
Holes can be positioned on the edge to make surface mountable connections.
#### [v15.17.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.17.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.17.0...v15.17.1 "diff with v15.17.0")
* 2021-06-07 [`4fc8a7f`](https://github.com/nophead/NopSCADlib/commit/4fc8a7f47df9a880b8e02c9e0f1a3a63d9939c3e "show commit") [C.P.](# "Chris Palmer") Fixed z-fighting between transparent LEDs and PCB.
### [v15.17.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.17.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.16.2...v15.17.0 "diff with v15.16.2")
* 2021-06-06 [`a9ed994`](https://github.com/nophead/NopSCADlib/commit/a9ed9944c328d1fa5121ae10e4e0243bda45f001 "show commit") [C.P.](# "Chris Palmer") Added PERF70x51.
* 2021-06-06 [`9cd2dbc`](https://github.com/nophead/NopSCADlib/commit/9cd2dbc3167c1d14ac1f72e5676f4154151b5638 "show commit") [C.P.](# "Chris Palmer") Added copper colour constant.
Copper PCB pads and veroboard tracks now use copper colour.
#### [v15.16.2](https://github.com/nophead/NopSCADlib/releases/tag/v15.16.2 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.16.1...v15.16.2 "diff with v15.16.1")
* 2021-06-06 [`f3bfbbf`](https://github.com/nophead/NopSCADlib/commit/f3bfbbfcf21209fd993aa7ebc25c8d8d3c12fbd5 "show commit") [C.P.](# "Chris Palmer") Fixed Python error when top level assembly is empty.
* 2021-06-06 [`baaa85f`](https://github.com/nophead/NopSCADlib/commit/baaa85ffedb1a7cdca42e01ca8f2e257438070fc "show commit") [C.P.](# "Chris Palmer") Updated readme.
* 2021-06-06 [`f1a49d4`](https://github.com/nophead/NopSCADlib/commit/f1a49d4e28bf063950b113c64acaa918d470767f "show commit") [C.P.](# "Chris Palmer") Better description of `pcb_grid()`.
#### [v15.16.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.16.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.16.0...v15.16.1 "diff with v15.16.0")
* 2021-06-04 [`9a4cc7e`](https://github.com/nophead/NopSCADlib/commit/9a4cc7ec42bf440e24ad3dacd88d7055736ae793 "show commit") [C.P.](# "Chris Palmer") Ziptie BOM entries no longer segregated by radius wrapped around.
### [v15.16.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.16.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.15.0...v15.16.0 "diff with v15.15.0")
* 2021-06-04 [`a782d43`](https://github.com/nophead/NopSCADlib/commit/a782d43e67f4091f44bd9018817e7263e2944477 "show commit") [C.P.](# "Chris Palmer") `bom.py` now generates `bom.csv` to allow costed BOMs to be made using a spreadsheet.
### [v15.15.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.15.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.14.2...v15.15.0 "diff with v15.14.2")
* 2021-06-03 [`823f3b9`](https://github.com/nophead/NopSCADlib/commit/823f3b936e6c33897445d3f3272b69237f013537 "show commit") [C.P.](# "Chris Palmer") Add the ability to have a target specific top level module in place of `main_assembly()`.
#### [v15.14.2](https://github.com/nophead/NopSCADlib/releases/tag/v15.14.2 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.14.1...v15.14.2 "diff with v15.14.1")
* 2021-06-02 [`749a1f0`](https://github.com/nophead/NopSCADlib/commit/749a1f0648196bd0ae47dbe93ac1b5e3a06d78cd "show commit") [C.P.](# "Chris Palmer") Fixed male thread z-fighting bug.
* 2021-06-01 [`5c898df`](https://github.com/nophead/NopSCADlib/commit/5c898df2172a7e202c9e3d8c6641a0aaf95e5d48 "show commit") [C.P.](# "Chris Palmer") More readable code in `rounded_polygon`.
#### [v15.14.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.14.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.14.0...v15.14.1 "diff with v15.14.0")
* 2021-06-01 [`20d799a`](https://github.com/nophead/NopSCADlib/commit/20d799a3c115d3d32f101c4419d6e9b57c3be8c7 "show commit") [C.P.](# "Chris Palmer") `IEC_320_C14_switched_fused_inlet` now shows the correct object name in the example.
### [v15.14.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.14.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.13.4...v15.14.0 "diff with v15.13.4")
* 2021-05-31 [`2581098`](https://github.com/nophead/NopSCADlib/commit/258109811b7b7f71895340dc4b86b96d7dbc2037 "show commit") [C.P.](# "Chris Palmer") Added uppercase version of `BLCD_motors.scad`.
* 2021-05-31 [`b39fd53`](https://github.com/nophead/NopSCADlib/commit/b39fd536c2841a95ab50b8a196e21ee8fc5976d1 "show commit") [C.P.](# "Chris Palmer") Removed lower case version of `bldc_motors.scad`.
* 2021-05-31 [`a5a87d2`](https://github.com/nophead/NopSCADlib/commit/a5a87d260dd4bbe40a8727a4099207271918d02b "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
* 2021-05-30 [`00ca412`](https://github.com/nophead/NopSCADlib/commit/00ca412441c85ea1fd7082453c823445fbbdce4e "show commit") [M.B.](# "Martin Budden") Added BLDC3548 motor.
* 2021-05-30 [`1e6d7f5`](https://github.com/nophead/NopSCADlib/commit/1e6d7f5dd68e64181aef019bb8bca186abb2ac68 "show commit") [M.B.](# "Martin Budden") Brushless DC motors.
#### [v15.13.4](https://github.com/nophead/NopSCADlib/releases/tag/v15.13.4 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.13.3...v15.13.4 "diff with v15.13.3")
* 2021-05-30 [`ec07d95`](https://github.com/nophead/NopSCADlib/commit/ec07d95657d52aab375b3b2acb95c87b369d2194 "show commit") [M.B.](# "Martin Budden") Added assertion to check colour format in module thread.
#### [v15.13.3](https://github.com/nophead/NopSCADlib/releases/tag/v15.13.3 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.13.2...v15.13.3 "diff with v15.13.2")
* 2021-05-19 [`0dab0dc`](https://github.com/nophead/NopSCADlib/commit/0dab0dca08485d1717ee516a61831fcd6963e335 "show commit") [C.P.](# "Chris Palmer") Added missing includes `core.scad` which generates warnings with latest OpenSCAD snapshots.
* Note, however, NopSCADlib does not work with the current OpenSCAD snapshot.
#### [v15.13.2](https://github.com/nophead/NopSCADlib/releases/tag/v15.13.2 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.13.1...v15.13.2 "diff with v15.13.1")
* 2021-05-15 [`9689683`](https://github.com/nophead/NopSCADlib/commit/9689683b7efbde882c057a903dd7fa018107d029 "show commit") [M.B.](# "Martin Budden") Typo in `global_defs`.
#### [v15.13.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.13.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.13.0...v15.13.1 "diff with v15.13.0")
* 2021-05-18 [`11ebe22`](https://github.com/nophead/NopSCADlib/commit/11ebe2225db09bdd45089e4ebf5c1037243bf45c "show commit") [C.P.](# "Chris Palmer") Removed spurious convexity in difference from `rounded_polygon()`.
### [v15.13.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.13.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.12.0...v15.13.0 "diff with v15.12.0")
* 2021-05-02 [`3401919`](https://github.com/nophead/NopSCADlib/commit/34019196cdac6b08e57d773e138a22394b609ea5 "show commit") [C.P.](# "Chris Palmer") Updated readme
* 2021-05-02 [`436fc71`](https://github.com/nophead/NopSCADlib/commit/436fc71cf319c1e71b6cbd240b76d7cad5ecd8ba "show commit") [M.B.](# "Martin Budden") Added `blower_size` function.
### [v15.12.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.12.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.11.1...v15.12.0 "diff with v15.11.1")
* 2021-04-26 [`e2feceb`](https://github.com/nophead/NopSCADlib/commit/e2feceb608b4491424c0e4c1e7c191f7d8aeceec "show commit") [C.P.](# "Chris Palmer") Updated readme
* 2021-04-25 [`9c1a9bf`](https://github.com/nophead/NopSCADlib/commit/9c1a9bf3572c07a57b5bd1fde1d9a4aba14e5ea8 "show commit") [M.B.](# "Martin Budden") Add facility to orient `core_xy` with left motor being lower or upper motor.
#### [v15.11.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.11.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.11.0...v15.11.1 "diff with v15.11.0")
* 2021-04-25 [`feec1e7`](https://github.com/nophead/NopSCADlib/commit/feec1e7ae5a5217586e0ab9e7b002e8af8f7c749 "show commit") [C.P.](# "Chris Palmer") Updated readme.
* 2021-04-25 [`be76af2`](https://github.com/nophead/NopSCADlib/commit/be76af2fc490e10e4dd115a56019e33005f87db9 "show commit") [M.B.](# "Martin Budden") Fixed typo in `leadnut.scad`.
### [v15.11.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.11.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.10.1...v15.11.0 "diff with v15.10.1")
* 2021-04-25 [`49fdfea`](https://github.com/nophead/NopSCADlib/commit/49fdfea7926d677b6e0a9eee2fbd928f2935e1eb "show commit") [C.P.](# "Chris Palmer") Added 35BYGHJ75 geared stepper.
#### [v15.10.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.10.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.10.0...v15.10.1 "diff with v15.10.0")
* 2021-04-25 [`ac0bacf`](https://github.com/nophead/NopSCADlib/commit/ac0bacfeda43af62256e7bd3184df695b3e01d37 "show commit") [C.P.](# "Chris Palmer") Removed echo in rails test.
### [v15.10.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.10.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.9.0...v15.10.0 "diff with v15.9.0")
* 2021-04-13 [`e379fa8`](https://github.com/nophead/NopSCADlib/commit/e379fa8ada4a4089fc24ce5fc2c140a2531e2e95 "show commit") [C.P.](# "Chris Palmer") Updated readme.
* 2021-04-13 [`5fbff06`](https://github.com/nophead/NopSCADlib/commit/5fbff060b019a983eba93eb8c5b16adfb6a3f7ee "show commit") [M.B.](# "Martin Budden") Added a `pcb_component` function.
### [v15.9.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.9.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.8.0...v15.9.0 "diff with v15.8.0")
* 2021-04-13 [`edc0b86`](https://github.com/nophead/NopSCADlib/commit/edc0b86bb1cd52e90fe353c4aea9539e95aa5aee "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
* 2021-03-31 [`b70c2f9`](https://github.com/nophead/NopSCADlib/commit/b70c2f993c351bf71da57cfc169ed02a235cf4f3 "show commit") [M.B.](# "Martin Budden") Added box sections.
### [v15.8.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.8.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.7.0...v15.8.0 "diff with v15.7.0")
* 2021-04-12 [`145c5d9`](https://github.com/nophead/NopSCADlib/commit/145c5d9b1a7c873940abf266a321edabdff3b7a0 "show commit") [C.P.](# "Chris Palmer") Updated readme.
* 2021-04-12 [`1efed64`](https://github.com/nophead/NopSCADlib/commit/1efed649cf54607b9d39d4b7f422dd385ccb441f "show commit") [M.B.](# "Martin Budden") Added PSU size function.
### [v15.7.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.7.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.6.1...v15.7.0 "diff with v15.6.1")
* 2021-04-12 [`3f31607`](https://github.com/nophead/NopSCADlib/commit/3f31607840d162f63d12eb2317d2f28af1ecf492 "show commit") [C.P.](# "Chris Palmer") Added No8 screws.
#### [v15.6.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.6.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.6.0...v15.6.1 "diff with v15.6.0")
* 2021-04-05 [`f12b36e`](https://github.com/nophead/NopSCADlib/commit/f12b36ea046b5a784dd81b3c4e95eaf4cf24a58d "show commit") [C.P.](# "Chris Palmer") Corrected MGN12 rail end value.
Added assert for rail end value too big.
### [v15.6.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.6.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.5.0...v15.6.0 "diff with v15.5.0")
* 2021-04-03 [`51cc2fd`](https://github.com/nophead/NopSCADlib/commit/51cc2fd6791065e1c94c761abf7dac0271e6ab28 "show commit") [C.P.](# "Chris Palmer") Carriages now appear on the BOM and both variants are shown in the rail test.
* 2021-03-31 [`608168d`](https://github.com/nophead/NopSCADlib/commit/608168de8e56bfdde5ba605d27baca1900895926 "show commit") [M.B.](# "Martin Budden") Added MGN7H and MGN9H carriages.
### [v15.5.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.5.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.4.0...v15.5.0 "diff with v15.4.0")
* 2021-04-02 [`cc794cd`](https://github.com/nophead/NopSCADlib/commit/cc794cd7c3cd3e3f63d15ebbe5dabb773812ae72 "show commit") [C.P.](# "Chris Palmer") Updated readme.
* 2021-03-31 [`fc45a40`](https://github.com/nophead/NopSCADlib/commit/fc45a40bd3c3b524d9edc226952482296e776831 "show commit") [M.B.](# "Martin Budden") Added translated children to pulley.
### [v15.4.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.4.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.3.1...v15.4.0 "diff with v15.3.1")
* 2021-04-02 [`b2d712b`](https://github.com/nophead/NopSCADlib/commit/b2d712bca94165a338e5f904880d12f9c4c5ecd0 "show commit") [C.P.](# "Chris Palmer") Added `quadratic_real_roots()` and `cubic_real_roots()`.
#### [v15.3.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.3.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.3.0...v15.3.1 "diff with v15.3.0")
* 2021-04-02 [`f3376ed`](https://github.com/nophead/NopSCADlib/commit/f3376edaf186b32f442b94d6d0b42f1ba0c7612c "show commit") [C.P.](# "Chris Palmer") Documented `xor()` function.
### [v15.3.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.3.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.2.0...v15.3.0 "diff with v15.2.0")
* 2021-04-02 [`c073419`](https://github.com/nophead/NopSCADlib/commit/c073419c0b4eddcda4cda5bd0f8d48268b6e58ec "show commit") [C.P.](# "Chris Palmer") Added `opengrab_screw_depth()` function.
### [v15.2.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.2.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.1.1...v15.2.0 "diff with v15.1.1")
* 2021-03-22 [`ca1b34e`](https://github.com/nophead/NopSCADlib/commit/ca1b34e9cad5d82bd878fa4ebf439c0fbdad7f77 "show commit") [C.P.](# "Chris Palmer") Added `sink` parameter to `screw_polysink()` to recess the head.
#### [v15.1.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.1.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.1.0...v15.1.1 "diff with v15.1.0")
* 2021-03-22 [`cbab9ce`](https://github.com/nophead/NopSCADlib/commit/cbab9cea028a204032a91729597572a39ed893a2 "show commit") [C.P.](# "Chris Palmer") Fixed `M6_cs_cap_screw`.
### [v15.1.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.1.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v15.0.1...v15.1.0 "diff with v15.0.1")
* 2021-03-21 [`4aa7dbb`](https://github.com/nophead/NopSCADlib/commit/4aa7dbb416773e42b2b5f77b345f18fcd4d2ae2c "show commit") [C.P.](# "Chris Palmer") Added `M6_cs_cap_screw`.
#### [v15.0.1](https://github.com/nophead/NopSCADlib/releases/tag/v15.0.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v15.0.0...v15.0.1 "diff with v15.0.0")
* 2021-03-21 [`7c7c2e5`](https://github.com/nophead/NopSCADlib/commit/7c7c2e5d3f76e84ae86892f9d90f21619fa61a47 "show commit") [C.P.](# "Chris Palmer") Pixel changes due to switch to summer computer.
* 2021-03-15 [`f6f6664`](https://github.com/nophead/NopSCADlib/commit/f6f6664c0d06a7cc3d49f805a2fd4f4978a3a35a "show commit") [C.P.](# "Chris Palmer") Updated OpenSCAD version required.
## [v15.0.0](https://github.com/nophead/NopSCADlib/releases/tag/v15.0.0 "show release") Breaking Changes [...](https://github.com/nophead/NopSCADlib/compare/v14.1.1...v15.0.0 "diff with v14.1.1")
* 2021-03-14 [`9ded315`](https://github.com/nophead/NopSCADlib/commit/9ded3158010b577088fdaca8a25e478f48a27376 "show commit") [C.P.](# "Chris Palmer") Removed the belt gap options and changed the tests to use open loops instead.
Note previous belt lengths were incorrect with negative turns.
Fixed spelling typos.
`_belt_length()` no longer needs belt type.
Uptated images and readme.
* 2021-03-14 [`d2c795f`](https://github.com/nophead/NopSCADlib/commit/d2c795f5f5c564ec4686a7857bd894738a93a6a0 "show commit") [S.](# "SmoothieAq") fix nan angle (hopefully)
* 2021-03-14 [`573c507`](https://github.com/nophead/NopSCADlib/commit/573c50774bfb2edae25a415ca864abb39c4c1bcf "show commit") [S.](# "SmoothieAq") changes after review
* 2021-03-11 [`2403347`](https://github.com/nophead/NopSCADlib/commit/240334784db8002468fe0f51c1f6404a64fe44a4 "show commit") [S.](# "SmoothieAq") Extension to `belt.scad`
* Can now:
- render open loops
- twist the belt
- use pulleys instead of radius in the points list
* Fixes some precision a few places
Breaking change in `belt_length();` now requires a type argument
#### [v14.1.1](https://github.com/nophead/NopSCADlib/releases/tag/v14.1.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v14.1.0...v14.1.1 "diff with v14.1.0")
* 2021-03-13 [`4b93623`](https://github.com/nophead/NopSCADlib/commit/4b93623492a2b8a073ab9dccc91fb2b21c475f21 "show commit") [C.P.](# "Chris Palmer") `changelog.py` now omits "Updated changelog" commits.
### [v14.1.0](https://github.com/nophead/NopSCADlib/releases/tag/v14.1.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v14.0.1...v14.1.0 "diff with v14.0.1")
* 2021-03-13 [`544e69c`](https://github.com/nophead/NopSCADlib/commit/544e69c71b404636df320be278b3fa7442f10429 "show commit") [C.P.](# "Chris Palmer") `pulley_pr()` now has an optional belt type for non-standard belt over smooth pulleys.
#### [v14.0.1](https://github.com/nophead/NopSCADlib/releases/tag/v14.0.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v14.0.0...v14.0.1 "diff with v14.0.0")
* 2021-03-08 [`e46e6b6`](https://github.com/nophead/NopSCADlib/commit/e46e6b6e5b95792b5b2b4d7a7e4360beed22df0b "show commit") [C.P.](# "Chris Palmer") Fixed markdown numbered points in `core_xy`.
## [v14.0.0](https://github.com/nophead/NopSCADlib/releases/tag/v14.0.0 "show release") Breaking Changes [...](https://github.com/nophead/NopSCADlib/compare/v13.5.0...v14.0.0 "diff with v13.5.0")
* 2021-03-06 [`298d1f9`](https://github.com/nophead/NopSCADlib/commit/298d1f92841f30e13b437c6770fc113954b94108 "show commit") [C.P.](# "Chris Palmer") Interface is the same but filenames to be included or used changed.
Changlog upated.
Changelog updated.
* 2021-03-06 [`491c3b4`](https://github.com/nophead/NopSCADlib/commit/491c3b4ea8d2ef51e55fd389f0dc0b9a6b9bd9a4 "show commit") [C.P.](# "Chris Palmer") Updated readme, `lib.scad` and image.
@@ -41,9 +276,7 @@ Changlog upated.
* 2021-03-03 [`614e5f3`](https://github.com/nophead/NopSCADlib/commit/614e5f3a72db309a3dee996d7241317556883e8d "show commit") [C.P.](# "Chris Palmer") Issues in the changelog now link to to the issue.
* 2021-03-03 [`a7eae4f`](https://github.com/nophead/NopSCADlib/commit/a7eae4f549b51dbe4624a8b67012919cef6cb24a "show commit") [C.P.](# "Chris Palmer") Neater changlog format.
* 2021-03-03 [`7b770ab`](https://github.com/nophead/NopSCADlib/commit/7b770abe12b71fa4b4f7415aa9f46d0f2c9d54f1 "show commit") [C.P.](# "Chris Palmer") Udpated changelog
* 2021-03-03 [`a7eae4f`](https://github.com/nophead/NopSCADlib/commit/a7eae4f549b51dbe4624a8b67012919cef6cb24a "show commit") [C.P.](# "Chris Palmer") Neater changelog format.
* 2021-03-03 [`31ab856`](https://github.com/nophead/NopSCADlib/commit/31ab8562a783464f93812b8c7c45d403587efd0a "show commit") [C.P.](# "Chris Palmer") Updated images
@@ -66,7 +299,7 @@ Changlog upated.
* 2021-02-20 [`03a0c2f`](https://github.com/nophead/NopSCADlib/commit/03a0c2fe981ce12cda51a693f69b4fb19696cb8a "show commit") [C.P.](# "Chris Palmer") Fixed typo.
### [v13.3.0](https://github.com/nophead/NopSCADlib/releases/tag/v13.3.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v13.2.0...v13.3.0 "diff with v13.2.0")
* 2021-02-20 [`7c2df8d`](https://github.com/nophead/NopSCADlib/commit/7c2df8d36d214a8bf8ebdcd39da293209bc175ab "show commit") [C.P.](# "Chris Palmer") The pose module can now specify the camera distance supressing viewall and
* 2021-02-20 [`7c2df8d`](https://github.com/nophead/NopSCADlib/commit/7c2df8d36d214a8bf8ebdcd39da293209bc175ab "show commit") [C.P.](# "Chris Palmer") The pose module can now specify the camera distance suppressing viewall and
autocentre.
### [v13.2.0](https://github.com/nophead/NopSCADlib/releases/tag/v13.2.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v13.1.0...v13.2.0 "diff with v13.1.0")
@@ -361,9 +594,9 @@ Updated pics and readme.
* 2020-12-28 [`ba586b3`](https://github.com/nophead/NopSCADlib/commit/ba586b368582db163af143ebb60afed270f77b1c "show commit") [C.P.](# "Chris Palmer") Example images update to match new contersink screws and teardrops.
### [v10.21.0](https://github.com/nophead/NopSCADlib/releases/tag/v10.21.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v10.20.1...v10.21.0 "diff with v10.20.1")
* 2020-12-28 [`8d22940`](https://github.com/nophead/NopSCADlib/commit/8d22940506df525ac52ef6f8a00ea03661f3b682 "show commit") [C.P.](# "Chris Palmer") Project blurb can now be split with into sections with markdown horizonal rules
* 2020-12-28 [`8d22940`](https://github.com/nophead/NopSCADlib/commit/8d22940506df525ac52ef6f8a00ea03661f3b682 "show commit") [C.P.](# "Chris Palmer") Project blurb can now be split with into sections with markdown horizontal rules
made with asterisks.
If an image is include in the first section the default image is supressed.
If an image is include in the first section the default image is suppressed.
#### [v10.20.1](https://github.com/nophead/NopSCADlib/releases/tag/v10.20.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v10.20.0...v10.20.1 "diff with v10.20.0")
* 2020-12-26 [`87c8bbb`](https://github.com/nophead/NopSCADlib/commit/87c8bbb9a549aabb84004426332dc964583472c5 "show commit") [M.B.](# "Martin Budden") Fixed error in `carriage_size` function.
@@ -378,12 +611,12 @@ If an image is include in the first section the default image is supressed.
### [v10.20.0](https://github.com/nophead/NopSCADlib/releases/tag/v10.20.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v10.19.0...v10.20.0 "diff with v10.19.0")
* 2020-12-24 [`6f8ff60`](https://github.com/nophead/NopSCADlib/commit/6f8ff606fa5b2ef7d81fb687b77bd6236f6d277f "show commit") [C.P.](# "Chris Palmer") Removed `woven_sheet()` from the readme.
Removed redundent code.
Removed redundant code.
* 2020-12-24 [`acd5de0`](https://github.com/nophead/NopSCADlib/commit/acd5de0fbd513b67387478b4c89a5ef4f11b440b "show commit") [C.P.](# "Chris Palmer") Fixed extra BOM entries for woven sheet.
Added render colour to BOM for 3D sheets.
* 2020-12-23 [`cc1e3ba`](https://github.com/nophead/NopSCADlib/commit/cc1e3baaf6ba7451b3545efc949015af822dc95c "show commit") [C.P.](# "Chris Palmer") Reimplemeted woven sheets with an eye to speed and interface consistancy.
* 2020-12-23 [`cc1e3ba`](https://github.com/nophead/NopSCADlib/commit/cc1e3baaf6ba7451b3545efc949015af822dc95c "show commit") [C.P.](# "Chris Palmer") Reimplemeted woven sheets with an eye to speed and interface consistency.
* 2020-12-13 [`85cb54e`](https://github.com/nophead/NopSCADlib/commit/85cb54ef318597a4922077785247ddcb08d5e00d "show commit") [M.B.](# "Martin Budden") Added sheet with checkerboard texture to simulate carbon fiber.
@@ -848,7 +1081,7 @@ Done to reduced the number of global constants.
`Panel_meters` can now have inner apertures and buttons.
### [v7.2.0](https://github.com/nophead/NopSCADlib/releases/tag/v7.2.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v7.1.1...v7.2.0 "diff with v7.1.1")
* 2020-05-02 [`baa737c`](https://github.com/nophead/NopSCADlib/commit/baa737c4d83be0ab38685122ebe535872fe63e20 "show commit") [C.P.](# "Chris Palmer") Updated example to use Foot contructor.
* 2020-05-02 [`baa737c`](https://github.com/nophead/NopSCADlib/commit/baa737c4d83be0ab38685122ebe535872fe63e20 "show commit") [C.P.](# "Chris Palmer") Updated example to use Foot constructor.
* 2020-05-02 [`70b13d2`](https://github.com/nophead/NopSCADlib/commit/70b13d2f2723caa18a69afb7a179d88366c82c51 "show commit") [C.P.](# "Chris Palmer") Added functions to create property lists that are created by the client.
Foot, box, bbox, pbox, `flat_hinge` and `strap_handle`.
@@ -1052,7 +1285,7 @@ The implementation files are still lower case for backwards compatibility.
* 2020-03-03 [`bd60b50`](https://github.com/nophead/NopSCADlib/commit/bd60b50b099d76f6588ddfe900be276ed7d0cf98 "show commit") [C.P.](# "Chris Palmer") Removed lower case tests
* 2020-03-03 [`4d51cb7`](https://github.com/nophead/NopSCADlib/commit/4d51cb73f3d2b3a92ac4c12a2002bc4918228969 "show commit") [C.P.](# "Chris Palmer") Table of contents now has three vitamin coloumns
* 2020-03-03 [`4d51cb7`](https://github.com/nophead/NopSCADlib/commit/4d51cb73f3d2b3a92ac4c12a2002bc4918228969 "show commit") [C.P.](# "Chris Palmer") Table of contents now has three vitamin columns
* 2020-03-02 [`3b77c97`](https://github.com/nophead/NopSCADlib/commit/3b77c975325851caf5e602ae6ceaa8e5d9126425 "show commit") [C.P.](# "Chris Palmer") Example now include `core.scad` instead of `lib.scad`.
@@ -1329,7 +1562,7 @@ This means 5mm, 6mm etc comes before 10mm in BOM.
* 2020-01-11 [`d1324a6`](https://github.com/nophead/NopSCADlib/commit/d1324a670eb7ec898e6663dc9394fc1bd19ef664 "show commit") [M.B.](# "Martin Budden") Added JST-XH connector for pcbs.
* 2020-02-22 [`599fbba`](https://github.com/nophead/NopSCADlib/commit/599fbba6c2b036a4a22fa04f2e06f67ef5bb9578 "show commit") [C.P.](# "Chris Palmer") Reduced dependecies in `pcb_mount` test.
* 2020-02-22 [`599fbba`](https://github.com/nophead/NopSCADlib/commit/599fbba6c2b036a4a22fa04f2e06f67ef5bb9578 "show commit") [C.P.](# "Chris Palmer") Reduced dependencies in `pcb_mount` test.
### [v2.19.0](https://github.com/nophead/NopSCADlib/releases/tag/v2.19.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v2.16.0...v2.19.0 "diff with v2.16.0")
* 2020-02-22 [`6097e07`](https://github.com/nophead/NopSCADlib/commit/6097e0709498166c61712094fcc11f083e25959f "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
@@ -1645,7 +1878,7 @@ IEC screw length fixed at 10 if inserts used.
* 2019-06-14 [`a51e96e`](https://github.com/nophead/NopSCADlib/commit/a51e96ec433c6d347e0d313573585cda9978e7b4 "show commit") [C.P.](# "Chris Palmer") Nuts now show their thickness on the BOM so half nuts have a different description.
## [v1.0.0](https://github.com/nophead/NopSCADlib/releases/tag/v1.0.0 "show release") Breaking Changes [...](https://github.com/nophead/NopSCADlib/compare/v0.0.1...v1.0.0 "diff with v0.0.1")
* 2019-06-14 [`b719601`](https://github.com/nophead/NopSCADlib/commit/b719601a645d899f5477c13a34f857d178bcc3a1 "show commit") [C.P.](# "Chris Palmer") Fixed cable strip parameters and BOM desciption
* 2019-06-14 [`b719601`](https://github.com/nophead/NopSCADlib/commit/b719601a645d899f5477c13a34f857d178bcc3a1 "show commit") [C.P.](# "Chris Palmer") Fixed cable strip parameters and BOM description
#### [v0.0.1](https://github.com/nophead/NopSCADlib/releases/tag/v0.0.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v0.0.0...v0.0.1 "diff with v0.0.0")
* 2019-06-14 [`5ede2d0`](https://github.com/nophead/NopSCADlib/commit/5ede2d0895a8a813ef2bc47bf94462d668bc440b "show commit") [C.P.](# "Chris Palmer") Smooth pulleys now show their OD on the BOM.

View File

@@ -1,7 +1,7 @@
# NopSCADlib usage
## Requirements
1. OpenSCAD 2019.05 or later, download it from here: https://www.openscad.org/downloads.html
1. OpenSCAD 2021.01 or later, download it from here: https://www.openscad.org/downloads.html
1. Python 2.7+ or 3.6+ from https://www.python.org/downloads/
1. ImageMagick 7 www.imagemagick.org
@@ -270,6 +270,22 @@ The target config file is selected by generating `target.scad` that includes `co
The rest of the project includes `target.scad` to use the configuration.
Additionally all the generated file directories (assemblies, bom, stls, dxfs, etc.) are placed in a sub-directory called `<target_name>`.
The build system will look for a `<target_name>_assembly` module and use it as the top level module instead of `main_assembly` if it it exists.
That allows the project description to be target specific if the top level modules are in different scad files.
The top level assembly instructions and assembly contents could also be different if appropriate.
If the top level module is just a shell wrapper that simply includes one other assembly, with no additional parts, then it is removed from the build instructions and
the assembly it calls becomes the top level. This allows a different project description for each target but only one set of top level instructions without repeating them.
### Costed BOMs
A costed bill of materials can be made by opening the generated file `bom/bom.csv` in a spreadsheet program using a single quote as the string delimiter and comma as the field separator.
That gets a list of part descriptions and quantities to which prices can be added to get the total cost and perhaps a URL of where to buy each part.
If a Python file called `parts.py` is found then `bom.py` will attempt to call functions for each part to get a price and URL.
Any functions not found are printed, so you can see the format expected.
The function are passed the quantity to allow them to calculate volume discounts, etc.
### Other libraries
The build scripts need to be able to locate the source files where the modules to generate the STL files and assemblies reside. They will search all the scad files

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View File

@@ -0,0 +1,16 @@
'Ferrule for 1.5mm^2 wire - not shown', 3
'Wire blue 30/0.25mm strands, length 150mm - not shown', 2
'Wire brown 30/0.25mm strands, length 150mm - not shown', 2
'Wire green & yellow 30/0.25mm strands, length 150mm - not shown', 2
'IEC inlet for ATX', 1
'Heatfit insert M3', 2
'4mm shielded jack socket blue', 2
'4mm shielded jack socket brown', 1
'4mm shielded jack socket green', 2
'Mains socket 13A', 1
'Nut M3 x 2.4mm nyloc', 6
'Screw M3 cs cap x 12mm', 2
'Screw M3 cs cap x 20mm', 2
'Screw M3 dome x 10mm', 4
'Heatshrink sleeving ID 3.2mm x 15mm - not shown', 8
'Washer M3 x 7mm x 0.5mm', 10
1 'Ferrule for 1.5mm^2 wire - not shown', 3
2 'Wire blue 30/0.25mm strands, length 150mm - not shown', 2
3 'Wire brown 30/0.25mm strands, length 150mm - not shown', 2
4 'Wire green & yellow 30/0.25mm strands, length 150mm - not shown', 2
5 'IEC inlet for ATX', 1
6 'Heatfit insert M3', 2
7 '4mm shielded jack socket blue', 2
8 '4mm shielded jack socket brown', 1
9 '4mm shielded jack socket green', 2
10 'Mains socket 13A', 1
11 'Nut M3 x 2.4mm nyloc', 6
12 'Screw M3 cs cap x 12mm', 2
13 'Screw M3 cs cap x 20mm', 2
14 'Screw M3 dome x 10mm', 4
15 'Heatshrink sleeving ID 3.2mm x 15mm - not shown', 8
16 'Washer M3 x 7mm x 0.5mm', 10

View File

@@ -27,15 +27,16 @@
// Setting $_bom in the local file overrides it in the local file but not in the libs.
//
rr_green = [0, 146/255, 0]; // RepRap logo colour
crimson = [220/255, 20/255, 60/255];
$_bom = is_undef($bom) ? 0 : $bom; // 0 no bom, 1 assemblies and stls, 2 vitamins as well
$exploded = is_undef($explode) ? 0 : $explode; // 1 for exploded view
layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // layer heigth when printing
layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // layer height when printing
extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // filament width when printing
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // minimum tool radius when milling 2D objects
pp1_colour = is_undef($pp1_colour) ? rr_green : $pp1_colour; // printed part colour 1, RepRap logo colour
pp2_colour = is_undef($pp2_colour) ? "Crimson" : $pp2_colour; // printed part colour 2
pp2_colour = is_undef($pp2_colour) ? crimson : $pp2_colour; // printed part colour 2
pp3_colour = is_undef($pp3_colour) ? "SteelBlue" : $pp3_colour; // printed part colour 3
pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
@@ -53,9 +54,10 @@ $fs = extrusion_width / 2;
function round_to_layer(z) = ceil(z / layer_height) * layer_height;
// Some additional named colours
function grey(n) = [0.01, 0.01, 0.01] * n; //! Generate a shade of grey to pass to color().
gold = [255/255, 215/255, 0/255];
brass = [255/255, 220/255, 100/255];
silver = [0.75, 0.75, 0.75];
gold = [255, 215, 0] / 255;
brass = [255, 220, 100] / 255;
copper = [230, 140, 51] / 255;
/*
* Enums

View File

@@ -28,6 +28,8 @@ include <vitamins/pcbs.scad>
include <vitamins/batteries.scad>
include <vitamins/bearing_blocks.scad>
include <vitamins/blowers.scad>
include <vitamins/bldc_motors.scad>
include <vitamins/box_sections.scad>
include <vitamins/bulldogs.scad>
include <vitamins/buttons.scad>
include <vitamins/cameras.scad>
@@ -53,6 +55,7 @@ include <vitamins/pulleys.scad>
include <vitamins/ring_terminals.scad>
include <vitamins/rails.scad>
include <vitamins/rod.scad>
include <vitamins/servo_motors.scad>
include <vitamins/shaft_couplings.scad>
include <vitamins/sheets.scad>
include <vitamins/sk_brackets.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 KiB

After

Width:  |  Height:  |  Size: 931 KiB

View File

@@ -45,7 +45,9 @@ use <tests/ball_bearings.scad>
use <tests/batteries.scad>
use <tests/bearing_blocks.scad>
use <tests/belts.scad>
use <tests/BLDC_motors.scad>
use <tests/blowers.scad>
use <tests/box_sections.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_strips.scad>
@@ -90,6 +92,7 @@ use <tests/rockers.scad>
use <tests/rod.scad>
use <tests/screws.scad>
use <tests/sealing_strip.scad>
use <tests/servo_motors.scad>
use <tests/shaft_couplings.scad>
use <tests/sheets.scad>
use <tests/SK_brackets.scad>
@@ -183,16 +186,15 @@ translate([x5, cable_grommets_y + 250])
translate([950, 600])
box_test();
translate([830, 770])
translate([900, 750])
pocket_handles();
translate([950, 750])
translate([900, 850])
printed_boxes();
translate([850, 1330])
translate([850, 1330 + 85])
bbox_test();
inserts_y = 0;
nuts_y = inserts_y + 20;
washers_y = nuts_y + 120;
@@ -204,10 +206,11 @@ sealing_strip_y = springs_y + 20;
tubings_y = sealing_strip_y + 20;
pillars_y = tubings_y + 20;
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 + 90;
pulleys_y = ball_bearings_y + 40;
leadnuts_y = pulleys_y + 60;
linear_bearings_y = leadnuts_y + 50;
steppers_y = linear_bearings_y + 110;
sheets_y = steppers_y + 55;
pcbs_y = sheets_y + 60;
displays_y = pcbs_y + 170;
fans_y = displays_y + 80;
@@ -253,13 +256,16 @@ translate([x0, ball_bearings_y])
translate([x0, pulleys_y])
pulleys();
translate([x0, leadnuts_y])
leadnuts();
translate([x0, linear_bearings_y]) {
linear_bearings();
rods();
}
translate([x0 + 10, hot_ends_y])
hot_ends();
translate([x0, steppers_y])
stepper_motors();
translate([x0, sheets_y])
sheets();
@@ -277,7 +283,7 @@ translate([x0, fans_y]) {
fan_guards();
}
translate([x0, transformers_y])
translate([760, fans_y])
variacs();
translate([x0, psus_y]) {
@@ -289,7 +295,6 @@ translate([x0, psus_y]) {
zipties_y = 0;
bulldogs_y = zipties_y + 30;
swiss_clips_y = bulldogs_y + 35;
leadnuts_y = swiss_clips_y + 50;
translate([x1, zipties_y])
zipties();
@@ -300,10 +305,6 @@ translate([x1, bulldogs_y])
translate([x1, swiss_clips_y])
swiss_clips();
translate([x1, leadnuts_y])
leadnuts();
leds_y = 0;
carriers_y = leds_y + 40;
magnets_y = carriers_y + 40;
@@ -360,18 +361,18 @@ iecs_y = d_connectors_y + 80;
modules_y = iecs_y + 60;
ssrs_y = modules_y + 80;
blowers_y = ssrs_y + 60;
batteries_y = blowers_y + 100;
steppers_y = batteries_y + 55;
panel_meters_y = steppers_y + 70;
hot_ends_y = blowers_y + 100;
batteries_y = hot_ends_y + 55;
panel_meters_y = batteries_y + 70;
extrusions_y = panel_meters_y + 80;
translate([x3, veroboard_y])
veroboard_test();
translate([x3 + 70, veroboard_y + 30])
translate([x3 + 60, veroboard_y + 20])
geared_steppers();
translate([x3 + 140, veroboard_y + 20])
translate([x3 + 160, ssrs_y])
pcb_mounts();
translate([x3 + 170, veroboard_y + 16])
@@ -407,8 +408,8 @@ translate([x3, blowers_y])
translate([x3, batteries_y])
batteries();
translate([x2, steppers_y]) // interloper
stepper_motors();
translate([x3 + 10, hot_ends_y])
hot_ends();
translate([x2, panel_meters_y])
panel_meters();
@@ -416,7 +417,7 @@ translate([x2, panel_meters_y])
translate([x2, extrusions_y])
extrusions();
translate([x3, transformers_y])
translate([400, transformers_y])
transformers();
@@ -424,15 +425,20 @@ belts_y = 0;
rails_y = belts_y + 200;
extrusion_brackets_y = rails_y + 250;
sk_brackets_y = extrusion_brackets_y + 80;
kp_pillow_blocks_y = sk_brackets_y + 50;
kp_pillow_blocks_y = sk_brackets_y + 60;
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
cable_strip_y = sheets_y;
box_sections_y = batteries_y;
BLDC_y = steppers_y;
translate([0, transformers_y])
servo_motors();
translate([x4 + 200, belts_y + 58]) {
belt_test();
translate([0, 60])
opengrab_test();
}
translate([x4 + 175, belts_y, -20])
@@ -441,7 +447,7 @@ translate([x4 + 175, belts_y, -20])
translate([x4, rails_y + 130])
rails();
translate([770, fans_y + 50])
translate([x4, cable_strip_y])
cable_strips();
translate([x4, kp_pillow_blocks_y])
@@ -453,12 +459,17 @@ translate([x4, sk_brackets_y])
translate([x4, extrusion_brackets_y])
extrusion_brackets();
translate([x4 + 120, extrusion_brackets_y])
translate([x1, swiss_clips_y + 50])
shaft_couplings();
translate([x4, scs_bearing_blocks_y])
scs_bearing_blocks();
translate([x4, BLDC_y])
bldc_motors();
translate([x2, box_sections_y])
box_sections();
translate([x6, 125])
light_strips();

View File

@@ -54,7 +54,7 @@ function bbox(screw, sheets, base_sheet, top_sheet, span, size, name = "bbox", s
[ screw, sheets, base_sheet, top_sheet, span, size.x, size.y, size.z, name, skip_blocks, star_washers ];
function bbox_volume(type) = bbox_width(type) * bbox_depth(type) * bbox_height(type) / 1000000; //! Internal volume in litres
function bbox_area(type) = let(w = bbox_width(type), d = bbox_depth(type), h = bbox_height(type)) //! Internal surdface area in m^2
function bbox_area(type) = let(w = bbox_width(type), d = bbox_depth(type), h = bbox_height(type)) //! Internal surface area in m^2
2 * (w * d + w * h + d * h) / 1000000;
module bbox_shelf_blank(type) { //! 2D template for a shelf

View File

@@ -45,7 +45,7 @@ function door_hinge_stat_screw() = stat_screw; //! Screw use to fas
function door_hinge_stat_width() = stat_width; //! Width of the stationary part
function door_hinge_stat_length() = stat_length; //! Length of the stationary part
module door_hinge_hole_positions(dir = 0) { //! Position chidren at the door hole positions
module door_hinge_hole_positions(dir = 0) { //! Position children at the door hole positions
hole_pitch = width - 10;
for(side = [-1, 1])

View File

@@ -57,7 +57,7 @@ module door_latch_stl() { //! Generates the STL for the printed part
}
}
module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specified sheet thickess
module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specified sheet thickness
washer = screw_washer(screw);
nut = screw_nut(screw);

View File

@@ -20,7 +20,7 @@
//
//! Parametric cable drag chain to limit the bend radius of a cable run.
//!
//! Each link has a maximum bend angle of 45&deg;, so the mininium radius is proportional to the link length.
//! Each link has a maximum bend angle of 45&deg;, so the minimum radius is proportional to the link length.
//!
//! The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
//!

View File

@@ -17,7 +17,7 @@
// If not, see <https://www.gnu.org/licenses/>.
//
//! Pintable fan finger guard to match the specified fan. To be `include`d, not `use`d.
//! Printable fan finger guard to match the specified fan. To be `include`d, not `use`d.
//!
//! The ring spacing as well as the number of spokes can be specified, if zero a gasket is generated instead of a guard.
//

View File

@@ -40,7 +40,7 @@ function hinge_knuckles(type) = type[6]; //! How many knuckles
function hinge_screw(type) = type[7]; //! Screw type to mount it
function hinge_screws(type) = type[8]; //! How many screws
function hinge_clearance(type) = type[9]; //! Clearance between knuckles
function hinge_margin(type) = type[10]; //! How far to keep the screws from the knuckes
function hinge_margin(type) = type[10]; //! How far to keep the screws from the knuckles
function flat_hinge(name, size, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin) = //! Construct the property list for a flat hinge.
[name, size.x, size.y, size.z, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin];
@@ -73,7 +73,7 @@ module hinge_male(type, female = false) { //! The half with the stationary
assert(kr > pr, "knuckle diameter must be bigger than the pin diameter");
n = hinge_knuckles(type);
assert(n >= 3, "must be at least three knuckes");
assert(n >= 3, "must be at least three knuckles");
mn = ceil(n / 2); // Male knuckles
fn = floor(n / 2); // Female knuckles
gap = hinge_clearance(type);

View File

@@ -41,6 +41,7 @@ overlap = 6;
cable_tie_inset = wall + 4;
function psu_shroud_extent(type) = 15 + wall; //! How far it extends beyond the PSU to clear the connections
function psu_shroud_wall(type) = wall; //! The wall thickness
function psu_shroud_depth(type) = //! Outside depth of the shroud
psu_left_bay(type) + overlap + psu_shroud_extent(type);
@@ -154,7 +155,7 @@ assembly(str("PSU_shroud_", name), ngb = true) {
insert(insert);
}
module psu_shroud_fastened_assembly(type, cable_d, thickness, name, cables = 1) //! Assembly with screws in place
module psu_shroud_fastened_assembly(type, cable_d, thickness, name, cables = 1, screw = screw) //! Assembly with screws in place
{
screw_length = screw_length(screw,thickness + counter_bore, 2, true);

555
readme.md

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,12 @@ from set_config import *
import json
import re
try:
import parts
got_parts_py = True
except:
got_parts_py = False
def find_scad_file(mname):
for filename in os.listdir(source_dir):
if filename[-5:] == ".scad":
@@ -46,6 +52,18 @@ def find_scad_file(mname):
return filename
return None
def main_assembly(target):
file = None
if target:
assembly = target + "_assembly"
file = find_scad_file(assembly)
if not file:
assembly = "main_assembly"
file = find_scad_file(assembly)
if not file:
raise Exception("can't find source for " + assembly)
return assembly, file
class Part:
def __init__(self, args):
self.count = 1
@@ -117,6 +135,33 @@ class BOM:
return ass
return ass.replace("assembly", "assemblies")
def print_CSV(self, file = None):
i = 0
for part in sorted(self.vitamins):
i += 1
if ': ' in part:
part_no, description = part.split(': ')
else:
part_no, description = "", part
qty = self.vitamins[part].count
if got_parts_py:
match = re.match(r'^.*\((.*?)[,\)].*$', part_no)
if match and not match.group(1).startswith('"'):
part_no = part_no.replace('(' + match.group(1), '_' + match.group(1) + '(').replace('(, ', '(')
func = 'parts.' + part_no.replace('(', '(%d, ' % qty).replace(', )', ')')
func = func.replace('true', 'True').replace('false', 'False').replace('undef', 'None')
try:
price, url = eval(func)
print("'%s',%3d,%.2f,'=B%d*C%d',%s" % (description, qty, price, i, i, url), file=file)
except:
if part_no:
print("%s not found in parts.py" % func)
print("'%s',%3d" % (description, qty), file=file)
else:
print("'%s',%3d" % (description, qty), file=file)
if got_parts_py:
print(",'=SUM(B1:B%d)',,'=SUM(D1:D%d)'" %(i, i), file=file)
def print_bom(self, breakdown, file = None):
if self.vitamins:
print("Vitamins:", file=file)
@@ -221,28 +266,20 @@ def parse_bom(file = "openscad.log", name = None):
return main
def usage():
print("\nusage:\n\tbom [target_config] [<accessory_name>_assembly] - Generate BOMs for a project or an accessory to a project.")
print("\nusage:\n\tbom [target_config] - Generate BOMs for a project.")
sys.exit(1)
def boms(target = None, assembly = None):
def boms(target = None):
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)
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
# Find the scad file that makes the main assembly
#
scad_file = find_scad_file(assembly)
if not scad_file:
raise Exception("can't find source for " + assembly)
assembly, scad_file = main_assembly(target)
#
# make a file to use the module
#
@@ -259,8 +296,9 @@ def boms(target = None, assembly = None):
main = parse_bom("openscad.echo", assembly)
if assembly == "main_assembly":
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
main.print_CSV(open(bom_dir + "/bom.csv","wt"))
for ass in main.assemblies:
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
@@ -278,20 +316,8 @@ def boms(target = None, assembly = None):
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 3: usage()
if len(sys.argv) > 2: usage()
if len(sys.argv) == 3:
target, assembly = sys.argv[1], sys.argv[2]
else:
if len(sys.argv) == 2:
if sys.argv[1][-9:] == "_assembly":
target, assembly = None, sys.argv[1]
else:
target, assembly = sys.argv[1], None
else:
target, assembly = None, None
target = sys.argv[1] if len(sys.argv) == 2 else None
if assembly:
if assembly[-9:] != "_assembly": usage()
boms(target, assembly)
boms(target)

View File

@@ -24,6 +24,7 @@ from __future__ import print_function
import sys
import subprocess
import re
from tests import do_cmd
filename = 'CHANGELOG.md'
@@ -159,5 +160,7 @@ if __name__ == '__main__':
print('%s [%s](%s "show release") %s %s' % ('#' * (level + 1), ver, url + '/releases/tag/' + ver, type, diff), file = file)
# Print commits excluding merges
if not c.comment.startswith('Merge branch') and not c.comment.startswith('Merge pull'):
if not c.comment.startswith('Merge branch') and not c.comment.startswith('Merge pull') and not re.match(r'U..ated changelog.*', c.comment):
print('* %s [`%s`](%s "show commit") %s %s\n' % (c.date, c.hash[:7], url + '/commit/' + c.hash, initials(c.author), fixup_comment(c.comment, url)), file = file)
do_cmd(('codespell -w -L od ' + filename).split())

View File

@@ -17,7 +17,7 @@
# If not, see <https://www.gnu.org/licenses/>.
#
# Set command line options from enviroment variables and check if they have changed
# Set command line options from environment variables and check if they have changed
import json, os, deps
from colorama import Fore, init

View File

@@ -173,7 +173,7 @@ def tests(tests):
impl_name = None
if libtest:
vsplit = "AJR" + chr(ord('Z') + 1)
vsplit = "AIR" + 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:

View File

@@ -77,12 +77,12 @@ def bom_to_assemblies(bom_dir, bounds_map):
#
if flat_bom:
ass = flat_bom[-1]
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
if len(ass["assemblies"]) == 1 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
flat_bom = flat_bom[:-1]
return [assembly["name"] for assembly in flat_bom]
def eop(doc_file, last = False, first = False):
print('<span></span>', file = doc_file) # An invisable marker for page breaks because markdown takes much longer if the document contains a div
print('<span></span>', file = doc_file) # An invisible marker for page breaks because markdown takes much longer if the document contains a div
if not first:
print('[Top](#TOP)', file = doc_file)
if not last:
@@ -161,6 +161,7 @@ def views(target, do_assemblies = None):
# Find all the scad files
#
main_blurb = None
main_assembly, main_file = bom.main_assembly(target)
pngs = []
for dir in source_dirs(bom_dir):
if os.path.isdir(dir):
@@ -232,7 +233,7 @@ def views(target, do_assemblies = None):
update_image(tmp_name, tn_name)
done_assemblies.append(real_name)
else:
if module == 'main_assembly':
if module == main_assembly:
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
line_no += 1
#
@@ -246,9 +247,6 @@ def views(target, do_assemblies = None):
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
print('<a name="TOP"></a>', file = doc_file)
print('# %s' % project, file = doc_file)
main_file = bom.find_scad_file('main_assembly')
if not main_file:
raise Exception("can't find source for main_assembly")
text = blurb.scrape_blurb(source_dir + '/' + main_file)
blurbs = blurb.split_blurb(text)
if len(text):

31
tests/BLDC_motors.scad Normal file
View File

@@ -0,0 +1,31 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/bldc_motors.scad>
module bldc_motors()
layout([for(b = bldc_motors) BLDC_diameter(b)])
rotate(-90)
BLDC(bldc_motors[$i]);
if($preview)
let($show_threads = 1)
bldc_motors();

View File

@@ -20,10 +20,10 @@
//
//! BOM and assembly demonstration
//
$explode = 1; // Normally set on the command line when generating assembly views with views.py
include <../core.scad>
include <../vitamins/sheets.scad>
use <../vitamins/insert.scad>
$explode = 1; // Normally set on the command line when generating assembly views with views.py
screw = M3_cap_screw;
sheet = PMMA3;

View File

@@ -16,6 +16,7 @@
// 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/ldrs.scad>
use <../utils/layout.scad>

View File

@@ -64,21 +64,25 @@ test_pcb = ["TestPCB", "Test PCB",
[ 16, 2, 90, "smd_res", RES1206, "1K"],
[ 19, 2, 90, "smd_res", RES0805, "1K"],
[ 22, 2, 90, "smd_res", RES0603, "1K"],
[ 25, 2, 90, "smd_cap", CAP1206, 1.5],
[ 28, 2, 90, "smd_cap", CAP0805, 1.0],
[ 31, 2, 90, "smd_cap", CAP0603, 0.7],
[ 10, 10, 0, "2p54header", 4, 1],
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
[ 10, 20, 0, "2p54boxhdr", 4, 2],
[ 10, 30, 0, "2p54socket", 6, 1],
[ 25, 30, 0, "2p54socket", 4, 1, false, 0, false, "red" ],
[ 10, 40, 0, "chip", 10, 5, 1, grey(20)],
[ 5, 50, 0, "led", LED3mm, "red"],
[ 12, 50, 0, "led", LED5mm, "orange"],
[ 25, 50, 0, "led", LED10mm, "yellow"],
[ 10, 65, 180, "rj45"],
[ 8, 85, 180, "usb_A"],
[ 65, 50, 0, "led", LED3mm, "red"],
[ 75, 50, 0, "led", LED5mm, "orange"],
[ 90, 50, 0, "led", LED10mm, "yellow"],
[ 10, 45, 180, "rj45"],
[ 8, 65, 180, "usb_A"],
[ 8, 105, 180, "usb_Ax2"],
[ 7, 85, 180, "molex_usb_Ax1"],
[ 8.5,125, 180, "molex_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"],
@@ -127,6 +131,8 @@ test_pcb = ["TestPCB", "Test PCB",
[ 52, 200, 0, "pcb", 11, TMC2130 ],
[ 80, 200, 0, "pdip", 24, "27C32", true, inch(0.6) ],
[ 80, 170, 0, "pdip", 8, "NE555" ],
[ 80, 150, 0, "chip", 10, 5, 1, grey(20)],
[ 52, 206, 0, "2p54socket", 8, 1 ],
[ 52, 194, 0, "2p54socket", 8, 1, false, 0, false, "red" ],
[ 50, 220, 0, "standoff", 5, 4.5, 12.5, 2.54],

View File

@@ -29,7 +29,12 @@ module pcbs() {
rotate(90)
pcb_assembly(pcbs[$i], 5 + $i, 3);
translate([0, 110])
translate([0, 45])
layout([for(p = tiny_pcbs) pcb_length(p)], 3)
translate([0, pcb_width(tiny_pcbs[$i]) / 2])
pcb_assembly(tiny_pcbs[$i], 5 + $i, 3);
translate([0, 120])
layout([for(p = perfboards) pcb_length(p)], 10)
translate([0, -pcb_width(perfboards[$i]) / 2])
pcb_assembly(perfboards[$i], 5 + $i, 3);

View File

@@ -22,18 +22,20 @@ include <../vitamins/extrusions.scad>
use <../utils/layout.scad>
module sk_brackets() {
module sk_brackets(examples = false) {
screws = [M4_dome_screw, M4_cap_screw, M5_cap_screw, M5_cap_screw];
nuts = [M4_hammer_nut, M4_sliding_t_nut, M5_sliding_t_nut, undef];
// channel depth = 6 for 2020 extrusion, 9 for 3030 extrusion
depths = [6, 6, 9, 0];
layout([for(s = sk_brackets) 1.5 * sk_size(s)[1]]) {
sk_bracket_assembly(sk_brackets[$i], screw_type = screws[$i], nut_type = nuts[$i], max_screw_depth = depths[$i]);
translate([0, -sk_hole_offset(sk_brackets[$i]) - extrusion_width($i < 2 ? E2020 : E3030) / 2, 0])
rotate([0, 90, 0])
extrusion($i < 2 ? E2020 : E3030, 20, false);
if(examples)
translate([0, -sk_hole_offset(sk_brackets[$i]) - extrusion_width($i < 2 ? E2020 : E3030) / 2, 0])
rotate([0, 90, 0])
extrusion($i < 2 ? E2020 : E3030, 20, false);
}
}
if($preview)
sk_brackets();
sk_brackets(true);

View File

@@ -28,6 +28,11 @@ module smds() {
translate([0, 3])
layout([for(l = smd_leds) smd_led_size(l).x], 1)
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
translate([0, 6])
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);
}
if($preview)

View File

@@ -16,7 +16,7 @@
// 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/ball_bearings.scad>

View File

@@ -25,9 +25,9 @@ use <../utils/layout.scad>
module belt_test() {
p2 = [-75, -50];
p3 = [-75, 100];
p4 = [75, 100];
p4 = [ 75, 100];
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
p5 = [ 75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
module pulleys(flip = false) {
@@ -52,19 +52,21 @@ module belt_test() {
translate(p6) pulley_assembly(GT2x16_plain_idler);
}
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
path = [ [-40, 0, 0],
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)],
[p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
[40, 0, 0],
];
belt = GT2x6;
belt(belt, path, 80, [0, 0]);
belt(belt, path, open = true);
pulleys();
translate_z(20)
hflip() {
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
belt(belt, path, open = true, belt_colour = grey(90), tooth_colour = grey(50));
pulleys(flip=true);
}
@@ -72,6 +74,31 @@ module belt_test() {
layout([for(b = belts) belt_width(b)], 10)
rotate([0, 90, 0])
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
// new example with open loop - this is a simplified example of the style used for example for the BLV 3D printer
pulley = GT2x20ob_pulley;
idler = GT2x16_plain_idler;
corners = [[-75,-50],[75,100]];
carriagepos = [0,0];
carriagew = 80;
points = [
[carriagepos.x - carriagew / 2, carriagepos.y, 0],
[corners[0].x + belt_pulley_pr(belt, pulley) + belt_pulley_pr(belt, idler), carriagepos.y - belt_pulley_pr(belt, idler), idler],
[corners[0].x, corners[0].y, pulley],
[corners[0].x, corners[1].y, idler],
[corners[1].x, corners[1].y, idler],
[corners[1].x, carriagepos.y + belt_pulley_pr(belt, idler), idler],
[carriagepos.x + carriagew / 2, carriagepos.y, 0]
];
translate_z(-30) {
belt(belt, points, open=true, auto_twist=true);
for (p = points)
if (is_list(p.z))
translate([p.x, p.y, 0])
pulley_assembly(p.z);
}
}
if($preview)

30
tests/box_sections.scad Normal file
View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/box_sections.scad>
module box_sections() {
layout([for(b = box_sections) box_section_size(b).x], 20)
box_section(box_sections[$i], 100);
}
if($preview)
box_sections();

View File

@@ -16,6 +16,7 @@
// 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/displays.scad>
@@ -23,7 +24,8 @@ use <../vitamins/pcb.scad>
module displays()
layout([for(d = displays) pcb_length(display_pcb(d))], 10)
display(displays[$i]);
vflip()
display(displays[$i]);
if($preview)
displays();

View File

@@ -16,13 +16,51 @@
// 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 <../core.scad>
include <../vitamins/extrusion_brackets.scad>
include <../vitamins/extrusions.scad>
include <../vitamins/extrusion_brackets.scad>
include <../vitamins/washers.scad>
include <../vitamins/nuts.scad>
module inner_bracket_test(bracket, backwards = false)
rotate([90, 0, 180]) {
extrusion = extrusion_inner_corner_bracket_extrusion(bracket);
eWidth = extrusion_width(extrusion);
size = extrusion_inner_corner_bracket_size(bracket);
tnut = extrusion_inner_corner_bracket_tnut(bracket);
translate([backwards ? -eWidth : 0, 0])
extrusion_inner_corner_bracket(bracket, backwards = backwards);
translate([-eWidth / 2, 0])
rotate([-90, 0, 0])
extrusion(extrusion, size.x - nut_thickness(tnut) - extrusion_tab_thickness(extrusion), false, cornerHole = eWidth > 20);
translate([-eWidth, -eWidth / 2])
rotate([0, 90, 0])
extrusion(extrusion, eWidth + size.y - nut_thickness(tnut) - extrusion_tab_thickness(extrusion), false, cornerHole = eWidth > 20);
}
module bracket_test(bracket)
rotate([90, 0, 180]) {
extrusion = extrusion_corner_bracket_extrusion(bracket);
eWidth = extrusion_width(extrusion);
size = extrusion_corner_bracket_size(bracket);
extrusion_corner_bracket_assembly(bracket);
translate([-eWidth / 2, 0])
rotate([-90, 0, 0])
extrusion(extrusion, size.y, false, cornerHole = eWidth > 20);
translate([-eWidth, -eWidth / 2])
rotate([0, 90, 0])
extrusion(extrusion, eWidth + size.x, false, cornerHole = eWidth > 20);
}
module extrusion_brackets(examples = false) {
extrusion_inner_corner_bracket(E20_inner_corner_bracket);
@@ -32,34 +70,30 @@ module extrusion_brackets(examples = false) {
translate([60, 0])
extrusion_corner_bracket_assembly(E20_corner_bracket);
eWidth = extrusion_width(E2020);
translate([110, 0])
extrusion_inner_corner_bracket(E40_inner_corner_bracket);
translate([140, 0])
extrusion_corner_bracket_assembly(E40_corner_bracket);
if(examples) {
translate([20, 60, 10]) rotate([90, 0, 180]) {
extrusion_inner_corner_bracket(E20_inner_corner_bracket);
translate([20, 50, 10])
inner_bracket_test(E20_inner_corner_bracket, true);
translate([-eWidth / 2, 0, 0])
rotate([-90, 0, 0])
extrusion(E2020, 20, false);
translate([20, 80, 10])
inner_bracket_test(E20_inner_corner_bracket);
translate([-eWidth, -eWidth / 2, 0])
rotate([0, 90, 0])
extrusion(E2020, 40, false);
}
translate([20, 120, 10])
bracket_test(E20_corner_bracket);
translate([100, 60, 10]) rotate([90, 0, 180]) {
extrusion_corner_bracket_assembly(E20_corner_bracket);
translate([100, 70, 10])
inner_bracket_test(E40_inner_corner_bracket);
translate([-eWidth / 2, 0, 0])
rotate([-90, 0, 0])
extrusion(E2020, 30, false);
translate([-eWidth, -eWidth / 2, 0])
rotate([0, 90, 0])
extrusion(E2020, 50, false);
}
translate([100, 130, 10])
bracket_test(E40_corner_bracket);
}
}
if($preview)
extrusion_brackets(true);
let($show_threads = true)
extrusion_brackets(true);

View File

@@ -21,9 +21,24 @@ use <../utils/layout.scad>
include <../vitamins/extrusions.scad>
gap = 10;
module extrusions()
layout([for(e = extrusions) extrusion_width(e)], 10)
extrusion(extrusions[$i], 80, cornerHole = extrusion_width(extrusions[$i]) > 20);
layout([for(e = extrusions) is_list(e[0]) ? extrusion_width(e[0]) : extrusion_width(e)], gap)
let(e = extrusions[$i])
if(is_list(e[0])) {
list = e;
heights = [for(e = list) extrusion_height(e)];
l = len(heights) - 1;
offset = (heights * [for(i = [0 : l]) 1] + l * gap) / 2;
translate([0, -offset])
rotate(90)
layout(heights, gap)
rotate(-90)
extrusion(list[$i], 80, cornerHole = extrusion_width(list[$i]) > 20);
}
else
extrusion(e, 80, cornerHole = extrusion_width(e) > 20);
if ($preview)
extrusions();

View File

@@ -16,12 +16,13 @@
// 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/geared_steppers.scad>
use <../utils/layout.scad>
module geared_steppers()
layout([for(g = geared_steppers) gs_diameter(g)], 5)
layout([for(g = geared_steppers) max(gs_diameter(g), gs_pitch(g) + gs_lug_w(g) / 2)], 5)
geared_stepper(geared_steppers[$i]);
geared_steppers();

View File

@@ -16,6 +16,7 @@
// 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/green_terminals.scad>

View File

@@ -16,6 +16,7 @@
// 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/hygrometer.scad>
if($preview)

View File

@@ -16,6 +16,7 @@
// 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/microview.scad>
microview(!$preview);

View File

@@ -52,6 +52,12 @@ module nuts() {
if(n == M5_nut)
sliding_t_nut(M5_sliding_t_nut);
if(n == M6_nut)
sliding_t_nut(M6_sliding_t_nut);
if(n == M8_nut)
sliding_t_nut(M8_sliding_ball_t_nut);
}
translate([0, 80]) {

View File

@@ -16,6 +16,7 @@
// 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/o_ring.scad>
module o_rings()

View File

@@ -64,8 +64,9 @@ module pin_headers() {
pin_socket(pin_headers[$i], 3, 3, right_angle = true);
}
for(i = [0, 1], p = [5, 2][i], j = [0 , 1]) {
h = [jst_ph_header, jst_xh_header][j];
headers = [jst_zh_header, jst_ph_header, jst_xh_header];
for(i = [0, 1], p = [5, 2][i], j = [0 : len(headers) - 1]) {
h = headers[j];
translate([-20 * (i + 1), 0 + j * 40])
jst_xh_header(h, p);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 162 KiB

BIN
tests/png/bldc_motors.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
tests/png/box_sections.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 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: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 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: 111 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 146 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: 154 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 176 KiB

BIN
tests/png/servo_motors.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

@@ -16,8 +16,8 @@
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../printed/press_fit.scad>
include <../core.scad>
use <../printed/press_fit.scad>
module press_fits()
{

View File

@@ -22,21 +22,28 @@ include <../vitamins/rails.scad>
use <../utils/layout.scad>
use <../vitamins/nut.scad>
length = 200;
sheet = 3;
pos = 1; //[-1 : 0.1 : 1]
function rail_carriages(rail) = [for(c = carriages) if(carriage_rail(c) == rail) c];
module rails()
layout([for(l = carriages) carriage_width(l)], 20)
layout([for(r = rails) carriage_width(rail_carriages(r)[0])], 10)
rotate(-90) {
carriage = carriages[$i];
rail = carriage_rail(carriage);
length = 200;
rail = rails[$i];
carriages = rail_carriages(rail);
carriage = carriages[0];
screw = rail_screw(rail);
nut = screw_nut(screw);
washer = screw_washer(screw);
rail_assembly(carriage, length, pos * carriage_travel(carriage, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
if(len(carriages) > 1)
translate([-carriage_travel(carriages[1], length) / 2, 0])
carriage(carriages[1]);
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));
rail_hole_positions(rail, length, 0)

View File

@@ -16,6 +16,10 @@
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
// Extra countersink depth
sink = 0; // [0 : 0.05: 1.0]
include <../core.scad>
module polysink_stl() {
@@ -32,9 +36,9 @@ module polysink_stl() {
let(s = cs_screws[i])
translate([i * 20, 0]) {
translate_z(size.z)
screw_polysink(s, 2 * size.z + 1);
screw_polysink(s, 2 * size.z + 1, sink = sink);
screw_polysink(s, 2 * size.z + 1, alt = true);
screw_polysink(s, 2 * size.z + 1, alt = true, sink = sink);
}
}
}
@@ -44,7 +48,7 @@ module screws() {
for(x = [0 : len(screw_lists[y]) -1]) {
screw = screw_lists[y][x];
if(screw) {
length = screw_head_type(screw) == hs_grub ? 6
length = screw_head_type(screw) == hs_grub ? screw_radius(screw) * 4
: screw_radius(screw) <= 1.5 ? 10
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
: 30;

31
tests/servo_motors.scad Normal file
View File

@@ -0,0 +1,31 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/servo_motors.scad>
module servo_motors()
layout([for(s = servo_motors) servo_motor_width(s)], 10) let(s = servo_motors[$i]) {
rotate(-90) // Show the keyway
servo_motor(s);
}
if($preview)
servo_motors();

View File

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

View File

@@ -29,7 +29,7 @@
//! This is to prevent the global BOM page becoming too wide in large projects by having it include just the major assemblies.
//!
//! 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.
//! The resulting flat BOM is shown but hierarchical BOMs are also generated for real projects.
//!
//! If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
//! it with code.

View File

@@ -18,7 +18,7 @@
//
//
//! Construct arbirarily large box to partition 3D space and clip objects, useful for creating cross sections to see the inside when debugging.
//! Construct arbitrarily large box to partition 3D space and clip objects, useful for creating cross sections to see the inside when debugging.
//!
//! Original version by Doug Moen on the OpenSCAD forum
//

View File

@@ -28,12 +28,12 @@
//! large increase in the number of facets.
//! When set to 1 the polygons alternate each layer, when set higher the rotation takes `twist + 1` layers to repeat.
//! A small additional rotation is added to make the polygon rotate one more side over the length of the hole to make it appear round when
//! veiwed end on.
//! viewed end on.
//!
//! When `twist` is set the resulting cylinder is extended by `eps` at each end so that the exact length of the hole can be used without
//! leaving a scar on either surface.
//
function sides(r, n = undef) = is_undef(n) ? max(round(4 * r), 3) : n ? max(n, 3) : r2sides(r); //! Optimium number of sides for specified radius
function sides(r, n = undef) = is_undef(n) ? max(round(4 * r), 3) : n ? max(n, 3) : r2sides(r); //! Optimum number of sides for specified radius
function corrected_radius(r, n = undef) = r / cos(180 / sides(r, n)); //! Adjusted radius to make flats lie on the circle
function corrected_diameter(d, n = undef) = 2 * corrected_radius(d / 2 , n); //! Adjusted diameter to make flats lie on the circle

View File

@@ -26,7 +26,7 @@
//
module teardrop(h, r, center = true, truncate = true, chamfer = 0, chamfer_both_ends = true, plus = false) { //! For making horizontal holes that don't need support material, set `truncate = false` to make traditional RepRap teardrops that don't even need bridging
module teardrop_2d(r, truncate) {
er = layer_height / 2 - eps; // Extrustion edge radius
er = layer_height / 2 - eps; // Extrusion edge radius
R = plus ? r + er : r; // Corrected radius
offset = plus ? -er : 0; // Offset inwards
hull()

View File

@@ -51,15 +51,20 @@ function coreXY_lower_tooth_colour(type) = type[8]; //! Colour of the lower b
// relative to the anchor pulley so that the belts align properly
function coreXY_drive_pulley_x_alignment(type) = //! Belt alignment offset of the drive pulley relative to the anchor pulley
(pulley_od(coreXY_drive_pulley(type)) - pulley_od(coreXY_toothed_idler(type))) / 2;
function coreXY_coincident_separation(type) = //! Value of x, y separation to make y-carriage pulleys coincident
[ -coreXY_plain_idler_offset(type).x, -(pulley_od(coreXY_plain_idler(type)) + pulley_od(coreXY_toothed_idler(type)))/2, 0 ];
function coreXY_plain_idler_offset(type) = //! Offset of y-carriage plain idler
[ (pulley_od(coreXY_plain_idler(type)) + pulley_od(coreXY_drive_pulley(type))) / 2 + coreXY_drive_pulley_x_alignment(type), pulley_od(coreXY_plain_idler(type))/2, 0 ];
function coreXY_toothed_idler_offset(type) = //! offset of y-carriage toothed idler
[ 0, -pulley_pr(coreXY_toothed_idler(type)), 0 ];
// helper functions for positioning idlers when the stepper motor drive pulley is offset
function coreXY_drive_toothed_idler_offset(type) = //! Offset of toothed drive idler pulley
[ 0, coreXY_drive_pulley_x_alignment(type), 0 ];
function coreXY_drive_plain_idler_offset(type) = //! Offset of plain drive idler pulley
[ coreXY_plain_idler_offset(type).x, -(pulley_od(coreXY_plain_idler(type)) + pulley_od(coreXY_drive_pulley(type))) / 2, 0 ];
@@ -86,7 +91,7 @@ module coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_off
// toothed idler for offset stepper motor drive pulley
p3t_type = coreXY_toothed_idler(type);
p3t = [ -size.x / 2 + (drive_pulley_offset.x > 0 ? 0 : 2*coreXY_drive_pulley_x_alignment(type)),
p3t = [ -size.x / 2 + (drive_pulley_offset.x > 0 ? 0 : 2 * coreXY_drive_pulley_x_alignment(type)),
size.y / 2 + coreXY_drive_pulley_x_alignment(type) + drive_pulley_offset.y
];
@@ -102,11 +107,11 @@ module coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_off
size.y / 2 - pulley_od(p3p_type) / 2 - pulley_od(p3d_type) / 2 + drive_pulley_offset.y
];
// dummy pulleys for y separation
p5_type = p4_type;
p5 = [ pos.x - size.x / 2, -size.y / 2 + pos.y + separation_y / 2 ];
p6_type = p0_type;
p6 = [ pos.x - size.x / 2, -size.y / 2 + pos.y - separation_y / 2 ];
// Start and end points
start_p = [ pos.x - size.x / 2 + x_gap / 2, -size.y / 2 + pos.y - separation_y / 2, 0 ];
end_p = [ pos.x - size.x / 2 - x_gap / 2, -size.y / 2 + pos.y + separation_y / 2, 0 ];
//p6_type = p0_type;
module show_pulleys(show_pulleys) {// Allows the pulley colour to be set for debugging
if (is_list(show_pulleys))
@@ -119,16 +124,21 @@ module coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_off
show_pulleys(show_pulleys) {
translate(p0)
pulley_assembly(p0_type); // y-carriage toothed pulley
translate(p1)
pulley_assembly(p1_type); // bottom right toothed idler pulley
translate(p2)
pulley_assembly(p2_type); // bottom left anchor toothed idler pulley
translate(p3d)
hflip(hflip)
pulley_assembly(p3d_type); // top left stepper motor drive pulley
if (drive_pulley_offset.x) { // idler pulleys for offset stepper motor drive pulley
translate(p3t)
pulley_assembly(p3t_type); // toothed idler
translate(p3p)
pulley_assembly(p3p_type); // plain idler
}
@@ -157,41 +167,38 @@ module coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_off
[ p3t.x, p3t.y, pulley_od(p3t_type) / 2 ],
[ p4.x, p4.y, -pulley_od(p4_type) / 2 ]
];
path1 = [ // use eps for corner radius to get sharp corners so this part of the belt is deleted by the gap
[ p5.x, p5.y, eps ],
[ p6.x, p6.y, eps ]
];
belt = coreXY_belt(type);
path0 = drive_pulley_offset.x == 0 ? concat(path0a, path0b) : drive_pulley_offset.x > 0 ? concat(path0a, path0c) : concat(path0a, path0d);
path = separation_y == 0 ? path0 : concat(path0, path1);
path = concat([start_p], path0, [end_p]);
belt(type = belt,
points = path,
gap = [ x_gap + eps, abs(separation_y) + 2 ],
gap_pos = [ pos.x - size.x / 2, pos.y - size.y / 2 + belt_pitch_height(belt) - belt_thickness(belt) / 2 ],
open = true,
belt_colour = lower_belt ? coreXY_lower_belt_colour(type) : coreXY_upper_belt_colour(type),
tooth_colour = lower_belt ? coreXY_lower_tooth_colour(type) : coreXY_upper_tooth_colour(type));
}
module coreXY(type, size, pos, separation, x_gap, plain_idler_offset = 0, upper_drive_pulley_offset, lower_drive_pulley_offset, show_pulleys = false) { //! Wrapper module to draw both belts of a coreXY setup
module coreXY(type, size, pos, separation, x_gap, plain_idler_offset = 0, upper_drive_pulley_offset, lower_drive_pulley_offset, show_pulleys = false, left_lower = false) { //! Wrapper module to draw both belts of a coreXY setup
translate([size.x / 2 - separation.x / 2, size.y / 2, -separation.z / 2]) {
// lower belt
hflip()
hflip(!left_lower)
explode(25)
coreXY_half(type, size, [size.x - pos.x - separation.x, pos.y], separation.y, x_gap, plain_idler_offset, [-lower_drive_pulley_offset.x, lower_drive_pulley_offset.y], show_pulleys, lower_belt = true, hflip = true);
coreXY_half(type, size, [size.x - pos.x - separation.x/2 - (left_lower ? x_gap : 0), pos.y], separation.y, x_gap, plain_idler_offset, [-lower_drive_pulley_offset.x, lower_drive_pulley_offset.y], show_pulleys, lower_belt = true, hflip = true);
// upper belt
translate([separation.x, 0, separation.z])
explode(25)
coreXY_half(type, size, [pos.x, pos.y], separation.y, x_gap, plain_idler_offset, upper_drive_pulley_offset, show_pulleys, lower_belt = false, hflip=false);
hflip(left_lower)
explode(25)
coreXY_half(type, size, [pos.x + separation.x/2 + (left_lower ? x_gap : 0), pos.y], separation.y, x_gap, plain_idler_offset, upper_drive_pulley_offset, show_pulleys, lower_belt = false, hflip = false);
}
}
module coreXY_belts(type, carriagePosition, coreXYPosBL, coreXYPosTR, separation, x_gap = 20, upper_drive_pulley_offset = [0, 0], lower_drive_pulley_offset = [0, 0], show_pulleys = false) { //! Draw the coreXY belts
module coreXY_belts(type, carriagePosition, coreXYPosBL, coreXYPosTR, separation, x_gap = 20, upper_drive_pulley_offset = [0, 0], lower_drive_pulley_offset = [0, 0], show_pulleys = false, left_lower = false) { //! Draw the coreXY belts
assert(coreXYPosBL.z == coreXYPosTR.z);
coreXYSize = coreXYPosTR - coreXYPosBL;
translate(coreXYPosBL)
coreXY(type, coreXYSize, [carriagePosition.x - coreXYPosBL.x + separation.x / 2, carriagePosition.y - coreXYPosBL.y], separation = separation, x_gap = x_gap, plain_idler_offset = 0, upper_drive_pulley_offset = upper_drive_pulley_offset, lower_drive_pulley_offset = lower_drive_pulley_offset, show_pulleys = show_pulleys);
coreXY(type, coreXYSize, [carriagePosition.x - coreXYPosBL.x, carriagePosition.y - coreXYPosBL.y], separation = separation, x_gap = x_gap, plain_idler_offset = 0, upper_drive_pulley_offset = upper_drive_pulley_offset, lower_drive_pulley_offset = lower_drive_pulley_offset, show_pulleys = show_pulleys, left_lower = left_lower);
}

View File

@@ -135,4 +135,4 @@ function involute_worm_profile(m, pa = 20, clearance = undef) = //! Calculate wo
let(tooth = involute_rack_tooth_profile(m),
pitch = PI * m,
y_min = min([for(p = tooth) p.y])
) [for(p = tooth) [p.x - pitch / 2, p.y - y_min, 0]]; // Offset to be positive in y, centred in x and add 0 z ordintate
) [for(p = tooth) [p.x - pitch / 2, p.y - y_min, 0]]; // Offset to be positive in y, centred in x and add 0 z coordinate

View File

@@ -88,6 +88,7 @@ function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matr
[0, 0, 0, 1]
];
function vec2(v) = [v.x, v.y]; //! Return a 2 vector with the first two elements of `v`
function vec3(v) = [v.x, v.y, v.z]; //! Return a 3 vector with the first three elements of `v`
function vec4(v) = [v.x, v.y, v.z, 1]; //! Return a 4 vector with the first three elements of `v`
function transform(v, m) = vec3(m * [v.x, v.y, v.z, 1]); //! Apply 4x4 transform to a 3 vector by extending it and cropping it again
@@ -153,3 +154,36 @@ function circle_intersect(c1, r1, c2, r2) = //! Calculate one point where tw
d = norm(v), // Distance between centres
a = atan2(v.z, v.x) - acos((sqr(d) + sqr(r2) - sqr(r1)) / (2 * d * r2)) // Cosine rule to find angle from c2
) c2 + r2 * [cos(a), 0, sin(a)]; // Point on second circle
function map(v, func) = [ for (e = v) func(e) ]; //! make a new vector where the func function argument is applied to each element of the vector v
function mapi(v, func) = [ for (i = [0:len(v)-1]) func(i,v[i]) ]; //! 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.
function reduce(v, func, unity) = let ( r = function(i,val) i == len(v) ? val : r(i + 1, func(val, v[i])) ) r(0, 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
function sumv(v) = reduce(v, function(a, b) a + b, 0); //! sum a vector of values that can be added with "+"
function xor(a,b) = (a && !b) || (!a && b); //! Logical exclusive OR
function cuberoot(x)= sign(x)*abs(x)^(1/3);
function quadratic_real_roots(a, b, c) = //! Returns real roots of a quadratic equation, biggest first. Returns empty list if no real roots
let(2a = 2 * a,
2c = 2 * c,
det = b^2 - 2a * 2c
) det < 0 ? [] :
let(r = sqrt(det),
x1 = b < 0 ? 2c / (-b + r) : (-b - r) / 2a,
x2 = b < 0 ? (-b + r) / 2a : 2c / (-b - r)
) [x2, x1];
function cubic_real_roots(a, b, c, d) = //! Returns real roots of cubic equation
let(b = b / a,
c = c / a,
d = d / a,
inflection = -b / 3,
p = c - b^2 / 3,
q = 2 * b^3 / 27 - b * c / 3 + d,
det = q^2 / 4 + p^3 / 27,
roots = !p && !q ? 1 : nearly_zero(det) ? 2 : det < 0 ? 3 : 1,
r = sqrt(det),
x = cuberoot(-q / 2 - r) + cuberoot(-q / 2 + r)
) roots == 1 ? [x] :
roots == 2 ? [3 * q /p + inflection, -3 * q / p / 2 + inflection] :
[for(i = [0 : roots - 1]) 2 * sqrt(-p / 3) * cos(acos(3 * q * sqrt(-3 / p) / p / 2) - i * 120) + inflection];

View File

@@ -24,6 +24,7 @@
//! Because the tangents need to be calculated to find the length these can be calculated separately and re-used when drawing to save calculating them twice.
//
include <../utils/core/core.scad>
use <../utils/maths.scad>
function circle_tangent(p1, p2) = //! Compute the clockwise tangent between two circles represented as [x,y,r]
let(
@@ -36,56 +37,66 @@ function circle_tangent(p1, p2) = //! Compute the clockwise tangent between two
v = [cos(theta), sin(theta)]
)[ p1 + r1 * v, p2 + r2 * v ];
function rounded_polygon_tangents(points) = //! Compute the straight sections needed to draw and to compute the lengths
let(len = len(points))
[for(i = [0 : len - 1])
let(ends = circle_tangent(points[i], points[(i + 1) % len]))
for(end = [0, 1])
ends[end]];
function rounded_polygon_arcs(points, tangents) = //! Compute the arcs at the points, for each point [angle, rotate_angle, length]
let(
len = len(points)
) [ for (i = [0: len-1])
let(
p1 = vec2(tangents[(i - 1 + len) % len][1]),
p2 = vec2(tangents[i][0]),
p = vec2(points[i]),
v1 = p1 - p,
v2 = p2 - p,
sr = points[i][2],
r = abs(sr),
a = r < 0.001 ? 0 : let( aa = acos((v1 * v2) / sqr(r)) ) cross(v1, v2) * sign(sr) <= 0 ? aa : 360 - aa,
l = PI * a * r / 180,
v0 = [r, 0],
v = let (
vv = norm(v0 - v2) < 0.001 ? 0 : abs(v2.y) < 0.001 ? 180 :
let( aa = acos((v0 * v2) / sqr(r)) ) cross(v0, v2) * sign(sr) <= 0 ? aa : 360 - aa
) sr > 0 ? 360 - vv : vv - a
) [a, v, l]
];
function sumv(v, i = 0, sum = 0) = i == len(v) ? sum : sumv(v, i + 1, sum + v[i]);
function rounded_polygon_tangents(points) = //! Compute the straight sections between a point and the next point, for each section [start_point, end_point, length]
let(len = len(points))
[ for(i = [0 : len - 1])
let(ends = circle_tangent(points[i], points[(i + 1) % len]))
[ends[0], ends[1], norm(ends[0] - ends[1])]
];
// the cross product of 2D vectors is the area of the parallelogram between them. We use the sign of this to decide if the angle is bigger than 180.
function rounded_polygon_length(points, tangents) = //! Calculate the length given the point list and the list of tangents computed by ` rounded_polygon_tangents`
let(
len = len(points),
indices = [0 : len - 1],
straights = [for(i = indices) norm(tangents[2 * i] - tangents[2 * i + 1])],
arcs = [for(i = indices) let(p1 = tangents[2 * i + 1],
p2 = tangents[(2 * i + 2) % (2 * len)],
corner = points[(i + 1) % len],
c = [corner.x, corner.y],
v1 = p1 - c,
v2 = p2 - c,
r = abs(corner.z),
a = acos((v1 * v2) / sqr(r))) r ? PI * (cross(v1, v2) <= 0 ? a : 360 - a) * r / 180 : 0]
)
sumv(concat(straights, arcs));
arcs = rounded_polygon_arcs(points, tangents)
) sumv( map( concat(tangents, arcs), function(e) e[2] ) );
module rounded_polygon(points, _tangents = undef) { //! Draw the rounded polygon from the point list, can pass the tangent list to save it being calculated
len = len(points);
indices = [0 : len - 1];
tangents = _tangents ? _tangents : rounded_polygon_tangents(points);
difference(convexity = points) {
difference() {
union() {
for(i = indices)
for(i = indices, last = (i - 1 + len) % len)
if(points[i][2] > 0)
hull() {
translate([points[i].x, points[i].y])
translate(vec2(points[i]))
circle(points[i][2]);
polygon([tangents[(2 * i - 1 + 2 * len) % (2 * len)], tangents[2 * i], [points[i].x, points[i].y]]);
polygon([vec2(tangents[last][1]), vec2(tangents[i][0]), vec2(points[i])]);
}
polygon(tangents, convexity = points);
polygon([for(t = tangents) each(vec2(t))], convexity = points);
}
for(i = indices)
for(i = indices, last = (i - 1 + len) % len)
if(points[i][2] < 0)
hull() {
translate([points[i].x, points[i].y])
translate(vec2(points[i]))
circle(-points[i][2]);
polygon([tangents[(2 * i - 1 + 2 * len) % (2 *len)], tangents[2 * i], [points[i].x, points[i].y]]);
polygon([vec2(tangents[last][1]), vec2(tangents[i][0]), vec2(points[i])]);
}
}
}

View File

@@ -18,7 +18,7 @@
//
//
//! Utility to generate a polhedron by sweeping a 2D profile along a 3D path and utilities for generating paths.
//! Utility to generate a polyhedron by sweeping a 2D profile along a 3D path and utilities for generating paths.
//!
//! The initial orientation is the Y axis of the profile points towards the initial center of curvature, Frenet-Serret style.
//! Subsequent rotations use the minimum rotation method.

View File

@@ -50,6 +50,7 @@ function thread_profile(h, crest, angle, overlap = 0.1) = //! Create thread prof
[[-base / 2, -overlap, 0], [-crest / 2, h, 0], [crest / 2, h, 0], [base / 2, -overlap, 0]];
module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef) { //! Create male or female thread, ends can be tapered, chamfered or square
assert(is_undef(colour) || is_list(colour), "Thread colour must be in [r, g, b] form");
//
// Apply colour if defined
//
@@ -155,7 +156,7 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
translate([0, offset])
square([r, len]);
translate([0, bot_chamfer_h])
translate([0, offset + bot_chamfer_h])
square([r + h + overlap, len - top_chamfer_h - bot_chamfer_h]);
}
if(!solid)
@@ -190,7 +191,8 @@ module female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1,
}
function metric_coarse_pitch(d) //! Convert metric diameter to pitch
= d == 1.6 ? 0.35 // M1.6
= d == 1.4 ? 0.3 // M1.4
: d == 1.6 ? 0.35 // M1.6
: [0.4, // M2
0.45,// M2.5
0.5, // M3

View File

@@ -25,7 +25,9 @@ include <../utils/core/core.scad>
module ring(or, ir) //! Create a ring with specified external and internal radii
difference() {
circle4n(or);
circle4n(ir);
if(ir > 0)
circle4n(ir);
}
module tube(or, ir, h, center = true) //! Create a tube with specified external and internal radii and height `h`
@@ -69,7 +71,7 @@ module woven_tube(or, ir, h, center= true, colour = grey(30), colour2, warp = 2,
}
}
module rectangular_tube(size, center = true, thickness = 1, fillet = 0.5) { //! Create a retangular tube with filleted corners
module rectangular_tube(size, center = true, thickness = 1, fillet = 0.5) { //! Create a rectangular tube with filleted corners
extrude_if(size.z, center = center)
difference() {
rounded_square([size.x, size.y], fillet);

View File

@@ -18,19 +18,29 @@
//
//
//! Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
//! Only models 2D paths, so not crossed belt core XY!
//! Models timing belt running in a path over toothed or smooth pulleys and calculates an accurate length.
//! Only models 2D paths, belt may twist to support crossed belt core XY and other designs where the belt twists!
//!
//! By default the path is a closed loop. An open loop can be specified by specifying `open=true`, and in that case the start and end points are not connected, leaving the loop open.
//!
//! To get a 180 degree twist of the loop, you can use the `twist` argument. `Twist` can be a single number, and in that case the belt will twist after
//! the position with that number. Alternatively `twist` can be a list of boolean values with a boolean for each position; the belt will then twist after
//! the position that have a `true` value in the `twist` list. If the path is specified with pulley/idler types, then you can use `auto_twist=true`; in
//! that case the belt will automatically twist so the back of the belt always runs against idlers and the tooth side runs against pulleys. If you use
//! `open=true` then you might also use `start_twist=true` to let the belt start the part with the back side out.
//!
//! The path must be specified as a list of positions. Each position should be either a vector with `[x, y, pulley]` or `[x, y, r]`. A pulley is a type from
//! `pulleys.scad`, and correct radius and angle will automatically be calculated. Alternatively a radius can be specified directly.
//!
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
//!
//! By default the path is a closed loop but a gap length and position can be specified to make open loops.
//! To draw the gap its XY position is specified by `gap_pos`. `gap_pos.z` can be used to specify a rotation if the gap is not at the bottom of the loop.
//! Alternatively you can just specify smooth pulleys in the path, and it will then happen automatically.
//!
//! Individual teeth are not drawn, instead they are represented by a lighter colour.
//
include <../utils/core/core.scad>
use <../utils/rounded_polygon.scad>
use <../utils/maths.scad>
use <pulley.scad>
function belt_pitch(type) = type[1]; //! Pitch in mm
function belt_width(type) = type[2]; //! Width in mm
@@ -41,47 +51,102 @@ function belt_pitch_height(type) = type[5] + belt_tooth_height(type); //! Offset
function belt_pitch_to_back(type) = belt_thickness(type) - belt_pitch_height(type); //! Offset of the back from the pitch radius
//
// We model the belt path at the pitch radius of the pulleys and the pitch line of the belt to get an accurate length.
// The belt is then drawn by offseting each side from the pitch line.
//
module belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20), tooth_colour = grey(50)) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
module belt(type, points, belt_colour = grey(20), tooth_colour = grey(50), open = false, twist = undef, auto_twist = false, start_twist = false) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless open is specified
width = belt_width(type);
pitch = belt_pitch(type);
thickness = belt_thickness(type);
info = _belt_points_info(type, points, open, twist, auto_twist, start_twist);
dotwist = info[0]; // array of booleans, true if a twist happen after the position
twisted = info[1]; // array of booleans, true if the belt is twisted at the position
pointsx = info[2]; // array of [x,y,r], r is negative if left-angle (points may have pulleys as third element, but pointsx have radii)
tangents = info[3];
arcs = info[4];
length = ceil(_belt_length(info, open) / pitch) * pitch;
part = str(type[0],pitch);
vitamin(str("belt(", no_point(part), "x", width, ", ", points, arg(gap, 0), arg(gap_pos, undef), "): Belt ", part," x ", width, "mm x ", length, "mm"));
vitamin(str("belt(", no_point(part), "x", width, ", ", pointsx, "): Belt ", part," x ", width, "mm x ", length, "mm"));
len = len(points);
tangents = rounded_polygon_tangents(points);
length = ceil((rounded_polygon_length(points, tangents) - (is_list(gap) ? gap.x + gap.y : gap)) / pitch) * pitch;
module shape() rounded_polygon(points, tangents);
ph = belt_pitch_height(type);
th = belt_tooth_height(type);
module gap()
if(gap)
translate([gap_pos.x, gap_pos.y])
rotate(is_undef(gap_pos.z) ? 0 : gap_pos.z)
translate([0, ph - thickness / 2])
square(is_list(gap) ? [gap.x, gap.y + thickness + eps] : [gap, thickness + eps], center = true);
ph = belt_pitch_height(type);
module beltp() translate([ph - th, -width / 2]) square([th, width]);
module beltb() translate([ph - thickness, -width / 2]) square([thickness - th, width]);
color(belt_colour)
linear_extrude(width, center = true)
difference() {
offset(-ph + thickness ) shape();
offset(-ph + th) shape();
gap();
}
for (i = [0 : len - (open ? 2 : 1)]) {
p1 = tangents[i].x;
p2 = tangents[i].y;
v = p2-p1;
a = atan(v.y / v.x) - (v.x < 0 ? 180 : 0); //a2(p2-p1);
l = norm(v);
translate(p1) rotate([-90, 0, a - 90]) {
twist = dotwist[i] ? 180 : 0;
mirrored = twisted[i] ? 1 : 0;
color(tooth_colour) linear_extrude(l, twist = twist) mirror([mirrored, 0, 0]) beltp();
color(belt_colour) linear_extrude(l, twist = twist) mirror([mirrored, 0, 0]) beltb();
}
}
color(tooth_colour)
linear_extrude(width, center = true)
difference() {
offset(-ph + th) shape();
offset(-ph) shape();
gap();
}
for (i = [(open ? 1 : 0) : len - (open ? 2 : 1)]) {
p = pointsx[i];
arc = arcs[i];
translate([p.x, p.y]) rotate([0, 0, arc[1]]) {
mirrored = xor(twisted[i], p[2] < 0) ? 0 : 1;
color(tooth_colour) rotate_extrude(angle = arc[0]) translate([abs(p[2]), 0, 0]) mirror([mirrored, 0, 0]) beltp();
color(belt_colour) rotate_extrude(angle = arc[0]) translate([abs(p[2]), 0, 0]) mirror([mirrored, 0, 0]) beltb();
}
}
}
function belt_length(points, gap = 0) = rounded_polygon_length(points, rounded_polygon_tangents(points)) - gap; //! Compute belt length given path and optional gap
function _belt_points_info(type, points, open, twist, auto_twist, start_twist) = //! Helper function that calculates [twist, istwisted, points, tangents, arcs]
let(
len = len(points),
isleft = function(i) let(
p = vec2(points[i]),
p0 = vec2(points[(i - 1 + len) % len]),
p1 = vec2(points[(i + 1) % len])
) cross(p-p0,p1-p) > 0,
dotwist = function(i, istwisted) let( in = (i + 1) % len )
is_list(twist) ? twist[i] :
!is_undef(twist) ? i == twist :
open && is_list(points[in][2]) && auto_twist ? !pulley_teeth(points[in][2]) && !xor(isleft(in), istwisted) :
false,
twisted = [
for (
i = 0,
istwisted = start_twist,
twist = dotwist(i, istwisted),
nexttwisted = xor(twist, istwisted);
i < len;
i = i + 1,
istwisted = nexttwisted,
twist = dotwist(i, istwisted),
nexttwisted = xor(twist, istwisted)
) [twist, istwisted] ],
pointsx = mapi(points, function(i, p) !is_list(p[2]) ? p : [p.x, p.y, let( // if p[2] is not a list it is just r, otherwise it is taken to be a pulley and we calculate r
isleft = isleft(i),
r = belt_pulley_pr(type, p[2], twisted = !xor(pulley_teeth(p[2]), xor(isleft, twisted[i][1])))
) isleft ? -r : r ] ),
tangents = rounded_polygon_tangents(pointsx),
arcs = rounded_polygon_arcs(pointsx, tangents)
) [ [ for (t = twisted) t[0] ], [ for (t = twisted) t[1] ], pointsx, tangents, arcs];
function belt_pulley_pr(type, pulley, twisted=false) = //! Pitch radius. Default it expects the belt tooth to be against a toothed pulley an the backside to be against a smooth pulley (an idler). If `twisted` is true, the the belt is the other way around.
let(
thickness = belt_thickness(type),
ph = belt_pitch_height(type)
) pulley_teeth(pulley)
? pulley_pr(pulley) + (twisted ? thickness - ph : 0 )
: pulley_ir(pulley) + (twisted ? ph : thickness - ph );
function belt_length(type, points, open = false) = _belt_length(_belt_points_info(type, points, open), open); //! Compute belt length given path
function _belt_length(info, open) = let(
len = len(info[0]),
d = open ? 1 : 0,
tangents = slice(info[3], 0, len - d) ,
arcs = slice(info[4], d, len - d)
) sumv( map( concat(tangents, arcs), function(e) e[2] ));

288
vitamins/bldc_motor.scad Normal file
View File

@@ -0,0 +1,288 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/>.
//
//
//! Brushless DC electric motor
//
include <NopSCADlib/core.scad>
use <NopSCADlib/vitamins/rod.scad>
use <NopSCADlib/utils/thread.scad>
use <NopSCADlib/utils/tube.scad>
function BLDC_diameter(type) = type[1]; //! Diameter of motor
function BLDC_height(type) = type[2]; //! Height of motor including boss, if any, but excluding prop shaft
function BLDC_shaft_diameter(type) = type[3]; //! shaft diameter
function BLDC_shaft_length(type) = type[4]; //! Total shaft length
function BLDC_shaft_offset(type) = type[5]; //! shaft offset from base
function BLDC_body_colour(type) = type[6]; //! Body colour
function BLDC_base_diameter(type) = type[7]; //! Base diameter
function BLDC_base_height_1(type) = type[8]; //! Base height 1
function BLDC_base_height_2(type) = type[9]; //! Base height 2
function BLDC_base_hole_diameter(type) = type[10]; //! Base hole diameter
function BLDC_base_holes(type) = type[11]; //! Base holes
function BLDC_base_open(type) = type[12]; //! Base open
function BLDC_wire_diameter(type) = type[13]; //! Wire diameter
function BLDC_side_colour(type) = type[14]; //! Side colour
function BLDC_bell_diameter(type) = type[15]; //! Bell diameter
function BLDC_bell_height_1(type) = type[16]; //! Bell height 1
function BLDC_bell_height_2(type) = type[17]; //! Bell height 2
function BLDC_bell_hole_diameter(type) = type[18]; //! Bell hole diameter
function BLDC_bell_holes(type) = type[19]; //! Bell holes
function BLDC_bell_spokes(type) = type[20]; //! Bell spoke count
function BLDC_boss_diameter(type) = type[21]; //! Boss diameter
function BLDC_boss_height(type) = type[22]; //! Boss height
function BLDC_prop_shaft_length(type) = type[23]; //! Prop shaft length, including threaded section
function BLDC_prop_shaft_diameter(type) = type[24]; //! Diameter of unthreaded portion of prop shaft
function BLDC_prop_shaft_thread_length(type) = type[25]; //! Length of threaded section of prop shaft
function BLDC_prop_shaft_thread_diameter(type) = type[26]; //! Diameter of threaded section of prop shaft
bldc_cap_colour = grey(50);
bldc_shaft_colour = grey(90);
bldc_bearing_colour = grey(80);
module BLDC(type) { //! Draw specified BLDC motor
vitamin(str("BLDC(", type[0], "): Brushless DC motor ", type[0]));
body_colour = BLDC_body_colour(type);
side_colour = BLDC_side_colour(type);
body_diameter = BLDC_diameter(type);
wall_thickness = 1;
height = BLDC_height(type) - BLDC_boss_height(type);
module feet(base_diameter) {
holes = BLDC_base_holes(type);
hole_count = is_list(holes) ? len(holes) : 4;
for(i = [0 : 1 : hole_count - 1]) {
spacing = is_list(holes) ? holes[i] : holes;
radius = base_diameter / 2 - spacing / 2;
rotate(i * 360 / hole_count + (hole_count == 4 ? 45 : 0))
difference() {
hull() {
circle(r = radius);
translate([-spacing / 2, 0])
circle(r = radius);
}
translate([-spacing / 2, 0])
circle(d = BLDC_base_hole_diameter(type));
}
}
}
module cutout(d1, d2, r, h) {
translate_z(-eps)
linear_extrude(h + 2 * eps)
hull() {
translate([d1 / 2, 0])
circle(r = r);
translate([d2 / 2, -r])
square([eps, 2 * r]);
}
}
module cutout2(d1, r1, d2, r2, h) {
translate_z(-eps)
linear_extrude(h + 2 * eps)
hull() {
translate([d1 / 2, 0])
circle(r = r1);
translate([d2 / 2, 0])
circle(r = r2);
}
}
module base() {
base_diameter = BLDC_base_diameter(type);
h1 = BLDC_base_height_1(type);
h2 = BLDC_base_height_2(type);
color(body_colour)
if (BLDC_base_open(type)) {
linear_extrude(h1)
difference() {
union() {
feet(base_diameter);
circle(d = 3 * BLDC_shaft_diameter(type));
}
circle(d = 2 * BLDC_shaft_diameter(type));
}
translate_z(h1)
cylinder(d = 3 * BLDC_shaft_diameter(type), h = h2);
} else {
difference() {
union() {
render(convexity = 8)
linear_extrude(h1)
difference() {
circle(d = base_diameter);
circle(d = 2 * BLDC_shaft_diameter(type));
BLDC_base_screw_positions(type)
circle(d = BLDC_base_hole_diameter(type));
}
rotate_extrude()
polygon([ [base_diameter / 2, 0], [body_diameter / 2, h1], [body_diameter / 2, h1+h2], [body_diameter / 2 - wall_thickness, h1 + h2], [body_diameter / 2 - wall_thickness, h1], [base_diameter / 2, h1] ]);
}
r = body_diameter > 40 ? 2 : body_diameter * PI / (8 * 3);
if (body_diameter > 40) {
r = 2;
// cutout for wires
translate_z(h2 /2)
cutout(base_diameter, body_diameter, 6, h1);
for (a = [90, 180, 270])
rotate(a) {
cutout(base_diameter - 2 * r, body_diameter, r, h1 + h2 / 2);
for (b = [-90 / 4, 90 / 4])
rotate(b)
cutout(base_diameter - 5 * r, body_diameter, r, h1 + h2 / 2);
}
} else {
r = body_diameter * PI / (8 * 3);
for (a = [0, 90, 180, 270])
rotate(a)
cutout(base_diameter, body_diameter, r, h1);
}
}
}
color(bldc_bearing_colour)
translate_z(0.25)
tube(or = BLDC_shaft_diameter(type), ir = BLDC_shaft_diameter(type) / 2, h = h1, center = false);
if (show_threads)
BLDC_base_screw_positions(type)
female_metric_thread(BLDC_base_hole_diameter(type), metric_coarse_pitch(BLDC_base_hole_diameter(type)), h1, center = false, colour = body_colour);
wire_diameter = BLDC_wire_diameter(type);
for (i = [0 : 2])
color(wire_diameter >= 3 ? ["yellow", grey(20), "red"][i] : grey(20))
translate([body_diameter / 5, (i - 1) * wire_diameter, wire_diameter / 2 + 0.25 + (body_diameter > 40 ? h2/2 : 0)])
rotate([0, 90, 0])
cylinder(r = wire_diameter / 2, h = body_diameter / 2, center = false);
} // end module base
module bell() {
bell_diameter = BLDC_bell_diameter(type);
h1 = BLDC_bell_height_1(type);
h2 = BLDC_bell_height_2(type);
gap = BLDC_base_open(type) ? 0 : height > 20 ? 0.5 : 0.25;
side_length = height - h2 - h1 - gap - BLDC_base_height_1(type) - BLDC_base_height_2(type);
color(body_colour) {
translate_z(height - h2) {
difference() {
union() {
top_thickness = min(h2, 2);
render(convexity = 8)
translate_z(h2 - top_thickness)
linear_extrude(top_thickness)
difference() {
circle(d = bell_diameter);
if (BLDC_shaft_length(type) > height)
circle(d = BLDC_shaft_diameter(type));
BLDC_bell_screw_positions(type)
circle(d = BLDC_bell_hole_diameter(type));
}
rotate_extrude()
polygon([ [bell_diameter/2, h2], [body_diameter/2, 0], [body_diameter/2, -h1], [body_diameter/2 - wall_thickness, -h1], [body_diameter/2 - wall_thickness, 0], [bell_diameter/2, h2 - top_thickness] ]);
}
spoke_count = BLDC_bell_spokes(type);
if (spoke_count % 4 == 0) {
r = body_diameter > 40 ? body_diameter / 15 : 2.5;
for (a = [0, 90, 180, 270])
rotate(a) {
cutout(bell_diameter + 2 * r, body_diameter, r, h2);
rotate(45) {
cutout(bell_diameter, body_diameter, r, h2);
}
}
} else {
r1 = bell_diameter * PI / (spoke_count * 3);
r2 = body_diameter * PI / (spoke_count * 3);
for (i = [0 : 1 : spoke_count - 1])
rotate(i * 360 / spoke_count)
cutout2(bell_diameter, r1, body_diameter, r2, h2);
}
} // end difference
} // end translate
if (BLDC_boss_height(type))
translate_z(height)
tube(or = BLDC_boss_diameter(type)/2, ir = BLDC_shaft_diameter(type)/2, h = BLDC_boss_height(type), center = false);
} // end colour
color(BLDC_prop_shaft_thread_length(type) == 0 ? bldc_shaft_colour : body_colour)
if (BLDC_prop_shaft_diameter(type))
translate_z(height + BLDC_boss_height(type)) {
thread_diameter = BLDC_prop_shaft_thread_diameter(type);
unthreaded_length = BLDC_prop_shaft_length(type) - BLDC_prop_shaft_thread_length(type);
cylinder(d=BLDC_prop_shaft_diameter(type), h = unthreaded_length);
if (BLDC_prop_shaft_thread_length(type) > 0)
translate_z(unthreaded_length)
if (show_threads)
male_metric_thread(thread_diameter, metric_coarse_pitch(thread_diameter), BLDC_prop_shaft_thread_length(type), center = false);
else
cylinder(d = thread_diameter, h = BLDC_prop_shaft_thread_length(type));
}
color(side_colour)
translate_z(height - h2 - h1 -side_length)
tube(body_diameter/2, body_diameter/2 - wall_thickness, side_length, center = false);
if (show_threads)
translate_z(height)
BLDC_bell_screw_positions(type)
vflip()
female_metric_thread(BLDC_bell_hole_diameter(type), metric_coarse_pitch(BLDC_bell_hole_diameter(type)), h2, center = false, colour = body_colour);
} // end module bell
base();
bell();
color(bldc_shaft_colour)
translate_z(-BLDC_shaft_offset(type) - eps)
not_on_bom()
rod(d = BLDC_shaft_diameter(type), l = BLDC_shaft_length(type), center = false);
}
module BLDC_screw_positions(holes, n = 4) { //! Screw positions utility function
hole_count = is_list(holes) ? len(holes) : 4;
for($i = [0 : min(n, hole_count) - 1]) {
spacing = is_list(holes) ? holes[$i] : holes;
rotate($i * 360 / hole_count)
translate([spacing / 2, 0])
rotate(-$i * 90)
children();
}
}
module BLDC_base_screw_positions(type, n = 4) { //! Positions children at the base screw holes
if (BLDC_base_holes(type))
rotate(is_list(BLDC_base_holes(type)) && len(BLDC_base_holes(type)) == 3 ? 180 : 45)
BLDC_screw_positions(BLDC_base_holes(type), n)
children();
}
module BLDC_bell_screw_positions(type, n = 4) { //! Positions children at the bell screw holes
if (BLDC_bell_holes(type))
rotate(is_list(BLDC_bell_holes(type)) && len(BLDC_bell_holes(type)) == 3 ? 30 : 0)
BLDC_screw_positions(BLDC_bell_holes(type), n)
children();
}

37
vitamins/bldc_motors.scad Normal file
View File

@@ -0,0 +1,37 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/>.
//
//
// Brushless DC electric motors
//
// shaft shaft shaft body base holes base side bell holes boss prop shaft thread
// diameter height diam length offset colour diam h1 h2 diam position open wire colour diam h1 h1 d pos spokes d h length diam length diam
BLDC0603 = ["BLDC0603", 9.0, 8, 1, 15.5, 1, crimson, 10, 1, 1.5, 1.4, [6,6,6], true, 0.8, grey(20), 9, 1, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0];
BLDC0802 = ["BLDC0802", 11.5, 9.5, 1.5, 12, 0.5, grey(20), 9, 1, 2, 1.6, [6,6,6], true, 1.0, grey(20), 11, 2, 0.75, 0, 0, 3, 0, 0, 0, 0, 0, 0];
BLDC1105 = ["BLDC1105", 14.0, 11.75, 1.5, 11, 0, grey(90), 12.5, 1.6, 1.4, 2, 9, true, 1.0, grey(90), 12, 1, 1, 2, [5,5], 4, 0, 0, 0, 0, 0, 0];
BLDC1306 = ["BLDC1306", 17.75, 14.5, 2, 14, 0, crimson, 16, 1.5, 1, 2, 12, false, 1.0, grey(20), 12, 1, 1, 0, 0, 6, 8, 1, 11.5, 5, 6.5, 5];
BLDC1804 = ["BLDC1804", 23.0, 12, 2, 11, 0, grey(20), 19, 2.5, 1.5, 2, 12, false, 1.5, grey(20), 18, 1, 2.5, 0, 0, 6, 9, 1, 12, 5, 6, 5];
BLDC2205 = ["BLDC2205", 28.0, 17.25, 3, 16, 0, crimson, 26, 2, 3, 3, [19,16,19,16], false, 1.6, grey(20), 22.5, 1, 3.75, 0, 0, 6, 0, 0, 14, 5, 9, 5];
BLDC2212 = ["BLDC2212", 28.0, 27, 3, 26, 0, grey(20), 23, 4, 2, 3, [19,16,19,16], false, 2.0, grey(20), 18, 2, 4, 0, 0, 6, 0, 0, 14, 8, 7, 6];
BLDC3548 = ["BLDC3548", 35.0, 45, 5, 65.5, 1, gold, 32, 7, 1, 3, [25,19,25,19], false, 3.0, grey(20), 32, 2, 4,2.5, [16,16,16],6,12, 3.4, 0, 0, 0, 0];
BLDC4250 = ["BLDC4250", 42.5, 48, 5, 70, 20, crimson, 38, 4, 6, 3, 25, false, 3.5, grey(20), 28, 3, 6, 3, 17, 8, 12, 2, 0, 0, 0, 0];
bldc_motors = [BLDC0603, BLDC0802, BLDC1105, BLDC1306, BLDC1804, BLDC2205, BLDC2212, BLDC3548, BLDC4250];
use <bldc_motor.scad>

View File

@@ -28,6 +28,7 @@ use <screw.scad>
function blower_length(type) = type[2]; //! Length of enclosing rectangle
function blower_width(type) = type[3]; //! Width of enclosing rectangle
function blower_depth(type) = type[4]; //! Height
function blower_size(type) = [blower_length(type), blower_width(type), blower_depth(type)]; //! Size
function blower_bore(type) = type[5]; //! The air intake hole diameter
function blower_screw(type) = type[6]; //! The type of screws needed
function blower_hub(type) = type[7]; //! Rotor hub diameter

58
vitamins/box_section.scad Normal file
View File

@@ -0,0 +1,58 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/>.
//
//
//! Box sections.
//
include <../utils/core/core.scad>
include <../utils/tube.scad>
include <../vitamins/sheets.scad>
function box_section_material(type) = type[1]; //! Material description
function box_section_size(type) = type[2]; //! Size
function box_section_thickness(type) = type[3]; //! Wall thickness
function box_section_fillet(type) = type[4]; //! Fillet
function box_section_colour(type) = type[5]; //! Colour
function box_section_colour2(type) = type[6]; //! Colour2, for woven box section
function box_section_is_woven(type) = !is_undef(type[6]); //! Box section is woven, eg carbon fiber
module box_section(type, length, center = true) {
vitamin(str("box_section(", type[0], arg(length, 15), "): ", box_section_material(type), ", length ", length, "mm"));
size = box_section_size(type);
thickness = box_section_thickness(type);
if (box_section_is_woven(type))
translate_z(center ? 0 : length / 2) {
rotate([0, -90, 90])
for (z = [-size.y / 2, size.y / 2 - thickness])
translate_z(z)
woven_sheet(CF1, thickness, box_section_colour(type), box_section_colour2(type), length, size.x)
square([length, size.x], center=true);
rotate([0, -90, 0])
for (z = [-size.x / 2, size.x / 2 - thickness])
translate_z(z)
woven_sheet(CF1, thickness, box_section_colour(type), box_section_colour2(type), length, size.y)
square([length, size.y], center=true);
}
else
color(box_section_colour(type))
rectangular_tube([size.x, size.y, length], center, thickness, box_section_fillet(type));
}

View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2021
// 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/>.
//
//
// Box sections
//
AL12x8x1 = ["AL12x8x1", "Aluminium rectangular box section 12mm x 8mm x 1mm", [12, 8], 1, 0.5, silver, undef];
AL20x20x2 = ["AL20x20x2", "Aluminium rectangular box section 20mm x 20mm x 2mm", [20, 20], 2, 0.5, silver, undef];
CF10x10x1 = ["CF10x10x1", "Carbon fiber rectangular box section 10mm x 10mm x 1mm", [10, 10], 1, 0.5, grey(35), grey(20)];
box_sections = [AL12x8x1, AL20x20x2, CF10x10x1];
use <box_section.scad>

View File

@@ -20,7 +20,7 @@
//
//! A strip of polypropylene used with ribbon cable to make a cable flexible in one direction only.
//!
//! Modelled with a Bezier spline, which is not quite the same as a minimum energy curve but very close, epecially
//! Modelled with a Bezier spline, which is not quite the same as a minimum energy curve but very close, especially
//! near the extreme positions, where the model needs to be accurate.
//!
//! When the sides are constrained then a circular model is more accurate.

View File

@@ -25,7 +25,7 @@ use <pcb.scad>
function camera_pcb(type) = type[2]; //! The PCB part of the camera
function camera_lens_offset(type) = type[3]; //! Offset of the lens center from the PCB centre
function camera_lens(type) = type[4]; //! Stack of lens parts, can be round, rectanular or rounded rectangular, with optional tapered aperture
function camera_lens(type) = type[4]; //! Stack of lens parts, can be round, rectangular or rounded rectangular, with optional tapered aperture
function camera_connector_pos(type) = type[5]; //! The flex connector block for the camera itself's position
function camera_connector_size(type)= type[6]; //! The flex connector block for the camera itself's size

View File

@@ -18,7 +18,7 @@
//
//
//! LCD dispays.
//! LCD displays.
//
include <../utils/core/core.scad>

View File

@@ -53,7 +53,7 @@ LCDS7282BPCB = ["", "", 85, 36, 1.65, 0, 2.56, 0, "green", false, [[-2.5, -2.5],
[]];
LCDS7282B = ["LCDS7282B", "LCD display S-7282B", 73.6, 28.7, 9.6, LCDS7282BPCB,
[-2.5, 0, 0], // pcb offst
[-2.5, 0, 0], // pcb offset
[[-64.5 / 2, -14.5 / 2], [64.5 / 2, 14.5 / 2, 0.6]], // aperture
[], // touch screen
0, // thread length

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