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.

Author: Ed

  • Raspberry Pi Streaming Radio Player: Minimum Viable Product

    With the numeric keypad producing events, and the USB audio box producing sound, the next steps involve starting mplayer through Python’s subprocess interface and feeding keystrokes into it.

    There’s not much to it:

    As much hardware doc as you need:

    RPi Streaming Player - first lashup
    RPi Streaming Player – first lashup

    The green plug leads off to a set of decent-quality PC speakers with far more bass drive than seems absolutely necessary in this context. The usual eBay vendor bungled an order for the adapter between the RCA line-out jacks and the 3.5 mm plug that will avoid driving the speakers from the UCA202’s headphone monitor output; I doubt that will make any audible difference. If you need an adapter with XLR female to 1/4 inch mono, let me know…

    The keypad labels provide all the UI documentation there is:

    Numeric Keypad - stream labels
    Numeric Keypad – stream labels

    The Python source code as a GitHub Gist:

    from evdev import InputDevice,ecodes,KeyEvent
    import subprocess32
    Media = {'KEY_KP7' : ['mplayer','http://relay.publicdomainproject.org:80/classical.aac'%5D,
    'KEY_KP8' : ['mplayer','http://relay.publicdomainproject.org:80/jazz_swing.aac'%5D,
    'KEY_KP9' : ['mplayer','http://live.str3am.com:2070/wmht1'%5D,
    'KEY_KP6' : ['mplayer','http://pubint.ic.llnwd.net/stream/pubint_wamc'%5D,
    'KEY_KP1' : ['mplayer','-playlist','http://dir.xiph.org/listen/5423257/listen.m3u'%5D,
    'KEY_KP2' : ['mplayer','-playlist','http://dir.xiph.org/listen/5197460/listen.m3u'%5D,
    'KEY_KP3' : ['mplayer','-playlist','http://dir.xiph.org/listen/5372471/listen.m3u'%5D,
    'KEY_KP0' : ['mplayer','-playlist','http://dir.xiph.org/listen/5420157/listen.m3u'%5D
    }
    Controls = {'KEY_KPSLASH' : '/',
    'KEY_KPASTERISK' : '*',
    'KEY_KPDOT' : ' '
    }
    k=InputDevice('/dev/input/keypad')
    print 'Starting mplayer'
    p = subprocess32.Popen(Media['KEY_KP7'],stdin=subprocess32.PIPE)
    print ' … running'
    for e in k.read_loop():
    if (e.type == ecodes.EV_KEY) and (KeyEvent(e).keystate == 1):
    kc = KeyEvent(e).keycode
    if kc == 'KEY_NUMLOCK':
    continue
    print "Got: ",kc
    if kc == 'KEY_BACKSPACE':
    print 'Backspace = shutdown!'
    p = subprocess32.call(['sudo','halt'])
    break
    if kc in Controls:
    print 'Control:', kc
    p.stdin.write(Controls[kc])
    if kc in Media:
    print 'Switching stream to ',Media[kc]
    print ' … halting'
    p.communicate(input='q')
    print ' … restarting'
    p = subprocess32.Popen(Media[kc],stdin=subprocess32.PIPE)
    print ' … running'
    print "Out of loop!"

    The Media dictionary relates keycodes with the command line parameters required to fire mplayer at the streaming stations. With that running, the Controls dictionary turns keycodes into mplayer keyboard controls.

    There’s no display: you have no idea what’s going on. I must start the program manually through an ssh session and can watch mplayer‘s console output.

    Poking the Halt button forcibly halts the RPi, after which you squeeze the Reset button to reboot the thing. There’s no indication that it’s running, other than sound coming out of the speakers, and no way to tell it fell of the rails other than through the ssh session.

    The loop blocks on events, so it can’t also extract stream titles from the (not yet implemented) mplayer stdout pipe / file and paste them on the (missing) display; that’s gotta go.

    There’s a lot not to like about all that, of course, but it’s in the tradition of getting something working to discover how it fails and, in this case, how it sounds, which is even more important.

  • Raspberry Pi: USB Keypad Via evdev

    The general idea is to use keystrokes plucked from a cheap numeric keypad to control mplayer, with the intent of replacing some defunct CD players and radios and suchlike. The keypads look about like you’d expect:

    Numeric keypads
    Numeric keypads

    The keypad layouts are, of course, slightly different (19 vs 18 keys!) and they behave differently with regard to their NumLock state, but at least they produce the same scancodes for the corresponding keys. The black (wired) keypad has a 000 button that sends three 0 events in quick succession, which isn’t particularly useful in this application.

    With the appropriate udev rule in full effect, this Python program chews its way through incoming events and reports only the key-down events that will eventually be useful:

    from evdev import InputDevice,ecodes,KeyEvent
    k=InputDevice('/dev/input/keypad')
    for e in k.read_loop():
    if (e.type == ecodes.EV_KEY) and (KeyEvent(e).keystate == 1):
    if (KeyEvent(e).keycode == 'KEY_NUMLOCK'):
    continue # we don't care about the NumLock state
    else:
    print KeyEvent(e).scancode, KeyEvent(e).keycode

    Pressing the keys on the white keypad in an obvious sequence produces the expected result:

    82 KEY_KP0
    79 KEY_KP1
    80 KEY_KP2
    81 KEY_KP3
    75 KEY_KP4
    76 KEY_KP5
    77 KEY_KP6
    71 KEY_KP7
    72 KEY_KP8
    73 KEY_KP9
    98 KEY_KPSLASH
    55 KEY_KPASTERISK
    14 KEY_BACKSPACE
    74 KEY_KPMINUS
    78 KEY_KPPLUS
    96 KEY_KPENTER
    83 KEY_KPDOT
    

    Observations

    • KeyEvent(e).keycode is a string: 'KEY_KP0'
    • e.type is numeric, so just compare against evcodes.EV_KEY
    • KeyEvent(e).scancode is the numeric key identifier
    • KeyEvent(e).keystate = 1 for the initial press
    • Those KeyEvent(e).key_down/up/hold values don’t change

    If you can type KEY_KP0 correctly, wrapping it in quotes isn’t such a big stretch, so I don’t see much point to running scancodes through ecodes.KEY[KeyEvent(e).scancode] just to compare the enumerations.

    I’m surely missing something Pythonic, but I don’t get the point of attaching key_down/up/hold constants to the key event class. I suppose that accounts for changed numeric values inside inherited classes, but … sheesh.

    Anyhow, that loop looks like a good starting point.

  • Makerspace Starter Kit Available

    For a variety of reasons that aren’t relevant here, I must dramatically reduce the amount of stuff in the Basement Laboratory / Machine Shop / Warehouse.

    If you (or someone you know) has / is starting / will start a makerspace or similar organization, here’s an opportunity to go from zero to hero with a huge infusion of tools / instruments / make-froms / raw material / gadgets / surplus gear.

    Think of it as a Makerspace Starter Kit: everything you need in one acquisition.

    You’ve seen much of the stuff in these blog posts during the past five years, although I tightly crop the photos for reasons that should be obvious when you consider the backgrounds.

    A few glimpses, carefully chosen to make the situation look much tidier than it really is:

    This slideshow requires JavaScript.

    I’m not a hoarder, but I can look right over the fence into that territory…

    I want to donate the whole collection to an organization that can figure out how to value it and let me write it off. Failing that, I’m willing to sell the whole collection to someone who will move it out and enjoy it / put it to good use / part it out / hoard it.

    We can quibble over the value, which surely lies between scrap metal and filet mignon.

    As nearly as I can estimate from our last two moves, I have 6±2 short tons of stuff:

    • Metal shop: old South Bend lathe / vertical mill-drill / bandsaw / hand tools / arbor press
    • Cabinets / shelves loaded with cutters / tools / micrometers / calipers / whatever
    • Gas & electric welding equipment, gas foundry furnace
    • Walls / bins / drawers of fasteners / wire nuts / plumbing fittings / pipe clamps / you-name-its
    • Bookshelves of references / magazines / databooks; I’ll keep at most one set of the magazines with my columns
    • Ham radio equipment / antennas / cables
    • Radial saw, blades, clamps, tooling, and a lumber / plywood stockpile
    • Labeled boxes of make-froms on steel shelving; you get the shelves, the boxes, and their contents.
    • Solvents, chemicals, metals, minerals, elements, etc.
    • Electronic / optical / mechanical surplus & doodads
    • Stockpiles of metal rods / pipes / beams / flanges / sheets / scrap parts
    • Tools & toys & treasures beyond your wildest imagination

    When we left Raleigh, the moving company estimator observed “This will be like moving a Home Depot!”

    You must take everything, which means you must have the ability & equipment to handle 6±2 tons of stuff in relatively small, rather heavy, not easily stackable lumps. You’ll need 1000+ square feet of space with at least a seven-foot ceiling on your end to unload the truck(s) and create a solid block of stuff with skinny aisles between the shelves. This is not a quick afternoon trip for you, your BFF, a pickup truck, and a storage unit.

    I plan to keep the Sherline, the M2 3D printer, various small tools, some hardware / parts / stock, most of the electronic instruments (antique-ish, at best) and components, plus odds and ends. I’ll extract or clearly mark those items, leaving your team to move everything else without (too many) on-the-fly decisions.

    I can provide photos and descriptions, but, realistically, you should evaluate the situation in person.

    Although we’re not planning to move in the near future, if you’re thinking of moving into the Mid Hudson Valley and always wanted a house with a ready-to-run Basement Shop, we can probably work something out. Note: all of the online real estate descriptions, including Zillow, seem confused, as the two houses on our two-acre property contain the total square footage / rooms / baths / whatever. Contact us for the Ground Truth after you’ve contemplated the satellite view.

    As the saying goes, “Serious inquiries only.”

  • Adaptek AVA-2902E/I SCSI Card: Low Profile Bracket Hack

    I picked up an Adaptek AVA-2902 SCSI card from eBay to use with an ancient Epson Perfection 636 SCSI scanner from the heap, but it came with a high-profile bracket wrapped around its DB-25 connector:

    SCSI card bracket fix - before
    SCSI card bracket fix – before

    The old-school serial port card sitting atop it (from one of the off-lease Optiplexes in the stable) has a low-profile bracket that seemed promising, so I swapped the brackets.

    Alas, the SCSI card positioned the DB-25 just a smidge higher than the serial card, putting the right-angle top of the bracket about 2 mm above the ledge, where it prevented the locking cover from engaging. I filed the bracket’s DB-25 mounting holes into ovals, using up all the slop around the connector shell, to no avail.

    So I snipped off most of the bracket’s top, grabbed it in the bench vise, smashed the corner with a drift punch, and bashed the whole affair 2 mm lower. It fit reasonably well, although there’s an air gap near the bottom of the bracket where it tapers down to the guide slot. The SCSI connector barely fit, with some persuasion, under the locking cover:

    SCSI card bracket fix - installed
    SCSI card bracket fix – installed

    Close enough for me; the scanner (looming over the SCSI connector) works fine and delivers much better image quality / color balance than the crappy HP 7400C with an auto-feeder that I’d been using.

    SCSI cables look like gas pipes in this day & age of tiny USB cables and teensy HDMI connectors

  • Maxell LR44 Cells: Packaging Glitch

    These look to be Maxell LR44 cells in OEM retail packaging, exactly as advertised, but … one cell seems odd:

    Maxell LR44 cells - hologram packages
    Maxell LR44 cells – hologram packages

    A closer look:

    Maxell LR44 cells - flipped cell
    Maxell LR44 cells – flipped cell

    The production values seem high enough to suggest that they’re Genuine Maxell products, hologram packaging and all, but you’d expect the Maxell end-of-line QC should pick out a flipped cell.

    If one were the wondering sort, though, one might wonder why the Maxell USA website search function doesn’t return any mention of LR44 cells…

  • Kenmore Model 158: Older Foot Pedal Resistor

    Based on the paperwork tucked into the sewing table, the most recent Kenmore Model 158 sewing machine in our stable dates to 1972, a bit earlier than the others, and has a metal-cased foot pedal with a wire-wound resistor:

    Kenmore Model 158 - new-ish foot pedal resistor
    Kenmore Model 158 – new-ish foot pedal resistor

    The cord insulation stiffened up over the decades and I wanted to replace it, but the contacts in the sewing machine connector were spot-welded to the conductors with no room for teeny screws:

    Kenmore Model 158 - new-ish foot pedal connector
    Kenmore Model 158 – new-ish foot pedal connector

    I blew out the fuzz, put it back together, and it works pretty well, modulo the usual low torque at slow speeds issue.

    The discrete resistor taps produce a somewhat stepped response, but early reports suggest it’s not enough to be annoying; it’s much more stable than the carbon disks in the more recent pedals.

  • LED Shoplight Conversion: Fluorescent Fixture Teardown

    The weakest fluorescent shop light fixtures always fail during cold weather (apart from the usual early tube failures) and this winter’s cold spells triggered the usual carnage, so I picked up half a dozen (cheap) 22 W LED T8 tubes and set about rewiring three defunct (cheap) fluorescent fixtures from the recycle heap. The new LED tubes run directly from the AC line; you must remove the fluorescent fixture’s ballasts / capacitors / starters and rewire the “tombstone” lampholders accordingly.

    The first challenge, as always, involved taking the fixtures apart. Turns out prying the endcap away from the fixture enough to clear the pair of bumps punched into the metal does the trick:

    Fluorescent Shoplights - endcap latches
    Fluorescent Shoplights – endcap latches

    Each endcap contains the ballast inductor / choke and power-factor correction capacitor for one tube. The inductors from one shoplight had a fancy plastic tab that might have held the capacitor in place, but that’s about the only difference:

    Fluorescent Shoplights - ballasts
    Fluorescent Shoplights – ballasts

    The 150 kΩ resistor has its leads twisted around the capacitor leads without benefit of that fancy solder stuff one might think necessary for a good connection.

    The capacitor contacts use the minimum possible amount of material:

    Fluorescent Shoplights - capacitor termination
    Fluorescent Shoplights – capacitor termination

    I think the caps use metallized Mylar film, but who knows?

    The inductors measure 280 mH and the caps a whopping 5 µF. I might trust the inductors in a low-voltage circuit, but the caps have no redeeming features and went directly to the trash.

    The starter PCB lived in the center of the fixture:

    Fluorescent Shoplights - starter circuit
    Fluorescent Shoplights – starter circuit

    I deliberately picked LED tubes with the AC line contact on one end and the neutral contact on the other, so as to not put line and neutral contacts in the same tombstone. After rewiring, the neutral endcap looks like this:

    Fluorescent Shoplights - neutral endcap
    Fluorescent Shoplights – neutral endcap

    The other endcap holds the power cord and has a green earth ground wire snaking out to a little tab passed into a slot punched in the metal case. I replaced the tab with an actual screw / solderless connector / toothed washer, but have no pix to show for it.

    The LED tubes run at 6500 K and contrast harshly with the warm-white tubes in the fluorescent shoplights. I went with the highest light output, because even the best (cheap) LED tubes produce barely half the output of the fluorescents: 2000-ish lumens vs 3900-ish.