The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Tag: Repairs

If it used to work, it can work again

  • Harbor Freight Bar Clamp: New Handle

    Conjuring up a replacement handle for that broken Harbor Freight bar clamp turned out to be easier than I expected:

    HF bar clamp handle - installed
    HF bar clamp handle – installed

    The thing omits the original’s fancy edge rounding, because I just hit the finger grips with a rat-tail file after it cooled:

    HF bar clamp handle - build platform
    HF bar clamp handle – build platform

    The solid model uses OpenSCAD’s hull() operation for the beak and straight side of the handle, with a handful of circles chopping out the recesses. The rightmost arc lies tangent to the near side of the beak, so as to join without a stress-raiser bump:

    HF Bar Clamp - support - solid model
    HF Bar Clamp – support – solid model

    The little yellow doodad is (a duplicate of) the support structure inside the pivot hole that prevents the middle section from drooping. It’s easier to see from the bottom:

    HF Bar Clamp - solid model - bottom
    HF Bar Clamp – solid model – bottom

    Removing the plug required nothing more than a fat pin punch and a whack from a brass hammer, with the plug centered over a hole in a random chunk of aluminum (with many other holes):

    HF bar clamp handle - support plug removed
    HF bar clamp handle – support plug removed

    Much to my delight, the holes & pivot recesses came out exactly the right size on the first version, with HoleWindage = 0.2. What’s new & different: that the first layer height has stabilized at 0.25 mm and the first few layers don’t get squished.

    I built three more handles in one setup, just to have some show-n-tell objects, with one prepped and on hot standby should the other Harbor Freight handle break. If these handles break, something aluminum on the Sherline will be in order.

    Now that clamp can go back into the collection. Puzzle: which one isn’t like the other ones?

    Too many bar clamps
    Too many bar clamps

    I should’a used Safety Orange filament, eh?

    [Update: xylitol designed a much better looking version that should be a drop-in replacement. Perhaps you can print it standing on edge (or end) to eliminate the support structures?]

    The OpenSCAD source code:

    // Handle for Harbor Freight bar clamp
    // Ed Nisley KE4ZNU - Jan 2012
    
    Layout = "Show";                // Build Show
    
    Support = true;
    SupportColor = "Yellow";
    
    //- Extrusion parameters must match reality!
    //  Print with +1 shells and 3 solid layers
    //  Use infill solidity = 0.5 or more...
    
    ThreadThick = 0.25;
    ThreadWidth = 2.0 * ThreadThick;
    
    HoleWindage = 0.2;
    
    Protrusion = 0.1;           // make holes end cleanly
    
    CircleSides = 4*8;
    $fn = CircleSides;
    
    //-------
    // Handle dimensions
    
    OALength = 49;
    OAThickness = 6.0;
    
    BodyWidth = 12;
    
    BeakRadius = 12;                            // hole to tip
    BeakEndRadius = 1.0;                        // roundness of tip
    BeakIncludedAngle = 40;
    BeakAngle = 55;
    BeakAdder = [2.0,1.0];                      // additional meat on outer and upper sides
    
    BeakHalfWidth = IntegerMultiple(BeakRadius*sin(BeakIncludedAngle/2),ThreadWidth);
    
    PivotXY = BeakRadius*[cos(BeakAngle),sin(BeakAngle)]; // pivot hole offset from beak tip
    
    PivotShaftDia = 2.6;
    PivotRecessDia = 5.0;
    PivotRecessDepth = 2.5;
    
    NumScallops = 3;
    ScallopRadius = [5,9,9];        // first scallop must be tangent to beak!
    ScallopX = [-((ScallopRadius[0] + BeakHalfWidth)*cos(90 - (BeakAngle - BeakIncludedAngle/2))),
                -17.5,-31.5];
    ScallopY = [-((ScallopRadius[0] + BeakHalfWidth)*sin(90 - (BeakAngle - BeakIncludedAngle/2))),
                -12,-12];
    
    echo(str("Scallops R=",ScallopRadius," X=",ScallopX," Y=",ScallopY));
    
    TailOuterRadius = 12;
    TailInnerRadius = 22;
    
    //-------
    
    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(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
    }
    
    module ShowPegGrid(Space = 10.0,Size = 1.0) {
    
      Range = floor(50 / Space);
    
        for (x=[-Range:Range])
          for (y=[-Range:Range])
            translate([x*Space,y*Space,Size/2])
              %cube(Size,center=true);
    
    }
    
    //-------
    // Bits and pieces
    
    module Pivot() {
    
      translate([0,0,-Protrusion])
        PolyCyl(PivotShaftDia,(OAThickness + 2*Protrusion));
    
      translate([0,0,(OAThickness - PivotRecessDepth)])
        PolyCyl(PivotRecessDia,(PivotRecessDepth + Protrusion));
    
      translate([0,0,-Protrusion])
        PolyCyl(PivotRecessDia,(PivotRecessDepth + Protrusion));
    
    }
    
    module HandleBlock() {
    
      hull() {                            // beak
        cylinder(r=BeakHalfWidth,h=OAThickness);
        translate(BeakAdder)
          cylinder(r=BeakHalfWidth,h=OAThickness);
        translate([(PivotXY[0] - BeakEndRadius*cos(BeakAngle)),
                  -(PivotXY[1] - BeakEndRadius*sin(BeakAngle))])
          cylinder(r=BeakEndRadius,h=OAThickness);
      }
    
      hull() {                            // straight body edge
        translate(BeakAdder)
          cylinder(r=BeakHalfWidth,h=OAThickness);
        translate([-(OALength - PivotXY[0] - TailOuterRadius),BeakAdder[1]])
          cylinder(r=BeakHalfWidth,h=OAThickness);
      }
    
      translate([ScallopX[0],0,0])        // scalloped edge tips
        rotate(180)
          cube([(OALength - PivotXY[0] + ScallopX[0] - TailOuterRadius),
                (BodyWidth/2 - ThreadWidth),      // small Finagle constant = flat tips
                OAThickness],center=false);
    
      translate([-(OALength - PivotXY[0] - TailOuterRadius),        // tail
                (BeakHalfWidth + BeakAdder[1] - TailOuterRadius)])
        rotate(180)
          intersection() {
            cylinder(r=TailOuterRadius,h=OAThickness);
            translate([0,-TailOuterRadius])
              cube([TailOuterRadius,2*TailOuterRadius,OAThickness]);
          }
    
    }
    
    module SupportPlug() {
    
      color(SupportColor)
      union() {
        cylinder(r=IntegerMultiple((PivotRecessDia - ThreadWidth),ThreadWidth)/2,
                  h=2*ThreadThick);
        for (Index=[0,1])
          rotate(Index*90)
            translate([0,0,(PivotRecessDepth - ThreadThick)/2])
              cube([(PivotRecessDia - ThreadWidth - 2*Protrusion),
                    2*ThreadWidth,(PivotRecessDepth - ThreadThick)],
                  center=true);
      }
    }
    
    //------
    
    module Handle() {
    
        difference() {
          HandleBlock();
    
          translate([-(OALength - PivotXY[0] - TailOuterRadius),    // trim tail tip
                    -(PivotXY[1] - ThreadWidth),
                    -Protrusion])
            rotate(180)
              cube([TailOuterRadius,TailOuterRadius,(OAThickness + 2*Protrusion)]);
    
          for (Index=[0:NumScallops-1]) {
            translate([ScallopX[Index],ScallopY[Index],-Protrusion])
              cylinder(r=ScallopRadius[Index],h=(OAThickness + 2*Protrusion));
          }
    
          Pivot();
        }
    
        if (Support)                    // choose support to suit printing orientation
          SupportPlug();
    }
    
    //-------
    
    ShowPegGrid();
    
    if (Layout == "Show") {
      translate([OALength/3,10,0])
        Handle();
      translate([10,0,0])
        SupportPlug();
    }
    
    if (Layout == "Build")
      translate([OALength/3,0,0])
        Handle();
    

    The original doodles, which I started by scanning an unbroken handle and overlaying a grid, then scaling the grid so the end-to-end measurement worked out to the proper number of millimeters:

    Handle dimension doodles
    Handle dimension doodles
  • Moderate Lifetime CFL Failure

    Not all CFL bulbs fail after a year. This one seems to have lasted six years, only to burn out a few days after the other one:

    Burned-out CFL bulb
    Burned-out CFL bulb

    I’m sure the date code just over the base means January 2006, not June 2001, simply because I used much larger bulbs a decade ago. Those have long since failed…

    These bulbs all operate in nearly the worst possible condition: base-up inside a ceiling downlight can, although without a cover glass. It’s much cooler in there than with the equivalent incandescent bulb, but they still get pretty toasty. The housing discoloration and the brittle bosses around the tube glass looks a bit less saturated in real life, but this will give you an idea:

    CFL bulb - heat damage
    CFL bulb – heat damage
  • Brita Pitcher Lid Hinge Redux

    Well, that fix didn’t last nearly as long as I’d hope, although I must admit whacking the pitcher lid against the refrigerator door certainly hastened its demise.

    So I found a suitable screw in the Tiny Box o’ Teeny Screws (in a sub-container of eyeglass repair screws), drilled a snug hole where the plastic pin used to be (entirely by hand on the drill press, feeding the lid into the drill), and snapped everything together again:

    Brita pitcher lid hinge - screw
    Brita pitcher lid hinge – screw

    The remaining plastic pin had a fracture at its base, but I just glued it and will defer installing a screw until it finishes disintegrating. At some point we’re going to be forced to buy a new pitcher…

  • Zire 71 Button Shield Repair

    My decrepit Zire 71 PDA (remember PDAs?) has a cute little joystick dingus that, when pressed, displays the clock. That’s great, except that it stands proud of the surface by just enough to be constantly pressed by my pants fabric. Hence, the need for a button shield… which, after all these years, snapped at an obvious high-stress spot:

    Broken Zire button shield
    Broken Zire button shield

    A dab of solvent glue, a few minutes of finger pressure, and let it cure overnight. That was easy.

    But then it occurred to me that this was a broken plastic part and I had a 3D printer…

  • EAGLE 6.x Manual: Printing the Whole Thing

    Although reading PDF documents on the shining screen works fine for some topics, I’d much rather curl up with a printed version for the first read-through. Adobe Reader’s print-as-booklet option does all the heavy lifting required to print a PDF document four pages to a single Letter-size sheet of paper, after which I do a little slicing & binding to get a nice comb-bound book.

    So I printed out the entire EAGLE 6 manual (found in /wherever/eagle-6.1.0/doc/), which led to the discovery that page 86 is missing (at least in the 1st edition version). That screws up the pagination from page 87 onward: odd-numbered pages move to the left side of the binding, even-numbered pages to the right, and the blank space reserved for the gutter / binding appears on the outside margins. Fortunately, it’s still readable.

    To avoid that problem, do this:

    Print Range → Pages → [1-85,301,86-334]

    That selects the first set of contiguous pages, jams a copy of a “This page has been left free intentionally” page from the back of the manual in place of the missing page 86, and then selects the rest of the book.

    Print the front sides, flip the stack over, print the back sides (with the same page range), and bind as usual.

    FWIW, this is much better than having the printer mis-feed about 3/4 of the way through the back sides, which it has done in the past while printing a big book. I now run off about 20 sheets at a time, with only that many pieces of paper in the feeder, just to make sure it doesn’t ruin the entire job.

    One could, I suppose, use pdftk to shuffle the PDF into a complete file which would Just Work, but that seems like more trouble than it’s worth. Ditto for expecting CadSoft to re-create the PDF.

    Memo to Self: Check the last page. If the logical page doesn’t match what’s shown on the PDF page, then something’s wrong.

  • Thing-O-Matic: Dummy Load Fan Replacement

    Dummy load fan replacement
    Dummy load fan replacement

    The fan on the dummy load that consumes the required minimum current to keep the ATX power supply happy wasn’t starting up reliably. That’s not surprising: I connected it to 5 V rather than the rated 12 V, because the load heatsink needs just a whisper of air flow to stay barely above room temperature, so it’s barely turning over and has no spare torque at all.

    It turns out the heatsink really doesn’t need any forced air flow, despite having the fins oriented crosswise. Without the fan, it stabilizes just above comfortable-to-the-touch, a bit hotter than I’d prefer.

    While I had the hood up for the HBP rebuild, though, I swapped in another fan and the heatsink is now cool to the touch. I did clean that dust off the fins, too.

    If this one also fails at +5 V, I’ll fiddle the wiring to put it across the +12 V and +5 V supplies, where it’ll see 7 V. That should improve its disposition…

  • Dishwasher Rack Protectors

    After a decade of stacking the plates in the dishwasher the same way every time, the flexible coating over the steel rods has worn through:

    Dishwasher rack abrasion
    Dishwasher rack abrasion

    We can’t stack them the other way, because the rotor spray rattles them unmercifully, and a fix is in order. Apparently, one can purchase touchup paint for this very purpose, but what’s the fun in that? Besides, I’d expect it to wear through even faster than the original coating, if only because adhesion is never as good as you’d expect from reading the label.

    So this little dingus fits around a vertical pin and rests atop the horizontal rod, with the edge of the plate nestled into the joint between the two cylinders:

    Dishwasher rack protector - solid model
    Dishwasher rack protector – solid model

    Being very small, they build best in large groups:

    Dishwasher rack protectors - on build platform
    Dishwasher rack protectors – on build platform

    The horizontal half-cylinders require internal support, shown here adjacent to the protector for easy viewing:

    Dishwasher rack protector - support model
    Dishwasher rack protector – support model

    Those fins just barely clear the interior of the horizontal cylinder, so the two parts don’t bond together very well (that’s the ideal condition, of course). The flat plate glues the support fins firmly to the build platform, which is easier to see on these somewhat shorter prototypes with a layer or two of orange filament on their bottoms:

    Dishwasher rack protectors - support
    Dishwasher rack protectors – support

    The support chops out neatly with a repurposed nail set punch:

    Dishwasher rack protector - removing support
    Dishwasher rack protector – removing support

    Actually, I stood each one vertically on an aluminum chunk, held the punch in place with finger pressure, and whacked it with a small brass hammer. The OpenSCAD code now adds a small tab each end to help align the punch for the first whack.

    The rod (vertical) hole came out just about exactly the right size (admittedly, with a 0.4 mm HoleFinagle adjustment), but required a pass with a drill in a pin vise to clear out the Reversal Zittage. The result slides easily over undamaged pins, but some pins had rust at either the top or bottom that required a bit of cleanup. This is a trial fit:

    Dishwasher rack protectors - trial fit
    Dishwasher rack protectors – trial fit

    I put a blob of acrylic caulk on the abraded spots to (attempt to) seal them from further damage, then squished the protectors in place. The dishwasher demonstrated that it’s perfectly capable of blasting an unglued protector (without a plate) up and off the pin, ingesting it into the trash grinder, chewing it up, and spitting the pieces down the drain. Lost a couple of prototypes before I figured that out, too.

    Ya learn something new every day…

    The OpenSCAD source code:

    // Dishwasher rack protector
    // Ed Nisley KE4ZNU - Jan 2012
    
    Layout = "Show";                    // Show Build Support
    
    Support = true;                     // true to add support inside rod half-cylinder
    
    include </home/ed/Thing-O-Matic/lib/visibone_colors.scad>
    
    //-------
    //- Extrusion parameters must match reality!
    //  Print with +0 shells
    //  Infill = 1.0, line, perpendicular to Bar axis on first bridge layer
    //  Multiply = at least four copies to prevent excessive slowdown
    
    ThreadThick = 0.25;
    ThreadWidth = 2.0 * ThreadThick;
    
    HoleFinagle = 0.4;
    HoleFudge = 1.00;
    
    function HoleAdjust(Diameter) = HoleFudge*Diameter + HoleFinagle;
    
    Protrusion = 0.1;           // make holes end cleanly
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    function IntegerMultipleMin(Size,Unit) = Unit * floor(Size / Unit);
    
    //-------
    // Dimensions
    
    PinDia = 4.0 + 0.5;                 // upright pin diameter + clearance
    PinRadius = PinDia/2;
    
    PinSpace = 35.0;                    // pin spacing along bar
    
    PinOC = 3.4;                        // bar center to pin center
    
    PinTubeLength = 15.0;               // length of upright tube along pin
    
    BarDia = 4.7 + 0.2;                 // horizontal bar diameter + clearance
    BarRadius = BarDia/2;
    
    BarTubeLength = PinSpace - 5.0;     // length of horizontal half tube along bar
    
    TubeWall = 4*ThreadWidth;           // wall thickness -- allow for fill motion
    
    TubeSides = 4 * 4;                  // default side count for tubes (in quadrants)
    $fn = TubeSides;
    
    SupportClear = 0.85;                // support structure clearance fraction
    
    //-------
    
    module PolyCyl(Dia,Height,ForceSides=0) {           // based on nophead's polyholes
      Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
      FixDia = Dia / cos(180/Sides);
      cylinder(r=HoleAdjust(FixDia)/2,h=Height,$fn=Sides);
    }
    
    module ShowPegGrid(Space = 10.0,Size = 1.0) {
    
      Range = floor(50 / Space);
      for (x=[-Range:Range])
        for (y=[-Range:Range])
          translate([x*Space,y*Space,Size/2])
            %cube(Size,center=true);
    }
    
    //--------
    // Support under bar tube shells
    
    module SupportStructure() {
    
      color("cyan")
      difference() {
        union() {
          for (Index=[-4:4])
            translate([Index*(BarTubeLength/8.5),0,0])
              rotate([0,90,0])
                rotate(180/TubeSides)
                  cylinder(r=SupportClear*BarRadius,h=2*ThreadWidth,center=true);
    
          rotate([0,90,0])
            rotate(180/TubeSides)
              cylinder(r=SupportClear*BarRadius,h=10*ThreadWidth,center=true);
    
          translate([0,0,ThreadThick])
            cube([(BarTubeLength + 4*ThreadWidth),BarRadius,2*ThreadThick],center=true);
        }
    
        translate([0,0,-(BarRadius + Protrusion)/2])
          cube([(BarTubeLength + 2*Protrusion),
              BarDia,
              (BarRadius + Protrusion)],center=true);
    
      }
    
    }
    
    //-------
    // Put it together
    
    module Protector() {
    
      difference() {
        union() {
          translate([0,PinOC,0])
            rotate(180/TubeSides)
              cylinder(r=(PinDia + 2*TubeWall)/2,h=PinTubeLength);
          translate([-BarTubeLength/2,0,0])
            rotate([0,90,0])
              rotate(180/TubeSides)
                cylinder(r=(BarDia + 2*TubeWall)/2,h=BarTubeLength);
        }
    
        translate([0,PinOC,-Protrusion])
          rotate(180/TubeSides)
            PolyCyl(PinDia,(PinTubeLength + 2*Protrusion),TubeSides);
    
        translate([-BarTubeLength/2,0,0])
          rotate([0,90,0])
            rotate(180/TubeSides)
              translate([0,0,-Protrusion])
                cylinder(r=BarRadius,h=(BarTubeLength + 2*Protrusion));
    
        translate([0,0,-(BarRadius + TubeWall + Protrusion)/2])
          cube([(BarTubeLength + 2*Protrusion),
              BarTubeLength,
              (BarRadius + TubeWall + Protrusion)],center=true);
      }
    
    }
    
    //-------
    // Build it!
    
    ShowPegGrid();
    
    if (Layout == "Support")
      SupportStructure();
    
    if (Layout == "Show") {
      Protector();
      translate([0,-10,0])
        SupportStructure();
    }
    
    if (Layout == "Build")
      rotate(90) {
        if (Support)
          SupportStructure();
        Protector();
      }