// NOTE regarding Patents: Since 1977 the LEGO Group has produced "Technic" // elements with gear teeth, axles, axle-holes, and other features closely // resembling the design(s) in this file, as part of their "Expert Builder" // and "Technical Sets", now called "Technic" (see for example set 961, // peeron.com/inv/sets/961-1?showpic=9288 ). By 1989 they had added pieces // with rounded ends (see peeron.com/inv/sets/5264-1?showpic=8542 (set 5264 // from 1987) and peeron.com/inv/sets/5110-2?showpic=8543 (set 5110 from 1989)) // The object(s) produced by this SCAD file are different from real LEGO(r) // elements, and any similarities of features, such as the shapes of axles // and axle-holes, are functional in nature. The functions in question // resemble those in LEGO patents that have already expired (or, if not // patented, became prior art when the product(s) became available for // purchase, i.e. 1989 at the latest). Nevertheless, one must not infringe // on non-expired patents and any non-patent rights, such as LEGO(r) // trademarks and brand identity. An example of such infringement would be // to make objects and then try to "pass them off" as LEGO products. See // for example the Kirkbi AG v. Ritvik Holdings Inc. case, (Supreme Court of // Canada [2005] 3 S.C.R. 302). // Contains some code from thing 29989 by bjepson on Thingiverse, thing 40410 // by Robert Munafo, and MCAD library. myGear() from 40410 is here, but with // different (better) involute gear teeth shape, and with some tweaks to make // better gears without degenerate faces. // // Everything other is (c)oded by me, Vitaliy Filippov. License is GNU LGPL2.1+ // // Also I HIGHLY recommend to build OpenSCAD from my fork: github.com/vitalif/openscad, // because there's a patch that makes OpenSCAD to use Delaunay triangulation which // greatly improves the resulting model quality. // Standard LEGO dimensions: // Stud spacing = 8mm // Studded beam height = 9.6mm // Most beams, mounts and etc are 7.2mm thick in cross direction (i.e. beam is 8mm x 7.2mm, half-bush has 7.2mm radius etc) // Hole diameter (ideal) = 4.8mm // Hole diameter (for FDM printing) = 5.0-5.1mm // Pin holes (on beams etc) have ending notches that are 0.8mm deep and 3mm in radius (i.e. diameter is 6mm) // 0.8mm thick are also various borders like ones on the end of a full bush // Inner bush diameter = 5.7mm // Axle diameter = 4.6mm // Axle mesh thickness = 1.7mm // Screw gear outer radius = 9.8mm // Thickness of normal (non-bevel) gear wheels is 3.8mm // Standard 40t gear: root_radius=18.75 outer_radius=20.85 (mm_per_tooth =~ 3.1 by root) // Standard 24t gear: root_radius=10.7 outer_radius=12.8 (mm_per_tooth =~ 3.06 by root) // Standard 16t gear: root_radius=6.8 outer_radius=8.7 (mm_per_tooth =~ 3.05 by root) // Standard 8t gear: root_radius=2.8 outer_radius=4.9 (mm_per_tooth =~ 3.05 by root) // Standard 12t bevel gear: 12.7mm bottom diameter, 1.6mm top teeth length, 10.6mm top teeth outer diameter, 7.7mm top teeth root diameter, 2.5mm gear height + 0.5mm flat base + 1mm spacer at bottom // Standard 20t idler bevel gear: 20.4mm bottom diameter, 18.4mm top teeth outer diameter, 1.8mm top teeth length, 15.6mm top teeth root diameter // Standard 36t double bevel gear: 37.2mm teeth outer diameter, 31.6mm teeth root diameter, 2.5mm central non-bevel part thickness, 7.2mm total thickness // Formulas for gear radiuses: //outer_radius = mm_per_tooth*(n_teeth/2+1)/3.1415926 - clearance; //root_radius = mm_per_tooth*(n_teeth/2-1)/3.1415926; HOLE_RADIUS = 2.5; HOLE_RING_HEIGHT = 0.9; //------------------------------------------- // Overview of this file //------------------------------------------- /* 32-teeth planetary assembly */ /*rotate([0, 0, 10]) translate([0, 0, 0.9]) ring_gear_2u_32t(); translate([0, 0, 8.1]) satellites_32t(); translate([0, 0, 16+7.2]) color([0.5, 1, 1, 1]) rotate([180, 0, 0]) carrier_32t_easy(); translate([0, 0, -8]) color([0.5, 1, 0.5, 1]) sun_drive_32t(); translate([20, 0, 0]) color([1, 0.5, 0.5, 1]) rotate([0, 0, -19]) std_gear8(); translate([20, 0, -8]) color([1, 0.5, 0.5, 1]) rotate([0, 0, -22.5]) std_gear8(); translate([20, 0, 16]) color([1, 0.5, 0.5, 1]) rotate([0, 0, -22.5]) std_gear8();*/ /* (experiment) 1-stud thick variant of 32-teeth ring gear */ //ring_gear_1u_32t(); //ring_gear_2u_32t(); //carrier_32t_easy(); //carrier_32t_not_so_easy(); //sun_drive_32t(); //sun_drive_32t_simpler(); double_bevel_36t(); /* Standard 8-teeth gear */ //std_gear8(); /* 40-teeth (both inside and outside) planetary ring gear */ //rotate([180, 0, 0]) planetary_ring_gear(plane_height=1); /* Solid clutch gear, like standard 16-teeth */ //clutchGear(32); /* Gear with clutch fully offset to one side - useful for compact gearbox because allows to make clutch gears smaller than 16t */ //offsetClutchGear(9, gear_height=4); //offsetClutchGear(23, gear_height=3.8); /* Solid gear fully offset to one side */ //offsetGear(number_of_teeth=8, gear_height=3.8); /* Sample offset gear with 28 teeth and 4 holes */ //gear28_4holes(); /* Gear with offset teeth, axle hole and sparse body */ //offsetGearSparse(20, gear_height=3.8, jaggy=1); /* Half-stud parametric gear with some holes */ //myGear(16); /* Generic gear with involute teeth */ //gear(mm_per_tooth=3.05, number_of_teeth=16, thickness=4, pressure_angle=20); /* Same, but using an experimental OpenSCAD feature - vector concat() function */ //gear_concat(mm_per_tooth=3.05, number_of_teeth=24, thickness=3.8); //------------- module sun_drive_32t() { root = 3.06*(32/2-1)/3.1415926; segments = 32*2; // so gear teeth edge never match cylinder segment edges difference() { union() { translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, pressure_angle=20); cylinder($fn=100, h=7.2, r=root); cylinder($fn=100, h=8, r=3.6); } rotate([0, 0, 45]) axleCut(0, 0, -0.2, 10); translate([-8, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([0, -8, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([0, 8, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([8, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([-8, 0, -0.1]) cylinder($fn=32, h=1+0.1, r=3); translate([0, -8, -0.1]) cylinder($fn=32, h=1+0.1, r=3); translate([0, 8, -0.1]) cylinder($fn=32, h=1+0.1, r=3); translate([8, 0, -0.1]) cylinder($fn=32, h=1+0.1, r=3); } } module sun_drive_32t_simpler() { root = 3.06*(32/2-1)/3.1415926; segments = 32*2; // so gear teeth edge never match cylinder segment edges union() { difference() { union() { gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=7.2, pressure_angle=20); difference() { cylinder($fn=32*2, h=7.2, r=root); translate([0, 0, 1]) cylinder($fn=32*2, h=7.1, r=root-2); } cylinder($fn=100, h=8, r=1.95+2); union() { translate([-1, -root+0.5, 0.8]) cube(size=[2, root*2-1, 6.4]); rotate([0, 0, 90]) translate([-1, -root+0.5, 0.8]) cube(size=[2, root*2-1, 6.4]); } } rotate([0, 0, 45]) axle(0, 0, -0.2, 10); } } } // Symmetric planetary carrier gear (not so easy to print because it needs support) module carrier_32t_not_so_easy() { root = 3.1*(32/2-1)/3.1415926; fn = 32*2; // so gear teeth edge never match cylinder segment edges difference() { union() { translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.1, number_of_teeth=32, thickness=4, pressure_angle=20); translate([0, 0, HOLE_RING_HEIGHT]) cylinder($fn=fn, r=root, h=8-2*HOLE_RING_HEIGHT); cylinder($fn=32, r=HOLE_RADIUS+1.2, h=8); } translate([0, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([-8, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([0, -8, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([0, 8, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([8, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); } } // Easy to print planetary carrier gear module carrier_32t_easy() { root = 3.1*(32/2-1)/3.1415926; fn = 32*2; // so gear teeth edge never match cylinder segment edges difference() { union() { gear_teeth(mm_per_tooth=3.1, number_of_teeth=32, thickness=8-2*HOLE_RING_HEIGHT, pressure_angle=20); cylinder($fn=fn, r=root, h=8-2*HOLE_RING_HEIGHT); cylinder($fn=32, r=HOLE_RADIUS+1.2, h=8-HOLE_RING_HEIGHT); // 1.2 = 0.4(nozzle)*3 perimeters } translate([0, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([-8, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([0, -8, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([0, 8, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); translate([8, 0, -0.2]) cylinder($fn=32, h=10, r=HOLE_RADIUS); } } module carrier_32t() { root = 3.06*(32/2-1)/3.1415926; segments = 32*2; // so gear teeth edge never match cylinder segment edges difference() { union() { difference() { translate([0, 0, 2]) gear_teeth(mm_per_tooth=3.06, number_of_teeth=32, thickness=4, pressure_angle=20); cylinder($fn=100, h=8, r=root-0.5); } difference() { translate([0, 0, 0.8]) cylinder($fn=32*2, h=7.2, r=root); translate([0, 0, -0.1]) cylinder($fn=32*2, h=7.3, r=root-1); translate([0, 0, 7.2-0.1]) cylinder($fn=32*2, h=1, r=3.06*(24/2)/3.1415926); } translate([0, 0, 3.5]) cylinder($fn=32*2, h=1, r=root-0.5); cylinder($fn=100, h=8, r=3.5); difference() { union() { translate([-8, 0, 0]) cylinder($fn=32*2, h=8, r=3.5); translate([0, -8, 0]) cylinder($fn=32*2, h=8, r=3.5); translate([0, 8, 0]) cylinder($fn=32*2, h=8, r=3.5); translate([8, 0, 0]) cylinder($fn=32*2, h=8, r=3.5); translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]); rotate([0, 0, 90]) translate([-0.5, -root+0.5, 0]) cube(size=[1, root*2-1, 8]); } translate([-20, -20, 8-0.8]) cube(size=[40, 40, 1]); translate([-20, -20, -0.2]) cube(size=[40, 40, 1]); } } translate([-8, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.5); translate([0, -8, -0.2]) cylinder($fn=32*2, h=10, r=2.5); translate([0, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.5); translate([0, 8, -0.2]) cylinder($fn=32*2, h=10, r=2.5); translate([8, 0, -0.2]) cylinder($fn=32*2, h=10, r=2.5); } } // Most compact planetary ring gear: 1 unit thick, 32 teeth outside, 24 teeth inside module ring_gear_1u_32t() { difference() { gear(mm_per_tooth=3.06, number_of_teeth=32, thickness=7.8, pressure_angle=20); translate([0, 0, 1.7]) gear(mm_per_tooth=3.28, number_of_teeth=24, thickness=4.4, pressure_angle=20); translate([0, 0, -0.1]) cylinder($fn=32*2, h=8.2, r=3.28*(24/2-1)/3.1415926); } } // Solid easy-to-print 2U 32T ring gear, with mounting holes // Print with 0.1mm layer, 300% first layer and 1 perimeter module ring_gear_2u_32t() { fn = 32*2; difference() { union() { // 0.9mm spacing (skipped) + 6.2mm outer gear + 1mm spacing // + 6.9mm inner gear + 1mm spacing (skipped) gear_teeth(mm_per_tooth=3.1, number_of_teeth=32, thickness=6.2, pressure_angle=20); cylinder($fn=fn, h=14.1, r=3.1*(32/2-1)/3.1415926); } translate([0, 0, 6.2]) difference() { // inner gear radius should be 26.4mm, but we make it slightly bigger gear(mm_per_tooth=3.22, number_of_teeth=24, thickness=10, pressure_angle=20); cylinder($fn=fn, h=1, r=HOLE_RADIUS+1.2); } translate([0, 0, -0.1]) cylinder($fn=fn, h=20, r=HOLE_RADIUS); // holes translate([0, -8, -0.1]) cylinder($fn=fn, h=20, r=HOLE_RADIUS); translate([0, 8, -0.1]) cylinder($fn=fn, h=20, r=HOLE_RADIUS); translate([-8, 0, -0.1]) cylinder($fn=fn, h=20, r=HOLE_RADIUS); translate([8, 0, -0.1]) cylinder($fn=fn, h=20, r=HOLE_RADIUS); } } // Satellites and sun gear for 32t ring gear module satellites_32t() { color([1, 0.5, 0.5, 1]) rotate([0, 0, -5]) std_gear8(); color([0.5, 0.5, 1, 1]) translate([8, 0, 0]) rotate([0, 0, 30]) std_gear8(); color([0.5, 0.5, 1, 1]) translate([-8, 0, 0]) rotate([0, 0, 30]) std_gear8(); color([0.5, 0.5, 1, 1]) translate([0, 8, 0]) rotate([0, 0, 30]) std_gear8(); color([0.5, 0.5, 1, 1]) translate([0, -8, 0]) rotate([0, 0, 30]) std_gear8(); } //------------- // An attempt to make something like standard 36t double bevel gear... module double_bevel_36t() { intersection() { union() { translate([0, 0, 1.5]) linear_extrude(slices=5, height=2.5, scale=(36/2+1-2.5*tan(45))/(36/2+1)) gear_concat_flat(mm_per_tooth=3.53, number_of_teeth=36, backlash=2, clearance=0.8, trim_factor=0.7); translate([0, 0, -1.5]) rotate([180, 0, 0]) linear_extrude(slices=5, height=2.5, scale=(36/2+1-2.5*tan(45))/(36/2+1)) gear_concat_flat(mm_per_tooth=3.53, number_of_teeth=36, backlash=2, clearance=0.8, trim_factor=0.7); translate([0, 0, -4]) cylinder($fn=48, h=8, r=3.14*(36/2-1)/3.1415926); translate([0, 0, -1.5]) cylinder($fn=48, h=3, r=3.14*(36/2+1)/3.1415926); } translate([0, 0, -8]) linear_extrude(slices=5, height=16) gear_concat_flat(mm_per_tooth=3.14, number_of_teeth=36); } } //------------- // An attempt to make something like standard 20t bevel gear... module bevel_20t() { difference() { union() { translate([0, 0, 1.5]) linear_extrude(slices=5, height=2.5, scale=(20/2+1-2.5*tan(45))/(20/2+1), twist=0) gear_concat_flat(mm_per_tooth=3.53, number_of_teeth=20, backlash=2, clearance=0.8, trim_factor=0.7); cylinder($fn=48, h=1.5, r=3.53*(20/2-1)/3.1415926); cylinder($fn=48, h=4, r=3.53*(20/2-1)/3.1415926*(20/2+1-2.5*tan(45))/(20/2+1)); } translate([0, 0, -0.1]) difference() { cylinder($fn=48, h=8, r=100); translate([0, 0, -0.1]) cylinder($fn=48, h=8.2, r=3.53*(20/2-1)/3.1415926); } axle(0, 0, -0.2, 10); } } // An attempt to make something like standard 12t bevel gear... module bevel_12t() { difference() { union() { translate([0, 0, 1.5]) linear_extrude(slices=5, height=2.5, scale=(12/2+1-2.5*tan(45))/(12/2+1), twist=0) gear_concat_flat(mm_per_tooth=3.76, number_of_teeth=12, backlash=1, clearance=0.4, trim_factor=0.75); cylinder($fn=48, h=1.5, r=3.76*(12/2-1)/3.1415926); cylinder($fn=48, h=4, r=3.76*(12/2-1)/3.1415926*(12/2+1-2.5*tan(45))/(12/2+1)); } translate([0, 0, -0.1]) difference() { cylinder($fn=48, h=8, r=10); translate([0, 0, -0.1]) cylinder($fn=48, h=8.2, r=3.76*(12/2-1)/3.1415926); } axle(0, 0, -0.2, 10); } } // Standard 8-teeth gear module std_gear8() { difference() { union() { cylinder($fn=50, h=8, r=3.05*(8/2-1)/3.1415926); translate([0, 0, 2.1]) gear(mm_per_tooth=3.05, number_of_teeth=8, thickness=3.8, pressure_angle=20); } axle(0, 0, -1, 10); }} // Planetary ring gear, 2 stud thick module planetary_ring_gear() { difference() { union() { cylinder($fn=80, h=8, r=(1.2+3.28*(40/2+1)/3.1415926)); translate([0, 0, 8]) cylinder($fn=80, h=2, r=(3.1*(40/2+1)/3.1415926)); translate([0, 0, 10]) gear(mm_per_tooth=3.1, number_of_teeth=40, thickness=4, pressure_angle=20); translate([0, 0, 13]) cylinder($fn=80, h=2.2, r=(3.1*(40/2-1)/3.1415926)); translate([0, 0, 8]) cylinder($fn=40, h=8, r=HOLE_RADIUS+1.2); } translate([0, 0, -0.1]) gear(mm_per_tooth=3.28, number_of_teeth=40, thickness=7.2+0.1, pressure_angle=20); difference() { translate([0, 0, 7.2-0.1]) cylinder($fn=80, h=0.9, r=(3.28*(40/2-1)/3.1415926)-1); translate([0, 0, 7.2-0.2]) cylinder($fn=50, h=1, r=HOLE_RADIUS+1.2); } translate([-8, -8, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([-8, 0, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([-8, 8, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([0, -8, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([0, 0, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([0, 8, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([8, -8, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([8, 0, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); translate([8, 8, 0]) cylinder($fn=50, h=20, r=HOLE_RADIUS); } } // Example 28-teeth offset gear with 4 pin holes module gear28_4holes() { difference() { offsetGear(28, 3.9); translate([-8, 0, 0]) pinHole(3.9); translate([0, 8, 0]) pinHole(3.9); translate([8, 0, 0]) pinHole(3.9); translate([0, -8, 0]) pinHole(3.9); } } // Hole for a standard LEGO pin with height parameter intended to be cut // from some solid part (like half or full beam) module pinHole(height=8) { union() { translate([0, 0, -0.1]) cylinder($fs=0.5, h=height+0.2, r=2.5); translate([0, 0, -0.1]) cylinder($fs=0.5, h=0.8+0.1, r=3); translate([0, 0, height-0.8]) cylinder($fs=0.5, h=0.8+0.1, r=3); } } // Gear with offset teeth, axle hole and sparse body module offsetGearSparse(number_of_teeth, gear_height=3.9, jaggy=1) { root_radius = 3.05*number_of_teeth/3.1415926/2 - 3.05/3.1415926; difference() { offsetGear(number_of_teeth, gear_height, jaggy); translate([0, 0, -0.1]) difference() { cylinder($fn=50, h=gear_height+0.2, r=root_radius-1.5); cylinder($fn=50, h=gear_height+0.2, r=3.5); translate([-root_radius-1, 3.1-0.75, 0]) cube(size=[root_radius*2+2, 1.5, 2*gear_height+0.4], center=false); translate([-root_radius-1, -3.1-0.75, 0]) cube(size=[root_radius*2+2, 1.5, 2*gear_height+0.4], center=false); rotate([0, 0, 90]) { translate([-root_radius-1, 3.1-0.75, 0]) cube(size=[root_radius*2+2, 1.5, 2*gear_height+0.4], center=false); translate([-root_radius-1, -3.1-0.75, 0]) cube(size=[root_radius*2+2, 1.5, 2*gear_height+0.4], center=false); } } } } // Gear with offset teeth and axle hole module offsetGear(number_of_teeth, gear_height=3.9, jaggy=1) { difference() { union() { gear(number_of_teeth=number_of_teeth, mm_per_tooth=3.05, thickness=gear_height, pressure_angle=20); translate([0, 0, gear_height]) cylinder($fs=0.5, h=8-gear_height, r=3.5); } // axle hole rotate([0, 0, -jaggy*360/number_of_teeth]) axle(0, 0, -1, 10); } } // Gear with interface for driving ring, with offset teeth // => The minimal printable size of such gear is 9 teeth... // (8 teeth will probably be too thin at root circle) module offsetClutchGear(number_of_teeth, gear_height=3.8) { union() { difference() { union() { gear(number_of_teeth=number_of_teeth, mm_per_tooth=3.05, thickness=gear_height+0.1); translate([0, 0, gear_height]) cylinder($fn=max(32,2*number_of_teeth), h=8-gear_height, r=6.8); } difference() { translate([0, 0, 4.8]) cylinder($fn=50, h=4, r=5.8); translate([0, 0, 4.8]) cylinder($fn=50, h=4, r=3.3); } if (number_of_teeth > 13) { difference() { translate([0, 0, -0.1]) cylinder($fn=50, h=gear_height-1+0.1, r=3.05*(number_of_teeth/2-1)/3.1415926-1); translate([0, 0, -0.2]) cylinder($fn=50, h=4, r=3.5); translate([-0.5, -20, -0.1]) cube(size=[1, 40, 10]); translate([-20, -0.5, -0.1]) cube(size=[40, 1, 10]); } } // round hole translate([0, 0, -2]) cylinder($fn=50, h=12, r=2.5); } translate([0, 0, 2.9]) union() { clutchTeeth(); rotate([0, 0, 90]) clutchTeeth(); rotate([0, 0, 180]) clutchTeeth(); rotate([0, 0, -90]) clutchTeeth(); } } } // Axle module axle(x, y, z, height) { axle_gap = 1.95; union() { translate([x - HOLE_RADIUS, y - axle_gap/2, z]) roundedRect([HOLE_RADIUS * 2, axle_gap, height], .2); translate([x - axle_gap/2, y - HOLE_RADIUS, z]) roundedRect([axle_gap, HOLE_RADIUS * 2, height], .2); } } // Axle hole (for difference()) with fixing slit module axleCut(x, y, z, height) { axle_gap = 1.95; axle_gap_cut = 1.8; union() { translate([x - HOLE_RADIUS, y - axle_gap/2, z]) roundedRect([HOLE_RADIUS * 2, axle_gap, height], .2); translate([x - axle_gap_cut/2, y - HOLE_RADIUS, z]) roundedRect([axle_gap_cut, HOLE_RADIUS * 2, height], .2); translate([x-0.25, y-5, z]) cube(size=[0.5, 10, height]); translate([x, y, z]) difference() { cylinder($fn=32, r=4, h=height); translate([0, 0, -0.1]) cylinder($fn=32, r=3.6, h=height+0.2); translate([-2, -5, -0.1]) cube(size=[4, 10, height+0.2]); } } } // Gear with interface for driving ring, with centered teeth // => The minimal size of such gear is 16 teeth module clutchGear(number_of_teeth) { union() { difference() { union() { gear(thickness=3.7, mm_per_tooth=3.05, number_of_teeth=number_of_teeth, pressure_angle=20); translate([0, 0, 1]) cylinder($fn=number_of_teeth*2, h=5.8-1, r=6.8); translate([0, 0, -2]) cylinder($fn=number_of_teeth*2, h=2+1, r=3.7); } difference() { translate([0, 0, 1.8]) cylinder($fn=number_of_teeth*2, h=4.1, r=5.8); translate([0, 0, 1.7]) cylinder($fn=number_of_teeth*2, h=4.1+0.2, r=3.3); } translate([0, 0, -3]) cylinder($fn=number_of_teeth*2, h=10, r=HOLE_RADIUS); translate([0, 0, -2.2]) cylinder($fn=number_of_teeth*2, h=1, r=3.1); } clutchTeeth(); rotate([0, 0, 90]) clutchTeeth(); rotate([0, 0, 180]) clutchTeeth(); rotate([0, 0, -90]) clutchTeeth(); } } // Clutch: 0.7 from the top, 1.5 width, 1 thickness module clutchTeeth() { translate([5.8+0.1, 0, 1.8-0.1]) rotate([0, -90, 0]) linear_extrude(height = 1+0.1, center = false) polygon([ [0, -0.8], [0, 0.8], [3.2+0.1, 0.1], [3.2+0.1, -0.1], ]); } module myGear(n_teeth) { if (n_teeth >= 56) { myGearParamed(n_teeth, 6, 4, 5, 5); } else if (n_teeth >= 48) { myGearParamed(n_teeth, 4, 4, 5, 3); } else if (n_teeth >= 40) { myGearParamed(n_teeth, 4, 2, 3, 3); } else if (n_teeth >= 32) { myGearParamed(n_teeth, 2, 2, 3, 3); } else if (n_teeth >= 26) { myGearParamed(n_teeth, 2, 2, 3, 1); } else if (n_teeth >= 21) { myGearParamed(n_teeth, 2, 2, 1, 1); } else { myGearParamed(n_teeth, 0, 0, 1, 1); } } module myGearParamed(num_teeth, holes_row, holes_col, plus_row, plus_col) { jaggy_angle = 0; beam_width = 7.8; // Needs to be a bit less than the LEGO stud spacing = 7.99 mm gearHeight = 3.67; axle_gap = 1.9; // axle thickness is actually about 1.8 mm difference() { gear(thickness=gearHeight, number_of_teeth=num_teeth, mm_per_tooth=3.06, pressure_angle=20); // We do two rectangular grids of holes, rotate 90 degrees and do them // again. for (i = [jaggy_angle, jaggy_angle+90]) { rotate([0,0,i]) { // Cut the cross-axle holes (8.0mm = stud spacing) if (plus_row > 0) { for (x=[-4 * (plus_row - 1 ): 8.0 : 4 * (plus_row -1 )]) { for (y=[-4 * (plus_col - 1 ): 8.0 : 4 * (plus_col -1)]) { translate([x - HOLE_RADIUS, y - axle_gap/2, -0.1]) roundedRect([HOLE_RADIUS * 2, axle_gap, gearHeight+0.2], .2); translate([x - axle_gap/2, y - HOLE_RADIUS, -0.1]) roundedRect([axle_gap, HOLE_RADIUS * 2, gearHeight+0.2], .2); } } } if (holes_row > 0) { // Cut the round holes for (x=[-4 * (holes_row-1) : 8.0 : 4 * (holes_row-1)]) { for (y=[-4 * (holes_col-1) : 8.0 : 4 * (holes_col-1)]) { translate([x, y, -0.1]) { cylinder(r=HOLE_RADIUS, h = gearHeight+0.2, $fs=0.5); } } } } } } } } // --------------------------------------------------------------------------------- // // module for rounded rectangles by tlrobinson on Thingiverse in a // comment posted to http://www.thingiverse.com/thing:9347 on March // 29, 2012, 3:57:46 AM EDT // module roundedRect(size, radius) { x = size[0]; y = size[1]; z = size[2]; linear_extrude(height=z) hull() { translate([radius, radius, 0]) circle(r=radius); translate([x - radius, radius, 0]) circle(r=radius); translate([x - radius, y - radius, 0]) circle(r=radius); translate([radius, y - radius, 0]) circle(r=radius); } } /////////////////////////////////////////////// // Good gear() module -- without experimental OpenSCAD features // Does not support hole_diameter and teeth_to_hide parameters, // but generates good solid gears with no face problems module gear( mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth number_of_teeth = 11, //total number of teeth around the entire perimeter thickness = 6, //thickness of gear in mm twist = 0, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees. clearance = 0.0, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters) backlash = 0.0 //gap between two meshing teeth, in the direction along the circumference of the pitch circle ) { pi = 3.1415926; p = mm_per_tooth * number_of_teeth / pi / 2; //radius of pitch circle c = p + mm_per_tooth / pi - clearance; //radius of outer circle b = p*cos(pressure_angle); //radius of base circle r = p-(c-p)-clearance; //radius of root circle t = mm_per_tooth/2-backlash/2; //tooth thickness at pitch circle k = -iang(b, p) - t/2/p/pi*180; //angle to where involute meets base circle on each side of tooth difference() { union() { // $fn: so gear teeth edge never match cylinder segment edges translate([0, 0, -1]) cylinder($fn=number_of_teeth*2, h=thickness+2, r=r); translate([0, 0, -0.5]) for (i = [0:number_of_teeth-1]) rotate([0,0,i*360/number_of_teeth]) linear_extrude(height = thickness+1, center = false, convexity = 10, twist = twist) polygon( points=[ [0, 0], polar(r, -181/number_of_teeth), polar(r*0.9, r= 0 ? concat(range(n-1), [n]) : []); // radius a fraction f up the curved side of the tooth, rotated at 'rot' angle function q7r(f,r,b,r2,t,s,rot) = q6r(b,s,t,(1-f)*max(b,r)+f*r2,rot); // point at radius d on the involute curve, rotated at 'rot' angle function q6r(b,s,t,d,rot) = polar(d,rot+s*(iang(b,d)+t)); // Original gear() module // Teeth shape is good, but the body is composed from individual sectors; // this sometimes results in bad "degenerate" faces due to floating point issues. // Can be checked with FreeCAD 'mesh evaluation' module gear_original( mm_per_tooth = 3, //this is the "circular pitch", the circumference of the pitch circle divided by the number of teeth number_of_teeth = 11, //total number of teeth around the entire perimeter thickness = 6, //thickness of gear in mm hole_diameter = 0, //diameter of the hole in the center, in mm twist = 0, //teeth rotate this many degrees from bottom of gear to top. 360 makes the gear a screw with each thread going around once teeth_to_hide = 0, //number of teeth to delete to make this only a fraction of a circle pressure_angle = 28, //Controls how straight or bulged the tooth sides are. In degrees. clearance = 0.0, //gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters) backlash = 0.0 //gap between two meshing teeth, in the direction along the circumference of the pitch circle ) { pi = 3.1415926; p = mm_per_tooth * number_of_teeth / pi / 2; //radius of pitch circle c = p + mm_per_tooth / pi - clearance; //radius of outer circle b = p*cos(pressure_angle); //radius of base circle r = p-(c-p)-clearance; //radius of root circle t = mm_per_tooth/2-backlash/2; //tooth thickness at pitch circle k = -iang(b, p) - t/2/p/pi*180; //angle to where involute meets base circle on each side of tooth difference() { for (i = [0:number_of_teeth-teeth_to_hide-1]) rotate([0,0,i*360/number_of_teeth]) linear_extrude(height = thickness, center = false, convexity = 10, twist = twist) polygon( points=[ [0, -hole_diameter/10], polar(r, -181/number_of_teeth), polar(r, r