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

  • Browning Hi-Power Magazine: Nut Trap Block Trial

    The general idea is to reduce the capacity of a 13 round Browning Hi-Power magazine to 10 rounds, in compliance with the NY Safe Act, using a number of possibly invalid assumptions. The new Firearms tag will produce earlier posts.

    This early prototype tried out the sizes, shapes, and angles, using an M3x0.5 socket head cap screw:

    Browning Hi-Power Magazine Block - solid model - nut trap prototype
    Browning Hi-Power Magazine Block – solid model – nut trap prototype

    The bottom nut trap locates the block on the inner floor plate by capturing the nut. It might need a bit more clearance or a chamfer to allow for brazing material around the nut flats; cleaning up the brazed nut with a file might also help.

    The central trap holds a nut that anchors the block; the trap must be about 50% longer than the nut to allow for thread alignment, because the central hole is a loose tap fit.

    That central nut probably isn’t needed, because you’d fill the central shaft with metal-loaded epoxy, which would form a perfectly serviceable, exactly form-fitting, and utterly non-removable “nut”. The vent from the end of the screw shaft releases air trapped behind the epoxy by the screw; if you don’t have a vent, then air pressure will force the epoxy out of the cavity.

    If the epoxy “nut” is workable, then you can build it in a single piece printed vertically on the platform. Having a split version makes it easier to show off and, in truth, the cemented joint is about as strong as the rest of the object.

    Hot off the M2 3D printer, it looks like this:

    BHP magazine block - prototype nut trap - bare
    BHP magazine block – prototype nut trap – bare

    A few threads droop into the air vent, so that channel should be larger. The overall plastic block may be porous enough to release the air pressure even without a vent.

    With locating pins glued in place and a nut in the central trap:

    BHP magazine block - prototype nut trap
    BHP magazine block – prototype nut trap

    Pretty much as I expected, it doesn’t quite fit in the magazine, because it doesn’t have clearance for the little tab on the inner floor plate that captures the spring.

    One might argue that a plastic block isn’t “permanent”, but it’s definitely not “readily” removed:

    • PLA doesn’t dissolve in common solvents
    • It doesn’t actually melt and flow away at high temperatures
    • It’s protected by the spring and inner floor plate
    • It’s certainly strong enough to resist simple mechanical attacks

    This is a start…

    The OpenSCAD source code, replete with inadequacies:

    // Browning Hi-Power Magazine Plug
    // Ed Nisley KE4ZNU November 2013
    
    Layout = "Show";			// Show Whole Pin Build
    
    CrossSection = 1;			// -1, 0, 1 to select section side or none
    
    Section = (Layout == "Build") ? 1 : CrossSection;		// for cross-section for build
    
    //- Extrusion parameters must match reality!
    //  Print with 2 shells and 3 solid layers
    
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    Protrusion = 0.1;			// make holes end cleanly
    
    //----------------------
    // Dimensions
    
    Angle = 12.5;				// from vertical
    
    EndDia = 10.3;				// an 11/32 inch drill fits
    EndRadius = EndDia / 2;
    
    Length = 24.0;				// front-to-back perpendicular to magazine shaft
    Height = 14.0;				// bottom-to-top, parallel to magazine shaft
    							//  14 = 10 round capacity
    							//  28 = 7 round
    
    RectLength = Length - EndDia;	// block length between end radii
    
    ScrewOD = 3.0 - 0.5;		// bottom screw tapping diameter
    ScrewLength = 11.0;
    ScrewOffset = 0;			//   ... from centerline
    
    NutOD = 5.5;				// hex nut dia across flats
    NutThick = 2.4;				//  ... then add 50% for thread engagement & epoxy
    NutOffset = 6.0;			//  ... base height from floor
    
    VentWidth = 2*ThreadWidth;	// air vent from back of screw recess
    VentDepth = 4*ThreadThick;
    
    NumSides = 8*4;				// default cylinder sides
    
    PinOD = 1.72;				// alignment pins
    PinLength = 6.0;
    PinInset = 0.9*EndRadius;	// from outside edges
    echo(str("Alignment pin length: ",PinLength));
    
    Offset = 5.0/2;				// from centerline for build layout
    
    //----------------------
    // Useful routines
    
    // Locating pin hole with glue recess
    //  Default length is two pin diameters on each side of the split
    
    module LocatingPin(Dia=PinOD,Len=0.0) {
    
    	PinLen = (Len != 0.0) ? Len : (4*Dia);
    
    	translate([0,0,-ThreadThick])
    		PolyCyl((Dia + 2*ThreadWidth),2*ThreadThick,4);
    
    	translate([0,0,-2*ThreadThick])
    		PolyCyl((Dia + 1*ThreadWidth),4*ThreadThick,4);
    
    	translate([0,0,-(Len/2 + ThreadThick)])
    		PolyCyl(Dia,(Len + 2*ThreadThick),4);
    
    }
    
    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 ShowPegGrid(Space = 10.0,Size = 1.0) {
    
      Range = floor(50 / Space);
    
    	for (x=[-Range:Range])
    	  for (y=[-Range:Range])
    		translate([x*Space,y*Space,Size/2])
    		  %cube(Size,center=true);
    
    }
    
    //----------------------
    // Components
    
    module Block(SectionSelect = 0) {
    
    Delta = tan(Angle)*(Length/2);				// incremental length due to angle
    
    CropHeight = Height*cos(Angle);				// block height perpendicular to base
    
    echo(str("Perpendicular height: ",CropHeight));
    
    	difference() {
    		intersection() {
    			rotate([Angle,0,0])
    				difference() {
    					translate([0,0,-Height/2])
    						linear_extrude(height=2*Height,convexity=2) {
    							for (i=[-1,1])
    								translate([0,(i*RectLength/2),0])
    									rotate(180/NumSides)
    										circle(r=EndRadius/cos(180/NumSides),
    												$fn=NumSides);
    							square([EndDia,RectLength],center=true);
    						}
    					for (i=[-1,1])
    						translate([0,
    									(i*(Length/2 - PinInset)),
    									(CropHeight/2 + i*(CropHeight/2 - PinInset))])
    							rotate([0,90,0]) rotate(45-Angle)
    								LocatingPin(PinOD,PinLength);
    				}
    			translate([0,0,CropHeight/2])
    				cube([2*EndDia,3*Length,CropHeight],center=true);
    		}
    		translate([0,ScrewOffset,-Protrusion])		// screw
    			rotate(180/6)
    				PolyCyl(ScrewOD,(ScrewLength + Protrusion),6);
    
    		translate([0,ScrewOffset,NutOffset])		// nut trap in center
    			rotate(180/6)
    				PolyCyl(NutOD,1.5*NutThick,6);
    
    		translate([0,ScrewOffset,-Protrusion])		// nut clearance at base
    			rotate(180/6)
    				PolyCyl(NutOD,(1.1*NutThick + Protrusion),6);
    
    		translate([0,-(ScrewOffset + NutOD),(ScrewLength - Protrusion)/2])	// air vent
    			cube([VentDepth/2,VentWidth,(ScrewLength + Protrusion)],center=true);
    		translate([0,(ScrewOffset - NutOD/2),(ScrewLength - VentWidth/2)])
    			cube([VentDepth/2,NutOD,VentWidth],center=true);
    
    		if (SectionSelect == 1)
    			translate([EndDia,0,Height/2-Protrusion])
    				cube([2*EndDia,3*Length,Height+2*Protrusion],center=true);
    		else if (SectionSelect == -1)
    			translate([-EndDia,0,Height/2-Protrusion])
    				cube([2*EndDia,3*Length,Height+2*Protrusion],center=true);
    	}
    
    }
    
    //-------------------
    // Build it...
    
    ShowPegGrid();
    
    if (Layout == "Pin")
    	LocatingPin(PinOD,PinLength);
    
    if (Layout == "Show")
    	Block(CrossSection);
    
    if (Layout == "Whole")
    	Block(0);
    
    if (Layout ==  "Build") {
    	translate([(Offset + Length/2),Height/2,0])
    		rotate(90) rotate([0,-90,-Angle])
    			Block(-1);
    	translate([-(Offset + Length/2),Height/2,0])
    		rotate(-90) rotate([0,90,Angle])
    			Block(1);
    }
    
  • Samsung Quiet Jet Vacuum: Improved Floor Brush Strips

    Those simple floor brush strips for the Samsung vacuum cleaner worked moderately well, but the urethane adhesive didn’t have enough grip on the plastic strips. Having just run out of that batch, I made up another set with slightly undercut holes:

    Bushing Solid Model - better holes - bottom
    Bushing Solid Model – better holes – bottom

    That’s half a thread width on each side, just enough to give the adhesive something to grab. Such is the plan, anyway.

    I taped the strips to a pair of credit cards (actually, flat cards without embossed characters), slathered a thin layer of urethane atop them, and laid on squares of the same wool fabric I used the last time:

    Samsung vacuum floor strips - gluing
    Samsung vacuum floor strips – gluing

    Then I piled a steel block atop an aluminum slab on both arrays, fast forwarded a day, peeled and flexed and cut the strips apart:

    Samsung floor brushes - glued
    Samsung floor brushes – glued

    The urethane foamed through the holes as I hoped and (seems to have) locked the fabric in place, at least well enough to withstand some experimental bending on the workbench.

    Now, to see how they stand up to actual use…

    The OpenSCAD source code:

    // Samsung Vacuum cleaner nozzle floor strips
    // Ed Nisley KE4ZNU January 2013
    //  November 2013 - adapt to M2, enlarge holes
    
    Layout = "Build";			// Show, Build
    
    //- Extrusion parameters must match reality!
    //  Print with +0 shells and 3 solid layers
    
    ThreadThick = 0.25;
    ThreadWidth = 0.4;
    
    HoleWindage = 0.75;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    Protrusion = 0.1;           // make holes end cleanly
    
    //----------------------
    // Dimensions
    
    Body = [6.0,59.0,3*ThreadThick];	// width, length, thick
    
    Tab1 = [4.5,5.0,0.0];				// width, length, offset from centerline
    Tab2 = [3.5,5.0,0.5];
    
    HoleOC = 8.0;						// adhesive anchoring holes
    HoleDia = 2.0;
    HoleSides = 4;
    HoleMax = floor(Body[1]/(2*HoleOC));
    
    echo("HoleMax: ",HoleMax);
    
    //----------------------
    // 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 ShowPegGrid(Space = 10.0,Size = 1.0) {
    
        Range = floor(50 / Space);
    
        for (x=[-Range:Range])
            for (y=[-Range:Range])
                translate([x*Space,y*Space,Size/2])
                %cube(Size,center=true);
    
    }
    
    module BackingStrip() {
    
    	difference() {
    		union() {
    			translate([0,0,Body[2]/2])
    			cube(Body,center=true);
    			translate([Tab1[2],-1*Body[1]/2,Body[2]/2])
    			cube([Tab1[0],2*Tab1[1],Body[2]],center=true);
    			translate([Tab2[2],+1*Body[1]/2,Body[2]/2])
    			cube([Tab2[0],2*Tab2[1],Body[2]],center=true);
    		}
    		for (i = [-HoleMax:HoleMax])
    			translate([0,i*HoleOC,-Protrusion])
    			rotate(45) {
    				PolyCyl(HoleDia,(Body[2] + 2*Protrusion),HoleSides);
    				PolyCyl((HoleDia + ThreadWidth),(ThreadThick + Protrusion),HoleSides);
    			}
    	}
    }
    
    //----------------------
    // Build it!
    
    ShowPegGrid();
    
    if (Layout == "Show")
    	BackingStrip();
    
    if (Layout == "Build")
    	rotate(90) BackingStrip();
    
    
  • Toyota Sienna Hood Rod Pivot

    We don’t drive the van nearly often enough (*) to keep the battery charged in cold weather, so I use a trickle charger to keep it alive between jaunts. While opening the hood one evening, I managed to twist the plastic fitting that anchors the hood prop rod beyond its limits and snapped the poor thing off, which left me holding the hood in one hand and the rod in the other.

    After extricating most of the fragments from under the van, I found that the OEM part had a hollow post that snapped into a square hole in the front bulkhead under the hood. The post had two keys and a pair of snap latches that held it in place, a design that seemed optimized for rapid assembly with no fiddly parts, but which depended on a few millimeters of plastic to restrain a meter of steel rod.

    I made up a simple replacement with a solid square post and a square cap to clamp it against the bulkhead:

    Toyota Sienna hood rod pivot - first version
    Toyota Sienna hood rod pivot – first version

    The general idea is that the screw puts the entire post under compression, giving it less temptation to shear at the deck line when I twist the rod a bit too far out of line. That 8-32 screw seemed entirely adequate to the task; a 10-32 screw would take up too much of the post for my liking.

    Alas, it turns out that underneath the bulkhead’s top flange lies a metal plate surrounding the headlight that’s so close to the hole that the big blocky cap wouldn’t fit. So I slimmed the cap down to three thread widths and tried again, only to discover that the plate came that close to the edge of square hole.

    However, there was a gap between the bottom of the bulkhead and the top of the plate, so I introduced pivot and cap to Mr Belt Sander, removed enough plastic to let the cap slide into the gap, then discovered the 8-32 screw head was just slightly too large to let the screw align with the post.

    Another tweak to the model, based on actual measurements on the abused parts, produced the final version:

    Toyota Sienna Hood Rod Pivot - solid model
    Toyota Sienna Hood Rod Pivot – solid model

    The rod hole has a nice bevel, there’s no fragile neck between the rod hole and the base flange, the solid post lies flat on the platform for EZ building, and there’s a slight offset between the post and the flange that eliminates the need for support material. Printing it lying down orients the filament paths around the hole and base, making the part stronger in the direction it needs the most strength.

    I think the cap walls could be slightly thicker, but we’ll see how long the thing lasts…

    A group photo of all the versions, lined up from left to right, shows the broken OEM part, the first blocky attempt, the slimmed-down and too-long version to the rear, the shorter version that actually fit, and a backup part for when that one breaks:

    Toyota Sienna hood rod pivot versions
    Toyota Sienna hood rod pivot versions

    The sanded-down part held the hood open while I took that group picture. Here’s what it looks like under load:

    Toyota Sienna hood rod pivot - in place
    Toyota Sienna hood rod pivot – in place

    The scrawls on the bulkhead just in front of the pivot remind me of fluid levels, torques, and suchlike. The stud sticking out to the rear is a headlight aiming screw mounted in the plate that caused so much hassle; you’d think I’d have noticed it before starting this adventure, but noooo

    For what it’s worth, that’s rapid prototyping in action: three (and a half) iterations in quick succession, each getting closer to a goal that you (well, I) can’t quite define, but will recognize when it appears. Took about three hours over the course of two days.

    I loves me my M2 3D printer…

    (*) Indeed, the tires often take three miles to warm up their flat spots due to sitting in the garage for a week…

  • HP Scope Probe Flange Repair: Improved Spares

    While reducing the clutter atop the Electronics Workbench, I ran off four more probe flange reinforcements, just so I’m ready for the next crunch:

    HP scope probe flange disks
    HP scope probe flange disks

    They’re almost identical to the previous version, although I tweaked the taper to end slightly inside the cylindrical cup, thereby eliminating the coincident faces and leaving a minute rim that doesn’t matter:

    HP Scope Probe Flange Repair - bottom
    HP Scope Probe Flange Repair – bottom

    Given that I’ve had the ‘scope for nigh onto two decades and have only broken one probe flange, I think four reinforcements will be a lifetime supply: with any luck, the scope will blow a capacitor before I do.

    The OpenSCAD source code:

    // Tek Scope Probe Flange
    // Ed Nisley KE4ZNU November 2013
    
    //- Extrusion parameters must match reality!
    //  Print with 2 shells and 3 solid layers
    
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    Protrusion = 0.1;            // make holes end cleanly
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    //----------------------
    // Dimensions
    
    FlangeOD = 16.0;
    FlangeID = 8.75;
    FlangeThick = IntegerMultiple(1.25,ThreadThick);
    
    DiskOD = FlangeOD + 4*ThreadWidth;
    DiskThick = FlangeThick + 4*ThreadThick;
    
    NumSides = 8*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 ShowPegGrid(Space = 10.0,Size = 1.0) {
    
    Range = floor(50 / Space);
    
    for (x=[-Range:Range])
    for (y=[-Range:Range])
    translate([x*Space,y*Space,Size/2])
    %cube(Size,center=true);
    
    }
    
    //----------------------
    // Build it
    
    ShowPegGrid();
    
    difference() {
    union() {
    translate([0,0,2*ThreadThick])
    cylinder(r=DiskOD/2,h=DiskThick,$fn=NumSides);    // cylinder around flange
    
    cylinder(r1=(DiskOD - 2*ThreadWidth)/2,                // flange reinforcing plate
    r2=DiskOD/2,
    h=(2*ThreadThick + Protrusion),
    $fn=NumSides);
    }
    translate([0,0,(DiskThick - FlangeThick)])                // flange clearance
    PolyCyl(FlangeOD,2*FlangeThick,NumSides);
    
    translate([0,0,-DiskThick/2])                            // probe nose clearance
    PolyCyl(FlangeID,2*DiskThick,NumSides);
    }
    
  • Marmorated Stink Bug Sighting

    Late in the fall, Brown Marmorated Stink Bugs move indoors to spend the winter; they can infiltrate through the smallest of cracks and seem to show up unannounced in the strangest locations. This one magically appeared on my M2 printer while I was starting it up:

    Brown Marmorated Stink Bug on M2 Printer
    Brown Marmorated Stink Bug on M2 Printer

    I unceremoniously flushed its contribution to the gene pool…

  • Solubility of PLA in Common Gun Bore Cleaners

    According to Wikipedia, Polylactic acid, a.k.a. PLA “is soluble in chlorinated solvents, hot benzene, tetrahydrofuran, and dioxane” and is not soluble in acetone, alcohol, or water.

    Just to see what happens, I dunked a pair of those 3D printed dummy bullets in Shooter’s Choice Gun Solvent (which has since gone obsolete) and Hoppe’s No. 9 Gun Bore Cleaner (which seems to have been reformulated several times), then let them air-dry in those background puddles:

    PLA dummy bullets after solvent bath
    PLA dummy bullets after solvent bath

    Nothing much happened: they’re not soft or gummy, haven’t slumped, and seem undaunted.

    That’s in contrast to ABS plastic, which is readily soluble in acetone and the aromatic hydrocarbons commonly found in solvents used around firearms. Apart from that, ABS would be a slightly better choice on mechanical grounds. I’m not sure the difference really matters for most purposes, given the very wide tolerances on 3D printed objects.

  • Dummy 9 mm Luger Cartridge: 100 μm Layers

    As you might expect, changing the layer thickness to 0.1 mm = 100 μm dramatically improves the appearance of the dummy 9 mm Luger bullet on the left, compared to the 0.25 mm = 250 μm layers on the right:

    Dummy 9 mm Luger cartridges - 0.1 mm layer - overview
    Dummy 9 mm Luger cartridges – 0.1 mm layer – overview

    The inside edge of the translucent skirt around the quartet measured 90 to 110 μm, so the layer height is spot on:

    Dummy 9 mm Luger bullets - 0.1 mm layer - overhead on platform
    Dummy 9 mm Luger bullets – 0.1 mm layer – overhead on platform

    That required no adjustments to the M2 at all; It Just Works. Admittedly, that’s with a custom platform and firm supports replacing the springs, plus better Z-axis homing, but the overall structure was fine to start with.

    I used the same Slic3r settings as before, with the only change being the layer thickness. Letting it pick the layer width might produce better results, but a 0.35 mm nozzle won’t go much narrower than 0.40 mm anyway.

    A closer look at the bullet show the thinner layers provide a better rendition of the stretched sphere forming the nose; it’s less pointy than the one assembled from thicker layers:

    Dummy 9 mm Luger bullets - 0.1 mm layer - side
    Dummy 9 mm Luger bullets – 0.1 mm layer – side

    The nose closes better with thinner layers:

    Dummy 9 mm Luger bullets - 0.1 mm layer - nose
    Dummy 9 mm Luger bullets – 0.1 mm layer – nose

    None of that really matters for this application, but it’s a useful data point.

    The downside is that printing with thinner layers requires more time: a single bullet (of 16) requires 2.2 minutes at 250 μm and (of 4) 9 minutes at 100 μm. The simple ratio of layer thicknesses predicts a factor of 2.5, not 4, but the skirt requires a larger fraction of the total time. The estimated time for a 4×4 array at 100 μm comes out at 5.2 minutes each, a factor of 2.4, which is close enough.

    Although 100 μm certainly looks better, it doesn’t really improve anything for most of the blocky stuff I make…