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 158 LED Strip Lighting: Now With Improved Wiring!

    It Has Been Decided (in that place where what is decided must be) to allow a single hole in the sewing machine’s front panel:

    Kenmore 158 - Front LED strip - wire routing
    Kenmore 158 – Front LED strip – wire routing

    The hole barely passes the 2 mm coaxial cable I’m misusing for the LED strips and is located where it:

    • Clears the machine’s metal frame to the upper left
    • Isn’t blocked by the knob’s mounting bracket to the lower right
    • Doesn’t snag the knob’s cam followers all over the insides
    • Lines up directly below the orange dot for pretty

    The first three of those happen behind the front panel, inside the frame, where you (well, I) can neither see nor measure the locations. I used a large outside caliper to get a feel for where the hole could possibly fit, then got it right on the first try!

    On the rear panel, it turns out that the presser foot lever doesn’t quite touch the top of its slot in the frame, so the cable for those LED strips can sneak through:

    Kenmore 158 - Rear LED strips - wire routing
    Kenmore 158 – Rear LED strips – wire routing

    Just inside that slot, the cable turns right, passes into the endcap, then goes upward to re-emerge at the top, inside the channel used for the old 120 VAC zip cord that powered the incandescent bulb in the endcap.

    I had some square cable clips lying around, so I used them, but the (yet to be designed) round versions will look better.

    The grody frame tells you this is the crash test dummy machine I’m using to verify things before installing them in Mary’s machine.

    The improved cable routing required different hole positions in the LED strip mounts:

    Strip Light Mount - Drilled cable routing
    Strip Light Mount – Drilled cable routing

    The internal wire route follows the original 120 VAC zip cord’s route from the bottom of the machine to the endcap (on the left), with the new branch for the front LEDs curving over the main shaft:

    Kenmore 158 - LED strips - internal wire routing
    Kenmore 158 – LED strips – internal wire routing

    The four-conductor ribbon cable also carries the supply voltage for the yet-to-be-built high intensity LED emitters in the end cap that will replace the 10 mm LEDs, with the ends terminated under the clamp in the middle. Those old steel wire clamps seem grossly oversized for the job, but that’s OK with me.

    The ribbon cable eases past that whirling crank arm, then passes through the frame to the outside cover under the handwheel, where it just barely clears the drive belts. A few zip ties hold it out of the way.

    The OpenSCAD source code offsets the wiring holes by 0.5 mm from the ends of the LED strips for easier wire bending, but is otherwise pretty much the same as before:

    // LED Strip Lighting Brackets for Kenmore Model 158 Sewing Machine
    // Ed Nisley - KE4ZNU - March 2014
    //  October 2014 - tweak endcap length & channel position
    
    Layout = "Build";			// Build Show Channels Strip
    
    //- 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
    
    AlignPinOD = 1.70;			// assembly alignment pins: filament dia
    
    inch = 25.4;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    //----------------------
    // Dimensions
    
    LEDSegment = [25.0,10.0,3.0];		//  size of each LED segment
    SEGLENGTH = 0;
    SEGWIDTH = 1;
    SEGHEIGHT = 2;
    
    WireChannel = 3.0;				// wire routing channel diameter
    
    StripHeight = 12.0;				// sticky tape width
    
    DefaultLayout = [1,2,"Wire","NoWire"];
    NUMSEGS = 0;
    NUMSTRIPS = 1;
    WIRELEFT = 2;
    WIRERIGHT = 3;
    
    EndCapSides = 8*4;				// endcap smoothness
    EndCapShim = 0.5;				// additional space for easier wire bending
    
    function EndCapSize(Layout) = [(2*WireChannel + EndCapShim),Layout[NUMSTRIPS]*LEDSegment[SEGWIDTH],StripHeight];
    
    //----------------------
    // 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);
    
    }
    
    //-- The negative space used to thread wires into the endcap
    
    module MakeWireChannel(Layout = DefaultLayout,Which = "Left") {
    
    	EndCap = EndCapSize(Layout);	// radii of end cap spheroid
    
    	HalfSpace = EndCap[0] * ((Which == "Left") ? 1 : -1);
    
    	render(convexity=2)
    	translate([0,LEDSegment[SEGWIDTH]/2,0])
    		intersection() {
    			union() {
    				cube([2*WireChannel,WireChannel,EndCap[2]],center=true);
    				translate([-2*EndCap[0],0,EndCap[2]/2])
    					rotate([0,90,0]) rotate(180/6)
    						PolyCyl(WireChannel,4*EndCap[0],6);
    			}
    			translate([HalfSpace,0,(EndCap[2] - Protrusion)]) {
    				cube(2*EndCap,center=true);
    			}
    		}
    }
    
    //-- The whole strip, minus wiring channels
    
    module MakeStrip(Layout = DefaultLayout) {
    
    	EndCap = EndCapSize(Layout);	// radii of end cap spheroid
    
    	BarLength = Layout[NUMSEGS] * LEDSegment[SEGLENGTH];				// central bar length
    
    	echo(str("Strip OAL: ",BarLength + 2*EndCap[SEGLENGTH]));
    
    	hull()
    		difference() {
    			for (x = [-1,1])						// endcaps as spheroids
    				translate([x*BarLength/2,0,0])
    					resize(2*EndCap) rotate([0,90,0]) sphere(1.0,$fn=EndCapSides);
    			translate([0,0,-EndCap[2]])
    				cube([2*BarLength,3*EndCap[1],2*EndCap[2]],center=true);
    			translate([0,-EndCap[1],0])
    				cube([2*BarLength,2*EndCap[1],3*EndCap[2]],center=true);
    		}
    
    }
    
    //-- Cut wiring channels out of strip
    
    module MakeMount(Layout = DefaultLayout) {
    
    	BarLength = Layout[NUMSEGS] * LEDSegment[SEGLENGTH];
    
    	difference() {
    		MakeStrip(Layout);
    		if (Layout[WIRELEFT] == "Wire")
    			translate([(BarLength/2 + EndCapShim),0,0])
    				MakeWireChannel(Layout,"Left");
    		if (Layout[WIRERIGHT] == "Wire")
    			translate([-(BarLength/2 + EndCapShim),0,0])
    				MakeWireChannel(Layout,"Right");
    	}
    }
    
    //- Build it
    
    ShowPegGrid();
    
    if (Layout == "Channels") {
    	translate([ (2*WireChannel + 1.0),0,0]) MakeWireChannel(DefaultLayout,"Left");
    	translate([-(2*WireChannel + 1.0),0,0]) MakeWireChannel(DefaultLayout,"Right");
    }
    
    if (Layout == "Strip") {
    	MakeStrip(DefaultLayout);
    }
    
    if (Layout == "Show") {
    	MakeMount(DefaultLayout);
    }
    
    if (Layout == "Build") {
    
    	if (false) {					// original no-drill wiring
    		translate([0,(3*LEDSegment[SEGWIDTH]),0]) MakeMount([1,2,"Wire","Wire"]);		// rear left side, vertical
    		translate([0,0,0]) MakeMount([5,2,"Wire","NoWire"]);				// rear top, across arm
    		translate([0,-(3*LEDSegment[SEGWIDTH]),0]) MakeMount([6,2,"NoWire","Wire"]);	// front top, across arm
    	}
    
    	if (true) {						// front: drill panel, rear: route through foot lift lever
    		translate([0,(3*LEDSegment[SEGWIDTH]),0])
    			MakeMount([1,2,"NoWire","Wire"]);				// rear left side, vertical
    		translate([0,0,0])
    			MakeMount([5,2,"Wire","Wire"]);					// rear top, across arm
    		translate([0,-(1*LEDSegment[SEGWIDTH]),0])
    			rotate(180)
    			MakeMount([6,2,"NoWire","Wire"]);				// front top, across arm
    	}
    }
    
  • Motor RPM Sensor Mounting: Bracket Madness

    The first sensor bracket came from the scrap pile, but showed that it would produce 1/rev pulses from the motor shaft pulley. The positioning wasn’t quite right, so I made another bracket that put the TCRT5000 sensor at right angles to the pulley:

    TCTR5000 Motor RPM Sensor - end view
    TCTR5000 Motor RPM Sensor – end view

    All of the sensors have a rakish tilt over their PCB, so at some point I must resolder them:

    TCTR5000 Motor RPM Sensor - side view
    TCTR5000 Motor RPM Sensor – side view

    It might not matter, as the phototransistor on the left peers directly at the pulley, with the LED on the right acting as a floodlight.

    “Made another bracket” sounds like the metal sprang fully formed from the concept. Herewith, the early contestants atop a sketch and the flat layout for The Ultimate Bracket:

    Motor RPM Sensor Brackets
    Motor RPM Sensor Brackets

    A closer look at that final dimension sketch, because I’ll need it again:

    RPM Bracket Dimensions
    RPM Bracket Dimensions

    The vertical size of the center section (12 mm) sets the perpendicular distance of the sensor from the shaft. The horizontal size (14 mm) controls the pulley-to-sensor spacing.

    The horizontal distance from the center section to the hole on the right (10 mm) adjusts the sensor spacing parallel to the shaft.

    I cut the overall rectangle with tin snips, drilled & cleaned the holes, applied a nibbling tool to the details, trimmed the corners, filed off sharp edges & spines, and it was all good.

    The doodles for the first few attempts, as I don’t want to repeat those mistakes:

    Bracket Doodles
    Bracket Doodles

    All in all, a few more hours of Quality Shop Time than I expected…

  • Sewing Machine RPM Sensing: Gun Bluing FTW!

    A quick-and-dirty bracket (made from a leftover strip in the pile of chassis clips) affixed an IR reflective sensor (based on the ubiquitous TCRT5000 module) to the sewing machine motor:

    TCRT5000 sensor on motor
    TCRT5000 sensor on motor

    That’s scribbling black Sharpie around the retroreflective tape for the laser tachometer, which worked just about as poorly as you’d expect. Retroreflective tape, by definition, reflects the light directly back at the LED, but in this case you want it bounced to the photosensor.

    An IR view shows the geometry and highlights the LED:

    TCRT5000 sensor - IR view
    TCRT5000 sensor – IR view

    The TCRT5000 datasheet suggests that the peak operating distance is 2.5 mm, roughly attained by tinkering with the bracket. The datasheet graph shows that anything between 1 and 5 mm should be just fine:

    IR Reflective Sensor module - TCRT5000 - response vs distance
    IR Reflective Sensor module – TCRT5000 – response vs distance

    Soooo, a bit of contrast improvement is in order:

    • Scrape off the tape
    • Remove adhesive and Sharpie with xylene
    • Scuff with sandpaper
    • Apply Brownell’s Oxpho-Blue gun bluing with a cotton swab
    • Buff with 0000 steel wool
    • Repeat
    • Apply stainless steel tape around half the circumference
    • Burnish flat

    Which looks pretty good:

    Kenmore 158 motor pulley - black-silver
    Kenmore 158 motor pulley – black-silver

    The stainless tape butts up against the setscrew:

    Kenmore 158 motor pulley - black-silver at setscrew
    Kenmore 158 motor pulley – black-silver at setscrew

    Adjusting the sensitivity midway between the point where the output is low (OFF) over the black and high (ON) over the tape seems reasonable.

    Running at the slowest possible speed produces this pulse train:

    Motor sense - min speed
    Motor sense – min speed

    The motor at 19 rev/s = 1140 RPM corresponds to about 2 rev/s of the sewing machine shaft= 2 stitch/s. Slower than, that, the pedal won’t go in simple open-loop mode.

    The setscrew causes those “glitches” on the rising edge. They look like this at a faster sweep:

    Motor sense - min speed - setscrew
    Motor sense – min speed – setscrew

    At maximum speed, the setscrew doesn’t show up:

    Motor sense - max speed
    Motor sense – max speed

    The motor at 174 rev/s = 10440 RPM would do 1000 stitch/s, but that’s just crazy talk: it runs at that speed with the handwheel clutch disengaged and the motor driving only the bobbin winder. I was holding the machine down with the shaft engaged and all the gimcrackery flailing around during that shot.

    The sensor board may have an internal glitch filter, but it’s hard to say: the eBay description has broken links to the circuit documentation.

    I could grind the setscrew flush with the pulley OD and cover it with tape, but that seems unreasonable. Fixing the glitch in firmware shouldn’t be too difficult: ignore a rising edge that occurs less than, say, 1/4 of the previous period following the previous edge.

    Perhaps buffing half the pulley’s circumference to a reasonable shine (minus the bluing) would eliminate the need for the stainless steel tape.

    Iterating the bluing operation / scrubbing with steel wool should produce a darker black, although two passes yields a nice flat black.

  • LV Interface Board: +7 V Regulator

    This takes most of the load off the Arduino Pro Mini’s teeny SMD regulator by knocking the +12 V ATX supply down to +7 V:

    LV Power Interface - 7 V Regulator
    LV Power Interface – 7 V Regulator

    It’s on the heatsink beyond the ATX connector at the right edge of the board:

    Low Voltage Interface Board - detail
    Low Voltage Interface Board – detail

    It also provides a (more) stable voltage for the current sense amp than you can reasonably expect directly from the ATX power supply:

    Current Sense Amp - schematic
    Current Sense Amp – schematic

    Not much to it: the thing Just Works…

  • AC Interface Board: Line Voltage Interlock

    The relay at the top connects the AC hot line to the rest of the circuitry, with a feeble red LED to show when it’s live:

    AC Power Interface
    AC Power Interface

    The driver lives on the Low Voltage Interface board:

    LV Power Interface - AC Relay driver
    LV Power Interface – AC Relay driver

    The GX270’s front-panel hard drive LED now serves to indicate when the AC power goes live.

    I’d originally intended to turn the AC on when the Arduino gains control, but after seeing those pictures, I think it’ll remain disabled unless there’s a call for motor motion.

    The interlock switch closes when the case opens, grounding the transistor base and disconnecting the AC power.

    Of course, you can cheat by simply unplugging the switch, so it’s not failsafe. If you want failsafe, you need a normally closed switch in series with the collector; that’s not what Dell used as a chassis intrusion switch. That’s my story and I’m sticking with it.

  • Kenmore 158: Open-Loop Current Limiting

    Although I plan to servo the motor speed to the pedal position, a quick open-loop test seems in order. The motor requires nigh onto half an amp before it can spin the sewing machine shaft, so this chunk of Arduino code scales-and-offsets ten bits of pedal position voltage into twelve bits of DAC output that produce a corresponding current limit for the motor winding:

    ADCvalue = (word)analogRead(PIN_PEDAL);
    DACvalue = map(ADCvalue,0x0100,0x03ff,0x0800,0x0fff);
    dac.setVoltage(DACvalue,false);
    

    Putting that in the Arduino’s main loop and holding the pedal down produces this pleasant result:

    Current Sense Amp vs Tek - 200 mA-div
    Current Sense Amp vs Tek – 200 mA-div

    The current sense amp output in the top trace is scaled at 525 mA/V = 525 mA/div and the bottom trace is from the Tek current probe at 200 mA/div. Fiddling with the scope’s gain & offset exactly overlays the two traces and they remain overlaid through the full pedal travel, so the ferrite toroid isn’t saturating and the output remains nicely linear.

    The flat tops in that picture show the ET227 transistor limiting the motor current to 600 mA, exactly the way it should.

    Of course, the LM324 has a GBW = 1 MHz and, with a gain of three, a bandwidth of barely 300 kHz, so there’s a distinct lack of fuzz on that trace compared to the Tek probe’s 10 MHz bandwidth.

    It’s easy to hold the sewing machine at a constant speed with a constant load, but touching the handwheel stalls the motor at a constant pedal position. Similarly, releasing the handwheel causes a runaway, unless I let up on the pedal fairly quickly.

    Setting the Tek probe to 500 mA/div and triggering on a somewhat higher current while stomping on the pedal and grabbing the sewing machine’s handwheel shows the current increasing with the motor under heavier load:

    Model 158 - Current sense vs Tek 500 mA-div
    Model 158 – Current sense vs Tek 500 mA-div

    The current limit reaches just under 2 A, over on the right side, for both traces.

    So the hardware works pretty much the way it should.

    Wheee-hooo!

  • Hall Effect Motor Current Sensing

    Given that the motor current amounts to maybe 3 A, absolute maximum, with a locked rotor, those skinny wires on the slit ferrite toroid won’t pose a problem:

    HV Interface board - detail
    HV Interface board – detail

    I really like how that 3D printed armor worked out, even if I still haven’t poured any goop around the windings to lock them down; they’re held in by raw faith and friction.

    The current sense circuitry appears along the bottom of the AC Power Interface schematic:

    AC Power Interface
    AC Power Interface

    The differential amplifier lives on the Low Voltage Interface board, forming the clump of parts just in front of the LM324 op amp on the left:

    Low Voltage Interface Board - detail
    Low Voltage Interface Board – detail

    Which has the usual handful of components required to get anything done in the analog realm:

    Current Sense Amp - schematic
    Current Sense Amp – schematic

    The power supplies come directly from the ATX connector. I’m ignoring the whole decoupling issue, because the supplies have essentially no load (and it’s all DC, anyway).

    The trim pot sets the offset voltage to bring the Hall effect sensors’s VCC/2 offset down close to zero; the 100 mV figure is nominal, not actual, but should be a bit over 0 V to allow for a wee bit o’ drift. This time around, I’ll measure and subtract the actual offset, rather than (try to) auto-zero it.

    The voltage gain runs just under 3, set by 1% resistors from the heap. The overall gain works out to about 1.9 V/A or 525 mA/V, setting the high end at 5 V to a scant 2.6 A. Subject to actual calibration with more attention to detail, that’s close enough; we’re more interested in the around-an-amp range where the motor operates under nominal load.

    The nose-to-tail Schottky diodes clamp the op amp output to avoid annoying the Arduino’s ADC input. It has protection circuitry, too, but there’s no point in stressing it.