Chapter 10. Stepper Motors

If you have a standard printer (or, for that matter, a 3D printer), it probably contains a stepper motor or several. Figure 10-1 is responsible for feeding the plastic into the extruder of the 3D printer. Stepper motors are commonly used in printers because they move in a very precise way, one step at a time.

Figure 10-1. A stepper motor in a 3D printer

Quite different techniques are required to control stepper motors compared to DC motors. In this chapter, both unipolar and bipolar stepper motors are used, and the various driver chips that you will need to drive the motors are explored.

Stepper Motors

As the name suggests, stepper motors rotate in a series of short steps. This has the advantage that if the motor is free to turn, then by counting the steps you tell it to turn through, you know how much it has turned. This is one reason why stepper motors get used in printers, both of the 2D and 3D variety, to accurately position paper, a 3D printer bed, or print nozzle. Figure 10-2 shows three different types of stepper motor.

Figure 10-2. A selection of stepper motors

The tiny motor on the left is of the type used to move lens elements in a compact camera or smartphone camera. In the center is a 5V geared stepper motor. This combines both a stepper motor and a gearbox. On the right is a stepper motor typical of the sort you would find in a printer.

Bipolar Stepper Motors

Figure 10-3 shows how a stepper motor works. More specifically, it shows how a bipolar stepper motor works. In “Unipolar Stepper Motors”, you will learn about a different type of stepper motor.

Figure 10-3. How a bipolar stepper motor works

Typically, there will be four coils, the opposite coils being connected together so that they work in unison. The coils are all on the stator (outside of the motor) and therefore there is no need for a commutator and brushes as there is in a DC motor.

In a stepper motor, the rotor is made in the form of a cog with alternating north and south poles marked by N and S. There will normally be a lot more cogs on the rotor than the number shown in Figure 10-3. Each of the coils can be energized to be magnetic north or south depending on the direction of the current through the coil (do you smell H-bridges in the air?). Coils 1 and 3 operate together, so that if Coil 1 is N so will Coil 3 be. The same applies to Coils 2 and 4.

Starting with Figure 10-3a, if Coil 1 (and therefore Coil 3) is energized to be S then opposites attract and like poles repel, so the rotor will rotate conter-clockwise until the S of Coil 1 is aligned with the nearest N cog, as shown in Figure 10-3b. To keep the clockwise turning, the next step is to energize Coils 2 and 4 to be N (Figure 10-3c), pulling the nearest S cog to Coil 2 level with the coil.

After all this effort, the motor has now advanced one step. To continue rotating counter-clockwise, Coil 1 now needs to be N. 

Table 10-1 shows the sequence of coil activations to rotate the motor counter-clockwise.

Table 10-1. Sequence for counter-clockwise rotation of a stepper motor
Coil 1 and 3 Coil 2 and 4
S -
- N
N -
- S

A dash indicates that the coil is not having any effect on the rotation and does not need to be energized. In the cases where there is a dash, the polarity could be arranged to be the same as the cog that will be directly opposite it, to give an extra push to the motor, giving the revised table (Table 10-2).

Table 10-2. Revised sequence of activations for rotation of a stepper motor
Coil 1 and 3 Coil 2 and 4
S N
N N
N S
S S

You may be wondering what would have happened if we had started with Coil 2 rather than Coil 1. In that case, the other coil being energized will encourage the cog in the correct direction.

To reverse the direction of the rotor, all you need to do is energize the coils in the reverse of the table order in Table 10-2.

Experiment: Controlling a Bipolar Stepper Motor

There are two coils (well, actually two pairs, for a total of four coils altogether) to control and we need to reverse the direction of the current in both coils, so what we need is two H-bridges. This sounds like a job for the L293D.

In this experiment (shown in Figure 10-4), you will use an L293D on the breadboard to control a bipolar stepper motor using both Arduino and Raspberry Pi.

Figure 10-4. Controlling a bipolar stepper motor

Although this experiment uses a 12V stepper motor, it will still work with a 6V battery box to supply power to the motor. It will have less torque, but will turn just as well.

Parts List

Whether you are using a Raspberry Pi or Arduino (or both), you are going to need the following parts to carry out this experiment:

Name Part Sources
IC1 L293D H-bridge IC

Adafruit: 807

Mouser: 511-L293D

C1 100nF capacitor

Adafruit: 753

Mouser: 810-FK16X7R2A224K

C2 100µF 16V capacitor 

Adafruit: 2193

Sparkfun: COM-00096
Mouser: 647-UST1C101MDD

M1 Bipolar stepper motor 12V

Adafruit: 324

  6V (4 x AA) battery box Adafruit: 830
  400-point solderless breadboard Adafruit: 64
  Male-to-male jumper wires

Adafruit: 758

   Female-to-male jumper wires (Raspberry Pi only) Adafruit: 826

If you are planning to try this experiment with a Raspberry Pi, you will need female-to-male jumper wires to connect the Raspberry Pi GPIO pins to the breadboard.

Design

Figure 10-5 shows the schematic diagram for this experiment. 

In this case, we are not going to use PWM and so the two Enable pins of the L293D are connected to 5V to leave both H-bridges permanently enabled. The stepper motor is controlled by the four connections In 1, In 2, In 3, and In 4 that will be driven by digital outputs on the Arduino or Raspberry Pi.

Figure 10-5. Schematic diagram for controlling a bipolar stepper motor

Arduino

The Arduino version of this experiment will use the Serial Monitor to send commands to the Arduino that will then control the motor. The three commands are represented by a single letter followed by a number. For example:

  • f100 moves the motor forward by 100 steps

  • r100 moves the motor 100 steps in the reverse direction

  • p10 sets the period of the delay between step pulses to be 10 milliseconds

Figure 10-6 shows the Arduino version of the experiment.

Arduino Connections

The Arduino version of this experiment uses the following pins connected to the L293D:

L293D pin name L293 pin number Arduino pin
In1 2 10
In2 7 9
In3 10 11
In4 15 8

Figure 10-7 shows the breadboard layout for Arduino.

Figure 10-6. Arduino stepper motor control

Make sure that the IC is positioned correctly (the notch should be at the top), and that C2 the 100µF capacitor has its positive lead connected to pin 8 of the L293D. The positive lead of an electrolytic capacitor like C2 is normally longer than the negative lead. The negative lead of C2 may also be marked on the body of the capacitor with a minus sign or diamond symbol.

Figure 10-7. Arduino breadboard layout for a bipolar stepper motor

Arduino Software (the Hard Way)

There are two versions of the Arduino software for this experiment. The first does things the hard way, by setting the control pins for the L293D in the sequence described in “Bipolar Stepper Motors”. This is a useful exercise for understanding exactly how the stepper motor works.

The second example sketch uses the Arduino Stepper library to do all the work and is therefore a lot shorter.

The first Arduino sketch can be found in arduino/experiments/bi_stepper_no_lib:

const int in1Pin = 10;    1
const int in2Pin = 9;
const int in3Pin = 11;
const int in4Pin = 8;

int period = 20;       2

void setup() {         3
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  Serial.begin(9600);
  Serial.println("Command letter followed by number");
  Serial.println("p20 - set the inter-step period to 20ms (control speed)");
  Serial.println("f100 - forward 100 steps");
  Serial.println("r100 - reverse 100 steps");
}

void loop() {       4
  if (Serial.available()) {
    char command = Serial.read();
    int param = Serial.parseInt();
    if (command == 'p') {         5
      period = param;
    }
    else if (command == 'f') {    6
      stepForward(param, period);
    }
    else if (command == 'r') {
      stepReverse(param, period);
    }   
  } 
  setCoils(0, 0, 0, 0); // power down
}

void stepForward(int steps, int period) {      7
  for (int i = 0; i < steps; i++) {
    singleStepForward(period);
  }
}

void singleStepForward(int period) {        8
  setCoils(1, 0, 0, 1);
  delay(period);
  setCoils(1, 0, 1, 0);
  delay(period);
  setCoils(0, 1, 1, 0);
  delay(period);
  setCoils(0, 1, 0, 1);
  delay(period);
}

void stepReverse(int steps, int period) {
  for (int i = 0; i < steps; i++) {200
    singleStepReverse(period);
  }
}

void singleStepReverse(int period) {        9
  setCoils(0, 1, 0, 1);
  delay(period);
  setCoils(0, 1, 1, 0);
  delay(period);
  setCoils(1, 0, 1, 0);
  delay(period);
  setCoils(1, 0, 0, 1);
  delay(period);
}

void setCoils(int in1, int in2, int in3, int in4) {    // 10
  digitalWrite(in1Pin, in1);
  digitalWrite(in2Pin, in2);
  digitalWrite(in3Pin, in3);
  digitalWrite(in4Pin, in4);
}
1

The code starts by defining the pins that will be used to control the motor. You can, of course, change these pins as long as you also modify your breadboard to match.

2

The variable period is the delay between each coil activation in a step of the motors’ rotation. This is initially set to 20 milliseconds. You can change this value over the Serial Monitor to speed up or slow down the motor.

3

The setup() function sets the control pins to be digital outputs, starts serial communication with the Serial Monitor, and then prints out a message explaining the format of the commands that you can send.

4

The loop() function waits for commands to arrive over serial and then processes them. If a command has been received (indicated by Serial.available), then loop() first reads the command letter into the variable command and then reads the number parameter that follows it.

Next, a series of if statements take the appropriate action depending on the command.

5

If the command is 'p' then the period variable is set to the number supplied as a parameter.

6

If, however, the command is 'f' or 'r'then stepForward or stepReverse is called as appropriate accompanied by the number of steps to take and the period between each polarity change in the step as parameters.

7

stepForward and stepReverse are very similar and repeatedly call singleStepForward or singleStepReverse for the number of times specified in steps.

8

Next, we come to the function singleStepForward that holds the pattern of polarities needed for the four phases to advance the motor by one step. You can see the pattern in the parameters to setCoils

9

singleStepReverse is the same as singleStepForward but reverses the sequence. Compare the steps with Table 10-2.

10

Finally, the setCoils function sets the control pins according to the pattern supplied as its parameters.

Arduino Software (the Easy Way)

The Arduino IDE includes the Stepper library, which works just fine and will reduce the size of the sketch considerably. You can find this sketch in the arduino/experiments/ex_07_bi_stepper_lib/ directory (you’ll find this in the place where you downloaded the book’s code—see “Downloading the Software”): 

#include <Stepper.h>    1

const int in1Pin = 10;
const int in2Pin = 9;
const int in3Pin = 8;
const int in4Pin = 11;

Stepper motor(200, in1Pin, in2Pin, in3Pin, in4Pin);     // 2

void setup() {       3
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  while (!Serial);
  Serial.begin(9600);
  Serial.println("Command letter followed by number");
  Serial.println("p20 - set the motor speed to 20");
  Serial.println("f100 - forward 100 steps");
  Serial.println("r100 - reverse 100 steps");
  motor.setSpeed(20);        4
}

void loop() {         5
    if (Serial.available()) {
    char command = Serial.read();
    int param = Serial.parseInt();
    if (command == 'p') {
      motor.setSpeed(param);
    }
    else if (command == 'f') {
      motor.step(param);
    }
    else if (command == 'r') {
      motor.step(-param);
    }   
  } 
}
1

The first line of the sketch imports the Stepper library, which is included as part of the Arduino IDE and does not need to be specially installed. 

2

To use the library, a variable motor is defined of type Stepper. The parameters supplied to motor set up the motor so that it can be used. The first parameter is the number of steps the motor takes per revolution. The Adafruit stepper motor that I used is specified as 200 steps, which is a common number of steps. Actually this really means 200 phase changes per revolution, which is 50 actual shaft positions per revolution. The other four parameters are the coil pins to use.

3

The setup() function is almost the same as the long version of the sketch. The message is slightly different, because in this case, the 'p' command will set the motor’s speed in rpm (revolutions per minute) rather than the raw delay time. However, both have the effect of changing the motor’s speed.

4

The default speed is also set to 20rpm in setup() using motor.setSpeed.

5

The loop() function is also very similar to the long version of the sketch; however, in this case, the number of steps and direction for the motor are specified as a positive number for forward and a negative number for reverse.

The number of quarter-steps specified in the 'f' or 'r' parameter is in this case the number of phase changes, so for one complete revolution of the Adafruit motor you will need to enter a value of 200. 

Arduino Experimentation

Try out both versions of the stepper code by all means, but here I will assume that you have ex_05_bi_stepper_lib uploaded to your Arduino. Open the Serial Monitor and you should be greeted with the message shown in Figure 10-8.

Figure 10-8. Controlling the stepper motor in the Serial Monitor

Enter the command f200 and click Send. The motor should turn through one complete revolution. If it doesn’t turn, but rather jitters or hums, it probably means that you positioned one of the coil leads incorrectly. So, swap over the stepper leads that go to pins 3 and 6 of the L293D and try the command again.

Try r200 and the motor should turn through one revolution in the opposite direction.

Next, try experimenting with the speed using the command p followed by the speed in rpm. For example,  p5 followed by f200. Again the motor will turn one revolution, but very slowly. You can increase the speed by specifying a higher value, say p100, but you will find that there is a maximum speed somewhere around 130rpm before some steps get lost and the motor does not make one complete revolution.

Raspberry Pi

Controlling a stepper motor using Python or a Raspberry Pi is very similar to the non-library Arduino approach. Controlling the L293D will require four control outputs from the Raspberry Pi.

The Python program will prompt you to enter the inter-phase delay, direction, and number of steps to take.

Raspberry Pi Connections

You can keep the breadboard layout as the Arduino, but the header pins for connecting to the Raspberry Pi need to be female-to-male rather than male-to-male. Figure 10-9 shows the breadboard layout to connect to a Raspberry Pi.

Figure 10-9. Raspberry Pi breadboard layout for a stepper motor

Raspberry Pi Software

The Raspberry Pi version of the stepping code is almost a word-for-word translation of the non-library Arduino code. This program is called bi_stepper.py and is located in the python/experiments directory (you’ll find this in the place where you downloaded the book’s code):

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

in_1_pin = 23      1
in_2_pin = 24
in_3_pin = 25
in_4_pin = 18

GPIO.setup(in_1_pin, GPIO.OUT)
GPIO.setup(in_2_pin, GPIO.OUT)
GPIO.setup(in_3_pin, GPIO.OUT)
GPIO.setup(in_4_pin, GPIO.OUT)

period = 0.02

def step_forward(steps, period):     2
  for i in range(0, steps):
    set_coils(1, 0, 0, 1)
    time.sleep(period)
    set_coils(1, 0, 1, 0)
    time.sleep(period)
    set_coils(0, 1, 1, 0)
    time.sleep(period)
    set_coils(0, 1, 0, 1)
    time.sleep(period)

def step_reverse(steps, period):   
  for i in range(0, steps):
    set_coils(0, 1, 0, 1)
    time.sleep(period)
    set_coils(0, 1, 1, 0)
    time.sleep(period)
    set_coils(1, 0, 1, 0)
    time.sleep(period)
    set_coils(1, 0, 0, 1)
    time.sleep(period)

  
def set_coils(in1, in2, in3, in4):      3
  GPIO.output(in_1_pin, in1)
  GPIO.output(in_2_pin, in2)
  GPIO.output(in_3_pin, in3)
  GPIO.output(in_4_pin, in4)
  

try:
    print('Command letter followed by number');
    print('p20 - set the inter-step period to 20ms (control speed)');
    print('f100 - forward 100 steps');
    print('r100 - reverse 100 steps');
    
    while True:       4
        command = raw_input('Enter command: ')
        parameter_str = command[1:] # from char 1 to end
        parameter = int(parameter_str)      5
        if command[0] == 'p':      6
            period = parameter / 1000.0
        elif command[0] == 'f':
            step_forward(parameter, period)
        elif command[0] == 'r':
            step_reverse(parameter, period)

finally:
    print('Cleaning up')
    GPIO.cleanup()
1

The program defines constants for the four control pins and sets them to be outputs.

2

The step_forward and step_reverse functions are just like their equivalents in the Arduino. The four coil activations take place in the appropriate order using the set_coils function. This is repeated steps times with a delay of period between each change in coil activation.

3

set_coils sets the digital output control pins according to its four parameters.

4

The main loop of the program reads the command string using raw_input. The parameter that follows the letter is first cut off the command using the syntax [1:], which for a Python string means the string from position 1 (the second character) to the end of the string.

5

This string parameter is then converted into a number using the int built-in function.

6

A series of three if statements then carry out the appropriate action for the command, either changing the value of the period variable or sending the motor in one direction or the other.

Raspberry Pi Experimentation

Run the Python program using the command sudo python ex_07_bi_stepper.py. You will be prompted with the possible commands that you can enter. These are just the same as for the Arduino version.

Test out running the motor in both directions and find the smallest value of delay that you can achieve before the motor starts missing steps:

$ sudo python ex_05_bi_stepper.py 
Command letter followed by number
p20 - set the inter-step period to 20ms (control speed)
f100 - forward 100 steps
r100 - reverse 100 steps
Enter command: p5
Enter command: f50
Enter command: p10
Enter command: r100
Enter command: 

Unipolar Stepper Motors

Unipolar stepper motors work in a very similar manner to bipolar motors, but do not need H-bridges to control them. The accomplish this trick by a more complicated coil arrangement. Figure 10-10 shows how a unipolar stepper motor works.

A unipolar stepper motor will have five leads rather than the four of a bipolar motor. Four of the leads are just the same as those of a bipolar motor; they are just the ends of the coils, A, B, C, and D. In fact, there will be another pair of coils, not shown in Figure 10-10, just like a bipolar motor. If you want to, you can use the leads A, B, C, and D with an H-bridge just as if it is a bipolar stepper and it will work just fine.

Figure 10-10. A unipolar stepper motor

The fifth lead connects half way along each of the coils. If you imagine that this lead was connected to ground, then you can polarize the coil to be North by supplying power through A or South by supplying power to B. No need for an H-bridge.

Darlington Arrays

Although you do not need an H-bridge to use a unipolar stepper motor, the motor coils still take too much current to be driven directly from the pins of an Arduino or Raspberry Pi.

The obvious way of upping the current is to use transistors, just as you did back in “Experiment: Controlling a Motor”. You will of course need four transistors, one for each of the coil connections A, B, C, and D. You will also need current limiting resistors connected to the bases of these transistors as well as protection diodes across each coil. Figure 10-11 shows the schematic that you might use to connect to each coil of a unipolar stepper. For a full system, you would need to repeat this four times.

Figure 10-11. Driving a unipolar stepper with separate transistors

You can make this just fine on the breadboard, but there will be quite a lot of wires to connect up.

A neater approach is to use a driver chip such as the ULN2803. These low-cost ICs have eight Darlington transistors in one package, and also include diode protection and base resistors, so the only thing you need to add is a reservoir capacitor.

The ULN2803 can provide 500mA per channel and a maximum voltage of 50V. 

In “Experiment: Controlling a Unipolar Stepper Motor”, you will use one of these devices to control a unipolar stepper motor from Arduino and Raspberry Pi.

Experiment: Controlling a Unipolar Stepper Motor

Figure 10-12 shows an Arduino controlling a unipolar stepper motor. The motor used is another widely available stepper motor type. It includes an integrated 1:16 reduction gearbox. So, although the motor itself only has 32 steps, the gearbox means that it actually takes 513 phase changes for one revolution, equating to 128 steps per revolution.

Figure 10-12. Controlling a unipolar stepper motor with a Raspberry Pi

Hardware

Figure 10-13 shows the circuit of Figure 10-11 reimplemented using a ULN2003. Note that there are still four unused Darlington transistors that could be used to control a second stepper motor. For higher-current stepper motors, you can even double-up the outputs by connecting two inputs together with the corresponding two outputs.

The motor used here is 5V and also low current enough to draw its power from the Raspberry Pi or Arduino. It draws about 150mA with two coils activated. If you have a hungrier motor, or one that operates at a higher voltage, you will need to use a separate power supply, as you did with the bipolar stepper motor.

Finding which leads are connected to what inside the motor can be done in the same way as for bipolar motors (see “Identifying Stepper Motor Leads”) with the added complication that there is a common lead. So, start by identifying the common lead, which will give resistance to turning when connected to any of the other leads. Then use the same method as for a bipolar motor on the remaining leads.

Figure 10-13. Schematic for unipolar motor control (lead colors may vary)

Parts List

Whether you are using a Raspberry Pi or Arduino (or both), you are going to need the following parts to carry out this experiment:

Name Part Sources
IC1 ULN2803

Adafruit: 970

Mouser: 511-ULN2803A

C2 100µF 16V capacitor 

Adafruit: 2193

Sparkfun: COM-00096
Mouser: 647-UST1C101MDD

M1 Unipolar Stepper Motor 5V

Adafruit: 858

  6V (4 x AA) battery box Adafruit: 830
  400-point solderless breadboard Adafruit: 64
  Male-to-male jumper wires

Adafruit: 758

  Female-to-male jumper wires (Raspberry Pi only) Adafruit: 826

If you are planning to try this experiment with a Raspberry Pi, you will need female-to-male jumper wires to connect the Raspberry Pi GPIO pins to the breadboard.

Arduino Connections

Figure 10-14 shows how an Arduino Uno can be connected up to a ULN2803.

Figure 10-14. Connecting an Arduino to a ULN2803

You need to make sure that the capacitor is positioned properly, with the longer positive lead to the right. The chip should be positioned with the notch toward the top of the board.

The layout is actually really neat compared with that of the bipolar layout. 

Raspberry Pi Connections

Figure 10-15 shows the Raspberry Pi layout and connections.

Figure 10-15. Connecting a Raspberry Pi to a ULN2803

Software

Apart from the fact that some of the pins are swapped over, the software for both Arduino and Raspberry Pi is exactly the same as for “Experiment: Controlling a Bipolar Stepper Motor”. The programs with the modified pin connections are:

  • For the Arduino: uni_stepper_lib.ino 
  • For the Raspberry Pi: uni_stepper.py 

Microstepping

You probably noticed that the stepper motor’s rotation was not very smooth, even when rotating fairly fast. For most applications, this isn’t really a problem, but sometimes it’s nice to have the movement be a bit smoother.

Microstepping is a technique that allows a much smoother motion of the motor. Rather than simply turning the coils on and off, PWM is used to energize the coils more smoothly. This creates a smoother rotation of the motor.  

While possible using software, it is generally easier to use hardware specifically designed to microstep stepper motors such as the EasyDriver designed by Brian Schmalz. This board is based on the A3967 IC.

You can find a great tutorial on using this board with an Arduino on Sparkfun’s project page for this board (product ROB-12779), so I will not repeat that information here. Instead, I offer a Raspberry Pi alternative in the form of “Experiment: Microstepping on Raspberry Pi”.

Experiment: Microstepping on Raspberry Pi

In this experiment, you will use an EasyDriver stepper motor board to microstep the 12V bipolar stepper motor that you used in “Experiment: Controlling a Bipolar Stepper Motor” with a Raspberry Pi. You could also use a unipolar motor, but don’t connect the common lead and use the unipolar motor as if it were bipolar.

The EasyDriver stepper motor board is supplied with header pins that allow it to be plugged directly onto breadboard.

Figure 10-16 shows the finished build for the experiment.

Figure 10-16. Microstepping with a Raspberry Pi

Parts List

You need the following parts to carry out this experiment:

Part Sources
EasyDriver stepper motor board Sparkfun: ROB-12779
Bipolar stepper motor 12V

Adafruit: 324

6V (4 x AA) battery box Adafruit: 830
400-point solderless breadboard Adafruit: 64
Female-to-male jumper wires Adafruit: 826

Most 12V stepper motors will work OK at 6V, but feel free to substitute the battery pack for a 12V power supply.

Raspberry Pi Connections

Figure 10-17 shows the breadboard layout and connections to the Raspberry Pi.

Figure 10-17. Breadboard layout and connections for microstepping with a Raspberry Pi

The EasyDriver board has the capacitors on board that you would normally need to add to your circuit. It also has a voltage regulator chip that provides the power supply to its A3967 IC, so you do not even need to supply the board with power from the Pi. All that is needed is a common ground and four control signals. 

Software

As its name correctly suggests, the EasyDriver stepper motor is extremely easy to control using software. The main process of telling the motor to step is accomplished by just two control pins. When the step pin receives a HIGH pulse, the motor takes one step in the direction set by the direction pin.

Two other pins, ms1 and ms2, control the degree of microstepping from none to 1/8th.

The code for the following program is in the microstepping.py file (which you’ll find in the place where you downloaded the book’s code): 

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

step_pin = 24
dir_pin = 25
ms1_pin = 23
ms2_pin = 18

GPIO.setup(step_pin, GPIO.OUT)
GPIO.setup(dir_pin, GPIO.OUT)
GPIO.setup(ms1_pin, GPIO.OUT)
GPIO.setup(ms2_pin, GPIO.OUT)

period = 0.02

def step(steps, direction, period):   1
  GPIO.output(dir_pin, direction)  
  for i in range(0, steps):
    GPIO.output(step_pin, True)
    time.sleep(0.000002)
    GPIO.output(step_pin, False)
    time.sleep(period)

def step_mode(mode):                  2
    GPIO.output(ms1_pin, mode & 1)    3
    GPIO.output(ms2_pin, mode & 2)

try:
    print('Command letter followed by number');
    print('p20 - set the inter-step period to 20ms (control speed)');
    print('m - set stepping mode (0-none 1-half, 2-quater, 3-eighth)');
    print('f100 - forward 100 steps');
    print('r100 - reverse 100 steps');
    
    while True:                        4
        command = raw_input('Enter command: ')
        parameter_str = command[1:] # from char 1 to end
        parameter = int(parameter_str)
        if command[0] == 'p':
            period = parameter / 1000.0
        elif command[0] == 'm':
            step_mode(parameter)
        elif command[0] == 'f':
            step(parameter, True, period)
        elif command[0] == 'r':
            step(parameter, False, period)

finally:
    print('Cleaning up')
    GPIO.cleanup()

By now, you should be familiar with the GPIO pin setup and initialization code that starts most of the Python programs in this book. If not, refer back to some of the earlier chapters.

1

The function step contains the actual code for moving the motor on by a number of steps (or microsteps). It takes parameters of the number of steps to take, the direction (0 to 1), and the period of the delay to leave between each step. The body of the function first of all sets the direction pin (dir_pin) of the EasyDriver board and then generates the required number of pulses on the step_pin. The duration of each step_pin pulse is just 2 microseconds. The datasheet for the A3967 says that the pulse must be at least 1 microsecond.

2

The step_mode function sets the stepping mode pins according to the value of mode that should be between 0 and 3.

3

The code inside step_mode separates the two bits of the mode number and sets ms1_pin and ms2_pin using the logical and operator (&amp;). Table 10-3 shows the relationship between the mode number, the microstepping pins, and the behavior of the motor.

Table 10-3. Microstepping control pins
Value of mode ms1_pin ms2_pin Microstepping mode
0 LOW LOW None
1 HIGH LOW Half stepping
2 LOW HIGH Quarter stepping
3 HIGH HIGH One eighth stepping
4

The main loop() function is very similar to that of the Python program for “Experiment: Controlling a Bipolar Stepper Motor” except that an extra command of m is added to allow the microstepping mode to be set.

Experimenting

Run the program microstepping.py and then the program will prompt you to enter a command:

$ sudo python microstepping.py 
Command letter followed by number
p20 - set the inter-step period to 20ms (control speed)
m - set stepping mode (0-none 1-half, 2-quater, 3-eighth)
f100 - forward 100 steps
r100 - reverse 100 steps
Enter command: m0
Enter command: p8
Enter command: f800

Enter the commands m0, p8, and then f800. This should result in the motor rotating through four revolutions (for a 200-step motor). Make a mental note of the smoothness (or otherwise) of the rotation. Next, enter the following commands: m3, p1, f6400.

The motor should still rotate four times and at the same speed but noticeably smoother.

Note that to keep the same speed, the period between steps was reduced by a factor of 8 and the number of steps (or in this case, microsteps) increased by a factor of 8.

Brushless DC Motors

Brushless DC (BLDC) motors (Figure 10-18) are the ferocious little high-powered motors that you find in quadcopters and remote control airplanes. Weight for weight, they can create far more torque than a regular DC motor. They are included in this chapter, because although technically a DC motor, they actually have more in common with stepper motors.

Figure 10-18. A BLDC motor

Unlike “brushed" DC motors (see Chapter 7), BLDC motors do not have a mechanical commutator that reverses the direction of the current as the motor rotates. Instead, they are more similar in design to a stepper motor, except that instead of having two coils (each in pairs) they have three, repeated many times. They can therefore be classified as three-phase motors, and driving these motors involves more than just an H-bridge. In fact, each of the three connections to a coil must be capable of sourcing current, sinking current, and also being in a third “high impedance” state where the coil connection is effectively disconnected. To drive the motor effectively, the motor driver circuit measures the voltage at the “disconnected” coil for a particular coil to adjust the time for switching to the next phase.

Sadly, there does not seem to be a readily available breadboard-able IC that can take on the role of driving such a motor, so the best bet is to look for a ready-made driver board, of which various models can be found on eBay.

If you want the power and size of a BLDC motor without the fuss of a driver board, you can also buy motors that have a built-in controller and just two wires exiting the motor housing, so that you can use it just like it is a DC motor. In fact, the velocity pump pictured back in Figure 7-13 uses just such a motor.

Summary

In this chapter, we have explored the topic of stepper motors and learned how they can be used with both Arduino and Raspberry Pi. In the next chapter, you will learn about how to control heating and cooling. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.88.252