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

Fabric arts and machines

  • Kenmore Model 158 Speed Control: Carbon Disk Replacement

    The speed control pedal on Mary’s sewing machine once again started racing away from a dead stop, which we now know means more disks inside the carbon pile rheostat have disintegrated. It looked pretty much the same as when I took it apart in 2009:

    Rheostat graphite wafers and contacts
    Rheostat graphite wafers and contacts

    This time, it had one cracked wafer and several thin ones, reducing the length of the stacks so much that the pedal exerted very little force (thus, not starting the motor) before the shorting contacts caused a runaway.

    Back then, I’d machined two brass disks to fill the empty space:

    Rheostat with brass spacer button
    Rheostat with brass spacer button

    A rough measurement showed I’d have to double their thickness to about 7 mm each, but it seemed like replacing high-resistance carbon with low-resistance brass wasn’t a Good Idea, at least when taken to an extreme. Not knowing what would count as an extreme in this situation, I decided to replace the brass disks with graphite cylinders sized to fill up the empty space.

    The Little Box o’ Machinable Graphite produced a small bar, from which I sliced a square with jeweler’s pull saw:

    Machineable Graphic - rough-sawn slab
    Machineable Graphic – rough-sawn slab

    Cutting that in half, then one of the bars in half, produced a pair of cubes:

    Machineable Graphic - cubes
    Machineable Graphic – cubes

    I tried sanding off the corners:

    Machineable Graphic - sanded cube
    Machineable Graphic – sanded cube

    After it became painfully obvious that process would take just slightly less than forever, I deployed the Dremel sanding drum:

    Machineable Graphic - cylinders
    Machineable Graphic – cylinders

    Much to my surprise, the shop vacuum didn’t quite inhale the cloth, I didn’t drop either of the cylinders into its gaping maw or sand away my fingertips, and the cylinders emerged more-or-less good looking. I sanded the faces reasonably smooth and parallel, removed a few high spots left by the Dremel, and the cylinders slid neatly into the holes in the ceramic rheostat.

    I felt a definite kinship with those guys in the rackets (not squash, as I once knew) court under the stadium seats…

    I put the cylinders at the end of the stacks, against the graphite buttons (shown in the top picture), and left the disks to settle themselves against the brass contacts. In retrospect, I should have put the cylinders against the brass, so that the inevitable erosion will chew on the (relatively) easily replaced bulk cylinders.

    Each graphite cylinder displaced six disks, so now I have some spares for next time. I’m certain that the graphite has lower resistance than the equivalent length of disks, but it’s probably higher than the same length of brass. I was not going to slice those cylinders into disks.

    After vigorous and repeated handwashing with gritty cleaner after leaving the Basement Laboratory Workshop, the pedal assembly went back together smoothly and, once again, operates the way it should: controllable smooth low speeds, crazy-fast high speeds, and a steady transition between the two. Mary has resumed quilting up a storm.

    That shop vacuum may never forgive me, but it totally eliminated all the carbon dust from the work area. The filter started out coated with a generous layer of dust and crud, so I’m pretty sure it collected most of the very fine dust, too.

    I briefly considered using the lathe, but came to my senses.

    The cheap way to do AC motor speed control involves a triac chopping the sine wave, so as to produce all manner of hash above and beyond the usual motor commutation noise. It occurs to me that the sewing machine has a universal motor that would run just as happily on 120 V DC as it does on AC, so a cheap 120 V DC supply (around 2 A should suffice) from the usual eBay supplier and a high voltage MOSFET on a generous heatsink would work even better. One might even get by with just a full-wave rectifier bridge and pulsating DC.

    The rheostat doesn’t dissipate more than a few watts, I think, so thermal management should not pose a serious problem.

    The motor rating says it’s good for 1 A, which means the power should be less than a few tens of watts. Some resistance and current measurements are in order.

    You can actually buy replacement pedals, but what’s the fun in that?

  • Sewing Machine Bulb: LED Replacement Doodle

    Mary wants more light directly around the needle of her Kenmore Model 158 sewing machine, as the existing light (a 120 V 15 W incandescent bulb tucked inside the end housing) casts more of a diffuse glow than a directed beam:

    Kenmore Model 158 Sewing Machine - lamp
    Kenmore Model 158 Sewing Machine – lamp

    The end cap fits snugly around the bulb, but I thought a pair of 10 mm white LEDs, mounted side-by-side and aimed downward at the cover plate, would work. Of course, plugging a pair of white LEDs into a 120 VAC socket won’t work, but some judicious rewiring and a new 12 V DC wall wart will take care of that.

    The bulb has a dual-contact bayonet base, with both pins isolated from the shell and connected to the non-polarized (!) line cord through the power switch. I didn’t know it was called a BA15d base, but now I do.

    A 12 V automotive brake/taillight bulb (type 1157, I think) pulled from the Big Box o’ Bulbs has a slightly different pin arrangement that keys the filaments (which are not isolated from the shell) to the surrounding reflector:

    BA15d Bayonet Bulb Bases - 120V vs. 12V pins
    BA15d Bayonet Bulb Bases – 120V vs. 12V pins

    So I conjured a mockup to see if it would fit, using 2-56 screws to mimic whatever hardware might be practical:

    BA15d Bulb - LED Adapter
    BA15d Bulb – LED Adapter

    The solid model shows how it all fits together:

    Sears Lamp LED Adapter - Show view
    Sears Lamp LED Adapter – Show view

    The two tiny ruby-red pins represent filament snippets in alignment holes, barely visible in real life:

    LED holder parts
    LED holder parts

    I glued those pieces together, using a tiny machinist’s square as a jig to keep them perpendicular:

    LED holder clamping
    LED holder clamping

    Some random 10 mm LEDs served for testing:

    BA15d Bulb - 10 mm LEDs
    BA15d Bulb – 10 mm LEDs

    It actually fit pretty well, ignoring the fact that the LEDs point 90° from the intended direction (so I could see how the holes came out inside the pivot, honest), and lit up the area quite well, but it’s such a delicate affair that removing the entire socket and replacing it with a dedicated metal bracket / heatsink for two high-power SMD LEDs will be better.

    The OpenSCAD source code:

    // Adapter for LEDs in Sears sewing machine lamp socket
    // Ed Nisley - KE4ZNU - January 2014
    
    Layout = "Show";		// Build Show LEDTab LEDPlate ShellMount
    
    //- Extrusion parameters must match reality!
    //  Print with 2 shells and 3 solid layers
    
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;			// extra clearance
    
    Protrusion = 0.1;			// make holes end cleanly
    Gap = 2.0;					// spacing between Show parts
    
    AlignPinOD = 1.70;			// assembly alignment pins: filament dia
    
    inch = 25.4;
    
    //----------------------
    // Dimensions
    
    //-- LED mounting plate
    
    LEDDia = 10.0;				// LED case OD
    LEDFlangeOD = 10.7;
    
    LEDPlateThick = 2.0;		// mounting plate thickness
    LEDMargin = 2.0;
    
    LEDSpaceOC = LEDDia + LEDMargin;		// LED center-to-center distance (single margin between!)
    
    LEDTabLength = 15.0;		// base to screw hole center
    
    LEDTabThick = 4.0;			// tab with hole for mounting screw
    LEDTabScrewOD = 2.0;
    LEDTabWidth = (3.0*2) + LEDTabScrewOD;
    
    LEDMountHeight = 25.0;		// estimated mounting screw centerline to bottom of LEDs
    
    //-- Lamp base adapter
    //		hard inch dimensions!
    
    ShellOD = 0.600 * inch;				// dia of metallic shell
    ShellOAL = 0.66 * inch;				//  ... total length
    ShellInsert = 7/16 * inch;			//  ... length engaging socket
    
    ShellSides = 4*4;
    
    BulbOD = 0.75 * inch;				// glass bulb
    BulbLength = 1.14 * inch;
    
    InsulOD = 0.485 * inch;				// insulating stub around contact pins
    InsulThick = 0.070 * inch;			//  ... beyond end of shell
    
    ContactOD = 2.0;					// contact holes through base (not heads)
    ContactOC = 0.300 * inch;			//  ... center-to-center spacing
    
    BayonetOD = 0.080 * inch;			// bayonet pin diameter
    BayonetOffset = 0.125 * inch;		// from end of metal base
    
    LampOAL = InsulThick + ShellOAL + BulbLength;
    echo(str("Overall Length: ",LampOAL));
    
    //-- Miscellany
    
    //----------------------
    // 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);
    }
    
    //-- Tab for screw mounting LED holder
    //		AddLength remains below Z=0 for good union
    
    module LEDTab() {
    
    	difference() {
    		linear_extrude(height=LEDTabThick)
    			hull() {
    				circle(d=LEDTabWidth);
    				translate([LEDTabLength/2,0,0])
    					square([LEDTabLength,LEDTabWidth],center=true);
    			}
    		translate([0,0,-Protrusion])
    			rotate(180/6)
    				PolyCyl(LEDTabScrewOD,(LEDTabThick + 2*Protrusion),6);
    		for (i=[-1,1])
    			translate([LEDTabLength/2,i*LEDTabWidth/4,LEDTabThick/2])
    				rotate([0,90,0]) rotate(180/4)
    					PolyCyl(AlignPinOD,(LEDTabLength/2 + Protrusion),4);
    	}
    }
    
    //-- Plate holding LEDs
    
    module LEDPlate() {
    
    	difference() {
    		union() {
    			linear_extrude(height=LEDPlateThick)
    				hull() {
    					for (i=[-1,1])
    						translate([i*LEDSpaceOC/2,0,0])
    							circle(d=(LEDDia + 2*LEDMargin));
    					translate([0,(LEDFlangeOD/2 + LEDTabWidth/2),0])
    						square([LEDTabThick,LEDTabWidth],center=true);
    				}
    		}
    		for (i=[-1,1])
    			translate([i*LEDSpaceOC/2,0,-Protrusion])
    				rotate(180/12)
    					PolyCyl(LEDDia,(LEDPlateThick + 2*Protrusion),12);
    		for (i=[-1,1])
    			translate([0,(i*LEDTabWidth/4 + LEDFlangeOD/2 + LEDTabWidth/2),3*ThreadThick]) rotate(180/4)
    				PolyCyl(AlignPinOD,(LEDTabLength/2 + Protrusion),4);
    
    	}
    }
    
    //-- Bulb shell mounting adapter
    
    module ShellMount() {
    
    	difference() {
    		union() {
    			cylinder(r1=InsulOD/2,r2=ShellOD/2,h=(InsulThick + Protrusion),$fn=ShellSides);
    			translate([0,0,InsulThick])
    				cylinder(r=ShellOD/2,h=(LampOAL - LEDMountHeight + LEDTabWidth/2),$fn=ShellSides);
    		}
    
    		translate([0,ShellOD,(InsulThick + BayonetOffset)])		// bayonet pin hole
    			rotate([90,0,0]) rotate(180/4)
    				PolyCyl(BayonetOD,2*ShellOD,4);
    
    		translate([0,ShellOD,(InsulThick + LampOAL - LEDMountHeight)])		// LED mount screw hole
    			rotate([90,0,0])
    				PolyCyl(LEDTabScrewOD,2*BulbOD,6);
    
    		translate([0,0,(InsulThick + ShellOAL + LampOAL/2)])		// slot for LEDTab mount
    			cube([2*ShellOD,(LEDTabThick + 2*Protrusion),LampOAL],center=true);
    
    		for (i=[-1,1])											// contact pin holes
    			translate([i*ContactOC/2,0,-Protrusion])
    				rotate(180/6)
    					PolyCyl(ContactOD,2*LampOAL,6);
    	}
    
    }
    
    //- Build it
    
    ShowPegGrid();
    
    if (Layout == "LEDTab")
    	LEDTab();
    
    if (Layout == "LEDPlate")
    	LEDPlate();
    
    if (Layout == "ShellMount")
    	ShellMount();
    
    if (Layout == "Show") {
    	LEDPlate();
    	translate([-LEDTabThick/2,(LEDFlangeOD/2 + LEDTabWidth/2),(LEDTabLength + LEDPlateThick + Gap)])
    		rotate([0,90,0])
    			LEDTab();
    	for (i=[-1,1])
    #	translate([0,(i*LEDTabWidth/4 + LEDFlangeOD/2 + LEDTabWidth/2),(LEDPlateThick + Gap/4)])
    		rotate(180/4)
    		cylinder(r=AlignPinOD/2,h=Gap/1,$fn=4);		// fake the pins
    
    	translate([0,(LEDFlangeOD/2 + LEDTabWidth/2),(LampOAL - LEDTabWidth/2)])
    		rotate([0,180,0]) rotate(90)
    			ShellMount();
    }
    
    if (Layout == "Build") {
    	translate([0,LEDDia,0])
    		LEDPlate();
    
    	translate([-10,-(LEDMargin + LEDTabWidth),0])
    		rotate(-90)
    			LEDTab();
    
    	translate([10,-(LEDMargin + LEDTabWidth),0])
    		ShellMount();
    }
    

    The original doodles for the bulb dimensions and adapter layout:

    Bulb dimensions - adapter doodles
    Bulb dimensions – adapter doodles
  • Quilting Pin Caps: More!

    These quilting pin caps are slightly longer than the previous version and, due to the M2’s smaller nozzle, have slightly thinner single-thread walls. Because Slic3r does a better (although not ideal) job of path planning than Skeinforge, it’s easier to create an array of the caps in the solid model than to manually add duplicates in Slic3r:

    Quilting Pin Cap - array
    Quilting Pin Cap – array

    They look like egg cases from Prometheus:

    Quilting pin cap array - on platform
    Quilting pin cap array – on platform

    Fill with silicone caulk on waxed paper and they look even more like that:

    Quilting pin caps - silicone fill
    Quilting pin caps – silicone fill

    Fast-forward a few days, rub off the excess caulk, trim off a few blobs, and they’re ready for presentation:

    Quilting pin caps - finished
    Quilting pin caps – finished

    In use, they look about like you’d expect:

    Quilting pin caps - in use
    Quilting pin caps – in use

    The pin caps I made from a 5 gallon bucket’s O-ring gasket didn’t work out well, as the plastic didn’t like being poked with pins and put up a stiff resistance. Silicone caulk has exactly the right consistency.

    When Mary ramps up a full-scale quilt, we’ll need a few hundred of the things. The commercial version has dropped to 40 cents each, which makes all this worthwhile.

    The OpenSCAD source code:

    // Quilting pin caps
    // Ed Nisley KE4ZNU April 2012
    //	January 2013 - modify for Slic3r and M2
    
    //- Extrusion parameters must match reality!
    //  Print with +1 shells and 3 solid layers
    
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    Protrusion = 0.1;			// make holes end cleanly
    
    //----------------------
    // Dimensions
    
    ID = 5.0;
    OD = ID + 2*ThreadWidth;
    Length = 8.0;
    Sides = 8;
    
    CapArray = [6,6];			// XY layout of caps
    CapsOC = OD + 2.0;			// OC spacing
    
    //----------------------
    // 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) {
    
      RangeX = floor(100 / Space);
      RangeY = floor(125 / Space);
    
    	for (x=[-RangeX:RangeX])
    	  for (y=[-RangeY:RangeY])
    		translate([x*Space,y*Space,Size/2])
    		  %cube(Size,center=true);
    
    }
    
    module PinCap() {
    	rotate(180/Sides) {
    		difference() {
    		PolyCyl(OD,Length,8);
    		translate([0,0,-Protrusion])
    			PolyCyl(ID,(Length + 2*Protrusion),8);
    		}
    	}
    
    }
    
    //----------------------
    // Build them!
    
    ShowPegGrid();
    
    translate([(-CapsOC*(CapArray[0] - 1)/2),(-CapsOC*(CapArray[1] - 1)/2),0])
    	for (i=[0:(CapArray[0] - 1)],j=[0:(CapArray[1] - 1)])
    		translate([i*CapsOC,j*CapsOC,0])
    			PinCap();
    

    They seem to work pretty well…

  • Modified Quilting Foot: Speed Wrench Knob

    The Nyloc nut atop that modified quilting foot requires more grip than fingers can provide:

    Modified Darning Foot - in action
    Modified Darning Foot – in action

    The “precision” wrench I adapted to that nut works for small adjustments, but for larger ones it’s easier to take the foot off and spin this knob:

    Quilting Foot Knob - knurling
    Quilting Foot Knob – knurling

    It has a hex opening in each end that fits the nut, with a through hole for the bolt. The top looks exactly like you’d expect:

    Quilting Foot Knob - top
    Quilting Foot Knob – top

    The bottom needs a bit of support:

    Quilting Foot Knob - bottom support
    Quilting Foot Knob – bottom support

    The solid model shows off the support in color:

    Quilting Foot Knob
    Quilting Foot Knob

    The OpenSCAD source code doesn’t have many surprises:

    // Quilting foot knob
    // Ed Nisley KE4ZNU January 2013
    
    use <knurledFinishLib_v2.scad>
    
    //- Extrusion parameters must match reality!
    //  Print with +1 shells and 3 solid layers
    
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    Protrusion = 0.1;			// make holes end cleanly
    
    //----------------------
    // Dimensions
    
    KnobOD = 20.0;
    KnobLength = 25.0;
    KnobSides = 12;
    
    DiamondLength = KnobLength/3;
    DiamondWidth = DiamondLength/2;
    DiamondDepth = 1.0;
    
    NutOD = 7.0;				// across flats!
    NutLength = 6.0;
    ScrewOD = 4.0;
    
    DoSupport = true;
    
    //----------------------
    // 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) {
    
      RangeX = floor(100 / Space);
      RangeY = floor(125 / Space);
    
    	for (x=[-RangeX:RangeX])
    	  for (y=[-RangeY:RangeY])
    		translate([x*Space,y*Space,Size/2])
    		  %cube(Size,center=true);
    
    }
    
    module Knob() {
    	rotate(180/Sides) {
    		difference() {
    //			cylinder(r=KnobOD/2,h=KnobLength,$fn=KnobSides);
    			render(convexity=10)
    			knurl(k_cyl_hg=KnobLength,
    				  k_cyl_od=KnobOD,
    				  knurl_wd=DiamondWidth,
    				  knurl_hg=DiamondLength,
    				  knurl_dp=DiamondDepth,
    				  e_smooth=DiamondLength/2);
    			translate([0,0,-Protrusion])
    				PolyCyl(ScrewOD,(KnobLength + 2*Protrusion),6);
    			translate([0,0,(KnobLength - NutLength)])
    				PolyCyl(NutOD,(NutLength + Protrusion),6);
    			translate([0,0,-Protrusion])
    				PolyCyl(NutOD,(NutLength + Protrusion),6);
    		}
    	}
    }
    
    module Support() {
    	color("Yellow")
    		for (Seg=[0:5]) {
    			rotate(360*Seg/6)
    			translate([0,0,(NutLength - ThreadThick)/2])
    				cube([(NutOD - 1*ThreadWidth),
    						2*ThreadWidth,
    						(NutLength - ThreadThick)],
    						center=true);
    			}
    }
    
    //----------------------
    // Build them!
    
    ShowPegGrid();
    
    Knob();
    
    if (DoSupport)
    	Support();
    

    Mary likes it… and thinks I’m being silly. She’s right, of course.

  • Free Motion Quilting Darning Foot Modification: The Home Shop Way

    Mary has been learning free motion quilting, which uses a special sewing-machine foot that holds the fabric in place. Leah Day describes modifying a standard darning foot, but I suggested deploying a bit more shop-fu to do it right. The notion of “adjusting” something with a twisted rubber band just made my skin crawl…

    The starting point is a Brewer BP1814 “FOOT Darning/Quilting low shank with clear base”, two of which appear next to an older version that she’s had for quite some time. The rightmost one has my modifications:

    Brewer BP1814 Quilting Foot - assortment
    Brewer BP1814 Quilting Foot – assortment

    The older (mostly metal) foot works much better for its intended purpose, but the newer white plastic version seems easier to modify for free-motion quilting. The older spring is much softer than the new ones, for whatever that’s worth. After the modification, the spring pressure becomes largely irrelevant, as it only acts when something pushes up on the base.

    The first modification improves visibility by cutting out part of the transparent plastic base. Leah suggests chopping it with a diagonal cutter (“jewelry clippers”), but I deployed a slitting saw in the Dremel tool at low speed to avoid melting. Mary wanted angled cuts, so that’s what she got:

    Modified Darning Foot - opened base
    Modified Darning Foot – opened base

    A bit of touchup with a fine file smoothed out the edges so the base slides easily over the fabric. There’s no way to remove the red guide lines; the un-modified foot on the left emerged from its bag with that smeared line.

    Then drive out the top metal pin with a small drift punch, hold the base and shaft, remove the C-clip, capture the spring, and extract the base and shaft. The 4.0 mm diameter metal shaft cries out to be threaded, so that’s what I did; this picture shows the reassembled shaft and spring:

    Modified Darning Foot - threaded shaft
    Modified Darning Foot – threaded shaft

    That’s significantly harder to accomplish than it looks, because there’s no practical way to remove the plastic base (it’s pinned in place, but one side of the cross-hole is blocked). I filed the end of the shaft to a taper that started the M4.0x0.7 die a bit more easily, clamped the shaft in the bench vise, applied nasty sulfur-based tapping fluid, crossed my fingers and eyes, held my nose, and managed to make it happen without cracking the plastic.

    I reamed out the Nyloc nut with a hand-twisted series of drills, through about #24 = 3.861 mm, to reduce the locking torque. It’s now just slightly more than finger-tight, which should suffice.

    In use, the foot fits under the sewing machine’s arm and puts the nut where fingers can’t reach. I filed a 6.0 mm “precision wrench” to fit the 6.8 mm nut flats and it’s All Good:

    Modified Darning Foot - assembled with wrench
    Modified Darning Foot – assembled with wrench

    A staged photo op atop some trial quilting:

    Modified Darning Foot - in action
    Modified Darning Foot – in action

    With a Nyloc nut instead of a rubber band, it will stay exactly where she wants it…

  • Making Finger Grip Dents: The Chord Equation

    The handle of that quilting circle template has a pair of finger grip dents, which, while they aren’t strictly necessary, seemed like a nice touch:

    Quilting circle template - solid model
    Quilting circle template – solid model

    They’re the result of subtracting a pair of spheres from the flat handle:

    Quilting circle template - handle dent spheres - solid model
    Quilting circle template – handle dent spheres – solid model

    Given:

    • m = the depth of the dent
    • c = its diameter on the surface of the handle

    There’s an easy way to compute R = the radius of the sphere that excavates the dent:

    Circle chord vs depth sketch
    Circle chord vs depth sketch

    Thusly:

    R = (m2 + c2/4) / (2 m)

    In OpenSCAD, that goes a little something like this:

    DentDepth = HandleThick/4;
    DentDia = 15.0;
    DentSphereRadius = (pow(DentDepth,2) + pow(DentDia,2)/4)/(2*DentDepth);
    

    Then generate the sphere (well, two spheres, one for each dent) and offset it to scoop out the dent:

    for (i=[-1,1]) {
    	translate([i*(DentSphereRadius + HandleThick/2 - DentDepth),0,StringHeight])
    		sphere(r=DentSphereRadius);
    

    HandleThick controls exactly what you’d expect. StringHeight sets the location of the hole punched through the handle for a string, which is also the center of the dents.

    The spheres have many facets, but only a few show up in the dent. I like the way the model looks, even if the facets don’t come through clearly in the plastic:

    Quilting circle template - handle dent closeup - solid model
    Quilting circle template – handle dent closeup – solid model

    It Just Works and the exact math produces a better result than by-guess-and-by-gosh positioning.

    The sphere radius will come out crazy large for very shallow dents. Here’s the helmet plate for my Bicycle Helmet Mirror Mount, which has an indentation (roughly) matching the curve on the side of my bike helmet:

    Helmet mirror mount - plate
    Helmet mirror mount – plate

    Here’s the sphere that makes the dent, at a somewhat different zoom scale:

    Helmet mirror mount - plate with sphere
    Helmet mirror mount – plate with sphere

    Don’t worry: trust the math, because It Just Works.

    You find equations like that in Thomas Glover’s invaluable Pocket Ref. If you don’t have a copy, fix that problem right now; I don’t get a cut from the purchase, but you’ll decide you owe me anyway. Small, unmarked bills. Lots and lots of small unmarked bills…

  • Quilting Circle Template: Why I Loves Me My 3D Printer(s)

    Mary just started an ambitious pieced quilt that requires 50-some-odd precisely sized 1-1/2 inch circles, with marks to locate a 1 inch circle in the middle. She started using a drafting template to mark the smaller circle on freezer paper (don’t ask, it’s complicated), but we couldn’t find the template I know I have with the larger circles.

    [Update: It’s a Bittersweet Briar traditional quilt. See all those little dots-for-berries?]

    So I says to my wife, I sez, “Hey, we have the technology. What would really simplify what you’re doing?” After a bit of doodling, we came up with a ring having the proper ID and OD, plus a flat handle of some sort.

    Half an hour later, I had a solid model:

    Quilting circle template - solid model
    Quilting circle template – solid model

    An hour after that I handed her a warm piece of plastic:

    Quilting circle template
    Quilting circle template

    The bottom ring is exactly 1-1/2 inch OD, 1 inch ID, and thin enough to draw around. The handle keeps her fingers out of the way and even has grips and a hole for a string.

    The print quality near the hole isn’t as good as I’d like, because the slicer turned that entire volume into a solid slab of plastic. I can fix that in the second version, but right now she has something to work with, evaluate, and figure out what would improve it.

    3D printing isn’t for everybody, but it’s a vital part of my shop!

    The OpenSCAD source code has parameters for everything, so we can crank out more templates without fuss:

    // Quilting - Circle Template
    // Ed Nisley KE4ZNU - July 2013
    
    Layout = "Show";                    // Show Build Circle Handle
    
    //-------
    //- Extrusion parameters must match reality!
    //  Print with 2 shells
    
    ThreadThick = 0.25;
    ThreadWidth = 0.40;
    
    HoleFinagle = 0.2;
    HoleFudge = 1.00;
    
    function HoleAdjust(Diameter) = HoleFudge*Diameter + HoleFinagle;
    
    Protrusion = 0.1;           // make holes end cleanly
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    function IntegerMultipleMin(Size,Unit) = Unit * floor(Size / Unit);
    
    inch = 25.4;
    
    //-------
    // Dimensions
    
    CircleID = (1) * inch;
    
    SeamAllowance = (1/4) * inch;
    
    CircleOD = CircleID + 2*SeamAllowance;
    
    CircleThick = 6*ThreadThick;
    
    CircleSides = 12*4;
    
    HandleHeight = (2) * inch;
    HandleThick = IntegerMultiple(5.0,ThreadWidth);
    HandleSides = 12*4;
    
    StringDia = 4.0;
    StringSides = 8;
    StringHeight = 0.75*HandleHeight;
    
    DentDepth = HandleThick/4;
    DentDia = 15.0;
    DentSphereRadius = (pow(DentDepth,2) + pow(DentDia,2)/4)/(2*DentDepth);
    
    //-------
    
    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=HoleAdjust(FixDia)/2,h=Height,$fn=Sides);
    }
    
    module ShowPegGrid(Space = 10.0,Size = 1.0) {
    
      RangeX = floor(100 / Space);
      RangeY = floor(125 / Space);
    
    	for (x=[-RangeX:RangeX])
    	  for (y=[-RangeY:RangeY])
    		translate([x*Space,y*Space,Size/2])
    		  %cube(Size,center=true);
    
    }
    
    //-------
    // Circle ring plate
    
    module CircleRing() {
    
    	rotate(180/CircleSides)
    		difference() {
    			cylinder(r=CircleOD/2,h=CircleThick,$fn=CircleSides);
    			translate([0,0,-Protrusion])
    				cylinder(r=CircleID/2,h=(CircleThick + 2*Protrusion),$fn=CircleSides);
    		}
    }
    
    //-------
    // Handle
    
    module Handle() {
    
    	difference() {
    		rotate([0,90,0])
    			scale([HandleHeight/(CircleOD/2),0.9,1])
    				rotate(180/HandleSides)
    					cylinder(r=CircleOD/2,h=HandleThick,center=true,$fn=HandleSides);
    		translate([0,0,-HandleHeight])
    			cube([2*CircleOD,2*CircleOD,2*HandleHeight],center=true);
    		translate([-HandleThick,0,StringHeight])
    			rotate([0,90,0])
    				rotate(180/StringSides)
    					PolyCyl(StringDia,2*HandleThick,StringSides);
    #		for (i=[-1,1]) {
    			translate([i*(DentSphereRadius + HandleThick/2 - DentDepth),0,StringHeight])
    				sphere(r=DentSphereRadius);
    		}
    	}
    
    }
    
    module Template() {
    	CircleRing();
    	Handle();
    }
    
    //-------
    // Build it!
    
    ShowPegGrid();
    
    if (Layout == "Circle")
    	CircleRing();
    
    if (Layout == "Handle")
    	Handle();
    
    if (Layout == "Show")
    	Template();