Bike Helmet Mirror: Brasswork Clamp

A bit of Quality Shop Time produced a slight improvement to the clamp holding the mirror to the stalk:

Helmet Mirror Ball Mount - mirror joint brasswork
Helmet Mirror Ball Mount – mirror joint brasswork

The general idea is to hold the wave washer (it’s mashed under the flat washer, honest) above those bumps on the plate holding the mirror and stalk balls. It’s a few millimeters from the end of a ¼ inch brass rod, drilled for the M3 screw, and reduced to 4.5 mm with a parting tool to clear the bumps.

While I was at it, I made two spare mirrors, just to have ’em around:

Helmet Mirror Ball Mount - new vs old
Helmet Mirror Ball Mount – new vs old

The new ball mount looks downright svelte compared to the old Az-El mount, doesn’t it?

I should replace the steel clamp plates with a stainless-steel doodad of some sort to eliminate the unsightly rust, but that’s definitely in the nature of fine tuning.

Mary’s Zucchini Bread Recipe

After grating the nutmeg, continue with this:

Mary's Zucchini Bread Recipe
Mary’s Zucchini Bread Recipe

To end up with this:

Zucchini bread - minus QC sample
Zucchini bread – minus QC sample

Mary omits the cloves.

Applesauce is completely optional. Should you prefer a softer & sweeter loaf, give it a try.

Conversely, reduce the sugar by about half if you’ve accustomed yourself to a keto-oid diet; the raisins carry enough sweetness for us. You can use brown sugar if you like.

She derived it from the Garden Way’s Zucchini Cookbook by Ralston & Jordan (© 1977):

Zucchini Bread Recipe - Garden Way Zucchini Cookbook
Zucchini Bread Recipe – Garden Way Zucchini Cookbook

Obviously, cooking is not an exact science; a recipe is just where you start …

Algorithmic pricing / money laundering is a thing:

Garden Way Zucchini Cookbook - Amazon listing
Garden Way Zucchini Cookbook – Amazon listing

Ya can’t make this stuff up …

Keyboard Tray Raising

Long ago and far away, I moved the keyboards off our desk surfaces to a more convenient location on a tray under the middle drawer. Mary’s desk recently gained a somewhat thinner keyboard with a thumbwheel volume control, so she wanted the tray moved up:

Keyboard Tray Relocation - in place
Keyboard Tray Relocation – in place

The supports on either side started out as 2×4 lumber with a slot cut (using the radial arm saw I no longer have) for the aluminum sheet:

Keyboard Tray Relocation - support view
Keyboard Tray Relocation – support view

For the record, a pair of screws hold each support to the drawer:

Keyboard Tray Relocation - support screw
Keyboard Tray Relocation – support screw

Not elegant. Works fine. Good enough!

Tiny Bandsaw™ wasn’t designed for ripsawing lumber, but the same Proxxon 10/14 TPI blade I use for aluminum worked better than I expected to lop a 1-¼ inch strip from the wood slats:

Keyboard Tray Relocation - bandsaw fixture
Keyboard Tray Relocation – bandsaw fixture

That’s a reenactment based on a true story. The wood scraps clamped on the bandsaw table leave enough clearance for the 2×4 slide to freely, yet not enough for the blade to wander off track.

You can tell how long ago I built the original trays: nary a trace of 3D printing!

Nutmeg Season

Well, it’s really zucchini bread season, with grated nutmeg among the spices (*):

Zucchini bread - minus QC sample
Zucchini bread – minus QC sample

Having recently bought a very sharp grater, I hauled out a small vise to save my fingertips:

Nutmeg grating - mini-vise
Nutmeg grating – mini-vise

The dark lunette comes from a previous clamping attempt; it takes a while to find the most secure pin arrangement.

Grate a flat:

Nutmeg grating - first flat
Nutmeg grating – first flat

I’ve always enjoyed the surprisingly intricate patterns inside what looks like a bland nut.

Flip it over, flatten the other side, and grab it in an even smaller vise:

Nutmeg grating - flat clamping
Nutmeg grating – flat clamping

In truth, that vise is intended for small cylinders, not flattened nuts, but I figured it’d suffice for light-duty use. Grate parallel to the vise screw, reclamp as needed, and it worked out reasonably well.

Eventually, you have a pile of powder and one cubic nutmeg:

Nutmeg grating - results
Nutmeg grating – results

I’m sure there’s a way to grate the remaining cube, but I’m unwilling to shred my fingertips.

Tip the powder into a small jar and repeat as needed. Each nutmeg produces about 5 grams and I did three of the things this time.


(*) We omit the cloves and knock the sugar down by half. Your tastes will surely differ.

Update: Mary’s recipe!

Bike Helmet Mirror: Ball Mount

Nine years ago, I didn’t know how enough to design a bike helmet mirror with a ball mount, but even an old dog can learn a new trick:

Helmet Mirror Ball Mount - on helmet
Helmet Mirror Ball Mount – on helmet

However, it’s worth noting my original, butt-ugly Az-El mounts lasted for all of those nine years, admittedly with adjustments along the way, which is far more than the commercial mounts making me unhappy enough to scratch my itch.

The mount adapts the split spherical clamp from the daytime running light:

Helmet Mirror Mount - Ball
Helmet Mirror Mount – Ball

Scaling it down for a 10 mm polypropylene ball around the base of the 30 mm inspection mirror’s shaft simplified everything:

Helmet Mirror Ball Mount - drilled ball test
Helmet Mirror Ball Mount – drilled ball test

I’m reasonably sure I couldn’t have bought 100 polypro balls for eight bucks a decade ago, but we’ll never know. Drilling the hole was a complete botch job, about which more later. The shaft came from a spare mirror mount I made up a while ago; a new shaft appears below.

The solid model, like Gaul, is in three parts divided:

Helmet Mirror Ball Mount - Slic3r
Helmet Mirror Ball Mount – Slic3r

The helmet plate (on the right) has a slight indent more-or-less matching the helmet curvature and gets a layer of good double-stick foam tape. The clamp base (on the left) has a pair of brass inserts epoxied into matching recesses below the M3 clearance holes:

Helmet Mirror Ball Mount - inserts
Helmet Mirror Ball Mount – inserts

A layer of epoxy then sticks the helmet plate in place, with the inserts providing positive alignment:

Helmet Mirror Ball Mount - plates
Helmet Mirror Ball Mount – plates

The clamp screws pull the inserts against the plastic in the clamp base, so they can’t pull out or through, and the plates give the epoxy enough bonding surface that (I’m pretty sure) they won’t ever come apart.

I turned down a 2 mm brass insert to fit inside the butt end of the mirror shaft and topped it off with a random screw harvested from a dead hard drive:

Helmet Mirror Ball Mount - assembled - rear view
Helmet Mirror Ball Mount – assembled – rear view

At the start, it wasn’t obvious the shaft would stay stuck in the ball, so I figured making it impossible to pull out would eliminate the need to find it by the side of the road. As things turned out, the clamp exerts enough force to ensure the shaft ain’t goin’ nowhere, so I’ll plug future shafts with epoxy.

The front side of the clamp looks downright sleek:

Helmet Mirror Ball Mount - assembled - front view
Helmet Mirror Ball Mount – assembled – front view

Well, how about “chunky”?

The weird gray-black highlights are optical effects from clear / natural PETG, rather than embedded grunge; it looks better in person. I should have used retina-burn orange or stylin’ black.

This mount is much smaller than the old one and should, in the event of a crash, not cause much injury. Based on how the running light clamp fractures, I expect the clamp will simply tear out of the base on impact. In the last decade, neither of us has crashed, so I don’t know what the old mount would do.

The clamp is 7 mm thick (front-to-back), set by the M3 washer diameter, with 1.5 mm of ball sticking out on each side. The model has a kerf one thread high (0.25 mm) between the pieces to add clamping force and, with the screws tightened down, moving the ball requires a disturbingly large effort. I added a touch of rosin and that ball straight-up won’t move, which probably means the shaft will bend upon droppage; I have several spare mirrors in stock.

On the other paw, the ball turns smoothly in the clamp and it’s easy to position the shaft as needed: much better than the old Az-El mount!

The inspection mirror hangs from a double ball joint which arrives with a crappy screw + nut. I epoxied the old mirror mount nut in place, but this time around I drilled the plates for a 3 mm stainless SHCS, used a wave washer for a bit of flexible force, and topped it off with a nyloc nut:

Helmet Mirror Ball Mount - mirror joint
Helmet Mirror Ball Mount – mirror joint

I’m unhappy with how it looks and don’t like how the washer hangs in free space between those bumps, so I may eventually turn little brass fittings to even things out. It’s either that or more epoxy.

So far, though, it’s working pretty well and both units meet customer requirements.

The OpenSCAD source code as a GitHub Gist:

// Bike helmet mirror mount - ball joint
// Ed Nisley KE4ZNU 2020-09
/* [Layout options] */
Layout = "Build"; // [Build, Show, Plate, Base, Clamp]
//-- Extrusion parameters
// Extrusion parameters
/* [Hidden] */
ThreadThick = 0.25;
ThreadWidth = 0.40;
HoleWindage = 0.2;
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
function IntegerLessMultiple(Size,Unit) = Unit * floor(Size / Unit);
Protrusion = 0.1; // make holes end cleanly
inch = 25.4;
ID = 0;
OD = 1;
//- Basic dimensions
MountDia = 30.0; // footprint on helmet
BallDia = 10.0;
BallRad = BallDia / 2;
WallThick = IntegerMultiple(2.0,ThreadWidth);
FloorThick = IntegerMultiple(2.0,ThreadThick);
CornerRound = 2.0;
Insert = [3.0,4.0,4.0]; // threaded brass insert
Screw = [3.0,5.5,25.0]; // clamp screw
Washer = [3.7,7.0,0.7]; // washer
ShowGap = 2.0;
BuildGap = 5.0;
//-- Helmet Interface Plate
ScrewOC = BallDia + 2*WallThick + Screw[ID];
echo(str("Screw OC: ",ScrewOC));
Clamp = [ceil(Washer[OD]), // barely holds washer under screw
ScrewOC + Washer[OD], // minimal clearance for washer
BallDia +2*FloorThick // screw fits through insert
Kerf = ThreadThick;
echo(str("Clamp: ",Clamp));
HelmetCX = 60.0; // empirical helmet side curve
HelmetMX = 3.0;
HelmetRX = (pow(HelmetMX,2) + pow(HelmetCX,2)/4)/(2*HelmetMX);
HelmetPlateC = MountDia;
HelmetPlateTheta = atan(HelmetPlateC/HelmetRX);
HelmetPlateM = 2*HelmetRX*pow(sin(HelmetPlateTheta/4),2);
echo(str("Plate indent: ",HelmetPlateM));
HelmetPlateThick = max(FloorThick,0.6*Insert[LENGTH]) + HelmetPlateM;
echo(str("Screw length: ",Clamp.z + Insert[LENGTH]));
MountSides = 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);
// Clamp frame around ball
module ClampFrame() {
difference() {
union() {
for (i=[-1,1], j=[-1,1]) {
translate([i*(Clamp.x/2 - CornerRound),j*(Clamp.y/2 - CornerRound),Clamp.z/2 - CornerRound])
translate([i*(Clamp.x/2 - CornerRound),j*(Clamp.y/2 - CornerRound),-Clamp.z/2])
for (j=[-1,1])
sphere(d=BallDia + HoleWindage,$fn=48);
for (j=[-1,1])
module ClampSelect(Section) {
XlateZ = (Section == "Top") ? Clamp.z/2 :
(Section == "Bottom") ? -Clamp.z/2 :
intersection(convexity=5) {
cube([2*Clamp.x,2*Clamp.y,Clamp.z + 2*Protrusion],center=true);
// Concave plate fitting helmet shell
module HelmetPlate() {
difference() {
translate([0,0,HelmetPlateThick - HelmetPlateM + HelmetRX])
for (j=[-1,1])
translate([0,j*ScrewOC/2,-Protrusion]) {
PolyCyl(Insert[OD],0.6*Insert[LENGTH] + Protrusion,6);
// Base of clamp ring
module MountBase() {
difference() {
union() {
translate([0,0,FloorThick + Clamp.z/2])
for (j=[-1,1])
PolyCyl(Insert[OD],0.6*Insert[LENGTH] + Protrusion,6);
// Lash it together
if (Layout == "Plate") {
if (Layout == "Base") {
if (Layout == "Clamp") {
if (Layout == "Show") {
translate([0,0,ShowGap]) {
translate([0,0,Clamp.z/2 + FloorThick + ShowGap/2])
translate([0,0,Clamp.z/2 + FloorThick + ShowGap])
if (Layout == "Build") {
translate([MountDia/2 + BuildGap,0,0])
translate([-(MountDia/2 + BuildGap),0,0])
translate([0,MountDia/2 + BuildGap,Clamp.z/2])

The original doodles include a bit of dress-up fairing that didn’t make the cut:

Helmet Mirror Ball Mount - doodles
Helmet Mirror Ball Mount – doodles

Discrete LM3909: Blue LED Waveforms

The circuitry and instrumentation is essentially the same discrete LM3909 as before:

LM3909 - blue - test setup
LM3909 – blue – test setup

With a few minor tweaks:

  • Blue LED, forward voltage 2.56 to 2.97 V
  • 24 Ω R1
  • One Q2 current mirror transistor driving Q3

With a pair of fresh AA alkaline cells producing 3.1 V (not the NiMH Duracells you see in the picture), the blue LED blinks brightly.

The 610 mV peak voltage across R1 shows the LED starts at 25.4 mA:

LM3909 blue - 3.1 V - R1 24 ohm
LM3909 blue – 3.1 V – R1 24 ohm

The capacitor reaches 1 V, then goes about 150 mV into reverse charge during the flash (note the different horizontal scales):

LM3909 blue - 3.1 V - C1 V
LM3909 blue – 3.1 V – C1 V

The Darlington version of Q1 seems to do a decent job of keeping the cap out of reverse charge. A Shottky diode would add a few hundred mV, but I doubt there’s anything nasty going on inside the cap as it stands.

The blue LED has a forward drop of 2.97 V at 20 mA, so I’m surprised the voltage across it hits 3.1 V at 25 mA:

LM3909 blue - 3.1 V - LED V
LM3909 blue – 3.1 V – LED V

Very little of the voltage appears across Q3, the driver transistor:

LM3909 blue - 3.1 V - Q3 coll
LM3909 blue – 3.1 V – Q3 coll

With a pair of nearly dead alkaline cells for a 2.0 V supply, the LED current peak drops to 4.6 mA:

LM3909 blue - 2.0 V - R1 24 ohm
LM3909 blue – 2.0 V – R1 24 ohm

The LED lights brightly, then fades away exactly like you’d expect from that waveform.

The cap still charges to about 1 V and stays well above 0 V during the (much longer) flash:

LM3909 blue - 2.0 V - C1 voltage
LM3909 blue – 2.0 V – C1 voltage

The voltage across the LED now reaches only 2.7 V, which is substantially higher than the 2.0 V battery supply and exactly why the LM3909 existed:

LM3909 blue - 2.0 V - LED voltage
LM3909 blue – 2.0 V – LED voltage

Q3 continues to saturate, although you can see the effect of the decreased base drive during the flash:

LM3909 blue - 2.0 V - Q3 coll
LM3909 blue – 2.0 V – Q3 coll

The blue LED won’t light at 1.3 V, but still gives out a weak flash at 1.7 V, so I’d say the tweaked LM3909 circuitry works reasonably well.

DSO150: USB Serial Output

Taking all those pictures of the DSO150 screen reminded me it has a data dump function: press the V/Div and ADJ buttons to squirt configuration, measurements, and trace data from the TX pad on the main board, just in front of the red-black power wires hot-melt glued in place:

DSO150 USB serial adapter - interior
DSO150 USB serial adapter – interior

The picture shows the “before” stage, while I was figuring out where to carve another hole in the case.

NB: The 113-15001-111 DSO150 firmware version includes the serial output option, so you won’t need third-party firmware. Similarly, current PCBs bring the serial pins to neatly labeled header pads. You should refer to the JYETech DSO150 / DSO Shell product page for the details.

After all the cuttin’ and filin’ was done, it looked like this:

DSO150 USB serial adapter - exterior
DSO150 USB serial adapter – exterior

The power switch on the back of the case (top of the picture) disconnects the lithium cell from the charge controller board (now tucked behind the battery) to eliminate any trickle current discharge. Charging the battery thus requires turning that switch on and turning the scope off with its own power switch (along its front edge). Capturing trace data requires having both switches on (duh), whereupon the scope’s normal operating current convinces the charge controller that the cell hasn’t reached full charge. Turn the scope off and, most likely, the controller will tell you the cell is fully charged.

An intro blurb squirts from the port at 115200 in good old 8N1 format when you turn the scope on:

DSO Shell
JYE Tech Ltd.
FW: 113-15001-111

Pressing the V/Div and ADJ buttons dumps the trace data:

VPos, -2.02V
TriggerLevel,  2.02V
Vmax,  2.85V
Vmin,  0.24V
Vavr,  0.87V
Vpp,  2.61V
Vrms,  1.03V
Freq, 0.441Hz
Cycl, 2.266s
PW, 0.231s
Duty, 10.2 %
00000,0000000000, 0.8518688
00001,0000000008, 0.5273474
00002,0000000016, 0.5273474
00003,0000000024, 0.5476300
00004,0000000032, 0.5476300
00005,0000000040, 0.5476300
<< snippage >>
01015,0000008120, 0.8113037
01016,0000008128, 0.8315863
01017,0000008136, 0.8315863
01018,0000008144, 0.8315863
01019,0000008152, 0.8315863
01020,0000008160, 0.8315863
01021,0000008168, 0.8315863
01022,0000008176, 0.8518688
01023,0000008184, 0.8518688

It’s all in neatly comma-separated-value format, so you can slam it into a spreadsheet and have your way with it. Utilities also exist to capture the data, extract the values, and send them directly to GNUplot, etc.

Like so:

DSO150 test image
DSO150 test image

If I expected to do a lot of that, I’d boldify the traces and embiggen the text, all of which is in the nature of fine tuning.

It’s hard to reproduce the beauty of the DSO150’s display, though:

DSO150 test image
DSO150 test image

The DSO150 remains pretty good for being the worst oscilloscope I’m willing to use …