331 lines
15 KiB
OpenSCAD
331 lines
15 KiB
OpenSCAD
/*
|
|
This OpenSCAD script can produce a spool holder with different spindle lengths, a spindle extension piece, and a bracket that has two different spindle mounting points.
|
|
Before printing the full set, use the 'test_pieces' module to generate a couple of parts that check the fitment of the male and female threads, and the size of the recessed nut slot.
|
|
Use the spindle_thread_tol parameter to alter the tightness of the threaded sections - a bigger value will make the parts fit less tightly.
|
|
Use the hex_ap parameter to adjust the size of the recessed nut slot - it represents the 'across points' dimension of the hexagonal nut slot.
|
|
By default the script produces a bracket for the top-right-front corner of the enclosure, which is the regular spindle location. This bracket will also fit the bottom-left-front, the top-left-rear and bottom-right-rear
|
|
Use the if_mirror option to flip the geometry. When mirrored, the bracket will fit the top_left_front, bottom-right-front, bottom-left-rear and top-right-rear
|
|
(Note that simply mirroring the model in the slicer will not work, since the screw threads will be reversed)
|
|
|
|
CJH 26 April 2023
|
|
Updated 17 April 2024 with V3 bracket design abd mirrored geometry option
|
|
Updated 28 April 2023 with new 3rd mounting hole location and addition of spare spindle storage
|
|
Updated 8th April 2024 with the if_mirror option, the option to specify a reduced depth for the hexagon lattice and spindle reinforcing bosses, and an adjustment to the location of the spare spindle so that it can be screwed all the way in without foulong the enclosure screw.
|
|
*/
|
|
|
|
$fa = 1;// minimum angle for a fragment } smaller values will improve STL resolution
|
|
$fs = 0.3;// minimum size of a fragment } but will increase rendering time
|
|
// } Beware - 0.1 can take a very long time to render!
|
|
|
|
include<threads-scad-master/threads.scad>
|
|
|
|
//*************************** Parameter Definitions **************************************
|
|
layer_ht = 0.3;//used to create the 'bridge helper' support layers for the 'suspended' bolt hole above the nut hole. 0.3mm works for a 0.2mm layer height, but not vice versa
|
|
|
|
//bracket options
|
|
second_spindle = false;//include an additional 'high capacity' spindle location
|
|
spare_spindle = false;//include a threaded hole to store a spare spindle or extension
|
|
if_mirror = true;//flip the geometry, but retain normal screw threads
|
|
third_hole = false;//include a third screw hole along the top edge of the enclosure frame
|
|
|
|
depth = 18.5;//depth, or thickness, of the bracket
|
|
frame_width = 8;//8;// width of main frame around hexagon lattice
|
|
|
|
//Spindle definitions
|
|
spindle_diam = 24;//the outer diameter of the spindle
|
|
spindle_length = 75;//the (default) length of the spindle (and the extension). Can be overriden with the 'length=' parameter.
|
|
spindle_thread = spindle_diam-6;//the outside diameter of the threaded sections - allows a 3mm 'landing' face
|
|
spindle_thread_tol = 0.6;//the difference between the male and female thread diameters, to allow for printing inaccuracies
|
|
spindle_end_diam = spindle_diam+10;//defines the diameter of the conical end of the spindle
|
|
x_offset = -50; //difference between the 'default' spindle location [0,0]
|
|
y_offset = -20; //and the 'high capacity' spindle location
|
|
hole_spindle = [x_offset,y_offset]; //
|
|
extra_spare_offset = 11.5;//11.5 places the spare spindle between the enclosure frame screws, so that it can be screwed fully in
|
|
hole_spare = [58.2+extra_spare_offset,81.65+extra_spare_offset]; //
|
|
|
|
//Screw hole definitions
|
|
hole1 = [43.95,95.9,0];// coordinates of the three screw/nut holes
|
|
hole2 = [72.45,67.4,0];// relative to main spindle origin
|
|
hole3 = [43.95-60,95.9,0]; //version 2 location of third mounting hole
|
|
//hole3 = [72.45,7.4,0]; //version 1 location of third mounting hole
|
|
hex_ap=6.3;//'across points' dimension of hex nut slot, allowing for printing inaccuracies.
|
|
//6.3 works for M3 nuts with Prusament PETG on my Prusa MK4, and gives tight push-fit. YMMV. Use the test pieces to check
|
|
//Any over-extrusion will make the nut holes smaller and may make the nuts difficult to insert.
|
|
|
|
//parameters to define the pattern of hexagons in the main bracket
|
|
hex_rad = 20;//15;//the radius of a circle that encloses the hexagon
|
|
hex_sepn = 3;//4;//the width of the dividing lines between adjacent hexagons
|
|
hex_cols = 5;//the number of columns and rows of hexagons to fill the bracket space
|
|
hex_rows = 6;//increase or decrease so that there are enough hexagons with the specified dimensions to cover the bracket
|
|
hex_depth = 12;//depth/2;// depth of hexagon lattice. Also defines the depth of the spindle reinforcing bosses
|
|
|
|
mirror = if_mirror ? [1,0,0]:[0,0,0];//create mirror vector depending on 'if_mirror' option
|
|
|
|
//*************************** Create the STLs **************************************
|
|
// prints the complete set of bracket, four spindles and two extension pieces
|
|
full_set(if_bracket=true,if_ext=false,if_ext50=false,if_75=false,if_90=false,if_125=false,if_165=false);
|
|
|
|
//print a couple of test pieces to check screw threads and nut slot dimensions for a given filament/printer setting
|
|
//test_pieces();
|
|
|
|
//generate modifiers for use in PrusaSlicer in case different settings are required for the thread sections
|
|
//modifiers();
|
|
|
|
//make a piece to test the spare spindle location
|
|
//spare_test();
|
|
|
|
//*************************** Component modules **************************************
|
|
module full_set(if_bracket=false,if_ext=false,if_50=false,if_75=false,if_90=false,if_125=false,if_165=false){// makes the complete set of bracket, 75mm, 90mm and 165mm spindles, and 75mm extension
|
|
if(if_bracket) bracket();
|
|
if(if_ext) translate([70,20,0]) spindle_ext();
|
|
if(if_ext50) translate([75,-15,0]) spindle_ext(length=50);
|
|
if(if_75) translate([60,70,0]) spindle();
|
|
if(if_90) translate([45,120,0]) spindle(length=90);
|
|
if(if_125) translate([-14,130,0]) spindle(length=125);
|
|
if(if_165) translate([-60,130,0]) spindle(length=165);
|
|
}
|
|
|
|
module test_pieces(){//makes a couple of test pieces to test the fit between the male and femaile threads, and the dimensions of a deep nut slot
|
|
translate([40,0,0])
|
|
difference(){
|
|
cylinder(d=spindle_diam,h=25);
|
|
female_thread();
|
|
}
|
|
difference(){
|
|
translate([0,0,0]) spindle(length=25);
|
|
translate([0,0,depth]) rotate([180,0,0]) deep_nut_slot();
|
|
}
|
|
}
|
|
|
|
module bracket(){// makes the main mounting bracket
|
|
mirror(mirror)
|
|
translate([0,0,depth]) rotate([180,0,180]) {
|
|
difference(){
|
|
raw_bracket();
|
|
translate(hole1) rotate([0,0,-15]) deep_nut_slot();
|
|
translate(hole2) rotate([0,0,-15]) deep_nut_slot();
|
|
if (third_hole) translate(hole3) deep_nut_slot();
|
|
mirror(mirror) female_thread();//spindle hole at [0,0]
|
|
if(second_spindle) translate(hole_spindle) mirror(mirror) female_thread();//spindle hole for larger diameter spools
|
|
if(spare_spindle) translate(hole_spare) mirror(mirror) female_thread();//spindle hole for spare storage
|
|
}
|
|
}
|
|
}
|
|
|
|
module spindle(length=spindle_length){//makes a spindle with a specified length. Defaults to 'spindle_length'
|
|
cylinder(h=2,d=spindle_end_diam);
|
|
translate([0,0,2]) cylinder(h=4,d1=spindle_end_diam,d2=spindle_diam);
|
|
translate([0,0,6]) cylinder(d=spindle_diam,h=length);
|
|
translate([0,0,length+6]) male_thread();
|
|
}
|
|
|
|
module spindle_ext(length=spindle_length){//makes a spindle extension with a specified length. Defaults to 'spindle_length'
|
|
difference(){
|
|
cylinder(d=spindle_diam,h=length);
|
|
female_thread();
|
|
}
|
|
translate([0,0,length]) male_thread();
|
|
}
|
|
|
|
module raw_bracket(){//makes the basic bracket before adding the nut slots and spindle screw threads
|
|
|
|
//hexagon lattice
|
|
translate([0,0,depth-hex_depth])
|
|
difference(){
|
|
// linear_extrude(depth) outline();
|
|
linear_extrude(hex_depth) offset(r=-0.1) outline();
|
|
translate([45,40,0]) rotate([90,0,0]) hexagons(r=hex_rad,s=hex_sepn,n_cols=hex_cols,n_rows=hex_rows);
|
|
}
|
|
|
|
//outer frame
|
|
difference(){
|
|
linear_extrude(depth) outline();
|
|
// linear_extrude(depth) offset(r=-8) outline();
|
|
linear_extrude(depth) offset(r=-frame_width) outline();
|
|
}
|
|
|
|
//screw hole 1
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
translate(hole1) cylinder(d=18,h=depth);
|
|
}
|
|
//screw hole 2
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
translate(hole2) cylinder(d=18,h=depth);
|
|
}
|
|
//screw hole 3
|
|
if (third_hole){
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
translate(hole3) cylinder(d=18,h=depth);
|
|
}
|
|
}
|
|
|
|
//default spindle with boss
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
// cylinder(d=34.5,h=depth);
|
|
translate([0,0,depth-hex_depth]) cylinder(d=spindle_thread+2*frame_width,h=hex_depth);
|
|
}
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
// cylinder(d=34.5,h=depth);
|
|
translate([0,0,0]) cylinder(d=spindle_diam,h=depth);
|
|
}
|
|
|
|
//high capacity spindle with boss
|
|
if(second_spindle){
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
// translate(hole_spindle) cylinder(d=34.5,h=depth);
|
|
translate(hole_spindle) translate([0,0,depth-hex_depth]) cylinder(d=spindle_thread+2*frame_width,h=hex_depth);
|
|
}
|
|
intersection(){
|
|
linear_extrude(depth) outline();
|
|
// translate(hole_spindle) cylinder(d=34.5,h=depth);
|
|
translate(hole_spindle) cylinder(d=spindle_diam,h=depth);
|
|
}
|
|
}
|
|
|
|
//extra lip around mounting holes
|
|
// translate([0,0,-1.5])
|
|
translate([0,0,-0.75])
|
|
intersection(){
|
|
// translate([30.8,104.3,0])
|
|
translate([60,85.6,0])
|
|
// rotate([0,0,-45]) cube([75,15,1.5]);
|
|
rotate([0,0,-45]) cube([80,15,1.51],center=true);
|
|
linear_extrude(depth) outline();
|
|
}
|
|
|
|
//spare spindle storage hole
|
|
if (spare_spindle) {
|
|
overlap = 0.1;//to ensure spare overlaps the bracket everywhere, to avoid meshing errors
|
|
translate([0,0,4])
|
|
linear_extrude(depth-4)
|
|
hull(){
|
|
translate(hole_spare) circle(d=((64.38-54.2)^2+(77.65-87.82)^2)^0.5+2*frame_width+2*overlap);
|
|
translate([64.38,77.65,0]) circle(d=9.95+overlap);
|
|
translate([54.2,87.82,0]) circle(d=9.95+overlap);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
module modifiers(){//makes modifiers for screw thread sections - may be useful for defining different print settings for screw threads
|
|
translate([0,0,depth]) rotate([180,0,180]) {
|
|
translate(hole_spindle) cylinder(d=spindle_diam,h=depth);
|
|
translate([0,0,0]) cylinder(d=spindle_diam,h=depth);
|
|
if(second_spindle) translate([0,0,4]) translate(hole_spare) cylinder(h=depth-4,d=spindle_diam);
|
|
}
|
|
}
|
|
|
|
module male_thread(length = depth, diam=spindle_thread,taper=true, trim=true){//makes the male threaded section for the spindle and the spindle extension
|
|
translate([0,0,length])
|
|
rotate([180,0,0])
|
|
difference(){
|
|
ScrewThread(outer_diam=diam, height=length, pitch=0, tooth_angle=30, tolerance=0.4, tip_height=0, tooth_height=0, tip_min_fract=0);
|
|
if(taper){
|
|
difference(){
|
|
translate([0,0,0]) cylinder(h=5,d1=diam*0.8+9,d2=diam+6);
|
|
translate([0,0,0]) cylinder(h=5,d1=diam*0.8,d2=diam);
|
|
}
|
|
}
|
|
if(trim){
|
|
difference(){
|
|
cylinder(d=spindle_thread+5,h=depth);
|
|
cylinder(d=spindle_thread-1,h=depth);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
module female_thread(length=depth+1,diam=spindle_thread+spindle_thread_tol,taper=false){//makes the female threaded section for subtracting from the spindle extension and the main bracket
|
|
male_thread(length = length, diam=diam,taper=false, trim=false);
|
|
cylinder(d=diam-3,h=depth+1);
|
|
}
|
|
|
|
module outline(){//defines the outline of the bracket
|
|
difference(){
|
|
hull(){
|
|
translate(hole1) circle(d=18);
|
|
translate(hole2) circle(d=18);
|
|
if (third_hole) translate(hole3) circle(d=18);
|
|
// translate(hole_spindle) circle(d=33);
|
|
// circle(d=33);
|
|
if(second_spindle) translate(hole_spindle) circle(d=spindle_thread+2*frame_width);
|
|
circle(d=spindle_thread+2*frame_width);
|
|
// translate(hole_spare) circle(d=33);
|
|
}
|
|
hull(){
|
|
translate([64.38,77.65,0]) circle(d=9.95);
|
|
translate([54.2,87.82,0]) circle(d=9.95);
|
|
translate([64.38+10,77.65+10,0]) circle(d=9.95);
|
|
translate([54.2+10,87.82+10,0]) circle(d=9.95);
|
|
}
|
|
}
|
|
}
|
|
|
|
module deep_nut_slot(){//makes a nut slot for use in deep sections. Uses a wider slot above the main nut slot, as used by Prusa in the original spool holder
|
|
translate([0,0,10.4]) rotate([180,0,0]) basic_nut_slot(hex_diam = hex_ap,bolt_diam = 3.2,recess = 3.6,bolt_length = 10.4+1.6);
|
|
translate([0,0,10]) linear_extrude(2.1,scale=1.8) hex_nut(r=hex_ap/2,points=false);
|
|
translate([0,0,10+2.1]) linear_extrude(5.9) hex_nut(r=1.8*hex_ap/2,points=false);
|
|
translate([0,0,10+2.1+5.9]) linear_extrude(0.6,scale=1.2) hex_nut(r=1.8*hex_ap/2,points=false);
|
|
}
|
|
|
|
module basic_nut_slot(hex_diam,bolt_diam,recess,bolt_length){//makes a basic nut slot, with small circular holes at the vertices of the hexagonal nut
|
|
//hex_diam = diameter of circle enclosing the hexagon
|
|
//bolt_diam = diameter of threaded part of bolt
|
|
//recess = depth of nut recess
|
|
//bolt_length = total length of bolt hole, including nut recess
|
|
cylinder(d=bolt_diam,h=bolt_length);
|
|
linear_extrude(recess) hex_nut(r=hex_diam/2);
|
|
intersection(){
|
|
linear_extrude(recess+layer_ht) hex_nut(r=hex_diam/2);
|
|
translate([-hex_diam/2,-bolt_diam/2,0]) cube([hex_diam,bolt_diam,recess+layer_ht]);
|
|
}
|
|
translate([-bolt_diam/2,-bolt_diam/2,0]) cube([bolt_diam,bolt_diam,recess+2*layer_ht]);
|
|
}
|
|
|
|
module hexagons(r,s,n_cols,n_rows){//makes a panel of extruded hexagons
|
|
cols = round(n_cols/2)==n_cols/2 ? n_cols : n_cols+1;//make cols an even number
|
|
l = 2*r*cos(30)+s;
|
|
for(col = [-cols/2 : cols/2]){
|
|
for(row = [-n_rows/2 : n_rows/2]){
|
|
offset_y = round(col/2)==col/2 ? l/2 : 0;
|
|
translate([col*l*cos(30),0,row*l+offset_y]) hexagon(r);
|
|
}
|
|
}
|
|
}
|
|
|
|
module hexagon(r){//makes a single hexagon extruded to the depth of the bracket
|
|
rotate([0,30,0])
|
|
rotate([-90,0,0])
|
|
linear_extrude(depth)
|
|
hex_nut(r,points=false);
|
|
}
|
|
|
|
module hex_nut(r,points=true){//makes a 2D hexagon with a specified radius. The boolean 'points' parameter specifies whether ther should be small circles at the vertices of the hexagon.
|
|
x = r*cos(30);
|
|
y = r*sin(30);
|
|
hex = [
|
|
[x,y],
|
|
[0,r],
|
|
[-x,y],
|
|
[-x,-y],
|
|
[0,-r],
|
|
[x,-y]
|
|
];
|
|
polygon(hex);
|
|
if(points) for(p=hex) translate(p) circle(d=r/6);
|
|
}
|
|
|
|
module spare_test(){//makes a test piece to test the location of the spare spindle
|
|
difference(){
|
|
rotate([0,0,45]) bracket();
|
|
translate([-50,-30,0]) cube([100,122,depth]);
|
|
}
|
|
}
|
|
|