Thing-O-Matic: Large Knots

Printing tiny knots showed the need for support under the loop takeoff points, which xorxo’s Hi-Res 3D Knot provides:

Large Knot - scaffolded
Large Knot - scaffolded

My Shop Assistant cleaned up a second version:

Large Knot cleaned - top
Large Knot cleaned - top

As the scrawled notation says: printed at 50 mm/s with 100 mm/s moves. The only cleanup: remove the scaffolding and slice off the Reversal zittage.

If the truth be known, that was actually the third knot. The first suffered a spectacular failure: one corner of the filament spool snagged on the wall behind the printer and jammed the filament:

Large Knot - failed
Large Knot - failed

The filament drive pulled all the slack out of the bundle, broke off three of the six internal guide posts (admittedly, they’re just hot-melt glued in place), and dragged a nasty kink halfway down the feeder tube. Obviously the stepper was shedding steps during that whole process, but it came rather close to doing the Ouroboros thing.

While that went down, I was puttering around in the far reaches of the Basement Laboratory, attempting to clean up a bit of the clutter, and checking in on the printer every now and again. Seemed like a good idea at the time, is all I can say.

Perhaps the Lords of Cosmic Jest simply decided this was an appropriate object to mess with. The vertices of the hexagonal filament spool stick out perhaps 10 mm from the printer’s backside and every one has cleared the wall on countless previous rotations. I moved the entire affair a bit further from the wall and maybe it’ll be all good from now on.

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?