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

Making the world a better place, one piece at a time

  • 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();
    
    
  • 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);
    }
    
  • PVC Cement Can Lid Griptivity Improvement

    I’ve been doing a lot of fiddly gluing lately and, despite my best efforts, some adhesive collects in the lid’s screw threads. The gummy residue makes it really hard to unscrew the lid without a strap wrench after a few days.

    Wrapping two turns of silicone tape around the cap helps tremendously:

    Silicone tape on PVC cement can lid
    Silicone tape on PVC cement can lid

    It’s obvious in retrospect, is all I can say…

  • Dehumidified Processor Crackers

    The cracker recipe I’m using produces eight sets of crackers, so this time I added a variety of toppings to see what would work out best:

    • Plain
    • Salt
    • Sugar
    • Cinnamon
    • Garlic
    • Chopped chocolate
    • Chopped cashews
    • Chopped walnuts

    Garlic wins over everything else, hands-down, no contest, but the mixture of all the toppings in the bottom of the cooling bowl was wonderful.

    The crackers went into a large pot with a bag of desiccant:

    Whole wheat crackers with desiccant
    Whole wheat crackers with desiccant

    It pulled out 30 grams of water while reducing the humidity to 20% overnight; the crackers started out crisp and became really snappy. Definitely the right way to get the job done.

    These vaguely resemble the Processor Crackers recipe in Flatbreads & Flavors (Alford & Duguid):

    • 3 C hard whole wheat flour
    • 1 tsp salt
    • 1 C warm water, more as needed
    • Toppings
    • Water sprayer

    I’m using coarse-ground red wheat that doesn’t soak up the water like fine-ground flour. The original recipe called for 1-½ C water, which produced a sticky ball.

    • Blend wheat & salt in food processor
    • Add water in a slow stream until dough firms up
    • Blend another minute
    • Knead half a minute on cutting board
    • Cover
    • Let rest 30 minutes while you prepare toppings

    Finely chopped toppings work best; the nuts were too coarse.

    • Preheat oven to 500 °F
    • Divide dough in eight pieces, cover

    For each piece of dough:

    • Roll to about 2 mm
    • Put dough on vented pizza pan
    • Cut cracker shapes with pizza cutter
    • Sprinkle topping
    • Spritz with water
    • Put in oven on top rack
    • Punch timer for 3 minutes
    • Prepare next piece
    • Swap pans
    • Iterate

    Toss the crackers into a big bowl to cool, sampling as needed.

    When crackers cool:

    • Dump into large pot
    • Add desiccant bag & humidity card
    • Cover
    • Snarf combined toppings from bowl
    • Leave crackers to dry overnight

    Wonderful!

    Memo to Self: Shredded Parmesan cheese would be pretty good…

  • 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…

  • Kitchen Spatula Handle Anchoring

    Shortly after we bought this kitchen scraper spatula (or whatever it’s called), the handle pulled out of the blade and left it sitting in a bowl of batter. That turned out to be unsurprising, given that neither side of the interface has any mechanical locking features. I rinsed the batter off, stuck some urethane glue inside, rammed the handle in place, and hoped for the best. Lacking any mechanical interlock and not bonding to either surface, the adhesive didn’t improve the situation.

    So I recently added a pair of stainless 4-40 setscrews standing just proud of the handle’s surface that should dig into the blade and hold it in place:

    Spatula handle enhancement
    Spatula handle enhancement

    Another item for the shopping list…

  • Broom Handle Screw With Dedendum: Effect of Printing Orientation

    Although the current OpenSCAD could produce a solid model with the screw thread’s dedendum, I’d never actually printed one of them:

    Broom Handle Screw - full thread - solid model
    Broom Handle Screw – full thread – solid model

    I need some fondlestuff illustrating how to handle overhangs, so I ran one standing vertically, which (pretty much as I expected) didn’t work well at all:

    Broom Handle Screw - dedendum - vertical
    Broom Handle Screw – dedendum – vertical

    The trick is to split the model down the middle:

    Broom Handle Screw - horizontal top
    Broom Handle Screw – horizontal top

    And put holes in each half for alignment pins:

    Broom Handle Screw - horizontal bottom
    Broom Handle Screw – horizontal bottom

    Then you can print it lying down:

    Broom Handle Screw - horizontal - as-printed top
    Broom Handle Screw – horizontal – as-printed top

    The internal overhang would probably call for some support material, particularly in the square recess at the end, but in this case it’s a lesson:

    Broom Handle Screw - horizontal - as-printed bottom
    Broom Handle Screw – horizontal – as-printed bottom

    Glue some filament snippets into the holes, snap it together, and it looks just fine over there on the right:

    Broom Handle Screw - orientation comparison
    Broom Handle Screw – orientation comparison

    Doesn’t matter how many I print, it still doesn’t make any economic sense as a broom repair…

    The OpenSCAD source code now has a Layout variable to control the orientation and, not as shown in the model, the alignment pins have glue gutters in the first layer:

    // Broom Handle Screw End Plug
    // Ed Nisley KE4ZNU October 2013
    
    Layout = "Horizontal";		// Vertical Horizontal Pin
    
    UseDedendum = true;			// true to create full thread form
    
    //- Extrusion parameters must match reality!
    
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    Protrusion = 0.1;			// make holes end cleanly
    
    //----------------------
    // Dimensions
    
    PostOD = 22.3;				// post inside metal handle
    PostLength = 25.0;
    
    FlangeOD = 24.0;			// stop flange
    FlangeLength = 3.0;
    
    PitchDia = 15.5;			// thread center diameter
    ScrewLength = 20.0;
    
    ThreadFormOD = 2.5;			// diameter of thread form
    ThreadPitch = 5.0;
    NumSegments = 32;			//  .. number of cylinder approximations per turn
    
    BoltOD = 7.0;				// clears 1/4-20 bolt
    BoltSquare = 6.5;			// across flats
    BoltHeadThick = 3.0;
    
    RecessDia = 6.0;			// recesss to secure post in handle
    
    OALength = PostLength + FlangeLength + ScrewLength;
    
    SplitOC = 1.25*FlangeOD;	// separation in Horizontal layout
    PinOD = 1.75;				// alignment pin diameter = filament stub
    PinLength = 7.0;			//  ... length
    
    $fn=8*4;					// default cylinder sides
    
    echo("Pitch dia: ",PitchDia);
    echo("Root dia: ",PitchDia - ThreadFormOD);
    echo("Crest dia: ",PitchDia + ThreadFormOD);
    
    Pi = 3.14159265358979;
    
    //----------------------
    // Useful routines
    
    // Wrap cylindrical thread segments around larger plug cylinder
    
    module CylinderThread(Pitch,Length,PitchDia,ThreadOD,PerTurn) {
    
    CylFudge = 1.02;				// force overlap
    
        RotIncr = 1/PerTurn;
        PitchRad = PitchDia/2;
    
        Turns = Length/Pitch;
        NumCyls = Turns*PerTurn;
    
        ZStep = Pitch / PerTurn;
    
        HelixAngle = atan(Pitch/(Pi*PitchDia));
        CylLength = CylFudge * (Pi*(PitchDia + ThreadOD) / PerTurn) / cos(HelixAngle);
    
    	for (i = [0:NumCyls-1]) {
    		assign(Angle = 360*i/PerTurn)
    			translate([PitchRad*cos(Angle),PitchRad*sin(Angle),i*ZStep])
    				rotate([90+HelixAngle,0,Angle])
    					cylinder(r1=ThreadOD/2,
    							r2=ThreadOD/(2*CylFudge),
    							h=CylLength,
    							center=true,$fn=12);
    	}
    }
    
    // Build complete plug
    
    module ScrewPlug() {
    	difference() {
    		union() {
    			cylinder(r=PostOD/2,h=PostLength);
    			cylinder(r=PitchDia/2,h=OALength);
    			translate([0,0,PostLength])
    				cylinder(r=FlangeOD/2,h=FlangeLength);
    			color("Orange")
    			translate([0,0,(PostLength + FlangeLength)])
    				CylinderThread(ThreadPitch,(ScrewLength - ThreadFormOD/2),PitchDia,ThreadFormOD,NumSegments);
    		}
    
    		translate([0,0,-Protrusion])
    			PolyCyl(BoltOD,(OALength + 2*Protrusion),6);
    
    		translate([0,0,(OALength - BoltHeadThick)])
    			PolyCyl(BoltSquare,(BoltHeadThick + Protrusion),4);
    
    		if (UseDedendum)
    			translate([0,0,(PostLength + FlangeLength + ThreadFormOD/2 - ThreadPitch/(2*NumSegments))])
    				rotate(-90 - 360/(2*NumSegments))
    				CylinderThread(ThreadPitch,ScrewLength,PitchDia,ThreadFormOD,NumSegments);
    
    		for (i = [0:90:270]) {
    			rotate(45 + i)					// 45 works better with Horizontal layout
    				translate([PostOD/2,0,PostLength/2])
    					sphere(r=RecessDia/2,$fn=8);
    		}
    	}
    }
    
    // Locating pin hole with glue recess
    
    module LocatingPin() {
    
    	translate([0,0,-ThreadThick])
    		PolyCyl((PinOD + 2*ThreadWidth),2*ThreadThick,4);
    	translate([0,0,-(PinLength/2 + ThreadThick)])
    		PolyCyl(PinOD,(PinLength + 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);
    
    }
    
    //-------------------
    // Build it...
    
    ShowPegGrid();
    
    if (Layout == "Vertical")
    	ScrewPlug();
    
    if (Layout == "Pin")
    	LocatingPin();
    
    if (Layout == "Horizontal")
    	for (i=[-1,1])
    		difference() {
    			translate([i*SplitOC/2,PostLength/2,0])
    				rotate([90,180*(i + 1)/2,0])
    					ScrewPlug();
    
    			translate([0,0,-FlangeOD/2])
    				cube([2*OALength,2*OALength,FlangeOD],center=true);
    
    			for (j=[-1,1], pin=[-1,1])
    				assign(PinX = i*SplitOC/2 + pin*(PostOD + BoltOD)/4,
    					   PinY = j*PostLength/4) {
    					translate([PinX,PinY,0])
    						rotate(45)
    							LocatingPin();
    					echo("i j pin: ",i,j,pin);
    					echo("X Y: ",PinX,PinY);
    				}
    		}