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.

The New Hotness

  • BOB Yak Trailer: Fender Front Mount

    I eventually tracked a distressingly loud rattle from the BOB Yak trailer to a fender mount failure:

    BOB Yak Trailer fender front mount - aluminum fatigue
    BOB Yak Trailer fender front mount – aluminum fatigue

    The screw clamped the round aluminum fender between two flat washers (the other of which has been touring the workbench). The hole in the aluminum started as a screw slot and eventually fretted away around the edge of the washers, leaving a trapped fragment to fall out as I loosened the screw.

    Well, this mount lasted a decade longer than the wire mount at the top of the fender, so there’s that.

    As before, a bit of math conjures a chunky mount from the vasty digital deep:

    Fender front mount - solid model - Show view
    Fender front mount – solid model – Show view

    The first iteration didn’t have the hole for the threaded insert angled downward at 10°, but it’s easier to make better measurements with a “pretty close” prototype. I’m reasonably sure the angle is a glitch due to hand-brazing the frame tubes, but we’ll never know.

    The inner plate angles to match the insert, thus keeping the screw & washer perpendicular to the surface:

    Fender front mount - solid model - Mounts view
    Fender front mount – solid model – Mounts view

    A brim around that chip of plastic ensures a good grip on the platform:

    BOB Yak Trailer - fender front mount - PrusaSlicer preview
    BOB Yak Trailer – fender front mount – PrusaSlicer preview

    I suppose rounding the corners would make it prettier:

    BOB Yak Trailer fender front mount - inner plate
    BOB Yak Trailer fender front mount – inner plate

    The original screw was slightly too short, so that’s a shiny replacement from the Drawer o’ Random M5 Screws. If I ever have occasion to go in there again, I’ll use a button head screw, although there’s certainly enough clearance:

    BOB Yak Trailer fender front mount - tire clearance
    BOB Yak Trailer fender front mount – tire clearance

    From the top, the gray PETG-CF looks like it grew there:

    BOB Yak Trailer fender front mount - installed
    BOB Yak Trailer fender front mount – installed

    I figured the mount’s radius by feeding measurements into the chord equation and assuming the overall curve is circular; the radius came out slightly too large, which likely won’t make much difference.

    The OpenSCAD source code as a GitHub Gist:

    // BOB Yak Trailer – fender front mount
    // Ed Nisley – KE4ZNU
    // 2026-06-15
    include <BOSL2/std.scad>
    Layout = "Show"; // [Build,Show,Frame,Fender,OuterMount,InnerMount,Mounts]
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    HoleWindage = 0.2;
    Protrusion = 0.01;
    NumSides = 4*3*2*4;
    Gap = 5.0/2;
    $fn=NumSides;
    WallThick = 5.0;
    Washer = [6.0,16.0,1.5]; // M5 fender washer
    Rivnut = [5.0,10.3,1.5]; // M5 rivnut in frame
    FrameOD = 16.1; // trailer frame tubing
    FrameAngle = 10;
    FenderOA = [52,440,1.5]; // minor major thickness
    BlockOA = [0,40.0,1.25*Washer[OD]];
    //—–
    // Define things
    // Relevant part of the trailer frame
    // origin at center of rivnut
    module Frame() {
    yrot(FrameAngle)
    union() {
    left(Rivnut[LENGTH])
    ycyl(2*BlockOA.y,d=FrameOD,anchor=RIGHT);
    xcyl(FrameOD/2,d=Rivnut[OD],anchor=RIGHT);
    left(Protrusion)
    xcyl(10,d=Rivnut[OD],anchor=LEFT);
    }
    }
    module OuterFender() {
    torus(od=FenderOA[OD],d_min=FenderOA[ID],orient=FRONT,anchor=LEFT);
    }
    module FullFender() {
    difference() {
    OuterFender();
    right(FenderOA[LENGTH]) // make it a cup
    torus(od=FenderOA[OD] – 2*FenderOA[LENGTH],d_min=FenderOA[ID] – 2*FenderOA[LENGTH],
    orient=FRONT,anchor=LEFT);
    right(FenderOA[ID]/2) // remove inner half
    ycyl(2*BlockOA.y,d=FenderOA[OD] – FenderOA[ID],anchor=LEFT);
    down(2*Washer[OD]) // remove bottom part
    cuboid(2*[FenderOA[OD],FenderOA[OD],FenderOA[OD]],anchor=TOP+LEFT);
    }
    }
    module OuterMount() {
    difference() {
    right(FenderOA[ID]/2)
    cuboid([FrameOD/3 + Washer[LENGTH] + FenderOA[ID]/2,BlockOA.y,BlockOA.z],
    rounding=1.0,anchor=RIGHT);
    Frame();
    OuterFender();
    }
    }
    module InnerMount() {
    difference() {
    render()
    intersection() {
    yrot(FrameAngle)
    cuboid([WallThick + FenderOA[LENGTH],BlockOA.y,BlockOA.z],anchor=LEFT);
    right(FenderOA[LENGTH])
    OuterFender();
    }
    yrot(FrameAngle)
    xcyl(FenderOA[ID],d=Washer[ID],anchor=LEFT);
    }
    }
    //—–
    // Build it
    if (Layout == "Frame") {
    Frame();
    }
    if (Layout == "Fender") {
    FullFender();
    }
    if (Layout == "OuterMount") {
    OuterMount();
    }
    if (Layout == "InnerMount") {
    InnerMount();
    }
    if (Layout == "Mounts") {
    OuterMount();
    InnerMount();
    }
    if (Layout == "Show") {
    OuterMount();
    InnerMount();
    color("Gray",0.6) {
    Frame();
    FullFender();
    }
    }
    if (Layout == "Build") {
    up(BlockOA.z/2) left(FenderOA[ID]/4)
    OuterMount();
    up(BlockOA.z/2)
    xrot(180)
    yrot(-FrameAngle)
    InnerMount();
    }