-
Rubber Soaker Hose Repair
A soaker hose leaped under a descending garden fork and accumulated a nasty gash:

Soaker Hose Splice – gashed Mary deployed a spare and continued the mission, while I pondered how to fix such an odd shape.
For lack of anything smarter, I decided to put a form-fitting clamp around the hose, with silicone caulk buttered around the gash to (ideally) slow down any leakage:

Soaker Hose Splice – Solid Model – Assembled As usual, some doodling got the solid model started:

Soaker Hose Splice – Dimension doodle 1 A hose formed from chopped rubber doesn’t really have consistent dimensions, so I set up the model to spit out small test pieces:

Soaker Hose Splice – Test Fit – Slic3r Lots and lots of test pieces:

Soaker Hose Splice – test pieces Each iteration produced a better fit, although the dimensions never really converged:

Soaker Hose Splice – Dimension doodle 2 The overall model looks about like you’d expect:

Soaker Hose Splice – Complete – Slic3r The clamp must hold its shape around a hose carrying 100 psi (for real!) water, so I put 100 mil aluminum backing plates on either side. Were you doing this for real, you’d shape the plates with a CNC mill, but I just bandsawed them to about the right size and transfer-punched the hole positions:

Soaker Hose Splice – plate transfer punch Some drill press action with a slightly oversize drill compensated for any misalignment and Mr Disk Sander rounded the corners to match the plastic block:

Soaker Hose Splice – plate corner rounding A handful of stainless steel 8-32 screws holds the whole mess together:

Soaker Hose Splice – installed These hoses spend their lives at rest under a layer of mulch, so I’m ignoring the entire problem of stress relief at those sharp block edges. We’ll see how this plays out in real life, probably next year.
I haven’t tested it under pressure, but it sure looks capable!
The OpenSCAD source code as a GitHub Gist:
This file contains hidden or 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// Rubber Soaker Hose Splice // Ed Nisley KE4ZNU July 2018 Layout = "Build"; // Hose Block Show Build TestFit = false; // true to build test fit slice from center //- 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 // Hose lies along X axis Hose = [200,27.0,12.0]; // X = longer than anything else Block = [80.0,50.0,4.0 + Hose.z]; // overall splice block size echo(str("Block: ",Block)); Kerf = 0.1; // cut through middle to apply compression ID = 0; OD = 1; LENGTH = 2; // 8-32 stainless screws Screw = [4.1,8.0,3.0]; // OD = head LENGTH = head thickness Washer = [4.4,9.5,1.0]; Nut = [4.1,9.7,6.0]; CornerRadius = Washer[OD]/2; NumScrews = 3; // screws along each side of cable ScrewOC = [(Block.x – 2*CornerRadius) / (NumScrews – 1), Block.y – 2*CornerRadius, 2*Block.z // ensure complete holes ]; echo(str("Screw OC: x=",ScrewOC.x," y=",ScrewOC.y)); //———————- // 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); } // Hose shape // This includes magic numbers measured from reality module HoseProfile() { RimThick = 10.0; // outer sections RimOD = RimThick; RimFlatRecess = -0.7; // recess to front flat surface OuterOC = Hose.y – RimOD; // outer tube centers RecessM = 1.5; // back recess chord RecessC = OuterOC; RecessR = (pow(RecessM,2) + pow(RecessC,2)/4) / (2*RecessM); RidgeM = 1.0; // front ridge chord RidgeC = 8.0; RidgeR = (pow(RidgeM,2) + pow(RidgeC,2)/4) / (2*RidgeM); NumSides = 12*4; rotate([0,-90,0]) translate([0,0,-Hose.x/2]) linear_extrude(height=Hose.x,convexity=4) difference() { union() { for (j=[-1,1]) // outer channels translate([0,j*OuterOC/2]) circle(d=RimOD,$fn=NumSides); translate([-RimOD/4,0]) // rear flat fill square([RimOD/2,OuterOC],center=true); translate([(RimOD/4 + RimFlatRecess),0]) // front flat fill square([RimOD/2,OuterOC],center=true); intersection() { translate([Hose.z/2,0]) square([Hose.z,OuterOC],center=true); translate([-RidgeR + RimOD/2 + RimFlatRecess + RidgeM,0]) circle(r=RidgeR,$fn=NumSides); } } translate([-(RecessR + RimOD/2 – RecessM),0]) circle(r=RecessR,$fn=2*NumSides); } } // Outside shape of splice Block // Z centered on hose rim circles, not overall thickness through center ridge module SpliceBlock() { difference() { hull() for (i=[-1,1], j=[-1,1]) // rounded block translate([i*(Block.x/2 – CornerRadius),j*(Block.y/2 – CornerRadius),-Block.z/2]) cylinder(r=CornerRadius,h=Block.z,$fn=4*8); for (i = [0:NumScrews – 1], j=[-1,1]) // screw holes translate([-(Block.x/2 – CornerRadius) + i*ScrewOC.x, j*ScrewOC.y/2, -(Block.z/2 + Protrusion)]) PolyCyl(Screw[ID],Block.z + 2*Protrusion,6); cube([2*Block.x,2*Block.y,Kerf],center=true); // slice through center } } // Splice block less hose module ShapedBlock() { difference() { SpliceBlock(); HoseProfile(); } } //———- // Build them if (Layout == "Hose") HoseProfile(); if (Layout == "Block") SpliceBlock(); if (Layout == "Bottom") BottomPlate(); if (Layout == "Top") TopPlate(); if (Layout == "Show") { difference() { SpliceBlock(); HoseProfile(); } color("Green",0.25) HoseProfile(); } if (Layout == "Build") { SliceOffset = TestFit && !NumScrews%2 ? ScrewOC.x/2 : 0; intersection() { translate([SliceOffset,0,Block.z/4]) if (TestFit) cube([ScrewOC.x/2,4*Block.y,Block.z/2],center=true); else cube([4*Block.x,4*Block.y,Block.z/2],center=true); union() { translate([0,0.6*Block.y,Block.z/2]) ShapedBlock(); translate([0,-0.6*Block.y,Block.z/2]) rotate([0,180,0]) ShapedBlock(); } } }