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

  • Wheel Stress Test

    Wheel Stress Test

    Spotted while walking on Rombout House Lane out of the Vassar Preserve:

    Pothole vs wheel weight
    Pothole vs wheel weight

    Looks like somebody hit that pothole at a pretty good clip and knocked a wheel weight loose.

    Rombout House Lane is a tiny L-shaped road serving as a Preserve entrance and exit not at the intersection of Rt 376 / Raymond / Hooker, but it’s slated for oblivion when NYS DOT finishes constructing the roundabout / rotary. With plenty of heavy equipment now crushing it, a walking pace is as fast as anyone should drive (or bicycle!) there.

  • Dumbbell Nuts

    Dumbbell Nuts

    Being an Old Guy, I lift dumbbell weights after bike rides for load-bearing upper-body exercise, but need a few more dumbbell nuts (a.k.a. “collars”) to simplify adjusting the weights for each set. Such things are commercially available, but the reviews suggest abysmally bad thread QC and a high return rate.

    Given that I treat my toys carefully, this should suffice:

    Dumbbell Nut - finished
    Dumbbell Nut – finished

    Start with a scan of a steel nut in GIMP:

    Dumbbell Nut - scan
    Dumbbell Nut – scan

    Blow out the contrast, trace it, smooth out some irregularities, get a mask:

    Dumbbell Nut - mask
    Dumbbell Nut – mask

    Select by color, convert the selection to a path, save as SVG, import into OpenSCAD, add a nut with threads from the incomparably useful BOSL2 library, extrude a few features, and this pops out:

    Dumbbell Nut - solid model
    Dumbbell Nut – solid model

    Run it through PrusaSlicer, print on the MK4, and iterate a few times to get everything right:

    Dumbbell Nut - test pieces
    Dumbbell Nut – test pieces

    I naively thought the threads were something standard like Acme, but they’re full-frontal custom trapezoidal. I knew the first pass would be wrong, so the small hex nut on the left started the whole process. Upper left is a revised Acme thread with all the other features, lower middle is the custom trapezoidal thread, and the nut on the upper right worked. Make three more, just like the first one, enjoying the magic of 3D printing.

    Draw the bumper washer in LightBurn based on the dimensions in the OpenSCAD code, cut a set from stamp-pad rubber & adhesive sheet, then assemble:

    Dumbbell Nut - assembly
    Dumbbell Nut – assembly

    As the saying goes, we got nuts:

    Dumbbell Nut - installed
    Dumbbell Nut – installed

    The gray PETG-CF looks black against a white background and gray against black iron.

    With a set of precisely fitting nuts in hand, I discovered one of the four bars in my weight sets is slightly larger than the others, so the code now produces an embiggened root diameter and I have two spares.

    The OpenSCAD code assembles a nut:

    // Dumbbell nut
    // Ed Nisley - KE4ZNU
    // 2024-10-04
    
    include <BOSL2/std.scad>
    include <BOSL2/threading.scad>
    
    ID = 0;
    OD = 1;
    THICK = 2;
    
    NutOAH = 20.0;
    BossOD = 45.0;
    Bumper = [33.0,40.0,2.5];
    
    NumSides = 4*9;
    
    difference() {
        intersection() {
            union() {
                down(NutOAH/2)
                    linear_extrude(height=NutOAH/2,convexity=2)
                        import("Dumbbell Nut - path.svg",
                                center=true);
                linear_extrude(height=NutOAH/2,convexity=2)
                    circle(d=BossOD,$fn=NumSides);
            }
            rotate(180/6)
                trapezoidal_threaded_nut(100.0,26.5,20.0,INCH/4,        // flat size, root dia, height, pitch
                                        bevel=false,ibevel=false,
                                        flank_angle=30,thread_depth=1.8);
        }
    
        up(NutOAH/2 - Bumper[THICK]/2)
            linear_extrude(height=2*Bumper[THICK],convexity=2) {
                difference() {
                    circle(d=Bumper[OD],$fn=NumSides);
                    circle(d=Bumper[ID],$fn=NumSides);
                }
            }
    
    }
    
    
  • Garden Hose Fitting Grip: MVP

    Garden Hose Fitting Grip: MVP

    The garden hose leading from the standpipe / hose bibs outside Mary’s garden to her drip irrigation plumbing has an octagonal fitting requiring more torque than her hand can easily produce. I offered to make a larger grip for the fitting, which amounts to a disk with a grippy rim sized to her hand and an interior opening suitable for gluing to the fitting.

    A couple of laser-cut MDF sizing prototypes accompanied me to the garden:

    Hose Fitting Grip - MDF prototype
    Hose Fitting Grip – MDF prototype

    The springy fingers around the fitting soak up the inevitable distortions found in a battered hose and will eventually be filled with adhesive to lock the grip in place.

    MDF being obviously the wrong material for a permanent installation, the final grip will be 3D printed, with the LightBurn layout modified to produce the internal structure:

    Hose Fitting Grip - LightBurn layers
    Hose Fitting Grip – LightBurn layers

    From left to right:

    • The stacked pieces in order of printing
    • Main grip with springy fingers
    • Spacer keeping the fingers away from the narrower opening
    • Support layer
    • Narrow opening to align the grip with the end of the fitting

    Exporting the SVG images and making a bank shot off Inkscape to create layer names:

    Hose Fitting Grip - Inkscape layers
    Hose Fitting Grip – Inkscape layers

    The ascending layer name + numbers allow a simple OpenSCAD program to extract the SVG shapes by name, extrude them to the proper thickness, put them at the proper height, then combine the result:

    Recenter = [-140,-108,0];
    
    Thick = [0,8.0,1.0,0.2,1.0];
    Level = [0,
             Thick[1],
             Thick[1]+Thick[2],
             Thick[1]+Thick[2]+Thick[3],
             Thick[1]+Thick[2]+Thick[3]+Thick[4]];
    Colors = ["Black","Red","Gray","Yellow","Green"];
    
    union()
        for (i = [1:len(Thick)-1]) {
            color(Colors[i])
                translate(Recenter + [0,0,Level[i-1]])
                    linear_extrude(height=Thick[i],convexity=10)
                        import("/mnt/bulkdata/Project Files/Laser Cutter/Gardening/Hose Fitting Grip/Hose Fitting Grip - Inkscape layout.svg",
                               layer=str("Layer ",i));
        }
    

    The hideous mess generating the Level vector happens because OpenSCAD does not have mutable variables and I hate retyping numbers. One can use a recursive function to add the values, but copypasta makes more sense in this case.

    Which produces this solid model, with garish colors for pedagogic purposes:

    Hose Fitting Grip - top - solid model
    Hose Fitting Grip – top – solid model

    The thin yellow band will be one thread thick to provide support for the green layer with a smaller ID than the springs below it. The gray layer below the yellow is the air gap above the springs.

    Peering inside the bottom shows the (gray) layer providing clearance between the springs and the (yellow) support layer:

    Hose Fitting Grip - bottom interior - solid model
    Hose Fitting Grip – bottom interior – solid model

    Exporting the model as a 3mf file, importing it into PrusaSlicer, and slicing it with suitable parameters (Extrusion Multipler = 0.8) does what you’d expect. This top view shows the internal structure just below the support bridge across the middle:

    Hose Fitting Grip - spring detail - PrusaSlicer
    Hose Fitting Grip – spring detail – PrusaSlicer

    Printing it in gray PETG-CF was uneventful, with the bridging layer coming out surprisingly well:

    Hose Fitting Grip - as printed
    Hose Fitting Grip – as printed

    The springs definitely have an air gap in there:

    Hose Fitting Grip - printed interior
    Hose Fitting Grip – printed interior

    And the support layer cuts out neatly with an Xacto knife:

    Hose Fitting Grip - support removed
    Hose Fitting Grip – support removed

    We’ve had enough rain over the last few days (something to do with a continental-scale storm) to keep me and my adhesives out of the garden, but it hasn’t needed any watering, either.

  • Bathtub Soap Tray V2

    Bathtub Soap Tray V2

    As expected, the adhesive foam strips I used on the bathtub soap tray didn’t survive continued exposure to hot soapy water, so Version 2 includes hooks securing it to the ceramic soap tray and a few other tweaks:

    Bathtub Soap Tray - V2 - LightBurn layout
    Bathtub Soap Tray – V2 – LightBurn layout

    The view from the top:

    Soap Tray V2 - top
    Soap Tray V2 – top

    The hooks are more visible from the bottom, as is the 10 AWG copper wire preventing the whole affair from rotating around the ceramic handle from the weight of the soap bar:

    Soap Tray V2 - bottom
    Soap Tray V2 – bottom

    Ignore the usual crud you’ll find on your ceramic soap tray, too.

    This time I glued things together with Weld-On IPS #3 acrylic solvent.

    The LightBurn 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.
  • Converted OttLite Rebasing

    Converted OttLite Rebasing

    The OttLite I converted into a NisLite fell over again and, now having a way to make the long-promised base, this happened:

    Converted Ottlite - cardboard base
    Converted Ottlite – cardboard base

    It’s not particularly elegant, what with being cardboard, but it’s a proof of concept that will determine the final size.

    The top layer is a ring around the lamp pedestal for a bit of stabilization protecting the four M3 screws holding the base to the lamp. Those screws sit on a 60 mm square, offset 1 mm to the front of the lamp:

    NisLite Baseplate - LightBurn layout
    NisLite Baseplate – LightBurn layout

    Which explains why I typically make the first few versions of anything out of cardboard.

    For the record, those inserts look like this:

    Converted Ottlite - brass inserts
    Converted Ottlite – brass inserts

    A pair of very flat-head M3 screws hold the front inserts in place through holes match-drilled in the remains of the bosses I’d long ago epoxied in place. I pressed the rear inserts in place by misusing the drill press, as the lamp is much too tall for the heat setter.

    Then comes the iron base weight:

    Converted Ottlite - iron weight
    Converted Ottlite – iron weight

    And then the steel outer plate:

    Converted Ottlite - steel cover plate
    Converted Ottlite – steel cover plate

    The new base plate gets a ring around its perimeter for clearance under the four pan head M3 screws into the inserts.

    If the cardboard base is stable enough, we’ll do an acrylic version in cheerful primary colors.

    The LightBurn layout in SVG format 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.
  • Ceiling Lamp Nuts

    Ceiling Lamp Nuts

    While cleaning dead bugs out of the ceiling lamps, we discovered the kitchen light was missing one of the three nuts holding its cover in place. While spare nuts might be available, this seemed like a quicker & easier solution:

    Ceiling Lamp Nut - bottom view - solid model
    Ceiling Lamp Nut – bottom view – solid model

    The stepped interior fits a brass insert with 8-32 threads (not metric, to my utter astonishment) rammed in place with a heat-set tool:

    Ceiling Lamp Nut - insert staking
    Ceiling Lamp Nut – insert staking

    Using the nominal diameters seems to work fine, although I’m sure some finesse will be needed with smaller inserts.

    Printed four just to be sure, rammed three inserts, and they’re ready:

    Ceiling Lamp Nuts - as-built
    Ceiling Lamp Nuts – as-built

    The curved cap matches the original nut through the use of the Chord Equation to get the cap radius as a function of its height (sagitta) & base diameter. Admittedly, it looks kinda grotty with only a dozen layers, but it’s the thought that counts.

    The original nuts are heavy knurled steel and the new ones are cheap plastic, but nobody will ever know:

    Ceiling Lamp Nut - installed
    Ceiling Lamp Nut – installed

    Bonus: now I have two spare steel nuts for the next time …

    The OpenSCAD source code:

    // Nuts for LED ceiling light fixture
    // Ed Nisley KE4ZNU
    // 2024-09-27
    
    KnurlLength = 7.4;
    KnurlOD = 9.0;
    
    CapOD = 9.0;
    CapHeight = 2.0;
    CapRadius = (pow(CapHeight,2) + pow(CapOD,2)/4)/(2*CapHeight);
    echo(CapRadius=CapRadius);
    
    NumSides = 1*(2*3*4);
    $fn = NumSides;
    
    Protrusion = 0.1;
    
    difference() {
        union() {
            intersection() {
                translate([0,0,KnurlLength + CapHeight - CapRadius])
                    sphere(r=CapRadius);
                translate([0,0,KnurlLength])
                    cylinder(d=2*KnurlOD,h=KnurlLength);
            }
    
            cylinder(d=KnurlOD,h=KnurlLength);
    
        }
    
    // Ad-hoc 8-32 brass insert sizes
    
        cylinder(d=5.5,h=8.0);
        cylinder(d=5.9,h=5.7);
        cylinder(d=6.2,h=2.2);
        translate([0,0,-Protrusion])
            cylinder(d=6.2,h=2.2);
    
    }
    
  • LightBurn to PrusaSlicer via Inkscape & OpenSCAD

    LightBurn to PrusaSlicer via Inkscape & OpenSCAD

    I laid out the cart coins in LightBurn for two reasons:

    • It’s easy to use
    • Making laser-cut cart coins is much faster than 3D printing

    The LightBurn layout looks like this:

    Cart coin - LightBurn screen shot
    Cart coin – LightBurn screen shot

    The red lines show cuts through the material to produce the overall shape with a hole for a keyring. The black areas show where the laser will raster-scan the surface at lower power to engrave the cart logo, which consists of vector outlines traced from a PNG file.

    LightBurn can export that design as an SVG drawing with all the elements properly aligned and OpenSCAD can import SVG drawings as 2D shapes, but that file produces only the filled outline of the coin:

    Cart coin - OpenSCAD outline screen shot
    Cart coin – OpenSCAD outline screen shot

    Presumably the other elements are still in there, but they’re hidden inside the outline and can’t be manipulated separately in OpenSCAD.

    OpenSCAD can pick out named elements, groups, or layers from the SVG file, but, alas, the LightBurn SVG file has no named items, as shown in this chunk:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="57.096mm" he
        <path transform="matrix(-1,0,0,1,0,0)" style="stroke:none;fill:#a000a0;fill-rule:evenodd" d="M350.
        <path transform="matrix(-1,0,0,1,0,0)" style="stroke:none;fill:#00a000;fill-rule:evenodd" d="M357.
        <path transform="matrix(-1,0,0,1,0,0)" style="stroke:none;fill:#00a000;fill-rule:evenodd" d="M358.
        <path transform="matrix(-1,0,0,1,0,0)" style="stroke:none;fill:#00a000;fill-rule:evenodd" d="M359.
        <path transform="matrix(-1,0,0,1,0,0)" style="stroke:none;fill:#00a000;fill-rule:evenodd" d="M343.
    </svg>
    

    So I copied that LightBurn design to put the shapes on two different layers marked for Fill processing:

    • The coin-with-handle
    • The cart logo

    It’s not absolutely necessary to use Fill layers, but they make it easier for me to visualize the shapes as solid objects.

    Subtracting the keyring hole and the cart logo from the overall coin-with-handle produces a single shape (with holes) for one material, plus the logo shapes in another material:

    Cart coin - separated - LightBurn screen shot
    Cart coin – separated – LightBurn screen shot

    Put the logo back in position before proceeding:

    Cart coin - overlaid - LightBurn screen shot
    Cart coin – overlaid – LightBurn screen shot

    Unlike the first LightBurn layout, these two layers won’t cut & engrave a cart coin: they define the shapes in such a way that OpenSCAD can turn them into 3D solid models. It’s straightforward to convert between those layouts and they can reside in the same LightBurn file as the original design; just select the one you want to burn or export, as needed.

    Note that LightBurn and Inkscape use the term “layer” in completely different ways:

    • A LightBurn layer defines the laser control settings for all the geometry in that layer
    • An Inkscape layer collects a bunch of shapes into a logical group, but does not otherwise influence them

    In particular, even though we now have objects in two different layers, the exported LightBurn SVG file still has no names for those layers. Fixing that requires a trip through Inkscape.

    Export the filled layout from LightBurn and open (or import) that SVG file with Inkscape, which automagically names the paths:

    Inkscape auto-generated path names
    Inkscape auto-generated path names

    In order from 5 down to 1, those paths correspond to:

    • The cart logo
    • Three go-fast stripes
    • The coin-with-handle outline with various holes

    Create two layers with memorable names, then move the appropriate paths into those layers:

    Cart Coin - Inkscape layer definitions
    Cart Coin – Inkscape layer definitions

    Save the Inkscape layout as an Inkscape SVG file, which will have contents something like this snippet:

    inkscape:groupmode="layer"
    id="layer2"
    inkscape:label="Coin"><path
      transform="matrix(-1.000003,0,0,
      style="display:inline;fill:#a000
      d="m 350.58594,298.00879 0.58716
      id="path1" /></g><g
    inkscape:label="Logo"
    inkscape:groupmode="layer"
    id="layer1"
    transform="translate(0,5.4354331)"
    style="display:inline"><g
      id="g1"
      transform="matrix(1.000003,0,0,1
        transform="scale(-1,1)"
        style="display:inline;fill:#00
        d="m 357.68781,313.02274 h -3.
        id="path2" /><path
        transform="scale(-1,1)"
        style="display:inline;fill:#00
        d="m 358.29401,310.65811 h -3.
        id="path3" /><path
        transform="scale(-1,1)"
        style="display:inline;fill:#00
        d="m 359.19412,307.96756 h -3.
        id="path4" /><path
        transform="scale(-1,1)"
        style="display:inline;fill:#00
        d="m 343.50088,317.48618 c -0.
        id="path5" /></g></g><metadata
    
    

    Note the inkscape:label="Coin" and inkscape:label="Logo" stanzas corresponding to the layers.

    Import that SVG file into OpenSCAD twice, once to extract each layer by name, extrude the 2D shapes to form a solid model with two parts, and give them distinctive colors:

        color("Gray")
        linear_extrude(height=1.6,convexity=10)
            import("/mnt/bulkdata/Project Files/Prusa Mk4/Models/Cart Coin/Cart Coin - Inkscape layers.svg",
                    layer="Coin",convexity=10);
    
        color("Orange")
        linear_extrude(height=1.6,convexity=10)
            import("/mnt/bulkdata/Project Files/Prusa Mk4/Models/Cart Coin/Cart Coin - Inkscape layers.svg",
                    layer="Logo",convexity=10);
    

    Which looks like this:

    Cart coin - OpenSCAD layer import
    Cart coin – OpenSCAD layer import

    The cart logo exactly fills the matching holes in the coin shape, but because it’s a different OpenSCAD object, it won’t merge with its surroundings.

    Export that model in 3mf format, because it seems better than stl for multi-material models, import it into PrusaSlicer, and get a helpful alert:

    PrusaSlicer multi-material alert
    PrusaSlicer multi-material alert

    Yes, do that thing, then assign the appropriate filament to each object:

    PrusaSlicer cart coin preview
    PrusaSlicer cart coin preview

    Arrange half a dozen instances on the platform and make yourself a set of cart coins:

    Blue cart coins on platform
    Blue cart coins on platform

    Now, the obvious question: “Why not just do this in Inkscape, set up all the layers for OpenSCAD, then also export the geometry to LightBurn?”

    LightBurn recently announced that Version 1.7 will be the last to support Linux, because Linux amounts to 1% of their users and we just don’t produce enough revenue to justify any effort to support us.

    I don’t see standing up a Windows 11 box in the Basement Shop just to drive the laser and there is no way I’ll start running Windows as my daily driver just to design layouts in LightBurn. So, yes, I expect over the next year I’ll be transitioning away from LightBurn to Inkscape + Visicut, even though the latter has some rough edges.