Archive for February, 2017
After the faceplant caused by the crappy compound way finishing, I decided to try repairing the tailstock ways as a means of gaining experience before tackling the real problem. The general idea is to see whether filling the gouges with epoxy will suffice.
I’m using good ol’ JB Weld steel-filled epoxy, rather than graphite / molybdenum disulfide loaded epoxy, mostly because:
- I have it on the shelf
- This is a non-sliding joint
- My technique needs polishing, too
The key point: the tailstock is (astonishingly) well aligned and, if I can manage to not change how it sits on the lathe bed, this should be a zero-impact operation. Scraping / filing / fiddling with the high spots will change the alignment; I expect I must eventually do such things; this represents a first pass at the problem.
Applying a fat blue Sharpie to the tailstock ways:
After sliding the tailstock back and forth a few times, the remaining blue shows where the ways did not make contact. Those shiny and silvery spots rubbed against the lathe bed ways.
The flat way looked like this:
The patch along the upper-left edge and the small dot near the upper-right corner are the only contact points across the entire flat.
The outside of the V groove:
As nearly as I can tell, that’s actually a reasonably flat and well-aligned surface, with small contact points scattered all over. Granted, there’s a larger contact patch to the left and less to the right.
The inside of the V groove:
There’s a single point near the top left, another over on the right, and that’s about it.
I cleaned the tailstock ways with acetone to get rid of the Sharpie / grease / oil / whatever. Under normal circumstances you’d roughen the surface to give the epoxy something to grip, which definitely seemed akin to perfuming a lily.
To prevent permanently affixing the tailstock to the lathe, some folks put a generous layer of oil / graphite / soot / release agent on the lathe bed ways. I used some 3 mil = 0.08 mm Kapton tape, figuring an impervious layer would pretty much guarantee I could get the tailstock off again, no matter what.
So, we begin.
Butter up the tailstock ways with epoxy and smoosh into place atop the Kapton:
Make sure the tailstock remains well-seated where it should be:
Do other things for 24 hours while the epoxy cures, pry the tailstock loose by hammering The Giant Prying Screwdriver between the lathe bed and the underside of the tailstock (just right of the V-groove, where nothing slides on the bed, but I did use a bit of plastic as a shield), chip off excess epoxy, clean things up, etc, etc.
This time, I applied Sharpie to the lathe bed, then slid the tailstock back & forth a few times. As a result, the blue areas now show the contact patches and the gray areas just slid by without touching.
The flat way looks pretty good:
That round dot over on the right seems to be a steel protrusion; I think it’s part of the same lump appearing in the “before” picture above. That rather sharp point seems to have indented the tape and produced a low area in the epoxy around it, which may not matter much: it was the only contact point before I did this.
The V groove isn’t anywhere near perfect:
On the upside, the ways have much, much larger contact patches spread across nearly their entire lengths, which isn’t to be sniffed at.
While reassembling the tailstock, I added a pair of M6 washers above the clamp plate so it cleared the bed with the screw tightened into the cam-lock post:
Which definitely calls for a small bushing, of course. If you put a lockwasher under the screw head, it won’t clear the end of the bed casting. So it goes.
Another washer under the ram lock screw changed the phase enough to keep the knob out of the way in both the fully locked and unlocked positions:
I slobbered some Mobil Vactra #2 Sticky Way Oil (thanks, Eks!) on the bed ways, snuggled the tailstock in place, and wow does that thing move! Verily, it slides smoothly and clamps solidly in place: a tremendous improvement over the status quo ante.
- The tape (perhaps the adhesive layer) produces a slightly textured epoxy surface
- The tailstock way’s small contact points indented the tape, even though it’s only 3 mil thick
- Filling the low areas in the way works well
- The high areas may not have enough epoxy for good durability
- I expect the epoxy will wear faster than steel, so contact should improve with time
- This is not a permanent fix
What I’ll do differently next time…
- Apply more epoxy to avoid those small gaps along the edges
- Use a real release agent: smoothed in place, it might provide a better finish. Might not matter
- Verify a good prying spot before epoxying, say, the compound
All in all, though, this worked much better than I expected!
A 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
However, plugging a network cable into the Pi 3 then produces two network connections: the wired one I wanted and 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
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…
This big branch must have landed with a mighty thump across the Maloney Road entrance to the Dutchess Rail Trail:
Yeah, some jerk ran a snowmobile up the slope around the tree, leaving a pile of dirt on the ramp. So it goes.
We took an alternate route, I emailed The Right Folks, and (most of) the tree vanished two days later; evidently, the property owner gets to deal with everything to the left of the line of trees.
At 200 mA/div, the top trace shows a bit under 1.2 A, a bit under the 1.68 A = 28 × 60 mA you’d expect; in round numbers, each RGB pixel draws 43 mA. Actually, the WS2812 specs don’t specify the maximum / typical LED current and, on belief and evidence, I doubt these units meet any particular specs you’d care to cite.
Also, the supply voltage (measured across the LED array “bus bar” wires) hits 3.37 V, well under the 5 V you’d expect from a USB charger and less than the 3.5 V called for by the WS2812 specs. Although the WS2812 nominally limits the LED current, there’s no telling how it varies with supply voltage.
A cheap USB 1 A wall-wart charger produced far more hash:
That’s with an additional 20 µF of tantalum capacitance across the power bus bars. The peak current looks like 1.4 A, with marginally more supply voltage at 3.56 V.
Bumping the trace speed shows the wall wart produces nasty current spikes, at what must be the poor thing’s switching speed, as it desperately tries to produce enough juice for the LEDs:
The step over on the right looks like a single RGB LED going dark, as it’s about 50 mA tall.
The output voltage doesn’t show the same spikes, so the LED array acts like a constant-voltage load. Given that the WS2812 probably connects all the LEDs pretty much straight across the supply, that’s not far from the truth: we’re looking at the forward drop of those blue LEDs.
Now, to let it cook away in the cool and the dark of the Basement Laboratory…
Mounting the ungainly WS2812 LED test fixture seemed like a Good Idea to keep the electricity out of the usual conductive litter:
The solid model shows more details:
The power wires along the array edges slide into the rear (thinner) slot, with enough friction from a few gentle bends to hold the whole mess in place.
The knockoff Arduino Nano rests on the recessed ledge in the pit, with M2 screws and washers at the corners holding it down (the PCB’s built-in holes might work with 1 mm or 0-90 screws, but that’s just crazy talk). I soldered the power wires directly to the coaxial jack pins under the PCB; they snake out to the LEDs through the little trench. There should be another cutout around the USB connector for in-situ programming, although the existing code works fine.
The front (wider) slot holds a piece of translucent white acrylic to diffuse the light:
It’s painfully bright: a few layers of neutral density filter would be appropriate for a desk toy.
The array runs hot enough at MaxPWM = 255 to produce a gentle upward breeze.
It looks even better without the flash:
You’ll find many easier ways to get RGB LED panels, but that’s not the point here; I’m waiting for these things to die an unnatural death.
The OpenSCAD source code as a GitHub Gist:
Given that I no longer trust any of the knockoff Neopixels, I wired the remaining PCB panel into a single hellish test fixture:
The 22 AWG wires deliver +5 V and Common, with good old-school Wire-Wrap wire passing to the four LEDs betweem them. The data daisy chain snakes through the entire array.
It seems only fitting to use a knockoff Arduino Nano as the controller:
The code descends from an early version of the vacuum tube lights, gutted of all the randomizing and fancy features. It updates the LEDs every 20 ms and, with only 100 points per cycle, the colors tick along fast enough reassure you (well, me) that the thing is doing something: the pattern takes about 20 seconds from one end of the string to the other.
At full throttle the whole array draws 1.68 A = 60 mA × 28 with all LEDs at full white, which happens only during the initial lamp test and browns out the supply (literally: the blue LEDs fade out first and produce an amber glow). The cheap 5 V 500 mA power supply definitely can’t power the entire array at full brightness.
The power supply current waveform looks fairly choppy, with peaks at the 400 Hz PWM frequency:
With the Tek current probe set at 200 mA/div, the upper trace shows 290 mA RMS. That’s at MaxPWM = 127, which reduces the average current but doesn’t affect the peaks. At full brightness the average current should be around 600 mA, a tad more than the supply can provide, but maybe it’ll survive; the bottom trace shows a nice average, but the minimum hits 4.6 V during peak current.
Assuming that perversity will be conserved as usual, none of the LEDs will fail for as long as I’m willing to let them cook.
The Arduino source code as a GitHub Gist:
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
192.168.1.101; 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" fi
/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 169.254.14.12 [ 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 169.254.1.0 to 169.254.254.255 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 192.168.0.0/16 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
interface wlan0 static ip_address=192.168.1.101/8 static routers=192.168.1.1 static domain_name_servers=192.168.1.1
En passant, I killed off IPV6 with this line in
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 -> http://188.8.131.52:7331/maschinengeist.org.mp3 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:
highlight="1,5,6,7,8,15,21"] Feb 14 08:42:24 streamer1 dhcpcd: wlan0: leased 192.168.1.101 for 86400 seconds Feb 14 08:42:24 streamer1 dhcpcd: wlan0: adding route to 192.168.1.0/24 Feb 14 08:42:24 streamer1 dhcpcd: wlan0: adding default route via 192.168.1.1 Feb 14 08:42:24 streamer1 avahi-daemon: Registering new address record for 192.168.1.101 on wlan0.IPv4. Feb 14 08:42:24 streamer1 dhcpcd: wlan0: deleting route to 169.254.0.0/16 Feb 14 08:42:24 streamer1 avahi-daemon: Withdrawing address record for 169.254.14.12 on wlan0. Feb 14 08:42:24 streamer1 avahi-daemon: Leaving mDNS multicast group on interface wlan0.IPv4 with address 169.254.14.12. Feb 14 08:42:24 streamer1 avahi-daemon: Joining mDNS multicast group on interface wlan0.IPv4 with address 192.168.1.101. Feb 14 08:42:25 streamer1 dhcpcd: wlan0: no IPv6 Routers available Feb 14 08:42:25 streamer1 ntpd_intres: DNS 0.debian.pool.ntp.org -> 184.108.40.206 Feb 14 08:42:25 streamer1 ntpd_intres: DNS 1.debian.pool.ntp.org -> 220.127.116.11 Feb 14 08:42:25 streamer1 ntpd_intres: DNS 2.debian.pool.ntp.org -> 18.104.22.168 Feb 14 08:42:25 streamer1 ntpd_intres: DNS 3.debian.pool.ntp.org -> 22.214.171.124 Feb 14 08:42:26 streamer1 ntpd: Listen normally on 6 wlan0 192.168.1.101 UDP 123 Feb 14 08:42:26 streamer1 ntpd: Deleting interface #3 wlan0, 169.254.14.12#123, interface stats: received=0, sent=0, dropped=4, active_time=3 secs Feb 14 08:42:26 streamer1 ntpd: 126.96.36.199 interface 169.254.14.12 -> (none) Feb 14 08:42:26 streamer1 ntpd: 188.8.131.52 interface 169.254.14.12 -> (none) Feb 14 08:42:26 streamer1 ntpd: 184.108.40.206 interface 169.254.14.12 -> (none) Feb 14 08:42:26 streamer1 ntpd: 220.127.116.11 interface 169.254.14.12 -> (none) Feb 14 08:42:26 streamer1 ntpd: peers refreshed Feb 15 04:20:10 streamer1 systemd: Time has been changed [/sourcecode]
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.