One of the octal tubes in my collection has a broken spigot / key post that lets some light in through the bottom of the normally opaque Bakelite base:

Perhaps drilling out the base would let more light pass around the evacuation tip, but that requires a shell drill to clear the tip. Some doodling suggested a drill with 12 mm OD and 8 mm ID, which was close enough to one of the smaller homebrew drills in my collection that I decided to see how it worked:

You (well, I) can’t freehand such a hole, particularly with a glass tip in the middle, so I needed a way to clamp the tube in either the drill press or the Sherline. A pad for the clamp screw in a V-block seemed appropriate:

The screw hole sits at the 1/3 point to put more pressure near the pin end of the base. Maybe that matters.
The setup looks like this, with a small red laser dot near the front of the base:

The tube rests on a random scrap of plastic, with the hope that the drill won’t apply enough pressure to break the glass envelope.
In normal use, the V-block would be oriented the other way to let you cross-drill the cylinder. In this end-on orientation, drilling torque can rotate the tube; compliant padding for more traction may be in order.
The OpenSCAD source code as a GitHub Gist now includes a module that spits out the clamp:
| // 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 | |
| DefaultSocket = "Mini7"; | |
| 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_TUBEOD = 7; // envelope or base diameter | |
| T_PIPEOD = 8; // light pipe from LED to tube base (clear evac tip / spigot) | |
| T_SCREWOC = 9; // mounting screw holes | |
| // Name pins BCD dia length hole punch tube pipe screw | |
| TubeData = [ | |
| ["Mini7", 8, 9.53, 1.016, 7.0, 16.0, 25.0, 18.0, 5.0, 35.0], // punch 11/16, screw 22.5 OC | |
| // ["Octal", 8, 17.45, 2.36, 11.0, 36.2, (8 + 1)/8 * inch, 32.0, 11.5, 47.0], // screw 39.0 OC | |
| ["Octal", 8, 17.45, 2.36, 11.0, 36.2, 25.0, 32.0, 11.5, 42.0], // platter + 4 mm screws | |
| ["Noval", 10, 11.89, 1.1016, 7.0, 22.0, 25.0, 21.0, 7.5, 35.0], // punch 7/8, screw 28.0 OC | |
| ["Magnoval", 10, 17.45, 1.27, 9.0, 29.7, (4 + 1)/4 * inch, 46.0, 12.4, 38.2], // similar to Novar | |
| // ["Duodecar", 13, 19.10, 1.05, 9.0, 32.0, (4 + 1)/4 * inch, 38.0, 12.5, 47.0], // screw was 39.0 OC | |
| ["Duodecar", 13, 19.10, 1.05, 9.0, 25.0, 25.0, 38.0, 12.5, 42.0], // 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 | |
| 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 | |
| //———————- | |
| // 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*Pixel[LENGTH])]; | |
| CapSides = 8*4; | |
| 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=(CapSize[OD] + 2*3*ThreadWidth),d2=CapSize[OD],h=1.5*Pixel[LENGTH],$fn=CapSides); // skirt | |
| } | |
| 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],(1.5*Pixel[LENGTH] + Protrusion),CapSides); | |
| translate([0,0,(1.5*Pixel[LENGTH] – 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,(CapSize[LENGTH] – CapTube[OD]/(2*cos(180/8)))]) // 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],(1.5*Pixel[LENGTH] + 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.9,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[ID] – Stud[OD] + (Stud[OD] – Stud[ID])/2); | |
| 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]) | |
| rotate(180/StudSides) | |
| difference() { | |
| cylinder(d=Stud[OD],h=Stud[LENGTH],$fn=2*StudSides); | |
| translate([0,0,Bottom]) | |
| 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; | |
| 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*100/2,j*100/2,BasePlate[2] – 2*ThreadThick]) | |
| cylinder(d=1.5,h=1,$fn=6); | |
| 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 | |
| linear_extrude(height=(Platter[LENGTH] + Protrusion),convexity=2) | |
| difference() { | |
| circle(d=(Platter[OD] + 1),$fn=8*4); | |
| circle(d=Platter[ID],$fn=8*4); | |
| } | |
| translate([0,0,BasePlate[2] – 4.0]) // drilling recess | |
| linear_extrude(height=(4.0 + Protrusion),convexity=2) | |
| difference() { | |
| circle(d=(Platter[OD] – 10),$fn=8*4); | |
| circle(d=(Platter[ID] + 10),$fn=8*4); | |
| } | |
| } | |
| } | |
| //———————- | |
| // 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 | |
| ClampArc = 3*45; // angle subtended by block bottom | |
| ClampChordWidth = 2 * (TubeData[Tube][T_TUBEOD]/2) * sin(ClampArc/2); | |
| ClampChordDepth = (ClampChordWidth / 2) * tan(ClampArc/4); | |
| echo(str("Chord width: ",ClampChordWidth," depth: ",ClampChordDepth)); | |
| ClampBlock = [ClampWidth,(ClampChordDepth + 2*ClampScrew[LENGTH]),ClampLength]; | |
| difference() { | |
| translate([0,(ClampBlock[1]/2 + TubeData[Tube][T_TUBEOD]/2 – ClampChordDepth),0]) | |
| intersection() { | |
| translate([0,0,ClampLength/2]) | |
| cube(ClampBlock,center=true); | |
| translate([0,(ClampBlock[1]/2 – ClampWidth/2),0]) | |
| cylinder(d=ClampWidth,h=ClampLength); | |
| } | |
| translate([0,0,-Protrusion]) // remove tube base (remains centered) | |
| cylinder(d=TubeData[Tube][T_TUBEOD],h=(ClampLength + 2*Protrusion)); | |
| translate([0,(TubeData[Tube][T_TUBEOD]/2 + ClampScrew[LENGTH]),ClampBlock[LENGTH]/3]) | |
| rotate([-90,0,0]) | |
| PolyCyl(ClampScrew[ID],2*ClampScrew[LENGTH],6); | |
| } | |
| } | |
| //———————- | |
| // 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 == "PlatterFixture") | |
| PlatterFixture(); | |
| if (Layout == "USBPort") | |
| USBPort(); | |
| if (Layout == "TubeClamp") | |
| TubeClamp("Octal"); | |
| 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");} |
Comments
One response to “Octal Tube Base Clamp”
[…] the glass envelope (1.5 inch = 38.1 mm OD) extends beyond the base (1.125 inch = 28.6 mm OD), the simple base clamp must let the tube extend over the […]