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.

Tag: Repairs

If it used to work, it can work again

  • Sewing Notions Drawer Pull Rethreading

    Sewing Notions Drawer Pull Rethreading

    A small sewing notions cabinet, once my mother’s, now holds some of Mary’s supplies and, a few days ago, had one of its drawer pulls fall off. While preemptively tightening all the screws, I found one no longer held onto its pull:

    Notions drawer pull - parts
    Notions drawer pull – parts

    They don’t make drawer pulls like that any more!

    As I see things, it can be forgiven for losing its grip after nearly a century.

    Thread the screw in as far as it will go and lay the pull flat on the bench vise anvil:

    Notions drawer pull - hammering setup
    Notions drawer pull – hammering setup

    A few gentle whacks with a pin punch on top and bottom, plus a tap on each side, compressed the pull’s remaining threads around & into the screw:

    Notions drawer pull - reshaped
    Notions drawer pull – reshaped

    Put it back in its drawer, snug the screw, and it’s all good.

    That should suffice for at least the remainder of its first century …

  • Dutchess Rail Trail: Brush Trimming & Pruner Repair

    Dutchess Rail Trail: Brush Trimming & Pruner Repair

    The bushes & trees along the Dutchess Rail Trail were reaching out to touch us again, so I took some slow rides with many stops.

    Maple Oak trees along Page Park Drive:

    DCRT Brush Trimming - oak - 2025-07
    DCRT Brush Trimming – oak – 2025-07

    Blackthorn encroaching through the fence at Overocker:

    DCRT Brush Trimming - blackthorn - 2025-07
    DCRT Brush Trimming – blackthorn – 2025-07

    A tree somebody tossed down the trail bank near Morgan Lake:

    DCRT Brush Trimming - discarded tree - 2025-07
    DCRT Brush Trimming – discarded tree – 2025-07

    The slide lock on my trusty rehabilitated Fiskars bypass pruner worked loose and began sliding into the LOCK position when held overhead, then fell apart during disassembly:

    Fiskars pruner - lock rebuild
    Fiskars pruner – lock rebuild

    The lock now consists of:

    • An M4 × 12 mm nut from a Chicago Screw that exactly matched the 5 mm OD cylinder passing through the pruner body
    • A laser-cut fluorescent acrylic disk for thumb grippiness
    • A washer just because
    • An M4 hex-head screw
    • A dab of Loctite bonding screw to nut

    Clean the blades with alcohol and it’s ready for the rest of the season.

    I should have put a wave washer in the stack for some springiness, but it works surprisingly well for what it is.

    Now: discover how long acrylic lasts out there in the wild.

    Update: Yeah, the lock needed a wave washer for more friction, which became apparent after the first overhead branch.

  • Newmowa NP-BX1: 2025 Batteries

    Newmowa NP-BX1: 2025 Batteries

    A new sextet of NP-BX1 batteries for the Sony AS-30V helmet camera arrived:

    Newmowa NP-BX1 - 2022 vs 2025
    Newmowa NP-BX1 – 2022 vs 2025

    The traces:

    • Blue = 2025 batteries
    • Red = 2022 batteries when new

    I don’t know what the bump in the middle of the new battery discharge curve means. Something weird in the chemistry, I suppose. Getting good batteries from Amazon surely remains a crapshoot and I now have four chargers.

    Recharging all six batteries required 5488 mA·hr, just over 900 mA·hr apiece. Running the camera on a one-hour bike ride burns 600-ish mA·hr, so that’s comforting.

    Comparing the new results with the 2022 batteries tested last month:

    NP-BX1 - Newmowa 2022 in 2025-06
    NP-BX1 – Newmowa 2022 in 2025-06

    The upper traces appear in red in the first plot, the lower curves come from three years of use.

    I’ll deploy the two best 2022 batteries (D and F) in the SJCAM M20 keeping watch from the Forester’s dashboard.

  • Plastic Spring Clamp Jaw Rod Replacement

    Plastic Spring Clamp Jaw Rod Replacement

    A recent quilt photo shoot degenerated into me chasing several bright orange clamp jaws across the deck as they popped off their clamps hanging from the photo backdrop scaffold. Most clamps have jaws snapping onto actual rods, but these clamps have molded-in-place “rods” much smaller than the 2 mm expected by the jaws and much more irregular than seems reasonable.

    Trace and scan the nose of a clamp:

    Large spring clamp nose outline
    Large spring clamp nose outline

    Curiously, the molded rod is not centered in the nose:

    Large spring clamp nose - pin locatIon
    Large spring clamp nose – pin locatIon

    Use LightBurn to coerce a scan of the first sketch into a suitable path, laser-cut some MDF, and glue up a drill fixture:

    Spring clamp jaw pins - fixture gluing
    Spring clamp jaw pins – fixture gluing

    Align the drill to the center of the off-center hole marked on the bottom layer:

    Spring clamp jaw pins - drill alignment
    Spring clamp jaw pins – drill alignment

    The drilling setup looks casual, but hand-holding the clamps against the rear wall and into the form-fitting nose recess sufficed:

    Spring clamp jaw pins - fixture overview
    Spring clamp jaw pins – fixture overview

    I snipped the plastic “rods” out before drilling the holes, then rammed 2 mm steel rods in place:

    Spring clamp jaw pins - steel
    Spring clamp jaw pins – steel

    They’re really 5/64 inch = 1.98 mm rods from the oil-hardening drill rod stash, but entirely sufficient for the purpose.

    With one clamp in hand, though, there was obviously no reason for the rods to be off-center. So I centered the drill in the nose, punctured the rest of the clamps, and pressed 2 mm carbon fiber rods in place:

    Spring clamp jaw pins - steel vs carbon fiber
    Spring clamp jaw pins – steel vs carbon fiber

    The rods were cut to 20 mm by rolling them across a pad with firm pressure from a utility knife. That was mostly to get some experience cutting carbon fiber, which is obviously overqualified for the job.

    Snap the orange jaws in place and I shall never suffer the embarrassment of chasing them again …

  • CNC-3018XL: Table Drive Nut Overstress

    CNC-3018XL: Table Drive Nut Overstress

    A confluence of unrelated events led me to unboxing and setting up the CNC-3018XL most recently used to plot Homage Tek Circuit Computer decks, but the table slid along its rods entirely too easily. A peek at the leadscrew revealed an assortment of parts last seen when I extended the frame:

    3018CNC - table drive - as found
    3018CNC – table drive – as found

    The featureless cylinder is the leadscrew follower nut, which evidently popped out of its proper place in the table drive block:

    3018CNC - table drive parts
    3018CNC – table drive parts

    The crude chamfer suggests that end went into the block first, so that’s what I did:

    3018CNC - table drive - follower nut installed
    3018CNC – table drive – follower nut installed

    It seems snug enough in there, at least for a machine used solely for plotting and maybe drag knife cuttery, so I’ll assume the box received some rough handling during our move.

    It’s now back in place and seems to work well enough:

    3018CNC - table drive - installed
    3018CNC – table drive – installed

    I briefly considered adding some setscrews to hold it in place, but came to my senses. If it pops out again, maybe it’ll be time to rebuild that block with proper retention.

    The software side of the thing surely needs TLC, too.

  • GIMP 3.0 vs. XSane vs. gimp-xsanecli

    GIMP 3.0 vs. XSane vs. gimp-xsanecli

    For reasons I do not profess to understand, GIMP 3.0 does not work with plugins written for GIMP 2.0, including the XSane plugin that handles scanning. This seems like an obvious oversight, but after three months it also seems to be one of those things that’s like that and that’s the way it is.

    Protracted searching turned up gimp-xsanecli, a GIMP 3.0 plugin invoking XSane through its command-line interface to scan an image into a temporary file, then stuff the file into GIMP. Unfortunately, it didn’t work over the network with the Epson ET-3830 printer / scanner in the basement.

    It turns out gimp-xsanecli tells XSane to output the filename it’s using, then expects to find the identifying XSANE_IMAGE_FILENAME string followed by the filename on the first line of whatever it gets back:

    if result != 'XSANE_IMAGE_FILENAME: ' + png_out:
      Gimp.message('Unexpected XSane result: ' + result)
      return Gimp.ValueArray.new_from_values([GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.EXECUTION_ERROR)])
    
    

    The font ligature that may or may not mash != into is not under my control.

    Protracted poking showed the scanner fires a glob of HTML through proc/stdout into gimp-xsanecli before XSane produces its output, but after the scan completes:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN "
    "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    … snippage …
    </head>
    <body><noscript>Enable your browser's JavaScript setting.</noscript></body></HTML>XSANE_IMAGE_FILENAME: /tmp/out.png
    

    Complicating the process:

    • The HTML glob only appears on the first scan, after which XSane produces exactly what gimp-xsanecli expects
    • There is no newline separating the glob from the expected output on the last line

    So …

    Insert a while loop into the main loop to strip off the HTML glob line by line by line:

            while True:
                    # Wait until XSane prints the name of the scanned file, indicating scanning is finished
                    # This blocks Python but that is ok because GIMP UI is not affected
    
                    # discard HTML header added by scanner to first scan
                    while True :
    
                            result = proc.stdout.readline().strip()
    
                            if r'</body>' in result :
                                    result = result.partition(r'</HTML>')[-1]
                            #        Gimp.message('Found end of HTML: ' + result)
                                    break
    
                            elif 'XSANE_IMAGE_FILENAME:' in result :
                            #        Gimp.message('Found filename: ' + result)
                                    break
    
                            else :
                            #        Gimp.message('Discarding: ' + result)
                                    continue
    
                    if result == '':
                            # XSane was closed
                            break
    
                    if result != 'XSANE_IMAGE_FILENAME: ' + png_out:
                            Gimp.message('Unexpected XSane result: ' + result)
                            return Gimp.ValueArray.new_from_values([GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.EXECUTION_ERROR)])
    
                    # Open image
                    image = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, Gio.File.new_for_path(png_out))
                    Gimp.Display.new(image)
    
                    # Remove temporary files
                    os.unlink(png_out)
    
                    if not SCAN_MULTIPLE:
                            proc.terminate()
                            break
    
            os.rmdir(tempdir)
    
            return Gimp.ValueArray.new_from_values([GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS), GObject.Value(Gimp.Image.__gtype__, image)])
    
    

    While it’s tempting to absorb the whole thing in one gulp with proc.stdout.read().strip(), that doesn’t work because nothing arrives until the XSane subprocess terminates, which is not what you want.

    A scan to show It Just Works™ :

    I expect it doesn’t work under a variety of common conditions, but … so far so good.

  • Newmowa NP-BX1: Three Years Later

    Newmowa NP-BX1: Three Years Later

    A pair of the 2022 batch of Newmowa NP-BX1 lithium batteries for the Sony AS-30V helmet camera no longer survive a typical hour-long bike ride:

    NP-BX1 - Newmowa 2022 in 2025-06
    NP-BX1 – Newmowa 2022 in 2025-06

    The best four have a capacity down 14% from the good old days and the weakest pair are down 29%.

    The camera uses 1.9 W, so a battery with 2.5 W·hr capacity should last 78 minutes, but about 400 mV of voltage depression causes the camera to give up before using its full capacity.

    So they have a useful lifetime of maybe two years in our regular bike riding schedule and I should have bought replacements last year. I hope the next batch isn’t New Old Stock or recycled cells.