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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
Hello,
ReplyDeleteJust 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
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.
DeleteI also have same problem as "madks". Hope you can help us.
ReplyDelete