A small ShopVac arrived with a ribbed hose carrying an absurdly long wand, so I conjured a barbed adapter with a much shorter tapered snout for the machine tools:

Trimming the hose end at one of the ribs makes a tidy fit:

Now I need not trip over the vacuum hose between the bandsaw bench and the sander bench…
The OpenSCAD code as a GitHub Gist:
| // Vacuum Hose Fittings | |
| // Ed Nisley KE4ZNU July 2016 | |
| // March 2017 | |
| Layout = "HoseBarb"; // PVCtoHose ExpandRing PipeToPort FVacPipe FVacFitting HoseBarb | |
| //- Extrusion parameters must match reality! | |
| // Print with 2 shells and 3 solid layers | |
| ThreadThick = 0.25; | |
| ThreadWidth = 0.40; | |
| HoleWindage = 0.2; | |
| Protrusion = 0.1; // make holes end cleanly | |
| //———————- | |
| // Dimensions | |
| ID = 0; | |
| OD = 1; | |
| LENGTH = 2; | |
| VacNozzle = [30.1,31.8,30.0]; // nozzle on vacuum hose (taper ID to OD over length) | |
| MINOR = 0; | |
| MAJOR = 1; | |
| PITCH = 2; | |
| FORM_OD = 3; | |
| HoseThread = [32.0,(37.0 + HoleWindage),4.25,(1.8 + 0.20)]; // vacuum hose thread | |
| NumSegments = 64; // .. number of cylinder approximations per turn | |
| $fn = NumSegments; | |
| ThreadLength = 4 * HoseThread[PITCH]; | |
| ScrewOAL = ThreadLength + HoseThread[PITCH]; | |
| WallThick = 2.5; | |
| echo(str("Pitch dia: ",HoseThread[MAJOR])); | |
| echo(str("Root dia: ",HoseThread[MAJOR] – HoseThread[FORM_OD])); | |
| echo(str("Crest dia: ",HoseThread[MAJOR] + HoseThread[FORM_OD])); | |
| //———————- | |
| // Wrap cylindrical thread segments around larger plug cylinder | |
| module CylinderThread(Pitch,Length,PitchDia,ThreadOD,PerTurn,Chirality = "Left") { | |
| CylFudge = 1.02; // force overlap | |
| ThreadSides = 6; | |
| RotIncr = 1/PerTurn; | |
| PitchRad = PitchDia/2; | |
| Turns = Length/Pitch; | |
| NumCyls = Turns*PerTurn; | |
| ZStep = Pitch / PerTurn; | |
| HelixAngle = ((Chirality == "Left") ? -1 : 1) * atan(Pitch/(PI*PitchDia)); | |
| CylLength = CylFudge * (PI*(PitchDia + ThreadOD) / PerTurn) / cos(HelixAngle); | |
| for (i = [0:NumCyls-1]) { | |
| Angle = ((Chirality == "Left") ? -1 : 1) * 360*i/PerTurn; | |
| translate([PitchRad*cos(Angle),PitchRad*sin(Angle),i*ZStep]) | |
| rotate([90+HelixAngle,0,Angle]) rotate(180/ThreadSides) | |
| cylinder(r1=ThreadOD/2, | |
| r2=ThreadOD/(2*CylFudge), | |
| h=CylLength, | |
| center=true,$fn=ThreadSides); | |
| } | |
| } | |
| //– PVC fitting to vacuum hose | |
| module PVCtoHose() { | |
| Fitting = [34.0,41.0,16.0]; // 1 inch PVC elbow | |
| Adapter = [HoseThread[MAJOR],(Fitting[OD] + 2*WallThick + HoleWindage),(ScrewOAL + Fitting[LENGTH])]; // dimensions for entire fitting | |
| union() { | |
| difference() { | |
| cylinder(d=Adapter[OD],h=Adapter[LENGTH]); // overall fitting | |
| translate([0,0,-Protrusion]) // remove thread pitch dia | |
| cylinder(d=HoseThread[MAJOR],h=(ScrewOAL + 2*Protrusion)); | |
| translate([0,0,(ScrewOAL – Protrusion)]) // remove PVC fitting dia | |
| cylinder(d=(Fitting[OD] + HoleWindage),h=(Fitting[LENGTH] + 2*Protrusion)); | |
| } | |
| translate([0,0,HoseThread[PITCH]/2]) // add the thread form | |
| CylinderThread(HoseThread[PITCH],ThreadLength,HoseThread[MAJOR],HoseThread[FORM_OD],NumSegments,"Left"); | |
| } | |
| } | |
| //– Expander ring from small OD to large ID PVC fittings | |
| // So a small elbow on the bandsaw fits into the hose adapter, which may not be long-term useful | |
| module ExpandRing() { | |
| Fitting_L = [34.0,41.0,16.0]; // 1 inch PVC pipe elbow | |
| Fitting_S = [26.8,32.8,17]; // 3/4 inch PVC elbow | |
| difference() { | |
| cylinder(d1=Fitting_L[OD],d2=(Fitting_L[OD] – HoleWindage),h=Fitting_L[LENGTH]); // overall fitting | |
| translate([0,0,-Protrusion]) | |
| cylinder(d=(Fitting_S[OD] + HoleWindage),h=(Fitting_L[LENGTH] + 2*Protrusion)); | |
| } | |
| } | |
| //– 1 inch PVC pipe into vacuum port | |
| // Stick this in the port, then plug a fitting onto the pipe section | |
| module PipeToPort() { | |
| Pipe = [26.5,33.5,20.0]; // 1 inch Schedule 40 PVC pipe | |
| difference() { | |
| union() { | |
| cylinder(d=Pipe[OD],h=(Pipe[LENGTH] + Protrusion)); | |
| translate([0,0,(Pipe[LENGTH] – Protrusion)]) | |
| cylinder(d1=VacNozzle[OD],d2=VacNozzle[ID],h=VacNozzle[LENGTH]); | |
| } | |
| translate([0,0,-Protrusion]) | |
| cylinder(d=Pipe[ID],h=(Pipe[LENGTH] + VacNozzle[LENGTH] + 2*Protrusion)); | |
| } | |
| } | |
| //– Female Vac outlet inside PVC pipe | |
| // Plug this into PVC fitting, then plug hose + nozzle into outlet | |
| module FVacPipe() { | |
| VacPort = [30.0,31.3,25]; // vacuum port on belt sander (taper ID to OD over length) | |
| Pipe = [26.5,33.5,20.0]; // 1 inch Schedule 40 PVC pipe | |
| difference() { | |
| cylinder(d=Pipe[OD],h=VacPort[LENGTH]); | |
| translate([0,0,-Protrusion]) | |
| cylinder(d1=VacPort[ID],d2=VacPort[OD],h=(VacPort[LENGTH] + 2*Protrusion)); | |
| } | |
| } | |
| //– Female Vac outlet on 3/4 inch fitting OD | |
| // Jam this onto OD of fitting, plug hose + nozzle into outlet | |
| module FVacFitting() { | |
| Adapter = [26.5,(33.5 + 2*WallThick),17.0]; // overall adapter | |
| //VacPort = [30.0,31.3,25]; // vacuum port on belt sander (taper ID to OD over length) | |
| VacPort = [30.1,31.8,30.0]; // vacuum port for bandsaw = inverse of hose nozzle | |
| Fitting = [26.8,32.8,17]; // 3/4 inch PVC elbow | |
| TaperLength = 5.0; // inner taper to avoid overhang | |
| difference() { | |
| cylinder(d=Adapter[OD],h=Adapter[LENGTH]); // overall fitting | |
| translate([0,0,-Protrusion]) | |
| cylinder(d=(Fitting[OD] + HoleWindage),h=(Adapter[LENGTH] + 2*Protrusion)); | |
| } | |
| translate([0,0,Adapter[LENGTH]]) | |
| difference() { | |
| cylinder(d=Adapter[OD],h=TaperLength); | |
| translate([0,0,-Protrusion]) | |
| cylinder(d1=(Fitting[OD] + HoleWindage),d2=VacPort[ID],h=(TaperLength + 2*Protrusion)); | |
| } | |
| translate([0,0,(TaperLength + Adapter[LENGTH])]) // vac fitting | |
| difference() { | |
| cylinder(d=Adapter[OD],h=VacPort[LENGTH]); | |
| translate([0,0,-Protrusion]) | |
| cylinder(d1=VacPort[ID],d2=VacPort[OD],h=(VacPort[LENGTH] + 2*Protrusion)); | |
| } | |
| } | |
| //– Hose barb to male vacuum taper | |
| module HoseBarb() { | |
| HoseFitting = [29.0,32.2,38.5]; | |
| Barb = [HoseFitting[OD],35.5,4.0]; | |
| BarbOffset = 17.0; | |
| Seat = [HoseFitting[OD],36.0,5.0]; | |
| SeatSupport = [HoseFitting[OD],Seat[OD],(Seat[OD] – HoseFitting[OD])/2]; | |
| OAL = HoseFitting[LENGTH] + SeatSupport[LENGTH] + Seat[LENGTH] + VacNozzle[LENGTH]; | |
| NumSides = 4*8; | |
| difference() { | |
| union() { | |
| cylinder(d=HoseFitting[OD],h=HoseFitting[LENGTH],$fn=NumSides); | |
| translate([0,0,BarbOffset]) | |
| cylinder(d1=Barb[ID],d2=Barb[OD],h=Barb[LENGTH],$fn=NumSides); | |
| translate([0,0,HoseFitting[LENGTH]]) | |
| cylinder(d1=SeatSupport[ID],d2=SeatSupport[OD],h=SeatSupport[LENGTH],$fn=NumSides); | |
| translate([0,0,HoseFitting[LENGTH] + SeatSupport[LENGTH]]) | |
| cylinder(d=Seat[OD],h=Seat[LENGTH],$fn=NumSides); | |
| translate([0,0,HoseFitting[LENGTH] + SeatSupport[LENGTH] + Seat[LENGTH]]) | |
| cylinder(d1=VacNozzle[OD],d2=VacNozzle[ID],h=VacNozzle[LENGTH],$fn=NumSides); | |
| } | |
| translate([0,0,-Protrusion]) | |
| cylinder(d1=HoseFitting[ID],d2=(VacNozzle[ID] – 10*ThreadWidth),h=OAL + 2*Protrusion,$fn=NumSides); | |
| } | |
| } | |
| //———- | |
| // Build things | |
| if (Layout == "PVCtoHose") | |
| PVCtoHose(); | |
| if (Layout == "ExpandRing") { | |
| ExpandRing(); | |
| } | |
| if (Layout == "PipeToPort") { | |
| PipeToPort(); | |
| } | |
| if (Layout == "FVacPipe") { | |
| FVacPipe(); | |
| } | |
| if (Layout == "FVacFitting") { | |
| FVacFitting(); | |
| } | |
| if (Layout == "HoseBarb") { | |
| HoseBarb(); | |
| } |






















