Posts Tagged Repairs

Raspberry Pi Slowdown

At first, the yard camera worked fine, but a few days later the stream of JPEG images would unpredictably stall. I connect to it through a public-key SSH session and, sometimes, the login would stall for tens of seconds and, with a session set up, various exciting operation like, say, htop would unpredictably stall; if I waited long enough, they’d complete normally.

This seemed familiar:

Samsung 16 GB Evo MicroSD card

Samsung 16 GB Evo MicroSD card

It’s a known-good card from a reputable supplier, not that that means much these days. The camera flash highlights the gritty silkscreen (?) texture of the orange overlay, but the production value seems high enough to pass muster.

Popping the card in my desktop PC showed:

  • It remains functional, at least to the extent of being mount-able and write-able
  • 3probe --time-ops /dev/sdb showed it still held 16 GB
  • fsck -fv /dev/sdb[12] shows no problems
  • Both partitions looked good

So I shrank the main partition to 7.5 GB, copied the image to the desktop PC’s SSD, fired up the Token Windows Laptop, ran the Official SD Card Formatter, and discovered that it thought the card had only 63 MB (yes, MB) available. That’s the size of the FAT boot partition, so I returned the card to the desktop PC, unleashed gparted on it, blew away the partitions, reformatted the whole thing to one 16 GB FAT32 partition, and stuck it back in the laptop, whereupon the Official Formatter agreed it had every byte it should.

A format-with-overwrite then proceeded apace; the card doesn’t support format-with-erase.

Back in the desktop, I copied the saved image back onto the card which, en passant, blew away the just-created FAT format and restored the Raspbian partition structure. The 8 GB of that copy proceeded at an average 12.1 MB/s. I did not watch the transfer closely enough to notice any protracted delays.

Back in the Pi, the card booted and ran perfectly, sending an image every second to the laptop (now running its usual Mint Linux) on the guest network:

Turkey flock in driveway - 2017-03-21

Turkey flock in driveway – 2017-03-21

SSH sessions now work perfectly, too, and commands no longer jam.

So it seems a good-quality MicroSD card can experience protracted delays while writing data, to the extent of tens of seconds, stalling the Pi in mid-operation without producing data errors or any other symptoms.

It’s not clear the Official Formatter does anything that simply copying the image back to the card wouldn’t also accomplish, although overwriting the entire 16 GB extent of the card exercises all the cells and forces the card controller to re/de/un/allocate bad blocks. If, indeed, the blocks are bad, rather than just achingly slow.

Moral of the story: Don’t use MicroSD cards as mass storage devices, at least not for industrial applications that require consistent performance.




Kitchen Sink Faucet Deck Sealing

I had to replace the faucet on a kitchen sink (not our own, for reasons not relevant here) after the steel nuts & washers holding the base to the sink deck rotted completely away. Why faucet manufacturers used plain steel in that location remains a mystery; I’m sure it has something to do with cost reduction and damn the consequences after a few years.

Of course, the new faucet didn’t sit quite flat on the sink deck, due to the raised rim around the perimeter. Installing it like that would prevent the (hard plastic) gasket from sealing against the deck, with the inevitable water leak below the sink; we started this project by scrapping a water-soaked shelf under the sink due to the previous faucet’s wrecked seal. Sliding the oval base forward enough to clear the rim would expose the two holes on each side, with similar results.

You can see the problem if you squint hard enough:

Kitchen Sink Faucet - gasket mask

Kitchen Sink Faucet – gasket mask

I decided raising the back of the base by maybe two millimeters wouldn’t be particularly visible, particularly if I filled the space with silicone snot (almost) matching the gasket to provide a solid foundation.

The blue tape masks the sink surface around the gasket to prevent silicone mishaps and simplify cleanup. I held the gasket in place, traced around it with new Xacto knife blade, and peeled the inside out just like I knew what I was doing.

Generous beads of snot around all the holes and across the back will provide a firm base and a good seal:

Kitchen Sink Faucet - gasket in place

Kitchen Sink Faucet – gasket in place

With that in place, I aligned the faucet over the gasket, gently tightened the nuts holding the base to the deck, and waited a day for the silicone to start curing before completing the plumbing. It’ll take a while to finish, due to the limited area exposed around the edges.

The water lines now have shutoff ball valves, which the next person to work on it will surely appreciate.


Kenmore Electric Clothes Dryer Rebuild

Our ancient Kenmore clothes dryer (Model 110.96282100 for maximal SEO goodness) developed symptoms suggesting the heater and overtemperature cutouts were in fine shape: it continued to turn and heat, but didn’t completely dry the clothes. In addition, it emitted a horrible whine that sounded like a bad bearing.

The wiring diagram pasted on the back panel shows how it works (clicky for more dots):

Kenmore clothes dryer 110.96282100 - wiring diagram

Kenmore clothes dryer 110.96282100 – wiring diagram

Obviously, it’s not a firmware problem…

The motor ran just fine, so Thermal Fuse 2 had never blown at 196 °F.

The Operating Thermostat (along the bottom edge of the diagram) switches the 240 VAC heater off when the clothes temperature (actually, the drum exhaust temperature) exceeds 155 °F. It’s in series with the non-resettable 350 °F thermal cutoff and the resettable 250 °F high limit thermostat, both of which were intact, as shown by the fact that the heater still worked.

We generally run the dryer in Auto mode, with the Temperature Selector in the middle position. The Selector varies the resistance in series with the Operating Thermostat heater (near the middle of the diagram), controlled by Timer Switch 1: increasing resistance reduces the heater current and requires hotter clothes before the Thermostat trips. For the first part of the cycle, the BK-BU contact closes to allow the Selector to affect the current. The BK-V contact also closes during the last part of the cycle, cutting out the Selector and letting the Thermostat hold the clothes at 155 °F by cycling the drum heater.

So I installed a new Operating Thermostat (plus the accompanying thermal fuse I didn’t need):

Kenmore clothes dryer - operating thermostat

Kenmore clothes dryer – operating thermostat

You can do that from the back of the dryer without dismantling it, by removing the rear cover.

For whatever it’s worth, the replacement Operating Thermostat heater has a 74 kΩ resistance, not the 5.6 to 8.4 kΩ range shown on the wiring diagram. Preliminary testing suggests it does what it’s supposed to, so maybe they’ve improved (and, surely, cheapnified) its guts to work with 1% of the original power. More likely, the Temperature Selector now doesn’t do anything, as its (minimum) 10 kΩ resistance on the High setting doesn’t amount to squat compared with the new thermostat heater, but we don’t have enough experience to say anything definite.

In an attempt to fix the whine, I took the whole thing apart to replace the idler wheels supporting the drum, the drum drive belt, and the belt tensioner pulley. The interior of the dryer is filled with sharp edges and hatred, so expect some bloodshed.

Removing and installing the triangular wheel retainers requires a small flat-blade screwdriver and considerable muttering. Here’s the old wheel to the left of the motor, before replacement:

Kenmore clothes dryer - tub support wheel

Kenmore clothes dryer – tub support wheel

After reassembling the dryer, the heater worked fine.

The whine also worked fine, much to my dismay.

So I took it all apart again, removed the plate covering the duct from the drum exhaust port to the blower wheel on the motor, removed a generous handful of lint from the middle of the blower wheel, extracted a pile of debris from the bottom of the duct below the wheel, vacuumed everything in sight, reassembled the dryer, and it now sounds great.

Along the way, a small square brass (?) rod fell out of the debris, sporting one shiny end, well-worn to a diagonal slope. I think the rod got trapped between the duct and the back of the blower wheel, where it would produce the whine only when the motor got up to speed (thus, sounding OK while hand-turning the motor). The accumulated debris & lint held it in place, so flipping the dryer on its face and rotating the motor in both directions had no effect: turning the dryer upright simply let it fall back into the same position.

No pictures, alas. We did the second teardown in a white-hot frenzy to Get It Done and swept the brass rod away with all the other debris.



Cheap WS2812 LEDs: Another Failure

A few days after epoxying a replacement WS2812 RGB LED into the base of the 21HB5A and, en passant, soldering a 3.5 mm plug-and-jack into the plate lead for EZ removal, the top LED failed.

21HB5A - Audio plug cable

21HB5A – Audio plug cable

In this case, it also failed the Josh Sharpie test with bad encapsulation sealing:

WS2812 LED failure - ink test patterns

WS2812 LED failure – ink test patterns

Here’s a view from another angle, with a warm-white desk lamp for a bit of color:

WS2812 LED failure - ink test patterns - 2

WS2812 LED failure – ink test patterns – 2

Those patterns took a few days to appear and also showed up in some, but not all, of the previous failing LEDs.

Although I have no idea what’s going on, it’s certainly distinctive!

An envelope of RGBW LEDs, allegedly with SK2812 controllers, has arrived from a different eBay supplier, so it’s time for an upgrade.



Tour Easy Rear Fender Clip

One of the clips holding the rear fender on my Tour Easy broke:

Rear fender clip - broken

Rear fender clip – broken

Well, if the truth be told, the fender jammed against the tire when I jackknifed the trailer while backing into a parking spot, dragged counterclockwise with the tire, and wiped that little tab right off the block. After 16 years of service, it doesn’t owe me a thing.

Although the clip around the fender sits a bit lower than it used to (actually, the entire fender sits a bit lower than it should be), you can see the tab had a distinct bend at the edge of the aluminum block supporting the underseat bag frame: the block isn’t perpendicular to the tire / fender at that point.

After devoting far too long to thinking about how to angle the tab relative to the clip, I realized that I live in the future and can just angle the clip relative to the tab. Soooo, the solid model has a rakish tilt:

Fender Clip - Slic3r preview

Fender Clip – Slic3r preview

The original design had a pair of strain relief struts where the tab meets the clip, but I figured I’ll add those after the PETG fractures.

I mooched the small bumpouts along the arc from the original design; they provide a bit of stretch & bend so to ease the hooks around the fender.

The hooks meet the clip with very slight discontinuities that, I think, come from slight differences between the 2D offset() operation and the circle() diameter; the usual 1/cos(180/numsides) trick was unavailing, so I tinkered until the answer came out right.

Despite those stretchy bumps, it took three iterations, varying the chord height by about 1.5 mm, to securely snap those hooks onto the fender:

Rear fender clip - 3D printed improvement

Rear fender clip – 3D printed improvement

Yeah, sorry ’bout the fuzzy focus on the screw head.

It’s impossible to measure the chord height accurately enough in that position and I was not going to dismount the rear tire just to get a better measurement.

You can see how the clip’s rakish tilt matches the fender’s slope, so the tab isn’t bent at all. It’ll probably break at the block the next time I jackknife the trailer, of course.

I heroically resisted the urge to run off a lower fender mount.

The OpenSCAD source code as a GitHub Gist:

The original doodle, with some measurements unable to withstand the test of time:

Rear Fender Clip - measurement doodles

Rear Fender Clip – measurement doodles


Leave a comment

Raspberry Pi 3: Disabling the Build-In WiFi

streaming media player in the Basement Laboratory Warehouse Wing has a concrete block wall between it and the WiFi router, so that even high(er)-gain USB antennas can’t grab enough signal for reliable streaming. After some fiddling, I snaked a cable from a hub, along the floor joints, to the Pi and declared victory. It turned out the Pi, an old Pi 1 Model B, had some trouble keeping up with the times, and I eventually swapped it for a Pi 3.

Forcing a static address for the wired port followed the now-standard recipe, with eth0 instead of wlan0 in /etc/dhcpcd.conf.

However, plugging a network cable into the Pi 3 then produces two network connections: the wired one I wanted and a the aforementioned unreliable WiFi link through the built-in hardware. The only reliable way to turn off the WiFi connection seems to require applying The BFH through a line in /etc/rc.local:

sudo ifconfig wlan0 down

Removing my WiFi credentials from /etc/wpa_supplicant/wpa_supplicant.conf prevents the hardware from connecting before the hammer comes down.

And then it streams perfectly…


Leave a comment

Raspberry Pi Boot vs. Avahi vs. DHCP

Sometimes, one of our homebrew streaming media players will emerge from reset without starting up properly. The system board LEDs blink more-or-less normally, but the WiFi activity monitor seems … odd. This post documents the results of some exploratory surgery hinting at a possible solution.

I set the router’s DHCP server to assign a fixed IP address to each of our homebrew streaming media players based on its MAC address. That seemed less horrible than setting a static IP address in each player’s configuration, although I could see advantages to either approach. For streamer1, the player discussed here, the IP address is; that’s a non-routable address used only on our network behind the router.

During the Raspberry Pi’s boot, the default /etc/rc.local script finds and displays its IP address:

_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"

The /var/log/boot log showed this after one boot:

--- snippage ---
         Starting LSB: Raise network interfaces....
[  OK  ] Started LSB: Raise network interfaces..
         Starting ifup for wlan0...
[  OK  ] Started ifup for wlan0.
[  OK  ] Reached target System Initialization.
[  OK  ] Listening on Avahi mDNS/DNS-SD Stack Activation Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Reached target Basic System.
         Starting Avahi mDNS/DNS-SD Stack...
         Starting Regular background program processing daemon...
[  OK  ] Started Regular background program processing daemon.
         Starting dhcpcd on all interfaces...
[  OK  ] Started Avahi mDNS/DNS-SD Stack.
[  OK  ] Started dhcpcd on all interfaces.
[  OK  ] Reached target Network.
         Starting /etc/rc.local Compatibility...
         Starting Permit User Sessions...
[  OK  ] Reached target Network is Online.
         Starting LSB: Start NTP daemon...
My IP address is
[  OK  ] Started Permit User Sessions.
connect: Network is unreachable
[  OK  ] Started /etc/rc.local Compatibility.
         Starting Terminate Plymouth Boot Screen...
         Starting Hold until boot process finishes up...

That mysterious IP address is a Link-local address, about which Wikipedia says: “If a host on an IEEE 802 (Ethernet) network cannot obtain a network address via DHCP, an address from to may be assigned pseudorandomly.”

So, having the router hand out IP addresses doesn’t quite work the way I expected. The Pi awards itself a link-local IP address before getting one from the DHCP server, presumably because the vast Linux startup Pachinko machine has a race condition. Alas, the pseudorandom LL address doesn’t fit in the network handled by the router: the Pi can’t connect to the network.

My code in /etc/rc.local starts the streaming player immediately after the default code displaying the IP address, thus joining the race condition: if the player starts up before the DCHP server assigns the proper IP address, it can’t connect to the music server out on the Interwebs. My code includes a retry loop with a five second delay which eventually connects, at least most of the time, but sometimes gets wedged.

The most reasonable fix seems to involve forcing a static address on each Raspberry Pi, so it can immediately connect to the network, without any negotiation, and get on with the business at hand.

Rather than configuring that in  /etc/network/interfaces as before, the New Hotness adds a stanza to  /etc/dhcpcd.conf:

interface wlan0
static ip_address=
static routers=
static domain_name_servers=

En passant, I killed off IPV6 with this line in /etc/sysctl.conf:


The router doesn’t support IPV6 and there’s no point in using it. Bonus: less log clutter. Double Bonus: startup happens faster!

All of which may help the NTP client update the system clock sooner, perhaps preventing time jumps like this:

2017-02-14 08:42:24,183 INFO: Player setup for: BR1
2017-02-14 08:42:24,184 INFO: Volume control knob: /dev/input/volume
2017-02-14 08:42:24,225 INFO: Starting mplayer on Ambient ->
2017-02-14 08:42:27,175 INFO: Track name: [Arcticology - Nocturnal Sounds]
2017-02-14 08:42:27,194 INFO: Track unmuted
2017-02-15 04:25:00,386 INFO: Track name: [Oöphoi - Suspended Matter]
2017-02-15 04:25:00,413 INFO: Track unmuted

The timestamps in the first five lines date back to the previous shutdown. The Pi remains plugged in and powered while it’s reset, which apparently preserves the system clock variables, albeit without a hardware clock ticking along: time stands still between shutdown and restart.

In this case, the IP address situation worked itself out before the player started, but the NTP clock reset on the sixth line happened at least three seconds after the log began.

This chunk of /var/log/syslog has more detail:

Feb 14 08:42:24 streamer1 dhcpcd[693]: wlan0: leased for 86400 seconds
Feb 14 08:42:24 streamer1 dhcpcd[693]: wlan0: adding route to
Feb 14 08:42:24 streamer1 dhcpcd[693]: wlan0: adding default route via
Feb 14 08:42:24 streamer1 avahi-daemon[387]: Registering new address record for on wlan0.IPv4.
Feb 14 08:42:24 streamer1 dhcpcd[693]: wlan0: deleting route to
Feb 14 08:42:24 streamer1 avahi-daemon[387]: Withdrawing address record for on wlan0.
Feb 14 08:42:24 streamer1 avahi-daemon[387]: Leaving mDNS multicast group on interface wlan0.IPv4 with address
Feb 14 08:42:24 streamer1 avahi-daemon[387]: Joining mDNS multicast group on interface wlan0.IPv4 with address
Feb 14 08:42:25 streamer1 dhcpcd[693]: wlan0: no IPv6 Routers available
Feb 14 08:42:25 streamer1 ntpd_intres[728]: DNS ->
Feb 14 08:42:25 streamer1 ntpd_intres[728]: DNS ->
Feb 14 08:42:25 streamer1 ntpd_intres[728]: DNS ->
Feb 14 08:42:25 streamer1 ntpd_intres[728]: DNS ->
Feb 14 08:42:26 streamer1 ntpd[720]: Listen normally on 6 wlan0 UDP 123
Feb 14 08:42:26 streamer1 ntpd[720]: Deleting interface #3 wlan0,, interface stats: received=0, sent=0, dropped=4, active_time=3 secs
Feb 14 08:42:26 streamer1 ntpd[720]: interface -> (none)
Feb 14 08:42:26 streamer1 ntpd[720]: interface -> (none)
Feb 14 08:42:26 streamer1 ntpd[720]: interface -> (none)
Feb 14 08:42:26 streamer1 ntpd[720]: interface -> (none)
Feb 14 08:42:26 streamer1 ntpd[720]: peers refreshed
Feb 15 04:20:10 streamer1 systemd[1]: Time has been changed

Given the timestamp resolution, NTP (or systemd) apparently resets the clock three seconds after the IP address changes. That may be as good as it gets, if only because the NTP daemon must find its servers, evaluate their status, then whack the local clock.

After forcing the static address, things look better, but it’s too soon to be sure. Many things can clobber streaming, not all of which happen on this side of our router.


1 Comment