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.

Category: Machine Shop

Mechanical widgetry

  • Tour Easy Front Fender Clip: Longer and Stronger

    We negotiated the Belmar Bridge connection stairway from the Allegheny River Trail to the Sandy Creek trail:

    Belmar Bridge Stairs - Overview
    Belmar Bridge Stairs – Overview

    We’re maneuvering Mary’s bike, but you get the general idea. Our bikes aren’t built for stairways, particularly ones with low overheads:

    Belmar Bridge Stairs - Low Overhead
    Belmar Bridge Stairs – Low Overhead

    The front fender clip on my Tour Easy snapped (at the expected spots) when the mudflap snagged on one of the angles:

    Belmar Bridge Stairs - First Turn
    Belmar Bridge Stairs – First Turn

    For some inexplicable reason, I didn’t have a roll of duct tape in my packs, so the temporary repair required a strip of tape from a battery pack, two snippets of hook-and-loop tape, and considerable muttering:

    Tour Easy front fender clip - expedient repair
    Tour Easy front fender clip – expedient repair

    It was good for two dozen more miles to the end of our vacation, so I’d say that was Good Enough.

    The new version has holes in the ferrules ten stay diameters deep, instead of six, which might eliminate the need for heatstink tubing. I added a small hole at the joint between the curved hooks and the ferrules to force more plastic into those spots:

    Front Fender Clip - Slic3r
    Front Fender Clip – Slic3r

    I also bent the hanger extension to put the fender’s neutral position closer to the wheel.

    We’ll see how long this one lasts. By now, I now have black double-sticky foam tape!

    The OpenSCAD source code as a GitHub Gist:

    // Tour Easy front fender clip
    // Ed Nisley KE4ZNU July 2017
    Layout = "Build"; // Build Profile Ferrule Clip
    //- 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
    // special case: fender is exactly half a circle!
    FenderC = 51.0; // fender outside width = chord
    FenderM = 21.0; // height of chord
    FenderR = (pow(FenderM,2) + pow(FenderC,2)/4) / (2 * FenderM); // radius
    echo(str("Fender radius: ", FenderR));
    FenderD = 2*FenderR;
    FenderA = 2 * asin(FenderC / (2*FenderR));
    echo(str(" … Arc: ",FenderA," deg"));
    FenderThick = 2.5; // fender thickness, assume dia of edge
    ClipHeight = 15.0; // top to bottom, ignoring rakish tilt
    ClipThick = IntegerMultiple(2.5,ThreadWidth); // thickness of clip around fender
    ClipD = FenderD; // ID of clip against fender
    ClipSides = 4 * 8; // polygon sides around clip circle
    BendReliefD = 2.5; // bend arch diameter
    BendReliefA = 2/3 * FenderA/2; // … angle from dead ahead
    BendReliefCut = 1.5; // factor to thin outside of bend
    ID = 0;
    OD = 1;
    LENGTH = 2;
    StayDia = 3.3; // fender stay rod diameter
    StayOffset = 15.0; // stay-to-fender distance
    StayPitch = -5; // angle from stay to fender arch
    DropoutSpace = 120; // stay spacing at wheel hub
    StayLength = 235; // stay length: hub to fender
    StaySplay = asin((DropoutSpace – FenderC)/(2*StayLength)); // outward angle to hub
    echo(str(" … Pitch: ",StayPitch," deg"));
    echo(str(" … Splay: ",StaySplay," deg"));
    FerruleSides = 2*4;
    Ferrule = [StayDia,3*FenderThick/cos(180/FerruleSides),10*StayDia + StayOffset]; // ID = stay rod OD
    FerruleHoleD = 0.1; // small hole to create solid plastic at ferrule joint
    //———————-
    // 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(r=(FixDia + HoleWindage)/2,
    h=Height,
    $fn=Sides);
    }
    //———————-
    // Clip profile around fender
    // Centered on fender arc
    module Profile(HeightScale = 1) {
    linear_extrude(height=HeightScale*ClipHeight,convexity=5) {
    difference() {
    offset(r=ClipThick) // outside of clip
    union() {
    circle(d=ClipD,$fn=ClipSides);
    for (i=[-1,1])
    rotate(i*BendReliefA) {
    translate([ClipD/2 + BendReliefD/2,0,0])
    circle(d=BendReliefD,$fn=6);
    }
    }
    union() { // inside of clip
    circle(d=ClipD,$fn=ClipSides);
    for (i=[-1,1])
    rotate(i*BendReliefA) {
    translate([ClipD/2 + BendReliefCut*BendReliefD/2,0,0])
    circle(d=BendReliefD/cos(180/6),$fn=6);
    translate([ClipD/2,0,0])
    square([BendReliefCut*BendReliefD,BendReliefD],center=true);
    }
    }
    translate([(FenderR – FenderM – FenderD/2),0]) // trim ends
    square([FenderD,2*FenderD],center=true);
    }
    for (a=[-1,1]) // hooks around fender
    rotate(a*(FenderA/2))
    translate([FenderR – FenderThick/2,0]) {
    difference() {
    rotate(1*180/12)
    circle(d=FenderThick + 2*ClipThick,$fn=12);
    rotate(1*180/8)
    circle(d=FenderThick,$fn=8);
    rotate(a * -90)
    translate([0,-2*FenderThick,0])
    square(4*FenderThick,center=false);
    }
    }
    }
    }
    //———————-
    // Ferrule body
    module FerruleBody() {
    translate([0,0,Ferrule[OD]/2 * cos(180/FerruleSides)])
    rotate([0,-90,0]) rotate(180/FerruleSides)
    difference() {
    cylinder(d=Ferrule[OD],h=Ferrule[LENGTH],$fn=FerruleSides,center=false);
    translate([0,0,StayOffset + Protrusion])
    PolyCyl(Ferrule[ID],Ferrule[LENGTH] – StayOffset + Protrusion,FerruleSides);
    }
    }
    //———————-
    // Generate entire clip at mounting angle
    module FenderClip() {
    difference() {
    union() {
    translate([FenderR,0,0])
    difference() { // angle and trim clip
    rotate([0,StayPitch,0])
    translate([-(FenderR + ClipThick),0,0])
    Profile(2); // scale upward for trimming
    translate([0,0,-ClipHeight]) // trim bottom
    cube(2*[FenderD,FenderD,ClipHeight],center=true);
    translate([0,0,ClipHeight*cos(StayPitch)+ClipHeight]) // trim top
    cube(2*[FenderD,FenderD,ClipHeight],center=true);
    }
    for (j = [-1,1]) // place ferrules
    translate([Ferrule[OD]*sin(StayPitch) + (Ferrule[OD]/2)*sin(StaySplay),j*(FenderR – FenderThick/2),0])
    rotate(-j*StaySplay)
    FerruleBody();
    }
    for (i=[-1,1]) // punch stiffening holes
    translate([FenderThick/2,-i*(FenderR – FenderThick/2),Ferrule[OD]/2])
    rotate([0,-90,i*StaySplay])
    PolyCyl(FerruleHoleD,Ferrule[OD],FerruleSides);
    }
    }
    //———————-
    // Build it
    if (Layout == "Profile") {
    Profile();
    }
    if (Layout == "Ferrule") {
    FerruleBody();
    }
    if (Layout == "Clip") {
    FenderClip();
    }
    if (Layout == "Build") {
    FenderClip();
    }

    As a bonus for paging all the way to the end, here’s the descent on the same stairway:

    Belmar Bridge Stairs - Descent
    Belmar Bridge Stairs – Descent

    No, I wasn’t even tempted …

  • Anker LC40 Flashlight: Anodizing Fade

    The top surface of the Anker LC40 flashlight serving as the daytime running light on Mary’s bike sees plenty of sunlight, particularly when it’s sitting beside her garden plots, and the black anodized finish on the screw-in battery cap has begun fading:

    Anker LC40 Flashlight - Anodizing fade
    Anker LC40 Flashlight – Anodizing fade

    The bottom side of the cap is in fine shape, as is the main case, so the two parts came from different metal finishing lines.

    The light on my bike, a marginally newer and essentially identical Bolder LC40, remains all black. I have no idea what “Bolder” means in this context.

    Obviously, I must get out more …

  • Side Mirror Turn Signal

    I hoped this bit of roadside debris would yield a shiny new amber LED and driver:

    Car mirror - shattered housing
    Car mirror – shattered housing

    But, alas, it uses an ordinary WY5W incandescent bulb:

    Car mirror - turn signal
    Car mirror – turn signal

    That whole assembly seems to be the replaceable unit, as the lens is firmly snapped-and-glued to the housing. The white shell used to hold the wires, but those vanished when the collision ripped the mirror off the car.

    After I pried off the shattered lens and extracted the bulb, I found a broken filament.

    Ah, well, now we won’t be riding through plastic shards along the shoulder.

  • Siglent SDS2304X Oscilloscope: Homebrew Front Cover

    Both my Tek 2215A and HP 54602 oscilloscopes came with snap-on front covers to protect all those delicate knobs and connectors. Not so the Siglent SDS2304X, which is basically a flat shoebox with a handle: the case has no features for a cover to snap onto, Siglent doesn’t offer a padded carrying case, and it’s too thick big for any of the laptop bags around here.

    I’ve been lugging it to Squidwrench meetings and can easily visualize a gash across the LCD panel or a knob rammed against a door frame.

    So I trimmed a pair of foam angles, punched holes to fit around the knobs along the right edge, cut up a cardboard tray from the heap, and duct-taped the whole mess together:

    Siglent SDS2304X Oscilloscope - crude front cover - interior
    Siglent SDS2304X Oscilloscope – crude front cover – interior

    The cover is equally ugly from the outside:

    Siglent SDS2304X Oscilloscope - crude front cover - installed
    Siglent SDS2304X Oscilloscope – crude front cover – installed

    A Velcro bellyband around the whole affair / through the handle holds it together.

    I considered 3D printing a set of corners and screwing them to a flat plastic plate, but came to my senses just in time.

  • Tour Easy Rack: Front Mount Screw

    Long ago, I conjured a front rack mount from an aluminum bar across the seat struts on our Tour Easy recumbents, with a spherical washer soaking up the angular misalignment. The rack on Mary’s bike developed a serious wobble due to a missing screw, which was easy enough to replace:

    Rack mount screw - rear
    Rack mount screw – rear

    From the side:

    Rack mount screw - side
    Rack mount screw – side

    It’s a 2 inch screw sawed down to 1.5 inch, ground to shape, then run through a die to clean up the threads.

    The nylon lock nut over on the left should keep the screw from working its way out of the tapped aluminum bar. On the other paw, a dab of Loctite survived nearly a decade of heavy loads and vibration.

  • Bypass Lopper

    Some surreptitious brush clearing called for a tool larger than our wonderful Fiskars PowerGear pruner, so I unearthed a long-disused bypass lopper in the garage (it may have Come With The House). Alas, the pivot bolt lost its jam nut long ago:

    Bypass loppers - OEM 10 mm bolt
    Bypass loppers – OEM 10 mm bolt

    That’s an M10x1.5 bolt, for which I lack a corresponding nut.

    But 3/8-16 is approximately M10x1.5, for small values of thread engagement, and I do have an assortment of inch-sized stainless steel fasteners:

    Bypass loppers - 0.375 inch bolt
    Bypass loppers – 0.375 inch bolt

    The nylon lock nut jams the bolt against the left blade, with the split washer applying pressure to the tapered blade. Slobbering oil in the sliding joints restored it to perfect working order.

    The weird round dingus on the far side of the pivot, up against the handles, is a bumper cushioning the fully closed position. It’s a nice touch and might work better if its rubber pad hadn’t aged out over the decades spent in the garage waiting for this very day.

    It’s my kind of yard work: “What do you need killed next?”

  • Bike Brake Pad Wear

    The rear brake on my bike wasn’t stopping nearly as well as it should, even after cleaning the rim and pads with brake cleaner, so I pulled the shoes and replaced the pads:

    Bike brake pad wear
    Bike brake pad wear

    It’s down a bit beyond the --WEAR--LINE-- indicator, of course.

    New brake shoes on clean rims work exactly like they should!