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.

Author: Ed

  • Stepper Sync Wheel: Group Sync

    A small tweak to that code produces a sync pulse for each full sine wave of microstepping current, aligned with the step pulses. The sync pulse occurs on the rising edge of the current waveform (because I set it up that way) and has 50% duty cycle to allow triggering at either zero-current microstep.

    Then pix like this happen:

    Microstepping Group Sync
    Microstepping Group Sync

    The traces:

    • top = 1/group sync
    • middle = winding current at 500 mA/div
    • bottom = step pulse, 1/microstep

    The big jump just before the zero-current microstep on the decreasing-current sides of the sine wave indicates that it’s hard to get all the current out of the windings at 12 V. A detail view of those steps shows that the current is 50% higher than it should be at the start of the zero-current microstep, having completely missed the last microstep:

    Decreasing Current
    Decreasing Current

    Which, of course, is why I’m doing all this: to explore that kind of behavior.

    You may find the generated sync pulses are off by ±1 microstep from the expected start of the zero-current microstep, because the optical 1/rev signal threshold may line up perversely with the start of a microstep. You can twist the sync wheel just slightly on the shaft, but it’s pretty much a matter of shaking the dice to see if a better combination comes up. Doesn’t make any real difference to the scope triggering, though, as any stable sync alignment is as good as any other.

    The code uses the 1/rev optical sync pulse once, to get the initial alignment, so whacking the wheel as it rotates may cause the generated sync pulses to skip a beat or twenty. The result remains stable, just at a different alignment.

    One could argue that you really don’t need the 1/rev optical signal at all, but I find it comforting to use an absolute rotational reference to lock the pulses in (pretty nearly) the same place every time. If you’re stuck with an in-place motor, then you probably don’t have a 1/rev signal and you must wing it.

    The Arduino source code:

    // Stepper motor driver synchronization
    // Ed Nisley KE4ZNU June 2011
    
    //-- Stepper parameters
    
    #define SYNC_OFFSET            8        // steps from 1/rev pulse to start of first 4-full-step group
    
    #define FULL_STEPS_PER_REV    200
    #define MICROSTEPPING        8
    
    #define GROUPS_PER_REV (FULL_STEPS_PER_REV / 4)
    #define STEPS_PER_GROUP (MICROSTEPPING * 4)
    
    //-- Pin definitions, all of which depend on internal hardware: do *not* change
    
    #define PIN_REV        2                // INT0 = positive 1/rev pulse from optical switch
    #define PIN_STEP    5                // T1 = positive 1/step pulse from stepper driver
    #define PIN_TRIGGER    9                // OC1A = positive trigger pulse to scope
    
    //-- Trace outputs may be chosen freely
    
    #define PIN_TRACE_A    10
    #define PIN_TRACE_B    11
    #define PIN_TRACE_C    12
    
    #define PIN_LED        13                // standard Arduino LED
    
    //---------------------
    // State Variables
    
    word PulseCounter;
    
    //---------------------
    // Useful routines
    
    //--- Input & output pins
    
    void TogglePin(char bitpin) {
    digitalWrite(bitpin,!digitalRead(bitpin));    // toggle the bit based on previous output
    }
    
    //----------------
    // Initializations
    
    void setup() {
    
    pinMode(PIN_REV,INPUT);        // INT0 1/rev pulse from wheel
    
    pinMode(PIN_STEP,INPUT);        // T1 step pulse from stepper driver
    
    pinMode(PIN_LED,OUTPUT);
    digitalWrite(PIN_LED,LOW);
    
    pinMode(PIN_TRACE_A,OUTPUT);
    pinMode(PIN_TRACE_B,OUTPUT);
    pinMode(PIN_TRACE_C,OUTPUT);
    
    //--- Prepare Timer1 to count external stepper drive pulses
    
    TCCR1B = B00001000;                // Timer1: Mode 4 = CTC, TOP = OCR1A, clock stopped
    
    pinMode(PIN_TRIGGER,OUTPUT);        // OC1A to scope trigger
    
    //-- Wait for rising edge of 1/rev pulse from optical switch
    
    TCCR1A = B11000000;                        // COM1A set on compare
    TCNT1 = 0;                                // ensure we start from zero
    OCR1A = SYNC_OFFSET;                        // set step counter
    
    while(!digitalRead(PIN_REV)) {            // stall until 1/rev input rises
    TogglePin(PIN_TRACE_A);
    }
    
    //-- Got it, fire up the timer to count steps to start of first group
    
    TCCR1B |= B00000111;                        // enable clock from T1 pin, rising edge
    
    digitalWrite(PIN_LED,HIGH);                // show we got here
    digitalWrite(PIN_TRACE_A,LOW);
    
    while(!(TIFR1 & _BV(OCF1A))) {            // wait for compare
    digitalWrite(PIN_TRACE_B,digitalRead(PIN_STEP));
    continue;
    }
    TIFR1 |= _BV(OCF1A);                        // clear match flag
    
    //-- Scope sync pulse is now active, we can enter the main loop
    
    }
    
    //----------------
    // The main event
    
    void loop() {
    
    //-- Scope sync pulse active
    
    digitalWrite(PIN_LED,LOW);                // show we got here
    digitalWrite(PIN_TRACE_B,LOW);
    
    //-- Set up for first half of the group, sync high -> low
    
    TCCR1A = B10000000;                        // COM1A clear on compare
    OCR1A = (STEPS_PER_GROUP / 2) - 1;
    
    while(!(TIFR1 & _BV(OCF1A))) {            // wait for compare
    digitalWrite(PIN_TRACE_B,digitalRead(PIN_STEP));
    continue;
    }
    TIFR1 |= _BV(OCF1A);                        // clear match flag
    digitalWrite(PIN_TRACE_B,LOW);
    
    //-- Set up for the second half, sync low -> high
    
    TCCR1A = B11000000;                        // COM1A set on compare
    OCR1A = (STEPS_PER_GROUP - (STEPS_PER_GROUP / 2)) - 1;    // may be odd, so allow for that
    
    while(!(TIFR1 & _BV(OCF1A))) {            // wait for compare
    digitalWrite(PIN_TRACE_B,digitalRead(PIN_STEP));
    continue;
    }
    TIFR1 |= _BV(OCF1A);                        // clear match flag
    digitalWrite(PIN_TRACE_B,LOW);
    
    //-- Shut down counter and wait for end of 1/rev pulse
    
    #if 0
    TCCR1B &= ~B00000111;                        // turn off timer clock
    
    while(digitalRead(PIN_REV)) {                // stall until 1/rev pulse goes low again
    TogglePin(PIN_TRACE_C);
    }
    digitalWrite(PIN_TRACE_B,LOW);
    #endif
    
    }
    
  • Stepper Motor Driver Bypassing: Mind the Voltage

    The supply voltage for that picture came from a bench supply and, having confirmed that the initial slope of the current waveform matched the voltage, I twiddled the knob while watching the slope change.

    As expected, lower voltage = lower slope and higher voltage = higher slope. That worked fine, right up until a firecracker popped about a foot in front of my face, launched a missile over my left shoulder, and filled the Basement Laboratory with the pungent smell of electrical death.

    Detonated electrolytic cap
    Detonated electrolytic cap

    While wiring up a hairball test circuit for that Pololu driver, I’d put a pair of electrolytic caps on the +5 and +12 V supply lines, seeing as how solderless breadboards aren’t all that great for power distribution. The brown fur growing just to the upper right of the heatsink is what’s left of a 16 V cap that had 25 V applied for a few seconds: I’d wired in the bench supply in place of the breadboard’s fixed +12 V output and forgot all about the caps.

    The cap body departed for the far reaches of the Basement Laboratory, leaving behind shredded cardboard and unrolled plastic strips. I’m sure it’ll turn up some day.

    Nothing else took any damage, but for a few minutes I thought I’d killed Eks’ AM503 current probe, which pokes in from the lower right.

    The black lump just above the probe is an ordinary AC current transformer that didn’t work well at all: the 1/rev frequency was just too low.

    If you don’t always wear glasses at the workbench, start now.

  • Stepper Sync Wheel: Current Waveform First Light

    Eks loaned me a Tek AM503 Current Probe Amplifier, one of those gorgeous instruments that Just Works: a clamp-on DC to 50 MHz Hall Effect current meter. Because it’s electrically isolated from all the hideous electrical hash that surrounds any stepper motor driver circuit, it doesn’t see much of the garbage that pollutes any current sensor depending on a series resistance and a differential amplifier.

    Which lets you take pix like this:

    Stepper Test
    Stepper Test

    From top to bottom:

    The initial ramp occupying the first third of each step comes from the motor’s L/R time constant coupled with the 9 V supply I was using. Back of the envelope: 2 mH / 2 Ω = 1 ms. With 8 V (9 V less MOSFET drops &c) applied, the initial slope = 8 V / 2 mH = 2500 A/s, so in 75 ms it rises 187 mA: close enough.

    The small ripples show the A4988 chopping the current to maintain the proper value for each microstep.

    Looks just like the pretty pictures in the datasheet, doesn’t it?

  • Bedbugs Redux

    Mary quite deliberately brought home a pair of bedbugs… even knowing what we went through, you cannot imagine how dead those things had to be. She doesn’t just want them dead, she wants them extinct.

    Anyhow.

    Some pix, atop a scale with 0.5 mm divisions:

    Bedbug - 4 mm - dorsal
    Bedbug – 4 mm – dorsal
    Bedbug - 4 mm - ventral
    Bedbug – 4 mm – ventral
    Bedbug - 6 mm - dorsal
    Bedbug – 6 mm – dorsal
    Bedbug - 6 mm - ventral
    Bedbug – 6 mm – ventral
    Bedbug - 6 mm - mouthparts
    Bedbug – 6 mm – mouthparts

    They were actually on load from Cornell’s Co-op lab, having recently been distinguished from bat bugs.

  • Thing-O-Matic: Multiple Bunnies vs Print Speed

    What’s more fun than one Stanford Bunny? A few litters!

    These at 50 mm/s feed came out a bit jittery. The ear overhangs were particularly messy:

    Small bunnies - ragged edges - 50-100
    Small bunnies – ragged edges – 50-100

    Another litter at 20 mms/s had better ear overhangs and much smoother coats with less overall jitter:

    Small bunnies - ragged ears - 20-100
    Small bunnies – ragged ears – 20-100

    The obvious shear line across their tummies came from my messing around with the HBP cabling, jerking the X stage while preventing the cables from snagging on the Y stage. Moral of the story: don’t mess around with anything inside the box while it’s printing!

    They have little droopy tails:

    Small bunnies - droopy tails - 20-100
    Small bunnies – droopy tails – 20-100

    I think 25 or 30 mm/s would be better all around, as it’d move the extruder away from the Z stage’s mechanical resonance at 1.10 rpm.

  • Gas Grill Igniter: Design Failure Therein

    The Judges at the Trinity College Home Firefighting Robot contest use butane grill igniters to light the candles in the arenas, but the gadgets seem to have terrible reliability problems: very often, they simply don’t work. I brought a few deaders back to the Basement Laboratory this April and finally got around to tearing them apart.

    It seems they don’t ignite because the trigger’s safety interlock mechanism shears the plastic gas hose against the fuel tank’s brass outlet tube:

    Grill igniter with sheared gas tube
    Grill igniter with sheared gas tube

    I tried putting a small brass tube around the (shortened and re-seated) hose, but it turns out the trigger interlock slides into that space and depends on the hose bending out of the way:

    Grill igniter with brass tubing
    Grill igniter with brass tubing

    So there’s no easy way to fix these things.

    It seems to me that a device using flammable gas should not abrade its gas hose, but what do I know?

  • Pololu Stepper Driver Board Heatsinking: Crude Prototype

    Those cute little Pololu stepper driver boards using the Allegro A4988 chip have one conspicuous problem: there’s no good way to heatsink the chip. The doc recommends heatsinking for currents around 1 A and some informal testing shows it will trip out on thermal protect around 800 mA, so heatsinking really isn’t optional.

    A thermal pad from the chip bonds to vias that conduct heat through the PCB to the bottom surface copper layer: putting a heatsink on the top doesn’t help as much as one on the bottom. What I’m doing here is a first pass at a bulk heatsink that would work with several of the driver chips lined up in a row; this one is ugly and doesn’t work well, but it should let me do some further electrical tests.

    The general idea is to clamp the heatsink around the board, with the chip as the top-side pressure point. The catch: no room for an actual heatsink underneath, because that’s where the connector pins live. You could mount the board upside-down, but then there’s no good way to tweak the stepper current trimpot. That may not be a problem after you get things set up, although I’d hate to unplug and replug the board for each adjustment.

    So I think a reasonable solution involves a metal strip to conduct the heat out the ends and up to the heatsink. What I’ve done here does not accomplish that; I’m just feeling around the parameter space.

    You can’t get too enthusiastic with the clamping force, lest you crush the chip, so moderate pressure is the rule of the day. However, the chip sits low on the board, surrounded by taller components, so I put a drop of epoxy on top and flipped it over to produce a short thermally conductive column that’s higher than everything else:

    Pololu stepper board - epoxy curing
    Pololu stepper board – epoxy curing

    The blue sheet comes from a trimmed-down TO-220 transistor heatsink pad; it’s thermally conductive silicone, provides a bit of compliance against the PCB, and insulates the REF trimpot test point from the heatsink.

    The result looks OK, but it would be better to embed a small metal block between thinner epoxy layers to get better thermal conductivity:

    Pololu stepper board - epoxy blob on driver chip
    Pololu stepper board – epoxy blob on driver chip

    Although most of the heat goes out the bottom, you still need something on the top to take the spring pressure. I trimmed down the TO-220 heatsink that came with that silicone pad; it must mount off-center to permit access to the trimpot but, alas, blocks the voltage monitoring pad and both sense resistors. A length of 45-mil music wire bent into a flat M  provides the spring:

    Pololu stepper board - heatsink top view
    Pololu stepper board – heatsink top view

    The side view show how the kludge fits together:

    Pololu stepper board - crude heatsink
    Pololu stepper board – crude heatsink

    The final result is truly ugly. The epoxy column didn’t turn out nearly as parallel to the PCB as I’d like, so some filing and finishing will be in order.

    Now, to find out if it’ll allow the chip to run above 1 A for at least a while.