Thursday, February 20, 2014

Stepper Motors

Stepper motors are unlike ordinary motors.  A simple motor will spin when current is applied to the coils.  Reverse the polarity of the current, and the motor spins in the opposite direction.  Stepper motors, however, contain multiple coils which can be energized individually to provide precise "stepping" of the motor.

This precise control makes them perfect for a variety of applications.  They are commonly used in floppy drives, hard drives and CD/DVD drives to precisely control the speed that the disc turns as well as where the read/write heads are positioned.  They are also used in scanners to position the scanning optics and in ink jet printers to move the paper and position the print head.  Any application that requires precise positioning is likely to use stepper motors.

For more details on the many varieties of stepper motors, see the following pages:

http://en.wikipedia.org/wiki/Stepper_motor

http://www.engineersgarage.com/articles/stepper-motors

Quick Start for Beginners - http://www.freescale.com/files/microcontrollers/doc/app_note/AN2974.pdf

Stepper Motor Basics - http://www.solarbotics.net/library/pdflib/pdf/motorbas.pdf

There are two basic methods for controlling a stepper motor.  One is to use an IC specifically designed as a stepper motor controller.  The other option is to use a microprocessor (the Raspberry Pi, in this case) to directly control the individual coils of the stepper motor.  This is the method that I demonstrate in the following video.




The code for the program used in this demo follows.


#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/timeb.h>
#include <pthread.h>
#include <wiringPi.h>
const int NUM_STEPS = 6; // number of steps including half steps
int currentStep = 1; // just assume this starting point
// this maps which coils should be energized to position to each step
// using the "half-step" method
// step zero is power off. The steps then go from 1 to 6
// this is only valid for a 3 coil motor like the one used in the demo
// and must be modified to match the layout of the motor you will be using
int StepMap[7][3] = {
{0, 0, 0},
{1, 0, 0},
{1, 1, 0},
{0, 1, 0},
{0, 1, 1},
{0, 0, 1},
{1, 0, 1}};
// sleep specified number of milliseconds
int Sleep(int millisecs)
{
return usleep(1000*millisecs);
}
// moves motor to specified step using the table above
void MoveStepper(int pos)
{
int i;
// NOTE: I am just using GPIO 0, 1 and 2 to keep this simple
for (i=0; i<3; i++)
digitalWrite(i, StepMap[pos][i]);
}
// step the motor. 1 for clockwise, -1 for counter-clockwise
void step(int dir)
{
currentStep += dir;
if (currentStep>NUM_STEPS)
currentStep = 1;
else if (currentStep<=1)
currentStep = NUM_STEPS;
MoveStepper(currentStep);
}
// spin the motor briefly. Start slow and speed up
void spin()
{
int x, i;
i = 0;
x = 50;
while (i<2000)
{
step(1);
Sleep(x);
if (x>=20) x -= x/20;
else if (x>=10) x -= 1;
i++;
}
}
//************************************************************************
int main()
{
int i, x, c;
// initialize WiringPi library
x = wiringPiSetup ();
if (x == -1)
{
printf("Error on wiringPiSetup. Program quitting.\n");
return 0;
}
// set the first three GPIO pins to output and set to 0
for (i=0; i<3; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, 0);
}
// this ugly hack turns off line buffering on the console so that getchar()
// returns immediately instead of waiting for the enter key
system("stty raw");
c = 0;
while (c!='q') // loop until q key is pressed
{
c = getchar(); // read keypress
switch (c) // select what action to take
{
case 's' : // step clockwise
printf("STEP\r\n");
step(1);
break;
case 'r' : // step counter-clockwise
printf("BACK\r\n");
step(-1);
break;
case 'z' : // do the spinning demo
printf("SPIN\r\n");
spin();
printf("DONE Spinning\r\n");
break;
}
}
// set power off on the motor
MoveStepper(0);
// restore line buffering on console
system("stty cooked");
printf("STOPPED\n");
return 1;
}
view raw stepper_demo.c hosted with ❤ by GitHub

3 comments:

  1. Hello,
    Just wondering, how much cpu utilization do you get while driving 1 stepper motor via software PWM of wiring pi? Is it possible to run other processes/threads in parallel without major slowdowns?

    Have you tried 2+ stepper motors?

    Ty in advance

    ReplyDelete
    Replies
    1. I did not check the CPU utilization while running the stepper motor, but I expect that it would be pretty low. The CPU is just sleeping the vast majority of the time while doing the pulses. You should also be able to run several steppers with this method.

      Delete
  2. I also have same problem as "madks". Hope you can help us.

    ReplyDelete