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

  • Astable Multivibrator: Dressed-up LED Spider

    Astable Multivibrator: Dressed-up LED Spider

    Adding a bit of trim to the bottom of the LED spider makes it look better and helps keep the strut wires in place:

    Astable Multivibrator - Alkaline - Radome trim
    Astable Multivibrator – Alkaline – Radome trim

    It’s obviously impossible to build like that, so it’s split across the middle of the strut:

    Astable Multivibrator - Alkaline - Radome trim
    Astable Multivibrator – Alkaline – Radome trim

    Glue it together with black adhesive and a couple of clamps:

    LED Spider - glue clamping
    LED Spider – glue clamping

    The aluminum fixtures (jigs?) are epoxied around snippets of strut wire aligning the spider parts:

    LED Spider - gluing fixture
    LED Spider – gluing fixture

    Those grossly oversized holes came pre-drilled in an otherwise suitable aluminum rod from the Little Tray o’ Cutoffs. I faced off the ends, chopped the rod in two, recessed the new ends, and declared victory. Might need better ones at some point, but they’ll do for now.

    Next step: wire up an astable with a yellow LED to go with the green and blue boosted LEDs.

  • Atreus Keyboard: LED Thoughts

    Atreus Keyboard: LED Thoughts

    Having helped grossly over-fund the Atreus Kickstarter earlier this year, a small box arrived pretty much on-time:

    Atreus keyboard - overview
    Atreus keyboard – overview

    I did get the blank keycap set, but have yet to screw up sufficient courage to install them. The caps sit atop the stock Kailh (pronounced, I think, kale) BOX Brown soft tactile switches; they’re clicky, yet not offensively loud.

    Removing a dozen screws lets you take it apart, revealing all the electronics on the underside of the PCB:

    Atreus keyboard - PCB overview
    Atreus keyboard – PCB overview

    The central section holds most of the active ingredients:

    Atreus keyboard - USB 32U4 Reset - detail
    Atreus keyboard – USB 32U4 Reset – detail

    The Atmel MEGA32U4 microcontroller runs a slightly customized version of QMK:

    Atreus keyboard - 32U4 - detail
    Atreus keyboard – 32U4 – detail

    Of interest is the JTAG header at the front center of the PCB:

    Atreus keyboard - JTAG header
    Atreus keyboard – JTAG header

    I have yet to delve into the code, but I think those signals aren’t involved with the key matrix and one might be available to drive an addressable RGB LED.

    For future reference, they’re tucked into the lower left corner of the chip (the mauled format comes from the original PDF):

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

    The alternate functions:

    • SCK = PB1
    • MOSI = PB2
    • MISO = PB3

    I don’t need exotic lighting, but indicating which key layer is active would be helpful.

    Love the key feel, even though I still haven’t hit the B key more than 25% of the time.

  • Roadside Overgrowth: Life Finds a Way

    Roadside Overgrowth: Life Finds a Way

    A few years ago, this traffic splitter had a magnificent overgrowth goin’ on:

    Traffic splitter bushes - Vassar Rd at Pine Tree Dr - Streetview 2018-07
    Traffic splitter bushes – Vassar Rd at Pine Tree Dr – Streetview 2018-07

    Eventually, somebody (perhaps the NYS DOT) cut the bushes off at their bases and probably hit them with defoliant to keep them down:

    Traffic splitter stumps - Vassar Rd at Pine Tree Dr - 2020-11
    Traffic splitter stumps – Vassar Rd at Pine Tree Dr – 2020-11

    I don’t know that the stems cracked the concrete, but they surely eased the slabs apart.

    The signpost had a substantial bush at its base:

    Traffic splitter stumps - signpost - Vassar Rd at Pine Tree Dr - 2020-11
    Traffic splitter stumps – signpost – Vassar Rd at Pine Tree Dr – 2020-11

    It’s tough to keep civilization running ahead of Mother Nature

  • CUPS Whoopsie

    CUPS Whoopsie

    No CUPS server setup can be considered complete without sending a print job to the wrong printer:

    HPLJ1200 - CUPS Pinball Panic - detail
    HPLJ1200 – CUPS Pinball Panic – detail

    Which wouldn’t be quite so bad if the printer weren’t ever so much faster than I am:

    HPLJ1200 - CUPS Pinball Panic - output pileup
    HPLJ1200 – CUPS Pinball Panic – output pileup

    It turns out an ordinary clothes iron can flatten those pages. Set it to “silk”, spread packing paper on the ironing board to intercept the toner, iron a few millimeters of pages at a time, and feed them back into the printer.

    Back in the day, laser-specific printer paper came with a grain arranged so it wouldn’t curl when you fed it into the printer with the proper side up. Those days are gone; I’ve tried both ways and they both curl.

    Protip: When CUPS thinks it’s done with the job and the Web interface shows nothing’s going on, it’s handed the job to the server’s printing subsystem, which continues spooling data to the printer. Choking off the bitstream requires one command-line invocation on the server connected to the printer:

    cancel -a
    

    A paper jam gives you enough time to figure all that out.

  • Manjaro 20.1: CUPS Setup

    Tweaking a new Manjaro Linux 20.1 installation to share printers and allow remote administration, done while replacing an aging Optiplex desktop box that’s been running unattended for far too long.

    Start by installing Manjaro’s printer support package:

    pamac install manjaro-printer
    

    In the general section of the default /etc/cups/cupsd.conf file, up near the top:

    Listen *:631       # listen on all interfaces
    DefaultShared Yes  # share the local printers
    BrowseWebIF Yes    # turn on the Web interface
    

    Allow remote admin:

    <Location />
      Allow all
      Order allow,deny
    </Location>
    <Location /admin>
      Allow all
      Order allow,deny
    </Location>
    
    

    Restart the CUPS server:

    sudo systemctl restart org.cups.cupsd
    

    And then It Should Just Work.

  • Bicycling For The Fun of It All

    Bicycling For The Fun of It All

    Somewhere out there, you’ll find his video:

    Photo Op - 2020-11-09 - 287
    Photo Op – 2020-11-09 – 287

    Everybody needs a reason to smile!

    Bonus: enough vehicles to keep the signal at Burnett green.

    In the unlikely event you were wondering, 287 is the frame number from the video-to-still conversion:

    ffmpeg -ss 00:03:30 -i /mnt/video/AS30V/2020-11-09/MAH07624.mp4 -t 20 -f image2 -q 1 'Photo Op - 2020-11-09 - '%03d.jpg

    All in all, a fine day for a ride …

  • Mini-Lathe Ball Drilling Fixture

    Mini-Lathe Ball Drilling Fixture

    Despite successfully drilling holes in a few plastic balls, I wanted a somewhat less terrifying setup than this:

    Micromark Ball Vise - lathe ball hack
    Micromark Ball Vise – lathe ball hack

    The stiffness of the bike helmet mirror mount suggested a similar clamp would have enough griptivity to immobilize the ball while cutting it in the lathe:

    Helmet Mirror Mount - 10 mm ball
    Helmet Mirror Mount – 10 mm ball

    Building the clamp around the lathe’s three-jaw lathe chuck eliminates the need for screws / washers / inserts:

    Lathe Ball Fixture - 19 mm - Show
    Lathe Ball Fixture – 19 mm – Show

    The Ah-ha! moment came when I realized the fixture can expose half of the ball’s diameter for drilling while clamping 87% of its diameter, because 0.5 = sin 30° and 0.87 = cos 30°:

    Lathe Ball Fixture - 19 mm - Show - front orthogonal
    Lathe Ball Fixture – 19 mm – Show – front orthogonal

    That’s an orthogonal view showing 13% of the ball radius sticking out of the fixture; it’s 6% of the diameter.

    Which looks like this in real life:

    Lathe Ball Fixture - 19 mm - sections with ball
    Lathe Ball Fixture – 19 mm – sections with ball

    The socket is offset toward the tailstock end of the clamp (on the right in the picture) to expose half its diameter flush with the surface perpendicular to the lathe axis. The other side necks down into a cylinder of the same diameter to clear the drill bit.

    This works nicely until the ball diameter equals the chuck jaw’s 20 mm length, whereupon larger balls protrude into the chuck body’s spindle opening. Although I haven’t yet built one, the 25 mm balls in my Box o’ Bearings should fit, with exceedingly sissy cuts required for large holes.

    The fixture doesn’t require support material, because the axial holes eliminate the worst of the overhang. Putting the tailstock side flat on the platform gives it the best-looking surface:

    Lathe Ball Fixture - 19 mm - Slic3r - equator
    Lathe Ball Fixture – 19 mm – Slic3r – equator

    The kerf between the segments ensures the jaws can apply pressure to the ball, whereupon the usual crappy serrated 3D printed surface firmly grabs it.

    The fixture is a slip fit on the chuck jaws:

    Lathe Ball Fixture - 19 mm - installed
    Lathe Ball Fixture – 19 mm – installed

    Tightening the jaws shoves them all the way into the fixture’s slots and clamps the ball:

    Lathe Ball Fixture - 19 mm - center drill
    Lathe Ball Fixture – 19 mm – center drill

    Overtightening the chuck will (probably) compress the ball around the drill, which will (best case) give you slightly oversize holes or (worst case) cause the ball to seize / melt around the drill bit, so sleaze up to the correct hole diameter maybe half a millimeter at a time:

    Lathe Ball Fixture - 19 mm - 6 mm drill
    Lathe Ball Fixture – 19 mm – 6 mm drill

    That fixture exposes 9.5 mm = 19/2 of the ball. The drill makes a 6 mm hole to fit the telescoping shaft seen above.

    Obviously, you must build a custom fixture for every ball diameter in your inventory, which is no big deal when you have a hands-off manufacturing process. Embossing the diameter into the fixture helps match them, although the scribbled Sharpie isn’t particularly elegant.

    The OpenSCAD source code as a GitHub Gist:

    // Lathe Ball Drilling Fixture
    // Ed Nisley KE4ZNU 2020-11
    /* [Layout options] */
    Layout = "Build"; // [Build, Show, Body, Jaws]
    BallDia = 10.0; // [5.0:0.5:25.0]
    /* [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;
    //* [Basic dimensions] */
    Chuck = [21.0,100.0,20.0]; // chuck bore, OD, jaw length
    Jaw = [Chuck[LENGTH],15.0,12.0]; // jaw free length, base width, first step radius
    JawInclAngle = 112; // < 120 degrees for clearance!
    JawAngle = JawInclAngle/2; // angle from radius
    WallThick = 5.0; // min wall thickness
    Kerf = 0.75; // space between clamp blocks
    ClampSides = 8*(2*3);
    ClampBore = BallDia/2; // clear bore through clamp
    ClampAngle = asin(ClampBore/BallDia); // angle from lathe axis to clamp front
    Plate = [ClampBore,
    BallDia + 2*WallThick + 2*Jaw.z,
    Jaw.x];
    LegendDepth = 1*ThreadWidth;
    ShaftOD = 3.6; // sample shaft
    ShowGap = 1.5;
    //———————-
    // Chuck jaws
    // Real jaws have a concave radiused tip we simply ignore
    module ChuckJaws(l=Jaw.x,r=10) {
    for (a=[0:120:240])
    rotate(a)
    linear_extrude(height=l)
    translate([r,0])
    difference() {
    translate([Chuck[OD]/4,0])
    square([Chuck[OD]/2,Jaw.y],center=true);
    for (i=[-1,1])
    rotate(i*(90 – JawAngle))
    translate([-Jaw.z/2,0])
    square([Jaw.z,2*Jaw.y],center=true);
    }
    }
    //———————-
    // Clamp body
    module ClampBlocks() {
    difference() {
    cylinder(d=Plate[OD],h=Plate[LENGTH],$fn=ClampSides); // main disk
    translate([0,0,-Protrusion]) // central bore
    cylinder(d=ClampBore,h=2*Plate[LENGTH],$fn=ClampSides);
    for (a=[0:120:240]) // kerf slits
    rotate(60 + a)
    translate([Plate[OD]/2,0,Protrusion])
    cube([Plate[OD],Kerf,2*Plate[LENGTH]],center=true);
    translate([0,0,BallDia/2 * cos(ClampAngle)]) // ball socket
    sphere(d=BallDia,$fn=ClampSides);
    for (a=[0:120:240]) { // legend
    rotate(4.5*360/ClampSides + a)
    translate([Plate[OD]/2 – LegendDepth,0,Plate[LENGTH]/2])
    rotate([0,90,0])
    linear_extrude(height=LegendDepth + Protrusion,convexity=10)
    mirror([0,0,0])
    text(text=str(BallDia," mm"),size=2.5,spacing=1.20,font="Arial:style:Bold",halign="center",valign="center");
    rotate(-4.5*360/ClampSides + a)
    translate([Plate[OD]/2 – LegendDepth,0,Plate[LENGTH]/2])
    rotate([0,90,0])
    linear_extrude(height=LegendDepth + Protrusion,convexity=10)
    mirror([0,0,0])
    text(text="KE4ZNU",size=2.5,spacing=1.20,font="Arial:style:Bold",halign="center",valign="center");
    }
    }
    }
    //———————-
    // Clamp with jaw cutouts
    module ClampBody() {
    difference() {
    ClampBlocks();
    translate([0,0,-Protrusion])
    ChuckJaws(l=Jaw.x + 2*Protrusion,r=BallDia/2 + WallThick);
    }
    }
    //———————-
    // Lash it together
    if (Layout == "Body") {
    ClampBlocks();
    }
    if (Layout == "Jaws") {
    ChuckJaws();
    }
    if (Layout == "Build") {
    ClampBody();
    }
    if (Layout == "Show") {
    ClampBody();
    color("ivory",0.2)
    ChuckJaws(r=BallDia/2 + WallThick + ShowGap); // move out for E-Z viewing
    color("red",0.4)
    translate([0,0,-Jaw.x/2])
    cylinder(d=ShaftOD,h=2*Jaw.x,$fn=ClampSides,center=false);
    color("white",0.5)
    translate([0,0,BallDia/2 * cos(ClampAngle)]) // ball socket
    sphere(d=BallDia,$fn=ClampSides);
    }

    The dimension doodles, including some notions that didn’t work:

    Lathe Ball Clamp - dimension doodles
    Lathe Ball Clamp – dimension doodles