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: Improvements

Making the world a better place, one piece at a time

  • KeyboardIO Atreus: RGB LED Installation

    KeyboardIO Atreus: RGB LED Installation

    Having scouted out the territory inside the KeyboardIO Atreus, adding an LED requires taking it completely apart to drill a hole in the aluminum faceplate:

    Atreus keyboard - panel drilling
    Atreus keyboard – panel drilling

    Reattaching the plate to the PCB with only three screws allows marking the hole position on the PCB, which is much easier than pretending to derive the position from first principles:

    Atreus keyboard - LED marking
    Atreus keyboard – LED marking

    Despite appearances, I traced the hole with a mechanical pencil: black graphite turns shiny silvery gray against matte black soldermask. Also, the PCB trace is off-center, not the hole.

    Overlay the neighborhood with Kapton tape to protect the PCB from what comes next:

    Atreus keyboard - Kapton tape

    Snip a WS2812 RGB LED from a strip, stick it in place with eyeballometric alignment over the target, and wire it up:

    Atreus keyboard - LED wiring
    Atreus keyboard – LED wiring

    Despite the terrible reliability of WS2812 RGB LEDs mounted on PCB carriers, a different set on a meter of high-density flex tape have worked reasonably well when not thermally stressed, so I’ll assume this one arrived in good order.

    Aligning the LED directly under the hole required a few iterations:

    Atreus keyboard - LED positioning
    Atreus keyboard – LED positioning

    The iridescent green patch is a diffraction pattern from the controller chip’s internal circuitry.

    The data comes from MOSI, otherwise known as B2, down in the lower left corner:

    Atmel 32U4 - JTAG pins
    Atmel 32U4 – JTAG pins

    Actually lighting the LED now becomes a simple matter of software QMK firmware.

  • Straightening Armature Wire

    Straightening Armature Wire

    Although I was blithely unaware when I bought some useful-looking surplus, it turns out 1/16 inch armature wire works really well to seal our homebrew masks around our noses. Mary added a narrow passage along the top edge of her slightly reshaped Fu Mask pattern to retain the wire and I provided 4.5 inch lengths of straightened wire:

    Armature wire - stock vs. straightened
    Armature wire – stock vs. straightened

    The wire comes off the roll in dead-soft condition, so I can straighten (and slightly harden) it by simply rolling each wire with eight fingertips across the battered cutting board. The slightly wavy wire shows its as-cut condition and the three straight ones are ready for their masks.

    Although nearly pure aluminum wire doesn’t work-harden quickly, half a year of mask duty definitely takes its toll. This sample came from my biking mask after the edges wore out:

    Armature wire - work-hardened
    Armature wire – work-hardened

    We initially thought using two wires would provide a better fit, but more metal just made adjusting the nose seal more difficult after each washing. The wire has work-hardened enough to make the sharper bends pretty much permanent; they can be further bent, but no longer roll out under finger pressure.

    Although we’re not yet at the point where we must reuse wires, I took this as an opportunity to improve my annealing hand: heat the wire almost to its melting point, hold it there for a few seconds, then let it cool slowly. The usual technique involves covering the aluminum with something like hand soap or permanent marker ink, heat until the soap / marker burns away, then let it air-cool. Unlike steel, there’s no need for quenching or tempering.

    Blue Sharpie worked surprisingly well with a propane torch:

    Armature wire - annealed straightened
    Armature wire – annealed straightened

    As far as I can tell after a few attempts, the pigment vanishes just below the annealing temperature and requires another pass to reach the right temperature. Sweep the flame steadily, don’t pause, and don’t hold the wire over anything melt-able.

    Those wires (I cut the doubled wire apart) aren’t quite as soft as the original stock, but they rolled straight and are certainly good enough for our simple needs; they’re back in the Basement Laboratory Warehouse for future (re)use.

  • Makergear M2: New Filament Drive and Guide Tube Adapter

    Makergear M2: New Filament Drive and Guide Tube Adapter

    After replacing the M2’s nozzle, I also installed a spare filament drive:

    Makergear M2 filament drive R3 - installed
    Makergear M2 filament drive R3 – installed

    That’s the V4 R3 version, although I bought it from Makergear rather than fight with all the support required to get a proper bearing opening.

    The long M4 screw and spring apply a constant force to the filament against the drive gear, rather than the constant position from the default (and much shorter) stock screw. The lever arm does have some springiness, but not much travel, so IMO the spring works better with the fine teeth in the drive gear.

    This drive has a 5 mm hole at the top for the stock PTFE guide tube, which I long ago replaced with ¼ inch OD HDPE tubing to reduce the friction required to get the filament off the spool and into the hot end. The rather hideous hot-melt glue blob holding a ¼ inch ID tube onto the previous drive never failed enough to bother me, but a little lathe action produced a much better adapter:

    Makergear M2 filament drive R3 - guide adapter
    Makergear M2 filament drive R3 – guide adapter

    It’s a chunk of ⅜ inch = 9.5 mm Delrin rod with a 2.4 mm hole through that 5 mm spigot for easy extraction of a gear-mashed 1.75 mm filament. The other end has a 6.5 mm hole drilled 20 mm deep to hold the guide tube.

    Looks downright dressy, it does!

  • Drive Wheelchair Brake Knob

    Drive Wheelchair Brake Knob

    The bent-steel brake levers on our Drive Blue Streak wheelchair present themselves edge-on to the rider:

    Drive Wheelchair Brake
    Drive Wheelchair Brake

    There are good mechanical reasons for shaping and orienting the steel like that, but the handle concentrates the considerable force required to push the brake tab into the rubberoid tire on your (well, my) palms. After a couple of weeks, I decided I didn’t need two more sore spots and conjured a palm-filling knob from the vasty digital deep:

    Wheelchair Brake Knob - installed
    Wheelchair Brake Knob – installed

    Bonus part: the little octagon near the wheel prevents the leg rest (seen in the first picture) from smashing into the end of the brake tab and chipping the lovely blue powder coat. The brown fuzzy felt foot seemed like a good idea at the time, but isn’t strictly necessary.

    A cylindrical handle on Thingiverse apparently fits on the bare steel underneath the rubberish “cushion”, but cutting a perfectly good, albeit uncomfortable, cushion off seemed like a step in the wrong direction. My knob thus descends from a doodle of the OEM dimensions:

    Drive Wheelchair Brake Handle - dimensions
    Drive Wheelchair Brake Handle – dimensions

    The knob builds in two halves adjoining the bonus octagon, which stands on edge to eliminate support inside its slot:

    Wheelchair Brake Mods - solid model - build layout
    Wheelchair Brake Mods – solid model – build layout

    You (probably) need two of all those shapes, a job your slicer is ready to perform. At three hours for each knob, I just printed the same G-Code twice.

    You can customize the knob width to fit your palm, with the other two dimensions fitting themselves around the cushion. Mary and I settled on a knob size that fits both our hands reasonably well, so it’s probably not critical.

    I tried building the knob halves without support for the first prototype, but the sloped upper surface produced awful bridging:

    Wheelchair Brake Knob - unsupported interior
    Wheelchair Brake Knob – unsupported interior

    It’s easy enough to design a customized support structure:

    Wheelchair Brake Mods - cross section
    Wheelchair Brake Mods – cross section

    I oriented the knob to put the split on the narrow sides of the brake handle in order to not have a seam facing my palm:

    Wheelchair Brake Knob - rear half installed
    Wheelchair Brake Knob – rear half installed

    The quartet of M3×20 mm socket-head cap screws thread into brass inserts epoxied into the rear half. I recessed their heads deeply into the front half and avoided thinking too hard about plugs matching the surface curvature:

    Wheelchair Brake Knob - front view
    Wheelchair Brake Knob – front view

    The low-vertex-count polygonal shape is a stylin’ thing and produces a nice feel during a firm shove, at least to my paws. Although I’d rather not need a wheelchair at all, setting the brakes now seems authoritative instead of annoying.

    The OpenSCAD source code as a GitHub gist:

    // Pride wheelchair brake lever mods
    // Ed Nisley KE4ZNU 2020-11
    /* [Layout options] */
    Layout = "Build"; // [Build, Show, Fit, TabCap, Handle, Knob, Support]
    // Hold up the knob's inside
    Support = true;
    /* [Extrusion parameters] */
    /* [Hidden] */
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    HoleWindage = 0.2;
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    function IntegerLessMultiple(Size,Unit) = Unit * floor(Size / Unit);
    Protrusion = 0.1; // make holes end cleanly
    inch = 25.4;
    ID = 0;
    OD = 1;
    LENGTH = 2;
    //———————-
    // Useful routines
    module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
    Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
    FixDia = Dia / cos(180/Sides);
    cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides);
    }
    //* [Basic dimensions] */
    WallThick = 4.0; // min wall thickness
    Screw = [3.0,5.5,20.0]; // thread, head, length under head
    Insert = [3.0,4.1,8.0]; // thread, knurl, length
    //———————-
    // Brake tab cap
    BrakeTab = [15,21,3.1]; // length to wheel, width, thickness
    BrakeTabSagitta = 8.0; // height of curved endcap
    CapOAL = [BrakeTab.y + 2*WallThick,BrakeTab.y + 2*WallThick,BrakeTab.z + 2*WallThick];
    module TabCap() {
    difference() {
    rotate(180/8)
    cylinder(d=CapOAL.y,h=CapOAL.z,center=true,$fn=8);
    translate([BrakeTab.x/2,0,0])
    cube(BrakeTab,center=true);
    rotate(180/8)
    cylinder(d=BrakeTab.y/cos(180/8),h=BrakeTab.z,center=true,$fn=8);
    }
    }
    //———————-
    // Brake lever handle
    // Soft covering with rounded sides that we square off for simplicity
    HandleRibs = [15,34,14]; // ignoring slight taper from end
    HandleCore = [50.0,24.0,12.0]; // straight section of lever to top of ribs
    HandleTipWidth = 30.0; // ignoring actual sector height
    module Handle() {
    union() {
    hull() {
    rotate(180/8)
    cylinder(d=HandleTipWidth/cos(180/8),h=HandleCore.z,center=true,$fn=8);
    translate([-HandleCore.x/2,0,0])
    cube(HandleCore,center=true);
    }
    translate([-(3*HandleCore.x/2 – Protrusion),0,0]) // extend base for ball trimming
    cube(HandleCore,center=true);
    translate([-HandleRibs.x/2,0,0])
    cube(HandleRibs,center=true);
    }
    }
    //———————-
    // Support structure for handle cavity inside knob
    // Totally ad-hoc tweakage
    // Remember it's lying on its side to match the handle
    NumRibs = 2 + 1; // must be odd
    RibSpace = floor(HandleCore.z/(NumRibs + 1));
    module KnobSupport() {
    color("Yellow") { // support overlaps in the middle
    render(convexity=3)
    intersection() {
    for (k=[-1,1])
    translate([0,k*ThreadThick,0]) // shrink inward to break adhesion
    Handle();
    translate([(HandleCore.x – HandleRibs.x)/2 – HandleCore.x – Protrusion,0,0])
    cube([HandleCore.x – HandleRibs.x,HandleRibs.y,HandleCore.z],center=true);
    union()
    for (k=[-floor(NumRibs/2):floor(NumRibs/2)])
    translate([0,0,k* RibSpace])
    cube([2*HandleCore.x,HandleRibs.y,2*ThreadWidth],center=true);
    }
    translate([(HandleCore.x – HandleRibs.x)/2 – HandleCore.x,0,0])
    cube([HandleCore.x – HandleRibs.x,4*ThreadWidth,NumRibs*RibSpace],center=true);
    }
    }
    //———————-
    // Brake handle knob
    // Largely built with magic numbers
    // Includes support because it's not really optional
    KnobOD = 55.0;
    KnobOffset = HandleRibs.x/1;
    KnobSides = 2*4*3;
    module Knob() {
    difference() {
    hull() {
    resize([0,HandleRibs.y + 4*WallThick,HandleCore.x + HandleTipWidth/2 + WallThick])
    sphere(d=KnobOD,$fn=KnobSides);
    }
    translate([0,0,KnobOffset])
    rotate([0,-90,0])
    Handle();
    for (i=[-1,1],k=[-1,1])
    translate([i*KnobOD/4,0,k*KnobOD/4]) {
    rotate([90,0,0])
    PolyCyl(Insert[OD],1.5*Insert[LENGTH],6);
    translate([0,-Screw[LENGTH]/2,0])
    rotate([-90,0,0])
    PolyCyl(Screw[ID],KnobOD,6);
    translate([0,Screw[LENGTH] – Insert[LENGTH],0])
    rotate([-90,0,0])
    PolyCyl(Screw[OD],KnobOD,6);
    }
    }
    if (Support)
    translate([0,0,KnobOffset])
    rotate([0,-90,0])
    KnobSupport();
    }
    //———————-
    // Lash it together
    if (Layout == "TabCap") {
    TabCap();
    }
    if (Layout == "Handle") {
    Handle();
    }
    if (Layout == "Support") {
    KnobSupport();
    }
    if (Layout == "Knob") {
    Knob();
    }
    if (Layout == "Show") {
    translate([60,0,0])
    TabCap();
    Knob();
    }
    if (Layout == "Fit") {
    translate([60,0,0])
    difference() {
    TabCap();
    translate([0,0,CapOAL.z/2])
    cube(CapOAL,center=true);
    }
    difference() {
    Knob();
    translate([KnobOD + KnobOD/4,0*KnobOD,0])
    cube(2*KnobOD,center=true);
    translate([-KnobOD,-KnobOD,0])
    cube(2*KnobOD,center=true);
    }
    }
    if (Layout == "Build") {
    translate([KnobOD/2,0,(CapOAL.y*cos(180/8))/2])
    rotate([0,-90,90])
    TabCap();
    for (j=[-1,1])
    translate([0,-j*0.75*HandleCore.x,0])
    difference() {
    rotate([j*90,0,0])
    Knob();
    translate([0,0,-KnobOD])
    cube(2*KnobOD,center=true);
    }
    }

    A doodle with dimensions of other parts:

    Drive Wheelchair - brake footrest tab dimensions
    Drive Wheelchair – brake footrest tab dimensions

    The angled tab on the middle left is for the leg rest release latch, but I decided not to silk-purse-ize the thing.

  • Hiatus

    Posts will appear intermittently over the next week or two.

    I’m still spending an inordinate amount of time studying the back of my eyelids while horizontally polarized in the lift chair. I can highly recommend not doing whatever it is that triggers a pinched lumbar nerve, but as nearly as I can tell, the proximate cause (shredding leaves) isn’t anything close to whatever the root cause might be.

    It does provide plenty of time to conjure solid models from the vasty digital deep:

    Wheelchair Brake Mods - solid model - build layout
    Wheelchair Brake Mods – solid model – build layout

    The wheelchair brake lever seems to have been designed by somebody who never actually had to shove it very often:

    Drive Wheelchair Brake
    Drive Wheelchair Brake

    At least I can fix that

  • Monthly Science: Batmax NP-BX1 Status

    Monthly Science: Batmax NP-BX1 Status

    After powering my Sony HDR-AS30V helmet camera for nearly all of this year’s riding, the Batmax NP-BX1 lithium batteries still have roughly 90% of their original capacity:

    Batmax NP-BX1 - 2020-11
    Batmax NP-BX1 – 2020-11

    Those are hot off the Official Batmax charger, which appears identical to other randomly named chargers available on Amazon.

    They’re holding up much better after a riding season than the DOT-01 batteries I used two years ago:

    Sony DOT-01 NP-BX1 - 2019-10-29
    Sony DOT-01 NP-BX1 – 2019-10-29

    Empirically, they power the camera for about 75 minutes, barely enough for our typical rides. I should top off the battery sitting in the camera unused for a few days, although that hasn’t happened yet.

    Of course, the Batmax NP-BX1 batteries I might order early next year for the new riding season have little relation to the ones you see here.

  • Neiko Hole Punch Accurizing

    Neiko Hole Punch Accurizing

    Having struggled to cut nice rings from gooey foam adhesive tape, I got a Neiko hollow hole punch set, despite reviews suggesting the pilot point might be a bit off. The case wrapper claims otherwise:

    Neiko hole punch - description
    Neiko hole punch – description

    As the saying (almost) goes:

    Inconcievable! Precision!”

    “You keep using that word. I do not think it means what you think it means.”

    Goldman, The Princess Bride

    An eyeballometric measurement suggests this is another one of those Chinese tools missing the last 10% of its manufacturing process:

    Neiko hole punch - as-received off-center tip
    Neiko hole punch – as-received off-center tip

    That’s the 5 mm punch, where being (at least) half a millimeter off-center matters more than it would in the 32 mm punch.

    Unscrewing the painfully awkward screw in the side releases the pilot:

    Neiko hole punch - punch tip debris
    Neiko hole punch – punch tip debris

    The debris on the back end of the pilot is a harbinger of things to come:

    Neiko hole punch - damaged spring debris
    Neiko hole punch – damaged spring debris

    Looks like whoever was on spring-cutting duty nicked the next coil with the cutoff wheel. I have no idea where the steel curl came from, as it arrived loose inside the spring.

    Although it doesn’t appear here, I replaced that huge screw with a nice stainless steel grub screw that doesn’t stick out at all.

    Chucking the pilot in the lathe suggested it was horribly out of true, but cleaning the burrs off the outside diameter and chamfering the edges with a file improved it mightily. Filing doesn’t remove much material, so apparently the pilot is supposed to have half a millimeter of free play in the handle:

    Neiko hole punch - undersized pilot
    Neiko hole punch – undersized pilot

    That’s looking down at the handle, without a punch screwed onto the threads surrounding the pilot.

    Wrapping a rectangle of 2 mil brass shimstock into a cylinder around the pilot removed the slop:

    Neiko hole punch - cleaned tip brass shim
    Neiko hole punch – cleaned tip brass shim

    But chucking the handle in the lathe showed the pilot was still grossly off-center, so I set it up for boring:

    Neiko hole punch - boring setup
    Neiko hole punch – boring setup

    The entry of the hole was comfortingly on-axis, but the far end was way off-center. I would expect it to be drilled on a lathe and, with a hole that size, it ought to go right down the middle. I’ve drilled a few drunken holes, though.

    Truing the hole enlarged it enough to require a 0.5 mm shimstock wrap, but the pilot is now pretty much dead on:

    Neiko hole punch - accurized results
    Neiko hole punch – accurized results

    Those are 5, 6, 8, and 10 mm punches whacked into a plywood scrap; looks well under a quarter millimeter to me and plenty good enough for what I need.