Created
September 21, 2016 23:50
-
-
Save ednisley/11e1c3bd828f41dda726bf29f918c069 to your computer and use it in GitHub Desktop.
OpenSCAD source code: Improved Compression clamp for Octal tube bases
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
// Vacuum Tube LED Lights | |
// Ed Nisley KE4ZNU February ... September 2016 | |
Layout = "TubeClamp"; // Cap LampBase USBPort Bushings | |
// Socket(s) Cap (Build)FinCap Platter[Base|Fixture] | |
// TubeClamp PlatterParts | |
DefaultSocket = "Octal"; | |
Section = false; // cross-section the object | |
Support = true; | |
//- Extrusion parameters must match reality! | |
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); | |
//---------------------- | |
// Dimensions | |
// https://en.wikipedia.org/wiki/Tube_socket#Summary_of_Base_Details | |
// punch & screw OC modified for drive platter chassis plate | |
// platter = 25 mm ID | |
// CD = 15 mm ID with raised ring at 37 mm, needs screw head clearance | |
T_NAME = 0; // common name | |
T_NUMPINS = 1; // total, with no allowance for keying | |
T_PINBCD = 2; // tube pin circle diameter | |
T_PINOD = 3; // ... diameter | |
T_PINLEN = 4; // ... length (must also clear evacuation tip / spigot) | |
T_HOLEOD = 5; // nominal panel hole from various sources | |
T_PUNCHOD = 6; // panel hole optimized for inch-size Greenlee punches | |
T_BASEOD = 7; // base OD | |
T_BULBOD = 8; // glass envelope OD | |
T_PIPEOD = 9; // light pipe from LED to tube base (clear evac tip / spigot) | |
T_SCREWOC = 10; // mounting screw holes | |
T_PLATECAP = 11; // nonzero to print a plate cap | |
// Name pins BCD dia length hole punch base bulb pipe screw cap | |
TubeData = [ | |
["Mini7", 8, 9.53, 1.016, 7.0, 16.0, 25.0, 18.0, 18.0, 5.0, 35.0, 0], // punch 11/16, screw 22.5 OC | |
// ["Octal", 8, 17.45, 2.36, 11.0, 36.2, (8 + 1)/8 * inch, 32.0, 38.1, 11.5, 47.0, 1], // screw 39.0 OC, base 32 or 39 | |
["Octal", 8, 17.45, 2.36, 11.0, 36.2, 25.0, 29.0, 38.1, 11.5, 42.0, 1], // platter + 4 mm screws | |
["Noval", 10, 11.89, 1.1016, 7.0, 22.0, 25.0, 21.0, 21.0, 7.5, 35.0, 0], // punch 7/8, screw 28.0 OC | |
["Magnoval", 10, 17.45, 1.27, 9.0, 29.7, (4 + 1)/4 * inch, 46.0, 46.0, 12.4, 38.2, 0], // similar to Novar | |
// ["Duodecar", 13, 19.10, 1.05, 9.0, 32.0, (4 + 1)/4 * inch, 38.0, 38.0, 12.5, 47.0, 1], // screw was 39.0 OC | |
["Duodecar", 13, 19.10, 1.05, 9.0, 25.0, 25.0, 38.0, 38.0, 12.5, 42.0, 1], // fit un-punched drive platter | |
]; | |
ID = 0; | |
OD = 1; | |
LENGTH = 2; | |
Pixel = [7.0,10.0,3.0]; // ID = contact patch, OD = PCB dia, LENGTH = overall thickness | |
PixelRecessHeight = 1.55*Pixel[LENGTH]; // enough of a recess to allow for tube top curvature | |
SocketNut = // socket mounting: threaded insert or nut recess | |
// [3.5,5.2,7.2] // 6-32 insert | |
[4.0,6.0,5.9] // 4 mm short insert | |
; | |
NutSides = 8; | |
SocketShim = 2*ThreadThick; // between pin holes and pixel top | |
SocketFlange = 1.5; // rim around socket below punchout | |
PanelThick = 1.5; // socket extension through punchout | |
FinCutterOD = 1/8 * inch; | |
FinCapSize = [(Pixel[OD] + 2*FinCutterOD),30.0,(10.0 + 2*Pixel[LENGTH])]; | |
USBPCB = | |
// [28,16,6.5] // small Sparkfun knockoff | |
[36,18 + 1,5.8 + 0.4] // Deek-Robot fake FTDI with ISP header | |
; | |
Platter = [25.0,95.0,1.26]; // hard drive platter dimensions | |
PlatterSides = 8*4; // polygon approximation | |
//---------------------- | |
// Useful routines | |
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); | |
} | |
//---------------------- | |
// Tube cap | |
CapTube = [4.0,3/16 * inch,10.0]; // brass tube for flying lead to cap LED | |
CapSize = [Pixel[ID],(Pixel[OD] + 2.0),(CapTube[OD] + 2.0*Pixel[LENGTH])]; | |
CapSides = 8*4; | |
SkirtOD = CapSize[OD] + 4*ThreadWidth; | |
CapTubeHeight = (CapSize[LENGTH] + PixelRecessHeight)/2; | |
CapTubeBossOD = 1*ThreadWidth + 2*(CapTubeHeight - PixelRecessHeight)/cos(180/8); | |
module Cap() { | |
difference() { | |
union() { | |
cylinder(d=CapSize[OD],h=(CapSize[LENGTH]),$fn=CapSides); // main cap body | |
translate([0,0,CapSize[LENGTH]]) // rounded top | |
scale([1.0,1.0,0.65]) | |
sphere(d=CapSize[OD]/cos(180/CapSides),$fn=CapSides); // cos() fixes slight undersize vs cylinder | |
cylinder(d1=SkirtOD,d2=CapSize[OD],h=PixelRecessHeight,$fn=CapSides); // skirt | |
translate([0,-SkirtOD/2,CapTubeHeight]) // boss around brass tube | |
rotate([-90,0,0]) | |
rotate(180/8) | |
cylinder(d=CapTubeBossOD,h=CapTube[LENGTH],$fn=8); | |
} | |
translate([0,0,-Protrusion]) // bore for wiring to LED | |
PolyCyl(CapSize[ID],(CapSize[LENGTH] + 3*ThreadThick + Protrusion),CapSides); | |
translate([0,0,-Protrusion]) // PCB recess with clearance for tube dome | |
PolyCyl(Pixel[OD],(PixelRecessHeight + Protrusion),CapSides); | |
translate([0,0,(PixelRecessHeight - Protrusion)]) // small step + cone to retain PCB | |
cylinder(d1=(Pixel[OD]/cos(180/CapSides) + HoleWindage),d2=Pixel[ID],h=(Pixel[LENGTH] + Protrusion),$fn=CapSides); | |
translate([0,0,CapTubeHeight]) // hole for brass tube holding wire loom | |
rotate([90,0,0]) rotate(180/8) | |
PolyCyl(CapTube[OD],CapSize[OD],8); | |
} | |
} | |
//---------------------- | |
// Heatsink tube cap | |
module FinCap() { | |
CableOD = 3.5; // cable + braid diameter | |
BulbOD = 3.75 * inch; // bulb OD; use 10 inches for flat | |
echo(str("Fin Cutter: ",FinCutterOD)); | |
FinSides = 2*4; | |
BulbRadius = BulbOD / 2; | |
BulbDepth = BulbRadius - sqrt(pow(BulbRadius,2) - pow(FinCapSize[OD],2)/4); | |
echo(str("Bulb OD: ",BulbOD," recess: ",BulbDepth)); | |
NumFins = floor(PI*FinCapSize[ID] / (2*FinCutterOD)); | |
FinAngle = 360 / NumFins; | |
echo(str("NumFins: ",NumFins," angle: ",FinAngle," deg")); | |
difference() { | |
union() { | |
cylinder(d=FinCapSize[ID],h=FinCapSize[LENGTH],$fn=2*NumFins); // main body | |
for (i = [0:NumFins - 1]) // fins | |
rotate(i * FinAngle) | |
hull() { | |
translate([FinCapSize[ID]/2,0,0]) | |
rotate(180/FinSides) | |
cylinder(d=FinCutterOD,h=FinCapSize[LENGTH],$fn=FinSides); | |
translate([(FinCapSize[OD] - FinCutterOD)/2,0,0]) | |
rotate(180/FinSides) | |
cylinder(d=FinCutterOD,h=FinCapSize[LENGTH],$fn=FinSides); | |
} | |
rotate(FinAngle/2) // cable entry boss | |
translate([FinCapSize[ID]/2,0,FinCapSize[LENGTH]/2]) | |
cube([FinCapSize[OD]/4,FinCapSize[OD]/4,FinCapSize[LENGTH]],center=true); | |
} | |
for (i = [1:NumFins - 1]) // fin inner gullets, omit cable entry side | |
rotate(i * FinAngle + FinAngle/2) // joint isn't quite perfect, but OK | |
translate([FinCapSize[ID]/2,0,-Protrusion]) | |
rotate(0*180/FinSides) | |
cylinder(d=FinCutterOD/cos(180/FinSides),h=(FinCapSize[LENGTH] + 2*Protrusion),$fn=FinSides); | |
translate([0,0,-Protrusion]) // PCB recess | |
PolyCyl(Pixel[OD],(PixelRecessHeight + Protrusion),FinSides); | |
PolyCyl(Pixel[ID],(FinCapSize[LENGTH] - 3*ThreadThick),FinSides); // bore for LED wiring | |
translate([0,0,(FinCapSize[LENGTH] - 3*ThreadThick - 2*CableOD/(2*cos(180/8)))]) // cable inlet | |
rotate(FinAngle/2) rotate([0,90,0]) rotate(180/8) | |
PolyCyl(CableOD,FinCapSize[OD],8); | |
if (BulbOD <= 10.0 * inch) // curve for top of bulb | |
translate([0,0,-(BulbRadius - BulbDepth + 2*ThreadThick)]) // ... slightly flatten tips | |
sphere(d=BulbOD,$fn=16*FinSides); | |
} | |
} | |
//---------------------- | |
// Aperture for USB-to-serial adapter snout | |
// These are all magic numbers, of course | |
module USBPort() { | |
translate([0,USBPCB[0]]) | |
rotate([90,0,0]) | |
linear_extrude(height=USBPCB[0]) | |
polygon(points=[ | |
[0,0], | |
[USBPCB[1]/2,0], | |
[USBPCB[1]/2,0.5*USBPCB[2]], | |
[USBPCB[1]/3,USBPCB[2]], | |
[-USBPCB[1]/3,USBPCB[2]], | |
[-USBPCB[1]/2,0.5*USBPCB[2]], | |
[-USBPCB[1]/2,0], | |
]); | |
} | |
//---------------------- | |
// Box for Leviton ceramic lamp base | |
module LampBase() { | |
Insert = [3.5,5.2,7.2]; // 6-32 brass insert to match standard electrical screws | |
Bottom = 3.0; | |
Base = [4.0*inch,4.5*inch,20.0 + Bottom]; | |
Sides = 12*4; | |
Retainer = [3.5,11.0,1.0]; // flat fiber washer holding lamp base screws in place | |
StudSides = 8; | |
StudOC = 3.5 * inch; | |
Stud = [Insert[OD], // insert for socket screws | |
min(15.0,1.5*(Base[ID] - StudOC)/cos(180/StudSides)), // OD = big enough to merge with walls | |
(Base[LENGTH] - Retainer[LENGTH])]; // leave room for retainer | |
union() { | |
difference() { | |
rotate(180/Sides) | |
cylinder(d=Base[OD],h=Base[LENGTH],$fn=Sides); | |
rotate(180/Sides) | |
translate([0,0,Bottom]) | |
cylinder(d=Base[ID],h=Base[LENGTH],$fn=Sides); | |
translate([0,-Base[OD]/2,Bottom + 1.2]) // mount on double-sided foam tape | |
rotate(0) | |
USBPort(); | |
} | |
for (i = [-1,1]) | |
translate([i*StudOC/2,0,0]) | |
rotate(180/StudSides) | |
difference() { | |
cylinder(d=Stud[OD],h=Stud[LENGTH],$fn=StudSides); | |
translate([0,0,Bottom]) | |
PolyCyl(Stud[ID],(Stud[LENGTH] - (Bottom - Protrusion)),6); | |
} | |
} | |
} | |
//---------------------- | |
// Base for hard drive platters | |
module PlatterBase(TubeName = DefaultSocket) { | |
PCB = | |
[36,18,3] // Arduino Pro Mini | |
; | |
Tube = search([TubeName],TubeData,1,0)[0]; | |
SocketHeight = Pixel[LENGTH] + SocketShim + TubeData[Tube][T_PINLEN] - PanelThick; | |
echo(str("Base for ",TubeData[Tube][0]," socket")); | |
Overhang = 5.5; // platter overhangs base by this much | |
Bottom = 4*ThreadThick; | |
Base = [(Platter[OD] - 3*Overhang), // smaller than 3.5 inch Sch 40 PVC pipe... | |
(Platter[OD] - 2*Overhang), | |
2.0 + max(PCB[1],(2.0 + SocketHeight + USBPCB[2])) + Bottom]; | |
Sides = 24*4; | |
echo(str(" Height: ",Base[2]," mm")); | |
Insert = // platter mounting: threaded insert or nut recess | |
// [3.5,5.2,7.2] // 6-32 insert | |
[3.7,5.0,8.0] // 3 mm - long insert | |
; | |
NumStuds = 4; | |
StudSides = 8; | |
Stud = [Insert[OD], // insert for socket screws | |
2*Insert[OD], // OD = big enough to merge with walls | |
Base[LENGTH]]; // leave room for retainer | |
StudBCD = floor(Base[OD] - Stud[OD]/cos(180/StudSides)); | |
echo(str("Platter screw BCD: ",StudBCD," mm")); | |
PCBInset = Base[ID]/2 - sqrt(pow(Base[ID]/2,2) - pow(PCB[0],2)/4); | |
union() { | |
difference() { | |
rotate(180/Sides) | |
cylinder(d=Base[OD],h=Base[LENGTH],$fn=Sides); | |
rotate(180/Sides) | |
translate([0,0,Bottom]) | |
cylinder(d=Base[ID],h=Base[LENGTH],$fn=Sides); | |
translate([0,-Base[OD]/2,Bottom + 1.2]) // mount PCB on foam tape | |
rotate(0) | |
USBPort(); | |
} | |
for (a = [0:(NumStuds - 1)]) // platter mounting studs | |
rotate(180/NumStuds + a*360/(NumStuds)) | |
translate([StudBCD/2,0,0]) | |
difference() { | |
rotate(180/(2*StudSides)) | |
cylinder(d=Stud[OD],h=Stud[LENGTH],$fn=2*StudSides); | |
translate([0,0,Bottom]) | |
rotate(180/StudSides) | |
PolyCyl(Stud[ID],(Stud[LENGTH] - (Bottom - Protrusion)),StudSides); | |
} | |
intersection() { // microcontroller PCB mounting plate | |
rotate(180/Sides) | |
cylinder(d=Base[OD],h=Base[LENGTH],$fn=Sides); | |
translate([-PCB[0]/2,(Base[ID]/2 - PCBInset),0]) | |
cube([PCB[0],Base[OD]/2,Base[LENGTH]],center=false); | |
} | |
difference() { | |
intersection() { // totally ad-hoc bridge around USB opening | |
rotate(180/Sides) | |
cylinder(d=Base[OD],h=Base[LENGTH],$fn=Sides); | |
translate([-1.25*USBPCB[1]/2,-(Base[ID]/2),0]) | |
cube([1.25*USBPCB[1],2.0,Base[LENGTH]],center=false); | |
} | |
translate([0,-Base[OD]/2,Bottom + 1.2]) // mount PCB on foam tape | |
rotate(0) | |
USBPort(); | |
translate([0,-(Base[ID]/2 - 2.0 + 1*ThreadWidth),Bottom - 3*ThreadThick]) // legend | |
rotate([90,0,180]) | |
linear_extrude(height=1*ThreadWidth + Protrusion) { | |
translate([0,(Base[LENGTH] - 5.5),0]) | |
text(text=TubeName,size=4,font="Arial:style=Bold",halign="center"); | |
// translate([0,(Base[LENGTH] - 8.5),0]) | |
// text(text=str("BCD ",StudBCD),size=2,font="Arial",halign="center"); | |
translate([0,(Base[LENGTH] - 11),0]) | |
text(text="KE4ZNU",size=3,font="Arial",halign="center"); | |
} | |
} | |
} | |
} | |
//---------------------- | |
// Drilling fixture for disk platters | |
module PlatterFixture() { | |
StudOC = [1.16*inch,1.16*inch]; // Sherline tooling plate screw spacing | |
StudClear = 5.0; | |
AlignOffset = 100; | |
AlignBar = [3*ThreadWidth,10.0,3*ThreadThick]; | |
BasePlate = [(20 + StudOC[0]*ceil(Platter[OD] / StudOC[0])),(Platter[OD] + 10),7.0]; | |
PlateRound = 10.0; // corner radius | |
difference() { | |
hull() // basic block | |
for (i=[-1,1], j=[-1,1]) | |
translate([i*(BasePlate[0]/2 - PlateRound),j*(BasePlate[1]/2 - PlateRound),0]) | |
cylinder(r=PlateRound,h=BasePlate[2],$fn=4*4); | |
for (i=[-1,1], j=[-1,1]) // index marks | |
translate([i*AlignOffset/2,j*AlignOffset/2,BasePlate[2] - 2*ThreadThick]) | |
cylinder(d=1.5,h=1,$fn=6); | |
for (i=[-1,1]) | |
translate([i*(AlignOffset + AlignBar[0])/2,0,(BasePlate[2] - AlignBar[2]/2 + Protrusion/2)]) | |
cube(AlignBar + [0,0,Protrusion],center=true); | |
for (j=[-1,1]) | |
translate([0,j*(AlignOffset + AlignBar[0])/2,(BasePlate[2] - AlignBar[2]/2 + Protrusion/2)]) | |
rotate(90) | |
cube(AlignBar + [0,0,Protrusion],center=true); | |
for (a=[0:90:270]) | |
rotate(a) | |
translate([(AlignBar[1]/2 + AlignBar[0]/2),0,(BasePlate[2] - AlignBar[2]/2 + Protrusion/2)]) | |
cube(AlignBar + [0,-Protrusion,Protrusion],center=true); | |
for (i=[-1,1], j=[-1,0,1]) // holes for tooling plate studs | |
translate([i*StudOC[0]*ceil(Platter[OD] / StudOC[0])/2,j*StudOC[0],-Protrusion]) | |
PolyCyl(StudClear,BasePlate[2] + 2*Protrusion,6); | |
translate([0,0,-Protrusion]) // center clamp hole | |
PolyCyl(StudClear,BasePlate[2] + 2*Protrusion,6); | |
translate([0,0,BasePlate[2] - Platter[LENGTH]]) // disk locating recess | |
rotate(180/PlatterSides) | |
linear_extrude(height=(Platter[LENGTH] + Protrusion),convexity=2) | |
difference() { | |
circle(d=(Platter[OD] + 1),$fn=PlatterSides); | |
circle(d=Platter[ID],$fn=PlatterSides); | |
} | |
translate([0,0,BasePlate[2] - 4.0]) // drilling recess | |
rotate(180/PlatterSides) | |
linear_extrude(height=(4.0 + Protrusion),convexity=2) | |
difference() { | |
circle(d=(Platter[OD] - 10),$fn=PlatterSides); | |
circle(d=(Platter[ID] + 10),$fn=PlatterSides); | |
} | |
} | |
} | |
//---------------------- | |
// Tube Socket | |
module Socket(Name = DefaultSocket) { | |
NumSides = 6*4; | |
Tube = search([Name],TubeData,1,0)[0]; | |
echo(str("Building ",TubeData[Tube][0]," socket")); | |
echo(str(" Punch: ",TubeData[Tube][T_PUNCHOD]," mm = ",TubeData[Tube][T_PUNCHOD]/inch," inch")); | |
echo(str(" Screws: ",TubeData[Tube][T_SCREWOC]," mm =",TubeData[Tube][T_SCREWOC]/inch," inch OC")); | |
OAH = Pixel[LENGTH] + SocketShim + TubeData[Tube][T_PINLEN]; | |
BaseHeight = OAH - PanelThick; | |
difference() { | |
union() { | |
linear_extrude(height=BaseHeight) // base outline | |
hull() { | |
circle(d=(TubeData[Tube][T_PUNCHOD] + 2*SocketFlange),$fn=NumSides); | |
for (i=[-1,1]) | |
translate([i*TubeData[Tube][T_SCREWOC]/2,0]) | |
circle(d=2.0*SocketNut[OD],$fn=NumSides); | |
} | |
cylinder(d=TubeData[Tube][T_PUNCHOD],h=OAH,$fn=NumSides); // boss in chassis punch hole | |
} | |
for (i=[0:(TubeData[Tube][T_NUMPINS] - 1)]) // tube pins | |
rotate(i*360/TubeData[Tube][T_NUMPINS]) | |
translate([TubeData[Tube][T_PINBCD]/2,0,(OAH - TubeData[Tube][T_PINLEN])]) | |
rotate(180/4) | |
PolyCyl(TubeData[Tube][T_PINOD],(TubeData[Tube][T_PINLEN] + Protrusion),4); | |
for (i=[-1,1]) // mounting screw holes & nut traps / threaded inserts | |
translate([i*TubeData[Tube][T_SCREWOC]/2,0,-Protrusion]) { | |
PolyCyl(SocketNut[OD],(SocketNut[LENGTH] + Protrusion),NutSides); | |
PolyCyl(SocketNut[ID],(OAH + 2*Protrusion),NutSides); | |
} | |
translate([0,0,-Protrusion]) { // LED recess | |
PolyCyl(Pixel[OD],(Pixel[LENGTH] + Protrusion),8); | |
} | |
translate([0,0,(Pixel[LENGTH] - Protrusion)]) { // light pipe | |
rotate(180/TubeData[Tube][T_NUMPINS]) | |
PolyCyl(TubeData[Tube][T_PIPEOD],(OAH + 2*Protrusion),TubeData[Tube][T_NUMPINS]); | |
} | |
for (i=[-1,1]) // cable retaining slots | |
translate([i*(Pixel[OD] + TubeData[Tube][T_SCREWOC])/4,0,(Pixel[LENGTH] - Protrusion)/2]) | |
cube([Pixel[LENGTH],TubeData[Tube][T_SCREWOC],(Pixel[LENGTH] + Protrusion)],center=true); | |
} | |
// Totally ad-hoc support structures ... | |
if (Support) { | |
color("Yellow") { | |
for (i=[-1,1]) // nut traps | |
translate([i*TubeData[Tube][T_SCREWOC]/2,0,(SocketNut[LENGTH] - ThreadThick)/2]) | |
for (a=[0:5]) | |
rotate(a*30 + 15) | |
cube([2*ThreadWidth,0.9*SocketNut[OD],(SocketNut[LENGTH] - ThreadThick)],center=true); | |
if (Pixel[OD] > TubeData[Tube][T_PIPEOD]) // support pipe only if needed | |
translate([0,0,(Pixel[LENGTH] - ThreadThick)/2]) | |
for (a=[0:7]) | |
rotate(a*22.5) | |
cube([2*ThreadWidth,0.9*Pixel[OD],(Pixel[LENGTH] - ThreadThick)],center=true); | |
} | |
} | |
} | |
//---------------------- | |
// Greenlee punch bushings | |
module PunchBushing(Name = DefaultSocket) { | |
PunchScrew = 9.5; | |
BushingThick = 3.0; | |
Tube = search([Name],TubeData,1,0)[0]; | |
echo(str("Building ",TubeData[Tube][0]," bushing")); | |
NumSides = 6*4; | |
difference() { | |
union() { | |
cylinder(d=Platter[ID],h=BushingThick,$fn=NumSides); | |
cylinder(d=TubeData[Tube][T_PUNCHOD],h=(BushingThick - Platter[LENGTH]),$fn=NumSides); | |
} | |
translate([0,0,-Protrusion]) | |
PolyCyl(PunchScrew,5.0,8); | |
} | |
} | |
//---------------------- | |
// Tube clamp | |
module TubeClamp(Name = DefaultSocket) { | |
Tube = search([Name],TubeData,1,0)[0]; | |
echo(str("Building ",TubeData[Tube][0]," clamp")); | |
ClampWidth = 37.0; // inside of clamp arch | |
ClampLength = 20; // along tube base | |
ClampScrew = [6.0,7.8,6.0]; // nose of clamp screw | |
ClampBlock = [4*ThreadWidth + TubeData[Tube][T_BULBOD], | |
4*ThreadWidth + TubeData[Tube][T_BULBOD], | |
ClampLength]; | |
difference() { | |
union() { | |
intersection() { | |
translate([0,0,ClampBlock[2]/2]) | |
rotate(45) | |
cube(ClampBlock,center=true); // V-block sides | |
translate([0,-ClampWidth/2,ClampBlock[2]/2]) | |
cube([ClampWidth,ClampWidth,ClampBlock[2]],center=true); // clamp sides | |
} | |
intersection() { | |
cylinder(d=ClampWidth,h=ClampBlock[2]); | |
translate([0,ClampWidth/4,ClampBlock[2]/2]) | |
cube([ClampWidth,ClampWidth/2,ClampBlock[2]],center=true); // clamp sides | |
} | |
} | |
translate([0,0,-Protrusion]) // remove tube base (remains centered) | |
cylinder(d=TubeData[Tube][T_BASEOD],h=(ClampLength + 2*Protrusion)); | |
translate([0,(ClampWidth/2 + TubeData[Tube][T_BASEOD]/2)/2,ClampBlock[LENGTH]/3]) | |
rotate([-90,0,0]) | |
PolyCyl(ClampScrew[ID],1*ClampScrew[LENGTH],6); // clamp screw recess | |
translate([0,-(6*ThreadWidth)/2,-Protrusion]) | |
cube([ClampWidth,6*ThreadWidth,(ClampLength + 2*Protrusion)]); // clamp relief slot | |
} | |
} | |
//---------------------- | |
// Build it | |
if (Layout == "Cap") { | |
if (Section) | |
difference() { | |
Cap(); | |
translate([-CapSize[OD],0,CapSize[LENGTH]]) | |
cube([2*CapSize[OD],2*CapSize[OD],3*CapSize[LENGTH]],center=true); | |
} | |
else | |
Cap(); | |
} | |
if (Layout == "FinCap") { | |
if (Section) render(convexity=5) | |
difference() { | |
FinCap(); | |
// translate([0,-FinCapSize[OD],FinCapSize[LENGTH]]) | |
// cube([2*FinCapSize[OD],2*FinCapSize[OD],3*FinCapSize[LENGTH]],center=true); | |
translate([-FinCapSize[OD],0,FinCapSize[LENGTH]]) | |
cube([2*FinCapSize[OD],2*FinCapSize[OD],3*FinCapSize[LENGTH]],center=true); | |
} | |
else | |
FinCap(); | |
} | |
if (Layout == "BuildFinCap") | |
translate([0,0,FinCapSize[LENGTH]]) | |
rotate([180,0,0]) | |
FinCap(); | |
if (Layout == "LampBase") | |
LampBase(); | |
if (Layout == "PlatterBase") | |
PlatterBase(); | |
if (Layout == "PlatterParts") { | |
Tube = search([DefaultSocket],TubeData,1,0)[0]; | |
echo(str("Parts for ",TubeData[Tube][T_NAME]," assembly")); | |
PlatterBase(); | |
translate([0.25*Platter[OD],-0.6*Platter[OD],0]) | |
rotate(0) | |
Socket(); | |
if (TubeData[Tube][T_PLATECAP]) | |
for (i=[-1,1]) | |
translate([(-0.25*Platter[OD] - i*Pixel[OD]),-0.6*Platter[OD],0]) | |
rotate(i*90) | |
Cap(); | |
} | |
if (Layout == "PlatterFixture") | |
PlatterFixture(); | |
if (Layout == "USBPort") | |
USBPort(); | |
if (Layout == "TubeClamp") | |
TubeClamp(); | |
if (Layout == "Bushings") | |
PunchBushing(); | |
if (Layout == "Socket") | |
if (Section) { | |
difference() { | |
Socket(); | |
translate([-100/2,0,-Protrusion]) | |
cube([100,50,50],center=false); | |
} | |
} | |
else | |
Socket(); | |
if (Layout == "Sockets") { | |
translate([0,50,0]) | |
Socket("Mini7"); | |
translate([0,20,0]) | |
Socket("Octal"); | |
translate([0,-15,0]) | |
Socket("Duodecar"); | |
translate([0,-50,0]) | |
Socket("Noval"); | |
translate([0,-85,0]) | |
Socket("Magnoval");} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
More detail on my blog at http://wp.me/poZKh-6cm