Stone Cold Swerve

We’re southbound on Rt 376, ticking along at about 15 mph, with fresh string-trimmer debris littering the shoulder:

T – 50 ms

Did you notice the rock? I didn’t.

The fairing ripples as my front tire hits the left side of the rock:

T = 0

I have no memory of the next two seconds.

The offset impact turns the front wheel to the left, so the bike steers out from underneath my weight:

T + 500 ms

Because the bike frame was still aimed straight ahead, the wheel is steering further to the left and putting me even more off-balance. I am somehow trying to lean left far enough to get my weight lined up with the bike:

T + 1.0 s

One second into the event, Mary has no idea what’s going on behind her.

My memory resumes with an image of the yellow midline just beyond my left foot:

T + 2.0 s

Mary heard an odd sound and asks (over the radio) “Are you all right?”

I’m approximately balanced, turning toward the shoulder, and manage to shout “NO!”:

T + 3.0 s

I’m coasting toward the shoulder with my feet off the pedals:

T + 4.0 s

Mary is stopping and I coast past her:

T + 5.0s

Landing gear out:

T + 6.0 s

Back on the shoulder, lining up with the guide rail:

T + 7 s

Dead slow:

T + 8.0 s

Docking adapter deployed:

T + 9.0 s

And stopped:

T + 10.0 s

I sat in that exact position for nearly four minutes.

A slideshow view of the same images so you can watch it unfold:

Doesn’t look like much, does it?

If I could have looked over my shoulder, this is what I would have seen, starting at T = 0 with the rock impact blurring the image:

Surely scared the daylights out of that driver, perhaps confirming all the usual expectations of crazy bicyclist behavior.

Here’s what Mary would have seen over her shoulder, again starting at T = 0 with the fairing bulging from the impact:

Timing is everything.

That Benz is new enough to have automatic emergency braking, as it slowed pretty dramatically while I was busy getting out of the way, but it’s not clear whether AEB knows about small / lightweight targets like pedestrians and bicyclists.

We completed the ride as planned, although I finally realized the front fender bracket had broken a few miles later.

Every adult human male has at least one story beginning “But for that millisecond or inch, I wouldn’t be here.” Now I have one more.

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past I will turn the inner eye to see its path. Where the fear has gone there will be nothing. Only I will remain.

Frank Herbert, Dune

Driving While Shouting

We generally don’t get hassled during our bike rides, perhaps because we ride like narrow vehicles and don’t pull stupid bicyclist tricks. The few folks who do hassle us seem to be twenty-something males, an endangered species of its own.

A shout of “Assholes!”

This slideshow requires JavaScript.

Unusually, there was no nearby traffic, so it’s not a case of mistaken identity.

Protip: Don’t do something in your employer’s vehicle that your employer may regret.

A shout of “Fuck you!”

This slideshow requires JavaScript.

Protip: Your car has a license plate. JCX-1393, matching my high-res version against the audio track; I shout the license plate and identifying information while I can see it.

Yes, I was young once … and stupid.

One hopes they outgrow it, too.

Digital Tattoo Power Supply: Polarity Doesn’t Matter

When I rewired the guts of the digital tattoo power supply to eliminate the series foot switch, I kept the original wiring polarity, with the black wire to the sleeve and the red wire to the tip:

Tattoo Digital Power Supply - internal view
Tattoo Digital Power Supply – internal view

It’s the same color code I (strongly) recommend in the Squidwrench Electronics Workshops: use any color for the ground / common wire as long as it’s black, then, if you have a red wire, use it for the positive supply. You can use yellow for the higher supply voltage, but stop being clever.

I put suitably colored Powerpoles on the far end of the cable to replace the standard tattoo machine spring clip connector, so I can attach clip leads, battery test fixtures, and so forth and so on.

We wired the supply into a clip-leaded diode measurement setup with a current limiting resistor and a pair of multimeters to measure the diode current and forward voltage, whereupon we noticed all the meters displayed negative voltages and currents.

After a frenzy of wire-checking verified their setup was all good, I forced the simplest possible test, herein recreated on my bench:

Tattoo Digital Power Supply - polarity test
Tattoo Digital Power Supply – polarity test

Which produced this display:

Tattoo Digital Supply - reverse polarity
Tattoo Digital Supply – reverse polarity


After a brief exploration of “Trust, but verify” territory, we swapped the clip leads from the power supply and continued the mission.

Back on my bench, I pulled the supply apart and measured the voltage at the jack terminals:

Tattoo Digital Power Supply - jack wiring
Tattoo Digital Power Supply – jack wiring

Still negative. Huh.

The bottom of the power supply PCB shows exactly what you should expect by now:

Tattoo Digital Power Supply - reversed color code
Tattoo Digital Power Supply – reversed color code

The red wire near the top of the board is, indeed, soldered to the trace labeled GND and goes to the jack’s tip terminal; the adjacent black wire goes to the front-panel LED. Similarly, the black wire just below it, soldered to the same trace as the yellow wire, goes to the jack’s sleeve terminal; that trace also connects to a resistor leading to the trace labeled LED+ and the LED’s red wire.

Although tattoo machines run from DC supplies, their motors or vibrators don’t depend on any particular polarity and will run fine with a backwards supply.

Resoldering the red and black wires where they should go produces the expected sign at the jack:

Tattoo Digital Supply - meter leads
Tattoo Digital Supply – meter leads

Although measuring and plotting diode voltages and currents may seem tedious, actually wiring stuff together and taking data reveals how difficult the real world can be.

I trusted the supply’s internal color code and, although I’m certain I tested the Powerpoles, I obviously didn’t notice the meter’s sign.

Memo to self: Sheesh.

Fairchild and Stoddard RF Current Probes / EMC Field Sniffers

I’ve always wondered how noisy those Arduino + fake Neopixel lamps might be and these RF sniffers might come in handy:

Fairchild MFC-25 and Stoddart 91550-1 Current Probes
Fairchild MFC-25 and Stoddart 91550-1 Current Probes

Even though they’re long obsolete, RF fields haven’t changed much in the intervening decades.

Fairchild Electronics may have become Electro-Metrics before they vanished in turn; the single useful search result offers a limited spec sheet that describes it as part of a set of three “loop probes covering the frequency range 10kHz-230MHz designed to search for RF magnetic leaks, especially in cabinets and shielded enclosures”. This one, with the blue coating, has a bandwidth of 22 MHz to 230 MHz. It has a TNC connector that now sports a cheap BNC adapter; note that it has standard polarity, not the reverse polarity required by FCC regulations that don’t take Amazon Prime into consideration.

Stoddard Aircraft Radio Co, Inc passed the 91550-1 baton to ETS-Lindgren, which (as of right now, anyway) offers a datasheet for a gadget that looks remarkably similar. The 30 Hz lower limit on the data plate suggests it’s roughly equivalent to ETS-L’s contemporary 20 Hz 91550-1L probe, but I doubt that makes much practical difference for my simple needs. The adapter takes the probe’s N connector to BNC.

The Word According to Mad Phil: If you can get to BNC, you can get to anything.


Hard Drive Platter Mood Light: Correct Phase Timing

As noted earlier, the timing for a π/16 phase delay works out to

218 steps = (π/16) * (1 cycle/2π) * (7 * 1000 step/cycle)

which amounts to a delay of 5.45 s = 218 step * 25 ms/step. That means a color should appear on the top platter 11 s after it appears on the bottom platter:

Mood Light - pi over 16 phase - composite
Mood Light – pi over 16 phase – composite

But when I actually got out a stopwatch and timed the colors, the bottom-to-top delay worked out to a mere 3.5 s…

After establishing that the steps ticked along at the expected 25 ms pace, the phase-to-step calculation produced the right answer, the increments were working as expected, I finally slept on the problem (a few times, alas) and realized that the increment happened in the wrong place:

for (int i=0; i < LEDSTRINGCOUNT; i++) { // for each layer byte Value[PIXELSIZE]; for (byte c=0; c > PIXELSIZE; c++) { // figure the new PWM values if (++Pixels[c].Step >= Pixels[c].NumSteps) {   //  ... from incremented step
            Pixels[c].Step = 0;
        Value[c] = StepColor(c,-i*Pixels[c].PlatterPhase);
    uint32_t UniColor = strip.Color(Value[RED],Value[GREEN],Value[BLUE]);
    for (int j=0; j < LEDSTRIPCOUNT; j++) {              // fill layer with color

The outer loop runs “for each layer”, so the increment happens three times on each step, making the colors shift three times faster than they should.

Promoting the increments to their own loop solved the problem:

	MillisNow = millis();
	if ((MillisNow - MillisThen) > UpdateMS) {
		for (byte c=0; c < PIXELSIZE; c++) { // step to next increment in each color if (++Pixels[c].Step >= Pixels[c].NumSteps) {
				Pixels[c].Step = 0;
				printf("Cycle %d steps %d at %8ld delta %ld ms\r\n",c,Pixels[c].NumSteps,MillisNow,(MillisNow - MillisThen));

		for (int i=0; i < LEDSTRINGCOUNT; i++) {				// for each layer
			byte Value[PIXELSIZE];
			for (byte c=0; c < PIXELSIZE; c++) {				//  ... for each color
				Value[c] = StepColor(c,-i*Pixels[c].PlatterPhase);		// figure new PWM value
//				Value[c] = (c == RED && Value[c] == 0) ? Pixels[c].MaxPWM : Value[c];	// flash highlight for tracking
			uint32_t UniColor = strip.Color(Value[RED],Value[GREEN],Value[BLUE]);
			if (false && (i == 0))
				printf("L: %d C: %08lx\r\n",i,UniColor);
			for (int j=0; j < LEDSTRIPCOUNT; j++) {				// fill layer with color

		MillisThen = MillisNow;

And then It Just Worked.

Verily, it is written: One careful measurement trumps a thousand expert opinions.


(The WordPress editor wrecked these code snippets. I’m leaving them broken so WP can maybe fix the problem.) The problem isn’t fixed, but these are OK now… as long as I don’t unleash the “improved” editor on the post, anyway.