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.

Tag: M2

Using and tweaking a Makergear M2 3D printer

  • BOB Yak Fender Fracture: Fixed

    We agreed that repairing the failed flag ferrule made the trailer much quieter, but it still seemed far more rattly than we remembered. It just had to be the fender, somehow, and eventually this appeared:

    BOB Yak Fender Mount - fractures
    BOB Yak Fender Mount – fractures

    The obviously missing piece of the fender fell out in my hand; the similar chunk just beyond the wire arch fell out after I took the pictures. Yes, the wire has indented the fender.

    The arch supports the aluminum fender, with a pair of (flat) steel plates clamping the wire to the fender:

    BOB Yak Fender Mount - screw plates and pads
    BOB Yak Fender Mount – screw plates and pads

    The cardboard scraps show I fixed a rattle in the distant past.

    Being aluminum, the fender can’t have a replacement piece brazed in place and, given the compound curves, I wasn’t up for the requisite fancy sheet metal work.

    Instead, a bit of math produces a pair of shapes:

    BOB Yak Fender Mount - solid model
    BOB Yak Fender Mount – solid model

    In this case, we know the curve radii, so the chord equation gives the depth of the curve across the (known) width & length of the plates; the maximum of those values sets the additional thickness required for the plates. The curves turn out to be rather steep, given the usual layer thickness and plate sizes, which gives them a weird angular look that absolutely doesn’t matter when pressed firmly against the fender:

    BOB Yak Fender Mount - Slic3r preview
    BOB Yak Fender Mount – Slic3r preview

    The computations required to fit Hilbert Curve surface infill into those small exposed areas took basically forever; given that nobody will ever see them, I used the traditional linear infill pattern. A 15% 3D Honeycomb interior infill turned them into rigid parts.

    The notch in the outer plate (top left, seen notch-side-down) accommodates the support wire:

    BOB Yak Fender Mount - outer
    BOB Yak Fender Mount – outer

    The upper surface would look better with chamfered edges, but that’s in the nature of fine tuning. That part must print with its top surface downward: an unsupported (shallow) chamfer would produce horrible surface finish and life is too short for fussing with support. Given the surrounding rust & dings, worrying about aesthetics seems bootless.

    The original screws weren’t quite long enough to reach through the plastic plates, so I dipped into my shiny-new assortment of stainless steel socket head cap screws. Although the (uncut) M5x16 screws seem to protrude dangerously far from the inner plate, there’s another inch of air between those screws and the tire tread:

    BOB Yak Fender Mount - inner
    BOB Yak Fender Mount – inner

    Given the increase in bearing area, that part of the fender shouldn’t fracture for another decade or two.

    I loves me my M2 3D printer …

    The OpenSCAD source code as a GitHub Gist:

    // BOB Yak Fender Mounting Bracket
    // Ed Nisley – KE4ZNU – July 2016
    Layout = "Build"; // Build Fender Rod BlockInner BlockOuter
    //- Extrusion parameters must match reality!
    // Print with 1 shell and 3 solid layers
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    HoleWindage = 0.3;
    Protrusion = 0.1; // make holes end cleanly
    inch = 25.4;
    //———————-
    // Dimensions
    IR = 0; // radii seem easier to measure here
    OR = 1;
    LENGTH = 2;
    Fender = [25,220,1]; // minor major thickness
    FenderSides = 128;
    FenderRod = [5.0/2,(Fender[IR] + 10),5.0/2]; // support rod dia/2, arch radius, rod dia/2 again
    ChordMajor = Fender[OR] – sqrt(pow(Fender[OR],2) – pow(40,2)/4);
    ChordMinor = Fender[IR] – sqrt(pow(Fender[IR],2) – pow(25,2)/4);
    ChordFit = max(ChordMajor,ChordMinor);
    echo("Chords: ",ChordMajor,ChordMinor,ChordFit);
    BlockInnerOA = [40,25,1 + ChordFit];
    BlockOuterOA = [35,25,2 + ChordFit];
    echo(str("Inner Block: ",BlockInnerOA));
    echo(str("Outer Block: ",BlockOuterOA));
    ScrewOD = 5.0;
    ScrewOC = 20.0;
    NumSides = 6*4;
    //———————-
    // Useful routines
    module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
    Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
    FixDia = Dia / cos(180/Sides);
    cylinder(r=(FixDia + HoleWindage)/2,
    h=Height,
    $fn=Sides);
    }
    module FenderShape() {
    rotate([90,0*180/FenderSides,0])
    rotate_extrude(angle=180,$fn=FenderSides)
    translate([(Fender[OR] – Fender[IR]),0])
    circle(r=Fender[IR],$fn=2*NumSides);
    }
    module RodShape() {
    rotate([90,0*180/FenderSides,0])
    rotate_extrude(angle=180,convexity=2,$fn=FenderSides)
    translate([(FenderRod[OR] – FenderRod[IR]),0])
    circle(r=FenderRod[IR],$fn=NumSides);
    }
    module BlockInner() {
    intersection() {
    difference() {
    linear_extrude(height=BlockInnerOA[LENGTH],convexity=3)
    hull() {
    for (i=[-1,1])
    translate([i*(BlockInnerOA[0]/2 – BlockInnerOA[1]/2),0,0])
    circle(d=BlockInnerOA[1]);
    }
    for (i=[-1,1])
    translate([i*(ScrewOC/2),0,-Protrusion])
    PolyCyl(ScrewOD,2*BlockInnerOA[2],6);
    }
    translate([0,0,(BlockInnerOA[2] – Fender[OR])])
    FenderShape();
    }
    }
    module BlockOuter() {
    difference() {
    linear_extrude(height=BlockOuterOA[LENGTH],convexity=4)
    hull() {
    for (i=[-1,1])
    translate([i*(BlockOuterOA[0]/2 – BlockOuterOA[1]/2),0,0])
    circle(d=BlockOuterOA[1]);
    }
    for (i=[-1,1])
    translate([i*(ScrewOC/2),0,-Protrusion])
    PolyCyl(ScrewOD,2*BlockOuterOA[2],6);
    translate([0,0,(BlockOuterOA[2] – ChordFit + Fender[OR])])
    rotate([180,0,0])
    FenderShape();
    translate([0,0,(FenderRod[OR] – 2*FenderRod[IR])])
    rotate([180,0,90])
    RodShape();
    }
    }
    //- Build things
    if (Layout == "Fender")
    FenderShape();
    if (Layout == "Rod")
    RodShape();
    if (Layout == "BlockInner")
    BlockInner();
    if (Layout == "BlockOuter")
    BlockOuter();
    if (Layout == "Build") {
    translate([0,-BlockInnerOA[0]/2,0])
    BlockInner();
    translate([0,BlockOuterOA[0]/2,0])
    BlockOuter();
    }

    The original dimension measurement and design doodle:

    BOB Yak Fender Mount - doodles
    BOB Yak Fender Mount – doodles
  • Dishwasher Rack Protectors in PETG

    Our standard dishwasher loadout changed a while back, so I ran off more protectors to fill the bottom rack. The crystalline look of natural PETG is probably wasted in there, even though it puts the old, rather yellowed, PLA protectors to shame:

    Dishwasher Rack Protectors - old PLA new PETG
    Dishwasher Rack Protectors – old PLA new PETG

    Dollops of silicone sealant hold them in place: the bigger the blob, the better the job.

    We don’t activate the drying heater, so the plastic doesn’t get exposed to absurdly high temperatures. As nearly as I can tell, those PLA protectors remain in fine physical condition, even though they’re turning an odd color.

    The support structures peeled out easily with a fingernail pull:

    Dishwasher Rack Protectors - 0.20 mm PETG bridging - detail
    Dishwasher Rack Protectors – 0.20 mm PETG bridging – detail

    PETG doesn’t bridge well, as shown by the gaps between the support ridges. Those 0.20 mm layers seemed skimpy for lightly supported PETG, so I ran another set at 0.25 mm:

    Dishwasher Rack Protectors - 0.25 mm PETG bridging - detail
    Dishwasher Rack Protectors – 0.25 mm PETG bridging – detail

    Not quite enough improvement for a Happy Dance, although fine for the application.

    We look forward to seeing what grows in those little crevices…

  • Inspiron Mini 10 as a 3D Printer Controller

    It turns out that the dual-core Intel Atom Inside an old Dell Mini 10 isn’t up to the demands of rendering modern web design; disk I/O speed has nothing to do with the CPU’s (lack of) ability to chew through multiple layers of cruft adorning what used to be straightforward static HTML.

    So, equipped with Linux Mint / XFCE, it’s now found a new purpose in life:

    SnowWhite back in action
    SnowWhite back in action

    In truth, an Atom isn’t quite up to the demands of modern 3D printing, either, at least in terms of processing a huge G-Code file into a layer-by-layer path preview. Fortunately, Pronterface doesn’t generate the preview until you ask for it: arranging the UI to put the preview on a separate tab eliminates that problem.

    The Mini 10 can dribble G-Code into the printer just fine and looks much cuter than the hulking laptop in the background.

  • Ersatz 5.5 mm Nut Driver

    A tiny 1/4 inch hex driver handle appeared from the far reaches of a drawer, sporting a handle better suited for tweaking the 3 mm adjusting nuts on the bottom of the M2’s platform than applying actual torque to real fasteners. Rather than breaking a set of nut drivers, I made a simple brass shim to soak up the difference between the handle’s 6.5 mm ID hex and the 5.5 mm OD of the nuts:

    Hex driver shim - installed
    Hex driver shim – installed

    That’s 15 mil = 0.40 mm shimstock to leave enough clearance for my crude forming technique.

    Which technique consisted of making a “mandrel” by lining up a trio of Nyloc nuts on a screw, snipping off a suitable shimstock rectangle, and squashing it into shape with parallel-jaw pliers:

    Hex driver shim - forming
    Hex driver shim – forming

    As you’d expect, the shimstock hex came out larger & uglier than the mandrel:

    Hex driver shim - formed
    Hex driver shim – formed

    But that doesn’t matter after it’s tucked inside the driver; it works perfectly.

    Took less time to do than to write up …

  • APRS/GPS + Voice Interface: Improved PTT Button Cap

    Long ago, Mary picked out a PTT switch with a raised, square post that provided a distinct shape and positive tactile feedback:

    PTT Button - bare post
    PTT Button – bare post

    Time passes, she dinged her thumb in the garden, and asked for a more rounded button. I have some switches with rounded caps, but replacing the existing switch looked a lot like work, sooooo:

    PTT Button Cap - Slic3r preview
    PTT Button Cap – Slic3r preview

    As with all small objects, building them four at a time gives the plastic in each one time to cool before slapping the next layer on top:

    PTT Button - on platform
    PTT Button – on platform

    The hole in the cap is 0.2 mm oversize, which results in a snug press fit on the small ridges barely visible around the post in the first image:

    PTT Button - rounded cap
    PTT Button – rounded cap

    Rather than compute the chord covering the surface, I just resized a sphere to twice the desired dome height (picked as 6 threads, just for convenience) and plunked it atop a cylinder. Remember to expand the sphere diameter by 1/cos(180/sides) to make it match the cylinder and force both to have the same number of sides.

    If it falls off, I have three backups.

    The OpenSCAD source code as a GitHub Gist:

    // PTT Button cap
    // Ed Nisley KE4ZNU – June 2016
    //- Extrusion parameters – must match reality!
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    Protrusion = 0.1;
    HoleWindage = 0.2;
    //——
    // Dimensions
    Post = [3.8,3.8,3.0];
    OD = 0;
    HEIGHT = 1;
    DOMEHEIGHT = 2;
    Button = [12,0+Post[2],6*ThreadThick];
    NumSides = 8*4;
    //———————-
    //- Build it
    difference() {
    union() {
    translate([0,0,Button[HEIGHT]])
    resize([0,0,2*Button[DOMEHEIGHT]])
    sphere(d=Button[OD]/cos(180/NumSides),$fn=NumSides);
    cylinder(d=Button[OD],h=Button[HEIGHT],$fn=NumSides);
    }
    translate([0,0,Post[2]/2 – Protrusion])
    cube(Post + [HoleWindage,HoleWindage,Protrusion],center=true);
    }
  • M2 Platform Alignment Check

    As part of setting the Makergear M2 up after The Great Cleanout, I ran off a set of thinwall calibration squares that showed the left rear corner was high by 0.12 mm: the square in that corner measured 2.88 mm, rather than the intended 3.0 mm. The walls were 0.43 mm, about 10% above the nominal 0.40 mm.

    That’s similar in both absolute values and alignment to the measurements from two months back.

    I tightened the rear platform screw by a bit under 1/12 turn, less than half a flat on the hex nut, and dialed the Extrusion Multiplier back by 10%. The next set of squares, set up for walls made of three parallel threads, came out with heights within 0.08 mm of each other and 1.15 mm thick (rather than the nominal 1.20 mm).

    They’re 40 mm on a side, mostly to produce bigger handouts for the next show-n-tell:

    Thinwall open box - array on platform - 3w 40 3.0
    Thinwall open box – array on platform – 3w 40 3.0

    Letting it sit for a few days and running the same G-Code produced heights within 0.07 mm and wall thickness at 1.18, which I defined to be Good Enough.

    Recent versions of Slic3r have been adjusting the various thread widths on the fly, as I’ve let everything except the basic extrusion width go with the default values. As a result, setting the wall width to 2 threads (0.80 mm) can produce an extremely thin third thread between the two perimeter threads that doesn’t extrude well. Making the wall three threads wide works much better:

    Calibration Box - open - 3w 40 3.0
    Calibration Box – open – 3w 40 3.0

    The slicing algorithms may be smart enough to make all the tricks I’ve learned completely obsolete; that’s fine with me!

    The raw measurements:

    Calibration box measurements - 2016-06
    Calibration box measurements – 2016-06
  • Clover Seam Ripper Cap

    Mary wanted a rigid cap for a Clover seam ripper that came with a small plastic sheath, so I called one from the vasty digital deep:

    Clover Seam Ripper - new cap
    Clover Seam Ripper – new cap

    The solid model looks about like you’d expect, with a brim around the bottom to paste it on the platform:

    Clover Seam Ripper Cap - Slic3r preview
    Clover Seam Ripper Cap – Slic3r preview

    I added a slightly tapered entry to work around the usual tolerance problems:

    Clover Seam Ripper Cap - bottom view
    Clover Seam Ripper Cap – bottom view

    The taper comes from a hull wrapped around eight small spheres:

    Clover Seam Ripper Cap - Entry Pyramid
    Clover Seam Ripper Cap – Entry Pyramid

    That’s surprisingly easy to accomplish, at least after you get used to this sort of thing:

    hull() {																		// entry taper
    	for (i=[-1,1] , j=[-1,1])
    		translate([i*(HandleEntry[0]/2 - StemRadius),j*(HandleEntry[1]/2 - StemRadius),0])
    			sphere(r=StemRadius,$fn=4*4);
    	for (i=[-1,1] , j=[-1,1])
    		translate([i*(HandleStem[0]/2 - StemRadius),j*(HandleStem[1]/2 - StemRadius),HandleEntry[2] - StemRadius])
    			sphere(r=StemRadius,$fn=4*4);	
    }
    

    The side walls are two threads thick and, at least in PETG, entirely too rigid to slide on easily. I think a single-thread wall with a narrow ridge would provide more spring; if this one gets too annoying, I’ll try that.

    The OpenSCAD source code as a GitHub gist:

    // Clover seam ripper cap
    // Ed Nisley KE4ZNU – April 2016
    //- Extrusion parameters – must match reality!
    // Build with a 5 mm brim to keep it glued to the platform
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    Protrusion = 0.1;
    //——
    // Dimensions
    StemRadius = 0.50; // corner radius
    HandleStem = [6.1, 7.1, 9.0];
    HandleEntry = HandleStem + [1.0,1.0,-4.0]; // Z is -(straight part of stem)
    Cap = [8.5,11.0,45.0]; // XY exterior, Z interior
    //———————-
    //- Build it
    difference() {
    union() {
    translate([0,0,Cap[2]/2]) // main body column
    cube(Cap,center=true);
    translate([-Cap[0]/2,0,Cap[2]]) // rounded cap
    rotate([0,90,0])
    cylinder(d=Cap[1],h=Cap[0],$fn=8*4);
    translate([Cap[0]/2 – Protrusion,0,(Cap[2] + Cap[1]/2)/2]) // text
    rotate([0,90,0])
    linear_extrude(height=ThreadWidth,convexity=10)
    text("Mary Nisley",halign="center",valign="center",size=0.5*Cap[1],font="Arial");
    }
    hull() // stem + blade clearance
    for (i=[-1,1] , j=[-1,1])
    translate([i*(HandleStem[0]/2 – StemRadius),j*(HandleStem[1]/2 – StemRadius),-Protrusion])
    cylinder(r=StemRadius,h=Cap[2] + Protrusion,$fn=4*4);
    hull() { // entry taper
    for (i=[-1,1] , j=[-1,1])
    translate([i*(HandleEntry[0]/2 – StemRadius),j*(HandleEntry[1]/2 – StemRadius),0])
    sphere(r=StemRadius,$fn=4*4);
    for (i=[-1,1] , j=[-1,1])
    translate([i*(HandleStem[0]/2 – StemRadius),j*(HandleStem[1]/2 – StemRadius),HandleEntry[2] – StemRadius])
    sphere(r=StemRadius,$fn=4*4);
    }
    }