diff --git a/lib.scad b/lib.scad index 81257ec..eab0bac 100644 --- a/lib.scad +++ b/lib.scad @@ -84,6 +84,7 @@ use use use use +use use use use diff --git a/readme.md b/readme.md index a6d4457..3aede3a 100644 --- a/readme.md +++ b/readme.md @@ -22,19 +22,19 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa Ball_bearings KP_pillow_blocks Ring_terminals Butt_box Bezier Clip Batteries LDRs Rockers Cable_grommets Dogbones Global Belts LED_meters Rod Carriers Fillet Polyholes - Blowers LEDs SCS_bearing_blocks Corner_block Hanging_hole Rounded_rectangle - Bulldogs Leadnuts SK_brackets Door_hinge Layout Sphere - Buttons Light_strips SMDs Door_latch Maths Teardrops - Cable_strips Linear_bearings SSRs Fan_guard Offset - Cameras Mains_sockets Screws Fixing_block Quadrant - Circlips Microswitches Sealing_strip Flat_hinge Round - Components Microview Sheets Foot Rounded_cylinder - DIP Modules Spades Handle Rounded_polygon - D_connectors Nuts Spools PCB_mount Sector - Displays O_ring Springs PSU_shroud Sweep - Extrusion_brackets Opengrab Stepper_motors Printed_box Thread - Extrusions PCB Swiss_clips Ribbon_clamp Tube - Fans PCBs Toggles SSR_shroud + Blowers LEDs SCS_bearing_blocks Corner_block Gears Rounded_rectangle + Bulldogs Leadnuts SK_brackets Door_hinge Hanging_hole Sphere + Buttons Light_strips SMDs Door_latch Layout Teardrops + Cable_strips Linear_bearings SSRs Fan_guard Maths + Cameras Mains_sockets Screws Fixing_block Offset + Circlips Microswitches Sealing_strip Flat_hinge Quadrant + Components Microview Sheets Foot Round + DIP Modules Spades Handle Rounded_cylinder + D_connectors Nuts Spools PCB_mount Rounded_polygon + Displays O_ring Springs PSU_shroud Sector + Extrusion_brackets Opengrab Stepper_motors Printed_box Sweep + Extrusions PCB Swiss_clips Ribbon_clamp Thread + Fans PCBs Toggles SSR_shroud Tube Fuseholder PSUs Transformers Screw_knob Geared_steppers Panel_meters Tubings Socket_box Green_terminals Pillars Variacs Strap_handle @@ -5221,6 +5221,44 @@ Rounded fillet for adding to corners. ![fillet](tests/png/fillet.png) +Top + +--- + +## Gears +Utilities for making involute gears. + +Formulas from +and + +```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D. +Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```. + +Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered +the practical minimum. + +The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter. + + +[utils/gears.scad](utils/gears.scad) Implementation. + +[tests/gears.scad](tests/gears.scad) Code for this example. + +### Functions +| Function | Description | +|:--- |:--- | +| ```centre_distance(m, z1, z2, pa)``` | Calculate distance between centres taking profile shift into account | +| ```involute(r, u)``` | Involute of circle radius r at angle u in radians | +| ```profile_shift(z, pa)``` | Calculate profile shift for small gears | + +### Modules +| Module | Description | +|:--- |:--- | +| ```involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20)``` | Calculate profile given module, number of teeth and pressure angle | + +![gears](tests/png/gears.png) + + Top --- diff --git a/tests/gears.scad b/tests/gears.scad new file mode 100644 index 0000000..1bb2aeb --- /dev/null +++ b/tests/gears.scad @@ -0,0 +1,58 @@ +// +// NopSCADlib Copyright Chris Palmer 2020 +// nop.head@gmail.com +// hydraraptor.blogspot.com +// +// This file is part of NopSCADlib. +// +// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +// GNU General Public License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with NopSCADlib. +// If not, see . +// +include <../utils/core/core.scad> +use <../utils/gears.scad> + +// left gear teeth +z1 = 39; // [7 : 1 : 99] + +// Right gear teeth +z2 = 7; // [7 : 1 : 99] + +// Modulus +m = 2.0; // [0.1 : 0.1 : 5.0] + +// Pressure angle +pa = 20; // [14.5, 20, 22.5, 25] + +$show_numbers = false; + +module gears() { + color(pp1_colour) + rotate($t * 360) + linear_extrude(eps, center = true, convexity = z1) + difference() { + involute_gear_profile(m, z1, pa); + + circle(r = m * z1 / 10); + } + + color(pp2_colour) + translate([centre_distance(m, z1, z2, pa), 0]) + rotate(180 + 180 / z2 + -$t * 360 * z1 / z2) + linear_extrude(eps, center = true, convexity = z2) + difference() { + involute_gear_profile(m, z2, pa); + + circle(r = m * z2 / 10); + } +} + +rotate(is_undef($bom) ? 0 : [70, 0, 315]) + gears(); diff --git a/tests/png/gears.png b/tests/png/gears.png new file mode 100644 index 0000000..07d3aa9 Binary files /dev/null and b/tests/png/gears.png differ diff --git a/utils/gears.scad b/utils/gears.scad new file mode 100644 index 0000000..7502cd1 --- /dev/null +++ b/utils/gears.scad @@ -0,0 +1,96 @@ +// +// NopSCADlib Copyright Chris Palmer 2020 +// nop.head@gmail.com +// hydraraptor.blogspot.com +// +// This file is part of NopSCADlib. +// +// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +// GNU General Public License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with NopSCADlib. +// If not, see . +// + +// +//! Utilities for making involute gears. +//! +//! Formulas from +//! and +//! +//! ```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D. +//! Helical gears can be made using ```twist``` and bevel gears using ```scale``` parameters of ```linear_extrude()```. +//! +//! Gears with less than 19 teeth (when pressure angle is 20) are profile shifted to avoid undercutting the tooth root. 7 teeth is considered +//! the practical minimum. +//! +//! The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter. +// +include +use + +function involute(r, u) = let(a = degrees(u), c = cos(a), s = sin(a)) r * [c + u * s, s - u * c]; //! Involute of circle radius r at angle u in radians + +function profile_shift(z, pa) = max(1 - z * sqr(sin(pa)) / 2, 0); //! Calculate profile shift for small gears + +function centre_distance(m, z1, z2, pa) = //! Calculate distance between centres taking profile shift into account + let(x1 = profile_shift(z1, pa), x2 = profile_shift(z2, pa)) m * (z1/2 + z2/2 + x1 + x2); + +module involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20) { //! Calculate profile given module, number of teeth and pressure angle + assert(z >= 7, "Gears must have at least 7 teeth."); + d = m * z; // Reference pitch circle diameter + x = profile_shift(z, pa); // Profile shift + c = is_undef(clearance) ? m / 6 : clearance; // Clearance from tip to root + + base_d = d * cos(pa); // Base diameter + root_r = d / 2 + m * (x - 1) - c; // Root radius (dedendum circle radius) + tip_d = d + 2 * m * (1 + x); // Tip diameter (addendum circle diameter) + tpa = acos(base_d / tip_d); // Tip pressure angle + inva = tan(pa) - radians(pa); // Involute alpha + invaa = tan(tpa) - radians(tpa); // Involute alphaa + ta = PI / (2 * z) + 2 * x * tan(pa) / z + inva - invaa; // Tooth tip thickness angle, radians + crest_w = ta * tip_d; // Crest width + umax = sqrt(sqr(tip_d / base_d) - 1); // Max value of the involute parameter + + base_r = base_d / 2; + p1 = involute(base_r, 0); + p2 = involute(base_r, umax); + dist = norm(p2 - p1); // distance between beginning and end of the involute curve + + base_angle = 2 * acos((sqr(base_r) + sqr(tip_d / 2) - sqr(dist)) / base_r / tip_d) + degrees(2 * ta); + root_angle = 360 / z - base_angle; + root_circle_r = base_r * sin(root_angle / 2); + + if(!is_undef($show_numbers) && $show_numbers) { + echo(d=d); + echo(base_d=base_d); + echo(tip_d=tip_d); + echo(tpa = tpa); + echo(inva=inva); + echo(invaa=invaa); + echo(x=x); + echo(ta=ta); + echo(crest_w=crest_w); + echo(umax = umax); + echo(base_angle=base_angle); + echo(root_angle=root_angle); + } + involute = [for(i = [0 : steps], u = umax * i / steps) involute(base_r, u)]; // involute for the bottom side of the tooth + truncated = [for(p = involute) if((rot2_z(-base_angle / 2) * p).y <= 0) p]; // removed any above the centreline to prevent overlap + reflection = reverse([for(p = truncated) rot2_z(base_angle) * [p.x, -p.y] ]); // reflect and rotate to make the top edge + + root = reverse([for(a = [90 : 180 / steps : 270]) rot2_z(base_angle + root_angle / 2) * ([base_r, 0] + root_circle_r * [cos(a), sin(a)]) ]); + tooth = concat(truncated, reflection, root); + gear = concat([for(i = [0 : z - 1], p = tooth) rot2_z(i * 360 / z) * p]); + rotate(-base_angle / 2) + union() { + polygon(gear); + + circle(root_r); + } +}