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: Machine Shop

Mechanical widgetry

  • Layered Paper: Cutting and Assembling the Cornell Painted Warblers

    Layered Paper: Cutting and Assembling the Cornell Painted Warblers

    With all the layers laid out, duplicating and plunking one in the middle of the LightBurn workspace looks like this:

    Page 4 - Layer 1 - Lightburn centered layout
    Page 4 – Layer 1 – Lightburn centered layout

    In Absolute Coordinates mode the laser will cut it at the center of the platform, so put a sheet right there:

    Print vs cut - 100.3pct plain paper - setup
    Print vs cut – 100.3pct plain paper – setup

    The Position Laser tool puts the laser head at a selected location in the design, with the picture showing it at the center of the upper right target. The trick is to slide the paper on the platform to put that target directly under the red-dot pointer:

    Print vs cut - 100.3pct plain paper - UR align
    Print vs cut – 100.3pct plain paper – UR align

    I occasionally fire a test pulse to verify the CO₂ laser hits the red dot:

    Red dot vs printed target vs laser spot alignment
    Red dot vs printed target vs laser spot alignment

    Do the same for the target in the lower left corner, rotating the paper around the upper right target, and iterating until both targets match.

    Because the printer does not produce accurately sized output, this can happen:

    Print vs cut - 100.3pct plain paper - LR
    Print vs cut – 100.3pct plain paper – LR

    You’ll get a hint of the problem when it’s impossible to put the targets under the the laser head at the lower targets, although it may look close enough to work.

    That offset was on plain paper with the output scaled by 100.3% vertically. Applying the same scaling (to the Happy Bird picture, but with the same page template) and printing on Art Cover paper produces this result:

    Print vs cut - 100.3pct Art Cover - LR
    Print vs cut – 100.3pct Art Cover – LR

    Eventually, I can find a suitable scale factor to make the printed image come out right and the cuts align properly:

    Page 5 - Test piece - as cut
    Page 5 – Test piece – as cut

    Those tenuous paper strands show why I couldn’t use the Letter page fixture and had to cut the sheets directly on the honeycomb: the weight of the uncut sections distorted the remaining sheet beyond belief. The squat silver cylinders in the pictures are neodymium magnets holding the paper flat on the honeycomb.

    All the other layers have trivial positioning, because the cuts need not line up with anything on the sheet:

    Layered paper alignment
    Layered paper alignment

    Just frame the first layout, center the sheet around it, set the MDF stops to kiss the edges of the paper, and all the other sheets will come out just fine.

    One side effect of all this cutting is the happiest scrap bin ever:

    Happy Laser Scrap Bin
    Happy Laser Scrap Bin

    With all the layers cut out, assemble them face-down in the gluing fixture, align the black mask on the front by hand, put the stack into a suitable frame, and it’s ready to show off:

    Cornell Warblers - page 4
    Cornell Warblers – page 4

    That wasn’t exactly easy, but next time I can make different mistakes.

  • Layered Paper: Aligning and Layering the Cornell Painted Warblers

    Layered Paper: Aligning and Layering the Cornell Painted Warblers

    Processing the original PDF of a Cornell Painted Warbler produces a PNG image:

    Page 4 - butterfly unmasked
    Page 4 – butterfly unmasked

    And an SVG file with shapes matching the regions to be cut out:

    Page 4 - black mask
    Page 4 – black mask

    Both of those derive from the same PDF page, cropped to emphasize the bird, then scaled to match the 172×220 mm rectangle in the middle of the LightBurn template corresponding to the alignment fixture:

    Printed sheet template - 8×10 - 172x220
    Printed sheet template – 8×10 – 172×220

    A key point: the blue outline around the image must be centered within the red outline marking the sheet cutout, because that dramatically simplifies the overall alignment process.

    Protip: Crop the image in GIMP with a fixed aspect ratio of 172:220 before scaling the result to match the 172×220 frame, then derive both the PNG and SVG from the result.

    The alert reader will recall the SVG shapes exclude the 6 pixel = 0.5 mm border closing the outlines, so the overall SVG size is 1 mm smaller than the PNG image. This will not be a problem, for reasons to become obvious.

    Because Inkscape can handle both SVG shapes and color PNG images (LightBurn turns them into grayscale):

    • Export the LightBurn template as an SVG
    • Open with Inkscape
    • Make the Tool layer elements visible
    • Import the PNG

    Without further ado, the PNG is automagically centered in both the blue and red rectangles:

    Page 4 - Layer 1 - Inkscape print layout
    Page 4 – Layer 1 – Inkscape print layout

    Print it, measure the vertical and horizontal distances between the corner target centers, scale the overall image to make the printed result come out exactly right, then iterate until satisfied. Scaling it 100.3% vertically worked for what’s called Art Cover paper printed with Stationery High Quality in an Epson ET-3830 printer. Your mileage will be different.

    Protip: Save the unscaled page as an Inkscape SVG, because the scale factor(s) depend on the paper / print quality setting / moon phase and you will print it several times under different conditions.

    In LightBurn:

    • Tweak a copy of the sheet template to eliminate the corner holes & suchlike
    • Import the Black Mask SVG into LightBurn
    • Drag-n-drop it at the center of the template
    • Set the speed / power to cut black Art Cover paper

    Which becomes the Black Mask layer:

    Page 4 - Layer 0 - Lightburn layout
    Page 4 – Layer 0 – Lightburn layout

    The alert reader will note the slightly different template layout: it’s been undergoing continuous process improvement and I’m not re-capturing all the details.

    The Black Mask SVG contains all the shapes-to-be-cut, so it forms the basis for all the sheets under the top mask. Drag-n-drop a copy of the Black Mask SVG at the center of a copy of the template, ungroup it, delete the outlines of all the shapes on the printed layer, and set the speed / power for ordinary Art Cover paper:

    Page 4 - Layer 1 - Lightburn layout
    Page 4 – Layer 1 – Lightburn layout

    The shapes on each layer will be the same as the one above it, minus whatever shapes have the color of that layer. After you finish each layer, select all its shapes, duplicate them, drop them at the center of the next sheet template, and iterate.

    Or just set up a line of templates spaced (say) 240 mm apart using the Grid Array tool:

    Page 4 - All layers - LightBurn layout
    Page 4 – All layers – LightBurn layout

    If you’re so inclined, set up their binary layer number holes:

    Layered Paper cutting fixture - layer binary code
    Layered Paper cutting fixture – layer binary code

    Then:

    • Select the finished shapes in one layer
    • Duplicate them (Ctrl-D)
    • Use the Numeric Edits toolbar to subtract 240 mm from their current location
    • Which causes them to appear exactly centered in the next template to the right without any drag-n-drop action

    Because my CO₂ laser has a Ruida controller and homes in the rear-right corner:

    • X coordinates increase to the left
    • Y coordinates increase to the front

    You can get used to anything if you do it enough and your coordinates will likely be different.

    Protip: Adding a description of each layer’s contents / color will be of great assistance when you select the paper.

    The end result of all that will be a set of sheet layouts ready to cut:

    • Select one entire sheet template + bird shapes
    • Duplicate it with Ctrl-D
    • Center the dupe on the LightBurn workspace with P (not Ctrl-P, which will send it to your printer)

    The next piece of the puzzle: correctly aligning a Letter piece of paper with those shapes …

  • Layered Paper: Masking the Cornell Painted Warblers

    Layered Paper: Masking the Cornell Painted Warblers

    After getting better at aligning printed sheets for laser cuttery and learning how to use GIMP’s Path Edit tool, a pair of Cornell Painted Warblers emerged!

    We call this one “Happy Bird”:

    Cornell Warblers - page 5
    Cornell Warblers – page 5

    And his companion “Pensive Bird”:

    Cornell Warblers - page 4
    Cornell Warblers – page 4

    The page numbers refer to the PDF file containing the outlines of all six birds.

    The wing feathers and butterfly require finer resolution than the black mask layer allows, so the first layer is printed on white paper. I put the berries and nut-like objects on that layer, too, mostly to reduce the number of layers.

    After considerable fumbling, it turns out GIMP provides a straightforward way to create the outlines required for the top Black Mask, from which all the other layers descend.

    A closeup of Happy Bird’s head as imported into GIMP from the PDF at 300 DPI = 11.8 pixel/mm:

    Page 5 - PDF line - detail
    Page 5 – PDF line – detail

    Because the Cornell Warblers were intended as a paint-by-number project, the PDF has (gray) color numbers in (most of the) regions. Selecting the numbers with GIMP’s Select by Color tool and hitting Delete clears the region for Bucket Fill colors copied from the key sheet with the Color Picker tool:

    Page 5 - Inkscape print layout
    Page 5 – Inkscape print layout

    I cropped the images to emphasize the birds and scaled the result to fit the 8×10 inch frame size. The picture is 172×220 mm within the red 200×250 mm frame cut from Letter size sheets of Art Cover paper stock. The corner targets come into play while aligning the paper with the laser pattern.

    Creating the Black Mask layer also starts from the cropped / scaled image. Select the black lines by color, then Grow the selection by 7 pixels = 0.6 mm to make the selection about 1.5 mm wide:

    Page 5 - PDF line - 1.5mm selection
    Page 5 – PDF line – 1.5mm selection

    Use Quick Mask to edit the selection. For example, I reduced the eye to a cutout through the mask revealing the white spot on the printed layer:

    Page 5 - PDF line - inverted quick mask
    Page 5 – PDF line – inverted quick mask

    Eventually the selection will neatly bracket the borders between the colors:

    Page 5 - PDF line - fill colors - mask overlay
    Page 5 – PDF line – fill colors – mask overlay

    The black legs and feet must be edited down to their original size, as became obvious on the first iteration:

    Page 5 - Test piece - stack oblique view
    Page 5 – Test piece – stack oblique view

    The fixed-up Quick Mask looks like this:

    Page 5 - PDF line - selection - printed areas
    Page 5 – PDF line – selection – printed areas

    The mask includes a 6 pixel = 0.5 mm border line around the perimeter of the image which serves as the outer edge of the cut-out areas and helps match the selections to the image.

    The process of growing & tweaking the selection will create orphan pixels:

    Page 5 - PDF line - orphan pixel selection
    Page 5 – PDF line – orphan pixel selection

    Each orphan pixel becomes a tiny triangle when imported into LightBurn:

    Page 5 - PDF line - orphan pixel - LighBurn vectors
    Page 5 – PDF line – orphan pixel – LighBurn vectors

    You’ll first notice those when the laser hesitates while cutting the outlines, which may overcook the adjacent paper. I cannot reliably detect these other than by watching the laser, because a single pixel is simply too small to see on-screen at normal zoom sizes. You can delete them in the LightBurn file or, if you prefer a single source of truth, in GIMP to regenerate the whole thing.

    The end result of all this is a single, rather complex, Selection that you must convert into a Path, which you then export to an SVG file and import into LightBurn for laser cuttery.

    Next: Aligning and layering

  • HQ Sixteen: Improved Anchor

    HQ Sixteen: Improved Anchor

    The original anchor / weight keeping the HQ Sixteen from rolling away suffered a disastrous fall, so I conjured a much better-looking replacement from the vasty digital deep:

    HQ Sixteen - improved anchor
    HQ Sixteen – improved anchor

    The handle and fancy nut came from the deceased pepper mill, sitting on laser-cut acrylic in a 3D printed base, with a drawer liner disk peeking out from underneath.

    The orange disk in the solid model represents the steel slug harvested from the old anchor:

    HQ Sixteen Anchor - solid model - Show view
    HQ Sixteen Anchor – solid model – Show view

    A ring of hot-melt glue under the weight keeps it from rattling around in there, with the snug-fitting central post encouraging good positioning. I made the acrylic lid sit flush with the top of the base by the simple expedient of running another ring of glue around it, plunking the base + weight atop it on a flat surface, then taking a deep breath while the glue solidified. The nut & screw thus compress a solid stack of acrylic + glue + steel + glue + PETG-CF, rather than just parts flying in formation.

    The OpenSCAD source code also produces a pair of outlines for laser-cutting the adhesive sheet and acrylic, suitable for export to an SVG file:

    HQ Sixteen Anchor - solid model - cuts
    HQ Sixteen Anchor – solid model – cuts

    They’re offset inward by amounts appropriate for my CO₂ laser:

    if (Layout == "Cuts") {
      left(BaseOD/2 + Gap)
        offset(r=-1.0)
          circle(d=BaseOD);
      right(Cap[OD]/2 + Gap)
        offset(r=-0.2/2)
          projection()
            tube(1.0,id=Cap[ID],od=Cap[OD],anchor=BOTTOM);
    }
    

    It might be prudent to apply those offsets to the original outlines in LightBurn or whatever you use for lasering.

    The OpenSCAD source code as a GitHub Gist:

    // Anchor block for HQ Sixteen
    // Ed Nisley – KE4ZNU
    // 2026-09-29
    include <BOSL2/std.scad>
    Layout = "Show"; // [Show,Build,Cuts]
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    Gap = 10.0/2; // build platform minimum spacing
    HoleWindage = 0.2;
    Protrusion = 0.1;
    NumSides = 8*3*2*4;
    $fn=NumSides;
    // Sizes
    Screw = [5.5,25.5,5.0]; // 10-24 screw + washer holding it together
    Weight = [11.0,80.0,11.5]; // stamped steel slug
    Cap = [26.0,Weight[OD],5.5]; // acrylic disk with handle hole
    BaseFloor = 10.0;
    BaseOD = 90.0; // printed anchor
    Spacing = 25.0; // Show view separation
    //———-
    // Model things
    module Housing() {
    tube(Screw[LENGTH],id=Screw[OD],od=BaseOD,anchor=BOTTOM) position(TOP) {
    tube(Weight[LENGTH],id=Screw[ID],od=Weight[ID],anchor=BOTTOM); // weight bushing
    tube(BaseFloor – Screw[LENGTH],id=Screw[ID],od=BaseOD,anchor=BOTTOM) position(TOP)
    tube(Cap[LENGTH] + Weight[LENGTH],id=Cap[OD],od=BaseOD,anchor=BOTTOM);
    }
    }
    //———-
    // Build things
    if (Layout == "Show") {
    Housing();
    color("Orange",0.7)
    up(BaseFloor + Spacing)
    tube(Weight[LENGTH],id=Weight[ID],od=Weight[OD],anchor=BOTTOM);
    color("Gray",0.8)
    up(BaseFloor + 2*Weight[LENGTH] + Spacing)
    tube(Cap[LENGTH],id=Cap[ID],od=Cap[OD],anchor=BOTTOM);
    }
    if (Layout == "Cuts") {
    left(BaseOD/2 + Gap)
    offset(r=-1.0)
    circle(d=BaseOD);
    right(Cap[OD]/2 + Gap)
    offset(r=0.2/2)
    projection()
    tube(1.0,id=Cap[ID],od=Cap[OD],anchor=BOTTOM);
    }
    if (Layout == "Build") {
    Housing();
    }

  • HQ Sixteen: Improved Fabric Rod Bushings

    HQ Sixteen: Improved Fabric Rod Bushings

    Descending from the previous bearings / sleeves / bushings, I added a rib to hold them in place as the rod slides back and forth while fiddling with fabric:

    HQ Sixteen - Rod Bushing - rib retainer - solid model - build view
    HQ Sixteen – Rod Bushing – rib retainer – solid model – build view

    An idealized serving suggestion:

    HQ Sixteen - Rod Bushing - rib retainer - solid model - show view
    HQ Sixteen – Rod Bushing – rib retainer – solid model – show view

    Which might count as the “better design” I expected it would need.

    They’re still almost invisible in use:

    HQ Sixteen - Rod Bushing - rib retainer
    HQ Sixteen – Rod Bushing – rib retainer

    Which is as it should be: inconspicuous, no more black dust, and E-Z rotation.

    The modified OpenSCAD source code is added to the original GitHub Gist:

    // Bushing for HQ Sixteen table rods
    // Ed Nisley – KE4ZNU
    // 2026-02-20
    // 2026-09-29 add retaining rib
    include <BOSL2/std.scad>
    Layout = "Show"; // [Show,Build]
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    HoleWindage = 0.2;
    Protrusion = 0.1;
    NumSides = 8*3*2*4;
    $fn=NumSides;
    Rod = [25.0,28.7,100.0]; // very short rod
    Sleeve = [Rod[OD] + 0.3,31.2 – 0.2,9.0]; // LENGTH = overall
    Rim = [Sleeve[ID],Sleeve[OD] + 6.0,0.6];
    LockRing = [Sleeve[ID],Sleeve[OD] + 2*(1.0),4.0]; // locks sleeve on plate
    IdlerLength = 15.0; // far right end of rods
    NumSlots = 2*4;
    Kerf = 1.0;
    Gap = 5.0;
    module Bushing(oal,lk=false) {
    difference() {
    union() {
    tube(oal,id=Sleeve[ID],od=Sleeve[OD],anchor=BOTTOM);
    tube(Rim[LENGTH],id=Rim[ID],od=Rim[OD],anchor=BOTTOM);
    if (lk)
    up(oal)
    tube(LockRing[LENGTH],id=LockRing[ID],od=LockRing[OD],chamfer=LockRing[LENGTH]/3,anchor=TOP);
    }
    for (a=[0:NumSlots-1])
    zrot(a*360/NumSlots)
    up(oal/4 + Rim[LENGTH])
    right(Sleeve[ID]/2)
    cuboid([Sleeve[OD],Kerf,oal],anchor=BOTTOM);
    }
    }
    //—–
    // Build things
    if (Layout == "Show") {
    color("Gray",0.5)
    xcyl(Rod[LENGTH],d=Rod[OD]);
    right(Rod[LENGTH]/3)
    zrot(180) yrot(90)
    Bushing(Sleeve[LENGTH]);
    left(Rod[LENGTH]/3)
    yrot(90)
    Bushing(IdlerLength,lk=true);
    }
    if (Layout == "Build") {
    right(Rim[OD]/2 + Gap/2)
    Bushing(Sleeve[LENGTH]);
    left(Rim[OD]/2 + Gap/2)
    Bushing(IdlerLength,lk=true);
    }
    // Bearing sleeve for HQ Sixteen table rods
    // Ed Nisley – KE4ZNU
    // 2026-02-20
    include <BOSL2/std.scad>
    Layout = "Show"; // [Show,Build]
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    HoleWindage = 0.2;
    Protrusion = 0.1;
    NumSides = 8*3*2*4;
    $fn=NumSides;
    Rod = [25.0,28.7,100.0]; // very short rod
    Sleeve = [Rod[OD] + 0.3,31.2 – 0.2,9.0]; // LENGTH = overall
    Rim = [Sleeve[ID],Sleeve[OD] + 6.0,0.6];
    IdlerLength = 15.0;
    NumSlots = 2*4;
    Kerf = 1.0;
    Gap = 5.0;
    module Bearing(oal) {
    difference() {
    union() {
    tube(oal,id=Sleeve[ID],od=Sleeve[OD],anchor=BOTTOM);
    tube(Rim[LENGTH],id=Rim[ID],od=Rim[OD],anchor=BOTTOM);
    }
    for (a=[0:NumSlots-1])
    zrot(a*360/NumSlots)
    up(oal/4 + Rim[LENGTH])
    right(Sleeve[ID]/2)
    cuboid([Sleeve[OD],Kerf,oal],anchor=BOTTOM);
    }
    }
    //—–
    // Build things
    if (Layout == "Show") {
    color("Gray",0.5)
    xcyl(Rod[LENGTH],d=Rod[OD]);
    right(Rod[LENGTH]/3)
    yrot(90)
    Bearing(Sleeve[LENGTH]);
    left(Rod[LENGTH]/3)
    yrot(90)
    Bearing(IdlerLength);
    }
    if (Layout == "Build") {
    right(Rim[OD]/2 + Gap/2)
    Bearing(Sleeve[LENGTH]);
    left(Rim[OD]/2 + Gap/2)
    Bearing(IdlerLength);
    }
  • HQ Sixteen: Grip Cap Assembly

    HQ Sixteen: Grip Cap Assembly

    After 3D printing another set of cap parts, glob the switches into place with tan JB Weld Plastic Bonder:

    HQ Sixteen grip cap - switch gluing
    HQ Sixteen grip cap – switch gluing

    More Plastic Bonder joins the cap body to the plug fitting into the handlebars:

    HQ Sixteen grip cap - gluing fixture
    HQ Sixteen grip cap – gluing fixture

    I laser-cut an acrylic disk to fit the plug stem and hold the bottom of the plug flush with the bottom of the cap, with the PTFE fabric preventing inadvertent bonding of All The Things. It’s perched atop an empty thread cone to cure: quilting requires a lot of thread and I have a good stock of cones.

    The button cap body solid model now includes alignment marks to eliminate the need for the bench block & clamps:

    HQ Sixteen grip cap - alignment marks
    HQ Sixteen grip cap – alignment marks

    Soldering the cable directly to the switch terminals is déclassé, but the collar prevents the cable from exerting any force on them:

    HQ Sixteen grip cap - wiring
    HQ Sixteen grip cap – wiring

    This time around, dabs of hot-melt glue hold the faceplate to the cap body.

    I also used hot-melt glue to stick the transparent cover onto the handlebar body, as the OEM sticky tape was losing its mojo:

    HQ Sixteen grip cap - wiring closeout
    HQ Sixteen grip cap – wiring closeout

    The rightmost three LEDs went dark a while ago and, while I had everything apart, I tracked the failure to the third LED from the right, replaced it, and it’s all good again. Those LEDs (plus the side groups) still can’t hold a candle to the Nose Ring Lights and Under-arm Lights, but it’s good to have all the lights working.

    I managed to break one tiny wire on the header (wrapped in black silicone tape next to the IC on the right) joining the two cables from the control caps, but other than that things went smoothly.

    Now I can start on other long-awaited tweaks before the next quilt arrives.

  • HQ Sixteen: New Grip Control Cap Labels

    HQ Sixteen: New Grip Control Cap Labels

    The Run/Stop (⏯) button on the HQ Sixteen’s left-hand grip control cap recently became intermittent:

    HQ Sixteen - grip cap installed - left
    HQ Sixteen – grip cap installed – left

    Which is a little more than a year after I built it, so I’m not red-hot pleased with the switch reliability. On the other paw, Mary has done a lot of quilting in the last year, generally controlling the machine with her left thumb, so that particular button has gotten a lot of use.

    Because I glued the caps together, rather than trying to hide screws in finger-friendly locations, the replaceable unit is the whole cap.

    I originally cut the cap labels using LightBurn’s Print-and-Cut tool to align the laser to the printed label, but subsequent experience making punched cards showed it’s generally easier (at least for my simple projects) to skootch the layout to match the laser position at known features:

    HQ Sixteen control caps - laser alignment
    HQ Sixteen control caps – laser alignment

    Those small magnets hold the laminated label flat against the honeycomb.

    The Position Laser tool puts the laser at a selected corner of the square, with Object Snap ensuring it’s really at the corner. Firing a test pulse to verify the red-dot pointer is aligned with the focused CO₂ laser spot is good practice.

    Unlike the cards, the control caps don’t have fractional-millimeter tolerances, so, after verifying the printed label alignment at all four outer corners, it’s Close Enough™:

    HQ Sixteen control caps - label cut
    HQ Sixteen control caps – label cut

    Cutting the adhesive sheet posed no alignment problems:

    HQ Sixteen control caps - adhesive cut
    HQ Sixteen control caps – adhesive cut

    Then it’s just a matter of peel-n-stick.