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

  • Chip-on-board LED Desk Lamp Retrofit

    After the 5 mm white LEDs failed on the original desk lamp rebuild, I picked up some chip-on-board LED lamps from the usual eBay supplier:

    COB LED Desk Lamp - bottom
    COB LED Desk Lamp – bottom

    The LED’s aluminum baseplate (perhaps there’s an actual “board” inside the yellow silicone fill) is firmly epoxied to a small heatsink from the Big Box o’ Heatsinks, chosen on the basis of being the right size and not being too battered.

    The rather limited specs say the LED supply voltage can range from 9 to 12 V, suggesting a bit of slack, with a maximum dissipation of 3 W, which definitely requires a heatsink.

    The First Light test looked promising:

     COB LED Desk Lamp - first light
    COB LED Desk Lamp – first light

    That’s driven from the same 12 VDC 200 mA wall wart that I used for the failed ring light version. Measuring the results shows that the supply now runs at the ragged edge of its current rating, with the output voltage around 10.5 V with plenty of ripple:

    COB LED V I 100ma div
    COB LED V I 100ma div

    The 260 mA current (bottom, trace 1 at 100 mA/div) varies from 200 to 300 mA as the voltage (top, trace 2 at 2 V/div) varies between 10 V and a bit under 11 V. If you believe the RMS values, it’s dissipating 2.7 W and the heatsink runs at a pleasant 105 °F in an ordinary room. The wall wart gets about as warm as you’d expect; it contains an old heavy-iron transformer and rectifier, not a trendy switcher.

    The heatsink mount looks nice, in a geeky way:

    COB LED Desk Lamp - side detail
    COB LED Desk Lamp – side detail

    The left side must be that long to anchor the gooseneck; I thought about tapering the slab a bit, but, really, it’s OK the way it is. Dabs of epoxy hold the gooseneck and heatsink in place.

    The heatsink rests on a small ledge at the bottom of the slab that’s as tall as the COB LED is thick, with a wire channel from the gooseneck socket:

    COB LED Heatsink mount - Slic3r
    COB LED Heatsink mount – Slic3r

    The Hilbert Curve infill on the top produces a textured finish; I’m a sucker for that pattern.

    The old lamp base isn’t particularly stylin’, but the new head lights up my desk below the big monitors without any glare:

    COB LED Desk Lamp - overview
    COB LED Desk Lamp – overview

    Now, let’s see how long this one lasts…

    The OpenSCAD source code as a Github gist:

  • Slic3r vs. Sequential 3D Printing

    The tiny posts on the fencing helmet ear grommet produced a remarkable amount of PETG hair, because the nozzle had to skip between four separate pieces on the platform at each layer:

    So I told Slic3r to build each part separately:

    Fencing helmet grommet - separate builds - first attempt
    Fencing helmet grommet – separate builds – first attempt

    Due to absolutely no forethought or planning on my part, that actually worked. Slic3r defines a cylindrical keep-out zone around the nozzle that I set to 15 mm radius and 25 mm height, but those numbers are completely wrong for the M2, particularly with a V4 hot end.

    To the rear, the nuts & bolts along the bottom of the X gantry sit 5 mm above the V4 nozzle, with the relaxed actuator on my re-relocated Z-axis home switch at Z=+1 mm:

    V4 PETG - extruder priming
    V4 PETG – extruder priming

    To the front, the bed fan doesn’t sit much higher:

    M2 V4 Extruder - 24 V fans
    M2 V4 Extruder – 24 V fans

    As it turned out, the front washers built first, sitting there in front of the gantry and behind the fan, the rear washers appeared last, and Everything Just Worked.

    However, even though the M2’s layout won’t allow for automated layout, I figured I could do it manually by building the parts from front to rear:

    Fencing Helmet Ear Grommet - Slic3r layout
    Fencing Helmet Ear Grommet – Slic3r layout

    That way, the already-built parts never pass under the gantry / switch. For particularly tall parts, I could remove / relocate the bed fan to clear the already-built parts as they appear.

    Come to find out that Slic3r, for whatever reason, doesn’t build the parts in the order you’d expect from the nice list on the far right side of the screen:

    Sequential Build Order - Slic3r vs Pronterface
    Sequential Build Order – Slic3r vs Pronterface

    Worse, the Slic3r 3D preview shows the threads by layer (which is what you’d expect), rather than by object for sequential builds:

    Slic3r - sequential preview vs build order
    Slic3r – sequential preview vs build order

    I don’t know how you’d force-fit a four-dimensional preview into the UI, so I won’t complain at all.

    There’s no way to tell which part will build first; selecting the part will highlight its entry in the list (and vice versa), but the order of appearance in that list doesn’t tell you where the G-Code will appear in the output file. That’s not a problem for extruders with a keep-out volume that looks like a cylinder, so there’s no reason for Slic3r to do it any differently: it will manage the extruder position to clear all the objects in any order.

    The Pronterface preview creates the objects by reading the G-Code file and displaying the threads in order, so, if you’re quick and it’s slow, you can watch the parts appear in their to-be-built order. The detailed preview (in the small window on the right in the screenshot) does show the parts in the order they will be built as you scroll upward through the “layers”, which is the only way you can tell what will happen.

    So doing sequential builds requires iterating through these steps until the right answer appears:

    •  Add all objects separately to get each one as a separate line in the list to the right
      • Using the More option to duplicate objects produces multiple objects per line = Bad Idea
    • Arrange objects in a line from front to back
    • Export G-Code file
    • Load G-Code file into Pronterface
    • Pop up the Pronterface layer preview, scroll upward to show build order, note carefully
    • Rearrange parts in Slic3r accordingly

    That’s do-able (note the different order from the Slic3r preview):

    Fencing helmet grommet - manual sequential build
    Fencing helmet grommet – manual sequential build

    But it’s tedious and enough of a pain that it probably makes no sense for anything other than parts that you absolutely can’t build any other way.

    In this case, completing each of the bottom washers separately eliminated all of the PETG hair between the small pegs. The upper washers still had some hair inside the inner cylinder, but not much. If you were fussy, you could suppress that by selecting “Avoid crossing perimeters”, at the cost of more flailing around in the XY plane.

    All those spare grommets will make a good show-n-tell exhibit…

  • Blue Gauntlet Fencing Helmet Ear Grommet

    Our Larval Engineer practiced fencing for several years, learning the fundamental truth that you should always bring a gun to a knife fight:

    Fencing - taking a hit
    Fencing – taking a hit

    It’s time to pass the gear along to someone who can use it, but we discovered one of the ear grommets inside the helmet had broken:

    Blue Gauntlet M003-BG Helmet - broken ear grommet
    Blue Gauntlet M003-BG Helmet – broken ear grommet

    The cylinder in the middle should be attached to the washer on the left, which goes inside the helmet padding. It’s a tight push fit inside the washer on the right, which goes on the outside of the padding. Ridges along the cylinder hold it in place.

    Being an injection-molded polyethylene part, no earthly adhesive or solvent will bother it, soooo… the solid model pretty much reproduces the original design:

    Fencing Helmet Ear Grommet - show
    Fencing Helmet Ear Grommet – show

    The top washer goes inside the padding against your (well, her) ear, so I chamfered the edges sorta-kinda like the original.

    There are no deliberate ridges on the central cylinder, but printing the parts in the obvious orientation with no additional clearance makes them a very snug push fit and the usual 3D printing ridges work perfectly; you could apply adhesive if you like. The outside washer has a slight chamfer to orient the post and get it moving along.

    The posts keep the whole affair from rotating, but I’m not sure they’re really necessary.

    Printing a pair doesn’t take much longer than just one:

    Fencing Helmet Ear Grommet - build
    Fencing Helmet Ear Grommet – build

    It doesn’t look like much inside the helmet:

    Blue Gauntlet M003-BG - replacement ear grommet - installed
    Blue Gauntlet M003-BG – replacement ear grommet – installed

    The OpenSCAD source code as a gist from Github:

  • Kenmore Progressive Vacuum Cleaner vs. Classic Electrolux Dust Brush

    Vacuum cleaner dust brushes, separated by millimeters and decades:

    Kenmore vs adapted Electrolux dust brushes
    Kenmore vs adapted Electrolux dust brushes

    The bulky one on the left came with our new Kenmore Progressive vacuum cleaner. It’s fine for dust on a flat horizontal or vertical surface and totally useless for dust on actual objects. It’s supposed to snap around the handle at the end of the cleaner’s flexy hose, where it helps make the entire assembly too large and too clumsy, or on the end of the “wand”, where it’s at the wrong angle. The bonus outer shell slides around the stubby bristles in the unlikely event they’re too long for the flat surface at hand.

    The brush on the right emerged from the Box o’ Electrolux Parts that Came With The House™, must be half a century old, and consists of a cast aluminum lump with various holes milled into it, adorned with luxuriously long and flexible horsehair. Suffice it to say they don’t make ’em like that any more. Heck, they probably don’t make horses with hair like that any more, either.

    The blue plastic adapter atop the aluminum ball looks like you’d expect by now:

    Electrolux Brush Adapter
    Electrolux Brush Adapter

    The short snout fits neatly into the space available inside the ball. The abrupt ledge at the top of the snout, of course, didn’t work well; I rushed the design for a show-n-tell.

    The OpenSCAD source code (as a Github gist) bevels that ledge and tweaks the interior air channel a bit:

    That’s  supposed to prevent the WordPress post editors from destroying the formatting…

  • Gorilla Glue: Cured in the Bottle

    So the dishwasher ate another rack protector, which happens a few times a year. I’m getting low on spares, so maybe it’s time to run off a few in cyan PETG to see if the cute support structure will still be removable:

    Dishwasher rack protector - support model
    Dishwasher rack protector – support model

    Anyhow, this time I used urethane glue, because the last of the acrylic caulk went into another project. I store the Gorilla Glue bottle upside-down so the entire top doesn’t cure solid, but:

    Gorilla Glue - cured in bottle
    Gorilla Glue – cured in bottle

    Usually, it’s just cured in the snout. This time, the layer across the bottom was a few millimeters thick and the glue below seemed rather thick. I tossed the solid lump, slobbered a dab of thick goo on the dishwasher rack, jammed the new protector in place, replaced the cap, and declared victory.

    That’s why I no longer buy that stuff in The Big Bottle…

     

  • Whirlpool Refrigerator Drawer Strut Tab Replacement

    The tab supporting the strut with the center slides for the lower drawers in our Whirlpool refrigerator broke of its own accord. This is a problem of long standing, somewhat exacerbated by the fact that lifting the strut will break the tab without much effort at all, but this time the drawers pulled the strut downward hard enough to not only break the tab, but also tear the small tabs that align the bracket right out of the frame.

    While pondering the problem, I glued the broken chunk back into the frame:

    Refrigerator Drawer Strut - clamping front plate
    Refrigerator Drawer Strut – clamping front plate

    We agreed that, after nigh onto two decades, it would be OK to swap the position of the two drawers, so as to let the strut use the undamaged part of the frame seen below. Presumably, we’ll eventually get used to having the apples on the right and the veggies on the left.

    But it was obvious Something Serious Had To Be Done about the tab.

    The tab should align like this inside the frame:

    Refrigerator Drawer Strut Tab - alignment
    Refrigerator Drawer Strut Tab – alignment

    The rightmost part of the tab rests atop a U-shaped metal bar that also supports and stiffens the entire front of the frame, but cantilevering the weight of both drawers on that extended tab overpowered my last attempt at making a glue joint. Soooo, I decided to build a (wait for it …) 3D printed part that screws firmly to the front of the strut.

    The first step involved introducing the strut to Mr Belt Sander to strip the wreckage of the OEM tab from the front end (visible through the opening) and smooth things out, then measuring the remainder. The locating flange inside the frame almost defeated me, but eventually I found a tool that fit inside the strut opening and around the flange:

    Refrigerator Drawer - measuring flange
    Refrigerator Drawer – measuring flange

    Which produced a sketch of the key dimensions:

    Refrigerator Drawer Strut - Dimension Doodles
    Refrigerator Drawer Strut – Dimension Doodles

    Which became an extruded polygon with a few holes punched in the side:

    Refrigerator Shelf Strut Tab - solid model
    Refrigerator Shelf Strut Tab – solid model

    Building it standing up wraps the plastic threads around the entire tab and stacks the layers along the length of the tab. Doing it lying down in the obvious hump-up orientation would put the layers parallel to the bottom surface, where they can pull apart under load.

    The key innovation here involves being willing to assemble the tab to the strut in situ, without insisting it fit through the frame opening and be more-or-less easily removable. That let me bulk up the tab to match the end of the strut, fill the entire frame opening with plastic, and get enough bulk for a pair of 4-40 screws that, being loaded in shear, should withstand the weight of all those fruits & veggies in the drawers.

    The screws simply thread into the holes in the tab, without benefit of tapping. The OpenSCAD code now includes a pair of nut traps, but I’m hoping they won’t be needed.

    The new tab really does fill the space available:

    Refrigerator Drawer Strut - new tab in place
    Refrigerator Drawer Strut – new tab in place

    The OpenSCAD code now moves the notch half a millimeter further away from the strut to center it over the ridge. What’s not obvious is how the frame slants toward the tab over the U-bar: the tab just barely clears and probably should have a tapered nose. You may add that if you like.

    The U-shaped bar constrains the tab pretty firmly and supports the end, which should now be plump enough to withstand the forces involved. The screws sit horizontally with the frame installed and can’t pull out, which is why I think they can get along without nut traps.

    It’s built in cyan PETG with three perimeter threads and 40% 3D Honeycomb fill, making it essentially a solid block of plastic; it’ll be interesting to see what fails next.

    The OpenSCAD source code, which I hammered out in a white-hot fury:

    // Refrigerator Shelf Strut Tab
    // Ed Nisley KE4ZNU December 2015
    
    //- Extrusion parameters must match reality!
    
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    Protrusion = 0.1;			// make holes end cleanly
    
    inch = 25.4;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    //----------------------
    // Dimensions
    
    TabSize = [20.0,12.0,35.0];							// length from bracket, height, width along front
    
    SlotSize = [3.0,7.0];
    SlotX = 7.0;
    
    TabProfile = [
    	[0,0],
    	[12,0],	[12,7.0],
    	[TabSize[0],7.0], [TabSize[0],TabSize[1]],
    	[SlotX + SlotSize[0]/2,TabSize[1]],
    	[SlotX + SlotSize[0]/2,5.0], [SlotX - SlotSize[0]/2,5.0],
    	[SlotX - SlotSize[0]/2,TabSize[1]],
    	[0,TabSize[1]]
    ];
    
    ScrewY = 7.0;
    ScrewOC = 25.0;
    ScrewOD = 2.5;
    
    NutOD = 6.6;					// across flats
    NutThick = 2.5;
    
    //----------------------
    // 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);
    }
    
    //----------------------
    // Build it
    
    difference() {
    	linear_extrude(height=TabSize[2],convexity=4)
    		polygon(points=TabProfile);
    	
    	for (i=[-1,1]) {
    		translate([-Protrusion,ScrewY,i*ScrewOC/2 + TabSize[2]/2])
    			rotate([0,90,0])
    				rotate(180/6)
    					PolyCyl(ScrewOD,SlotX,6);
    		translate([SlotX - SlotSize[0]/2 - NutThick - Protrusion,ScrewY,i*ScrewOC/2 + TabSize[2]/2])
    			rotate([0,90,0])
    				rotate(180/6)
    					PolyCyl(NutOD,NutThick + SlotSize[0],6);
    	}
    }
    

    Maybe that’ll last until we finally scrap out the refrigerator…

  • Kenmore 158: Presser Foot Screw Shrink

    Mary started doing “ruler quilting” that involves sewing seams aligned with templates, only to find that the thumbscrew holding the (modified) presser foot obscures the view to the left of the needle:

    Kenmore Model 158 - OEM Presser Foot Screw
    Kenmore Model 158 – OEM Presser Foot Screw

    The screw looked to be 6-32 and I wanted to use a socket head cap screw, but thread turns out to be 6-40. Having previously bought the Brownell’s Fillister Head Screw Assortment specifically to solve that problem, all I had to do was cut the screw to length:

    Kenmore Model 158 - Small Presser Foot Screw
    Kenmore Model 158 – Small Presser Foot Screw

    The washer epoxied to the screw provides a bit more bearing surface.

    Rather than putz with a screwdriver, this handle locates itself around the screw head; turn until the blade clicks into the screw slot, then tighten or loosen as needed:

    Kenmore Model 158 - Presser Foot - Driver and Screw
    Kenmore Model 158 – Presser Foot – Driver and Screw

    The chubby driver handle descends directly from the Sherline tommy bar handles and four-jaw chuck speed keys:

    Presser Foot Screw Driver - solid model
    Presser Foot Screw Driver – solid model

    The slot holds a chunk of spring steel (barely visible in the driver’s snout in group photo above) that accounts for the fat shaft around the screw head:

    Presser Foot Screw Driver - top - Slic3r
    Presser Foot Screw Driver – top – Slic3r

    I think the shaft could be a few millimeters narrower, but a bit of meat around the ends of the blade will support it against the torque.

    The screw head slot is about 1 mm and the blade is 0.75 mm. I chopped the blade to fit by whacking the spring with a poorly tempered cold chisel, then flexing across the impact line until it broke. That chisel needed sharpening anyhow.

    A dab of epoxy along the slot edges holds the blade in place. I inserted it flush with the top of the socket, then lined up the screw and pushed, with the steel bottomed out in the screw head and riding down for a perfect fit.

    Then it’s all good!

    The OpenSCAD source code:

    // Presser Foot Screw Driver for Kenmore Model 158
    // Ed Nisley - KE4ZNU - December 2015
    
    use <knurledFinishLib_v2.scad>
    
    //- Extrusion parameters must match reality!
    //  Print with 2 shells and 3 solid layers
    
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.3;			// extra clearance to improve hex socket fit
    
    Protrusion = 0.1;			// make holes end cleanly
    
    inch = 25.4;
    
    //----------------------
    // Dimensions
    
    SocketDia = 5.75;				// generous fit on 6-40 fillister screw head
    SocketDepth = 3.2;
    
    Blade = [9.0,1.0,ceil(SocketDepth + 5)];		// inserted metal driver blade
    echo(str("Blade: ",Blade));
    
    ShaftDia = 1.5*Blade[0];		// un-knurled section diameter
    ShaftLength = 10.0;				//  ... length
    
    KnurlLen = 10.0;				// length of knurled section
    KnurlDia = 18.0;				//   ... diameter at midline of knurl diamonds
    KnurlDPNom = 30;				// Nominal diametral pitch = (# diamonds) / (OD inches)
    
    DiamondDepth = 1.0;				//   ... depth of diamonds
    DiamondAspect = 2;				// length to width ratio
    
    KnurlID = KnurlDia - DiamondDepth;		// dia at bottom of knurl
    
    NumDiamonds = ceil(KnurlDPNom * KnurlID / inch);
    echo(str("Num diamonds: ",NumDiamonds));
    
    NumSides = 4*NumDiamonds;		// 4 facets per diamond
    
    KnurlDP = NumDiamonds / (KnurlID / inch);				// actual DP
    echo(str("DP Nom: ",KnurlDPNom," actual: ",KnurlDP));
    
    DiamondWidth = (KnurlID * PI) / NumDiamonds;
    
    DiamondLenNom = DiamondAspect * DiamondWidth;					// nominal diamond length
    DiamondLength = KnurlLen / round(KnurlLen/DiamondLenNom);		//  ... actual 
    
    TaperLength = 0.50*DiamondLength;
    
    KnobOAL = 2*TaperLength + KnurlLen + ShaftLength;
    
    //----------------------
    // 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() {
    		render(convexity=10)
    		translate([0,0,TaperLength])			// knurled cylinder
    			knurl(k_cyl_hg=KnurlLen,
    				  k_cyl_od=KnurlDia,
    				  knurl_wd=DiamondWidth,
    				  knurl_hg=DiamondLength,
    				  knurl_dp=DiamondDepth,
    				  e_smooth=DiamondLength/2);
    		color("Orange")							// lower tapered cap
    		cylinder(r1=ShaftDia/2,
    					r2=(KnurlDia - DiamondDepth)/2,
    					h=(TaperLength + Protrusion),
    					$fn=NumSides);
    		color("Orange")							// upper tapered cap
    		translate([0,0,(TaperLength + KnurlLen - Protrusion)])
    			cylinder(r2=ShaftDia/2,
    					r1=(KnurlDia - DiamondDepth)/2,
    					h=(TaperLength + Protrusion),
    					$fn=NumSides);
    		color("Moccasin")						// cylindrical extension
    		translate([0,0,(2*TaperLength + KnurlLen - Protrusion)])
    			cylinder(r=ShaftDia/2,h=(ShaftLength + Protrusion),$fn=NumSides);
    
    	}
    	
    	translate([0,0,(KnobOAL - SocketDepth + Protrusion)])
    		PolyCyl(SocketDia,(SocketDepth + Protrusion),8);	// screw head socket
    		
    	translate([0,0,KnobOAL - (Blade[2] - Protrusion)/2])
    		cube(Blade + [0,0,Protrusion],center=true);
    }