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

  • XFCE Keyboard Mapping: Random Jots

    The multimedia keyboard on this box doesn’t work, which likely has something to do with the fact that I’m running separate X sessions on two monitors. I described what does work on my laptop there.

    Here are some random & incomplete notes, with no good outcome…

    Key and keyboard definitions are in /usr/share/X11/xkb/keycodes with:

    • xfree86 mapping the symbolic name (as in <I1E>) to key number 158
    • inet mapping from XF86AudioRaiseVolume to symbolic name

    The Microsoft Comfort Curve Keyboard 2000 V1.0 (don’t you love how they name things?) seems to be a subset of the microsoftprousb keyboard definition.

    Manually assigning a key works like this:

    xfconf-query -c xfce4-keyboard-shortcuts \
      -p /commands/custom/XF85AudioRaiseVolume \
      -t string
      -n
      --set="amixer -c 0 sset Master 10%+"

    Use xev to find key numbers, which turn out to be more or less common values (contrary to what I initially thought)…

    • Back = 234 I6A
    • Forward = 233 I69
    • Vol down = 174 I2E
    • Mute = 160 I20
    • Vol up = 176 I30
    • Play/Pause = 162 I22
    • Home = 178 I32 XFree86HomePage
    • Search = 299 I65 XFree86Search
    • Email = 236 I6C XFree86Mail
    • Calculator = 161 I21 XFree86Calculator

    The first two keys are defined in nav_common and the rest are in media_common, with the combination in, of course, media_nav_common.

    But none of this actually works.

  • Attention: Patent Litigation Attorneys

    Read that before contacting me; it’ll save us both some time.

    Thanks…

  • Sunglasses Repair: New Hinge Holes

    Milling to remaining hinge plate
    Milling to remaining hinge plate

    With the epoxy cured overnight, I fired up the Sherline CNC mill to poke screw holes in the brass hinge splice.

    The first step was to mill a flat-bottomed hole in the lower surface of the thin brass to expose the threaded hole in the remaining hinge plate. I crunched the end of the frame in a machinist’s clamp, then grabbed that in the Sherline milling machine vise; the frame is upside-down in the picture.

    The brass stock was 0.015 inches, so I milled downward 0.020 inches to get through the epoxy. I’d love to say that worked perfectly, but I had to fiddle around a bit and eventually put a slight divot in the hinge plate.

    That alignment was by pure eyeballometric guesstimation, but poking a small epoxy disk out of the threaded hole revealed that the 2 mm milled hole was centered on the hinge hole. Pretty close. Kinda-sorta. Good enough for my purposes, anyway.

    Laser alignment to hinge hole
    Laser alignment to hinge hole

    I aligned the spindle to the actual hinge hole with my laser aligner, a process that turned out to be surprisingly easy: note where the red dot vanishes on each side of the hole, split the difference, repeat for the Y axis, and you’re done.

    Through-drilling top hole
    Through-drilling top hole

    With the spindle centered, I ran a #60 drill through the threaded hole (which it just barely cleared) and poked a hole in the thicker top plate (which is on the bottom here, remember). The packing under the hinge is a cut-up credit card; a handy source of thin sheets of stiff plastic.

    Then I flipped the frame over and drilled out the top hole with a #54 drill to clear the threads on a 00-90 machine screw. I’d like to say I did a precision alignment job, but what I actually did was chuck that little bitty drill up in my big drill press, run it on the slowest spindle speed (maybe 400 rpm), brace my arms on the table, and feed the frame onto the drill by hand. Works perfectly… if only because I’m enlarging the hole by, what, 7 thou on each side.

    Finished hinge - top view
    Finished hinge – top view

    A bit of filing cleaned up the drill chaff inside the hinge so I could mount the earpiece on the frame and screw it in place. I don’t have a 00-90 tap and wouldn’t use it in a titanium frame anyway, so you can tell this isn’t going to have a happy outcome, but, by and large, the undoubtedly metric threads in the frame did a pretty good job of re-forming the 00-90 brass threads. Ugly, but serviceable.

    Some Dremel-tool work with an itsy grinding wheel on the flexy shaft eroded the back side of the U-shaped brass and new hinge plate to clear the earpiece; I think it only took half a dozen trial fittings & tiny grindings before the earpiece folded properly.

    A dab of low-strength purple Loctite in the threads and I’d say that screw is in there for life!

    Finished hinge - side view
    Finished hinge – side view
    Finished hinge - bottom view
    Finished hinge – bottom view

    Then I cleaned it up with a miniature wire wheel and, hey, it’s got a certain geeky charm, doesn’t it?

    I have my doubts about how well the epoxy affixes itself to the brass, so I suspect I’ll be drilling a hole or two to mechanically lock it in place with some urethane adhesive when it falls off.

    If the remaining hinge plate fractures, however, then the frame is toast.

    Until I get around to having the optical shop dye up another pair, these should suffice for my simple needs.

    Trivia:

    The plastic film on the lenses comes from a big roll of the stuff they use to protect CRT monitors in shipping. Works great for shop projects and, back in the day, I used it when I was hauling monitors around. I think it’d suck the front right off an LCD panel, so I haven’t used much of it lately.

    If you’re following the pictures, you’ll notice that the dsc* numbering series resets right in the middle of the story. That’s where my Sony camera gagged while writing an image and explains why I don’t have pix of the first drilling steps.

    The color balance is weird on the milling machine pix because the shop lights are much cooler than the warm compact fluorescent bulb hovering over the table.

  • Sunglasses Repair: Half a Hinge Is Better Than None

    Broken hinge and brass shim stock repair parts
    Broken hinge and brass shim stock repair parts

    Some years ago I managed to talk one of the local optical shops into stripping the anti-reflective coating off my second-oldest pair of glasses, dunking the lenses in the gray dye pot, then re-coating them. I got a fine set of variable-bifocal sunglasses for 75 bucks; that’s why it took some persuasion. The near vision lens is a bit under my current prescription, but it’s good enough for driving and biking.

    All good things must come to an end: the right-side hinge broke. The bad news is that it’s a titanium frame (can’t be brazed, at least by me) and the whole affair is old enough that it’s not worth sinking a bunch of money into a new frame. This year calls for new glasses anyway, so with any luck they’ll be able to do it again.

    The good news: I can fix this thing with JB Weld epoxy and a few brass bits. So off to the Basement Laboratory, Machine Shop Division, we go…

    Resistance soldering brass parts
    Resistance soldering brass parts

    Fortunately, the unthreaded top hinge plate broke off, leaving the threaded bottom plate intact. The plan: replace the plate with a suitable bit of brass shim stock, solder it to a U-shaped sheet of brass, epoxy the thing to the temple, drill a hole through the new plate, and run a screw into the threaded plate.

    The top picture shows the broken hinge and the tediously cut-and-filed brass parts. The tab on the end of the flat plate fits around the remaining part of the hinge, the upper part is flush against the frame, and most of the plate will be trimmed off.

    Rough-filed hinge splice
    Rough-filed hinge splice

    After demonstrating that my smallest torch can satisfactorily melt tiny bits of brass shim stock, I (tediously) re-cut and re-fit another set of parts, then deployed the resistance soldering gadget I built a while back (and wrote up for Circuit Cellar, Feb / Apr / Jun 2008) and silver-soldered the bits together. I must describe that thing here one of these days; it’s built around a rewired kilowatt-class microwave oven transformer with triac pulse-duty-cycle switching to control the heat.

    A bit of diagonal cutter and file work produced a U-shaped channel that exactly fit over the remaining hinge. The rounded end (in the rear) is too wide, but that’ll get trimmed to fit when it’s in place.

    Aligning earpiece and frame for epoxy
    Aligning earpiece and frame for epoxy

    Wisely is it written that you cannot have too many clamps, which is what I used to build a fixture and align the earpiece with the lens frame to epoxy the hinge splice in place. As is always the case, nothing is square, plumb, true, or parallel. Fortunately, the glasses weigh basically zilch, so after I get the pieces aligned, they won’t shift out of place.

    That done, I worked some JB Weld epoxy into the hinge stub’s crevices, then slipped the splice into place. A small blue clamp applied a bit of pressure to make the friction fit marginally more secure…

    Final clamping overview
    Final clamping overview

    The trick here is to leave the plastic lid with the rest of the mixed epoxy sit on the workbench; if the epoxy in the lid isn’t cured, then there’s no point in moving the glasses and breaking the bond.

    Clamping with epoxy applied
    Clamping with epoxy applied

    Then I let the epoxy cure overnight… when the story continues.

  • Anchoring Sherline Stepper Motor Wires

    Anchoring stepper motor wires with cable ties
    Anchoring stepper motor wires with cable ties

    The wires coming out of Sherline CNC milling machine stepper motors, as with most small stepper motors, emerge from an epoxy-filled opening. As a result, whenever the motor or wires move, all the stress concentrates right at that epoxy surface.

    Which is exactly where the wires will break…

    There’s no good way to add strain relief to that point (more adhesive isn’t helpful), but you can anchor the cable to the motor frame so that the individual wires do not move relative to the motor.

    Cable ties will suffice. Add one around the entire motor to hold the wires in place, then lash the spiral sheath to one of the unused mounting holes in the motor frame.

    Pull those ties until they squeak! You can grab the tabs with flush-cutting diagonal cutters to get some traction, then rotate the cutters against the ratchet housing to pull another notch past the ratchet. When it’s so tight you’re stretching the tie, then it’s tight enough; clip the end off with the cutters.

    To cross-check, wiggle the connector end of the cable. If the wires move at the epoxy, then you haven’t done a sufficiently good job. Repeat until satisfied.

    This works for the milling machine and, as shown in the picture, the rotary table. Just do it!

  • Recovering JPG Images From Damaged Flash Memory

    My DSC-F717 just crashed as I took a picture in the Basement Laboratory; it stalled while writing a picture to the memory stick. This camera is known to have problems with its ribbon cables and I’ve fixed it a few times before, but right now I have other things to do. Who knows? Maybe it’s a different problem altogether.

    Thus, the pertinent question is how to grab the image files from the Memory Stick, even with a damaged filesystem. This trick will work with any memory device, so it’s not just a Memory Stick thing.

    The camera crashed with the Memory Stick activity LED stuck on. Turning the camera off didn’t work: it jammed in the power-down sequence. So I poked the Reset button, which snapped the camera back to 1 January 2002, just after midnight. Alas, it now couldn’t read the Memory Stick, which meant either the filesystem is pooched or the camera’s card socket has gone bad again.

    Mmm, do you know where your camera’s Reset button is? It might not even have one, in which case you just yank the battery. If you can yank the battery, that is.

    Anyhow…

    With the camera turned off: extract the memory card, poke it into a suitable USB card reader, and poke that into your PC (running Linux, of course).

    If the filesystem isn’t too badly damaged, you’ll probably get a popup asking what to do with the new drive (the memory card). Dismiss that, as you don’t want anything writing to the memory without your explicit permission, which you won’t give.

    Figure out which device corresponds to the card and which partition to use:

    dmesg | tail
    [29846.600524] sd 5:0:0:2: [sdd] 1947648 512-byte hardware sectors (997 MB)
    [29846.606022] sd 5:0:0:2: [sdd] Write Protect is off
    [29846.606030] sd 5:0:0:2: [sdd] Mode Sense: 23 00 00 00
    [29846.606033] sd 5:0:0:2: [sdd] Assuming drive cache: write through
    [29846.608748]  sdd: sdd1
    

    In this case, the Memory Stick was intact enough to have a valid partition table, so it could be successfully mounted. However, you don’t want any attempt to write the data, just to keep a bad situation from getting worse. You do that by mounting the device read-only:

    sudo mount -o ro /dev/sdd1 /mnt/part

    You’ll need a suitable mount point; I created /mnt/part early on to hold manually mounted disk partitions.

    The FAT filesystem seemed to point to valid files, but attempting to display them didn’t work. So unmount the device before proceding:

    sudo umount /dev/sdd1

    Switch to /tmp or anywhere you have enough elbow room for a few files the size of the memory card.

    Run dd to make a bit-for-bit copy of the entire drive:

    sudo dd if=/dev/sdd of=memstick.bin bs=1M

    The bs=1M should dramatically speed up the transfer; the default is, IIRC, 512 bytes.

    After this, everything you do uses memstick.bin, not the memory card itself. If you’re paranoid like me, you’ll make a copy of the file before you do anything hazardous. You could even make two copies directly from the memory card and compare them, which might be instructive.

    To find your precious JPG images among the rubble, look for their magic Exif headers:

    strings -t x memstick.bin | grep Exif
      68006 Exif
     258006 Exif
     680006 Exif
     848006 Exif
     a18006 Exif
     bf0006 Exif
     e00006 Exif
     fe8006 Exif
    11e8006 Exif
    1420006 Exif
    ... snippage ...
    

    Because the strings search ignores the (presumably broken) FAT directory structure, you’ll find all the image files on the drive, whether or not they’ve been deleted, partially overwritten, or whatever. This is great for forensics and terrible if you’ve got something to hide. You have been warned.

    The -t x parameter returns the string’s starting offset in hex, which you need to find the actual starting offset of the file: it’s 6 bytes lower! Your mileage may vary, so be prepared to fiddle around a bit.

    You could write a bunch of code to parse the JPG header and extract exactly the number of bytes required, but this is no time for subtle gestures. I just yank out whatever the largest possible image file could be, because image-processing programs only process the valid stuff anyway. So, knowing that this camera produces images in the 2.4 MB range, this extracts the first image:

    dd if=memstick.bin of=image.jpg bs=$((16#1000)) count=1K skip=$((16#68))
    

    The $(( … )) notation evaluates the numeric expression within and the 16#… notation expresses a hexadecimal value.

    Soooo, bs=$((16#1000)) says that the blocksize is 4096 bytes, which you can deduce from the fact that all the Exif headers start 6 bytes from a multiple of 0x1000. Again, your camera may do things differently, but the general notion should get you started.

    If you’re fussy, you’ll note that the headers are actually on multiples of 0x8000 bytes, but using 0x1000 means you can read the high-order digits right off the strings dump. Why make things more complicated than necessary?

    Given a 4K blocksize, count=1K extracts a 4MB chunk: 1024 blocks of 4096 bytes each. That’s larger than the largest possible image file from this camera; adjust it to suit whatever you expect to find. Don’t be stingy, OK?

    The skip=$((16#68)) says to begin extracting data 0x68 blocks into memstick.bin. You read that value directly from the strings output, which is easy enough.

    You could write a tidy Bash script to eat the strings values and spit out the corresponding file chunks. I had few enough images this time to just do it manually, which beats having to debug some code…

    Good luck!

  • Devil’s Pie for Xubuntu

    I have six workspaces set up on my left monitor (and, perforce, six on the right, where I need only two) with more-or-less ritualized contents: email, browser, terminals, simulation, graphics, and whatever else comes to mind.

    While I’m not attached to the notion of a particular program being on a specific workspace, I really don’t want to arrange all the programs every time this thing lights up. Alas, Xubuntu’s XFCE desktop doesn’t offer much control over where windows appear, particularly for KDE programs that don’t seem to play nicely with the rest of the desktop.

    Devil’s Pie (installable with package devilspie) solves some of that problem. It doesn’t handle dual monitors with separate X sessions, is utterly undocumented, requires more than a little patience to get working, and produces baffling error messages. But it does essentially everything I need doing.

    So…

    Install devilspie, which is at 0.22 -1 in the Xubuntu 8.10 universe repository.

    Create ~/.devilspie to hold configuration files and create the following files therein:

    firefox.ds

    ; Force Firefox to workspace 2
    (if
    (is (application_name) "Firefox")
    (set_workspace 2)
    )

    gimp.ds

    ; Force Gimp windows to workspace 6
    (begin
    (if
      (matches (application_name) "GNU Image Manipulation Program" )
      (begin
        (set_workspace 6)
      )
    )
    )

    kmail.ds

    ; Force Kmail windows to workspace 1
    (begin
    (if
      (matches (application_name) "^KMail$" )
      (begin
        (set_workspace 1)
        (geometry "960x1200+0+0")
      )
    )
    )

    The syntax is fairly obvious, the semantics rather less so. The man page is basically useless and has been that way forever, but a true heroine has already dug through the source code and documented what you need to know. Go there and read.

    If you’re doing system-wide configs for all users, you can allegedly put those files in /etc/devilspie, but I haven’t tried it out yet.

    The (matches string regex) conditional allows you to do regular expression matching, which is more flexible than string equality (is string string) or substring (contains string substring) matching. What you see above represents cruft from figuring out what works.

    Use the (begin …) syntax to wrap multiple statements in a single file; the parser seems to choke on anything more than one.

    Put (debug) in whatever new config file you create, (re-)start devilspie from a terminal, then start the program you’re trying to control. You’ll get a torrent of information about all the various & sundry windows; pluck readable bits from them and hammer out some regex matches. Tuck one of these into a (begin …) stanza along with stuff you’re trying to make work.

    Attempting starting devilspie before X comes up causes great discomfort, so you can’t start it from /etc/rc.local.

    Instead, add it to XFCE’s Autostarted Applications list: System Settings -> Session and Startup -> Application Autostart, then click the Add button to put /usr/bin/devilspie in the list.

    Memo to Self: this will be ideal for Mom’s PC beyond 8.04, assuming KDE continues to favor foo-foos over basic functionality.