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: Machine Shop

Mechanical widgetry

  • Tux Cookie Cutter

    Sean asked me to conjure up a Tux cookie cutter for the presentation on DIY 3D Printing and the Makerbot Thing-O-Matic I’m doing at the Mid-Hudson Valley LUG meeting tonight and, as is always the case, it took a bit more conjuring than either of us expected.

    For Tux pix, one should start with Larry Ewing’s drawings; I used the EPS version to get a scalable vector drawing. Run it through The GIMP, close the outline at the flippers, fill with black, save as PNG. Then import into Inkscape, trace the outline, and something like this pops out:

    Tux Outline
    Tux Outline

    The reason for using Inkscape is that OpenSCAD imports a very limited subset of all possible DXF files and, while Inkscape can (with some care) produce a DXF format that OpenSCAD can import, somehow the shape lacked interior fill. Sean took a slightly different approach with the same tools and managed to create a useful DXF file that produced this chunk o’ bits:

    Tux Slab - solid model
    Tux Slab – solid model

    The DXF import still didn’t work dependably, so I exported the Tux Slab from OpenSCAD to an STL file; if you want to extrude a solid Tux, that’s probably the way to go. Importing the STL in the next steps worked fine.

    The Parametric Cookie Cutter by nateoostendorp creates thin cutter walls by subtracting a linear dimension from the X- and Y-axis extents of the shape. Unfortunately, Tux has crazy flipper feet that didn’t respond well to that; the walls developed gaps at the inflection points from self-intersections.

    So I started from scratch with a Minkowski sum, which in this case amounts to rubbing a cylinder all over the Tux shape, then intersecting the resulting mega-penguin-post with a slab of the appropriate thickness sitting on the Z=0 plane. The Minkowski enlarges the XY outline by the cylinder’s radius and the Z thickness by twice the cylinder’s height, which I picked to be grossly excessive. Three Minkowskis produce the lip, wall, and tip of the cutter, which then stack up with a Tux-shaped hole subtracted from their midst:

    Tux Cookie Cutter - solid model
    Tux Cookie Cutter – solid model

    The thicknesses and heights all derive directly from the extrusion parameters used to print the thing, because there’s not much room for roundoff. The middle section (the wall) is four threads wide, but Skeinforge divides the interior pair of threads into shorter sections with breakpoints at each sharp corner. The cutter section (the lip) is one thread wide, because I couldn’t get a good result with two threads.

    The OpenSCAD preview has trouble with the Minkowski result and produces weird rendering glitches, but the CGAL model comes through fine. Note that Tux now has the opposite chirality, a gross oversight that became obvious only after the third cutter emerged from the Basement Laboratory. Here’s the second cutter:

    Tux Cutter - reversed
    Tux Cutter – reversed

    Each cutter takes about 35 minutes to build, so I boiled the highlights down into a thrilling 6 minute movie.

    The OpenSCAD source code, into which you can substitute your very own STL shape file:

    // Tux cookie cutter using Minkowski sum
    // Ed Nisley KE4ZNU - Sept 2011
    
    //- Extrusion parameters - must match reality!
    
    ThreadThick = 0.33;
    ThreadWidth = 2.0 * ThreadThick;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    MaxSize = 110;				// larger than any possible dimension ...
    
    //- Cookie cutter parameters
    
    Size = 100;
    
    TipHeight = IntegerMultiple(8,ThreadThick);
    TipThick = 1*ThreadWidth;
    
    WallHeight = IntegerMultiple(7,ThreadThick);
    WallThick = 4*ThreadWidth;
    
    LipHeight = IntegerMultiple(1.5,ThreadWidth);
    LipThick = IntegerMultiple(5,ThreadWidth);
    
    //- Wrapper for the shape of your choice
    
    module Shape(Size) {
      Tux(Size);
    }
    
    //- A solid slab of Tux goodness in simple STL format
    // Choose magic values to:
    //		center it in XY
    //		reversed across Y axis (prints with handle on bottom)
    //		bottom on Z=0
    //		make it MaxSize from head to feet
    
    module Tux(Scale) {
      STLscale = 250;
      scale(Scale/STLscale)
    	translate([105,-145,0])
    	  scale([-1,1,24])
    		import_stl(
    		  file = "/mnt/bulkdata/Project Files/Thing-O-Matic/Tux Cookie Cutter/Tux Plate.stl",
    		  convexity=5);
    }
    
    //- Given a Shape(), return enlarged slab of given thickness
    
    module EnlargeSlab(Scale, WallThick, SlabThick) {
    
    	intersection() {
    	  translate([0,0,SlabThick/2])
    		cube([MaxSize,MaxSize,SlabThick],center=true);
    	  minkowski() {
    		Shape(Scale);
    		cylinder(r=WallThick,h=MaxSize);
    	  }
    	}
    
    }
    
    //- Put peg grid on build surface
    
    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();
    
    //cube(5);
    
    difference() {
      union() {
    	translate([0,0,(WallHeight + LipHeight)])
    	  EnlargeSlab(Size,TipThick,TipHeight);
    	translate([0,0,LipHeight])
    	  EnlargeSlab(Size,WallThick,WallHeight);
    	EnlargeSlab(Size,LipThick,LipHeight);
      }
      Shape(Size);					// punch out cookie hole
    }
    
  • Stepper Dynamometer: Sync Wheel

    This is a modification of that sync gadget to work on the prototype stepper dynamometer. The key differences:

    • The wheel has a notch rather than a flag
    • The opto switch mounts on a sturdy post

    The wheel fits the shaft with a 4-40 setscrew to hold it in place. The post has 4-40 mounting holes for one of those optical switches, plus a big hole for the wiring. The solid models look about like you’d expect:

    Wheel and post solid model
    Wheel and post solid model

    I located the post’s holes on the baseplate with a spindly pair of transfer punches, after transferring the wheel’s centerline by eyeballometric guesstimation:

    Locating holes with transfer punches
    Locating holes with transfer punches

    Then aligned the baseplate on the Sherline, located the holes, and drilled ’em with manual CNC to get the proper spacing:

    Drilling opto switch post holes
    Drilling opto switch post holes

    And then it went together quite smoothly:

    Dyno with sync wheel
    Dyno with sync wheel

    What’s really nice about 3D printing is you can build stuff like this without too much fuss & bother: figure out the solid model, walk gingerly through the software minefield, and (usually) assemble the parts later that day.

    A bit of wiring to power the LED and pull up the phototransistor should do the trick.

    The OpenSCAD code, including a few tweaks that rationalize spacings and sizes and suchlike:

    // Optical Interrupter for stepper dynamometer
    // Suited for low speed demonstrations!
    // Ed Nisley KE4ZNU August 2011
    
    include </home/ed/Thing-O-Matic/lib/MCAD/units.scad>
    include </home/ed/Thing-O-Matic/Useful Sizes.scad>
    
    // Layout options
    
    Layout = "Build";					// Build Show Wheel Switch
    
    //- Extrusion parameters - must match reality!
    //  Print with +2 shells and 3 solid layers
    
    ThreadThick = 0.33;
    ThreadWidth = 2.0 * ThreadThick;
    
    HoleWindage = 0.3;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    Protrusion = 0.1;
    
    //- Wheel dimensions
    
    ShaftDia = (3/8) * inch;
    ShaftHeight = 27.39;					// from motor mount assembly
    
    HubDia = IntegerMultiple(ShaftDia,ThreadWidth) + 15*ThreadWidth;
    HubLength = IntegerMultiple(10.0,ThreadThick);		// total, not added to plate
    
    SetScrewOffset = 2*Tap4_40;
    SetScrewDia = Tap4_40;
    
    WheelRadius = IntegerMultiple(24.0,ThreadWidth);
    WheelThick = IntegerMultiple(1.5,ThreadThick);
    
    CutoutAngle = (2/50)*360;
    CutoutWidth = WheelRadius*tan(CutoutAngle);
    CutoutDepth = 6.0;
    
    echo(str("Wheel radius: ",WheelRadius," dia: ",2*WheelRadius," thick: ",WheelThick));
    echo(str("Hub sidewall:",(HubDia - ShaftDia)/2));
    echo(str("Cutout width: ",CutoutWidth," angle: ",CutoutAngle," depth: ",CutoutDepth));
    
    //- Optical switch dimensions
    
    OSBaseLength = (31/32) * inch;
    OSBaseWidth = (1/4) * inch;
    OSBaseThick = 0.100 * inch;
    
    OSLeadSpace = 0.300 * inch;							// leads fit though this opening
    
    OSHolesOC = (3/4) * inch;							// switch mounting holes
    OSHoleDia = Tap4_40;
    
    SwHeight = IntegerMultiple((ShaftHeight + OSBaseWidth),ThreadThick);
    SwWidth = IntegerMultiple(OSBaseLength,ThreadWidth);
    SwThick = IntegerMultiple(OSBaseWidth,ThreadWidth);
    
    SwBaseWidth = 4*SwThick;							// pillar base width
    SwBaseOC = IntegerMultiple(2.5*SwThick,1.0);		// base screw spacing
    
    echo(str("Pillar height: ",SwHeight," width: ",SwWidth," thick: ",SwThick));
    echo(str("       base screws: ",SwBaseOC," OC"));
    
    //----------------------
    // 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 Sector(OutR,InR,Thick,Angle) {
    
      difference() {
    	cylinder(r=OutR,h=Thick);
    	cylinder(r=InR,h=Thick);
    
    	rotate([0,0,CutoutAngle/2])
    	  translate([0,OutR,Thick/2])
    		cube([OutR*2,OutR*2,Thick],center=true);
    	rotate([0,0,-CutoutAngle/2])
    	  translate([0,-OutR,Thick/2])
    		cube([OutR*2,OutR*2,Thick],center=true);
      }
    }
    
    //-- Interrupter Wheel
    
    module Wheel() {
    
      difference() {
    	union() {
    	  cylinder(r=WheelRadius,h=WheelThick);			// base plate
    	  cylinder(r=HubDia/2,h=HubLength);				// hub
    	}
    
    	translate([0,0,-Protrusion])						// shaft hole
    	  PolyCyl(ShaftDia,(HubLength + 2*Protrusion));
    
    	translate([0,0,(HubLength - SetScrewOffset)])
    	  rotate([0,270,0])
    		PolyCyl(SetScrewDia,HubDia);
    
    	translate([0,0,-Protrusion])						// sector cutout
    	  Sector((WheelRadius + Protrusion),
    			(WheelRadius - CutoutDepth),
    			(WheelThick + 2*Protrusion),
    			CutoutAngle);
      }
    
    }
    
    //-- Optical Switch Mount
    
    module SwitchMount() {
    
      difference() {
    	union() {											// mounting pillar
    	  translate([0,0,SwHeight/2])
    		cube([SwThick,SwWidth,SwHeight],center=true);
    	  translate([0,0,SwThick/2])
    		cube([SwBaseWidth,SwWidth,SwThick],center=true);
    	}
    
    	translate([0,0,ShaftHeight]) {
    	  translate([-(SwThick/2 + Protrusion),0,0])		// lead clearance slot
    		rotate([0,90,0])
    		  scale([(OSBaseWidth/OSLeadSpace),1,1])
    			PolyCyl(OSLeadSpace,(SwThick + 2*Protrusion));
    
    	  for (y=[-1,1])									// switch screws
    		translate([0,(y*OSHolesOC/2),0])
    		  rotate([0,90,0])
    			cylinder(r=Tap4_40/2,h=(SwThick + 2*Protrusion),center=true,$fn=6);
    	}
    
    	for (x=[-1,1])										// base screws
    	  translate([(x*SwBaseOC/2),0,-Protrusion])
    		rotate([0,0,(x-1)*90])							// get points outward
    		  PolyCyl(Clear4_40,(SwThick + 2*Protrusion));
      }
    
    }
    
    //-------------------
    // Build it!
    
    ShowPegGrid();
    
    if (Layout == "Build") {
      translate([0,WheelRadius,0])
    	Wheel();
      translate([0,-SwWidth,0])
    	SwitchMount();
    }
    
    if (Layout == "Wheel")
      Wheel();
    
    if (Layout == "Switch")
      SwitchMount();
    
    if (Layout == "Show") {
      translate([0,WheelThick/2,ShaftHeight])
    	rotate([90,0,0])
    	  Wheel();
      translate([(WheelRadius + OSBaseThick + SwThick/2),0,0])
    	SwitchMount();
    }
    

    The sizes differ slightly from the photos, but you’d never see the difference.

  • New Clamp Pads: FAIL

    Well, that didn’t work quite right…

    Dislocated clamp pads
    Dislocated clamp pads

    I’d waited for a few days for the silicone to cure, then put the clamps back in their home. When I went to use them, the pads were firmly affixed to the plate. Evidently, the copper-loaded silicone gasket compound takes a few days longer than forever to cure, which is not what I gathered from reading the label.

    It may well be that adhesive has aged out, because when I went to try it again, the first half-inch inside the tube had turned into solid gum. Yes, it cures inside the tube and not outside.

    Other than that, it seems like good stuff; I may pick up another tube and give it a second chance. Who knows? It might be useful in a plastic extruder or something like that.

  • Casio EX-Z850 Camera Buttons Repaired!

    As described there, the buttons on the back of my pocket camera stopped working, but the obvious laying-on-of-hands repair (i.e., wiggling the cables) didn’t improve things. I later discovered out that two other buttons on the side that didn’t go through the same flex cable were also dead, which suggested that the common failure was on the CPU board deep inside the camera. I gave it to my Shop Assistant with some handwaving about how she could maybe fix it by delving deep inside, tracing the cables, and doing some jiggling: if she could fix it, she could have it.

    The first step was to take both covers off, which required a Philips 00 bit:

    EX-Z850 front cover removed
    EX-Z850 front cover removed

    Then the side plate comes off, which requires maneuvering the spring-loaded battery latch out of its recess, at which point the lug for the carry strap will fall out:

    EX-Z850 battery latch and carrying lug
    EX-Z850 battery latch and carrying lug

    En passant, we discovered why the clock dies while changing the battery pack. It seems the miniature rechargeable lithium (?) NiMH (?) cell has rotted out:

    EX-Z850 internal battery corrosion
    EX-Z850 internal battery corrosion

    Fortunately, it charges in a cradle, so the main battery can remain in place indefinitely. We’ll replace that thing at some point.

    The CPU board has two flex cable connectors on the front surface and two on the back. My Shop Assistant released the clamps, removed the cables, wiped down the contacts with DeoxIT Red, gave it a test run with the covers off, and came bounding up the stairs as happy as I’ve ever seen her: the camera worked perfectly again!

    Not being used to these things, though, she managed to crack one of the side latches on the far connector. I’ll admit to doing exactly the same thing, so I knew how to fix it: a dab of acrylic adhesive holds the fragment in place with a bit of springiness to hold the latch down.

    EX-Z850 connector repair
    EX-Z850 connector repair

    The connector in question comes from the flash control board, to which those other two buttons (Ex and Drive mode) connect. The inside of the camera is a maze of connections, so I guess that was the simplest way to get the conductors through the body.

    She reassembled the camera and it continued to work; we declared the job a complete success.

    Shortly after that, I promoted her from Shop Assistant to Larval Engineer, First Instar, and we installed her in her new socket at college, where that camera should come in handy for something.

    I think she’ll ace the Freshman Engineering Practicum, wherein her compadres will learn how to solder components to circuit boards, use multimeters & oscilloscopes & other instruments, and generally survive in a laboratory. Maybe she can wrangle a job as a Lab Assistant?

  • Mower Blade Hub Adapter

    Mower blade compatibility
    Mower blade compatibility

    So I picked up a new mower blade that sported a sticker claiming it probably fit my Craftsman mower. Got it home, took off the old blade, and it actually fit the mower; the holes matched the hub’s drive pins, although the bolt hole was oversized.

    The old blade was a replacement, too, with a square hub hole and an adapter to fit the bolt. The blade had slots for the drive pins, so the adapter was required.

    Seeing as how nothing exceeds like excess, I rummaged around in the heap to find something that would serve as an adapter in the central hole. It’s not really necessary, but I’m that type of guy.

    As it turned out, an ordinary lockwasher for a 3/8 inch bolt was just about perfect. I crunched one in a short bolt with two nuts jammed in place …

    Lockwasher ground for mower blade
    Lockwasher ground for mower blade

    … introduced it to the coarse side of Mr Grinding Wheel, and, after a few shots with a hammer, it became a perfect fit:

    Lockwasher in blade
    Lockwasher in blade

    Bolted it on the mower, put in two hours of yard aerobics, and it worked just fine. Sliced the top off a root that evaded the attention of the previous blade, too.

  • Stepper Dynamometer Mechanics

    Combine two of those mounts with one of those couplers, add two NEMA 17 steppers (the one on the right is that one), slide a baseplate underneath, sprinkle with various screws, and shazam you get a stepper motor dynamometer:

    Stepper Dynamometer
    Stepper Dynamometer

    The baseplate puts the mounts 65 mm apart on the 10-32 screw centers, which is entirely a function of the coupler length, and is easy with manual CNC on the Sherline.

    Changing the motors is straightforward: loosen coupler setscrew, remove base screws, slide motor away from coupler, remove mount screws. Won’t happen that often, methinks.

    The general idea is to drive one stepper with a known current, apply a known resistive load to the other motor’s windings, and then plot torque vs. speed. It won’t be quite that simple, of course, but should produce some interesting data.

     

  • Stepper Motor Shaft Coupler

    This simple cylinder connects two NEMA 17 stepper motors together:

    Stepper Shaft Coupler
    Stepper Shaft Coupler

    It’s quick-and-dirty:

    • Cut 2+ inches of 0.375 drill rod, face both ends
    • Drill #8 = 0.199 inch = 5.06 mm (because #9 = 0.196 inch = 4.98 mm is a bit too snug)
    • Cross-drill #41 in the Sherline (because #43 makes for stiff tapping)
    • Tap 4-40 for the setscrews
    • File off rough edges, run #8 drill through the bore to clean out tapping chips &c

    Now, you probably don’t want to do this in real life, because you want a coupler with a bit of compliance to soak up the inevitable misalignment and dampen the mechanical resonances.