Created
October 13, 2019 13:43
-
-
Save roboter/26bf241256d3975e338d69dad9e41aee to your computer and use it in GitHub Desktop.
Spool drawer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Spool parts storage organizer | |
Based on https://www.thingiverse.com/thing:2793548 by hirez99 | |
Frank van der Hulst drifter.frank@gmail.com | |
24 Feb 2018 | |
This generates a drawer that can be fitted into an empty filament spool to | |
provide storage for small parts. | |
Holes need to be drilled in the sides of the spool for axles | |
A drill guide is provided to get the axle holes in the right places on the spool. | |
Axles are provided using tbuser's Pin Connectors V2 library https://www.thingiverse.com/thing:10541 | |
Requires v2016.XX of OpenScad | |
8 Sep 2018: Increase Spool Inner, Outer, and Hole Diameter maximum values | |
Still to do: | |
A latch to make it stay closed... I'm thinking a magnet glued into a corner | |
A stacker thing to stack multiple spools on top of each other | |
*******************************************************************************************************/ | |
// Customizer User configuration settings... | |
$fn = 128; | |
// Outer diameter of the spool | |
Spool_Outer_Diam = 194; // [100:10:250] | |
// Inner diameter of the spool | |
Spool_Inner_Diam = 100; // [50:100] | |
// Diameter of the hole in the middle of the spool | |
Spool_Hole_Diam = 101; // [30:90] | |
// Width of spool between the sides | |
Spool_Width = 67; // [30:5:100] | |
// Thickness of spool wall | |
Spool_Wall_Thickness = 1; // [1:.5:3] | |
// Axle diameter (mm) | |
Axle_Diam = 8; // [2:20] | |
// Axle protrusion (mm) to link stacked drawers, and to go through one side of the spool | |
Axle_Height = 10; // [5:5:20] | |
// Number of organizer sections around the spool | |
Num_Drawers = 4; // [2:10] | |
// Number of drawers to stack in spool width | |
Drawer_Stack = 1; // [1, 2, 3, 4] | |
// Clearance between parts (mm) | |
Clearance = 0.3; // [0.2:0.1:2] | |
// Thickness of outer wall of organizer (mm) | |
Bottom_Thickness = 1.2; // [1.0:.25:3] | |
// Thickness of outer wall of organizer (mm) | |
Wall_Thickness = 1.6; // [1.6:.1:3] | |
// Type of internal divider | |
Divider_Type = "equal area"; // ["radial", "equal area"] | |
// Thickness of dividers inside the organizer (mm) | |
Divider_Thickness = 0.8; // [0.4:0.1:1.6] | |
// Height of dividers as percentage of drawer height | |
Divider_Height = 0; // [10:5:100] | |
// Number of rings of compartments | |
Num_Rings = 1; // [1,2,3] | |
// Number of compartments. If "radial is selected, there are the same number of compartments in every ring. If "equal area" is selected, there will be fewer compartments in inner rings, so that all compartments are approxiamtely the same area. | |
Num_Compartments = 10; // [1:20] | |
// [Hidden] | |
pi = 3.141592; | |
outerRad = Spool_Outer_Diam/2; | |
innerRad = Spool_Inner_Diam/2; | |
axleRad = Axle_Diam/2; | |
drawerAngle = 360/Num_Drawers; | |
axlePoint = [outerRad - axleRad - Wall_Thickness, axleRad + Wall_Thickness]; | |
ringSize = (outerRad - innerRad - Wall_Thickness)/Num_Rings; | |
drawer((Spool_Width / Drawer_Stack) - Clearance, Spool_Wall_Thickness); | |
// Axle between drawers | |
// The actual drawer, divided into compartments | |
module drawer(h, axleHeight) { | |
difference() { | |
union() { | |
// floor | |
linear_extrude(Bottom_Thickness) plan(); | |
linear_extrude(h) union() { | |
// outer walls | |
shell(Wall_Thickness) plan(); | |
// axle gusset | |
tangentPoint=[axlePoint[0]+cos(135)*(axleRad+Wall_Thickness), | |
axlePoint[1]+sin(135)*(axleRad+Wall_Thickness)]; | |
depth = sqrt(pow(tangentPoint[0]-(outerRad-Wall_Thickness), 2) + pow(tangentPoint[1]-Wall_Thickness, 2)); | |
outerGusset([outerRad-Wall_Thickness, Wall_Thickness], depth, outerRad); | |
// outer corner gusset | |
rotate(drawerAngle) | |
outerGusset([outerRad, -Wall_Thickness], Wall_Thickness*2, outerRad, a=-45); | |
// bottom inner corner gusset | |
innerGusset([innerRad, Wall_Thickness], Wall_Thickness*2, innerRad, a=135); | |
// top inner corner gusset | |
rotate(drawerAngle) | |
innerGusset([innerRad, -Wall_Thickness], Wall_Thickness*2, innerRad, a=225); | |
} | |
} | |
// axle hole in top of drawer | |
rotate([180, 0, 0]) translate([axlePoint[0], - axlePoint[1], -h]) | |
pinhole(h=Axle_Height, r=axleRad, lh=3, lt=1, t=Clearance, tight = false); | |
// axle hole in bottom of drawer | |
translate(axlePoint) | |
pinhole(h=Axle_Height, r=axleRad, lh=3, lt=1, t=Clearance, tight = false); | |
} | |
} | |
// Draw a 2D plan view of the drawer | |
// This is extruded for the floor, and used to mask other parts | |
module plan() { | |
difference() { | |
intersection() { | |
difference() { | |
circle(r= outerRad); | |
circle(r = innerRad); | |
} | |
// NB: Use of diameter instead of radius in calculating polygon, so | |
// the polygon is twice as big as the circle and its 2nd and 3rd sides don't | |
// intersect with the circle | |
if (Num_Drawers == 2) | |
// Handle special case for 2 sections | |
polygon([[-Spool_Outer_Diam, 0], [Spool_Outer_Diam, 0], | |
[Spool_Outer_Diam, Spool_Outer_Diam], [-outerRad, Spool_Outer_Diam]]); | |
else | |
polygon(points= [[0,0], | |
[Spool_Outer_Diam, 0], | |
[Spool_Outer_Diam, sin(drawerAngle)*Spool_Outer_Diam], | |
[cos(drawerAngle)*Spool_Outer_Diam, sin(drawerAngle)*Spool_Outer_Diam] | |
]); | |
} | |
// Round off the corner at the axle to stop it interfering with the | |
// next section when turning | |
translate(axlePoint) round(axleRad + Wall_Thickness); | |
} | |
} | |
// The drill guide | |
module guide() { | |
angleAxle = atan2(axlePoint[1]+axleRad, axlePoint[0]); | |
linear_extrude(3) { | |
for (a=[0:drawerAngle:drawerAngle]) | |
rotate(a) { | |
translate(axlePoint) | |
shell(3) circle(r=axleRad+3); | |
polygon(points=[[Spool_Hole_Diam/2-Wall_Thickness, 0], | |
[axlePoint[0]-axleRad, axlePoint[1]-3], | |
[axlePoint[0]-axleRad, axlePoint[1]+ 3], | |
[Spool_Hole_Diam/2-Wall_Thickness, 3]]); | |
} | |
} | |
rotate_extrude(angle=drawerAngle+angleAxle) | |
translate([Spool_Hole_Diam/2 - Wall_Thickness, 0]) | |
square([Wall_Thickness, 6]); | |
} | |
// Gusset the inside of an outer corner | |
// point = point to apply guuset to | |
// depth = depth of gusset = minimum dispance from point to gusset edge | |
// r = radius of circle that this gu | |
module outerGusset(point, depth, r, a = 45) { | |
points=[point, | |
[point[0], point[1] + depth*sin(a)*2], | |
[point[0]-depth*cos(a)*2, point[1]]]; | |
intersection() { | |
circle(r); | |
polygon(points = points); | |
} | |
} | |
// Gusset the inside of an inner corner | |
// point = point to apply guuset to | |
// depth = depth of gusset = minimum dispance from point to gusset edge | |
// r = radius of circle that this gu | |
module innerGusset(point, depth, r, a = 45) { | |
points=[point, [point[0]-Wall_Thickness, point[1] + depth*sin(a)*2], [point[0]-depth*cos(a)*2, point[1]]]; | |
difference() { | |
polygon(points = points); | |
circle(r); | |
} | |
} | |
// Round the outside of a corner | |
module round(r, a = 90) { | |
difference() { | |
translate([0, -r]) | |
square(r); | |
circle(r= r); | |
} | |
} | |
// Shell of a 2D object to get an outline which can be extruded for a wall | |
module shell(thickness = 1) { | |
difference() { | |
children(0); | |
offset(r=-thickness, chamfer=true) children(0); | |
} | |
} | |
// Find the sum of the values in a vector from the start (or s'th element) to the i'th element | |
function sumv(v,i,s=0) = (i==s ? v[i] : v[i] + sumv(v,i-1,s)); | |
include <pins.scad> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Pin Connectors V3 | |
// Tony Buser <tbuser@gmail.com> | |
// Modified by Emmett Lalish | |
object=0;//[0:pin,1:pinpeg,2:pinhole] | |
length=20; | |
diameter=8; | |
//Only affects pinhole | |
hole_twist=0;//[0:free,1:fixed] | |
//Only affects pinhole | |
hole_friction=0;//[0:loose,1:tight] | |
//Radial gap to help pins fit into tight holes | |
pin_tolerance=0.2; | |
//Extra gap to make loose hole | |
loose=0.3; | |
lip_height=3; | |
lip_thickness=1; | |
hf=hole_friction==0 ? false : true; | |
ht=hole_twist==0 ? false : true; | |
module test() { | |
tolerance = 0.3; | |
translate([-12, 12, 0]) pinpeg(h=20); | |
translate([12, 12, 0]) pintack(h=10); | |
difference() { | |
union() { | |
translate([0, -12, 2.5]) cube(size = [59, 20, 5], center = true); | |
translate([24, -12, 7.5]) cube(size = [12, 20, 15], center = true); | |
} | |
translate([-24, -12, 0]) pinhole(h=5, t=tolerance); | |
translate([-12, -12, 0]) pinhole(h=5, t=tolerance, tight=false); | |
translate([0, -12, 0]) pinhole(h=10, t=tolerance); | |
translate([12, -12, 0]) pinhole(h=10, t=tolerance, tight=false); | |
translate([24, -12, 15]) rotate([0, 180, 0]) pinhole(h=10, t=tolerance); | |
} | |
} | |
module pinhole(h=10, r=4, lh=3, lt=1, t=0.3, tight=true, fixed=false) { | |
// h = shaft height | |
// r = shaft radius | |
// lh = lip height | |
// lt = lip thickness | |
// t = extra tolerance for loose fit | |
// tight = set to false if you want a joint that spins easily | |
// fixed = set to true so pins can't spin | |
intersection(){ | |
union() { | |
if (tight == true || fixed == true) { | |
pin_solid(h, r, lh, lt); | |
translate([0,0,-t/2])cylinder(h=h+t, r=r, $fn=30); | |
} else { | |
pin_solid(h, r+t/2, lh, lt); | |
translate([0,0,-t/2])cylinder(h=h+t, r=r+t/2, $fn=30); | |
} | |
// widen the entrance hole to make insertion easier | |
//translate([0, 0, -0.1]) cylinder(h=lh/3, r2=r, r1=r+(t/2)+(lt/2),$fn=30); | |
} | |
if (fixed == true) { | |
translate([-r*2, -r*0.75, -1])cube([r*4, r*1.5, h+2]); | |
} | |
}} | |
module pin(h=10, r=4, lh=3, lt=1, t=0.2, side=false) { | |
// h = shaft height | |
// r = shaft radius | |
// lh = lip height | |
// lt = lip thickness | |
// side = set to true if you want it printed horizontally | |
if (side) { | |
pin_horizontal(h, r, lh, lt, t); | |
} else { | |
pin_vertical(h, r, lh, lt, t); | |
} | |
} | |
module pintack(h=10, r=4, lh=3, lt=1, t=0.2, bh=3, br=8.75) { | |
// bh = base_height | |
// br = base_radius | |
union() { | |
cylinder(h=bh, r=br); | |
translate([0, 0, bh]) pin(h, r, lh, lt, t); | |
} | |
} | |
module pinpeg(h=20, r=4, lh=3, lt=1, t=0.2) { | |
union() { | |
translate([0,-0.05, 0]) pin(h/2+0.1, r, lh, lt, t, side=true); | |
translate([0,0.05, 0]) rotate([0, 0, 180]) pin(h/2+0.1, r, lh, lt, t, side=true); | |
} | |
} | |
// just call pin instead, I made this module because it was easier to do the rotation option this way | |
// since openscad complains of recursion if I did it all in one module | |
module pin_vertical(h=10, r=4, lh=3, lt=1, t=0.2) { | |
// h = shaft height | |
// r = shaft radius | |
// lh = lip height | |
// lt = lip thickness | |
difference() { | |
pin_solid(h, r-t/2, lh, lt); | |
// center cut | |
translate([-lt*3/2, -(r*2+lt*2)/2, h/5+lt*3/2]) cube([lt*3, r*2+lt*2, h]); | |
//translate([0, 0, h/4]) cylinder(h=h+lh, r=r/2.5, $fn=20); | |
// center curve | |
translate([0, 0, h/5+lt*3/2]) rotate([90, 0, 0]) cylinder(h=r*2, r=lt*3/2, center=true, $fn=20); | |
// side cuts | |
translate([-r*2, -r-r*0.75+t/2, -1]) cube([r*4, r, h+2]); | |
translate([-r*2, r*0.75-t/2, -1]) cube([r*4, r, h+2]); | |
} | |
} | |
// call pin with side=true instead of this | |
module pin_horizontal(h=10, r=4, lh=3, lt=1, t=0.2) { | |
// h = shaft height | |
// r = shaft radius | |
// lh = lip height | |
// lt = lip thickness | |
translate([0, 0, r*0.75-t/2]) rotate([-90, 0, 0]) pin_vertical(h, r, lh, lt, t); | |
} | |
// this is mainly to make the pinhole module easier | |
module pin_solid(h=10, r=4, lh=3, lt=1) { | |
union() { | |
// shaft | |
cylinder(h=h-lh, r=r, $fn=30); | |
// lip | |
// translate([0, 0, h-lh]) cylinder(h=lh*0.25, r1=r, r2=r+(lt/2), $fn=30); | |
// translate([0, 0, h-lh+lh*0.25]) cylinder(h=lh*0.25, r2=r, r1=r+(lt/2), $fn=30); | |
// translate([0, 0, h-lh+lh*0.50]) cylinder(h=lh*0.50, r1=r, r2=r-(lt/2), $fn=30); | |
// translate([0, 0, h-lh]) cylinder(h=lh*0.50, r1=r, r2=r+(lt/2), $fn=30); | |
// translate([0, 0, h-lh+lh*0.50]) cylinder(h=lh*0.50, r1=r+(lt/2), r2=r-(lt/3), $fn=30); | |
translate([0, 0, h-lh]) cylinder(h=lh*0.25, r1=r, r2=r+(lt/2), $fn=30); | |
translate([0, 0, h-lh+lh*0.25]) cylinder(h=lh*0.25, r=r+(lt/2), $fn=30); | |
translate([0, 0, h-lh+lh*0.50]) cylinder(h=lh*0.50, r1=r+(lt/2), r2=r-(lt/2), $fn=30); | |
// translate([0, 0, h-lh]) cylinder(h=lh, r1=r+(lt/2), r2=1, $fn=30); | |
// translate([0, 0, h-lh-lt/2]) cylinder(h=lt/2, r1=r, r2=r+(lt/2), $fn=30); | |
} | |
} | |
module pinshaft(h=10, r=4, t=0.2, side=false){ | |
flip=side ? 1 : 0; | |
translate(flip*[0,h/2,r*0.75-t/2])rotate(flip*[90,0,0]) | |
intersection(){ | |
cylinder(h=h, r=r-t/2, $fn=30); | |
translate([-r*2, -r*0.75+t/2, -1])cube([r*4, r*1.5-t, h+2]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment