How to determine proper step rate for a stepper motor?

Hi all,

I’ve got a stepper motor that I bought from Amazon (http://www.amazon.com/gp/product/B00F4CSNDU/ref=oh_aui_detailpage_o08_s00).

It’s a 5 volt coil, 200 steps per rev motor. I couldn’t find a whole lot in the specifications department, so I’m experimenting.

I’m running the motor with a Seeed Studio motor shield V2.0 (http://www.seeedstudio.com/depot/motor-shield-v20-p-1377.html) and supplying the motor with 12 volts through an 8 ohm resistor.

Here’s the bit-banger code I’m testing it with:

///////////////////////////////////////////////
// stepper motor step rate test program
///////////////////////////////////////////////

#include <LiquidCrystal.h>

// LCD pin connections
#define _V0 33
#define _RS 32
#define _RW 31
#define _EN 30
#define _D7 29
#define _D6 28
#define _D5 27
#define _D4 26
#define _D3 25
#define _D2 24
#define _D1 23
#define _D0 22

// motor driver board defines
#define OUT1_PIN 8
#define OUT2_PIN 11
#define OUT3_PIN 12
#define OUT4_PIN 13
#define ENA_PIN 9
#define ENB_PIN 10

volatile uint8_t POS; // relative shaft position

char buffer [64];

static LiquidCrystal LCD (_RS, _RW, _EN, _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7);

int main (void)
{
	init ();
	Serial.begin (115200);

	uint16_t rate; // step delay

	// motor driver board outputs low
	digitalWrite (OUT1_PIN, LOW);
	digitalWrite (OUT2_PIN, LOW);
	digitalWrite (OUT3_PIN, LOW);
	digitalWrite (OUT4_PIN, LOW);

	// motor driver board enables off
	digitalWrite (ENA_PIN, LOW);
	digitalWrite (ENB_PIN, LOW);

	// motor driver board all outputs
	pinMode (OUT1_PIN, OUTPUT);
	pinMode (OUT2_PIN, OUTPUT);
	pinMode (OUT3_PIN, OUTPUT);
	pinMode (OUT4_PIN, OUTPUT);
	pinMode (ENA_PIN, OUTPUT);
	pinMode (ENB_PIN, OUTPUT);

	digitalWrite (_V0, LOW); // lcd backplane
	pinMode (_V0, OUTPUT);
	LCD.begin (16, 2); // 16 x 2 LCD

	while (1) {
		for (rate = 20000; rate > 5000; rate -= 500) {
			disp (rate); // display current delay constant
			motor (500, rate);
			_delay_ms (250);
			motor (-500, rate);
			_delay_ms (250);
		}
	}
}

void motor (int16_t steps, uint16_t dlay)
{
	// motor driver pins array
	const uint8_t pins[] = {
		OUT1_PIN, OUT3_PIN, OUT2_PIN, OUT4_PIN,
	};

	// half step bit pattern
	const uint8_t pattern[] = {
		0b0001, 0b0011,
		0b0010, 0b0110,
		0b0100, 0b1100,
		0b1000, 0b1001,
	};

	// 4 bits in motor drive pattern
	uint8_t x = 4;

	// how many steps in a sequence (4 or 8)
	uint8_t y = (sizeof (pattern) / sizeof (*pattern));

	// abs (steps)
	uint16_t z = (steps < 0) ? -steps : steps;

	// turn on the motor drivers
	digitalWrite (ENA_PIN, HIGH);
	digitalWrite (ENB_PIN, HIGH);

	while (z--) {
		x = 4;

		// write out next motor bit pattern
		while (x--) {
			digitalWrite (pins[x], (pattern[POS % y] & _BV (x)) ? HIGH : LOW);
		}

		// update shaft position
		POS += (steps < 0) ? -1 : +1;
		_delay_us (dlay / y);
	}

	// motor drivers off
	digitalWrite (ENA_PIN, LOW);
	digitalWrite (ENB_PIN, LOW);
}

void disp (uint16_t value)
{
	sprintf (buffer, "Delay: %5u", value);
	LCD.setLine (0, 0);
	LCD.print (buffer);
}

Here’s a video of the motor running the above code (and rotating a 10 turn pot):

OK now here’s my question: How do I tell what a “good” step rate is? I tried to determine it by how the motor sounded (how loud, how smooth) but nothing jumps out at me as making any sense.

Any ideas on how I can determine the maximum “good” step rate for this motor?

Thanks!

– Roger

Attach a pointer and make a mark at two points. Write code to step backwards and forwards between the two points with a rest between each sweep.

Keep increasing the speed until you see steps being dropped, that is the pointer not reaching as far as the marks.

Grumpy_Mike: Attach a pointer and make a mark at two points. Write code to step backwards and forwards between the two points with a rest between each sweep.

Keep increasing the speed until you see steps being dropped, that is the pointer not reaching as far as the marks.

A simple and clever idea. I like it! (and I'm going to try it right now).

Thanks!

-- Roger

Krupski: I'm running the motor with a Seeed Studio motor shield V2.0 (http://www.seeedstudio.com/depot/motor-shield-v20-p-1377.html) and supplying the motor with 12 volts through an 8 ohm resistor.

That stepper motor needs to be driven with a proper stepper motor driver board using a much higher voltage. Unfortunately it needs 2.8 amps and that is beyond the capacity of the "hobby" stepper drivers such as the Pololu A4988. However the Pololu page has a lot of useful information that will be applicable to a higher capacity stepper driver.

If you want high speeds from a stepper motor you must use a high voltage and a stepper driver board that can limit the maximum current to match the motor.

...R

Robin2:

Krupski: I'm running the motor with a Seeed Studio motor shield V2.0 (http://www.seeedstudio.com/depot/motor-shield-v20-p-1377.html) and supplying the motor with 12 volts through an 8 ohm resistor.

That stepper motor needs to be driven with a proper stepper motor driver board using a much higher voltage. Unfortunately it needs 2.8 amps and that is beyond the capacity of the "hobby" stepper drivers such as the Pololu A4988. However the Pololu page has a lot of useful information that will be applicable to a higher capacity stepper driver.

If you want high speeds from a stepper motor you must use a high voltage and a stepper driver board that can limit the maximum current to match the motor.

...R

I'm using a '298 based H-Bridge motor driver to run the stepper. The board can handle the current and the voltage just fine.

The motor I have has 5 volt coils (that is, each coil draws approximately 2.8 amps at 5 volts). So, I run it on 12 volts through a resistor to shorten the coil current rise time and limit the current.

The motor works just fine... I was simply looking for a way to determine the maximum step rate it could handle.

Krupski: The motor works just fine... I was simply looking for a way to determine the maximum step rate it could handle.

All I was trying to say is that you will get higher step rates with a proper stepper driver board and a 20v or 40v supply.

...R

the maximum step rate would mostly depend on the torque. The best way is to measure the back EMF and determine if a step has successfully occurred and how long did it took (this determines your maximum speed). Going above this will stall the motor.

Not as trivial as an open loop solution ;)

The best way is to measure the back EMF and determine if a step has successfully occurred

You sure of that?

It seems to me that you will get a back EMF from the collapsing field in the coil whether the motor moved a step or not.

This explains in larger detail:

BLDC - Sensorless

casemod: This explains in larger detail:

BLDC - Sensorless

Well it does explain about a brushless DC motor, but this thread, if you had not noticed, is about a stepping motor. The two are very different things and I think you have conflated them.

No, I was just pointing to the general sensorless theory to back up my last post For the stepper, as I mentioned on the first post, it is not trivial, but it can be done. Here's a paper that describes in detail: SENSORLESS CONTROL OF STEPPER MOTOR

I don't see how this is useful for anyone using an Arduino. It says that the update rate using the filter was not good enough to acheave stability. They recomend a DSP processor but note that they have not used this technique in practice. At the moment it is just a theoretical simulation.