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

Compare commits

...

52 Commits

Author SHA1 Message Date
Chris Palmer
c99ed98a64 Can now have right angle pin headers on PCBs.
Fixed bugs right angle pin headers with rows not equal to two.
Added more tests for pin headers.
2020-09-11 00:20:28 +01:00
Chris Palmer
7f65e5d539 Added M2 dome head screws. 2020-09-10 18:38:24 +01:00
Chris Palmer
ffb7f87cc5 Fixed typo in insert name. 2020-09-10 18:27:56 +01:00
Chris Palmer
d0513c7299 Bodge to jhead to allow the ziptie and sleaving to be removed by setting naked to undef. 2020-09-06 12:33:44 +01:00
Chris Palmer
d1429a3b7d Verboard can now have components on the underside, same as PCBs. 2020-09-06 12:32:42 +01:00
Chris Palmer
70513993bd Can now put wire links on PCBs 2020-09-06 12:31:41 +01:00
Chris Palmer
9eb35accfd Updated fan_guard picture. 2020-09-06 11:59:32 +01:00
Chris Palmer
7276f18566 Spacing 2020-09-06 11:56:55 +01:00
Chris Palmer
d944198dc4 25mm fans are actually 25.4, i.e. 1". 2020-09-06 11:55:58 +01:00
Chris Palmer
04f2499a9e Moved no_point(str) from belt.scad to global.scad 2020-09-06 11:51:33 +01:00
Chris Palmer
1eb8b378e9 Added magnets 2020-08-23 16:46:29 +01:00
Chris Palmer
362dbdb4fc Opengrab hole position children now passed diameter. 2020-08-22 14:32:23 +01:00
Chris Palmer
57d223d84b Added insert_nose_length() 2020-08-22 14:31:06 +01:00
Chris Palmer
699385342f quadrant can now have different height and width if passed a vector. 2020-08-22 14:27:01 +01:00
Chris Palmer
547a418cea Hanging hole now works when the hole has only four sides. 2020-08-22 13:52:25 +01:00
Chris Palmer
b6d25048bc Fixed belt gap positioning and added ability to rotae it. 2020-08-22 11:16:56 +01:00
Chris Palmer
4cdab218d9 Fix belt positioning bug.
Belt gap position is now relative to the pitch line.
Added belt_pitch_to_back().
2020-08-22 09:45:13 +01:00
Chris Palmer
b6147e5684 Code formatting 2020-08-13 17:02:14 +01:00
Chris Palmer
966ba536ed Fixed J-Head nozzle offset.
Reduced J-Head inset.
Removed J-Head MK4.
2020-08-13 12:44:17 +01:00
Chris Palmer
2419d50641 Added more PTFE tube sizes and amde them whiter. 2020-08-13 12:30:39 +01:00
Chris Palmer
02211c2034 Added tubing_or() and center option. 2020-08-13 11:56:53 +01:00
Chris Palmer
77d73b075d Added opengrab_side_hole_positions() 2020-08-13 11:55:31 +01:00
Chris Palmer
cb54a3131b Added USB-C connector, micro hdmi and RPI4. 2020-08-01 19:38:22 +01:00
Chris Palmer
3cf275579c Fixed ball bearing chamfers. 2020-07-31 01:33:33 +01:00
Chris Palmer
fb41f218fe Added involute_gear_od() function. 2020-07-28 21:24:01 +01:00
Chris Palmer
e6a26bc7b1 Changed some teardrop holes to teardrop plus. 2020-07-20 20:39:01 +01:00
Chris Palmer
cb4fa40643 Reimplemented teardrop_plus() again. 2020-07-20 16:55:55 +01:00
Chris Palmer
6a26903514 Added blog links for horiholes. 2020-07-18 23:53:15 +01:00
Chris Palmer
d08d949887 Corrected teardrop_plus() shape to be an accurate compensation for slicer
staircasing and added a plus option to tearslot(), etc.

Added horiholes.scad to depict staircase holes.
2020-07-18 19:28:26 +01:00
Chris Palmer
574a73e527 More spelling 2020-07-14 23:39:36 +01:00
Chris Palmer
87a35126de Spelling. 2020-07-14 09:48:30 +01:00
Chris Palmer
1ca485b66b Added involute_worm_profile() and involute_rack_tooth_profile() functions. 2020-07-14 09:47:45 +01:00
Chris Palmer
bc919529d3 Tweaks to thread.
Better thread crest detection.
No longer shrtens thread by eps (to avoid z fight) if all one colour.
Comment about left hand threads.
2020-07-14 09:42:32 +01:00
Chris Palmer
9f4ed2b915 Fixed capitalisation of Swiss_clips.scad. 2020-07-12 00:27:26 +01:00
Chris Palmer
7ce055373a Add rack to mesh with involute spur gears. 2020-07-07 22:36:34 +01:00
Chris Palmer
71ac571346 Added a utility for making involute spur gears 2020-07-06 23:22:11 +01:00
Chris Palmer
e4d93366fa Added degrees, radians and rot2_z() to maths.scad. 2020-07-06 12:43:24 +01:00
Chris Palmer
f047ac27f7 Added SMR95 ball bearing 2020-07-04 17:30:26 +01:00
Chris Palmer
a9e479d971 Documented camera lens module. 2020-07-04 14:57:01 +01:00
Chris Palmer
47b01af1ea Added RPI camera V2
Add cameras to lib.scad
2020-07-04 14:54:19 +01:00
Chris Palmer
fe19eba237 Tweaked flat_flex connectors. 2020-07-04 14:14:25 +01:00
Chris Palmer
235f7b86e3 Camera connector position and size separated.
Camera_lens() module added.
2020-07-04 09:55:38 +01:00
Chris Palmer
92d7e18b16 Added pcb_size() function. 2020-07-04 09:53:09 +01:00
Chris Palmer
6a7226120f Fixed RPI camera component positions. 2020-06-30 18:57:14 +01:00
Chris Palmer
8aa00cd041 Added MGN12H rail and included MGN12 in the test. 2020-06-30 09:28:32 +01:00
Chris Palmer
f6b512da1f Added a couple of Raspberry Pi cameras. 2020-06-29 23:03:54 +01:00
Chris Palmer
c7ea0939b9 Made flat_flex parametric and changed default orientation. 2020-06-29 23:01:34 +01:00
Chris Palmer
265b5ab555 Fixed layout to work with an empty list. 2020-06-27 20:00:47 +01:00
Chris Palmer
186dbbfd08 Added SMT resistors and 0603 LED. 2020-06-27 19:59:49 +01:00
Chris Palmer
60659a43f8 Added light_strip_clip_wall(). 2020-06-24 16:42:17 +01:00
Chris Palmer
f412cb1736 Tweaked lightstrip dimensions. 2020-06-21 20:35:13 +01:00
Chris Palmer
2b878556fc Bug fix to platters.scad for last change. 2020-06-21 16:00:26 +01:00
86 changed files with 1392 additions and 311 deletions

View File

@@ -29,6 +29,7 @@ include <vitamins/batteries.scad>
include <vitamins/blowers.scad>
include <vitamins/bulldogs.scad>
include <vitamins/buttons.scad>
include <vitamins/cameras.scad>
include <vitamins/components.scad>
include <vitamins/displays.scad>
include <vitamins/extrusions.scad>
@@ -42,6 +43,7 @@ include <vitamins/ldrs.scad>
include <vitamins/leadnuts.scad>
include <vitamins/led_meter.scad>
include <vitamins/light_strips.scad>
include <vitamins/magnets.scad>
include <vitamins/mains_sockets.scad>
include <vitamins/modules.scad>
include <vitamins/panel_meters.scad>
@@ -83,6 +85,7 @@ use <utils/rounded_cylinder.scad>
use <utils/dogbones.scad>
use <utils/tube.scad>
use <utils/quadrant.scad>
use <utils/gears.scad>
use <utils/hanging_hole.scad>
use <utils/fillet.scad>
use <utils/rounded_polygon.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 KiB

After

Width:  |  Height:  |  Size: 817 KiB

View File

@@ -29,6 +29,7 @@ use <tests/blowers.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/circlips.scad>
use <tests/components.scad>
use <tests/d_connectors.scad>
@@ -49,6 +50,7 @@ use <tests/LEDs.scad>
use <tests/light_strips.scad>
use <tests/linear_bearings.scad>
use <tests/LED_meters.scad>
use <tests/magnets.scad>
use <tests/microswitches.scad>
use <tests/modules.scad>
use <tests/nuts.scad>
@@ -72,7 +74,7 @@ use <tests/spades.scad>
use <tests/springs.scad>
use <tests/SSRs.scad>
use <tests/stepper_motors.scad>
use <tests/swiss_clips.scad>
use <tests/Swiss_clips.scad>
use <tests/toggles.scad>
use <tests/transformers.scad>
use <tests/tubings.scad>
@@ -270,8 +272,9 @@ translate([x1, leadnuts_y])
leds_y = 0;
carriers_y = leds_y + 40;
spades_y = carriers_y + 40;
buttons_y = spades_y + 40;
magnets_y = carriers_y + 40;
spades_y = magnets_y + 20;
buttons_y = spades_y + 20;
jacks_y = buttons_y + 40;
microswitches_y = jacks_y + 40;
rockers_y = microswitches_y + 40;
@@ -287,6 +290,9 @@ translate([x2 + 35, leds_y])
translate([x2 + 8, carriers_y])
carriers();
translate([x2, magnets_y])
magnets();
translate([x2 + 20, carriers_y])
led_meters();
@@ -334,6 +340,9 @@ translate([x3 + 70, veroboard_y + 30])
translate([x3 + 140, veroboard_y + 20])
pcb_mounts();
translate([x3 + 170, veroboard_y + 16])
cameras();
translate([x3, d_connectors_y])
d_connectors();
@@ -381,7 +390,7 @@ sk_brackets_y = extrusion_brackets_y + 80;
kp_pillow_blocks_y = sk_brackets_y + 50;
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
translate([x4 + 150, belts_y + 58]) {
translate([x4 + 200, belts_y + 58]) {
belt_test();
translate([0, 60])

View File

@@ -74,7 +74,7 @@ module door_hinge(door_thickness) { //! Generates STL fo
square([1, thickness + door_thickness]);
}
translate([dia / 2, thickness + door_thickness / 2])
teardrop(r = screw_clearance_radius(pin_screw), h = 0);
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
}
linear_extrude(thickness)
difference() {
@@ -127,7 +127,7 @@ module door_hinge_stat_stl() { //! Generates the STL for the stationary part
square([dia, 1], center = true);
}
translate([0, dia / 2 + stat_clearance])
teardrop(r = screw_clearance_radius(pin_screw), h = 0);
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
}
}
}

324
readme.md
View File

@@ -22,26 +22,26 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#KP_pillow_blocks">KP_pillow_blocks</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Global">Global</a> </td></tr>
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Layout">Layout</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Maths">Maths</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
</table>
---
@@ -85,6 +85,7 @@ Axial components for PCBs.
| 1 | ```ax_res(res1_4, 47000)``` | Resistor 47000 Ohms 5% 0.25W |
| 1 | ```ax_res(res1_2, 8200)``` | Resistor 8200 Ohms 5% 0.5W |
| 1 | ```ax_res(res1_2, 8250, tol = 1)``` | Resistor 8250 Ohms 1% 0.5W |
| 1 | ```wire_link(0.8, 10.16)``` | Wire link 0.8mm x 0.4" |
<a href="#top">Top</a>
@@ -133,7 +134,8 @@ Also single bearing balls are modelled as just a silver sphere and a BOM entry.
| 1 | ```ball_bearing(BB6201)``` | Ball bearing 6201-2RS 12mm x 32mm x 10mm |
| 1 | ```ball_bearing(BB624)``` | Ball bearing 624-2RS 4mm x 13mm x 5mm |
| 1 | ```ball_bearing(BB6808)``` | Ball bearing 6808-2RS 40mm x 52mm x 7mm |
| 5 | ``` bearing_ball(3)``` | Steel ball 3mm |
| 1 | ```ball_bearing(BBSMR95)``` | Ball bearing SMR95ZZ 5mm x 9mm x 2.5mm |
| 6 | ``` bearing_ball(3)``` | Steel ball 3mm |
<a href="#top">Top</a>
@@ -208,6 +210,7 @@ Only models 2D paths, so not core XY!
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
By default the path is a closed loop but a gap length and position can be specified to make open loops.
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.
Individual teeth are not drawn, instead they are represented by a lighter colour.
@@ -222,6 +225,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
| Function | Description |
|:--- |:--- |
| ```belt_pitch(type)``` | Pitch in mm |
| ```belt_pitch_height(type)``` | Offset of the pitch radius from the tips of the teeth |
| ```belt_thickness(type)``` | Total thickness including teeth |
| ```belt_tooth_height(type)``` | Tooth height |
| ```belt_width(type)``` | Width in mm |
@@ -230,12 +234,12 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
| Function | Description |
|:--- |:--- |
| ```belt_length(points, gap = 0)``` | Compute belt length given path and optional gap |
| ```belt_pitch_height(type)``` | Offset of the pitch radius from the tips of the teeth |
| ```belt_pitch_to_back(type)``` | Offset of the back from the pitch radius |
### Modules
| Module | Description |
|:--- |:--- |
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
| ```belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
![belts](tests/png/belts.png)
@@ -243,7 +247,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```belt(GT2x6, [ ... ])``` | Belt GT2 x 6mm x 128mm |
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0.81])``` | Belt GT2 x 6mm x 694mm |
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 696mm |
| 1 | ```belt(T2p5x6, [ ... ])``` | Belt T2.5 x 6mm x 130mm |
| 1 | ```belt(T5x10, [ ... ])``` | Belt T5 x 10mm x 130mm |
| 1 | ```belt(T5x6, [ ... ])``` | Belt T5 x 6mm x 130mm |
@@ -430,6 +434,45 @@ When the sides are constrained then a circular model is more accurate.
| 3 | ```cable_strip(20, 25, 100, 30)``` | Polypropylene strip 189mm x 24mm x 0.8mm |
<a href="#top">Top</a>
---
<a name="Cameras"></a>
## Cameras
PCB cameras.
[vitamins/cameras.scad](vitamins/cameras.scad) Object definitions.
[vitamins/camera.scad](vitamins/camera.scad) Implementation.
[tests/cameras.scad](tests/cameras.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```camera_connector_pos(type)``` | The flex connector block for the camera itself's position |
| ```camera_connector_size(type)``` | The flex connector block for the camera itself's size |
| ```camera_lens(type)``` | Stack of lens parts, can be round, rectanular or rounded rectangular, with optional tapered aperture |
| ```camera_lens_offset(type)``` | Offset of the lens center from the PCB centre |
| ```camera_pcb(type)``` | The PCB part of the camera |
### Modules
| Module | Description |
|:--- |:--- |
| ```camera(type)``` | Draw specified PCB camera |
| ```camera_lens(type, offset = 0)``` | Draw the lens stack, with optional offset for making a clearance hole |
![cameras](tests/png/cameras.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```camera(rpi_camera_v1)``` | Raspberry Pi camera V1 |
| 1 | ```camera(rpi_camera_v2)``` | Raspberry Pi camera V2 |
| 1 | ```camera(rpi_camera)``` | Raspberry Pi focusable camera |
<a href="#top">Top</a>
---
@@ -860,7 +903,7 @@ Can draw three styles: solid, open frame and open frame with screw bosses.
| ---:|:--- |:---|
| 1 | ```fan(fan120x25)``` | Fan 120mm x 25mm |
| 1 | ```fan(fan17x8)``` | Fan 17mm x 8mm |
| 1 | ```fan(fan25x10)``` | Fan 25mm x 10mm |
| 1 | ```fan(fan25.4x10)``` | Fan 25.4mm x 10mm |
| 1 | ```fan(fan30x10)``` | Fan 30mm x 10mm |
| 1 | ```fan(fan40x11)``` | Fan 40mm x 11mm |
| 1 | ```fan(fan50x15)``` | Fan 50mm x 15mm |
@@ -1210,6 +1253,7 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
| Function | Description |
|:--- |:--- |
| ```insert_boss_radius(type, wall)``` | Compute the outer radius of an insert boss |
| ```insert_nose_length(type, d)``` | The length before the second ring. |
### Modules
| Module | Description |
@@ -1224,7 +1268,7 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```insert(F1BM)``` | Heatfit insert M2 |
| 1 | ```insert(F1BM2)``` | Heatfit insert M2 |
| 1 | ```insert(F1BM2p5)``` | Heatfit insert M2.5 |
| 1 | ```insert(F1BM3)``` | Heatfit insert M3 |
| 1 | ```insert(F1BM4)``` | Heatfit insert M4 |
@@ -1554,9 +1598,10 @@ The `light_strip_clip()` module makes a clip to go around the light that can be
| Function | Description |
|:--- |:--- |
| ```light_strip_clip_depth(light)``` | Depth of the clip |
| ```light_strip_clip_length(light)``` | Outside length |
| ```light_strip_clip_length(light)``` | Outside length of clip |
| ```light_strip_clip_slot(light)``` | Clip slot size |
| ```light_strip_clip_width(light)``` | Outside width |
| ```light_strip_clip_wall()``` | Clip wall thickness |
| ```light_strip_clip_width(light)``` | Outside width of clip |
| ```light_strip_cut_length(type, segs)``` | Calculate cut length given segments |
| ```light_strip_segments(type, max_length)``` | Calculate the maximum number of segments that fit in max_length |
@@ -1632,6 +1677,36 @@ LMnUU linear bearings.
| 1 | ```linear_bearing(LM8UU)``` | Linear bearing LM8UU |
<a href="#top">Top</a>
---
<a name="Magnets"></a>
## Magnets
Cylindrical and ring magnets.
[vitamins/magnets.scad](vitamins/magnets.scad) Object definitions.
[vitamins/magnet.scad](vitamins/magnet.scad) Implementation.
[tests/magnets.scad](tests/magnets.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```magnet_h(type)``` | Height |
| ```magnet_id(type)``` | Inside diameter if a ring |
| ```magnet_od(type)``` | Outer diameter |
| ```magnet_r(type)``` | Corner radius |
### Modules
| Module | Description |
|:--- |:--- |
| ```magnet(type)``` | Draw specified magnet |
![magnets](tests/png/magnets.png)
<a href="#top">Top</a>
---
@@ -1943,6 +2018,7 @@ A permanent magnet that can be magnatized and de-magnatized electronically.
|:--- |:--- |
| ```opengrab()``` | Draw OpenGrab module |
| ```opengrab_hole_positions()``` | Position children at the screw positions |
| ```opengrab_side_hole_positions()``` | Position children at the two 4mm hole |
| ```opengrab_target()``` | Draw OpenGrab target |
![opengrab](tests/png/opengrab.png)
@@ -1950,8 +2026,8 @@ A permanent magnet that can be magnatized and de-magnatized electronically.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```opengrab_target()``` | OpenGrab silicon steel target plate |
| 1 | ```opengrab()``` | OpenGrab V3 electro permanent magnet |
| 1 | ```opengrab_target()``` | OpenGrab silicon steel target plate |
<a href="#top">Top</a>
@@ -2033,6 +2109,10 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Properties
| Function | Description |
|:--- |:--- |
| ```ff_back(type)``` | Flat flex back section size |
| ```ff_latch(type)``` | Flat flex latch size |
| ```ff_mid(type)``` | Flat flex middle section size |
| ```ff_slot(type)``` | Flat flex slot size |
| ```hdmi_depth(type)``` | Front to back depth |
| ```hdmi_height(type)``` | Outside height above the PCB |
| ```hdmi_height1(type)``` | Inside height at the sides |
@@ -2062,6 +2142,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
| ```pcb_size(type)``` | Length, width and thickness in a vector |
### Modules
| Module | Description |
@@ -2070,7 +2151,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```block(size, colour, makes_cutout, cutouts)``` | Draw a coloured cube to represent a random PCB component |
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and colour |
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flat_flex(type, cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flex(cutout = false)``` | Draw flexistrip connector |
| ```hdmi(type, cutout = false)``` | Draw HDMI socket |
| ```jack(cutout = false)``` | Draw 3.5mm jack |
@@ -2094,6 +2175,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```usb_Ax1(cutout = false)``` | Draw USB type A single socket |
| ```usb_Ax2(cutout = false)``` | Draw USB type A dual socket |
| ```usb_B(cutout = false)``` | Draw USB B connector |
| ```usb_C(cutout = false)``` | Draw USB C connector |
| ```usb_uA(cutout = false)``` | Draw USB micro A connector |
![pcb](tests/png/pcb.png)
@@ -2125,7 +2207,11 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```ax_res(res1_4, 10000)``` | Resistor 10000 Ohms 5% 0.25W |
| 1 | ```ax_res(res1_2, 100000)``` | Resistor 100000 Ohms 5% 0.5W |
| 1 | ```ax_res(res1_8, 1e+6, tol = 1)``` | Resistor 1e+6 Ohms 1% 0.125W |
| 1 | ```smd_led(LED0603, orange)``` | SMD LED 0603 orange |
| 1 | ```smd_led(LED0805, red)``` | SMD LED 0805 red |
| 1 | ```smd_resistor(RES0603, 1K)``` | SMD resistor 0603 1K 0.1W |
| 1 | ```smd_resistor(RES0805, 1K)``` | SMD resistor 0805 1K 0.125W |
| 1 | ```smd_resistor(RES1206, 1K)``` | SMD resistor 1206 1K 0.25W |
| 1 | ```square_button(button_6mm)``` | Square button 6mm |
| 1 | ```pcb(TMC2130)``` | TMC2130 |
| 1 | ```green_terminal(gt_5p08, 2)``` | Terminal block 2 way 0.2" |
@@ -2138,6 +2224,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 2 | ```green_terminal(gt_3p5, 4)``` | Terminal block 4 way 3.5mm |
| 1 | ```terminal_35(4)``` | Terminal block 4 way 3.5mm |
| 1 | ```pcb(TestPCB)``` | Test PCB |
| 1 | ```wire_link(0.8, 5.08, h = 10.16)``` | Wire link 0.8mm x 0.2" |
| 1 | ```wire_link(0.8, 10.16)``` | Wire link 0.8mm x 0.4" |
<a href="#top">Top</a>
@@ -2157,6 +2245,10 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Properties
| Function | Description |
|:--- |:--- |
| ```ff_back(type)``` | Flat flex back section size |
| ```ff_latch(type)``` | Flat flex latch size |
| ```ff_mid(type)``` | Flat flex middle section size |
| ```ff_slot(type)``` | Flat flex slot size |
| ```hdmi_depth(type)``` | Front to back depth |
| ```hdmi_height(type)``` | Outside height above the PCB |
| ```hdmi_height1(type)``` | Inside height at the sides |
@@ -2186,6 +2278,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
| ```pcb_size(type)``` | Length, width and thickness in a vector |
### Modules
| Module | Description |
@@ -2194,7 +2287,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```block(size, colour, makes_cutout, cutouts)``` | Draw a coloured cube to represent a random PCB component |
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and colour |
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flat_flex(type, cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
| ```flex(cutout = false)``` | Draw flexistrip connector |
| ```hdmi(type, cutout = false)``` | Draw HDMI socket |
| ```jack(cutout = false)``` | Draw 3.5mm jack |
@@ -2218,6 +2311,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```usb_Ax1(cutout = false)``` | Draw USB type A single socket |
| ```usb_Ax2(cutout = false)``` | Draw USB type A dual socket |
| ```usb_B(cutout = false)``` | Draw USB B connector |
| ```usb_C(cutout = false)``` | Draw USB C connector |
| ```usb_uA(cutout = false)``` | Draw USB micro A connector |
![pcbs](tests/png/pcbs.png)
@@ -2237,11 +2331,11 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```pcb(Keyes5p1)``` | Keyes5.1 Arduino Uno expansion board |
| 1 | ```pcb(MT3608)``` | MT3608 boost converter module |
| 1 | ```pcb(Melzi)``` | Melzi electronics |
| 4 | | Micro SD card |
| 5 | | Micro SD card |
| 1 | ```molex_254(2)``` | Molex KK header 2 way |
| 1 | ```molex_254(3)``` | Molex KK header 3 way |
| 16 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 30 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 34 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 16 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 12 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 1 | ```pcb(PI_IO)``` | PI_IO V2 |
@@ -2254,27 +2348,27 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```pin_socket(2p54header, 13, 2, right_angle = true)``` | Pin socket 13 x 2 right_angle |
| 1 | ```pcb(RAMPSEndstop)``` | RAMPS Endstop Switch |
| 1 | ```pcb(RPI3)``` | Raspberry Pi 3 |
| 1 | ```pcb(RPI4)``` | Raspberry Pi 4 |
| 1 | ```pcb(RPI0)``` | Raspberry Pi Zero |
| 12 | ```screw(M2_cap_screw, 16)``` | Screw M2 cap x 16mm |
| 4 | ```screw(M2_cap_screw, 20)``` | Screw M2 cap x 20mm |
| 2 | ```screw(M2p5_cap_screw, 16)``` | Screw M2.5 cap x 16mm |
| 4 | ```screw(M2p5_cap_screw, 20)``` | Screw M2.5 cap x 20mm |
| 4 | ```screw(M2p5_cap_screw, 25)``` | Screw M2.5 cap x 25mm |
| 4 | ```screw(M2p5_cap_screw, 30)``` | Screw M2.5 cap x 30mm |
| 8 | ```screw(M2p5_cap_screw, 30)``` | Screw M2.5 cap x 30mm |
| 4 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
| 12 | ```screw(M2p5_pan_screw, 25)``` | Screw M2.5 pan x 25mm |
| 4 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 8 | ```screw(M3_cap_screw, 30)``` | Screw M3 cap x 30mm |
| 4 | ```screw(M3_cap_screw, 35)``` | Screw M3 cap x 35mm |
| 4 | ```screw(M4_cap_screw, 30)``` | Screw M4 cap x 30mm |
| 8 | ```screw(M4_cap_screw, 35)``` | Screw M4 cap x 35mm |
| 12 | ```screw(M4_cap_screw, 35)``` | Screw M4 cap x 35mm |
| 1 | ```pcb(TP4056)``` | TP4056 Li-lon Battery charger module |
| 3 | ```terminal_35(2)``` | Terminal block 2 way 3.5mm |
| 2 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
| 1 | | USB A to Mini B lead |
| 1 | ```pcb(WD2002SJ)``` | WD2002SJ Buck Boost DC-DC converter |
| 16 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 30 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 34 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 16 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 12 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
| 1 | ```pcb(ZC_A0591)``` | ZC-A0591 ULN2003 driver PCB |
@@ -2293,14 +2387,15 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 4 | pcb_spacer25140_2.stl |
| 4 | pcb_spacer25150_2.stl |
| 4 | pcb_spacer25180.stl |
| 4 | pcb_spacer25190.stl |
| 2 | pcb_spacer2570.stl |
| 4 | pcb_spacer30160.stl |
| 4 | pcb_spacer30170.stl |
| 4 | pcb_spacer30220.stl |
| 4 | pcb_spacer30230.stl |
| 4 | pcb_spacer3050.stl |
| 4 | pcb_spacer40190.stl |
| 4 | pcb_spacer40200.stl |
| 4 | pcb_spacer40210.stl |
| 4 | pcb_spacer40220.stl |
<a href="#top">Top</a>
@@ -2381,7 +2476,7 @@ Pin headers and sockets, etc.
|:--- |:--- |
| ```box_header(type, cols = 1, rows = 1, smt = false, cutout = false)``` | Draw box header |
| ```idc_transition(type, cols = 5, skip = [], cutout = false)``` | Draw IDC transition header |
| ```jst_xh_header(type, pin_count, right_angle=false, colour, pin_colour)``` | Draw JST XH connector |
| ```jst_xh_header(type, pin_count, right_angle=false, colour = false, pin_colour = false)``` | Draw JST XH connector |
| ```pin(type, length = undef)``` | Draw a header pin |
| ```pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cutout = false, colour)``` | Draw pin header |
| ```pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt = false, cutout = false, colour)``` | Draw pin socket |
@@ -2392,11 +2487,18 @@ Pin headers and sockets, etc.
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```box_header(2p54header, 10, 2)``` | Box header 10 x 2 |
| 1 | ```box_header(2p54header, 8, 1)``` | Box header 8 x 1 |
| 1 | ```idc_transition(2p54header, 10)``` | IDC transition header 10 x 2 |
| 1 | ```pin_header(2p54header, 10, 2)``` | Pin header 10 x 2 |
| 1 | ```pin_header(2p54header, 10, 2, right_angle = true)``` | Pin header 10 x 2 right_angle |
| 1 | ```pin_header(2p54header, 3, 1, right_angle = true)``` | Pin header 3 x 1 right_angle |
| 1 | ```pin_header(2p54header, 3, 2, right_angle = true)``` | Pin header 3 x 2 right_angle |
| 1 | ```pin_header(2p54header, 3, 3, right_angle = true)``` | Pin header 3 x 3 right_angle |
| 1 | ```pin_header(2p54header, 8, 1)``` | Pin header 8 x 1 |
| 1 | ```pin_socket(2p54header, 10, 2)``` | Pin socket 10 x 2 |
| 1 | ```pin_socket(2p54header, 10, 2, right_angle = true)``` | Pin socket 10 x 2 right_angle |
| 1 | ```pin_socket(2p54header, 3, 1, right_angle = true)``` | Pin socket 3 x 1 right_angle |
| 1 | ```pin_socket(2p54header, 3, 2, right_angle = true)``` | Pin socket 3 x 2 right_angle |
| 1 | ```pin_socket(2p54header, 3, 3, right_angle = true)``` | Pin socket 3 x 3 right_angle |
| 1 | ```pin_socket(2p54header, 8, 1)``` | Pin socket 8 x 1 |
<a href="#top">Top</a>
@@ -2603,24 +2705,27 @@ Linear rails with carriages.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```rail(MGN15, 260)``` | Linear rail MGN15 x 260mm |
| 1 | ```rail(MGN12, 200)``` | Linear rail MGN12 x 200mm |
| 1 | ```rail(MGN12H, 200)``` | Linear rail MGN12H x 200mm |
| 1 | ```rail(MGN15, 200)``` | Linear rail MGN15 x 200mm |
| 1 | ```rail(MGN5, 200)``` | Linear rail MGN5 x 200mm |
| 1 | ```rail(MGN7, 200)``` | Linear rail MGN7 x 200mm |
| 1 | ```rail(MGN9, 200)``` | Linear rail MGN9 x 200mm |
| 1 | ```rail(SSR15, 200)``` | Linear rail SSR15 x 200mm |
| 26 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 17 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 31 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 4 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 11 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
| 15 | ```screw(M2_cs_cap_screw, 10)``` | Screw M2 cs cap x 10mm |
| 8 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
| 5 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 12 | ```screw(M3_cap_screw, 12)``` | Screw M3 cap x 12mm |
| 3 | ```screw(M3_cap_screw, 16)``` | Screw M3 cap x 16mm |
| 2 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
| 2 | ```screw(M3_cs_cap_screw, 16)``` | Screw M3 cs cap x 16mm |
| 6 | ```screw(M3_cs_cap_screw, 16)``` | Screw M3 cs cap x 16mm |
| 2 | ```screw(M4_cap_screw, 16)``` | Screw M4 cap x 16mm |
| 2 | ```screw(M4_cs_cap_screw, 20)``` | Screw M4 cs cap x 20mm |
| 26 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 17 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 31 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 4 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
@@ -2824,6 +2929,7 @@ Machine screws and wood screws with various head styles.
| 1 | ```screw(No632_pan_screw, 30)``` | Screw 6-32 pan x 30mm |
| 1 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
| 1 | ```screw(M2_cs_cap_screw, 10)``` | Screw M2 cs cap x 10mm |
| 1 | ```screw(M2_dome_screw, 10)``` | Screw M2 dome x 10mm |
| 1 | ```screw(M2p5_cap_screw, 10)``` | Screw M2.5 cap x 10mm |
| 1 | ```screw(M2p5_pan_screw, 10)``` | Screw M2.5 pan x 10mm |
| 1 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
@@ -3080,11 +3186,14 @@ Surface mount components for PCBs.
|:--- |:--- |
| ```smd_led_lens(type)``` | Lens length width and height |
| ```smd_led_size(type)``` | Body length, width and height |
| ```smd_res_end_cap(type)``` | End cap width |
| ```smd_res_power(type)``` | Power rating in Watts |
| ```smd_res_size(type)``` | Body length, width and height |
### Functions
| Function | Description |
|:--- |:--- |
| ```smd_100th(x)``` | Convert dimesion to 1/100" notation |
| ```smd_100th(x)``` | Convert dimension to 1/100" notation |
| ```smd_led_height(type)``` | Total height |
| ```smd_size(size)``` | Convert size to 1/100" notation |
@@ -3092,13 +3201,18 @@ Surface mount components for PCBs.
| Module | Description |
|:--- |:--- |
| ```smd_led(type, colour, cutout)``` | Draw an SMD LED with specified ```colour``` |
| ```smd_resistor(type, value)``` | Draw an SMD resistor with specified value |
![smds](tests/png/smds.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```smd_led(LED0805, green)``` | SMD LED 0805 green |
| 1 | ```smd_led(LED0603, green)``` | SMD LED 0603 green |
| 1 | ```smd_led(LED0805, blue)``` | SMD LED 0805 blue |
| 1 | ```smd_resistor(RES0603, 1R0)``` | SMD resistor 0603 1R0 0.1W |
| 1 | ```smd_resistor(RES0805, 10M)``` | SMD resistor 0805 10M 0.125W |
| 1 | ```smd_resistor(RES1206, 100K)``` | SMD resistor 1206 100K 0.25W |
<a href="#top">Top</a>
@@ -3516,10 +3630,15 @@ Tubing and sleeving. The internal diameter can be forced to stretch it over some
| ```tubing_material(type)``` | Material description |
| ```tubing_od(type)``` | Outside diameter |
### Functions
| Function | Description |
|:--- |:--- |
| ```tubing_or(type)``` | Outside radius |
### Modules
| Module | Description |
|:--- |:--- |
| ```tubing(type, length = 15, forced_id = 0)``` | Draw specified tubing with optional forced internal diameter |
| ```tubing(type, length = 15, forced_id = 0, center = true)``` | Draw specified tubing with optional forced internal diameter |
![tubings](tests/png/tubings.png)
@@ -3533,7 +3652,10 @@ Tubing and sleeving. The internal diameter can be forced to stretch it over some
| 1 | ```tubing(NEOP85)``` | Neoprene tubing OD 8mm ID 5mm x 15mm |
| 1 | ```tubing(PTFE07)``` | PTFE sleeving OD 1.2mm ID 0.71mm x 15mm |
| 1 | ```tubing(PTFE20)``` | PTFE sleeving OD 2.6mm ID 2mm x 15mm |
| 1 | ```tubing(PTFE2_3)``` | PTFE tubing OD 3mm ID 2mm x 15mm |
| 1 | ```tubing(PF7)``` | PTFE tubing OD 4.6mm ID 3.84mm x 15mm |
| 1 | ```tubing(PTFE2_4)``` | PTFE tubing OD 4mm ID 2mm x 15mm |
| 1 | ```tubing(PTFE4_6)``` | PTFE tubing OD 6mm ID 4mm x 15mm |
| 1 | ```tubing(PVC64)``` | PVC aquarium tubing OD 6mm ID 4mm x 15mm |
| 1 | ```tubing(PVC85)``` | PVC aquarium tubing OD 8mm ID 5mm x 15mm |
@@ -4175,7 +4297,7 @@ Star washers can be omitted by setting ```star_washers``` to false.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 3 | ```insert(F1BM)``` | Heatfit insert M2 |
| 3 | ```insert(F1BM2)``` | Heatfit insert M2 |
| 3 | ```insert(F1BM2p5)``` | Heatfit insert M2.5 |
| 3 | ```insert(F1BM3)``` | Heatfit insert M3 |
| 3 | ```insert(F1BM4)``` | Heatfit insert M4 |
@@ -4337,7 +4459,7 @@ The ring spacing as well as the number of spokes can be specified, if zero a gas
| ---:|:--- |
| 1 | fan_guard_120.stl |
| 1 | fan_guard_17.stl |
| 1 | fan_guard_25.stl |
| 1 | fan_guard_25.4.stl |
| 1 | fan_guard_30.stl |
| 1 | fan_guard_40.stl |
| 1 | fan_guard_50.stl |
@@ -4395,7 +4517,7 @@ Star washers can be omitted by setting ```star_washers``` to false.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 3 | ```insert(F1BM)``` | Heatfit insert M2 |
| 3 | ```insert(F1BM2)``` | Heatfit insert M2 |
| 3 | ```insert(F1BM2p5)``` | Heatfit insert M2.5 |
| 3 | ```insert(F1BM3)``` | Heatfit insert M3 |
| 3 | ```insert(F1BM4)``` | Heatfit insert M4 |
@@ -4725,7 +4847,7 @@ It can also have printed feet on the base with the screws doubling up to hold th
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 4 | ```insert(F1BM)``` | Heatfit insert M2 |
| 4 | ```insert(F1BM2)``` | Heatfit insert M2 |
| 4 | ```insert(F1BM3)``` | Heatfit insert M3 |
| 4 | ```screw(M2_cap_screw, 6)``` | Screw M2 cap x 6mm |
| 3 | ```screw(M3_pan_screw, 6)``` | Screw M3 pan x 6mm |
@@ -5155,6 +5277,53 @@ Rounded fillet for adding to corners.
![fillet](tests/png/fillet.png)
<a href="#top">Top</a>
---
<a name="Gears"></a>
## Gears
Utilities for making involute gears.
Formulas from <https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html>
<https://khkgears.net/new/gear_knowledge/gear_technical_reference/calculation_gear_dimensions.html>
and <https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/>
```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D.
Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```.
Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered
the practical minimum.
The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter.
The origin of the rack is the left end of the pitch line and its width is below the pitch line. I.e. it does not include the addendum.
```involute_worm_profile()``` returns a tooth profile that can be passed to ```thread()``` to make worms.
[utils/gears.scad](utils/gears.scad) Implementation.
[tests/gears.scad](tests/gears.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| ```centre_distance(m, z1, z2, pa = 20)``` | Calculate distance between centres taking profile shift into account |
| ```involute(r, u)``` | Involute of circle radius r at angle u in radians |
| ```involute_gear_od(m, z, pa = 20)``` | involute gear outside diameter given modulus, tooth count and pressure angle |
| ```involute_rack_tooth_profile(m, pa = 20, clearance = undef)``` | Calculate rack tooth profile given module and pressure angle |
| ```involute_worm_profile(m, pa = 20, clearance = undef)``` | Calculate worm profile suitable for passing to thread() |
| ```profile_shift(z, pa)``` | Calculate profile shift for small gears |
### Modules
| Module | Description |
|:--- |:--- |
| ```involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20)``` | Calculate gear profile given module, number of teeth and pressure angle |
| ```involute_rack_profile(m, z, w, pa = 20, clearance = undef)``` | Calculate rack profile given module, number of teeth and pressure angle |
![gears](tests/png/gears.png)
<a href="#top">Top</a>
---
@@ -5175,6 +5344,31 @@ Method to print holes in mid air. See <https://hydraraptor.blogspot.com/2014/03/
![hanging_hole](tests/png/hanging_hole.png)
<a href="#top">Top</a>
---
<a name="Horiholes"></a>
## Horiholes
Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops), see <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
[utils/horiholes.scad](utils/horiholes.scad) Implementation.
[tests/horiholes.scad](tests/horiholes.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| ```teardrop_plus_x(r, y, h)``` | Calculate the ordinate of a compensated teardrop given y and layer height. |
### Modules
| Module | Description |
|:--- |:--- |
| ```horihole(r, z, h = 0, center = true)``` | For making horizontal holes that don't need support material and are correct dimensions |
![horiholes](tests/png/horiholes.png)
<a href="#top">Top</a>
---
@@ -5217,17 +5411,21 @@ Maths utilities for manipulating vectors and matrices.
|:--- |:--- |
| ```angle_between(v1, v2)``` | Return the angle between two vectors |
| ```augment(m)``` | Augment a matrix by adding an identity matrix to the right |
| ```degrees(radians)``` | Convert degrees to radians |
| ```euler(R)``` | Convert a rotation matrix to a Euler rotation vector. |
| ```identity(n, x = 1)``` | Construct an arbitrary size identity matrix |
| ```invert(m)``` | Invert a matrix |
| ```nearly_zero(x)``` | True if x is close to zero |
| ```radians(degrees)``` | Convert radians to degrees |
| ```reverse(v)``` | Reverse a vector |
| ```rot2_z(a)``` | Generate a 2x2 matrix to rotate around z |
| ```rot3_z(a)``` | Generate a 3x3 matrix to rotate around z |
| ```rotate(a, v)``` | Generate a 4x4 rotation matrix, ```a``` can be a vector of three angles or a single angle around ```z```, or around axis ```v``` |
| ```rowswap(m, i, j)``` | Swap two rows of a matrix |
| ```scale(v)``` | Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally |
| ```solve(m, i = 0, j = 0)``` | Solve each row ensuring diagonal is not zero |
| ```solve_row(m, i)``` | Make diagonal one by dividing the row by it and subtract from other rows to make column zero |
| ```sqr(x)``` | Square x |
| ```transform(v, m)``` | Apply 4x4 transform to a 3 vector by extending it and cropping it again |
| ```transform_points(path, m)``` | Apply transform to a path |
| ```translate(v)``` | Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z``` |
@@ -5435,6 +5633,8 @@ specify a chamfer angle.
Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
example to make a printed pot with a screw top lid.
A left hand thread can be made by using mirror([0,1]).
Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
@@ -5461,7 +5661,7 @@ Threads obey the $fn, $fa, $fs variables.
|:--- |:--- |
| ```female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, colour = undef)``` | Create female thread with metric profile |
| ```male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef)``` | Create male thread with metric profile |
| ```thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef)``` | Create male or femail thread, ends can be tapered, chamfered or square |
| ```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 |
![thread](tests/png/thread.png)
@@ -5609,6 +5809,7 @@ Global constants, functions and modules. This file is used directly or indirectl
| ```inch(x)``` | Inch to mm conversion (For fractional inches, 'inch(1 + 7/8)' will work as expected.) |
| ```m(x)``` | m to mm conversion |
| ```mm(x)``` | Explicit mm specified |
| ```no_point(str)``` | Replace decimal point in string with 'p' |
| ```r2sides(r)``` | Replicates the OpenSCAD logic to calculate the number of sides from the radius |
| ```r2sides4n(r)``` | Round up the number of sides to a multiple of 4 to ensure points land on all axes |
| ```sqr(x)``` | Returns the square of ```x``` |
@@ -5741,6 +5942,9 @@ This ensures `hull` and `minkowski` results have the correct dimensions when sph
For making horizontal holes that don't need support material.
Small holes can get away without it, but they print better with truncated teardrops.
Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips
do not intrude into the circle. See <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
[utils/core/teardrops.scad](utils/core/teardrops.scad) Implementation.
@@ -5749,12 +5953,12 @@ Small holes can get away without it, but they print better with truncated teardr
### Modules
| Module | Description |
|:--- |:--- |
| ```semi_teardrop(h, r, d = undef, center = true, chamfer = 0)``` | A semi teardrop in the positive Y domain |
| ```teardrop(h, r, center = true, truncate = true, chamfer = 0)``` | For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging |
| ```semi_teardrop(h, r, d = undef, center = true, chamfer = 0, plus = false)``` | A semi teardrop in the positive Y domain |
| ```teardrop(h, r, center = true, truncate = true, chamfer = 0, 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 |
| ```teardrop_chamfer(h, center, chamfer)``` | Helper module for adding chamfer to a teardrop |
| ```teardrop_plus(h, r, center = true, truncate = true, chamfer = 0)``` | Slightly bigger teardrop to allow for the 3D printing staircase effect |
| ```tearslot(h, r, w, center = true, chamfer = 0)``` | A horizontal slot that doesn't need support material |
| ```vertical_tearslot(h, r, l, center = true, chamfer = 0)``` | A vertical slot that doesn't need support material |
| ```teardrop_plus(h, r, center = true, truncate = true, chamfer = 0)``` | Slightly elongated teardrop to allow for the 3D printing staircase effect |
| ```tearslot(h, r, w, center = true, chamfer = 0, plus = false)``` | A horizontal slot that doesn't need support material |
| ```vertical_tearslot(h, r, l, center = true, chamfer = 0, plus = false)``` | A vertical slot that doesn't need support material |
![teardrops](tests/png/teardrops.png)

View File

@@ -45,6 +45,7 @@ def plateup(target, part_type, usage = None):
# Loop through source directories
#
used = []
all_sources = []
for dir in [source_dir1, source_dir2]:
if not os.path.isdir(dir):
continue
@@ -60,6 +61,7 @@ def plateup(target, part_type, usage = None):
# Decide which files to make
#
sources = [file for file in os.listdir(dir) if file.endswith('.scad')]
all_sources += sources
#
# Run OpenSCAD on the source files to make the targets
#
@@ -100,7 +102,7 @@ def plateup(target, part_type, usage = None):
#
# Remove any cruft
#
targets = [file[:-4] + part_type for file in sources]
targets = [file[:-4] + part_type for file in all_sources]
for file in os.listdir(target_dir):
if file.endswith('.' + part_type):
if not file in targets and not file in copied:

View File

@@ -58,8 +58,12 @@ test_pcb = ["TestPCB", "Test PCB",
// components
[
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 0, "trimpot10", true],
[ 10, 2, 0, "smd_led", LED0805, "red"],
[ 20, -15, 90, "trimpot10", true],
[ 10, 2, 90, "smd_led", LED0805, "red"],
[ 13, 2, 90, "smd_led", LED0603, "orange"],
[ 16, 2, 90, "smd_res", RES1206, "1K"],
[ 19, 2, 90, "smd_res", RES0805, "1K"],
[ 22, 2, 90, "smd_res", RES0603, "1K"],
[ 10, 10, 0, "2p54header", 4, 1],
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
[ 10, 20, 0, "2p54boxhdr", 4, 2],
@@ -82,16 +86,20 @@ test_pcb = ["TestPCB", "Test PCB",
[ 5, 218, 180, "hdmi"],
[ 3, 235, 180, "mini_hdmi"],
[ 6, 175, 180, "uSD", [12, 11.5, 1.4]],
[ 65, 9, 0, "link", inch(0.4)],
[ 65, 12, 0, "ax_res", res1_8, 1000],
[ 65, 17, 0, "ax_res", res1_4, 10000],
[ 65, 22, 0, "ax_res", res1_2, 100000],
[ 80, 9, 0, "link", inch(0.2), inch(0.4)],
[ 80, 12, 0, "ax_res", res1_8, 1000000, 1, inch(0.1)],
[ 80, 17, 0, "ax_res", res1_4, 100, 2, inch(0.1)],
[ 80, 22, 0, "ax_res", res1_2, 10, 10, inch(0.2)],
[ 60, 3, 0, "flex"],
[ 50, 15, 0, "flat_flex"],
[ 50, 15, -90, "flat_flex"],
[ 40, 15, -90, "flat_flex", true],
[ 60, 35, 0, "D_plug", DCONN9],
[ 50, 50, 0, "molex_hdr", 2],

View File

@@ -21,9 +21,14 @@ use <../utils/layout.scad>
include <../vitamins/smds.scad>
module smds()
layout([for(l = smd_leds) smd_led_size(l).x], 1)
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
module smds() {
layout([for(r = smd_resistors) smd_res_size(r).x], 1)
smd_resistor(smd_resistors[$i], ["1R0", "10M", "100K"][$i % 3]);
translate([0, 3])
layout([for(l = smd_leds) smd_led_size(l).x], 1)
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
}
if($preview)
smds();

View File

@@ -60,7 +60,7 @@ module belt_test() {
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
];
belt = GT2x6;
belt(belt, path, 80, [0, belt_pitch_height(belt) - belt_thickness(belt) / 2]);
belt(belt, path, 80, [0, 0]);
translate([-25, 0])
layout([for(b = belts) belt_width(b)], 10)

31
tests/cameras.scad Normal file
View File

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

66
tests/gears.scad Normal file
View File

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

90
tests/horiholes.scad Normal file
View File

@@ -0,0 +1,90 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
$layer_height = 0.25;
include <../utils/core/core.scad>
use <../utils/horiholes.scad>
show_disc = true;
use_horihole = true;
thickness = 6;
length = 60;
height = 20;
overlap_x = 15;
overlap_y = 10;
module hole_positions() {
x0 = (length - 40) / 2;
for($i = [0 : 4], $z = 5 + $i * layer_height / 5, $r = 3)
translate([x0 + $i * 10, $z])
children();
for($i = [0 : 4], $z = 15 + $i * layer_height / 5, $r = 0.5 + $i / 2)
translate([x0 + $i * 10, $z])
children();
}
module horiholes_stl(t = thickness) {
rotate([90, 0, 0])
difference() {
linear_extrude(t, center = true) {
difference() {
square([length, height]);
hole_positions()
if(use_horihole)
horihole($r, $z);
else
teardrop_plus(h = 0, r = $r);
}
}
}
if(t == thickness)
translate([length / 2, 0])
rounded_rectangle([length + 2 * overlap_x, thickness + 2 * overlap_y, 2], 5);
}
module horiholes() {
stl_colour(pp1_colour)
rotate([-90, 0, 0])
horiholes_stl(eps);
if(show_disc)
hole_positions()
color(silver)
cylinder(r = $r, h = eps, center = true, $fn = 360);
hole_positions()
color("red")
linear_extrude(2 * eps, center = true)
intersection() {
difference() {
square(8, center = true);
horihole($r, $z);
}
circle($r, $fn = 360);
}
}
if($preview)
rotate(is_undef($bom) ? 0 : [70, 0, 315])
horiholes();
else
horiholes_stl();

29
tests/magnets.scad Normal file
View File

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

View File

@@ -23,26 +23,53 @@ include <../vitamins/pin_headers.scad>
pins = 10;
module pin_headers()
module pin_headers() {
layout([for(p = pin_headers) hdr_pitch(p) * pins], 15) {
idc_transition(pin_headers[$i], 10);
translate([0, 20])
pin_header(pin_headers[$i], 10, 2, right_angle = true);
pin_header(pin_headers[$i], 3, 2, right_angle = true);
translate([-10, 20])
pin_header(pin_headers[$i], 3, 1, right_angle = true);
translate([10, 20])
pin_header(pin_headers[$i], 3, 3, right_angle = true);
translate([0, 30])
pin_header(pin_headers[$i], 8, 1);
translate([0, 40])
pin_header(pin_headers[$i], 10, 2);
translate([0, 50])
box_header(pin_headers[$i], 8, 1);
translate([0, 60])
box_header(pin_headers[$i], 10, 2);
translate([0, 70])
pin_socket(pin_headers[$i], 8, 1);
translate([0, 80])
pin_socket(pin_headers[$i], 10, 2);
translate([0, 110])
pin_socket(pin_headers[$i], 10, 2, right_angle = true);
translate([-10, 105])
pin_socket(pin_headers[$i], 3, 1, right_angle = true);
translate([0, 105])
pin_socket(pin_headers[$i], 3, 2, right_angle = true);
translate([10, 105])
pin_socket(pin_headers[$i], 3, 3, right_angle = true);
}
translate([-20, 0])
jst_xh_header(jst_xh_header, 5);
translate([-20, 20])
jst_xh_header(jst_xh_header, 5, true);
}
if($preview)
pin_headers();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 95 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: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

BIN
tests/png/cameras.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 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: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

BIN
tests/png/gears.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
tests/png/horiholes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 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: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

BIN
tests/png/magnets.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 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: 168 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -67,7 +67,7 @@ module box1_external_additions() {
module box1_holes() {
box1_feet_positions()
teardrop(r = screw_pilot_hole(foot_screw(foot)), h = 10, center = true);
teardrop_plus(r = screw_pilot_hole(foot_screw(foot)), h = 10, center = true);
}

View File

@@ -25,10 +25,10 @@ use <../vitamins/nut.scad>
sheet = 3;
module rails()
layout([for(l = rails) carriage_width(rail_carriage(l))], 25)
layout([for(l = rails) carriage_width(rail_carriage(l))], 20)
rotate(-90) {
rail = rails[$i];
length = rail == MGN15 ? 260 : 200;
length = 200;
screw = rail_screw(rail);
nut = screw_nut(screw);
washer = screw_washer(screw);

View File

@@ -41,7 +41,10 @@ module teardrops() {
translate([20, 10])
semi_teardrop(h = 0, r = 3);
}
translate([20, 20])
teardrop(h = 0, r = 3, truncate = false, plus = true);
}
}
translate([40, 0, 1.5]) {
h = 3 + eps;
@@ -61,6 +64,9 @@ module teardrops() {
translate([20, 10])
semi_teardrop(h = h, r = 3, chamfer = chamfer);
translate([20, 20])
teardrop(h = h, r = 3, truncate = false, plus = false, chamfer = chamfer);
}
}
}

View File

@@ -26,27 +26,27 @@ profile = thread_profile(pitch / 2, pitch * 0.366, 30);
module threads()
for(female = [false, true]) translate([0, female ? -20 : 0]) {
length = female ? 8 : 40;
dia = female ? 8 : 8 - pitch;
colour = female ? brass : silver;
length = female ? 8 : 40;
dia = female ? 8 : 8 - pitch;
colour = female ? brass : silver;
thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour);
thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour);
color(colour)
translate([20, 0])
thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female);
color(colour)
translate([20, 0])
thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female);
translate([40, 0])
thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour);
translate([40, 0])
thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour);
color(colour)
translate([60, 0])
thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female);
color(colour)
translate([60, 0])
thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female);
color(colour)
translate([80, 0])
thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female);
}
color(colour)
translate([80, 0])
thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female);
}
let($show_threads = true)
threads();

View File

@@ -31,6 +31,7 @@ function m(x) = x * 1000.0;
function sqr(x) = x * x; //! Returns the square of ```x```
function echoit(x) = echo(x) x; //! Echo expression and return it, useful for debugging
function no_point(str) = chr([for(c = str(str)) if(c == ".") ord("p") else ord(c)]);//! Replace decimal point in string with 'p'
function in(list, x) = !!len([for(v = list) if(v == x) true]); //! Returns true if ```x``` is an element in the ```list```
function Len(x) = is_list(x) ? len(x) : 0; //! Returns the length of a list or 0 if ```x``` is not a list
function r2sides(r) = $fn ? $fn : ceil(max(min(360/ $fa, r * 2 * PI / $fs), 5)); //! Replicates the OpenSCAD logic to calculate the number of sides from the radius

View File

@@ -20,17 +20,32 @@
//
//! For making horizontal holes that don't need support material.
//! Small holes can get away without it, but they print better with truncated teardrops.
//!
//! Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips
//! do not intrude into the circle. See <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
//
module teardrop(h, r, center = true, truncate = true, chamfer = 0) { //! 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(h, r, center = true, truncate = true, chamfer = 0, 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) {
hull() {
circle4n(r);
if(truncate)
translate([0, r / 2])
square([2 * r * (sqrt(2) - 1), r], center = true);
else
polygon([[0, 0], [eps, 0], [0, r * sqrt(2)]]);
}
er = layer_height / 2 - eps; // Extrustion edge radius
R = plus ? r + er : r; // Corrected radius
offset = plus ? -er : 0; // Offset inwards
hull()
for(side = [0 : 1])
mirror([side, 0, 0])
intersection() {
hull()
translate([offset, 0]) {
circle4n(R);
if(truncate)
translate([0, R / 2])
square([2 * R * (sqrt(2) - 1), R], center = true);
else
polygon([[0, 0], [eps, 0], [0, R * sqrt(2)]]);
}
translate([0, -2 * R])
square([R, 4 * R]);
}
}
render(convexity = 5)
@@ -40,23 +55,23 @@ module teardrop(h, r, center = true, truncate = true, chamfer = 0) { //! For mak
teardrop_chamfer(h, center, chamfer) {
linear_extrude(eps, center = true)
teardrop_2d(r + chamfer / 2, truncate);
translate_z(-chamfer / 2)
linear_extrude(eps, center = true)
teardrop_2d(r, truncate);
}
}
module semi_teardrop(h, r, d = undef, center = true, chamfer = 0) { //! A semi teardrop in the positive Y domain
module semi_teardrop_2d(r, d) {
module semi_teardrop(h, r, d = undef, center = true, chamfer = 0, plus = false) { //! A semi teardrop in the positive Y domain
module semi_teardrop_2d(r, d)
intersection() {
R = is_undef(d) ? r : d / 2;
teardrop(r = R, h = 0);
teardrop(r = R, h = 0, plus = plus);
sq = R + 1;
translate([-sq, 0])
square([2 * sq, sq]);
}
}
render(convexity = 5)
extrude_if(h, center)
@@ -65,22 +80,21 @@ module semi_teardrop(h, r, d = undef, center = true, chamfer = 0) { //! A semi t
teardrop_chamfer(h, center, chamfer) {
linear_extrude(eps, center = true)
semi_teardrop_2d(r + chamfer / 2, d);
translate_z(-chamfer / 2)
linear_extrude(eps, center = true)
semi_teardrop_2d(r, d);
}
}
module teardrop_plus(h, r, center = true, truncate = true, chamfer = 0) //! Slightly bigger teardrop to allow for the 3D printing staircase effect
teardrop(h, r + layer_height / 4, center, truncate, chamfer);
module teardrop_plus(h, r, center = true, truncate = true, chamfer = 0) //! Slightly elongated teardrop to allow for the 3D printing staircase effect
teardrop(h, r, center, truncate, chamfer, plus = true);
module tearslot(h, r, w, center = true, chamfer = 0) { //! A horizontal slot that doesn't need support material
module tearslot_2d(r, w) {
hull() {
translate([-w / 2, 0]) teardrop(r = r, h = 0);
translate([w / 2, 0]) teardrop(r = r, h = 0);
}
}
module tearslot(h, r, w, center = true, chamfer = 0, plus = false) { //! A horizontal slot that doesn't need support material
module tearslot_2d(r, w)
hull()
for(x = [-1, 1])
translate([x * w / 2, 0]) teardrop(r = r, h = 0, plus = plus);
extrude_if(h, center)
tearslot_2d(r, w);
@@ -88,19 +102,19 @@ module tearslot(h, r, w, center = true, chamfer = 0) { //! A horizontal slot tha
teardrop_chamfer(h, center, chamfer) {
linear_extrude(eps, center = true)
tearslot_2d(r + chamfer / 2, w);
translate_z(-chamfer / 2)
linear_extrude(eps, center = true)
tearslot_2d(r, w);
}
}
module vertical_tearslot(h, r, l, center = true, chamfer = 0) { //! A vertical slot that doesn't need support material
module vertical_tearslot_2d(r, l) {
hull() {
translate([0, l / 2]) teardrop(0, r, true);
translate([0, -l / 2]) circle4n(r);
}
}
module vertical_tearslot(h, r, l, center = true, chamfer = 0, plus = false) { //! A vertical slot that doesn't need support material
module vertical_tearslot_2d(r, l)
hull()
for(y = [-1, 1])
translate([0, y * l / 2])
teardrop(0, r, true, plus = plus);
extrude_if(h, center)
vertical_tearslot_2d(r, l);
@@ -108,6 +122,7 @@ module vertical_tearslot(h, r, l, center = true, chamfer = 0) { //! A vertical s
teardrop_chamfer(h, center, chamfer) {
linear_extrude(eps, center = true)
vertical_tearslot_2d(r + chamfer / 2, l);
translate_z(-chamfer / 2)
linear_extrude(eps, center = true)
vertical_tearslot_2d(r, l);
@@ -123,4 +138,3 @@ module teardrop_chamfer(h, center, chamfer) { //! Helper module for adding chamf
hull()
children();
}

138
utils/gears.scad Normal file
View File

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

View File

@@ -39,11 +39,13 @@ module hanging_hole(z, ir, h = 100, h2 = 100) { //! Hole radius ```ir``` hanging
infill_angle = z % (2 * layer_height) ? -45 : 45;
below = min(z + eps, h2);
big = 1000;
render(convexity = 3) translate_z(z)
union() {
translate_z(2 * layer_height)
polyhole(ir - eps, h - 2 * layer_height);
if(sides(ir) > 4)
polyhole(ir - eps, h - 2 * layer_height);
else
poly_cylinder(ir, h - 2 * layer_height);
difference() {
translate_z(-below)

55
utils/horiholes.scad Normal file
View File

@@ -0,0 +1,55 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops), see <https://hydraraptor.blogspot.com/2020/07/horiholes-2.html>
//
include <../utils/core/core.scad>
function teardrop_plus_x(r, y, h) = //! Calculate the ordinate of a compensated teardrop given y and layer height.
let(fr = h / 2,
hpot = r + fr,
x2 = sqr(hpot) - sqr(y),
x = x2 > 0 ? sqrt(x2) : 0
)
max(0,
y < hpot / sqrt(2) ? x - fr :
y < hpot ? hpot * sqrt(2) - y - fr :
0);
module horihole(r, z, h = 0, center = true) { //! For making horizontal holes that don't need support material and are correct dimensions
bot_layer = floor((z - r) / layer_height);
top_layer = ceil((z + r) / layer_height);
render(convexity = 5)
extrude_if(h, center)
for(i = [bot_layer : top_layer]) {
Z = i * layer_height;
y = Z - z + layer_height / 2;
x = teardrop_plus_x(r, y, layer_height);
if(x > 0)
translate([0, y])
difference() {
square([2 * x + layer_height, layer_height], center = true);
for(end = [-1, 1])
translate([end * (x + layer_height / 2), 0])
circle(d = layer_height, $fn = 32);
}
}
}

View File

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

View File

@@ -20,7 +20,10 @@
//
//! Maths utilities for manipulating vectors and matrices.
//
function sqr(x) = x * x;
function sqr(x) = x * x; //! Square x
function radians(degrees) = degrees * PI / 180; //! Convert radians to degrees
function degrees(radians) = radians * 180 / PI; //! Convert degrees to radians
function translate(v) = let(u = is_list(v) ? len(v) == 2 ? [v.x, v.y, 0] //! Generate a 4x4 translation matrix, ```v``` can be ```[x, y]```, ```[x, y, z]``` or ```z```
: v
@@ -63,6 +66,12 @@ function rot3_z(a) = //! Generate a 3x3 matrix to rotate around z
[ s, c, 0],
[ 0, 0, 1] ];
function rot2_z(a) = //! Generate a 2x2 matrix to rotate around z
let(c = cos(a),
s = sin(a))
[ [ c, -s],
[ s, c] ];
function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matrix that scales by ```v```, which can be a vector of xyz factors or a scalar to scale all axes equally
[
[s.x, 0, 0, 0],

View File

@@ -23,18 +23,21 @@
include <../utils/core/core.scad>
module quadrant(w, r, center = false) { //! Draw a square with one rounded corner, can be centered on the arc centre, when ```center``` is ```true```.
offset = center ? r - w : 0;
translate([offset, offset])
h = is_list(w) ? w.y : w;
w = is_list(w) ? w.x : w;
offset_w = center ? r - w : 0;
offset_h = center ? r - h : 0;
translate([offset_w, offset_h])
hull() {
intersection() {
translate([w - r, w - r])
translate([w - r, h - r])
circle4n(r);
square(w);
square([w, h]);
}
square([w, eps]);
square([eps, w]);
square([eps, h]);
}
}

View File

@@ -26,6 +26,8 @@
//! Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
//! example to make a printed pot with a screw top lid.
//!
//! A left hand thread can be made by using mirror([0,1]).
//!
//! Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
//! a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
//!
@@ -47,7 +49,7 @@ function thread_profile(h, crest, angle, overlap = 0.1) = //! Create thread prof
let(base = crest + 2 * (h + overlap) * tan(angle / 2))
[[-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 femail thread, ends can be tapered, chamfered or square
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
//
// Apply colour if defined
//
@@ -61,10 +63,12 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
// Extract some properties from the profile, perhaps they should be stored in it.
//
h = max([for(p = sprofile) p.y]);
maxx = max([for(p = sprofile) p.x]);
minx = min([for(p = sprofile) p.x]);
crest_xmax = max([for(p = sprofile) if(p.x != maxx) p.x]);
crest_xmin = min([for(p = sprofile) if(p.x != minx) p.x]);
xs = [for(p = sprofile) p.x];
maxx = max(xs);
minx = min(xs);
crest_xs = [for(p = sprofile) if(p.y == h) p.x];
crest_xmax = max(crest_xs);
crest_xmin = min(crest_xs);
//
// If the ends don't taper we need an extra half turn past the ends to be cropped horizontally.
//
@@ -129,11 +133,13 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
render() intersection() {
polyhedron(points, ends_faces);
len = length - 2 * eps;
shorten = !is_undef(colour);
len = shorten ? length - 2 * eps : length;
offset = shorten ? eps : 0;
rotate_extrude()
if(female) {
difference() {
translate([0, eps])
translate([0, offset])
square([r + h + overlap, len]);
if(top_chamfer_h)
@@ -146,7 +152,7 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st
else
difference() {
hull() {
translate([0, eps])
translate([0, offset])
square([r, len]);
translate([0, bot_chamfer_h])

View File

@@ -24,6 +24,7 @@ include <../utils/core/core.scad>
include <../utils/round.scad>
module wire_link(d, l, h = 1, tail = 3) { //! Draw a wire jumper link.
vitamin(str("wire_link(", d, ", ", l, arg(h, 1, "h"), arg(tail, 3, "tail"), "): Wire link ", d, "mm x ", l / inch(1), "\""));
r = d;
$fn = 32;
@@ -57,13 +58,16 @@ module orientate_axial(length, height, pitch, wire_d) { // Orient horizontal or
min_pitch = ceil((length + 1) / inch(0.1)) * inch(0.1);
lead_pitch = pitch ? pitch : min_pitch;
if(lead_pitch >= min_pitch) {
wire_link(wire_d, lead_pitch, height);
not_on_bom()
wire_link(wire_d, lead_pitch, height);
translate_z(height)
rotate([0, 90, 0])
children();
}
else {
wire_link(wire_d, lead_pitch, length + 0.7 + wire_d);
not_on_bom()
wire_link(wire_d, lead_pitch, length + 0.7 + wire_d);
translate([-pitch / 2, 0, length / 2 + 0.2])
children();

View File

@@ -52,21 +52,21 @@ module ball_bearing(type) { //! Draw a ball bearing
rim_chamfer = rim / 6;
rotate_extrude()
hull() {
translate([or - rim / 2, 0])
square([rim, h - 2 * rim_chamfer], center = true);
translate([or - rim, -h / 2 + rim_chamfer])
square([rim, h - 2 * rim_chamfer]);
translate([or - rim / 2 - rim_chamfer, 0])
square([rim - rim_chamfer, h], center = true);
translate([or - rim, -h / 2])
square([rim - rim_chamfer, h]);
}
hub_chamfer = hub / 6;
rotate_extrude()
hull() {
translate([ir + hub / 2, 0])
square([hub, h - 2 * hub_chamfer], center = true);
translate([ir, -h / 2 + hub_chamfer])
square([hub, h - 2 * hub_chamfer]);
translate([ir + hub / 2 + hub_chamfer, 0])
square([hub - hub_chamfer, h], center = true);
translate([ir + hub_chamfer, -h / 2])
square([hub - hub_chamfer, h]);
}
}

View File

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

View File

@@ -24,29 +24,31 @@
//! 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.
//!
//! 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>
function belt_pitch(type) = type[1]; //! Pitch in mm
function belt_width(type) = type[2]; //! Width in mm
function belt_thickness(type) = type[3]; //! Total thickness including teeth
function belt_tooth_height(type) = type[4]; //! Tooth height
function belt_pitch_height(type) = belt_tooth_height(type) + type[4]; //! Offset of the pitch radius from the tips of the teeth
function belt_pitch_height(type) = type[5] + belt_tooth_height(type); //! Offset of the pitch radius from the tips of the teeth
function no_point(str) = chr([for(c = str) if(c == ".") ord("p") else ord(c)]);
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_pt = undef, belt_colour = grey(20), tooth_colour = grey(50)) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
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
width = belt_width(type);
pitch = belt_pitch(type);
thickness = belt_thickness(type);
part = str(type[0],pitch);
vitamin(str("belt(", no_point(part), "x", width, ", ", points, arg(gap, 0), arg(gap_pt, undef), "): Belt ", part," x ", width, "mm x ", length, "mm"));
vitamin(str("belt(", no_point(part), "x", width, ", ", points, arg(gap, 0), arg(gap_pos, undef), "): Belt ", part," x ", width, "mm x ", length, "mm"));
len = len(points);
@@ -56,24 +58,28 @@ module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20), tooth
module shape() rounded_polygon(points, tangents);
ph = belt_pitch_height(type);
th = belt_tooth_height(type);
module gap()
if(gap)
translate(gap_pt)
square([gap, thickness + eps], center = true);
translate([gap_pos.x, gap_pos.y])
rotate(is_undef(gap_pos.z) ? 0 : gap_pos.z)
translate([0, ph - thickness / 2])
square([gap, thickness + eps], center = true);
color(belt_colour)
linear_extrude(width, center = true)
difference() {
offset(thickness - belt_pitch_height(type)) shape();
offset(-belt_pitch_height(type) + belt_tooth_height(type)) shape();
offset(-ph + thickness ) shape();
offset(-ph + th) shape();
gap();
}
color(tooth_colour)
linear_extrude(width, center = true)
difference() {
offset(-belt_pitch_height(type) + belt_tooth_height(type)) shape();
offset(-belt_pitch_height(type)) shape();
offset(-ph + th) shape();
offset(-ph) shape();
gap();
}
}

89
vitamins/camera.scad Normal file
View File

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

73
vitamins/cameras.scad Normal file
View File

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

View File

@@ -17,28 +17,28 @@
// If not, see <https://www.gnu.org/licenses/>.
//
// w d b h s h t o b b a
// i e o o c u h u l o p
// d p r l r b i t a s p
// t t e e e c e d s e
// h h w d k r e r
// p i n s d t
// i a e d u
// t s i r
// c s a e
// h
// w d b h s h t o b b a
// i e o o c u h u l o p
// d p r l r b i t a s p
// t t e e e c e d s e
// h h w d k r e r
// p i n s d t
// i a e d u
// t s i r
// c s a e
// h
//
fan120x25= [120,25, 116,52.5, M4_dome_screw, 41, 4, 140, 9, 0, 137];
fan80x38 = [80, 38, 75, 35.75, M4_dome_screw, 40, 4.3, 84, 7, 0, 85];
fan80x25 = [80, 25, 75, 35.75, M4_dome_screw, 40, 4.3, 84, 7, 0, 85];
fan70x15 = [70, 15, 66, 30.75, M4_dome_screw, 29, 3.8, 70 ,7, 0, undef];
fan60x25 = [60, 25, 57, 25, M4_dome_screw, 31.5, 3.6, 64, 7, 0, 63];
fan60x15 = [60, 15, 57, 25, M4_dome_screw, 29, 2.4, 60, 7, 7.7, 63];
fan50x15 = [50, 15, 48, 20, M4_dome_screw, 25, 12.5,100,7, 0, undef];
fan40x11 = [40, 11, 37, 16, M3_dome_screw, 25, 7.5,100, 9, 0, undef];
fan30x10 = [30, 10, 27, 12, M3_dome_screw, 17, 10, 100, 5, 0, undef];
fan25x10 = [25, 10, 24, 10, M2p5_pan_screw, 16, 10, 100, 5, 0, undef];
fan17x8 = [17, 8, 16, 6.75, M2_cap_screw, 12.6, 8, 100, 7, 0, undef];
fan120x25= [120, 25, 116,52.5, M4_dome_screw, 41, 4, 140, 9, 0, 137];
fan80x38 = [80, 38, 75, 35.75, M4_dome_screw, 40, 4.3, 84, 7, 0, 85];
fan80x25 = [80, 25, 75, 35.75, M4_dome_screw, 40, 4.3, 84, 7, 0, 85];
fan70x15 = [70, 15, 66, 30.75, M4_dome_screw, 29, 3.8, 70 ,7, 0, undef];
fan60x25 = [60, 25, 57, 25, M4_dome_screw, 31.5, 3.6, 64, 7, 0, 63];
fan60x15 = [60, 15, 57, 25, M4_dome_screw, 29, 2.4, 60, 7, 7.7, 63];
fan50x15 = [50, 15, 48, 20, M4_dome_screw, 25, 12.5,100, 7, 0, undef];
fan40x11 = [40, 11, 37, 16, M3_dome_screw, 25, 7.5,100, 9, 0, undef];
fan30x10 = [30, 10, 27, 12, M3_dome_screw, 17, 10, 100, 5, 0, undef];
fan25x10 = [25.4,10, 24, 10, M2p5_pan_screw, 16, 10, 100, 5, 0, undef];
fan17x8 = [17, 8, 16, 6.75, M2_cap_screw, 12.6, 8, 100, 7, 0, undef];
fans = [fan17x8, fan25x10, fan30x10, fan40x11, fan50x15, fan60x15, fan60x25, fan70x15, fan80x25, fan80x38, fan120x25];

View File

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

View File

@@ -24,17 +24,26 @@ include <../utils/core/core.scad>
use <../utils/quadrant.scad>
use <../utils/thread.scad>
function insert_length(type) = type[1]; //! Length
function insert_outer_d(type) = type[2]; //! Outer diameter at the top
function insert_length(type) = type[1]; //! Length
function insert_outer_d(type) = type[2]; //! Outer diameter at the top
function insert_hole_radius(type) = type[3] / 2; //! Radius of the required hole in the plastic
function insert_screw_diameter(type) = type[4]; //! Screw size
function insert_barrel_d(type) = type[5]; //! Diameter of the main barrel
function insert_ring1_h(type) = type[6]; //! Height of the top and middle rings
function insert_ring2_d(type) = type[7]; //! Diameter of the middle ring
function insert_ring3_d(type) = type[8]; //! Diameter of the bottom ring
function insert_screw_diameter(type) = type[4]; //! Screw size
function insert_barrel_d(type) = type[5]; //! Diameter of the main barrel
function insert_ring1_h(type) = type[6]; //! Height of the top and middle rings
function insert_ring2_d(type) = type[7]; //! Diameter of the middle ring
function insert_ring3_d(type) = type[8]; //! Diameter of the bottom ring
function insert_hole_length(type) = round_to_layer(insert_length(type));
function insert_nose_length(type, d) = let( //! The length before the second ring.
length = insert_length(type),
ring1_h = insert_ring1_h(type),
chamfer1 = (insert_ring2_d(type) - insert_barrel_d(type)) / 2,
chamfer2 = (insert_ring3_d(type) - insert_barrel_d(type)) / 2,
ring2_h = ring1_h + chamfer1,
gap = (length - ring1_h - ring2_h - chamfer2) / 3
) ring1_h + gap + ring2_h - d + insert_barrel_d(type);
module insert(type) { //! Draw specified insert
length = insert_length(type);
ring1_h = insert_ring1_h(type);
@@ -42,12 +51,12 @@ module insert(type) { //! Draw specified insert
chamfer1 = (insert_ring2_d(type) - insert_barrel_d(type)) / 2;
chamfer2 = (insert_ring3_d(type) - insert_barrel_d(type)) / 2;
ring2_h = ring1_h + chamfer1;
gap = (length - ring1_h - ring2_h- chamfer2) / 3;
gap = (length - ring1_h - ring2_h - chamfer2) / 3;
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type)));
$fn = 64;
thread_d = insert_screw_diameter(type);
explode(20, offset =[0, 0, -5]) translate_z(eps) vflip() {
explode(20, offset = [0, 0, -5]) translate_z(eps) vflip() {
r1 = thread_d / 2;
r2 = insert_barrel_d(type) / 2;
r3 = insert_ring3_d(type) / 2;
@@ -58,7 +67,7 @@ module insert(type) { //! Draw specified insert
h3 = ring1_h + gap + ring2_h;
h4 = ring1_h + gap + ring2_h + gap;
color(brass)
rotate_extrude()
rotate_extrude(convexity = 3)
polygon([
[r1, 0],
[r1, length],

View File

@@ -29,7 +29,7 @@
// d d h d d
// d
//
F1BM2 = [ "F1BM", 4.0, 3.6, 3.2, 2, 3.0, 1.0, 3.4, 3.1 ];
F1BM2 = [ "F1BM2", 4.0, 3.6, 3.2, 2, 3.0, 1.0, 3.4, 3.1 ];
F1BM2p5 = [ "F1BM2p5", 5.8, 4.6, 4.0, 2.5, 3.65, 1.6, 4.4, 3.9 ];
F1BM3 = [ "F1BM3", 5.8, 4.6, 4.0, 3, 3.65, 1.6, 4.4, 3.9 ];
F1BM4 = [ "F1BM4", 8.2, 6.3, 5.6, 4, 5.15, 2.3, 6.0, 5.55 ];

View File

@@ -29,7 +29,6 @@ include <zipties.scad>
use <wire.scad>
use <../utils/tube.scad>
MK4_heater = [ 12.76, 15.88, 8.22, (15.88 / 2 - 4.5), (12.76 / 2 - 0.5 - 2.5 / 2), (-15.88 / 2 + 5), 9.5, 3];
MK5_heater = [ 12.76, 12.76, 8.22, (12.76 / 2 - 3.75), (12.76 / 2 - 0.5 - 2.5 / 2), (-12.76 / 2 + 4), 8, 2];
function heater_width(type) = type[0];
@@ -71,7 +70,7 @@ module heater_block(type, resistor, thermistor) {
cone_start_r = nozzle_cone(type) / 2;
straight = 1;
nozzle_r = 0.4 / 2;
translate_z(-h / 2) vflip()
translate([nozzle_x(type), 0, -h / 2]) vflip()
rotate_extrude()
polygon([
[nozzle_r, 0],
@@ -86,7 +85,7 @@ module heater_block(type, resistor, thermistor) {
module jhead_hot_end(type, filament) {
resistor = RIE1212UB5C5R6;
thermistor = Epcos;
heater = type == JHeadMk4 ? MK4_heater : MK5_heater;
heater = MK5_heater;
insulator_length = hot_end_insulator_length(type);
inset = hot_end_inset(type);
@@ -106,7 +105,7 @@ module jhead_hot_end(type, filament) {
square([hot_end_insulator_diameter(type) / 2 - chamfer, insulator_length]);
}
square([3.2 / 2, insulator_length]);
square([(filament + 0.2) / 2, insulator_length]);
translate([hot_end_groove_dia(type) / 2, insulator_length - hot_end_inset(type) - hot_end_groove(type)])
square([100, hot_end_groove(type)]);
@@ -122,7 +121,7 @@ module jhead_hot_end(type, filament) {
module jhead_hot_end_assembly(type, filament, naked = false) { //! Assembly with resistor, thermistor, tape, sleaving and ziptie
resistor = RIE1212UB5C5R6;
thermistor = Epcos;
heater = type == JHeadMk4 ? MK4_heater : MK5_heater;
heater = MK5_heater;
insulator_length = hot_end_insulator_length(type);
inset = hot_end_inset(type);
@@ -139,7 +138,7 @@ module jhead_hot_end_assembly(type, filament, naked = false) { //! Assembly with
//
// silcone tape
//
if(!naked)
if(is_undef(naked) || !naked)
color("red")
if(exploded())
translate([0, max(hot_end_insulator_diameter(type) / 2, heater_length(heater) / 2 - nozzle_x(heater)),
@@ -157,7 +156,7 @@ module jhead_hot_end_assembly(type, filament, naked = false) { //! Assembly with
//
// Zip tie and heatshrink
//
if(!naked)
if(!naked && !is_undef(naked))
rotate(10) {
dia = hot_end_insulator_diameter(type);
scale([1, (bundle + dia) / dia])

View File

@@ -85,7 +85,8 @@ module meter(type, colour = "red", value = "888", display_colour = false) //! Dr
translate([0, meter_shunt_y(type), size.z])
vflip()
color("#b87333")
wire_link(shunt.y, shunt.x, shunt.z, tail = 2);
not_on_bom()
wire_link(shunt.y, shunt.x, shunt.z, tail = 2);
}
clearance = 0.1;

View File

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

View File

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

49
vitamins/magnet.scad Normal file
View File

@@ -0,0 +1,49 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Cylindrical and ring magnets.
//
include <../utils/core/core.scad>
function magnet_od(type) = type[1]; //! Outer diameter
function magnet_id(type) = type[2]; //! Inside diameter if a ring
function magnet_h(type) = type[3]; //! Height
function magnet_r(type) = type[4]; //! Corner radius
module magnet(type) { //! Draw specified magnet
od = magnet_od(type);
id = magnet_id(type);
h = magnet_h(type);
r = magnet_r(type);
//vitamin(str("magnet(", type[0], "): Magnet ", od, "mm diameter, ", h, "mm high", id ? str(", ", id, "mm bore") : "" ));
or = od / 2;
ir = id / 2;
color(silver)
rotate_extrude()
union() {
translate([ir, 0])
rounded_square([or - ir, h], r, center = false);
if(!ir)
square([r, h]);
}
}

30
vitamins/magnets.scad Normal file
View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Cylindrical and ring magnets.
//
// od, id, h, r
MAG8x4x4p2 = ["MAG8x4x4p2", 8, 4.2, 4, 0.5];
MAG484 = ["MAG484", inch(1/4), inch(1/8), inch(1/4), 0.5];
MAG5x8 = ["MAG484", 8, 0, 5, 0.5];
magnets = [MAG8x4x4p2, MAG484, MAG5x8];
use <magnet.scad>

View File

@@ -25,7 +25,7 @@
include <../utils/core/core.scad>
use <../utils/thread.scad>
pitch = 33.8;
pitch = 33.8 / 2;
width = 40;
depth = 18;
magnet = 4.3;
@@ -37,10 +37,16 @@ pole_l = 36;
poles = 15;
module opengrab_hole_positions() //! Position children at the screw positions
for(x = [-1, 1], y = [-1, 1])
translate([x * pitch / 2, y * pitch / 2, 0])
children();
let($d = 3.2)
for($x = [-pitch, pitch], $y = [-pitch, pitch])
translate([$x, $y])
children();
module opengrab_side_hole_positions() //! Position children at the two 4mm hole
let($d = 4, pitch = width / 2 - 3.5)
for($x = [-pitch, pitch])
translate([$x, 0])
children();
function opengrab_width() = width; //! Module width
function opengrab_depth() = depth; //! Module height
@@ -82,7 +88,7 @@ module opengrab() { //! Draw OpenGrab module
}
module opengrab_target() { //! Draw OpenGrab target
vitamin("opengrab_target(): OpenGrab silicon steel target plate");
vitamin("opengrab_target(): OpenGrab silicon steel target plate");
color(grey(80))
linear_extrude(target)
@@ -90,10 +96,9 @@ module opengrab_target() { //! Draw OpenGrab target
square([width, width], center = true);
opengrab_hole_positions()
circle(d = 3.2);
circle(d = $d);
for(side = [-1, 1])
translate([side * (width / 2 - 3.5), 0])
circle(d = 4);
opengrab_side_hole_positions()
circle(d = $d);
}
}

View File

@@ -53,6 +53,8 @@ function pcb_accessories(type) = type[12]; //! List of accessories to go on the
function pcb_grid(type) = type[13]; //! Grid if a perfboard
function pcb_polygon(type) = type[14]; //! Optional outline polygon for odd shaped boards
function pcb_screw(type, cap = hs_cap) = Len(type[15]) ? type[15] : find_screw(cap, screw_smaller_than(pcb_hole_d(type))); //! Mounting screw type
function pcb_size(type) = [pcb_length(type), pcb_width(type), pcb_thickness(type)]; //! Length, width and thickness in a vector
function pcb_grid_pos(type, x, y, z = 0) = //! Returns a pcb grid position
[-pcb_length(type) / 2 + pcb_grid(type).x + 2.54 * x,
@@ -331,8 +333,9 @@ function hdmi_height2(type) = type[6]; //! Inside height in the middle
function hdmi_height(type) = type[7]; //! Outside height above the PCB
function hdmi_thickness(type) = type[8]; //! Wall thickness of the metal
hdmi_full = [ "hdmi_full", "HDMI socket", 12, 14, 10, 3, 4.5, 6.5, 0.5 ];
hdmi_mini = [ "hdmi_mini", "Mini HDMI socket", 7.5, 10.5, 8.3, 1.28, 2.5, 3.2, 0.35 ];
hdmi_full = [ "hdmi_full", "HDMI socket", 12, 14, 10, 3, 4.5, 6.5, 0.5 ];
hdmi_mini = [ "hdmi_mini", "Mini HDMI socket", 7.5, 10.5, 8.3, 1.28, 2.5, 3.2, 0.35 ];
hdmi_micro = [ "hdmi_micro", "Micro HDMI socket", 8.5, 5.9, 4.43, 1.4, 2.3, 3, 0.3 ];
module hdmi(type, cutout = false) { //! Draw HDMI socket
vitamin(str("hdmi(", type[0], "): ", type[1]));
@@ -435,6 +438,39 @@ module usb_uA(cutout = false) { //! Draw USB micro A connector
}
}
module usb_C(cutout = false) { //! Draw USB C connector
l = 7.35;
w = 8.94;
h = 3.26;
t = 0.4;
flange_h = 3;
flange_w = 8;
module O()
translate([0, h / 2])
rounded_square([w, h], h / 2 - 0.5, center = true);
if(cutout)
rotate([90, 0, 90])
linear_extrude(100)
offset(2 * panel_clearance)
O();
else
color("silver") rotate([90, 0, 90]) {
linear_extrude(l, center = true)
difference() {
O();
offset(-t)
O();
}
translate_z(-l / 2)
linear_extrude(2.51)
O();
}
}
module usb_B(cutout = false) { //! Draw USB B connector
l = 16.4;
w = 12.2;
@@ -636,56 +672,52 @@ module flex(cutout = false) { //! Draw flexistrip connector
translate([0, -w / 2 + slot_offset + slot_w / 2])
square([slot_l, slot_w], center = true);
}
}
}
}
module flat_flex(cutout = false) { //! Draw flat flexistrip connector as used on RPI0
l1 = 17;
w1 = 1.4;
h1 = 1.2;
small_ff = [[11.8, 0.9], [17, 1.4, 1.2], [12, 1.6, 1.2], [16, 1.1, 1.2]];
large_ff = [[16, 1.25], [22, 1.5, 2.5], [16, 4.0, 2.5], [21, 0, 2.5]];
l2 = 15.4;
w2 = 1.6;
h2 = 1.0;
function ff_slot(type) = type[0]; //! Flat flex slot size
function ff_latch(type) = type[1]; //! Flat flex latch size
function ff_mid(type) = type[2]; //! Flat flex middle section size
function ff_back(type) = type[3]; //! Flat flex back section size
l3 = 16;
w3 = 1.1;
h3 = 1.2;
module flat_flex(type, cutout = false) { //! Draw flat flexistrip connector as used on RPI0
slot = ff_slot(type);
latch = ff_latch(type);
mid = ff_mid(type);
back = ff_back(type);
l4 = 12;
slot_l = 11.8;
slot_h = 0.9;
w = w1 + w2 + w3;
w = latch.y + mid.y + back.y;
if(cutout)
;
else {
color(grey(30)) {
translate([w / 2 - w1, 0, h1 / 2])
rotate([90, 0, 90])
linear_extrude(w1)
color(grey(30))
translate([0, w / 2 - latch.y])
rotate([90, 0, 180])
linear_extrude(latch.y)
difference() {
square([l1, h1], center = true);
translate([-latch.x / 2, 0])
square([latch.x, latch.z]);
translate([0, -h1 / 2])
square([slot_l, slot_h * 2], center = true);
square([slot.x, slot.y * 2], center = true);
}
}
color(grey(90)) {
translate([-w / 2 + w3 / 2, 0, h3 / 2])
cube([w3, l3, h3], center = true);
color("ivory") {
translate([-back.x / 2, -w / 2])
if(back.y)
cube(back);
translate([-w / 2 + w3 + w2 / 2, 0, h2 / 2])
cube([w2, l2, h2], center = true);
translate([-w / 2 + w3 + w2 / 2, 0, h3 / 2])
cube([w2, l4, h3], center = true);
translate([-mid.x / 2, -w / 2 + back.y])
cube(mid);
}
color(grey(80))
translate([-back.x / 2, -w / 2 + back.y + eps])
cube([back.x, mid.y - 2 * eps, mid.z - eps]);
}
}
@@ -883,7 +915,7 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
function param(n, default = 0) = len(comp) > n ? comp[n] : default;
rotate(comp.z) {
// Components that have a cutout parameter go in this section
if(show(comp, "2p54header")) pin_header(2p54header, comp[4], comp[5], param(6, false), false, cutouts, colour = param(7, undef));
if(show(comp, "2p54header")) pin_header(2p54header, comp[4], comp[5], param(6, false), param(8, false), cutouts, colour = param(7, undef));
if(show(comp, "2p54boxhdr")) box_header(2p54header, comp[4], comp[5], param(6, false), cutouts);
if(show(comp, "2p54socket")) pin_socket(2p54header, comp[4], comp[5], param(6, false), param(7, 0), param(8, false), cutouts, param(9, undef));
if(show(comp, "chip")) chip(comp[4], comp[5], comp[6], param(7, grey(30)), cutouts);
@@ -892,12 +924,14 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
if(show(comp, "usb_Ax2")) usb_Ax2(cutouts);
if(show(comp, "usb_uA")) usb_uA(cutouts);
if(show(comp, "usb_B")) usb_B(cutouts);
if(show(comp, "usb_C")) usb_C(cutouts);
if(show(comp, "jack")) jack(cutouts);
if(show(comp, "barrel_jack")) barrel_jack(cutouts);
if(show(comp, "hdmi")) hdmi(hdmi_full, cutouts);
if(show(comp, "mini_hdmi")) hdmi(hdmi_mini, cutouts);
if(show(comp, "micro_hdmi")) hdmi(hdmi_micro, cutouts);
if(show(comp, "flex")) flex(cutouts);
if(show(comp, "flat_flex")) flat_flex(cutouts);
if(show(comp, "flat_flex")) flat_flex(param(4, false) ? large_ff : small_ff, cutouts);
if(show(comp, "uSD")) uSD(comp[4], cutouts);
if(show(comp, "trimpot10")) trimpot10(param(4, false), cutouts);
if(show(comp, "molex_usb_Ax2")) molex_usb_Ax2(cutouts);
@@ -919,11 +953,13 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
if(show(comp, "led")) led(comp[4], comp[5], 2.6);
if(show(comp, "pdip")) pdip(comp[4], comp[5], param(6, false), param(7, inch(0.3)));
if(show(comp, "ax_res")) ax_res(comp[4], comp[5], param(6, 5), param(7, 0));
if(show(comp, "link")) wire_link(l = comp[4], h = param(5, 1), d = param(6, 0.8), tail = param(7, 3));
if(show(comp, "D_plug")) translate_z(d_pcb_offset(comp[4])) d_plug(comp[4], pcb = true);
if(show(comp, "molex_hdr")) molex_254(comp[4]);
if(show(comp, "jst_xh")) jst_xh_header(jst_xh_header, comp[4], param(5, false), param(6, "white"), param(7, undef));
if(show(comp, "potentiometer")) potentiometer(param(4, 5), param(5, 9));
if(show(comp, "buzzer")) buzzer(param(4, 9), param(5, 12), param(6, grey(20)));
if(show(comp, "smd_res")) smd_resistor(comp[4], comp[5]);
}
}
}

View File

@@ -217,6 +217,25 @@ RPI3 = ["RPI3", "Raspberry Pi 3", 85, 56, 1.4, 3, 2.75, 6, "green"
[": Micro SD card"],
[32.5 - 9.5 * 2.54, 52.5 - 1.27, 20, 2]];
RPI4 = ["RPI4", "Raspberry Pi 4", 85, 56, 1.4, 3, 2.75, 6, "green", false, [[3.5, 3.5], [61.5, 3.5], [61.5, -3.5], [3.5, -3.5]], [
[32.5, -3.5, 0, "2p54header", 20, 2],
[-6.5, 9, 0, "usb_Ax2"],
[-6.5, 27, 0, "usb_Ax2"],
[-8.5, 45.75, 0, "rj45"],
[ 4, 28, 90, "flex"],
[11.2, 3.675 - 1.6, -90, "usb_C"],
[ 26, 2.5, -90, "micro_hdmi"],
[39.5, 2.5, -90, "micro_hdmi"],
[46.5, 11.5, -90, "flex"],
[ 54, 6, -90, "jack"],
[ 29.25, 32.5, 0, "chip", 14, 14, 2.4],
[ 60, -22.3, 0, "chip", 9, 9, 0.6],
[7.75, 28, 180, "-uSD", [12, 11.5, 1.28]]
], [": Micro SD card"], [32.5 - 9.5 * 2.54, 52.5 - 1.27, 20, 2]
];
RPI0 = ["RPI0", "Raspberry Pi Zero", 65, 30, 1.4, 3, 2.75, 6, "green", false, [[3.5, 3.5], [-3.5, 3.5], [-3.5, -3.5], [3.5, -3.5]],
[//[32.5, -3.5, 0, "2p54header", 20, 2],
[25.5, 13, 0, "chip", 12, 12, 1.2],
@@ -224,7 +243,7 @@ RPI0 = ["RPI0", "Raspberry Pi Zero", 65, 30, 1.4, 3, 2.75, 6, "gre
[54, 2, -90, "usb_uA"],
[41.4, 2, -90, "usb_uA"],
[7.25, 16.7, 180, "uSD", [12, 11.5, 1.4]],
[-1.3, 15, 0, "flat_flex"],
[-1.3, 15, -90, "flat_flex"],
],
[": Micro SD card"],
[32.5 - 9.5 * 2.54, 26.5 - 1.27, 20, 2]];
@@ -391,7 +410,7 @@ RAMPSEndstop = ["RAMPSEndstop", "RAMPS Endstop Switch",
[]];
pcbs = [TP4056, MT3608, RAMPSEndstop, ExtruderPCB, PI_IO, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PSU12V1A, WD2002SJ, RPI3, DuetE, Duex2, Duex5, Melzi];
pcbs = [TP4056, MT3608, RAMPSEndstop, ExtruderPCB, PI_IO, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PSU12V1A, WD2002SJ, RPI3, RPI4, DuetE, Duex2, Duex5, Melzi];
perfboards = [PERF74x51, PERF70x50, PERF60x40, PERF70x30, PERF80x20];

View File

@@ -58,18 +58,20 @@ module pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cu
translate_z(smt ? 3.5 - h : 0) {
for(x = [0 : cols - 1], y = [0 : rows - 1]) {
translate([pitch * (x - (cols - 1) / 2), pitch * (y - (rows - 1) / 2), 0])
// Vertical part of the pin
translate([pitch * (x - (cols - 1) / 2), pitch * (y - (rows - 1) / 2)])
if(right_angle)
pin(type, hdr_pin_below(type) + width / 2 + (y - 0.5) * pitch);
pin(type, hdr_pin_below(type) + (y + 0.5) * pitch);
else
pin(type);
if(right_angle) {
w = hdr_pin_width(type);
// Horizontal part of the pin
rotate([-90, 0, 180])
translate([pitch * (x - (cols - 1) / 2), -pitch * (y - (rows - 1) / 2) -width / 2, hdr_pin_below(type) - (y - 0.5) * pitch])
translate([pitch * (x - (cols - 1) / 2), -pitch * (y - (rows - 1) / 2) - width / 2, hdr_pin_below(type) - (y - (rows - 1) / 2) * pitch])
pin(type, hdr_pin_length(type) - hdr_pin_below(type) + ra_offset + pitch / 2 + (y - 0.5) * pitch);
// corner
translate([pitch * (x - (cols - 1) / 2), pitch * (y - (rows - 1) / 2) - w / 2, pitch * (y - (rows - 1) / 2) + width / 2 - w / 2])
rotate([0, -90, 0])
color(hdr_pin_colour(type))
@@ -78,7 +80,8 @@ module pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cu
square(w);
}
}
translate([0, right_angle ? -ra_offset - pitch / 2 : 0, right_angle ? width / 2 : 0])
// Insulator
translate([0, right_angle ? -ra_offset - (rows - 1) * pitch / 2 : 0, right_angle ? width / 2 : 0])
rotate([right_angle ? 90 : 0, 0, 0])
color(base_colour)
linear_extrude(h)
@@ -176,7 +179,7 @@ module pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt
vitamin(str("pin_socket(", type[0], ", ", cols, ", ", rows, arg(right_angle, false, "right_angle"), arg(height, 0, "height"), arg(smt, false, "smt"),
"): Pin socket ", cols, " x ", rows, right_angle ? " right_angle" : ""));
color(base_colour)
translate([0, right_angle ? -ra_offset - pitch / 2 : 0, right_angle ? width / 2 : 0])
translate([0, right_angle ? -ra_offset - (rows - 1) * pitch / 2 : 0, right_angle ? width / 2 : 0])
rotate([right_angle ? 90 : 0, 0, 0])
translate_z(depth / 2)
linear_extrude(depth, center = true)
@@ -192,11 +195,11 @@ module pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt
for(x = [0 : cols - 1], y = [0 : rows -1]) {
if(!smt)
translate([pitch * (x - (cols - 1) / 2), pitch * (y - (rows - 1) / 2), 0])
pin(type, hdr_pin_below(type) + width / 2 + (y - 0.5) * pitch);
pin(type, hdr_pin_below(type) + (y + 0.5) * pitch);
if(right_angle) {
rotate([-90, 0, 0])
translate([pitch * (x - (cols - 1) / 2), -pitch * (y - (rows - 1) / 2) -width / 2, 0])
rotate([-90, 0, 180])
translate([pitch * (x - (cols - 1) / 2), -pitch * (y - (rows - 1) / 2) - width / 2, hdr_pin_below(type) - (y - (rows - 1) / 2) * pitch])
pin(type, hdr_pin_below(type) + (y - 0.5) * pitch);
w = hdr_pin_width(type);
@@ -210,7 +213,7 @@ module pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt
}
}
module jst_xh_header(type, pin_count, right_angle=false, colour, pin_colour) { //! Draw JST XH connector
module jst_xh_header(type, pin_count, right_angle = false, colour = false, pin_colour = false) { //! Draw JST XH connector
colour = colour ? colour : hdr_base_colour(type);
pin_colour = pin_colour ? pin_colour : hdr_pin_colour(type);
sizeY = 5.75;

View File

@@ -17,15 +17,15 @@
// If not, see <https://www.gnu.org/licenses/>.
//
// p p b p p b Socket depth
// i i e i i a
// t n l n n s
// c o e
// h l w w c
// c
// p p b p p b Socket depth
// i i e i i a
// t n l n n s
// c o e
// h l w w c
// c
//
2p54header = ["2p54header", 2.54, 11.6, 3.2, 0.66, "gold", grey(20), 8.5];
jst_xh_header = ["JST XH header",2.5,10,3.4, 0.64, "gold", grey(90), 7];
2p54header = ["2p54header", 2.54, 11.6, 3.2, 0.66, "gold", grey(20), 8.5];
jst_xh_header = ["JST XH header",2.5, 10, 3.4, 0.64, "gold", grey(90), 7];
pin_headers = [ 2p54header ];

View File

@@ -25,6 +25,7 @@ MGN5_carriage = [ 16, 9.6, 12, 6, 1.5, 0, 8 , M2_cap_screw ];
MGN7_carriage = [ 23, 14.3, 17, 8, 1.5, 8, 12, M2_cap_screw ];
MGN9_carriage = [ 29.7, 20.8, 20, 10, 2, 10, 15, M3_cap_screw ];
MGN12_carriage = [ 34.7, 21.7, 27, 13, 3, 15, 20, M3_cap_screw ];
MGN12H_carriage= [ 45.4, 32.4, 27, 13, 3, 20, 20, M3_cap_screw ];
MGN15_carriage = [ 43.3, 27.7, 32, 16, 4, 20, 25, M3_cap_screw ];
SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw ];
//
@@ -36,9 +37,10 @@ MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.5, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriag
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, MGN7_carriage, M2_cs_cap_screw ];
MGN9 = [ "MGN9", 9, 6, 7.5, 20, 6.0, 3.5, 3.5, M3_cap_screw, MGN9_carriage, M3_cs_cap_screw ];
MGN12= [ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12_carriage, M3_cs_cap_screw ];
MGN12H=[ "MGN12H",12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12H_carriage,M3_cs_cap_screw ];
MGN15= [ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, MGN15_carriage, M3_cs_cap_screw ];
SSR15= [ "SSR15", 15, 12.5,10, 60, 7.5, 4.5, 5.3, M4_cap_screw, SSR15_carriage, M4_cs_cap_screw ];
rails = [MGN5, MGN7, MGN9, MGN15, SSR15];
rails = [MGN5, MGN7, MGN9, MGN12, MGN12H, MGN15, SSR15];
use <rail.scad>

View File

@@ -175,12 +175,15 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
if(head_type == hs_dome) {
lift = 0.38;
h = head_height - lift;
r = min(2 * head_height, (sqr(head_rad) + sqr(h)) / 2 * h); // Special case for M2
y = sqrt(sqr(r) - sqr(head_rad));
color(colour) {
rotate_extrude() {
difference() {
intersection() {
translate([0, -head_height + lift])
circle(2 * head_height);
translate([0, -y + lift])
circle(r);
square([head_rad, head_height]);
}

View File

@@ -75,10 +75,11 @@ M5_cap_screw = ["M5_cap", "M5 cap", hs_cap, 5, 8.5, 5, 2.5, 4.0
M6_cap_screw = ["M6_cap", "M6 cap", hs_cap, 6, 10, 6, 3.3, 5.0, 24, M6_washer, M6_nut, M6_tap_radius, M6_clearance_radius];
M8_cap_screw = ["M8_cap", "M8 cap", hs_cap, 8, 13, 8, 4.3, 6.0, 28, M8_washer, M8_nut, M8_tap_radius, M8_clearance_radius];
M2_cs_cap_screw = ["M2_cs_cap","M2 cs cap", hs_cs_cap,2, 3.8, 0, 0.65,1.27,16, M2_washer, M2_nut, M2_tap_radius, M2_clearance_radius];
M2_cs_cap_screw = ["M2_cs_cap","M2 cs cap", hs_cs_cap,2, 3.8, 0, 0.65,1.3, 16, M2_washer, M2_nut, M2_tap_radius, M2_clearance_radius];
M3_cs_cap_screw = ["M3_cs_cap","M3 cs cap", hs_cs_cap,3, 6.0, 0, 1.05,2.0, 18, M3_washer, M3_nut, M3_tap_radius, M3_clearance_radius];
M4_cs_cap_screw = ["M4_cs_cap","M4 cs cap", hs_cs_cap,4, 8.0, 0, 1.49,2.5, 20, M4_washer, M4_nut, M4_tap_radius, M4_clearance_radius];
M2_dome_screw = ["M2_dome", "M2 dome", hs_dome, 2, 3.5, 1.3, 0.6, 1.3, 16, M2_washer, M2_nut, M2_tap_radius, M2_clearance_radius];
M3_dome_screw = ["M3_dome", "M3 dome", hs_dome, 3, 5.7, 1.65, 1.04,2.0, 18, M3_washer, M3_nut, M3_tap_radius, M3_clearance_radius];
M4_dome_screw = ["M4_dome", "M4 dome", hs_dome, 4, 7.6, 2.2, 1.3, 2.5, 20, M4_washer, M4_nut, M4_tap_radius, M4_clearance_radius];
@@ -106,14 +107,14 @@ No6_screw = ["No6", "No6 pan wood", hs_pan, 3.5, 6.7, 2.2, 0, 0
No6_cs_screw = ["No6_cs", "No6 cs wood", hs_cs, 3.5, 7.0, 0, 0, 0, 0, M4_washer, false, No6_pilot_radius, No6_clearance_radius];
screw_lists = [
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
[ 0, 0, M3_low_cap_screw],
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
[ 0, No2_screw, No4_screw, No6_screw, No6_cs_screw],
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
[ 0, No2_screw, No4_screw, No6_screw, No6_cs_screw],
[ 0, M2_cs_cap_screw,M3_cs_cap_screw, M4_cs_cap_screw],
[ 0, 0, M3_dome_screw, M4_dome_screw],
[ 0, 0, M3_grub_screw, M4_grub_screw]
[ 0, M2_dome_screw, M3_dome_screw, M4_dome_screw],
[ 0, 0, M3_grub_screw, M4_grub_screw]
];
use <screw.scad>

View File

@@ -29,7 +29,7 @@ function smd_led_lens(type) = type[2]; //! Lens length width and height
function smd_led_height(type) = //! Total height
smd_led_size(type).z + smd_led_lens(type).z;
function smd_100th(x) = //! Convert dimesion to 1/100" notation
function smd_100th(x) = //! Convert dimension to 1/100" notation
let(s = str(round(x / inch(0.01))))
len(s) < 2 ? str("0", s) : s;
@@ -78,3 +78,33 @@ module smd_led(type, colour, cutout) { //! Draw an SMD LED with specified ```col
}
}
}
function smd_res_size(type) = type[1]; //! Body length, width and height
function smd_res_end_cap(type) = type[2]; //! End cap width
function smd_res_power(type) = type[3]; //! Power rating in Watts
module smd_resistor(type, value) { //! Draw an SMD resistor with specified value
size = smd_res_size(type);
vitamin(str("smd_resistor(", type[0], ", ", value, "): SMD resistor ", smd_size(size), " ", value, " ", smd_res_power(type), "W"));
t = 0.04;
cap = smd_res_end_cap(type);
color("white")
translate_z(size.z / 2)
cube([size.x - 2 * t, size.y, size.z - 2 * t], center = true);
color(grey(20))
translate_z(size.z - t)
cube([size.x - 2 * cap, size.y, eps], center = true);
color(silver)
for(end = [-1, 1])
translate([end * (size.x / 2 - cap / 2), 0, size.z / 2])
cube([cap, size.y - 2 * eps, size.z], center = true);
color("white")
translate([0, 0, size.z])
linear_extrude(eps)
resize([(size.x - 2 * cap) * 0.75, size.y / 2])
text(value, halign = "center", valign = "center");
}

View File

@@ -18,11 +18,18 @@
//
//
//! Axial components
//! SMD components
//
LED0805 = ["LED0805", [2, 1.25, 0.46], [1.4, 1.25, 0.54]];
LED0603 = ["LED0603", [1.6, 0.8, 0.18], [1.0, 0.8, 0.42]];
LED0805 = ["LED0805", [2.0, 1.25, 0.46], [1.4, 1.25, 0.54]];
smd_leds = [LED0805];
smd_leds = [LED0603, LED0805];
RES0603 = ["RES0603", [1.6, 0.8, 0.45], 0.3, 1/10];
RES0805 = ["RES0805", [2.0, 1.2, 0.45], 0.4, 1/8];
RES1206 = ["RES1206", [3.1, 1.6, 0.6], 0.5, 1/4];
smd_resistors = [RES0603, RES0805, RES1206];
use <smd.scad>

View File

@@ -27,7 +27,9 @@ function tubing_od(type) = type[2]; //! Outside diameter
function tubing_id(type) = type[3]; //! Inside diameter
function tubing_colour(type) = type[4]; //! Colour
module tubing(type, length = 15, forced_id = 0) { //! Draw specified tubing with optional forced internal diameter
function tubing_or(type) = tubing_od(type) / 2; //! Outside radius
module tubing(type, length = 15, forced_id = 0, center = true) { //! Draw specified tubing with optional forced internal diameter
original_od = tubing_od(type);
original_id = tubing_id(type);
id = forced_id ? forced_id : original_id;
@@ -37,7 +39,7 @@ module tubing(type, length = 15, forced_id = 0) { //! Draw specified tubing with
else
vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " OD ", original_od, "mm ID ", original_id,"mm x ",length, "mm"));
color(tubing_colour(type))
linear_extrude(length, center = true, convexity = 4)
linear_extrude(length, center = center, convexity = 4)
difference() {
circle(d = od);
circle(d = id);

View File

@@ -20,20 +20,21 @@
//
// Tubing and sleeving
//
tubing_colour = [0.8, 0.8, 0.8, 0.75 ];
PVC64 = ["PVC64", "PVC aquarium tubing", 6, 4, tubing_colour];
PVC85 = ["PVC85", "PVC aquarium tubing", 8, 5, tubing_colour];
PVC64 = ["PVC64", "PVC aquarium tubing", 6, 4, [0.8, 0.8, 0.8, 0.75 ]];
PVC85 = ["PVC85", "PVC aquarium tubing", 8, 5, [0.8, 0.8, 0.8, 0.75 ]];
NEOP85 = ["NEOP85", "Neoprene tubing", 8, 5, [0.2,0.2,0.2]];
PTFE07 = ["PTFE07", "PTFE sleeving", 1.2, 0.71, tubing_colour];
PTFE20 = ["PTFE20", "PTFE sleeving", 2.6, 2, tubing_colour];
PF7 = ["PF7", "PTFE tubing", 46/10, 3.84, tubing_colour];
PTFE07 = ["PTFE07", "PTFE sleeving", 1.2, 0.71, [0.95, 0.95, 0.95, 0.9]];
PTFE20 = ["PTFE20", "PTFE sleeving", 2.6, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE2_4 = ["PTFE2_4", "PTFE tubing", 4, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE2_3 = ["PTFE2_3", "PTFE tubing", 3, 2, [0.95, 0.95, 0.95, 0.9]];
PTFE4_6 = ["PTFE4_6", "PTFE tubing", 6, 4, [0.95, 0.95, 0.95, 0.9]];
PF7 = ["PF7", "PTFE tubing", 46/10, 3.84, [0.95, 0.95, 0.95, 0.9]];
HSHRNK16 = ["HSHRNK16", "Heatshrink sleeving", 2.0, 1.6, "grey"];
HSHRNK24 = ["HSHRNK24", "Heatshrink sleeving", 2.8, 2.4, "grey"];
HSHRNK32 = ["HSHRNK32", "Heatshrink sleeving", 3.6, 3.2, "grey"];
HSHRNK64 = ["HSHRNK64", "Heatshrink sleeving", 6.8, 6.4, "grey"];
HSHRNK100 = ["HSHRNK100", "Heatshrink sleeving",10.4, 10.0, [0.2,0.2,0.2]];
tubings = [PVC64, PVC85, NEOP85, PTFE07, PTFE20, PF7, HSHRNK16, HSHRNK24, HSHRNK64, HSHRNK100];
tubings = [PVC64, PVC85, NEOP85, PTFE07, PTFE20, PF7, PTFE2_3, PTFE2_4, PTFE4_6, HSHRNK16, HSHRNK24, HSHRNK64, HSHRNK100];
use <tubing.scad>

View File

@@ -132,8 +132,12 @@ module veroboard(type) { //! Draw specified veroboard with missing tracks and tr
module vero_components(type, cutouts = false, angle = undef)
for(comp = vero_components(type))
vero_grid_pos(type, comp.x, comp.y)
translate_z(vero_thickness(type))
pcb_component(comp, cutouts, angle);
if(comp[3][0] == "-")
vflip()
pcb_component(comp, cutouts, angle);
else
translate_z(vero_thickness(type))
pcb_component(comp, cutouts, angle);
module vero_cutouts(type, angle = undef) vero_components(type, true, angle); //! Make cutouts to clear components

View File

@@ -50,7 +50,7 @@ module mouse_hole(cable, h = 100, teardrop = false) { //! A mouse hole to allow
r = wire_hole_radius(cable);
if(teardrop)
vertical_tearslot(r = r, l = 2 * r, h = h);
vertical_tearslot(r = r, l = 2 * r, h = h, plus = true);
else
rotate(90)
slot(r, 2 * r, h = h);