The GE rod continues to corrode nicely:

But, as before, most of the corrosion is close to the top end. The rest of the rod was covered with a thick mineral scale that I hammered off, then scuffed the rod with a shoe rasp to expose some metal.
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.
Things around the home & hearth
Quite by accident, I spotted a considerable number of yellow-cap standard Coca-Cola bottles during a recent grocery ride:

As before, the main ingredient after fizzy water is good old sucrose, which is why it merits a yellow cap:

Four bottles spread out over the next few months will be about all I can stand…
Clearing off the shelves produced a book I haven’t opened in a loooong time:

The price sticker shows that textbooks have always been expensive:

The first line looks like a date and, indeed, I took “Principles of Mechanics” in Spring 1974, so that book would cost $88.08 in 2015 dollars, based on the official CPI calculator.
It’s harder to figure college costs, but the old rule of thumb says it’s a factor of two higher than the CPI. A bit of successive approximation with a compound interest calculator suggests an annual inflation of 3.9% and 7.8% says the book would cost $403 today.
Which, it turns out, isn’t all that much higher than what our Larval Engineer has been paying for the fatter textbooks in her engineering courses.
Even using today’s worthless dollars, that’s still a chunk o’ change…
Memo to Self: As the bumper sticker puts it, “If you think education is expensive, try ignorance.”
As we expected, the remaining temple of Mary’s Silhouette glasses broke, a bit over a year from the previous repair, and this repair proceeded along the same lines as the previous fix.
Cross-drill a brass tube for the teeny screws:

I don’t recall having to do quite this much filing to make the screws fit, but they don’t call ’em “needle files” for nothin’:

Trim the tube to the proper length by chucking it in the Sherline, rotating the spindle by hand, and filing a notch just below the jaws:

Then file the end flat, countersink it just a bit, and ream out the hole to fit the broken end of the earpiece. This one didn’t quite fit the tubing, but we’re talking a few mils of tolerance on a bent piece of titanium. Rough up the end of the earpiece, degrease everything, and a few dabs of epoxy suffice for another Steampunk repair:

The original fix continues to hold, but … this can’t go on.
I’d originally secured the rear fender to the steel strap connecting the chainstays on Mary’s Tour Easy with a cable tie: small, simple, light weight, reliable. Unfortunately, that put the end of the fender just slightly lower than the strap and, I fear, sprayed water all over the strap, where it worked its way through a paint flaw and rusted the steel under the paint. A simple metal clip would chew its way through the pain[t] on the strap, so, seeing as how we’re living in the future…
The C-shaped block on the top grips the steel cross-strap, the trough fits the fender’s curve, the little spider supports the inside of the nut recess, and a pair of alignment pin holes (one visible) help during gluing:

Although it’s tempting to 3D print both parts as a single unit, laying them out like this aligns the threads for best strength in each piece:

Pressing the bracket on the glass slab (flat side up, nubblies on the bottom) with the clamps in place finished the job. The slightly crushed support spider from the nut recess sits in the foreground:

Magenta PETG matches the red Tour Easy paint surprisingly well:

From below, you can see why the top block can’t extend all the way to the bottom of the fender mount:

That rubber boot needs replacing in the worst possible way, but I didn’t have anything suitable on hand and wouldn’t dismount that cable even if I had; cables never go back on properly.
Alas, because the brakes weren’t mounted when I did the measurements, I had to build one to find out why a long block wouldn’t work:

The screw atop the block (on the left in that picture) presses a small plastic slug against the steel strap, in the hopes it won’t chew through the paint quite as rapidly. The screws & nuts are stainless, so at least they’ll survive for a while.
The curve in the trough comes from the chord equation applied to these crude measurements:

Fortunately, it’s tucked into a spot where nobody ever looks…
The OpenSCAD source code:
// Tour Easy rear fender bracket
// Ed Nisley KE4ZNU March 2015
Layout = "Build"; // Build Show TabHolder Block
//- 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
PlateWidth = 45; // Tour Easy frame plate
PlateDepth = 17;
PlateThick = 3.3; // ... allow for a bit of crud
TabWidth = 32; // fender tab
TabLength = 40;
TabThick = 1.5;
TabDepth = 8;
ChordM = TabDepth - TabThick; // find fender tab's radius of curvature
ChordC = TabWidth;
TabRadius = ((ChordM * ChordM) + (ChordC * ChordC)/4) / (2 * ChordM);
echo(str("Fender radius: ", TabRadius));
FenderOffset = -25.0; // from bottom of frame plate
ScrewClear = 5.0; // close enough to 10-32
ScrewTap = ScrewClear - 1.0;
NutThick = 3.1; // 10-32 nut
NutOD = 9.5; // ... across flats
Chamfer = 5.0; // edge chamfer
BlockSlab = 10.0;
BlockWidth = TabWidth;
BlockDepth = PlateDepth + BlockSlab;
BlockHeight = TabLength + PlateThick + BlockSlab;
BlockOutline = [
[TabDepth/2,0],
[TabDepth/2,TabLength],
[PlateDepth,TabLength],
[PlateDepth,TabLength + PlateThick],
[0,TabLength + PlateThick],
[0,BlockHeight - Chamfer],
[Chamfer,BlockHeight],
[BlockDepth - Chamfer,BlockHeight],
[BlockDepth,BlockHeight - Chamfer],
[BlockDepth,TabLength - BlockSlab + Chamfer],
[BlockDepth - Chamfer,TabLength - BlockSlab],
[BlockSlab + Chamfer,TabLength - BlockSlab],
[BlockSlab,TabLength - BlockSlab - Chamfer],
// [BlockSlab,Chamfer], // full-length tab (TrimBlock = false)
// [BlockSlab - Chamfer,0], // ""
[TabDepth/2,TabLength - BlockSlab - Chamfer] // trim lower tab (TrimBlock = true)
];
TrimBlock = true;
BuildGap = 5.0;
//----------------------
// 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);
}
//- Locating pin hole with glue recess
// Default length is two pin diameters on each side of the split
PinOD = 1.75;
PinOC = TabLength / 2;
module LocatingPin(Dia=PinOD,Len=0.0) {
PinLen = (Len != 0.0) ? Len : (4*Dia);
translate([0,0,-ThreadThick])
PolyCyl((Dia + 2*ThreadWidth),2*ThreadThick,4);
translate([0,0,-2*ThreadThick])
PolyCyl((Dia + 1*ThreadWidth),4*ThreadThick,4);
translate([0,0,-(Len/2 + ThreadThick)])
PolyCyl(Dia,(Len + 2*ThreadThick),4);
}
module LocatingPins(Length) {
for (i=[-1,1])
translate([i*PinOC/2,0,0])
rotate(180/4)
LocatingPin(Len=Length);
}
//----------------------
// Pieces
module TabHolder() {
difference() {
translate([-TabWidth/2,-TabLength,0])
cube([TabWidth,TabLength,2*TabDepth],center=false);
translate([0,-TabLength/4,0])
LocatingPins(5.0);
if (!TrimBlock)
translate([0,-3*TabLength/4,0])
LocatingPins(5.0);
translate([0,FenderOffset,-Protrusion])
rotate(180/6)
PolyCyl(ScrewClear,3*TabDepth,6);
if (TrimBlock)
translate([0,FenderOffset,-Protrusion])
rotate(180/6)
PolyCyl(NutOD,NutThick + Protrusion,6);
translate([0,TabLength,TabRadius + TabDepth/2])
rotate([90,0,0])
rotate(180/(6*4))
cylinder(r=TabRadius,h=3*TabLength,$fn=6*4);
}
if (TrimBlock)
color("Yellow")
translate([0,FenderOffset,0])
for (Seg=[0:5]) {
rotate(30 + 360*Seg/6)
cube([NutOD/2,
2*ThreadWidth,
(NutThick - ThreadThick)],center=false);
}
}
module Block() {
difference() {
linear_extrude(height=BlockWidth,convexity=3)
polygon(points=BlockOutline);
if (!TrimBlock)
translate([TabDepth/2,TabLength/4,BlockWidth/2])
rotate([0,90,0])
LocatingPins(5.0);
translate([TabDepth/2,3*TabLength/4,BlockWidth/2])
rotate([0,90,0])
LocatingPins(5.0);
translate([-BlockDepth,TabLength + FenderOffset,BlockWidth/2])
rotate([0,90,0])
rotate(180/6)
PolyCyl(ScrewClear,3*BlockDepth,6);
translate([PlateDepth/2,BlockHeight - BlockSlab - Protrusion,BlockWidth/2])
rotate([-90,0,0])
PolyCyl(ScrewTap,2*BlockSlab,6);
if (!TrimBlock)
translate([(BlockSlab - NutThick),(TabLength + FenderOffset),BlockWidth/2])
rotate([0,90,0])
rotate(180/6)
PolyCyl(NutOD,NutThick + Protrusion,6);
}
}
//----------------------
// Build it
if (Layout == "TabHolder")
TabHolder();
if (Layout == "Block")
Block();
if (Layout == "Show") {
translate([0,BlockWidth/2,0])
rotate([90,0,0]) {
color("Magenta")
Block();
color("Orange")
translate([0,TabLength,TabWidth/2])
rotate([0,-90,0])
TabHolder();
}
}
if (Layout == "Build") {
translate([-BuildGap,0,0])
rotate(-90)
TabHolder();
translate([BuildGap,TrimBlock ? -BlockHeight/1.5 : -BlockHeight/3,0])
Block();
}
Well, another year, another deep-cleaning session, another break in the strut holding up the drawers in the Whirlpool refrigerator:

This time, there’s a fixture positioning the tab in the proper orientation while the solvent evaporates. The two bottom clamps hold an aluminum plate against the top (far side) of the strut, with the top-center clamp holding the tab against a steel block shimmed with cardboard to get the correct angle. The other two clamps squash the tab against the joint, which is well-soaked with IPS 4 adhesive.
I replaced the right-side guide plate, originally made from phosphor bronze strip, with some thicker steel strip. The bronze strip collapsed into the worn section of the plastic bump that appeared in the previous post:

I’ve written bigger caution messages on the top of the strut in red letters, but we think it’s getting on time for a whole new refrigerator…
Our Larval Engineer reports that the PLA pivot for the Sienna’s hood rod didn’t survive contact with the van’s NYS Inspection. I’m not surprised, as PLA tends to be brittle and the inspection happened on a typical February day in upstate New York. Seeing as how PETG claims to be stronger and more durable than PLA, I ran off some replacements:

The square cap fit snugly over the bottom of the post; PETG tolerances seem pretty much the same as for PLA.
A slightly larger loop may be more durable, so I changed one parameter in the OpenSCAD code to get this:

Which printed just like you’d expect:

Despite the hairs stretching between each part, the nozzle didn’t deposit any boogers during the print. The top and bottom use Hilbert Curve infill, which looks pretty and keeps the nozzle from zipping back and forth quite so much; perhaps that’s a step in the right direction.
Tapping the holes for 6-32 stainless machines screws went easily enough:

She gets one of each and I keep the others for show-n-tell sessions.
The OpenSCAD source code, which differs from the original by a constant or two:
// Sienna Hood Rod Pivot
// Ed Nisley KE4ZNU November 2013
//- Extrusion parameters must match reality!
// Print with 2 shells and 3 solid layers
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
ShellOD = 20.0;
ShellID = 8.75;
ShellLength = 10.0;
TaperLength = 1.5;
TaperID = 11.4;
BaseWidth = 20.0;
BaseThick = 3.0;
PegSide = 9.5; // mounting peg through sheet metal
PegLength = 7.0;
PegCornerTrim = 0.75;
PegHoleOD = 0.107*inch; // 6-32 tap hole
PegTrimSide = sqrt(2)*PegSide - PegCornerTrim;
ClampWall = 3.0; // clamping cap under sheet metal
ClampHoleOD = 0.150*inch; // 6-32 clearance hole
ClampCap = 3.0; // solid end thickness
PanelThick = 2.0; // sheet metal under hood
NumSides = 6*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);
}
module ShowPegGrid(Space = 10.0,Size = 1.0) {
Range = floor(50 / Space);
for (x=[-Range:Range])
for (y=[-Range:Range])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//----------------------
// Build it
//ShowPegGrid();
// pivot
translate([-ShellOD,0,0])
difference() {
union() {
cylinder(r=ShellOD/2,h=ShellLength,$fn=NumSides); // housing
translate([-ShellOD/2,0,0]) // filler
cube([ShellOD,(ShellOD/2 + BaseThick),ShellLength],center=false);
translate([0,(ShellOD/2 + BaseThick/2),ShellLength/2]) // foot
cube([BaseWidth,BaseThick,ShellLength],center=true);
translate([0, // peg
(ShellOD/2 + PegLength/2 + BaseThick - Protrusion),
PegSide/2])
intersection() {
cube([PegSide,(PegLength + Protrusion),PegSide],center=true);
rotate([0,45,0])
cube([PegTrimSide,2*PegLength,PegTrimSide],center=true);
}
}
PolyCyl(ShellID,ShellLength,NumSides); // central hole
translate([0,0,-Protrusion]) // end bevels
cylinder(r1=TaperID/2,r2=ShellID/2,h=(TaperLength + Protrusion),$fn=NumSides);
translate([0,0,(ShellLength + Protrusion)])
rotate([180,0,0])
cylinder(r1=TaperID/2,r2=ShellID/2,h=(TaperLength + Protrusion),$fn=NumSides);
translate([0,0,PegSide/2]) // screw tap hole
rotate([-90,0,0])
PolyCyl(PegHoleOD,(ShellOD + BaseThick + PegLength),6);
}
// anchor cap
translate([2*PegSide,0,0])
difference() {
translate([0,0,(PegLength + ClampCap)/2]) // overall shape
cube([(PegSide + ClampWall),(PegSide + ClampWall),(PegLength + ClampCap)],center=true);
translate([0,0,(PegLength/2 + ClampCap + Protrusion)]) // peg cutout
cube([(PegSide + ThreadWidth),(PegSide + ThreadWidth),(PegLength + Protrusion)],center=true);
translate([0,0,-Protrusion]) // screw clearance
PolyCyl(ClampHoleOD,2*PegLength,6);
}