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

  • Kitchen Scale: Button Shield

    Kitchen Scale: Button Shield

    While I was thinking about something else, I added a back shield to our kitchen scale:

    SmartHeart 19-106 Scale - button shield
    SmartHeart 19-106 Scale – button shield

    A pogo pin connected to the circuit common contacts the copper foil when the bottom cover is screwed down:

    SmartHeart 19-106 Scale - shield pogo pin - detal
    SmartHeart 19-106 Scale – shield pogo pin – detal

    The shield prevents the buttons from responding to fingers on the bottom of the scale, so it no longer wakes up when I extract it from the under-cabinet shelf, and concentrates its attention on the buttons, so it no longer seems quite so willing to lock up due to mysterious influences.

    With an absurd amount of rebuilding, this scale is becoming not a complete waste of free money.

    The batteries soaked up 240 mA·hr of charge, which means the scale drew about 10 mA/day over the last three weeks. Given that the scale’s original 2032 lithium cells have a total capacity around 220 ma·hr for currents in the microamp range, expecting them to supply a current around 10 mA is was absurd.

  • SJCAM M50 Trail Camera: Dead Remote

    SJCAM M50 Trail Camera: Dead Remote

    The remote control included with the SJCAM M50 trail camera did absolutely nothing. Not only did it not turn on the camera’s WiFi, the two indicator LEDs between the buttons didn’t blink:

    SJCAM M50 remote - front view
    SJCAM M50 remote – front view

    With not much to lose, I removed those four screws and popped the back cover:

    SJCAM M50 remote - interior
    SJCAM M50 remote – interior

    Yup, the OEM no-name CR2032 lithium cell was dead flat discharged. A new one perked it right up, with blinky LEDs and all.

    Now I can check the camera for interesting pix without hauling it into the house:

    The Early Raccoon
    The Early Raccoon

    Plenty of critters making the rounds out there …

  • Laser Air Assist Pump Snorkel

    Laser Air Assist Pump Snorkel

    Having verified that putting an assist air pump inside the laser cabinet is a Bad Idea™, I set about building a fitting to attach to the air pump’s inlet connection:

    OMTech 60 W Laser Air Assist - pump inlet
    OMTech 60 W Laser Air Assist – pump inlet

    Note that it’s possible to see the inlet, but not do much with it. I think the bottom plate could be pried off those squishy rubber pillars supporting / isolating the pump, but I didn’t see any need to do so.

    The doodle I made at the time gives the dimensions:

    OMTech 60 W Laser Air Assist - pump inlet fitting measurements
    OMTech 60 W Laser Air Assist – pump inlet fitting measurements

    Back then, I thought of 3D printing the fitting, but the fact that the parts had to be 1.5 mm thick suggested laser cutting the parts from acrylic sheet:

    Laser cutter air pump - keyed fitting A - parts
    Laser cutter air pump – keyed fitting A – parts

    The three top disks come from a 3M LSE adhesive sheet and hold the three layers together, with one spare because I know better than to cut exactly as many as I think I’ll need:

    Laser cutter air pump - keyed fitting - assembled
    Laser cutter air pump – keyed fitting – assembled

    The alert reader will note the middle layer in that picture isn’t a simple round disk. After putting the first version together, I realized the keyed bottom layer could continue turning until it fell out, so I added stops to the middle disk:

    Laser cutter air pump - keyed fitting B - parts
    Laser cutter air pump – keyed fitting B – parts

    Those stops came from the bottom layer layout by welding together three copies of the key opening:

    Laser Cutter Air Assist Pump Fitting - LB design layout
    Laser Cutter Air Assist Pump Fitting – LB design layout

    Space three of those shapes around the ring, subtract them from the outer disk (the same size as the keyed layer), weld them to the middle disk (the same size as the previous middle), and the stops appear as if by magic. Gotta love this geometry stuff.

    The same design produced matching adhesive disks that I applied with tweezers, but if you were doing it in production you’d definitely want to apply a sheet of adhesive to a sheet of acrylic and cut them in the same operation.

    Soften the slightly curved PVC tubing with a heat gun, persuade it to become straight, jam a drill bit inside and grab it in the lathe chuck to keep the fitting perpendicular, glob hot-melt glue around the tubing to hold it in place, and let it cool:

    Laser cutter air pump - fitting hose glue
    Laser cutter air pump – fitting hose glue

    Hot melt glue doesn’t adhere well to acrylic, so cut & apply a disk of LSE adhesive between them, because it sticks like … glue … to both substances.

    Mark and step-drill a hole in the bottom of the laser cabinet, install the fitting on the pump, line things up, and it’s ready to screw down:

    Laser cutter air pump - first trial fitting
    Laser cutter air pump – first trial fitting

    Whereupon I discovered the four silicone rubber feet I added to support the pump base plate and keep it from vibrating against the cabinet let the flexy rubber posts supporting the pump extend too far, thus causing the whole pump to rest on the glue around the fitting.

    Well, I can fix that and, while I’m at it, a snippet of fibrous stuff will keep the tube from rattling around:

    Laser cutter air pump - bottom view - assembled
    Laser cutter air pump – bottom view – assembled

    The four clear disks are 3 mm acrylic stuck to the rubbery feet with more LSE adhesive, with rings around the top to keep everything aligned. It may be possible to line up all four of those things while lowering the pump in place, but not for me.

    With all that once again ready to screw down, the blue tube and its fuzzy felt bumper fell right off, taking the pump’s air inlet connector along. Much to my surprise, the pump draws air through a simple 6 mm hole in its bottom plate:

    Laser cutter air pump - without fitting socket
    Laser cutter air pump – without fitting socket

    Now, the reason I went through all these gyrations was because I had examined that connector, decided it was an integral part of the pump, and there was no way for me to get it off without tearing the pump apart or applying brute force.

    Apparently, all the twisting & turning I did while getting the fittings assembled worked the connector’s unthreaded stem loose in its hole, ready to come out with the slightest pull.

    Verily: Hell hath no fury like that of an unjustified assumption.

    So I cut out a simple disk of 4.5 mm acrylic, hot-melt blobbed a 6 mm ID silicone tube into it, stuck it onto the pump with a (punch-cut!) disk of 3M double-sided foam tape, and declared victory:

    Laser cutter air pump - simple disk fitting
    Laser cutter air pump – simple disk fitting

    Fortunately, the step drill I used on the cabinet left a 9.5 mm hole easily passing the silicone tube’s 9 mm OD, so it all fit together just like I knew what I was doing.

    The silicone tubing has a much larger ID than the original plastic fitting, but the assist air flow remains around 10 l/min. That’s down from the 14 l/m when I installed the flowmeter and 12 l/min with the dual-path assist air control plumbing, but didn’t change with all this fiddling, so the real restriction is in all the blue tubing and myriad fittings on the way to the nozzle.

    On the upside, I now know a bit more about small-scale laser cutting and am well-satisfied with the results.

  • Car USB Charger: Structural Solder Failure

    Car USB Charger: Structural Solder Failure

    The USB charger plugged into the jack formerly known as a “cigarette lighter” and now called a “power supply socket” in the car woke up dead, with a blank LED display previously showing the battery voltage / USB current / ambient temperature. Cracking the case revealed two small circuit boards:

    Car USB charger - innards
    Car USB charger – innards

    You can see where this is going, right?

    A closer look at the base of the side contacts:

    Car USB charger - broken solder
    Car USB charger – broken solder

    The central tab goes through the PCB and should have been soldered on the other side, leaving the springy arms free to flex. Instead, only the arm over the topside pad had any solder; the other arm just got a solder blob atop the silkscreen over those traces.

    I soldered the bottom tab, although I also resoldered the side pad. After all, the structural solder survived for quite a few years, so it might well outlive the car this time.

  • Laser Air Assist Pump Filter: Ewww!

    Laser Air Assist Pump Filter: Ewww!

    Nine months ago I packed cheesecloth around the laser’s air assist pump inlet to filter the smog:

    OMTech 60 W Laser Air Assist - cheesecloth filter installed
    OMTech 60 W Laser Air Assist – cheesecloth filter installed

    Which worked better than I expected.

    I think the track on the right side of the lower / outer filter faced the interior of the cabinet and collected some incoming smog:

    Laser cutter assist air filter - 9 months - outer
    Laser cutter assist air filter – 9 months – outer

    The wad packed around the inlet fitting accumulated even more, due to the concentrated air flow through the round opening:

    Laser cutter assist air filter - 9 months - inner
    Laser cutter assist air filter – 9 months – inner

    Thus we can confirm putting the air pump inside the cutting chamber is not a particularly good idea:

    OMTech 60W laser - Z motor - air pump
    OMTech 60W laser – Z motor – air pump

    My initial notion of drilling a hole through the bottom of the cabinet so the pump can breathe relatively clean basement air takes on new urgency …

  • Tour Easy: SJCAM C100+ Mount

    Tour Easy: SJCAM C100+ Mount

    The batteries (which are no longer available) and the control buttons have worn out on the SJCAM M20 camera on the back of my Tour Easy, so a replacement is in order:

    Tour Easy - SJCAM C100 mount - installed
    Tour Easy – SJCAM C100 mount – installed

    It’s an SJCAM C100+ in its waterproof housing, screwed to a block descended from the M20 mount:

    SJCAM C100 Mount - solid model
    SJCAM C100 Mount – solid model

    The C100+ has a non-replaceable lithium pouch battery that may not last for the hour or so we generally ride, but at least this is a starting point for seeing how the thing works.

    The PrusaSlicer preview shows the support structure inside the seat rail arches:

    SJCAM C100 Mount - slicer
    SJCAM C100 Mount – slicer

    That appears under the four central facets of each arch, where I “painted” the support enforcers, because the automagic supports fill the entire arch and are basically impossible to pry off.

    The hole between the ears on the top holds an aluminum tab intended to diffuse the wobble from that tall camera. A laser-cut chipboard template simplified drilling & cutting the tab from an aluminum sheet:

    Tour Easy - SJCAM C100 mount - test fit
    Tour Easy – SJCAM C100 mount – test fit

    The tab and the brass inserts are held in place with JB Weld Plastic Bonder, my new go-to adhesive for such things.

    The camera includes WiFi and the inevitable app lets you download images without opening the case. Because I’ll be charging the camera after each ride, I may as well just haul the whole thing inside, plug it into a USB port, and proceed as before.

    For future reference, the manual details the operating modes:

    SJCAM C100 Manual - Modes
    SJCAM C100 Manual – Modes

    Because the camera powers up with WiFi enabled and I have no plans to communicate with it while riding, the startup sequence will be:

    • Long-press to power on
    • Double-click to disable WiFi
    • Single-click to start recording

    The OpenSCAD source code as a GitHub Gist:

    // SJCAM C100+ Camera Mount for Tour Easy seat back rail
    // Ed Nisley – KE4ZNU
    // 2023-04
    /* [Layout Options] */
    LookAngle = -20; // camera angle, looking backwards = 0°
    Layout = "Show"; // [Show,Build]
    /* [Hidden] */
    ThreadWidth = 0.40;
    ThreadThick = 0.25;
    HoleWindage = 0.2;
    Protrusion = 0.1;
    ID = 0;
    OD = 1;
    LENGTH = 2;
    //—–
    // Dimensions
    ClampScrew = [5.0,10.0,40.0]; // ID=thread OD=washer LENGTH=total
    ClampInsert = [5.0,7.5,10.5]; // brass insert
    MountScrew = [5.0,10.0,23.0]; // ID=thread OD=washer LENGTH=under nut
    MountInsert = [5.0,7.5,10.5]; // ID=screw OD, OD=knurl dia
    EmbossDepth = 2*ThreadThick + Protrusion; // recess depth + Protrusion beyond surface
    DebossHeight = EmbossDepth; // text height + Protrusion into part
    RailOD = 20.0; // slightly elliptical in bent section
    RailSides = 2*3*4;
    ClampOA = [60.0,40.0,ClampScrew[LENGTH]]; // set clamp size to avoid weird screw spacing
    echo(ClampOA = ClampOA);
    ClampScrewOC = IntegerMultiple(ClampOA.x – ClampScrew[OD] – 10*ThreadWidth,1.0);
    echo(ClampScrewOC = ClampScrewOC);
    ClampOffset = 5.0; // in case we need more room on top
    ClampRadius = 3.0;
    ClampSides = 8;
    Kerf = 1.0; // slice through the middle
    // center mount blade, Z = depth into block
    MountBlade = [15.0 + 2*HoleWindage,
    3.0 + 2*HoleWindage,
    (ClampOA.z – RailOD + ClampOffset)/2 – 4*ThreadThick + Protrusion];
    echo(MountBlade = MountBlade);
    MountRadius = MountBlade.x / 2;
    MountGap = 9.5; // camera mount gap around center blade
    MountOffset = [0,0,7.0]; // mount hole offset from block surface
    FadeColor = "Green";
    FadeAlpha = 0.25;
    //—–
    // Useful routines
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    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);
    }
    //—–
    // Clamp
    // Grips seat frame rail
    // Origin at middle of seat rail, X rearward, Y parallel to seat frame rail
    // Block offset raises whole thing
    module Clamp() {
    difference() {
    translate([0,0,ClampOffset]) {
    difference() {
    union() {
    hull() // the main block
    for (i=[-1,1], j=[-1,1], k=[-1,1])
    translate([i*(ClampOA.x – 2*ClampRadius)/2,
    j*(ClampOA.y – 2*ClampRadius)/2,
    k*(ClampOA.z – 2*ClampRadius)/2])
    sphere(r=ClampRadius/cos(180/ClampSides),$fn=ClampSides);
    hull() // camera mount boss
    for (k=[0,1])
    translate([0,0,k*(MountOffset.z) + ClampOA.z/2])
    rotate([0,90,LookAngle + 90]) rotate(180/12)
    cylinder(r=MountRadius,h=MountScrew[LENGTH],center=true,$fn=12);
    }
    for (i=[-1,1]) // clamp inserts
    translate([i*ClampScrewOC/2,0,-(ClampOA.z/2 + Protrusion)])
    rotate(180/6)
    PolyCyl(ClampInsert[OD],ClampInsert[LENGTH],6);
    for (i=[-1,1]) // clamp screw holes
    translate([i*ClampScrewOC/2,0,-ClampOA.z])
    rotate(180/6)
    PolyCyl(ClampScrew[ID],2*ClampOA.z,6);
    translate([0,0,ClampOA.z/2 – (MountBlade.z/2 – Protrusion/2)]) // camera center blade
    rotate(LookAngle)
    cube(MountBlade,center=true);
    rotate(LookAngle + 90) // camera mount boss slot
    translate([0,0,ClampOA.z/2 + 2*MountRadius])
    cube([MountGap,4*MountRadius,4*MountRadius],center=true);
    translate([0,0,ClampOA.z/2 + MountOffset.z]) // camera mount boss hole
    rotate([90,0,LookAngle])
    cylinder(d=MountScrew[ID],h=4*MountGap,center=true,$fn=6);
    translate([0.3*ClampOA.x, // recess for LookAngle legend
    -(ClampOA.y/2 – (EmbossDepth – Protrusion)/2),
    ClampOA.z/4])
    cube([15,EmbossDepth,8],center=true);
    translate([0,0,-ClampOA.z/2 + (EmbossDepth – Protrusion)/2]) // recess for ID legend
    cube([35,10,EmbossDepth],center=true);
    }
    translate([0.3*ClampOA.x, // LookAngle legend
    -ClampOA.y/2 + DebossHeight + Protrusion/2,
    ClampOA.z/4])
    rotate([90,0,00])
    linear_extrude(height=DebossHeight,convexity=20)
    text(text=str(LookAngle),size=6,spacing=1.20,
    font="Arial:style:Bold",halign="center",valign="center");
    translate([0,0,-ClampOA.z/2]) // ID legend
    linear_extrude(height=DebossHeight,convexity=20)
    mirror([0,1,0])
    text(text="KE4ZNU",size=5,spacing=1.20,
    font="Arial:style:Bold",halign="center",valign="center");
    }
    cube([2*ClampOA.x,2*ClampOA.y,Kerf],center=true); // split across rail
    rotate([90,0,0]) // seat rail
    cylinder(d=RailOD,h=2*ClampOA.y,$fn=RailSides,center=true);
    }
    }
    //—–
    // Build things
    // Layouts for design & tweaking
    if (Layout == "Show") {
    Clamp();
    color(FadeColor,FadeAlpha)
    rotate([90,0,0])
    cylinder(d=RailOD,h=2*ClampOA.y,$fn=RailSides,center=true);
    }
    // Build layout
    if (Layout == "Build") {
    translate([0,0.7*ClampOA.y,0])
    difference() {
    translate([0,0,-Kerf/2])
    Clamp();
    translate([0,0,-ClampOA.z])
    cube(2*ClampOA,center=true);
    }
    translate([0,-0.7*ClampOA.y,-0])
    difference() {
    translate([0,0,-Kerf/2])
    rotate([0,180,0])
    Clamp();
    translate([0,0,-ClampOA.z])
    cube(2*ClampOA,center=true);
    }
    }

  • Aperiodic Monotile Puzzle

    Aperiodic Monotile Puzzle

    The aperiodic monotile discovery prompted some reverse engineering, snapping a path to regular hexagons for the proper lengths and angles without mathing too hard:

    Aperiodic tile - hexagon overlay
    Aperiodic tile – hexagon overlay

    The resulting red path is the “hat” monotile, here shown as a PNG for neatness:

    Aperiodic monotile
    Aperiodic monotile

    With SVG hat in hand, I laid and cut a trial puzzle based on the sample shown in the paper:

    Aperiodic tile layout
    Aperiodic tile layout

    Which looked promising enough to add a few rings around that layout and turn it into an actual, albeit low budget, puzzle:

    Aperiodic tile puzzle - starting
    Aperiodic tile puzzle – starting

    The paper notes that one can build mutually incompatible patches, which is the state I immediately blundered into:

    Aperiodic tile puzzle - progress
    Aperiodic tile puzzle – progress

    The upper and lower left halves cannot be combined to extend rightward, as the middle section is incompatible with both. I began growing patches from the upper and lower right corners, hoping to use them to rectify the left half, but producing a small un-fillable situation in the middle:

    Aperiodic tile puzzle - incorrect layout
    Aperiodic tile puzzle – incorrect layout

    Obviously, I need a cheat code. I’m resolutely not looking at the source layout for a while.

    This would surely look good in fluorescent edge-lit acrylic!

    The LightBurn SVG layout as a GitHub Gist:

    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.