-
Rear Running Light: Tour Easy Seat Clamp
With the amber front running light blinking away, it’s time to replace the decade-old Planet Bike Superflash behind the seat:

Superflash on Tour Easy The new mount descends directly from the clamps holding the fairing strut on the handlebars and various hose clamps:

Rear Running Light Seat Clamp – solid model The central block has two quartets of brass inserts epoxied inside:

Rear Running Light Seat Clamp – sectioned – solid model That means I can install the light, then mount the whole affair on the bike, without holding everything together while fiddling with overly long screws.
A trial fit with the not-yet-cut-to-length 25.3 (-ish) PVC pipe body tube:

Rear Running Light – Tour Easy seat clamp trial fit The aluminum plates have the standard used-car finish: nice polish over deep scratches.
Although I’ve been thinking of mounting the light below the seat rail, as shown, it can also sit above the rail.
Mary hauls seedlings and suchlike to the garden in a plastic drawer bungied to the rack, with the SuperFlash serving as an anchor point; this light may need fine tuning for that purpose.
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// Rear running light clamp for Tour Easy seat strut // Ed Nisley – KE4ZNU – 2021-09 Layout = "Show"; // [Show,Build,Block] Section = true; /* [Hidden] */ ThreadThick = 0.25; ThreadWidth = 0.40; HoleWindage = 0.2; Protrusion = 0.1; // make holes end cleanly function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); ID = 0; OD = 1; LENGTH = 2; inch = 25.4; //———————- // Dimensions // Light case along X axis, seat strut along Y, Z=0 at strut centerline LightOD = 25.4 + HoleWindage; StrutOD = 5/8 * inch + HoleWindage; PlateThick = 1/16 * inch; WallThick = 2.0; Kerf = ThreadThick; Screw = [3.0,6.8,4.0]; // M3 OD=washer, length=nut + washers Insert = [3.0,5.4,8.0 + 1.0]; // splined brass insert RoundRadius = IntegerMultiple(Screw[OD]/2,0.5); // corner rounding ScrewOC = [IntegerMultiple(StrutOD + 2*WallThick + Screw[ID],1.0), IntegerMultiple(LightOD + 2*WallThick + Screw[ID],1.0)]; echo(str("Screw OC: ",ScrewOC)); BlockSize = [ScrewOC.x + Insert[OD] + 2*WallThick, ScrewOC.y + Insert[OD] + 2*WallThick, LightOD + StrutOD + 3*WallThick]; echo(str("Block: ",BlockSize)); BaseOffset = -(WallThick + LightOD/2); // block bottom to centerline StrutOffset = LightOD/2 + WallThick + StrutOD/2; // light centerline to strut centerline echo(str("Strut screw min: ",IntegerMultiple(PlateThick + WallThick + StrutOD/2 + Insert[LENGTH]/2,1.0))); echo(str("Light screw min: ",IntegerMultiple(PlateThick + WallThick + LightOD/2 + Insert[LENGTH]/2,1.0))); NumSides = 2*3*4; //———————- // 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); } // Block with light along X axis module Block() { difference() { hull() for (i=[-1,1], j=[-1,1]) translate([i*(BlockSize.x/2 – RoundRadius),j*(BlockSize.y/2 – RoundRadius),BaseOffset]) cylinder(r=RoundRadius,h=BlockSize.z,$fn=NumSides); for (i=[-1,1], j=[-1,1]) translate([i*ScrewOC.x/2,j*ScrewOC.y/2,BaseOffset – Protrusion]) rotate(180/8) PolyCyl(Screw[ID],BlockSize.z + 2*Protrusion,8); for (i=[-1,1], j=[-1,1]) translate([i*ScrewOC.x/2,j*ScrewOC.y/2,0]) { translate([0,0,-Protrusion]) rotate(180/8) PolyCyl(Insert[OD],Insert[LENGTH] + 1*Protrusion,8); translate([0,0,(StrutOffset – Insert[LENGTH] – Kerf/2 + Protrusion)]) rotate(180/8) PolyCyl(Insert[OD],Insert[LENGTH] + 1*Protrusion,8); } translate([-BlockSize.x,0,0]) rotate([0,90,0]) cylinder(d=LightOD,h=2*BlockSize.x,$fn=NumSides); translate([0,BlockSize.y,StrutOffset]) rotate([90,0,0]) cylinder(d=StrutOD,h=2*BlockSize.y,$fn=NumSides); translate([0,0,StrutOffset]) cube([2*BlockSize.x,2*BlockSize.y,Kerf],center=true); cube([2*BlockSize.x,2*BlockSize.y,Kerf],center=true); } } //- Build it if (Layout == "Block") if (Section) difference() { Block(); rotate(atan(ScrewOC.y/ScrewOC.x)) translate([0,BlockSize.y,0]) cube(2*BlockSize,center=true); } else Block(); if (Layout == "Show") { Block(); color("Green",0.25) translate([-BlockSize.x,0,0]) rotate([0,90,0]) cylinder(d=LightOD,h=2*BlockSize.x,$fn=NumSides); color("Green",0.25) translate([0,BlockSize.y,StrutOffset]) rotate([90,0,0]) cylinder(d=StrutOD,h=2*BlockSize.y,$fn=NumSides); } if (Layout == "Build") { translate([-1.2*BlockSize.x,0,-BaseOffset]) difference() { Block(); translate([0,0,BlockSize.z]) cube(2*BlockSize,center=true); } translate([1.2*BlockSize.x,0,StrutOD/2 + WallThick]) difference() { rotate([180,0,0]) translate([0,0,-StrutOffset]) Block(); translate([0,0,BlockSize.z]) cube(2*BlockSize,center=true); } translate([0,0,StrutOffset – Kerf/2]) rotate([180,0,0]) intersection() { Block(); translate([0,0,StrutOffset/2]) cube([2*BlockSize.x,2*BlockSize.y,StrutOffset],center=true); } }