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

  • Stack Light: EL817 Optoisolator Case

    Stack Light: EL817 Optoisolator Case

    Rather than let the boosted optoisolators flop around:

    Stack Light - controller hairball wiring
    Stack Light – controller hairball wiring

    A small case seemed like a Good Idea™:

    Optoisolator Case - OpenSCAD
    Optoisolator Case – OpenSCAD

    The little hex standoffs have M3 threads, although 6 mm screws are about as much as they’ll take. The recesses have clearance for the boost transistor underneath the PCB, but it’s your responsibility to not let random wires get in trouble with the exposed circuitry:

    Optoisolator case
    Optoisolator case

    A strip of good foam tape sticks it to the controller:

    Stack Light - controller wiring
    Stack Light – controller wiring

    Admittedly, the stack light wiring remains something of a hairball, but it’s in a good cause.

    The OpenSCAD code can build as many cavities as you need:

    Optoisolator Case - x5 - OpenSCAD
    Optoisolator Case – x5 – OpenSCAD

    The OpenSCAD source code as a GitHub Gist:

    // Optoisolator case
    // Ed Nisley – KE4ZNU
    // 2025-01-09
    include <BOSL2/std.scad>
    include <BOSL2/threading.scad>
    // Number of isolator mounts
    NumMounts = 2;
    /* [Hidden] */
    Protrusion = 0.1;
    PCB = [40.5,15.5,1.6]; // optoisolator PCB
    LipWidth = 0.8; // support lip under PCB
    Margin = [8.0,3.0,4.5]; // clearance around PCB
    BaseThick = 3.0; // underneath
    Block = PCB + [2*Margin.x, 2*Margin.y, (Margin.z + BaseThick)];
    echo(Block = Block);
    HolesOC = [9.5,10.0]; // M3 mounting holes (upper left / lower right)
    $fn = 3*4;
    //———-
    // Construct one mount
    module Mount() {
    union() {
    difference() {
    cube(Block,anchor=BOTTOM);
    up(Block.z – PCB.z)
    cube(PCB + [0,0,Protrusion],anchor=BOTTOM);
    up(BaseThick)
    cube(PCB – 2*[LipWidth,LipWidth,0] + [0,0,Block.z],anchor=BOTTOM);
    }
    for (i=[-1,1])
    translate([i*HolesOC.x/2,-i*HolesOC.y/2,BaseThick])
    threaded_nut(5.0,3.1,Margin.z,0.5, // flat size, root dia, height, pitch
    bevel=false,ibevel=false,anchor=BOTTOM);
    }
    }
    //———-
    // Mash together as many mounts as needed
    union()
    for (j=[0:(NumMounts – 1)])
    back(j*(Block.y – Margin.y))
    Mount();

  • Stack Light: Optoisolator Boost Transistor

    Stack Light: Optoisolator Boost Transistor

    The LEDs in each stack light layer require a current sink handling about 50 mA, far above the ability of cheap optoisolators based on the EL817 photocoupler:

    Optoisolator - OEM schematic
    Optoisolator – OEM schematic

    I’ll go into the motivation for optocouplers along with the laser controller wiring details.

    As delivered, the PCB has:

    • R1 = 1 kΩ (a convenient 1 V/mA current sense)
    • R2 = 10 kΩ (a rather high-value pullup)

    The idea is to add an able-bodied transistor to the output in a Darlington configuration:

    Optoisolator - Darlington output
    Optoisolator – Darlington output

    Some rummaging produced a small bag of 2N3904 transistors, although nearly any small NPN transistor will suffice. Removing R2 cleared the field for modification:

    Optoisolator modification - top
    Optoisolator modification – top

    The 2N3904 transistor (with the usual EBC pinout) fits face-down under the PCB:

    Stack Light - optoisolator transistor
    Stack Light – optoisolator transistor

    The cross-legged layout conceals the emitter and base leads being soldered snugly to the former OUT and GND terminals, respectively, with the collector going to the VCC terminal. The terminals thus become:

    • VCC → Collector
    • OUT → Emitter
    • GND→ X (no connection)

    Although I have little reason to believe the EL817 chips are anything other than what they claim to be, their topmarks seemed rather casual:

    EL817 optocoupler - top view
    EL817 optocoupler – top view

    The other four chips carried C333 rank + date codes.

    The datasheet says the C means the Current Transfer Ratio is 200% to 400%: the output current should be 2× to 4× the diode current. The test condition are 5 mA into the diode and 5 V across the transistor terminals. A quick test:

    • 2 mA → 4 mA = 2×
    • 5 mA → 15 mA = 3×
    • 10 mA → 35 mA = 3.5×
    • 12 mA → 40 mA = 3.3×

    The output transistor is rated only to 50 mA, so I stopped at 40 mA. The CTR is between 200% and 350% over that range, suggesting the parts are really real.

    The 2N3904 should have an hFE above 60 in that current range and multiply the EL817 gain by about that amount. Another quick test in the Darlington configuration, now with the 5 V supply across the 2N3904:

    • 100 µA → 8.1 mA = 81×
    • 250 µA → 43 mA = 172×
    • 500 µA → 83 mA = 166×

    The overall current gain is 40× to 50×, less than the estimate, but plenty high enough for my purposes. If you cared deeply, you’d run a circuit simulation to see what’s going on.

    Knowing I needed only 50-ish mA, stopping with the transistor burning half a watt (because VCE is held at 5 V) seemed reasonable. In actual use, VCE will be on the order of 1 V and the dissipation will be under 100 mW.

    A quick test shows they work as intended:

    Stack Light - controller hairball wiring
    Stack Light – controller hairball wiring

    But, yeah, talk about hairballs. Those things cry for little housings to keep them out of trouble.

    The chonky lumps with orange stripes are Wago Lever-Nut connectors: highly recommended.

  • Stack Light Base

    Stack Light Base

    Having external indications for the laser cutter’s internal status signals seemed like a good idea and, rather than build the whole thing, I got a five-layer stack light:

    Stack Light - disassembly
    Stack Light – disassembly

    It arrives sans instructions, apart from the data plate / wiring diagram label on the housing, so the first puzzle involves taking it apart to see what’s inside. My motivation came from a tiny chip of blue plastic on the kitchen table where I’d opened the unpadded bag. Apparently, a mighty force had whacked the equally unpadded box with enough force to crack the blue lens, but I have no idea how the sliver escaped the still-assembled stack.

    Anyhow, hold the blue/green lenses in one hand and twist the red/yellow lenses counterclockwise as seen looking at the cap over the red layer. Apply more force than you think appropriate and the latches will reluctantly give way. Do the same to adjacent layers all the way down, then glue the blue chip in place while contemplating other matters.

    A switch on each layer selects either steady (the default and what I wanted) or blinking (too exciting for my needs). Reassemble in reverse order.

    A Stack Light generally mounts on a production-line machine which might have a suitable cutout for exactly that purpose. I have no such machine and entirely too much clutter for a lamp, so I screwed it to a floor joist over the laser:

    Stack Light - installed
    Stack Light – installed

    The tidy blue PETG-CF base started as a scan of the lamp’s base to serve as a dimension reference:

    Stack Light - base scan
    Stack Light – base scan

    Import into LightBurn:

    • Draw a 70 mm square centered on the workspace
    • Round the corners until they match the 13 mm radius
    • Draw one 5.6 mm circle at the origin
    • Move the circle 52/2 mm left-and-down
    • Turn it into a 4 element array on 52 mm centers
    • Verify everything matches the image
    • Export as SVG

    Import into Inkscape:

    • Put the perimeter on one layer
    • Put the four holes on another
    • Center around an alignment mark at a known coordinate
    • Save as an Inkscape SVG

    Import into OpenSCAD, extrude into a solid model, and punch the holes:

    Stack Light Mount base - solid model
    Stack Light Mount base – solid model

    The lip around the inner edge aligns the lamp base.

    If I ever make another one, I’ll add pillars in the corners to put the threaded brass inserts close to the top for 10 mm screws instead of the awkward 30 mm screws in this one. More than a single screw hole in the bottom would align it on whatever you’re indicating.

    Now, to wire the thing up …

    The OpenSCAD source code 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.
    // Stack Light mount
    // Ed Nisley – KE4ZNU
    // 2025-01-03
    include <BOSL2/std.scad>
    /* [Hidden] */
    ID = 0;
    OD = 1;
    LENGTH = 2;
    BaseCenter = [100,100,0];
    Base = [70,70]; // nominal, for figuring holes
    Insert = [4.9,5.9,6.0];
    PlateThick = Insert[LENGTH];
    HolderTall = 24.0;
    WallThick = 2.7; // outer wall of light base
    LipThick = 1.5; // alignment lip inside light base
    LipTall = 0.75;
    CableOD = 5.0;
    Protrusion = 0.1;
    difference() {
    translate(-BaseCenter)
    linear_extrude(height=HolderTall + LipTall)
    import("Stack Light – base layout.svg",layer="Base Perimeter");
    up(Insert[LENGTH])
    translate(-BaseCenter)
    linear_extrude(height=HolderTall – LipTall)
    offset(delta=-(WallThick + LipThick))
    import("Stack Light – base layout.svg",layer="Base Perimeter");
    up(HolderTall)
    linear_extrude(height=HolderTall,convexity=5)
    translate(-BaseCenter)
    difference() {
    offset(delta=WallThick) // avoid glitches on perimeter edge
    import("Stack Light – base layout.svg",layer="Base Perimeter");
    offset(delta=-WallThick)
    import("Stack Light – base layout.svg",layer="Base Perimeter");
    }
    down(Protrusion)
    translate(-BaseCenter)
    linear_extrude(height=2*HolderTall,convexity=5)
    import("Stack Light – base layout.svg",layer="Base Holes");
    up(HolderTall/2)
    yrot(90) zrot(180/6)
    cylinder(d=CableOD,h=Base.x,$fn=6);
    }

  • Quick-n-Easy Window Shade End Cap

    Quick-n-Easy Window Shade End Cap

    While tracking down an air leak in a living room window, I noticed one of the cellular blinds was missing an end cap, so I scanned a pair of surviving caps:

    Living Room shade end caps - level adjust
    Living Room shade end caps – level adjust

    Blow out the contrast, save as a JPG.

    Import into LightBurn:

    • Trace the outlines into paths
    • Use LightBurn’s shape optimization tool to dramatically reduce the number of nodes & smooth the outlines
    • Overlay & align the shapes
    • Export as an SVG file

    Import into Inkscape:

    • Put the paths on named layers
    • Center around an alignment mark
    • Save as an Inkscape SVG
    Living Room shade end caps - Inkscape alignment
    Living Room shade end caps – Inkscape alignment

    It is slightly tilted, but that doesn’t matter. You could devote more time to smoothing / reverse-engineering the shapes, but that doesn’t make much difference, either.

    Inkscape exports the SVG coordinates with respect to the overall page origin in the lower left corner, so when OpenSCAD imports the SVG the paths end up far away from the origin. The trick is to put a 2 mm diameter circle at a known location, center the paths around it, then have OpenSCAD use the circle’s location to recenter the paths.

    Because Inkscape uses the lower left corner of each shape as its origin, you must put the circle at (99,99) to have its center at (100,100). That is one of the many reasons you (well, I) can’t use Inkscape as a CAD program.

    Import into OpenSCAD, recenter, and extrude the shapes:

    CapCenter = [100,100];
    
    PlateThick = 1.8;       // thickness of visible end cap
    
    HolderTall = 10.0 + PlateThick;
    
    union() {
      linear_extrude(height=PlateThick)
          translate(-CapCenter)
                import("Living Room shade end caps - Inkscape.svg",layer="Exterior");
      linear_extrude(height=HolderTall)
          translate(-CapCenter)
                import("Living Room shade end caps - Inkscape.svg",layer="Retainer");
    }
    

    Which produces a solid model:

    Living Room shade end caps - solid model
    Living Room shade end caps – solid model

    Save the model as 3mf, import into PrusaSlicer, and slice:

    Living Room shade end caps - PrusaSlicer preview
    Living Room shade end caps – PrusaSlicer preview

    Making the retainer shape a little wider would be a good idea to get better infill, but it’s a slip fit into the blind (surely why it fell out long ago) and need not withstand any stress.

    Print as usual:

    Living Room shade end cap - on platform
    Living Room shade end cap – on platform

    And then It Just Works™:

    Living Room shade end cap - installed
    Living Room shade end cap – installed

    It’s sitting atop a bookcase while I finish tinkering with its window.

    All that seems like a lot of fiddling around, but it uses each program to its best advantage and it’s surprisingly easy after the first few models.

  • Handi-Quilter HQ Sixteen: Preliminary Power PCB Schematic

    Handi-Quilter HQ Sixteen: Preliminary Power PCB Schematic

    Because I must eventually diagnose and fix the HQ Sixteen’s Motor Stall Heisenbug, I printed out several views of the power supply PCB on glossy photo paper for best visibility.

    The component side:

    Power PCB - components
    Power PCB – components

    The solder side:

    Power PCB - solder
    Power PCB – solder

    The X-ray view:

    Power PCB - overlaid
    Power PCB – overlaid

    Considerable pondering and sketching produced an annotated view of the solder side:

    HQ Sixteen - Power PCB - solder side - component labels - reduced
    HQ Sixteen – Power PCB – solder side – component labels – reduced

    Here’s a tentative schematic drawn on the fly while extracting it from the PCB traces:

    HQ Sixteen - Power PCB - rough schematic
    HQ Sixteen – Power PCB – rough schematic

    !!CAUTION!! I have not verified the schematic against the actual hardware / PCB / components, as the Heisenbug has not reoccurred and I had no occasion to take the machine apart for checking. Do not assume any connections or components are correctly drawn.

    Before I redraw the schematic in a more useful format, I must verify several nodes, because not everything in there makes sense.

    In particular, the elaborate resistor string in the middle of the page seems to establish reference voltages for everything else, from the motor power supply turn-on delay to the RUN signal starting the motor.

    The optoisolators definitely get the RUN command signal from the controller and feed the STALL motor status back to it. That’s assuming I understand enough to pin those labels on those connections.

    !!CAUTION!! Read my caveats about the direct-from-the-AC-line non-isolated +160 VDC motor supply before connecting your instruments. The GND traces are not isolated from the AC line and are not at the normal “0 V” AC neutral potential.

    But if this mess gets you further along with whatever you were doing, let me know how it all worked out for you.

  • Laser-Engraved PETG / PETG-CF

    Laser-Engraved PETG / PETG-CF

    Prompted by scruss’s report of successfully “engraving” PLA, I had to try this:

    Laser engraved PETG-CF
    Laser engraved PETG-CF

    It’s blue PETG-CF from the scrap box, done at 500 mm/s and 20% of a 60 W laser and came out looking really nice.

    I did a pass at 10%, low enough that the laser barely fired, and the mark was, correspondingly, barely visible: no color change and only a slight depth. Obviously, you’d want to tune for best picture depending on whatever you were trying to achieve.

    The results on black PETG, also from the scrap box, were somewhat less attractive:

    Laser engraved PETG - bottom surface
    Laser engraved PETG – bottom surface

    That’s at 500 mm/s with power at 10% and 20, so the outcome definitely depends on the material. That surface was against the platform when it was printed on the Makergear M2, explaining the glossy smooth threads.

    The other side was rougher and needed more power to punch a visible result into the plastic:

    Laser engraved PETG - top surface
    Laser engraved PETG – top surface

    All in all, the PETG-CF result looks usable, particularly for small-ish annotations on a flat surface where full-on multimaterial printing would take forever without adding much value.

  • HLP-200B Laser Power Meter: Variation Across the Platform

    HLP-200B Laser Power Meter: Variation Across the Platform

    It’s generally accepted that laser cutter performance varies across the platform due to differences in path length, with (in my OMTech 60 W machine) the rear left corner having more power because it’s closest to the laser tube and the front right corner having less power because it’s farthest away.

    Having measured the path lengths, set the laser pulse power to 25%, then plotted the power measurements against path length:

    HLP-200B Laser Power Meter - 60 W across platform measurements
    HLP-200B Laser Power Meter – 60 W across platform measurements

    I was mildly surprised at the minimal path length difference between the two corners and the center, but it’s due to the meter case reducing the distance along the X axis without a similar change along Y. In real life, you’d snuggle the HLP-200B sensor against the boundaries of the platform and measure the corresponding distances.

    Given the size of the standard deviation bars, you can surely draw different conclusions, but the linear fit suggests the beam loses 3.5 W per meter of path length: 3.9 W from left rear to right front. Using meters for the distance multiplies the coefficient by 1000 and brings the digits up out of the noise; don’t believe more than two digits.

    Although the beam diverges, the HLP-200B sensor is much larger than the beam and captures all the energy even in the front right corner, so beam divergence doesn’t matter and any square-law effect doesn’t apply.

    If I had measured the power at the tube exit, it would be around 34 W and the error bars would surely justify that expectation, too.

    Assuming the path loss in watts is proportional to the tube exit beam power, calling it 10% would be about right. That would definitely reduce the cutting performance in the front right corner if the power setting was barely adequate elsewhere on the platform.