-
Bike Rack Tray Holder: Stretchy Tiedown Straps
The tray holder on Mary’s bike worked well:

Bike Rack Tray Holder – in use Except for having the bungee cord run across the middle of the tray where it blocks access for larger trays and tends to bend the taller leaves.
Well, I can fix that:

Bike Rack Tray Holder – straps – rear The front tiedown is similar:

Bike Rack Tray Holder – straps – front They’re printed from TPU: rectangular blocks and chains, ending in wire hooks bashed from a coat hanger. The M4 button-head screws thread into (uncrushed) rivnuts, which seemed easier to manage than square nuts in this situation.
The chains are just thick circles, with half of the top links sunk into the blocks:

Stretchy Straps – build layout You’d (well, I’d) want to build them one at a time, because sometimes this happens:

Bike Rack Tray Holder – bad platform adhesion Based on those measurements, I raised the extruder by 0.1 mm, but apparently did a poor job of cleaning / flattening the cold TPU on the nozzle and got it wrong. As a result, the first layer didn’t get squooshed properly onto the BuildTak, came unstuck, and produced art . The track down the middle of the photo shows traces of a previous, badly over-squooshed test chain.
The stretched TPU relaxes enough to leave very little tension after a day, as shown by the unhooked right chain:

Bike Rack Tray Holder – straps – relaxing However, that make the chains exactly the right length, so they require even more force to get the hooks off the rack. After relaxing for another day, the stretched chains return to roughly their original lengths, so it’s all good.
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// TPU Tiedown Straps for bike rack tray holder // Ed Nisley – KE4ZNU // 2026-05-14 include <BOSL2/std.scad> Layout = "Build"; // [Show,Build,Chain,Blocks,Front,Rear] /* [Hidden] */ HoleWindage = 0.2; Protrusion = 0.01; NumSides = 4*3*2*4; Gap = 5.0; $fn=NumSides; LinkID = 7.0; LinkOD = 10.0; LinkOC = 14.0; LinkHeight = 4.0; JointWidth = 2.0; FrontChainAngle = 30; // from vertical FrontChainLength = 80.0; // nominal length RearChainAngle = 20; // from vertical RearChainLength = 100.0; // nominal length BlockOA = [80.0,12.0,15.0]; InsertOC = 30.0; //—– // Define things module Chain(n=2) { render() difference() { union() { hull() { cyl(LinkHeight,d=JointWidth,anchor=BOTTOM,rounding=0.0); back((n – 1)*LinkOC) cyl(LinkHeight,d=JointWidth,anchor=BOTTOM,rounding=0.0); } for (i = [0:n-1]) back(i*LinkOC) cyl(LinkHeight,d=LinkOD,anchor=BOTTOM,rounding=0.0); } for (i = [0:n-1]) back(i*LinkOC) down(Protrusion) cyl(LinkHeight + 2*Protrusion,d=(LinkID + HoleWindage),anchor=BOTTOM,rounding=-1.0); } } module FrontBlock() { difference() { cuboid(BlockOA,anchor=BOTTOM,chamfer=1.0,except=BACK); for (i = [-1:1]) right(i*InsertOC) down(Protrusion) { cyl(BlockOA.z + 2*Protrusion,d=4.0 + HoleWindage,anchor=BOTTOM); // screw clearance cyl(1.5,d=9.0,anchor=BOTTOM); // insert head cyl(11.0,d=6.0,anchor=BOTTOM); // insert body } } } module RearBlock() { up(BlockOA.z/2) fwd(BlockOA.y/2) difference() { cuboid(BlockOA,anchor=FRONT,chamfer=1.0,except=BACK); for (i = [-1:1]) right(i*InsertOC) fwd(Protrusion) { ycyl(BlockOA.z + 2*Protrusion,d=4.0 + HoleWindage,anchor=FRONT); // screw clearance ycyl(1.5,d=9.0,anchor=FRONT); // insert head ycyl(11.0,d=6.0,anchor=FRONT); // insert body } } } module FrontAssembly(cl=FrontChainLength,ca=FrontChainAngle) { Links = ceil(cl / LinkOC); union() { up(cl*cos(ca)) { FrontBlock(); back(BlockOA.y/2) xrot(90) for (i = [-1,1]) left(i*InsertOC/2) zrot(-i*ca + 180) Chain(Links); } } } module RearAssembly(cl=RearChainLength,ca=RearChainAngle) { Links = ceil(cl / LinkOC); union() { up(cl*cos(ca)) { RearBlock(); back(BlockOA.y/2) xrot(90) for (i = [-1,1]) left(i*InsertOC/2) zrot(-i*ca + 180) Chain(Links); } } } //—– // Build things if (Layout == "Chain") Chain(); if (Layout == "Blocks") { fwd(BlockOA.y) FrontBlock(); back(BlockOA.y) RearBlock(); } if (Layout == "Front") FrontAssembly(); if (Layout == "Rear") RearAssembly(); if (Layout == "Show") { fwd(BlockOA.y) FrontAssembly(); back(BlockOA.y) zrot(180) RearAssembly(); } if (Layout == "Build") { fwd(BlockOA.z + Gap/2) up(BlockOA.y/2) xrot(-90) down(FrontChainLength*cos(FrontChainAngle)) FrontAssembly(); back(BlockOA.z + Gap/2) zrot(180) up(BlockOA.y/2) xrot(-90) down(RearChainLength*cos(RearChainAngle)) RearAssembly(); }