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.

Category: Home Ec

Things around the home & hearth

  • Large Smashed Glass Coaster

    Large Smashed Glass Coaster

    Those of long memory will recall our vermiculture setup in the basement that turns kitchen scraps into plant food. We accumulate scraps in plastic milk jugs, which jugs get recycled after they become grody.

    I finally made a decorative coaster to keep the sometimes-wet jug off the counter:

    Printed Fragment Coaster 165mm - in use
    Printed Fragment Coaster 165mm – in use

    This used several of the larger smashed glass fragments from the collection:

    Fragments 165mm square - scan sample
    Fragments 165mm square – scan sample

    They all fit inside a 165 mm square, with the conformal perimeter disguising the outline:

    Printed Fragment Coaster 165mm - overview
    Printed Fragment Coaster 165mm – overview

    I printed the frame with the same blue PETG-CF that leaked epoxy the last time around. Using the correct filament setting (Extrusion Multiplier = 1.0) produced an epoxy-tight frame:

    Printed Fragment Coaster 165mm - epoxy filling
    Printed Fragment Coaster 165mm – epoxy filling

    The overall process:

    • Run a bead of epoxy around the edge of each recess
    • Fill in the center with a thin layer
    • Squish the metallized paper reflector in place starting from one end to ease the bubbles out
    • Cover the reflector with another layer of epoxy
    • Lay the glass fragment down starting at one end
    • Press gently down to get all the bubbles out
    • Cover the glass with more epoxy

    I dripped enough epoxy on each fragment to form a meniscus without having it go over the rim:

    Printed Fragment Coaster 165mm - epoxy meniscus
    Printed Fragment Coaster 165mm – epoxy meniscus

    The Basement Shop temperature is just over 60 °F, so I put a heating pad in a huge ziplock bag, laid an aluminum sheet atop it as a heat spreader, put some waxed paper on the aluminum just in case, then did the filling described above:

    Printed Fragment Coaster 165mm - warming setup
    Printed Fragment Coaster 165mm – warming setup

    A cardboard box on top helped the heating pad keep the coaster at a uniform 85 °F, slightly warmer than the epoxy instructions recommend, but it cured overnight with a wonderfully shiny surface.

    Now that I have the process down, making glittery coasters is surprisingly easy.

  • Bird Feeder Tray Mount

    Bird Feeder Tray Mount

    The mixed flock attending the bird feeder in the back yard scatters enough seeds to attract the deer, so I added a tray underneath to catch the overspray:

    Bird Feeder Tray Mount - installed
    Bird Feeder Tray Mount – installed

    Well, two trays, because it took a couple of iterations to make the solid model match reality:

    Bird Feeder Tray Mount - show layout
    Bird Feeder Tray Mount – show layout

    The n-1 iteration was Close Enough™ and two trays are obviously better than one.

    The “trays” are stray lids from the six gallon buckets we use for many purposes, including root-cellaring the vegetable garden harvest. The lid’s solid model was straightforward:

    Bird Feeder Tray Mount - lid model
    Bird Feeder Tray Mount – lid model

    Removing the lid from a solid block produces the most complex part of the mount:

    Bird Feeder Tray Mount - mount layout
    Bird Feeder Tray Mount – mount layout

    An aluminum plate on the outside (the gray slab in the overall view above) distributes the strain from the two M6 screws across the block.

    A smaller block on the inside of the lid has a pair of square nuts:

    Bird Feeder Tray Mount - segment layout
    Bird Feeder Tray Mount – segment layout

    All three parts build from their flattest side:

    Bird Feeder Tray Mount - build layout
    Bird Feeder Tray Mount – build layout

    The downward facing clamp arch in the main block didn’t need support, but the square nut sockets in the segment definitely came out better with little support blocks inside; PrusaSlicer does a good job with most support structures.

    The n-1 iteration used M6 rivnuts that were slightly too long after making the lid model match reality, so I switched to square nuts. The OpenSCAD code calculates the segment block length to match the actual screws, but 75 mm M6 screws and square nuts are barely long enough.

    I clamped the outer block to the lid as a drill guide for the first hole, then pinned the block with a screw to ensure it didn’t slip while drilling the second hole:

    Bird Feeder Tray Mount - drilling setup
    Bird Feeder Tray Mount – drilling setup

    Those were freehanded in the drill press at low speed with serious concentration; some things you just gotta do that way.

    The mixed flock overwhelmingly approves the trays, to the extent a dozen birds clamor to use them: definitely a crowd-pleaser!

    I’m certain you can buy pole-mounted trays, but what’s the fun in that?

    The OpenSCAD source code as a GitHub Gist:

    // Bird feeder tray mount
    // Ed Nisley – KE4ZNU
    // 2025-11-06
    include <BOSL2/std.scad>
    Layout = "Show"; // [Build,Show,Lid,Mount,Segment,Nut]
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    HoleWindage = [0.2,0.2,0.2];
    Protrusion = 0.1;
    NumRibs = 12; // stiffening ribs
    NumSides = 8*NumRibs;
    $fn=NumSides;
    Gap = 5.0;
    WallThick = 9.0; // robust walls
    Kerf = 1.0; // clamp cut
    TapeThick = 0.5; // wrap around pole
    LidOD = 12; // main diameter in inches
    PoleOD = 1*INCH;
    PlateThick = 2.0; // backing plate for clamp
    Screw = [6.0,12.0,6.0]; // thread OD, washerOD, head
    ScrewLength = 75.0;
    ScrewOC = 60.0; // chosen to clear stiffening ribs in lid
    LidLayers = [ // bottom to top, ID = 0 means solid disk, LENGTH = exterior measurement
    [0,(LidOD-2*(3/8))*INCH,Protrusion], // 0 – below zero to prevent Z fighting
    [0,(LidOD-2*(3/8))*INCH,(3/8)*INCH], // 1 – base inside bucket
    [0,(LidOD+2*(1/8))*INCH,(1/8)*INCH], // 2 – flange
    [(LidOD-2*(1/2))*INCH,LidOD*INCH,(7/8)*INCH], // 3 – sealing ring
    ];
    LidOAH = LidLayers[1][LENGTH] + LidLayers[2][LENGTH] + LidLayers[3][LENGTH];
    LidTopDepth = (3/4)*INCH; // from highest part of interior
    MountBlockWidth = ScrewOC + 2*WallThick;
    BaseSagitta = LidLayers[1][OD]/2 – sqrt((LidLayers[1][OD]/2)^2 – (MountBlockWidth^2)/4);
    echo(BaseSagitta=BaseSagitta);
    PoleOffset = BaseSagitta + ((LidLayers[2][OD] – LidLayers[1][OD])/2) + WallThick + PoleOD/2;
    MountBlock = [PoleOffset + PoleOD/2 + WallThick – PlateThick,MountBlockWidth,LidOAH];
    echo(MountBlock=MountBlock);
    SegBlockOffset = ScrewLength – MountBlock.x – PlateThick; // assumes recessed
    SegmentBlock = [2*SegBlockOffset,MountBlock.y,LidTopDepth];
    Rib = [2*6.0,5.0,LidTopDepth]; // lid stiffening ribs
    RibAlign = 0 * 180/NumRibs; // position ribs wrt mount
    EdgeRadius = 3.0;
    //—–
    // Rivnut
    // The model collects all the magic numbers right here
    /*
    RivnutOAL = 15.0;
    module Rivnut() {
    union() {
    cyl(1.6,d=13.0,circum=true,anchor=BOTTOM);
    cyl(RivnutOAL,d=9.0,circum=true,anchor=BOTTOM);
    }
    }
    */
    //—–
    // Square nut
    // The model collects all the magic numbers right here
    NutOAL = 5.0;
    module SquareNut() {
    cuboid([10.0,10.0,5.0],anchor=BOTTOM);
    }
    //—–
    // Bucket lid
    // Centered at XY=0, Z=0 at top of exterior flange
    module BucketLid(Interior=true,Expand=false) {
    render()
    union() {
    down(LidLayers[2][LENGTH])
    cyl(LidLayers[1][LENGTH],d=LidLayers[1][OD],anchor=TOP);
    cyl(LidLayers[2][LENGTH],d=LidLayers[2][OD],anchor=TOP);
    if (Interior) {
    if (false)
    down(Expand ? Protrusion : 0)
    tube(LidLayers[3][LENGTH] + (Expand ? 2*Protrusion : 0),
    id=LidLayers[3][ID],od=(Expand ? 2 : 1)*LidLayers[3][OD],anchor=BOTTOM);
    else
    difference() {
    cyl(LidLayers[3][LENGTH] + (Expand ? 2*Protrusion : 0),
    d=(Expand ? 2 : 1)*LidLayers[3][OD],anchor=BOTTOM);
    up(LidLayers[3][LENGTH] – LidTopDepth)
    cyl(LidTopDepth + (Expand ? 2*Protrusion : 0),
    d=LidLayers[3][ID],anchor=BOTTOM);
    }
    up(LidLayers[3][LENGTH] – LidTopDepth)
    for (i=[0:(NumRibs – 1)])
    zrot(i*360/NumRibs + RibAlign)
    right(LidLayers[3][ID]/2)
    cuboid(Rib,anchor=BOTTOM,rounding=1,edges="Z");
    }
    else
    down(Expand ? Protrusion : 0)
    cyl(LidLayers[3][LENGTH] + (Expand ? 2*Protrusion : 0),
    d=(Expand ? 2 : 1)*LidLayers[3][OD],anchor=BOTTOM);
    }
    }
    // Mount clamp
    module Mount() {
    render()
    difference() {
    cuboid(MountBlock,anchor=BOTTOM+LEFT,rounding=EdgeRadius,edges="X");
    left(LidLayers[1][OD]/2 – BaseSagitta)
    up(LidLayers[1][LENGTH] + LidLayers[2][LENGTH])
    BucketLid(Interior=false);
    right(PoleOffset) {
    cyl(3*MountBlock.z,d=(PoleOD + HoleWindage.x + 2*TapeThick),circum=true,anchor=CENTER);
    cuboid([Kerf,2*MountBlock.y,3*MountBlock.z]);
    }
    if (false)
    right(MountBlock.x – PlateThick)
    cuboid(3*[PlateThick,MountBlock.y,MountBlock.z],anchor=LEFT);
    up(LidOAH – LidLayers[3][LENGTH]/2)
    for (j=[-1,1])
    fwd(j*ScrewOC/2) {
    cyl(ScrewLength,d=Screw[ID] + HoleWindage.x,circum=true,orient=RIGHT,anchor=BOTTOM,$fn=6,spin=180/6);
    if (false)
    right(MountBlock.x + Protrusion)
    cyl(Screw[LENGTH] + Protrusion,d=Screw[OD] + HoleWindage.x,circum=true,
    orient=LEFT,anchor=BOTTOM,$fn=12,spin=180/12);
    }
    }
    }
    // Nut block segment inside lid
    module NutSegment() {
    render()
    difference() {
    cuboid(SegmentBlock,anchor=BOTTOM,rounding=EdgeRadius,edges="X");
    down(LidLayers[3][LENGTH] – LidTopDepth)
    left(LidLayers[1][OD]/2 – BaseSagitta)
    BucketLid(Interior=true,Expand=true);
    up(LidTopDepth – LidLayers[3][LENGTH]/2)
    for (j=[-1,1])
    fwd(j*ScrewOC/2) {
    left(SegmentBlock.x/2)
    cyl(ScrewLength,d=Screw[ID],circum=true,anchor=BOTTOM,$fn=6,spin=180/6,orient=RIGHT);
    left(SegmentBlock.x/2)
    yrot(90)
    SquareNut();
    }
    }
    }
    //—–
    // Build things
    if (Layout == "Lid")
    BucketLid();
    if (Layout == "Mount")
    Mount();
    if (Layout == "Segment")
    NutSegment();
    if (Layout == "Nut")
    Rivnut();
    if (Layout == "Show") {
    down(LidLayers[1][LENGTH] + LidLayers[2][LENGTH]) {
    Mount();
    color("Orange",0.5)
    up(LidOAH – LidLayers[3][LENGTH]/2)
    right(MountBlock.x + PlateThick)
    for (j=[-1,1])
    fwd(j*ScrewOC/2)
    cyl(ScrewLength,d=Screw[ID],circum=true,orient=LEFT,anchor=BOTTOM);
    }
    up(LidLayers[3][LENGTH] – LidTopDepth)
    NutSegment();
    color("Gray",0.4)
    right(PoleOffset)
    cylinder(3*MountBlock.z,d=(PoleOD),anchor=CENTER);
    color("Gray",0.4)
    left(LidLayers[1][OD]/2 – BaseSagitta)
    BucketLid();
    color("White",0.7)
    down(LidLayers[1][LENGTH] + LidLayers[2][LENGTH])
    right(MountBlock.x + 2*PlateThick)
    difference() {
    cuboid([PlateThick,MountBlock.y,MountBlock.z],anchor=BOTTOM+LEFT,rounding=EdgeRadius,edges="X");
    up(LidOAH – LidLayers[3][LENGTH]/2)
    for (j=[-1,1])
    fwd(j*ScrewOC/2)
    cyl(ScrewLength,d=Screw[ID],circum=true,orient=RIGHT,anchor=CENTER);
    }
    }
    if (Layout == "Build") {
    render()
    union() {
    difference() {
    left(MountBlock.z + Gap/2)
    up(PoleOffset – Kerf/2)
    yrot(90)
    Mount();
    cuboid([3*MountBlock.z,2*MountBlock.y,3*MountBlock.x],anchor=TOP);
    }
    render()
    right(Gap/2)
    intersection() {
    up(MountBlock.x)
    yrot(90)
    Mount();
    up(MountBlock.x – PoleOffset)
    right(MountBlock.z/2)
    cuboid([2*MountBlock.z,2*MountBlock.y,MountBlock.x],anchor=TOP);
    }
    right(2*MountBlock.z – BaseSagitta)
    up(SegmentBlock.x/2)
    yrot(-90)
    NutSegment();
    }
    }

  • Dryer Vent Filter Snout: TPU Warp

    Dryer Vent Filter Snout: TPU Warp

    Making the clothes dryer vent filter snout from TPU did not work nearly as well as I expected:

    Clothes Dryer Vent Filter Snout - TPU warp
    Clothes Dryer Vent Filter Snout – TPU warp

    I think that’s the result of applying heat to a slightly compressed rear wall made of bendy plastic.

    Making it from much stiffer white PETG required moving the front mounting tabs to the middle to allow enough bendiness to snap them into the vent:

    Clothes Dryer Vent Filter Snout - OpenSCAD plan
    Clothes Dryer Vent Filter Snout – slicer

    Although both pieces barely fit on the MK4’s platform, I made the upper ring first to verify the fit:

    Clothes Dryer Vent Filter Snout - slicer
    Clothes Dryer Vent Filter Snout – slicer

    If I ever make another, it’ll print as a single top-side-down unit, because the dimensions are now spot on.

    From outside, it looks just like the TPU version:

    Clothes Dryer Vent Filter Snout - PETG installed
    Clothes Dryer Vent Filter Snout – PETG installed

    The snood is a cheesecloth tube with shock cord holding it to the snout.

  • Humidifier Caster Feet

    Humidifier Caster Feet

    The ancient and muchrepaired Sears humidifier works better in its new location across the living room with its front raised a few millimeters, which may have something to do with its plastic housing supporting a pair of heavy water containers for a few decades.

    After fiddling around with shims to find the proper height, these feet descended from the Husky workbench feet:

    Humidifier Caster Feet - installed
    Humidifier Caster Feet – installed

    They’re glued up from 3 mm plywood sitting on a 1 mm layer of cork:

    Humidifier Caster Feet - clamping
    Humidifier Caster Feet – clamping

    The humidifier seems much happier with its casters 4 mm above the floor. Seems awfully fussy to me, but there’s no arguing with success.

  • DIY Birdsavers

    DIY Birdsavers

    Mary counts birds for Project Feederwatch and the feeder goes up at Halloween, whereupon birds begin smashing against the windows. Having bought a lifetime supply of paracord for this purpose on our previous house, I made a DIY Birdsaver for the rear windows:

    DIY Birdsavers - interior view
    DIY Birdsavers – interior view

    This project was tremendously simplified by discovering the soffits consist of molded PVC sheets having exactly the proper 4 inch spacing and a convenient lip perfectly suited to capture the knot:

    DIY Birdsavers - soffit mount
    DIY Birdsavers – soffit mount

    So far, no thuds …

  • Garden Knife Sheath Redux

    Garden Knife Sheath Redux

    A knife found in Mary’s Bucket o’ Gardening Gear was in need of a sheath:

    Serrated Garden Knife
    Serrated Garden Knife

    Unlike the time before or the time before that, a few minutes with LightBurn laid out the overall pattern:

    Garden Knife Sheath - LightBurn layout
    Garden Knife Sheath – LightBurn layout

    The knife’s silhouette came from a few minutes with GIMP, because cleaning up the edges on a graphics tablet is easier than fiddling with precise spline curves. Export the selection as an SVG, import into LightBurn, set to Fill, and Fire The Laser:

    Garden knife sheath
    Garden knife sheath

    The upper block in the LightBurn layout is an oversized rectangle so I could cut that out first, stick craft adhesive on both sides, trim the edges, drop it back into the hole, then cut the middle part of the sheath.

    It’s made of recycled through-dyed chipboard and it won’t last forever, but that’s not a problem because these things tend to wander off before they disintegrate.

    I must do a few more for the other garden bucket, but those should be straightforward.

  • Silicone Handle Wrap

    Silicone Handle Wrap

    The common fate of all “soft touch” silicone handles is to become sticky and gooey. While some goo may be removable, I’ve found that wrapping self-bonding silicone tape around the mess both encapsulates it and maintains the grippiness of the original silicone.

    The most recent casualty is the decade-old ceramic crysknife I returned to service while the rest of the knives were being sharpened:

    Ceramic knife - silicone handle wrap
    Ceramic knife – silicone handle wrap

    While I was at it, I added griptivity to the leaf blower handle:

    Leaf blower - silicone handle wrap
    Leaf blower – silicone handle wrap

    Long years ago, before getting transparent silicone tape, I’d wrapped a kitchen slotted spoon:

    Kitchen spoon - silicone handle wrap
    Kitchen spoon – silicone handle wrap

    Stipulated: Butt-ugly and built to stay that way.

    Oddly, the handle on the matching spatula / scraper remains non-gooey to this day.

    Should you care more about form than function, this repair is not the one you seek …