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: Recumbent Bicycling

Cruisin’ the streets

  • Tour Easy Daytime Running Light: Ball Clamp Ring

    With the flashlight firmly clamped inside its ball, a surrounding clamp ring holds the ball on the mount:

    Tour Easy - J5 Tactical V2 - front
    Tour Easy – J5 Tactical V2 – front

    The solid model chops a sphere to a completely empirical 70% of the inner ball’s length (which, itself, may be truncated to fit the flashlight grip) and glues on a hull containing the M3x50 mm screws:

    //- Clamp around flashlight ball
    module BallClamp() {
    BossLength = ClampScrew[LENGTH] – ClampScrewNut[LENGTH] – 2*ClampScrewWasher[LENGTH] – 4*ThreadThick;
    difference() {
    union() {
    intersection() {
    sphere(d=ClampOD,$fn=NumSides); // exterior ball blamp
    cube([ClampLength,2*ClampOD,2*ClampOD],center=true); // aiming allowance
    }
    for (i=[0])
    hull() {
    for (j=[-1,1])
    translate([i*(ClampLength/2 – ClampScrew[OD]),j*ClampScrewOC/2,-BossLength/2])
    rotate(180/8)
    cylinder(d=(ClampScrewWasher[OD] + 2*ThreadWidth),h=BossLength,$fn=8);
    }
    }
    sphere(d=(BallOD + 1*ThreadThick),$fn=NumSides); // interior ball
    for (i=[0] , j=[-1,1]) {
    translate([i*(ClampLength/2 – ClampScrew[OD]),j*ClampScrewOC/2,-ClampOD]) // screw clearance
    rotate(180/8)
    PolyCyl(ClampScrew[ID],2*ClampOD,8);
    }
    }
    color("Yellow")
    if (Support) { // ad-hoc supports for top half
    NumRibs = 6;
    RibLength = 0.5 * BallOD;
    RibWidth = 1.9*ThreadWidth;
    SupportOC = ClampLength / NumRibs;
    cube([ClampLength,RibLength,4*ThreadThick],center=true); // base plate for adhesion
    intersection() {
    sphere(d=BallOD – 0*ThreadWidth); // cut at inner sphere OD
    cube([ClampLength + 2*ThreadWidth,RibLength,BallOD],center=true);
    union() { // ribs for E-Z build
    for (j=[-1,0,1])
    translate([0,j*SupportOC,0])
    cube([ClampLength,RibWidth,1.0*BallOD],center=true);
    for (i=[0:NumRibs]) // allow +1 to fill the far end
    translate([i*SupportOC – ClampLength/2,0,0])
    rotate([0,90,0])
    cylinder(d=BallOD – 2*ThreadThick,
    h=RibWidth,$fn=NumSides,center=true);
    }
    }
    }
    }

    The complete ring looks about like you’d expect, although it’s never built like this:

    Fairing Flashlight Mount - Clamp - show view - solid model
    Fairing Flashlight Mount – Clamp – show view – solid model

    The top half builds as an arch on the platform:

    Fairing Flashlight Mount - Clamp - build view - solid model
    Fairing Flashlight Mount – Clamp – build view – solid model

    The uppermost layers on the inside of the arch have terrible overhang pulled upward by the cooling plastic, so the builtin support structure hold the layers downward. The preview shows they don’t quite touch, but in actual practice the support bonds to the arch and requires a bit of effort to crack off:

    Fairing Flashlight Mount - support structures
    Fairing Flashlight Mount – support structures

    The ones on the right come from my (failed) attempts to build the ball hemispheres in the obvious orientation. It’s worth noting that my built-in “support” both bonds to the part and breaks off in one piece, quite unlike the pitched battle required to separate Slic3r’s automatic support structures; I think that’s the difference between the minimum feasible and maximum possible support.

    Anyhow, the inside of the arch requires only a bit of cleanup with a ball mill before it clamps firmly around the flashlight ball. In the normal orientation, the space over the missing ball cap snuggles into the cleaned-up part of the arch and there’s enough friction on the remaining ball to hold it in place. If it does joggle loose, a wrap of tape should provide enough griptivity.

    I started by assuming socket-head cap screws and brass inserts embedded in the clamp ring could provide enough force to hold everything together:

    Fairing Flashlight Mount - Clamp - screw inserts - solid model
    Fairing Flashlight Mount – Clamp – screw inserts – solid model

    The head recesses into the top opening and the insert sits just below the split line on the XY plane. That turned out to be asking a lot from a pair of 3 mm knurled brass inserts, even with JB Weld in full effect, and I wasn’t at all confident they wouldn’t pop out under duress and fling the flashlight away.

    Each screw now compresses the entire boss between a pair of washers and the nyloc nut won’t vibrate loose. The screws also serve to stiffen the clamp ring front-to-back, although I’m not convinced it needs any reinforcement.

    I also considered splitting the ring parallel to the front, right down the middle, with screws extending through both halves:

    Fairing Flashlight Mount - Clamp - Front Back split - solid model
    Fairing Flashlight Mount – Clamp – Front Back split – solid model

    It’d be trivially easy to build the front half face-down on the platform, but the rear would have only half the surface area bonded to the plate against the fairing, which seemed like a Bad Idea. Worse, I couldn’t figure out how to align the rear half on the plate with enough room for the nuts / inserts / whatever and alignment space around the front half.

  • Tour Easy Daytime Running Light: Flashlight Ball

    A flashlight used as a daytime running light must point generally forward and an actual bike headlight must light up the road, so it must sit on an az-el mount. My old bike helmet mirror mount had actual vertical and horizontal joints:

    Helmet mirror mount - El slide in place
    Helmet mirror mount – El slide in place

    Every doodle along those lines seemed too big, too fragile, too fiddly, or all at once.

    Living here in the future, though, we can produce (crude) ball joints to order:

    Flashlight Ball Mount
    Flashlight Ball Mount

    That’s an early version of the outer mount using threaded brass inserts.

    The ball around the flashlight separates along the obvious plane of symmetry, with a 2 mm socket-head cap screw and brass insert on each side. I tried printing the hemispheres convex-side-up with hand-hewn support structures inside:

    Flashlight Ball Mount - support structure - on platform
    Flashlight Ball Mount – support structure – on platform

    The huge overhanging sections parallel to the axis didn’t bond to the supports, curled upward, and began nudging the dangling Z-axis homing switch actuator. This wasn’t a completely wasted effort, though, as similar support structures came in handy for the outer clamp ring.

    Flipping the hemispheres over so they printed U-channel upward didn’t work much better, even sitting on a flat section to eliminate the absurd part of the overhang. This view shows one hemisphere with the missing cap:

    Fairing Flashlight Mount - Ball - solid model
    Fairing Flashlight Mount – Ball – solid model

    Flipped over, the flat surface bonded perfectly to the platform, but the overhang still warped as the upper layers cooled and pulled the perimeter upward:

    Flashlight Ball Mount - warped section
    Flashlight Ball Mount – warped section

    Because normal support structures don’t contact the outer surface, I added fins to the model to hold the perimeter (almost) flat until the outer walls became sufficiently vertical to stop warping:

    Fairing Flashlight Mount - Ball - build view - solid model
    Fairing Flashlight Mount – Ball – build view – solid model

    They’re fearsome hedgehogs in person:

    Flashlight Ball Mount - flattening fins
    Flashlight Ball Mount – flattening fins

    The grip diameter determines the sphere diameter, as the sphere must have enough meat next to the grip to hold the screws and inserts. Rather than have the diameter different for every flashlight, I set it to the maximum of 45 mm or the actual diameter, which means all the flashlights in my collection have a common ball size. The hemispheres on the right have flattened ends to accommodate flashlight grips shorter than the sphere’s final diameter, achieved with a pair of intersection() operations lopping off the protruding bits:

    //- Ball around flashlight
    // Must print two!
    module BodyBall() {
    difference() {
    intersection() {
    sphere(d=BallOD,$fn=2*NumSides); // basic ball
    cube([BallLength,2*BallOD,2*BallOD],center=true); // max of flashlight grip length
    }
    translate([-LightBodies[FlashIndex][F_GRIPOD],0,0])
    rotate([0,90,0]) rotate(180/NumSides)
    PolyCyl(LightBodies[FlashIndex][F_GRIPOD],2*BallOD,NumSides); // flashlight body
    for (j=[-1,1])
    translate([0,j*BallScrewOC/2,0]) // commmon screw offset
    translate([0,0,-BallOD])
    PolyCyl(BallInsert[ID],2*BallOD,6); // punch screw shaft through everything
    translate([0,BallScrewOC/2,-Protrusion])
    PolyCyl(BallInsert[OD],(BallInsert[LENGTH] + 3*ThreadThick + Protrusion),6); // threaded insert
    translate([0,-BallScrewOC/2,BallThick])
    PolyCyl(BallScrew[OD],BallOD,6); // screw head clearance
    translate([0,0,-BallOD/2]) // remove bottom half
    cube(BallOD,center=true);
    translate([0,0,BallOD – BallThick/2]) // slice off top = bottom for E-Z build
    cube(BallOD,center=true);
    }
    if (Support) {
    NumRibs = 24;
    RibHeight = (BallOD – LightBodies[FlashIndex][F_GRIPOD]/cos(180/NumSides) – BallThick) / 2;
    ChordC = 2*sqrt(BallThick*BallOD/2 – pow(BallThick/2,2));
    intersection() {
    cube([BallLength,2*BallOD,2*BallOD],center=true); // max of flashlight grip length
    translate([0,0,BallOD/2 – BallThick/2])
    for (i=[0:NumRibs – 1])
    rotate(i*360/NumRibs + 180/NumRibs) // avoid screw holes
    translate([ChordC/2 + BallOD/8,0,-RibHeight/2])
    cube([BallOD/4,2*ThreadWidth,RibHeight],center=true);
    }
    }
    }

    Because the fins extend from resolutely convex surfaces, I snipped them off with flush-cutting pliers, reamed out the holes, epoxied the inserts in place, assembled the ball, and introduced it to Mr Belt Sander.

    Protip: don’t hold the ball with your finger through the hole. It will eventually fly off under the workbench and it’s better if it doesn’t break your finger in the process.

    A somewhat rough outer surface turns out to be an advantage, not a liability, as the clamp ring around the ball must hold it against the normal (and unusually severe) vibrations found on a bike.

    The inner cylindrical section is smooth enough to require a wrap of tape around the flashlight grip to anchor it in position. The tape adheres to the flashlight and squishes into the ball’s layer lines, even under mild pressure from the 2 mm screws. The outer clamp ring applies compression to the ball, so the tiny screws need not withstand much force at all, which is a good thing.

  • Tour Easy Daytime Running Light: Fairing Clamp Plates

    For reasons obvious to any cyclist, we must improve the forward conspicuity of our Tour Easy recumbents with a white daytime running light; a near-miss boosted this to the front of the project queue. While you can outfit a standard bike with a handlebar-mounted headlight (*), at any price from the sublime to the ridiculous, the smooth snout of a fully faired recumbent covers all the usual attachment points.

    A small LED flashlight tacked onto the fairing support bracket seems workable enough to make up for a significant case of ugly:

    Tour Easy - J5 Tactical V2 - front
    Tour Easy – J5 Tactical V2 – front

    That’s a J5 Tactical V2 flashlight on my bike.

    Mary’s bike has a tidier Anker LC40 in an earlier mount version:

    Tour Easy - Anker LC40 - front
    Tour Easy – Anker LC40 – front

    The Anker required an adapter to hold an 18650 cell in its 3xAAA-size body. The J5 V2 is resolutely 18650-only, which is fine with me.

    The intent here is to find out whether this works, figure out the proper aiming point(s), then de-bulk the mount.

    The next few posts will cover various bits & pieces of the design, because I must remember why I did things the way they turned out: sometimes the obvious choices didn’t work.

    The Zzipper fairing originally mounted to the strut across the handlebars with a single 1/4-20 nylon screw on each side. Even with a nylon washer on the outside, the stress concentration cracked the polycarbonate sheet around the screws and brackets, so I designed & printed flat ABS plates to spread the stress over a larger area:

    Fairing mount - inside
    Fairing mount – inside

    The tapered edges were supposed to be flexible, but the foam sheets sandwiched on both sides of the fairing actually provided most of the compliance. There’s another screw in the open hole binding the inner & outer plates together.

    The mounts worked perfectly, even as they faded over the years. The fairings became quite scuffed during the course of our near-daily rides, but, heck, we’re also a bit scuffed and it’s still all good.

    The new PETG inner plates seat on the bracket to nearly its full thickness:

    Tour Easy - Zipper fairing plate - inside
    Tour Easy – Zipper fairing plate – inside

    The flashlight on the outer plate applies torque around the bolt which (I hope) the sides of the recess can resist. This is the absolutely key part of the design and, I’m somewhat ashamed to admit, took me far too long to figure out. What you don’t want: weird & fragile gimcrackery clamped onto the strut extending under the fairing’s edge, with the flashlight hanging far off to the side.

    I modeled the fairing strut’s aluminum bracket as a 2D rectangle, plus a pair of chords, embiggened by a thread around the outside edge, minus the hole, then extruded to the proper height:

    //- Fairing Bracket
    // Magic numbers taken from the actual fairing mount
    // Centered on screw hole
    /* [Hidden] */
    inch = 25.4;
    BracketHoleOD = 0.25 * inch; // 1/4-20 bolt holes
    BracketHoleOC = 1.0 * inch; // fairing hole spacing
    // usually 1 inch, but 15/16 on one fairing
    Bracket = [48.0,16.3,3.6 – 0.6]; // fairing bracket end plate overall size
    BracketHoleOffset = (3/8) * inch; // end to hole center
    BracketM = 3.0; // endcap arc height
    BracketR = (pow(BracketM,2) + pow(Bracket[1],2)/4) / (2*BracketM); // … radius
    module Bracket() {
    linear_extrude(height=Bracket[2],convexity=2)
    difference() {
    translate([(Bracket[0]/2 – BracketHoleOffset),0,0])
    offset(delta=ThreadWidth)
    intersection() {
    square([Bracket[0],Bracket[1]],center=true);
    union() {
    for (i=[-1,0,1]) // middle circle fills gap
    translate([i*(Bracket[0]/2 – BracketR),0])
    circle(r=BracketR);
    }
    }
    circle(d=BracketHoleOD/cos(180/8),$fn=8); // dead center at the origin
    }
    }

    The hole isn’t strictly necessary, as I punch out both screw holes as part of the plate assemblies.

    The overall plate shape comes from the top half of a hull() wrapped around four squashed spheres:

    //- General plate shape
    // Centered on the hole for the fairing bracket
    Plate = [100.0,30.0,6*ThreadThick + Bracket[2]];
    PlateRad = Plate[1]/4;
    echo(str("Base plate thick: ",Plate[2]));
    module PlateBlank() {
    difference() {
    translate([BracketHoleOC,0,0])
    intersection() {
    translate([0,0,Plate[2]/2]) // select upper half of spheres
    cube(Plate,center=true);
    hull()
    for (i=[-1,1], j=[-1,1])
    translate([i*(Plate[0]/2 – PlateRad),j*(Plate[1]/2 – PlateRad),0])
    resize([2*PlateRad,2*PlateRad,2*Plate[2]])
    sphere(r=PlateRad); // nice rounded corners!
    }
    translate([2*BracketHoleOC,0,-Protrusion]) // screw holes
    PolyCyl(BracketHoleOD,2*Plate[2],8);
    translate([0,0,-Protrusion])
    PolyCyl(BracketHoleOD,2*Plate[2],8);
    }
    }

    Then the inner plate is just a plate blank stamped with the bracket:

    //- Inner plate
    module InnerPlate() {
    difference() {
    PlateBlank();
    translate([0,0,Plate[2] – Bracket[2] + Protrusion]) // punch out fairing bracket
    Bracket();
    }
    }

    You’ll need a set for the side of the fairing without the running light:

    Fairing Flashlight Mount - Plates - solid model
    Fairing Flashlight Mount – Plates – solid model

    The outer plate looks reasonably sleek in real life, although that’s not the primary consideration:

    Tour Easy - Zipper fairing plate - outside
    Tour Easy – Zipper fairing plate – outside

    You could replace the squared-off ends with simple half-circles, maybe stretched into stylin’ ellipse shapes, without too much effort.

    I got out the screws, set up to cut them with a pull saw and miter box, then realized they are plastic. Put away the saw, got out the utility knife, and cut them to length with one firm push. No distorted threads, no dust, no muss, no fuss.

    (*) Opinion: any headlight with non-replaceable, USB-chargeable cells is a toy. I can replace a discharged (or failed) 18650 cell in the middle of a ride, where a dead battery inside a spendy headlight would leave me in the dark. Might not matter for a DRL, but seems absolutely critical on night rides. ‘Nuff said.

  • Layout Pen For Black Objects

    This worked surprisingly well to lay out black foam gaskets for new fairing mounting plates:

    Black foam layout with ceramic fabric pen
    Black foam layout with ceramic fabric pen

    Mary uses the Fons & Porter Mechanical Pencil to mark quilting patterns on fabric. It has, they say, a “strong ceramic 0.9MM white lead” with “water-soluble dyes” capable of both laying down a durable mark and washing out without leaving a trace. I don’t care about the latter, of course, but it did brush off reasonably well.

    The next step involved running an X-Acto knife around the perimeter of the plate and punching the holes.

    You can get colored ceramic leads (for small values of color) for use on other backgrounds.

  • Tour Easy: White ABS vs. Six Years of Sunlight

    These white ABS fairing plates held the Zzipper fairing on my Tour Easy ‘bent since 2011:

    ABS Fairing Plates - 6 years
    ABS Fairing Plates – 6 years

    Over the course of those six years I’ve ridden about 6 × 2500 = 15000 miles, maybe more, maybe less. I can ride at 15 mph for a while, but 12 mph seems a more reasonable overall estimate, making for a bit over 1000 hours. Figure the bike spends that much time sitting outdoors at the far end of the ride and you’re looking at what 2000+ hours of sunlight does to ABS.

    In addition to discoloration, the plates have become brittle, as shown in the chips in third one down, and permanently deformed due to the pressure of the nylon bolts compressing the black foam against the fairing.

    A closer look at the top plate:

    ABS Fairing Plates - 6 years - detail
    ABS Fairing Plates – 6 years – detail

    My 3D print quality has improved a lot since then.

    New plates of a different design are, as NASA puts it, “in work”.

    The pix come from the new LiDE 120 scanner. It does a good job with the color, but has (for good reason) an essentially zero depth of field: if it’s not on the glass, it’s out of focus.

  • Monthly Image: Great Blue Heron

    This Great Blue Heron caught a bright orange goldfish in the Vassar Farm Pond just before I rode past, spotted the scene, and fumbled my camera out of the underseat bag.

    The heron hurked the fish down, with the abrupt right-angle bend in its neck marking the fish’s current location:

    Great Blue Heron - swallowing
    Great Blue Heron – swallowing

    A bit of wiggling & jiggling put the meal in the right place and the bird relaxed:

    Great Blue Heron - ruminating
    Great Blue Heron – ruminating

    A postprandial flight around the pond apparently settled the fish:

    Great Blue Heron - takeoff
    Great Blue Heron – takeoff

    It landed on a snag a few dozen feet from where it started, then proceeded to look regal:

    Great Blue Heron - idling
    Great Blue Heron – idling

    Those things really do look like pterodactyls in flight!

     

  • Disaster Tourism

    Riding around the block after a nasty storm showed far more than the usual number of leaves on the Dutchess Rail Trail:

    Wappinger Tornado - Rail Trail near Titusville Rd - 2017-06-01
    Wappinger Tornado – Rail Trail near Titusville Rd – 2017-06-01

    I spotted several trees down on both sides of the trail approaching Maloney Road, with another large branch across that access ramp:

    Wappinger Tornado - Maloney Rd Rail Trail ramp - 2017-06-01
    Wappinger Tornado – Maloney Rd Rail Trail ramp – 2017-06-01

    You might be able to see the large tree down across the trail on the far side of the road, up the slope.

    Maloney Rd had many downed trees:

    Wappinger Tornado - Maloney Rd 1 - 2017-06-01
    Wappinger Tornado – Maloney Rd 1 – 2017-06-01

    With chainsaw chips and flare ash piles everywhere:

    Wappinger Tornado - Maloney Rd 2 - 2017-06-01
    Wappinger Tornado – Maloney Rd 2 – 2017-06-01

    From the National Weather Service:

    The National Weather Service in coordination with Dutchess County Emergency Management officials, have confirmed a brief touchdown of a tornado on May 31. The tornado path began near the intersection of Maloney Road and Route 376. The tornado traveled due east along and just north of Maloney Road for approximately 1.25 miles before dissipating. Damage included numerous snapped hardwood and softwood trees and the roof lifted off a shed.

    Both of Mary’s gardens suffered beatdowns, with the Vassar Farm plot pretty thoroughly pulverized by marble-size hail; she’s not in a good mood right now.

    The DPW crews had plenty on their to-do list, but that branch was gone a day later.

    Update: The top of the barely visible tree in the second picture just kissed the trail fence, but a much larger tree smashed both fences on its way across the trail:

    Wappinger Tornado - Rail Trail S of Maloney - 2017-06-04
    Wappinger Tornado – Rail Trail S of Maloney – 2017-06-04

    If you need some firewood, maybe you can make a deal …