|
// Machining fixtures for CD and hard drive platters |
|
// Ed Nisley KE4ZNU February … September 2016 |
|
// 2019-08 split from tube base models |
|
|
|
PlatterName = "CD"; // [3.5inch,CD] |
|
|
|
CNCName = "3018"; // [3018,Sherline] |
|
|
|
TapeFlange = true; // Generate tape attachment |
|
|
|
PlateThick = 5.0; // [3.0,5.0,10.0,15.0] |
|
|
|
RecessDepth = 4.0; // [0.0,2.0,4.0] |
|
|
|
//- Extrusion parameters must match reality! |
|
|
|
/* [Hidden] */ |
|
|
|
ThreadThick = 0.25; |
|
ThreadWidth = 0.40; |
|
|
|
HoleWindage = 0.2; |
|
|
|
Protrusion = 0.1; // make holes end cleanly |
|
|
|
inch = 25.4; |
|
|
|
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); |
|
|
|
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes |
|
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2); |
|
FixDia = Dia / cos(180/Sides); |
|
cylinder(d=(FixDia + HoleWindage),h=Height,$fn=Sides); |
|
} |
|
|
|
|
|
ID = 0; |
|
OD = 1; |
|
LENGTH = 2; |
|
|
|
//———————- |
|
// Dimensions |
|
|
|
P_NAME = 0; // platter name |
|
P_ID = 1; // … inner diameter |
|
P_OD = 2; // … outer diameter |
|
P_THICK = 3; // … thickness |
|
|
|
PlatterData = [ |
|
["3.5inch", 25.0, 95.0, 1.75], |
|
["CD", 15.0, 120.0, 1.20], |
|
]; |
|
|
|
PlatterSides = 3*4*5; // polygon approximation |
|
|
|
B_NAME = 0; // machine name |
|
B_OC = 1; // … platform screw OC, use small integer for slot |
|
B_STUD = 2; // … screw OD clearance |
|
|
|
BaseData = [ |
|
["3018", [5.0, 45.0], 6.0], // slots along X axis |
|
["Sherline", [1.16*inch,1.16*inch], 5.0], // tooling plate |
|
|
|
]; |
|
|
|
PlateRound = 10.0; // corner radius |
|
|
|
FlangeSize = [5.0,5.0,3*ThreadThick]; // all-around tape flange |
|
|
|
//– calculate values based on input parameters |
|
|
|
PI = search([PlatterName],PlatterData,1,0)[P_NAME]; // get platter index |
|
echo(str("Platter: ",PlatterName)); |
|
Platter = [PlatterData[PI][P_ID], |
|
PlatterData[PI][P_OD], |
|
PlatterData[PI][P_THICK]]; |
|
|
|
BI = search([CNCName],BaseData,1,0)[B_NAME]; // get base index |
|
echo(str("Machine: ",CNCName)); |
|
|
|
AlignOC = IntegerMultiple(Platter[OD],10); |
|
echo(str("Alignment pip offset: ±",AlignOC/2)); |
|
AlignSlot = [3*ThreadWidth,10.0,3*ThreadThick]; |
|
|
|
StudClear = BaseData[BI][B_STUD]; // … clearance |
|
|
|
StudOC = [IntegerMultiple(AlignOC + 2*StudClear,BaseData[BI][B_OC].x), // … screw spacing |
|
BaseData[BI][B_OC].y]; |
|
echo(str("Stud spacing: ",StudOC)); |
|
NumStuds = [2,1 + 2*floor(Platter[OD] / StudOC.y)]; // holes only along ±X edges |
|
echo(str("Stud holes: ",NumStuds)); |
|
|
|
BasePlate = [(20 + StudOC.x*ceil(Platter[OD] / StudOC.x)), |
|
(10 + AlignOC), |
|
PlateThick]; |
|
echo(str("Plate: ",BasePlate)); |
|
|
|
Flange = [BasePlate.x + 2*FlangeSize.x,BasePlate.y + 2*FlangeSize.y,FlangeSize.z]; |
|
echo(str("Flange: ",Flange)); |
|
|
|
|
|
//———————- |
|
// Drilling fixture for disk platters |
|
|
|
module PlatterFixture() { |
|
|
|
difference() { |
|
union() { |
|
hull() // basic plate shape |
|
for (i=[-1,1], j=[-1,1]) |
|
translate([i*(BasePlate.x/2 – PlateRound),j*(BasePlate.y/2 – PlateRound),0]) |
|
cylinder(r=PlateRound,h=BasePlate.z,$fn=4*4); |
|
if (TapeFlange) |
|
hull() |
|
for (i=[-1,1], j=[-1,1]) |
|
translate([i*(Flange.x/2 – PlateRound), |
|
j*(Flange.y/2 – PlateRound), |
|
0]) |
|
cylinder(r=PlateRound,h=FlangeSize.z,$fn=4*4); |
|
} |
|
|
|
for (i=[-1,0,1], j=[-1,0,1]) // origin pips |
|
translate([i*AlignOC/2,j*AlignOC/2,BasePlate.z – 2*ThreadThick]) |
|
cylinder(d=4*ThreadWidth,h=1,$fn=6); |
|
|
|
for (i=[-1,1], j=[-1,1]) { // alignment slots |
|
translate([i*(AlignOC + AlignSlot.x)/2, |
|
j*Platter[OD]/4, |
|
(BasePlate.z – AlignSlot.z/2 + Protrusion/2)]) |
|
cube(AlignSlot + [0,0,Protrusion],center=true); |
|
translate([i*Platter[OD]/4, |
|
j*(AlignOC + AlignSlot.x)/2, |
|
(BasePlate.z – AlignSlot.z/2 + Protrusion/2)]) |
|
rotate(90) |
|
cube(AlignSlot + [0,0,Protrusion],center=true); |
|
} |
|
|
|
for (i=[-1,1], j=[-floor(NumStuds.y/2):floor(NumStuds.y/2)]) // mounting stud holes |
|
translate([i*StudOC.x/2,j*StudOC.y/2,-Protrusion]) |
|
rotate(180/6) |
|
PolyCyl(StudClear,BasePlate.z + 2*Protrusion,6); |
|
|
|
translate([0,0,-Protrusion]) // center clamp hole |
|
rotate(180/6) |
|
PolyCyl(StudClear,BasePlate.z + 2*Protrusion,6); |
|
|
|
translate([0,0,BasePlate.z – Platter[LENGTH]]) // disk locating recess |
|
rotate(180/PlatterSides) |
|
linear_extrude(height=(Platter[LENGTH] + Protrusion),convexity=2) |
|
difference() { |
|
circle(d=(Platter[OD] + 2*HoleWindage),$fn=PlatterSides); |
|
circle(d=Platter[ID] – HoleWindage,$fn=PlatterSides); |
|
} |
|
|
|
translate([0,0,BasePlate.z – RecessDepth]) // drilling recess |
|
rotate(180/PlatterSides) |
|
linear_extrude(height=(RecessDepth + Protrusion),convexity=2) |
|
difference() { |
|
circle(d=(Platter[OD] – 10),$fn=PlatterSides); |
|
circle(d=(Platter[ID] + 10),$fn=PlatterSides); |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
//———————- |
|
// Build it |
|
|
|
PlatterFixture(); |
|
|