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: Software

General-purpose computers doing something specific

  • SJCAM M20 Camera: NP-BX1 Battery and Charger Holder

    SJCAM M20 Camera: NP-BX1 Battery and Charger Holder

    A little tweakage to the NP-BX1 battery holder for the astable multivibrator blinkies produced a simple version with the wire exit holes on the bottom:

    NP-BX1 Simple Holder - solid model
    NP-BX1 Simple Holder – solid model

    The four corner holes hold locating pins in the layered acrylic base:

    SJCAM M20 Battery Replacement - case layers
    SJCAM M20 Battery Replacement – case layers

    Those pins got cut slightly shorter to fit in the battery holder; in this photo they’re serving to align the layers and adhesive sheets while I stacked them up.

    The geometry is straightforward, with the outer perimeter matching the 3D printed battery holder:

    SJCAM M20 Car-Mode Battery Hack - battery case
    SJCAM M20 Car-Mode Battery Hack – battery case

    Cut one base and two wall layers from 3 mm (or a bit less) transparent acrylic, plus three adhesive sheets. I stuck adhesive on both sides of one wall layer, using the pins to align the adhesive, stuck the layer to the base, then topped it with the second wall layer, again using the alignment pins.

    The motivation for transparent layered acrylic is being able to see the charge controller’s red and green status LEDs glowing inside the box. This probably isn’t required, but seemed like a Good Idea™ for the initial version.

    With all that in hand, wire it up:

    SJCAM M20 Battery Replacement - charger wiring
    SJCAM M20 Battery Replacement – charger wiring

    The USB charger PCB sits atop a layer of double-sided foam tape. After verifying that the circuitry worked, I globbed the wires in place with hot-melt glue to make it less rickety than the picture suggests.

    The alert reader will have noticed the holes in the 3D printed NP-BX1 holder were drilled, not printed. In the unlikely event I need another case, the holes will automagically appear in the right place.

    I haven’t yet peeled the protective paper off that top adhesive sheet to make a permanent assembly:

    SJCAM M20 Battery Replacement - trial install
    SJCAM M20 Battery Replacement – trial install

    We use the car so infrequently that it’ll take a while to build up enough confidence to stick it together and stick it to the dashboard.

    On the whole, it’s ugly but sufficient to the task.

    A doodle with key dimensions, plus some ideas not surviving contact with reality:

    SJCAM M20 Car-Mode Battery Hack - case doodle
    SJCAM M20 Car-Mode Battery Hack – case doodle

    I truly hope this entire effort is a waste of time.

  • SJCAM M20 Camera: Car Mode Battery Hack

    SJCAM M20 Camera: Car Mode Battery Hack

    The last lithium cell (a.k.a. battery) for the longsuffering SJCAM M20 transformed itself into a spicy pillow:

    SJCAM M20 - spicy pillow lithium battery
    SJCAM M20 – spicy pillow lithium battery

    SJCAM no longer sells those batteries and nobody else does, either, surely because the +4.35V marking shows they’re a special-formula high-voltage lithium mix that doesn’t work with ordinary chargers. Worse, you can’t substitute an ordinary (i.e. cheap) battery, because applying a high-voltage charger to a 4.2 V cell makes Bad Things™ happen.

    Putting the M20 camera in Car Mode makes it begin recording when it sees 5 V on its USB input and shut down a few seconds after the USB input drops to 0 V. Without the internal battery, the camera’s clock doesn’t survive when the external power vanishes, which seems critical for a camera sitting on a dashboard.

    Mashing all that together, I wondered if I could use one of the many leftover low-voltage NP-BX1 batteries from the Sony AS30V helmet camera without starting a dashboard fire, by preventing the camera from charging the battery, while still using it when the USB input is inactive (which, for our car, is pretty nearly all the time).

    The circuitry, such as it is, uses a cheap 1S USB charge controller and a Schottky diode:

    SJCAM M20 Car-Mode Battery Hack - circuit doodle
    SJCAM M20 Car-Mode Battery Hack – circuit doodle

    Power comes in on the left from a USB converter plugged into the Accessory Power Outlet in the center console and goes out to the camera’s USB jack, using a butchered cable soldered to the charge controller’s pads in the middle. The controller manages the NP-BX1 battery as usual, but a diode prevents the camera from trying to send charge current into the controller.

    This should just barely work, as the diode reduces the battery voltage by a few hundred millivolts, so the camera will see the fully charged low-voltage battery as a mostly discharged high-voltage battery.

    Suiting action to words:

    SJCAM M20 Battery Replacement - circuitry
    SJCAM M20 Battery Replacement – circuitry

    It’s built inside the gutted remains of an M20 battery case. The 100µF tantalum cap provides local buffering to prevent the camera from browning out during bursts of file activity while recording. The wire emerges through holes gnawed in the battery case and the camera housing:

    SJCAM M20 Battery Replacement - camera cable exit
    SJCAM M20 Battery Replacement – camera cable exit

    The charge controller on the other end of the wire lives in a layered laser-cut acrylic case attached to a modified version of the venerable 3D printed NP-BX1 battery holder:

    SJCAM M20 Battery Replacement - charger wiring
    SJCAM M20 Battery Replacement – charger wiring

    More on the cases tomorrow.

    Putting it all together, the lashup goes a little something like this:

    SJCAM M20 Battery Replacement - trial install
    SJCAM M20 Battery Replacement – trial install

    The battery pack will eventually get stuck to the dashboard underneath the overhang, out of direct sunlight. Things get hot in there, but with a bit of luck the battery will survive.

    The rakish tilt puts the hood along the bottom of the image, although raising the camera would reduce tilt and cut down on the skyline view:

    SJCAM M20 Car-Mode Battery Hack - test ride
    SJCAM M20 Car-Mode Battery Hack – test ride

    The battery icon instantly switches from “charging” to “desperately low” when the USB power drops, which is about what I expected, but the camera continues to record for about ten seconds before shutting down normally.

    The NP-BX1 battery in the holder comes from the batch of craptastic BatMax batteries with a depressed starting voltage. An actual new cell with a slightly higher voltage would keep the camera slightly happier during those last ten seconds, but … so far, so good.

    Another possibility would be a trio of 1.5 V bucked lithium AA cells, with the diode to prevent charging and minus the charger.

  • Mini-Lathe Chuck Stops: CNC Pocketing

    Mini-Lathe Chuck Stops: CNC Pocketing

    With the fixture aligned and the chuck stop blank clamped down, all that’s left is to make three little pockets:

    Lathe Chuck Stop - Pocketing - LinuxCNC backplot
    Lathe Chuck Stop – Pocketing – LinuxCNC backplot

    Although Javascript may be the gom jabbar of programming, the blinding syntactic noise of raw G-Code puts you in a similar world of hurt:

    #<chuckrad>=20.000                  (radius to center of magnet)
    #<chuckjaws>=3                      (number of jaws)
    #<chuckang>=[360.0/#<chuckjaws>]    (angle between jaws)
    
    #<bitrad>=[2.900/2]                 (cutter radius)
    
    #<pocketrad>=[4.100/2]              (magnet pocket radius)
    #<pocketdeep>=2.200                 ( … depth)
    #<xoffs>=[#<pocketrad>-#<bitrad>]   (pocket center to cutter center)
    
    #<safez>=20.0                   (above all the clamps & gadgets)
    
    G21 G54 G80 G90 G94             (metric!)
    
    F600                            (full speed for the Sherline)
    
    G0 Z#<safez>
    

    Obviously, those magic numbers must match the laser-cut blanks, the magnets, the cutting bit in the spindle, the clamps on the table, the speed of the machine, and everything else you overlooked.

    So. Much. Pain.

    Knowing the angle to the current pocket, polar coordinate notation gets to the center point, with a jaunt in relative motion to the starting point for the helix into the pocket:

    #<ang>=[#<chuckang>/2]          (set starting angle)
    O100 REPEAT [#<chuckjaws>]
    
    G0 @#<chuckrad> ^#<ang>         (to hole center)
    G91                             (relative motion …)
    G0 X#<xoffs>                    ( … to helix start …)
    G90                             ( … and done)
    
    G0 Z0                           ( to surface)
    

    Each pocket consists of a helix cut to the bottom, two clearing passes, and another helix back to the surface:

    G2 I[-#<xoffs>] Z[-#<pocketdeep>] P[1+FUP[#<pocketdeep>]]   (into hole)
    G2 I[-#<xoffs>] P2                                          (clean bottom)
    G3 I[-#<xoffs>] Z0 P[1+FUP[#<pocketdeep>]]                  (shave sides)
    

    That dance produced rounder pockets with cleaner bottoms than just a single helix down and a straight pull upward.

    Then set up for the next hole and clean up after the last one:

    G0 @#<chuckrad> ^#<ang>         (back to center)
    G0 Z#<safez>
    
    #<ang>=[#<ang>+#<chuckang>]     (set up next hole)
    O100 ENDREPEAT
    
    G0 Z[2*#<safez>]
    G0 X0 Y0
    
    M2
    

    I ran the Sherline XY axes at their 600 mm/min top speed, the spindle at 10 kRPM with a shiny new 3 mm (nominal!) cutter, ramped into the helix at ≅10° (on a 1 mm circle!), and it sliced the acrylic into nice chips without getting all melty.

    Unlike with Javascript, when you get something wrong in G-Code, you can hear the crash.

    The LinuxCNC pocketing code as a GitHub Gist:

    (Magnet pockets for laser-cut lathe chuck stops)
    (2023-07 Ed Nisley)
    #<chuckrad>=20.000 (radius to center of magnet)
    #<chuckjaws>=3 (number of jaws)
    #<chuckang>=[360.0/#<chuckjaws>] (angle between jaws)
    #<bitrad>=[2.900/2] (cutter radius)
    #<pocketrad>=[4.100/2] (magnet pocket radius)
    #<pocketdeep>=2.200 ( … depth)
    #<xoffs>=[#<pocketrad>-#<bitrad>] (pocket center to cutter center)
    #<safez>=20.0 (above all the clamps & gadgets)
    G21 G54 G80 G90 G94 (metric!)
    F600 (full speed for the Sherline)
    G0 Z#<safez>
    #<ang>=[#<chuckang>/2] (set starting angle)
    O100 REPEAT [#<chuckjaws>]
    G0 @#<chuckrad> ^#<ang> (to hole center)
    G91 (relative motion …)
    G0 X#<xoffs> ( … to helix start …)
    G90 ( … and done)
    G0 Z0 ( to surface)
    G2 I[-#<xoffs>] Z[-#<pocketdeep>] P[1+FUP[#<pocketdeep>]] (into hole)
    G2 I[-#<xoffs>] P2 (clean bottom)
    G3 I[-#<xoffs>] Z0 P[1+FUP[#<pocketdeep>]] (shave sides)
    G0 @#<chuckrad> ^#<ang> (back to center)
    G0 Z#<safez>
    #<ang>=[#<ang>+#<chuckang>] (set up next hole)
    O100 ENDREPEAT
    G0 Z[2*#<safez>]
    G0 X0 Y0
    M2
  • Mini-Lathe Chuck Stops: Pocketing Fixture

    Mini-Lathe Chuck Stops: Pocketing Fixture

    Putting pockets in the legs of the mini-lathe chuck stop blanks requires a fixture to align them in the Sherline mill:

    Lathe Chuck Stops - pocketing setup
    Lathe Chuck Stops – pocketing setup

    Because it need not withstand much lateral force and will get used only a dozen-ish times, the base is MDF and the stop alignment happens in three matching chipboard layers:

    Lathe Chuck Stops - Pocketing Fixture - LB layout
    Lathe Chuck Stops – Pocketing Fixture – LB layout

    The three stops (over on the right) are copy-pasta from the originals. A 0.1 mm outset in the chipboard (center) lets the acrylic shapes drop into the chipboard sheets with Good Enough™ alignment accuracy. The MDF layer (left) provides some overshoot comfort below the chipboard.

    The chipboard layers each have four alignment targets at (±30,±20):

    Lathe Chuck Stops - pocketing fixture touchoff
    Lathe Chuck Stops – pocketing fixture touchoff

    Touch off the lower-left target at (-30,-20) and G0 X30 Y30 should drop the laser dot in the middle of the upper-right target. With the (0,0) origin at the geometric center of the stop, LinuxCNC’s polar notation picks out the three pockets:

    G0 @20 ^-60
    G0 @20 ^180
    G0 @20 ^60
    

    The plywood disk under the Sherline’s clamp has a glued ring to put the clamping force out near the ends of the legs. I started with just the aluminum clamp, but the legs needed a bit more stability; a laser cutter makes impromptu widgets like that trivially easy.

    Next: write the G-Code to make the pockets.

    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.

  • Mini-lathe Chuck Stops

    Mini-lathe Chuck Stops

    Having occasionally been in need of a lathe chuck stop, I finally cleared that project off the heap:

    Lathe Chuck Stops - demo setup
    Lathe Chuck Stops – demo setup

    These are definitely not up to commercial standards, but also don’t cost fifty bucks each. A trio of 4×2 mm neodymium disk magnets stick the stop to the chuck (and to each other) with enough force to hold it there, but not enough to make removing it a hassle.

    I imported the Z axis orthogonal view of the chuck jaws from the ball fixture for the running lights:

    Lathe Chuck Jaws - solid model axial
    Lathe Chuck Jaws – solid model axial

    Trace the right-side jaw, clean it up, put the tip a known distance from the origin, make a circular array, and draw a comfort circle the size of the chuck OD.

    The stop geometry comes from a hull wrapped around a circle a few millimeters larger than the 4 mm magnet (out 20 mm from the center) and a circle at the center sized so the hull clears the jaws:

    Lathe Chuck Stops - LB layout
    Lathe Chuck Stops – LB layout

    Then a small circle at the center allows me to drop the stop atop a known coordinate and rotate it around the circle, because the XY coordinate center is not at the geometric center.

    I cut out a few chipboard samples to verify the sizes, a few more from scrap acrylic to set up the pocketing operation, then half a dozen of each in cheerful kindergarten colors:

    Lathe Chuck Stops - on-lathe storage
    Lathe Chuck Stops – on-lathe storage

    The 5 mm stop is obviously too fragile for commercial success, but I figured it’ll survive long enough around here. Worst case, I can make another handful as needed.

    Although I have laser-engraved pockets in plywood, a few experiments in acrylic confirmed the surface finish is terrible and the depth control is iffy, at best. Given that I need a 2.2 mm deep pocket in 3 mm acrylic, a CNC mill seems the right way to poke the pockets:

    Lathe Chuck Stops - pocketing setup
    Lathe Chuck Stops – pocketing setup

    More on that tomorrow.

    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.

  • Eyeglass Case Padding Redux

    Eyeglass Case Padding Redux

    Confronted with a nice metal eyeglass case that had lost its original liner, I traced the outline on paper and scanned it:

    Metal case outline
    Metal case outline

    Unlike the plastic Zenni cases, this one has nice straight edges, so:

    • Eyeball a LightBurn rectangle over the traced image
    • Round the corners to suit
    • Shrink it by a few millimeters to make it fit inside

    Then:

    • Add a perimeter line offset by the 6 mm required to cover the sides
    • Draw a dart in each corner to allow for bending the foam
    • Set the perimeter priority to 1 so it cuts last
    • Put the original outline to a tool layer to remind me how to do this the next time around

    Which looks like this:

    Metal case pad - LightBurn layout
    Metal case pad – LightBurn layout

    Then Fire The Laser into a sheet of EVA foam:

    Metal eyeglass case - padding cut
    Metal eyeglass case – padding cut

    Stuff it into the case, do another one in brown, and the result looks kinda like it should:

    Metal eyeglass case - padding installed
    Metal eyeglass case – padding installed

    That was easy …

  • Patio Chair Foot Adapters

    Patio Chair Foot Adapters

    Some years ago we acquired a free quartet of aluminum-frame patio chairs in need of new straps and feet. Eventually enough straps broke to force me to re-strap the things and I finally got around to replacing the badly worn OEM feet:

    Patio Chair Foot Adapter - OEM feet
    Patio Chair Foot Adapter – OEM feet

    The small drilled holes let me yoink most them out with sheet-metal screw attached to a slide hammer, then apply the Designated Prydriver to the most recalcitrant / broken ones.

    Some feet had worn enough to expose the aluminum tubes, but most had at least a thin layer of plastic:

    Patio Chair Foot Adapter - OEM foot erosion
    Patio Chair Foot Adapter – OEM foot erosion

    Obviously, I should have stripped and repainted the frames (if that’s possible, as they’re probably powder-coated), but a man’s gotta know his limitations and this job needed to get done.

    One might think patio furniture replacement feet are cheap & readily available, but no amount of keyword engineering produced search results with any degree of assured fit, so I conjured adapters for screw-in feet from the vasty digital deep:

    Patio Chair Foot Adapters - solid models
    Patio Chair Foot Adapters – solid models

    This was a long-awaited opportunity to explore the BOSL2 library and it worked wonderfully well. Each adapter is whittled from a huge hex nut with threads that perfectly fit the M8×1.25 stud, which stands vertically through the middle of the (slightly oval) bottom surface parallel to the floor.

    The front tubes have a 5° angle with respect to the vertical:

    Patio Chair Foot Adapter - front
    Patio Chair Foot Adapter – front

    And the rear tubes are 15° off:

    Patio Chair Foot Adapter - rear
    Patio Chair Foot Adapter – rear

    Each adapter has an orientation notch pointing toward the front of the front leg and the rear of the rear leg:

    Patio Chair Foot Adapter - orientation notch
    Patio Chair Foot Adapter – orientation notch

    I expected to apply adhesive on the inside and outside of the adapters, but they tapped firmly into place inside the legs and the studs screwed firmly into them, so we’ll see how they survive in actual use. I expect the studs to rust after a while, but that might not be the most awful thing ever to happen.

    The OpenSCAD source code as a GitHub Gist:

    // Patio chair foot adapter
    // Ed Nisley – KE4ZNU – 2023-06
    include <BOSL2/std.scad>
    include <BOSL2/threading.scad>
    LegAngles = [5,15];
    /* [Hidden] */
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    HoleWindage = 0.2;
    Protrusion = 0.1; // make holes end cleanly
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    ID = 0;
    OD = 1;
    LENGTH = 2;
    inch = 25.4;
    //———————-
    // Dimensions
    LegTube = [18.8 – HoleWindage,22.5,0];
    Stud = [8.0,1.25,10.0]; // M8x1.25 foot stud
    FlangeBase = 3.0;
    //———————–
    for (i=[0:len(LegAngles)-1]) {
    ang = LegAngles[i];
    FlangeIncr = LegTube[OD]*tan(ang);
    Flange = [Stud[0],LegTube[OD],FlangeBase + FlangeIncr];
    translate([i*1.5*Flange[OD],0,0])
    difference() {
    translate([0,0,0*-FlangeIncr/2])
    threaded_nut(2*Flange[OD],Stud[0],1.5*Stud[2],Stud[1],
    anchor=BOTTOM,bevel=false,$slop=0.2);
    rotate([0,ang,0]) {
    translate([0,0,FlangeBase + FlangeIncr/2])
    tube(4*Stud[2],2*Flange[OD],LegTube[ID]/2,
    anchor=BOTTOM);
    tube(4*Stud[2],2*Flange[OD],Flange[OD]/2,
    anchor=CENTER);
    }
    cube([Flange[OD],ThreadWidth,2*ThreadThick],anchor=BOTTOM+RIGHT);
    }
    }