And we have a model subframe which is really promising! OpenSCAD for the win!

This commit is contained in:
Simon Brooke 2025-09-04 12:10:31 +01:00
parent bcea01f8b6
commit f863799729
23 changed files with 6330 additions and 5 deletions

View file

@ -10,4 +10,4 @@ Still at a very preliminary, pre-prototype stage. Work is documented [here](http
## Copyright
Copyright © Simon Brooke, 2024-2025; may be used and modified under [Creative Commons Attribution-Share Alike](https://creativecommons.org/licenses/by-sa/4.0/deed.en) licence; but (currently) uses elements from [Pierre Rouzeau](https://rouzeau.net/)'s [BentSim](https://github.com/PRouzeau/BentSim) project, which is [GPL](https://github.com/PRouzeau/BentSim/blob/master/LICENSE) licensed.
Copyright © Simon Brooke, 2024-2025; may be used and modified under [Creative Commons Attribution-Share Alike](https://creativecommons.org/licenses/by-sa/4.0/deed.en) licence; but (currently) uses elements from [Pierre Rouzeau](https://rouzeau.net/)'s [BentSim](https://github.com/PRouzeau/BentSim) project, which is [GPL](https://github.com/PRouzeau/BentSim/blob/master/LICENSE) licensed, and sprockets from [Hampus Andersson](https://www.thingiverse.com/haand001/designs)'s [Sprocket Generator V2](https://www.thingiverse.com/thing:3059422), which is licensed under [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/).

View file

@ -0,0 +1 @@
This thing was created by Thingiverse user haand001 (Hampus Andersson), and is licensed under Creative Commons - Attribution

View file

@ -0,0 +1,4 @@
Sprocket Generator V2 - OpenSCAD by haand001 on Thingiverse: https://www.thingiverse.com/thing:3059422
Summary:
This is a sprocket generator that is designed and coded to be easy to use, even if you are new to OpenSCAD. Customize your own sprocket according to your needs and export it directly to a .stl file. Slice it and print it!For example, you can change:Bore diameterTeeth countPitch, roller diameterToleranceThicknessShaft length and diameterNumber of holes evenly distributedand a lot more...Test it using the Customizer to the right --> !Use PETG or Nylon for best results with 100% infill, many wall layers and concentric filling setting.The code is generously commented and easy to understand for you to make your own adjustments if required by your specific application. All measurements is in millimeters.Enjoy!

View file

@ -0,0 +1,166 @@
/*
Sprocket generator v2
This code is based on the code written by *Talon_1* who based his code on the work of
*Aleksejs*. Big thanks for your contributions. The aim of this code is to be easier
understood by folks that are new to OpenSCAD. The rendered sprocket can be downloaded
as a .STL file and 3D-printed directly using any slicing program.
*/
//////////////////////
/* CHAIN-PARAMETERS */
//////////////////////
// THESE ARE FOR 25H/04C
roller_d = 4.1;
thickness = 2.9;
pitch = 6.35;
tolerance = 0.05;
///////////////
/* VARIABLES */
///////////////
teeth = 10;
// Shaft
bottom_shaft_d = 10;
bottom_shaft_h = 2; // = 0 to remove
top_shaft_d = 10;
top_shaft_h = 3; // = 0 to remove
toptop_shaft_d = 16;
toptop_shaft_h = 8; // = 0 to remove
// Bore
hole_d = 8;
// Holes
number_of_holes = 0;
hole_dia = 4;
hole_ring_dia = 40;
///////////////////////
// RENDERING QUALITY */
///////////////////////
// HIGH : fs=0.25 : fa=3 : fn=0
// LOW : fs=1 : fa=7 : fn=0
fs = 0.25; // Minimum size of a fragment
fa = 1; // Minimum angle for a fragment
fn = 0; // Number of fragments (overrides fs & fa if non zero)
///////////////
/* MAIN CODE */
///////////////
difference()
{
// Create a union of four shapes, 3 cylinders and 1 sprocket
union()
{
// Create sprocket using the difined module
sprocket(teeth, roller_d, pitch, thickness, tolerance);
// Create cylinder on front side of sprocket
translate([0, 0, thickness])
cylinder(top_shaft_h, top_shaft_d/2, top_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
// Create cylinder on back side of sprocket
rotate([0,180])
cylinder(bottom_shaft_h, bottom_shaft_d/2, bottom_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
// Create cylinder on top of the front side cylinder
translate([0, 0, thickness+top_shaft_h])
cylinder(toptop_shaft_h, toptop_shaft_d/2, toptop_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
}
// Rest of shapes are removal of material
// Drills out the center hole with 1 mm extra in both directions
translate([0, 0, -bottom_shaft_h-1])
{
cylinder(bottom_shaft_h+thickness+top_shaft_h+toptop_shaft_h+2, hole_d/2, hole_d/2, $fs=fs, $fa=fa, $fn=fn);
}
// Drills 'number_of_holes' many holes in a circle
angle_between_holes = 360/number_of_holes;
for(hole_angle = [0:360/number_of_holes:360])
{
translate([hole_ring_dia/2*cos(hole_angle), hole_ring_dia/2*sin(hole_angle), -bottom_shaft_h-1])
{
cylinder(h = bottom_shaft_h+thickness+top_shaft_h+toptop_shaft_h+2, r = hole_dia/2, $fs=fs, $fa=fa, $fn=fn);
}
}
}
/////////////////////
/* SPROCKET MODULE */
/////////////////////
module sprocket(teeth=20, roller=3, pitch=17, thickness=3, tolerance=0.2)
{
roller_radius = roller/2; //We need radius in our calculations, not diameter
distance_from_center = pitch/(2*sin(180/teeth));
angle = (360/teeth);
pitch_radius = sqrt((distance_from_center*distance_from_center) - (pitch*(roller_radius+tolerance))+((roller_radius+tolerance)*(roller_radius+tolerance)));
difference()
{
union()
{
// Quality parameters
$fs = fs;
$fa = fa;
$fn = fn;
// Create inner cylinder with radius = pitch_radius
cylinder(r=pitch_radius, h=thickness);
// Create outer part of the teeth
for(tooth=[1:teeth])
{
intersection()
{
rotate(a=[0, 0, angle*(tooth+0.5)])
{
translate([distance_from_center, 0, 0])
{
$fs = fs;
$fa = fa;
$fn = fn;
cylinder(r=pitch-roller_radius-tolerance, h=thickness);
}
}
rotate(a=[0,0,angle*(tooth-0.5)])
{
translate([distance_from_center,0,0])
{
cylinder(r=pitch-roller_radius-tolerance,h=thickness);
}
}
}
}
}
// Cuts away the inner groove between the teeth
for(tooth=[1:teeth])
{
rotate(a=[0, 0, angle*(tooth+0.5)])
{
translate([distance_from_center, 0, -1])
{
$fs = fs;
$fa = fa;
$fn = fn;
cylinder(r=roller_radius+tolerance, h=thickness+2);
}
}
}
}
}

View file

@ -0,0 +1,166 @@
/*
Sprocket generator v2
This code is based on the code written by *Talon_1* who based his code on the work of
*Aleksejs*. Big thanks for your contributions. The aim of this code is to be easier
understood by folks that are new to OpenSCAD. The rendered sprocket can be downloaded
as a .STL file and 3D-printed directly using any slicing program.
*/
//////////////////////
/* CHAIN-PARAMETERS */
//////////////////////
// THESE ARE FOR 25H/04C
roller_d = 4.1;
thickness = 2.9;
pitch = 6.35;
tolerance = 0.05;
///////////////
/* VARIABLES */
///////////////
teeth = 23;
// Shaft
bottom_shaft_d = 20;
bottom_shaft_h = 2; // = 0 to remove
top_shaft_d = 40;
top_shaft_h = 8; // = 0 to remove
toptop_shaft_d = 36;
toptop_shaft_h = 4; // = 0 to remove
// Bore
hole_d = 12;
// Holes
number_of_holes = 12;
hole_dia = 4;
hole_ring_dia = 30;
///////////////////////
// RENDERING QUALITY */
///////////////////////
// HIGH : fs=0.25 : fa=3 : fn=0
// LOW : fs=1 : fa=7 : fn=0
fs = 0.25; // Minimum size of a fragment
fa = 1; // Minimum angle for a fragment
fn = 0; // Number of fragments (overrides fs & fa if non zero)
///////////////
/* MAIN CODE */
///////////////
difference()
{
// Create a union of four shapes, 3 cylinders and 1 sprocket
union()
{
// Create sprocket using the difined module
sprocket(teeth, roller_d, pitch, thickness, tolerance);
// Create cylinder on front side of sprocket
translate([0, 0, thickness])
cylinder(top_shaft_h, top_shaft_d/2, top_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
// Create cylinder on back side of sprocket
rotate([0,180])
cylinder(bottom_shaft_h, bottom_shaft_d/2, bottom_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
// Create cylinder on top of the front side cylinder
translate([0, 0, thickness+top_shaft_h])
cylinder(toptop_shaft_h, toptop_shaft_d/2, toptop_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
}
// Rest of shapes are removal of material
// Drills out the center hole with 1 mm extra in both directions
translate([0, 0, -bottom_shaft_h-1])
{
cylinder(bottom_shaft_h+thickness+top_shaft_h+toptop_shaft_h+2, hole_d/2, hole_d/2, $fs=fs, $fa=fa, $fn=fn);
}
// Drills 'number_of_holes' many holes in a circle
angle_between_holes = 360/number_of_holes;
for(hole_angle = [0:360/number_of_holes:360])
{
translate([hole_ring_dia/2*cos(hole_angle), hole_ring_dia/2*sin(hole_angle), -bottom_shaft_h-1])
{
cylinder(h = bottom_shaft_h+thickness+top_shaft_h+toptop_shaft_h+2, r = hole_dia/2, $fs=fs, $fa=fa, $fn=fn);
}
}
}
/////////////////////
/* SPROCKET MODULE */
/////////////////////
module sprocket(teeth=20, roller=3, pitch=17, thickness=3, tolerance=0.2)
{
roller_radius = roller/2; //We need radius in our calculations, not diameter
distance_from_center = pitch/(2*sin(180/teeth));
angle = (360/teeth);
pitch_radius = sqrt((distance_from_center*distance_from_center) - (pitch*(roller_radius+tolerance))+((roller_radius+tolerance)*(roller_radius+tolerance)));
difference()
{
union()
{
// Quality parameters
$fs = fs;
$fa = fa;
$fn = fn;
// Create inner cylinder with radius = pitch_radius
cylinder(r=pitch_radius, h=thickness);
// Create outer part of the teeth
for(tooth=[1:teeth])
{
intersection()
{
rotate(a=[0, 0, angle*(tooth+0.5)])
{
translate([distance_from_center, 0, 0])
{
$fs = fs;
$fa = fa;
$fn = fn;
cylinder(r=pitch-roller_radius-tolerance, h=thickness);
}
}
rotate(a=[0,0,angle*(tooth-0.5)])
{
translate([distance_from_center,0,0])
{
cylinder(r=pitch-roller_radius-tolerance,h=thickness);
}
}
}
}
}
// Cuts away the inner groove between the teeth
for(tooth=[1:teeth])
{
rotate(a=[0, 0, angle*(tooth+0.5)])
{
translate([distance_from_center, 0, -1])
{
$fs = fs;
$fa = fa;
$fn = fn;
cylinder(r=roller_radius+tolerance, h=thickness+2);
}
}
}
}
}

View file

@ -0,0 +1,166 @@
/*
Sprocket generator v2
This code is based on the code written by *Talon_1* who based his code on the work of
*Aleksejs*. Big thanks for your contributions. The aim of this code is to be easier
understood by folks that are new to OpenSCAD. The rendered sprocket can be downloaded
as a .STL file and 3D-printed directly using any slicing program.
*/
//////////////////////
/* CHAIN-PARAMETERS */
//////////////////////
// THESE ARE FOR 25H/04C
roller_d = 4.1;
thickness = 2.9;
pitch = 6.35;
tolerance = 0.05;
///////////////
/* VARIABLES */
///////////////
teeth = 31;
// Shaft
bottom_shaft_d = 20;
bottom_shaft_h = 0; // = 0 to remove
top_shaft_d = 50;
top_shaft_h = 3; // = 0 to remove
toptop_shaft_d = 24;
toptop_shaft_h = 8; // = 0 to remove
// Bore
hole_d = 20;
// Holes
number_of_holes = 5;
hole_dia = 4;
hole_ring_dia = 40;
///////////////////////
// RENDERING QUALITY */
///////////////////////
// HIGH : fs=0.25 : fa=3 : fn=0
// LOW : fs=1 : fa=7 : fn=0
fs = 0.25; // Minimum size of a fragment
fa = 1; // Minimum angle for a fragment
fn = 0; // Number of fragments (overrides fs & fa if non zero)
///////////////
/* MAIN CODE */
///////////////
difference()
{
// Create a union of four shapes, 3 cylinders and 1 sprocket
union()
{
// Create sprocket using the difined module
sprocket(teeth, roller_d, pitch, thickness, tolerance);
// Create cylinder on front side of sprocket
translate([0, 0, thickness])
cylinder(top_shaft_h, top_shaft_d/2, top_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
// Create cylinder on back side of sprocket
rotate([0,180])
cylinder(bottom_shaft_h, bottom_shaft_d/2, bottom_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
// Create cylinder on top of the front side cylinder
translate([0, 0, thickness+top_shaft_h])
cylinder(toptop_shaft_h, toptop_shaft_d/2, toptop_shaft_d/2, $fs=fs, $fa=fa, $fn=fn);
}
// Rest of shapes are removal of material
// Drills out the center hole with 1 mm extra in both directions
translate([0, 0, -bottom_shaft_h-1])
{
cylinder(bottom_shaft_h+thickness+top_shaft_h+toptop_shaft_h+2, hole_d/2, hole_d/2, $fs=fs, $fa=fa, $fn=fn);
}
// Drills 'number_of_holes' many holes in a circle
angle_between_holes = 360/number_of_holes;
for(hole_angle = [0:360/number_of_holes:360])
{
translate([hole_ring_dia/2*cos(hole_angle), hole_ring_dia/2*sin(hole_angle), -bottom_shaft_h-1])
{
cylinder(h = bottom_shaft_h+thickness+top_shaft_h+toptop_shaft_h+2, r = hole_dia/2, $fs=fs, $fa=fa, $fn=fn);
}
}
}
/////////////////////
/* SPROCKET MODULE */
/////////////////////
module sprocket(teeth=20, roller=3, pitch=17, thickness=3, tolerance=0.2)
{
roller_radius = roller/2; //We need radius in our calculations, not diameter
distance_from_center = pitch/(2*sin(180/teeth));
angle = (360/teeth);
pitch_radius = sqrt((distance_from_center*distance_from_center) - (pitch*(roller_radius+tolerance))+((roller_radius+tolerance)*(roller_radius+tolerance)));
difference()
{
union()
{
// Quality parameters
$fs = fs;
$fa = fa;
$fn = fn;
// Create inner cylinder with radius = pitch_radius
cylinder(r=pitch_radius, h=thickness);
// Create outer part of the teeth
for(tooth=[1:teeth])
{
intersection()
{
rotate(a=[0, 0, angle*(tooth+0.5)])
{
translate([distance_from_center, 0, 0])
{
$fs = fs;
$fa = fa;
$fn = fn;
cylinder(r=pitch-roller_radius-tolerance, h=thickness);
}
}
rotate(a=[0,0,angle*(tooth-0.5)])
{
translate([distance_from_center,0,0])
{
cylinder(r=pitch-roller_radius-tolerance,h=thickness);
}
}
}
}
}
// Cuts away the inner groove between the teeth
for(tooth=[1:teeth])
{
rotate(a=[0, 0, angle*(tooth+0.5)])
{
translate([distance_from_center, 0, -1])
{
$fs = fs;
$fa = fa;
$fn = fn;
cylinder(r=roller_radius+tolerance, h=thickness+2);
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -1,10 +1,88 @@
// tricycle.scad:
include <Library/BentSim/Bike_accessories.scad>
include <Library/SprocketGenerator2/files/Sprocket_Generator_v2_example_10.scad>
module subframe () {
translate([0, 180, 109])
cube([50, 25, 230], center = true);
// front leg (supports cross-shaft, epicyclic, motor
translate([-25, 1820, -550])
color("grey")
cube([50, 25, 230]);
// bottom bracket leg
translate([-25, 1690, -578])
color("grey")
cube([50, 25, 310]);
// wheel leg
translate([-70, 1430, -593])
rotate([0, 5, 0])
color("grey")
cube([25, 75, 363]);
// front upper
translate([-25, 2000, -385])
rotate([70, 0, 0])
color("grey")
cube([50, 25, 330]);
// central upper
translate([-25, 1700, -275])
rotate([82, 0, 0])
color("grey")
cube([50, 25, 370]);
// rear leg
translate([-25, 1200, -515])
rotate([-23, 0, 0])
color("grey")
cube([50, 25, 344]);
cube([50, 25,
// wheel
translate([0, 1467.5, -450])
rotate([0, 0, 90])
// Pierre Rouzeau's wheel is beautifully modelled and parameterised, but it doesn't seem to be scaled as I'd expect...
scale([0.70, 0.70, 0.70])
wheel(rim=451, spoke_nbr=0);
// bottom bracket
translate([-25, 1680, -390])
color("black")
rotate([0, 90, 0])
cylinder(h=68, r=26);
translate([-35, 1680, -390])
color("silver")
rotate([0, 90, 0])
sprocket(teeth=82, roller=7.9, pitch=12.7);
// left crank
translate([-44, 1680, -395])
color("black")
cube([12,20,150]);
// left pedal
translate([-120, 1670, -265])
color("black")
cube([70,40,15]);
// left pedal shaft
translate([-120, 1690, -257.5])
color("silver")
rotate([0,90,0])
cylinder(h=80,r=4);
// right crank
translate([44, 1680, -535])
color("black")
cube([12,20,150]);
// right pedal
translate([58, 1670, -525])
color("black")
cube([70,40,15]);
// right pedal shaft
translate([44, 1690, -517.5])
color("silver")
rotate([0,90,0])
cylinder(h=80,r=4);
}
subframe();
subframe();

BIN
sketches/sketch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

1228
sketches/sketch.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 59 KiB

1013
sketches/tricycle-sketch.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 701 KiB