.. note::
Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts.
**Why Join?**
- **Expert Support**: Solve post-sale issues and technical challenges with help from our community and team.
- **Learn & Share**: Exchange tips and tutorials to enhance your skills.
- **Exclusive Previews**: Get early access to new product announcements and sneak peeks.
- **Special Discounts**: Enjoy exclusive discounts on our newest products.
- **Festive Promotions and Giveaways**: Take part in giveaways and holiday promotions.
👉 Ready to explore and create with us? Click [|link_sf_facebook|] and join today!
.. _1.3.3_stepper_c_pi5:
1.3.3 Stepper Motor
====================
Introduction
------------
Stepper motors, due to their unique design, can be controlled to a high
degree of accuracy without any feedback mechanisms. The shaft of a
stepper, mounted with a series of magnets, is controlled by a series of
electromagnetic coils that are charged positively and negatively in a
specific sequence, precisely moving it forward or backward in small
\"steps\".
Components
----------
.. image:: img/list_1.3.3.png
Principle
---------
**Stepper Motor**
There are two types of steppers, unipolars and bipolars, and it is very
important to know which type you are working with. In this experiment,
we will use a unipolar stepper.
The stepper motor is a four-phase one, which uses a unipolarity DC power
supply. As long as you electrify all phase windings of the motor by an
appropriate timing sequence, you can make it rotate step by step. The
schematic diagram of a four-phase reactive stepper motor:
.. image:: img/image129.png
In the figure, in the middle of the motor is a rotor - a gear-shaped
permanent magnet. Around the rotor, 0 to 5 are teeth. Then more outside,
there are 8 magnetic poles, with each two opposite ones connected by
coil winding. So they form four pairs from A to D, which is called a
phase. It has four lead wires to be connected with switches SA, SB, SC,
and SD. Therefore, the four phases are in parallel in the circuit, and
the two magnetic poles in one phase are in series.
**Here's how a 4-phase stepper motor works:**
When switch SB is power on, switch SA, SC, and SD is power off, and
B-phase magnetic poles align with tooth 0 and 3 of the rotor. At the
same time, tooth 1 and 4 generate staggered teeth with C- and D-phase
poles. Tooth 2 and 5 generate staggered teeth with D- and A-phase poles.
When switch SC is power on, switch SB, SA, and SD is power off, the
rotor rotates under magnetic field of C-phase winding and that between
tooth 1 and 4. Then tooth 1 and 4 align with the magnetic poles of
C-phase winding. While tooth 0 and 3 generate staggered teeth with A-
and B-phase poles, and tooth 2 and 5 generate staggered teeth with the
magnetic poles of A- and D-phase poles. The similar situation goes on
and on. Energize the A, B, C and D phases in turn, and the rotor will
rotate in the order of A, B, C and D.
.. image:: img/image130.png
The four-phase stepper motor has three operating modes: single
four-step, double four-step, and eight-step. The step angle for the
single four-step and double four-step are the same, but the driving
torque for the single four-step is smaller. The step angle of the
eight-step is half that of the single four-step and double four-step.
Thus, the eight-step operating mode can keep high driving torque and
improve control accuracy.
The stator of Stepper Motor we use has 32 magnetic poles, so a circle
needs 32 steps. The output shaft of the Stepper Motor is connected with
a reduction gear set, and the reduction ratio is 1/64. So the final
output shaft rotates a circle requiring a 32*64=2048 step.
**ULN2003**
To apply the motor in the circuit, a driver board needs to be used. Stepper Motor Driver-ULN2003 is a 7-channel inverter circuit. That is, when the input pin is at high level, the output pin of ULN2003 is at low level, and vice versa. If we supply high level to IN1, and low level to IN2, IN3 and IN4, then the output end OUT1 is at low level, and all the other output ends are at high level.
The internal structure of the chip is shown as below.
.. image:: img/image338.png
The stepper motor driver constituted by ULN2003 chip and 4 LEDs is shown
as follows. On the board, IN1,IN2,IN3 and IN4 work as input and the four
LEDs, A, B, C, D are the indicators of input pin. In addition,
OUT1,OUT2, OUT3 and OUT4 are connected to SA, SB, SC and SD on the
stepper motor driver. When the value of IN1 is set to a high level, A
lights up; switch SA is power on, and the stepper motor rotates one
step. The similar case repeats on and on. Therefore, just give the
stepper motor a specific timing sequence, it will rotate step by step.
The ULN2003 here is used to provide particular timing sequences for the
stepper motor.
.. image:: img/image132.png
Schematic Diagram
-----------------
.. image:: img/image339.png
Experimental Procedures
-----------------------
**Step 1:** Build the circuit.
.. image:: img/image134.png
:width: 800
**Step 2**: Go to the folder of the code.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/c/1.3.3/
**Step 3**: Compile the code.
.. raw:: html
.. code-block::
gcc 1.3.3_StepperMotor.c -lwiringPi
**Step 4**: Run the executable file.
.. raw:: html
.. code-block::
sudo ./a.out
As the code runs, the stepper motor will rotate clockwise or
anticlockwise according to your input \'a\' or \'c\'.
.. note::
If it does not work after running, or there is an error prompt: \"wiringPi.h: No such file or directory\", please refer to :ref:`install_wiringpi_pi5`.
**Code**
.. code-block:: c
#include
#include
const int motorPin[] = {1, 4, 5, 6};
int rolePerMinute = 15;
int stepsPerRevolution = 2048;
int stepSpeed = 0;
void rotary(char direction){
if(direction == 'c'){
for(int j=0;j<4;j++){
for(int i=0;i<4;i++)
{digitalWrite(motorPin[i],0x99>>j & (0x08>>i));}
delayMicroseconds(stepSpeed);
}
}
else if(direction =='a'){
for(int j=0;j<4;j++){
for(int i=0;i<4;i++)
{digitalWrite(motorPin[i],0x99<>i));}
delayMicroseconds(stepSpeed);
}
}
}
void loop()
{
char direction = '0';
while (1)
{
printf("select motor direction a=anticlockwise, c=clockwise: ");
delay(100);
direction=getchar();
if (direction == 'c')
{
printf("motor running clockwise\n");
delay(100);
break;
}
else if (direction == 'a')
{
printf("motor running anti-clockwise\n");
delay(100);
break;
}
else
{
printf("input error, please try again!\n");
delay(100);
}
}
while(1)
{
rotary(direction);
}
}
void main(void)
{
if (wiringPiSetup() == -1)
{
printf("setup wiringPi failed !");
return;
}
for (int i = 0; i < 4; i++)
{
pinMode(motorPin[i], OUTPUT);
}
stepSpeed = (60000000 / rolePerMinute) / stepsPerRevolution;
loop();
}
**Code Explanation**
.. code-block:: c
int rolePerMinute = 15;
int stepsPerRevolution = 2048;
int stepSpeed = 0;
**rolePerMinute:** revolutions per minute, the RPM of the stepper motor
used in this kit should be 0~17.
**stepPerRevolution:** the number of steps for each turn, and the
stepper motor used in this kit needs 2048 steps per revolution.
**stepSpeed:** the time used for each step, and in main(), we assign the
values to them:「(60000000 / rolePerMinute) /
stepsPerRevolution」(60,000,000 us=1minute)
.. code-block:: c
void loop()
{
char direction = '0';
while (1)
{
printf("select motor direction a=anticlockwise, c=clockwise: ");
direction=getchar();
if (direction == 'c')
{
printf("motor running clockwise\n");
break;
}
else if (direction == 'a')
{
printf("motor running anti-clockwise\n");
break;
}
else
{
printf("input error, please try again!\n");
}
}
while(1)
{
rotary(direction);
}
}
The loop() function is roughly divided into two parts (located between two while(1)) :
The first part is to get the key value. When \'a\' or \'c\' is obtained, exit the loop and stop the input.
The second part calls rotary(direction) to make the stepper motor run.
.. code-block:: c
void rotary(char direction){
if(direction == 'c'){
for(int j=0;j<4;j++){
for(int i=0;i<4;i++)
{digitalWrite(motorPin[i],0x99>>j & (0x08>>i));}
delayMicroseconds(stepSpeed);
}
}
else if(direction =='a'){
for(int j=0;j<4;j++){
for(int i=0;i<4;i++)
{digitalWrite(motorPin[i],0x99<>i));}
delayMicroseconds(stepSpeed);
}
}
}
To make stepper motor **rotate clockwise**, level status of motorPin
should is shown in the table below:
.. image:: img/image340.png
Therefore, potential write of MotorPin is implemented by using a
two-layer of for loop.
In Step1, j=0, i=0~4.
motorPin[0] will be written in the high level(10011001&00001000=1)
motorPin[1] will be written in the low level(10011001&00000100=0)
motorPin[2] will be written in the low level(10011001&00000010=0)
motorPin[3] will be written in the high level(10011001&00000001=1)
In Step2, j=1, i=0~4.
motorPin[0] will be written in the high level(01001100&00001000=1)
motorPin[1] will be written in the low level(01001100&00000100=1)
and so on.
And to make the stepper motor rotate **anti-clockwise**, the level
status of motorPin is shown in the following table.
.. image:: img/image341.png
In Step1, j=0, i=0~4.
motorPin[0] will be written in the high level(10011001&10000000=1)
motorPin[1] will be written in the low level(10011001&01000000=0)
In Step2,j=1, i=0~4.
motorPin[0] will be written in the high level(00110010&10000000=0)
motorPin[1] will be written in the low level(00110010&01000000=0)
and so on.