16. Chapter Stepper Motor

In this chapter, we will learn a new component, Seven-segment display (SSD).

16.1. Project Seven -segment display

16.1.1. Component List

  1. Raspberry Pi (with 40 GPIO) x1

  2. GPIO Extension Board & Ribbon Cable x1

  3. Breadboard x1

Jumper Wires x6

jumper-wire

Stepper Motor x1

stepper_Motor

ULN2003 Stepper Motor Driver x1

stepper_Motor_Driver

9V battery (prepared by yourself) & battery line

Battery_cable

Breadboard Power module x1

power-module

16.1.2. Component knowledge

16.1.2.1. Stepper Motor

Stepper Motors are an open-loop control device, which converts an electronic pulse signal into angular displacement or linear displacement. In a non-overload condition, the speed of the motor and the location of the stops depends only on the pulse signal frequency and number of pulses and is not affected by changes in load as with a DC Motor. A small Four-Phase Deceleration Stepper Motor is shown here:

../../../_images/steppter_Motor_1.png

The electronic schematic diagram of a Four-Phase Stepper Motor is shown below:

../../../_images/stepper_Motor_2.png

The outside case or housing of the Stepper Motor is the Stator and inside the Stator is the Rotor. There is a specific number of individual coils, usually an integer multiple of the number of phases the motor has, when the Stator is powered ON, an electromagnetic field will be formed to attract a corresponding convex diagonal groove or indentation in the Rotor’s surface. The Rotor is usually made of iron or a permanent magnet. Therefore, the Stepper Motor can be driven by powering the coils on the Stator in an ordered sequence (producing a series of “steps” or stepped movements).

A common driving sequence is shown here:

../../../_images/stepper_Motor_3.png

In the sequence above, the Stepper Motor rotates by a certain angle at once, which is called a “step”. By controlling the number of rotational steps, you can then control the Stepper Motor’s rotation angle. By defining the time between two steps, you can control the Stepper Motor’s rotation speed. When rotating clockwise, the order of coil powered on is: A -> B -> C -> D -> A -> ... . And the rotor will rotate in accordance with this order, step by step, called four-steps, four-part. If the coils is powered ON in the reverse order, D -> C -> B -> A -> D -> ... , the rotor will rotate in counter-clockwise direction. There are other methods to control Stepper Motors, such as: connect A phase, then connect A B phase, the stator will be located in the center of A B, which is called a half-step. This method can improve the stability of the Stepper Motor and reduces noise. Tise sequence of powering the coils looks like this: A -> AB -> B -> BC -> C -> CD -> D -> DA -> A -> ..., the rotor will rotate in accordance to this sequence ar, a half-step at a time, called four-steps, eight-part. Conversely, if the coils are powered ON in the reverse order the Stepper Motor will rotate in the opposite direction.

The stator in the Stepper Motor we have supplied has 32 magnetic poles. Therefore, to complete one full revolution requires 32 full steps. The rotor (or output shaft) of the Stepper Motor is connected to a speed reduction set of gears and the reduction ratio is 1:64. Therefore, the final output shaft (exiting the Stepper Motor’s housing) requires 32 X 64 = 2048 steps to make one full revolution.

16.1.2.2. ULN2003 Stepper Motor driver

A ULN2003 Stepper Motor Driver is used to convert weak signals into more powerful control signals in order to drive the Stepper Motor. In the illustration below, the input signal IN1-IN4 corresponds to the output signal A-D, and 4 LEDs are integrated into the board to indicate the state of these signals. The PWR interface can be used as a power supply for the Stepper Motor. By default, PWR and VCC are connected.

../../../_images/stepper_Motor_Driver_1.png

16.1.3. Circuit

When building the circuit, note that rated voltage of the Stepper Motor is 5V, and we need to use the breadboard power supply independently, (Caution do not use the RPi power supply). Additionally, the breadboard power supply needs to share Ground with Rpi.

Schematic diagram

stepper_Motor_Sc

Hardware connection. If you need any support,please feel free to contact us via:

support@freenove.com

stepper_Motor_Fr

16.1.4. Sketch

In this project, a separate thread is opened to control the stepper motor. The uncertainty of the system time slice allocation may lead to the running of the stepper motor not smooth, which is a normal phenomenon.

16.1.4.1. Sketch SteppingMotor

First observe the result after running the sketch, and then learn about the code in detail.

  1. Use Processing to open the file Sketch_16_1_1_SteppingMotor.

$ processing ~/Freenove_Kit/Processing/Sketches/Sketch_16_1_1_SteppingMotor/Sketch_16_1_1_SteppingMotor.pde
  1. Click on “RUN” to run the code.

After the program is executed, Display Window shows a pattern used to simulate the motor, and a button used to control RUN/STOP state of stepper motor. The stepper motor in the circuit and the virtual motor in the Display Window will start to rotate at the same time.

../../../_images/pr_motor_cw.png

The stepper motor rotates clockwise at a fixed speed for a circle and then rotates counterclockwise for another circle, which repeats in an endless loop. Clicking on the Button can change the state (start or stop) of the stepper motor.

../../../_images/pr_motor_ccw.png

This project contains several code files, as shown below:

fnk0066/codes/_static/imgs/pr_motor_code.png

The following is program code:

 1/*****************************************************
 2 * Filename    : Sketch_16_1_1_SteppingMotor
 3 * Description : Control the stepping motor
 4 * auther      : www.freenove.com
 5 * modification: 2024/09/04
 6 *****************************************************/
 7import freenove.processing.io.*;
 8
 9int[] pins = {18, 23, 24, 25};    //connect to motor phase A,B,C,D pins 
10BUTTON btn;    //BUTTON Object, For controlling the direction of motor 
11SteppingMotor m = new SteppingMotor(pins);    
12float rotaSpeed = 0, rotaPosition = 0;  //motor speed
13boolean isMotorRun = true;    //motor run/stop flag
14
15void setup() {
16  size(640, 360);
17  btn = new BUTTON(45, height - 90, 50, 30);   //define the button
18  btn.setBgColor(0, 255, 0);  //set button color
19  btn.setText("RUN");        //set button text
20  m.motorStart();            //start motor thread
21  rotaSpeed = 0.002 * PI;  //virtual fan's rotating speed
22}
23
24void draw() {
25  background(255);
26  titleAndSiteInfo();  //title and site information
27  btn.create();      //create the button
28  if (isMotorRun) {   //motor is runnig
29    fill(0);
30    textAlign(LEFT,BOTTOM);
31    textSize(20);
32    if (m.dir == m.CW) {
33      text("CW",btn.x,btn.y);    //text "CW "
34      rotaPosition+=rotaSpeed;    
35      if (rotaPosition>=TWO_PI) {
36        rotaPosition = 0;
37      }
38    } else if (m.dir == m.CCW) {
39      text("CCW",btn.x,btn.y);  //text "CCW"
40      rotaPosition-=rotaSpeed;
41      if (rotaPosition<=0) {
42        rotaPosition = TWO_PI;
43      }
44    }
45  }
46  if (m.steps<=0) {      //if motor has stopped,
47    if (m.dir == m.CCW) {        //change the direction ,restart.
48      m.moveSteps(m.CW, 1, 512);    
49    } else if (m.dir == m.CW) {     
50      m.moveSteps(m.CCW, 1, 512);
51    }
52  }
53  drawFan(rotaPosition);    //show the virtual fan in Display window
54}
55//Draw a clover fan according to the stating angle
56void drawFan(float angle) {    
57  constrain(angle, 0, 2*PI);
58  fill(0);
59  for (int i=0; i<3; i++) {
60    arc(width/2, height/2, 200, 200, 2*i*PI/3+angle, (2*i+0.3)*PI/3+angle, PIE);
61  }
62  fill(0);
63  ellipse(width/2, height/2, 30, 30);
64  fill(128);
65  ellipse(width/2, height/2, 15, 15);
66}
67
68void exit() {
69  m.motorStop();
70  println("exit");
71  System.exit(0);
72}
73void mousePressed() {
74  if ((mouseY< btn.y+btn.h) && (mouseY>btn.y) 
75    && (mouseX< btn.x+btn.w) && (mouseX>btn.x)) { // the mouse click the button
76    if (isMotorRun) {
77      isMotorRun = false;
78      btn.setBgColor(255, 0, 0);
79      btn.setText("STOP");
80      m.motorStop();
81    } else {
82      isMotorRun = true;
83      btn.setBgColor(0, 255, 0);
84      btn.setText("RUN");
85      m.motorRestart();
86    }
87  }
88}
89void titleAndSiteInfo() {
90  fill(0);
91  textAlign(CENTER);    //set the text centered
92  textSize(40);        //set text size
93  text("Motor", width / 2, 40);    //title
94  textSize(16);
95  text("www.freenove.com", width / 2, height - 20);    //site
96}

First define 4 GPIOs connected to the motor, the BUTTON class object and SteppingMotor class object.

1int[] pins = {18, 23, 24, 25};    //connect to motor phase A,B,C,D pins 
2BUTTON btn;    //BUTTON Object, For controlling the direction of motor 
3SteppingMotor m = new SteppingMotor(pins);    

In the function setup(), initialize the Button, start thread of stepping motor, and set the rotating speed of the virtual motor.

1void setup() {
2  size(640, 360);
3  btn = new BUTTON(45, height - 90, 50, 30);   //define the button
4  btn.setBgColor(0, 255, 0);  //set button color
5  btn.setText("RUN");        //set button text
6  m.motorStart();            //start motor thread
7  rotaSpeed = 0.002 * PI;  //virtual fan's rotating speed
8}

In the function draw(), first draw the button, and calculate the position of the virtual motor and show the current rotating direction.

 1background(255);
 2titleAndSiteInfo();  //title and site information
 3btn.create();      //create the button
 4if (isMotorRun) {   //motor is runnig
 5  fill(0);
 6  textAlign(LEFT,BOTTOM);
 7  textSize(20);
 8  if (m.dir == m.CW) {
 9    text("CW",btn.x,btn.y);    //text "CW "
10    rotaPosition+=rotaSpeed;    
11    if (rotaPosition>=TWO_PI) {
12      rotaPosition = 0;
13    }
14  } else if (m.dir == m.CCW) {
15    text("CCW",btn.x,btn.y);  //text "CCW"
16    rotaPosition-=rotaSpeed;
17    if (rotaPosition<=0) {
18      rotaPosition = TWO_PI;
19    }
20  }
21}

And then determine whether the stepper motor is in stopping state according to the value of “m.steps”. If it is true, change the rotating direction of motor, and drive the motor to rotate a circle.

1if (m.steps<=0) {      //if motor has stopped,
2  if (m.dir == m.CCW) {        //change the direction ,restart.
3    m.moveSteps(m.CW, 1, 512);    
4  } else if (m.dir == m.CW) {     
5    m.moveSteps(m.CCW, 1, 512);
6  }
7}

Finally draws the virtual fan.

1drawFan(rotaPosition);

16.1.4.2. Reference

class SteppinMotor

This is a custom class that defines some methods to drive the four-phase stepper motor.

public SteppingMotor(int[] mPins)

Constructor. The parameter represents the GPIO pin connected to the stepper motor.

public void motorStart()

Start a stepper motor thread, then the thread is in the state of waiting, waiting for a notification to wake it up.

public void moveSteps(int idir, int ims, int isteps)

Used to drive stepper motor to rotate, the parameter “idir” indicates the direction that can be set as CW/CCW. The parameter “ims” is the delay (with unit ms) between each two steps of stepper motor. The higher the value of “ims”, the lower the speed of stepper motor. Parameter “isteps” specifies the number of rotating steps of the stepper motor. As for four-phase stepper motor, four steps make a cycle, if set isteps=1, which means to specify the stepping motor to rotate four steps.

public void motorStop()

Stop stepper motor.

public void motorRestart()

Restart to drive stepper motor.