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".

Required Components

In this project, we need the following components.

../_images/1.3.3_stepper_motor_list.png

Schematic Diagram

../_images/1.3.3_stepper_motor_schematic.png

Experimental Procedures

Step 1: Build the circuit.

../_images/1.3.3_stepper_motor_circuit.png

Step 2: Open the code file.

cd ~/davinci-kit-for-raspberry-pi/python-pi5

Step 3: Run.

sudo python3 1.3.3_StepperMotor_zero.py

As the code runs, the stepper motor will turn clockwise or anti-clockwise depending on your input 'a' or 'c'.

Code

Note

You can Modify/Reset/Copy/Run/Stop the code below. But before that, you need to go to source code path like davinci-kit-for-raspberry-pi/python-pi5. After modifying the code, you can run it directly to see the effect.

#!/usr/bin/env python3
from gpiozero import OutputDevice
from time import sleep

# Initialize motor pins to GPIO pins 18, 23, 24, 25
motorPin = [OutputDevice(pin) for pin in (18, 23, 24, 25)]

# Set motor rotation speed parameters
rotationPerMinute = 15
stepsPerRevolution = 2048
# Calculate time to wait between each step for smooth motor operation
stepSpeed = (60 / rotationPerMinute) / stepsPerRevolution

def rotary(direction):
    """
    Controls the rotation of the motor based on the specified direction.

    :param direction: 'c' for clockwise, 'a' for anti-clockwise
    """
    if direction == 'c':
        # Execute the stepping sequence for clockwise rotation
        for j in range(4):
            for i in range(4):
                if 0x99 << j & (0x08 >> i):
                    motorPin[i].on()
                else:
                    motorPin[i].off()
                sleep(stepSpeed)
    elif direction == 'a':
        # Execute the stepping sequence for anti-clockwise rotation
        for j in range(4):
            for i in range(4):
                if 0x99 >> j & (0x08 >> i):
                    motorPin[i].on()
                else:
                    motorPin[i].off()
                sleep(stepSpeed)

def loop():
    """
    Continuously prompts the user to select the motor rotation direction
    and controls the motor based on this input.
    """
    while True:
        direction = input('Select motor direction a=anticlockwise, c=clockwise: ')
        if direction == 'c':
            print('Motor running clockwise\n')
            break
        elif direction == 'a':
            print('Motor running anti-clockwise\n')
            break
        else:
            print('Input error, please try again!')

    # Keep the motor rotating in the selected direction
    while True:
        rotary(direction)

def destroy():
    """
    Safely turns off all motor pins, used for clean shutdown.
    """
    for pin in motorPin:
        pin.off()

# Main program execution
try:
    loop()
except KeyboardInterrupt:
    destroy()  # Handle keyboard interrupt to safely shut down the motor

Code Explanation

  1. This section imports necessary libraries. gpiozero for controlling GPIO pins and time for the sleep function used in timing control.

    #!/usr/bin/env python3
    from gpiozero import OutputDevice
    from time import sleep
    
  2. Initializes GPIO pins 18, 23, 24, and 25 as output devices for controlling the stepper motor.

    # Initialize motor pins to GPIO pins 18, 23, 24, 25
    motorPin = [OutputDevice(pin) for pin in (18, 23, 24, 25)]
    
  3. Sets the motor’s rotation speed and calculates the time interval between each step for smooth operation.

    # Set motor rotation speed parameters
    rotationPerMinute = 15
    stepsPerRevolution = 2048
    # Calculate time to wait between each step for smooth motor operation
    stepSpeed = (60 / rotationPerMinute) / stepsPerRevolution
    
  4. The rotary function controls the motor’s rotation. It uses bit manipulation and a stepping sequence to activate the motor pins in the correct order for either clockwise or anti-clockwise rotation.

    def rotary(direction):
        """
        Controls the rotation of the motor based on the specified direction.
    
        :param direction: 'c' for clockwise, 'a' for anti-clockwise
        """
        if direction == 'c':
            # Execute the stepping sequence for clockwise rotation
            for j in range(4):
                for i in range(4):
                    if 0x99 << j & (0x08 >> i):
                        motorPin[i].on()
                    else:
                        motorPin[i].off()
                    sleep(stepSpeed)
        elif direction == 'a':
            # Execute the stepping sequence for anti-clockwise rotation
            for j in range(4):
                for i in range(4):
                    if 0x99 >> j & (0x08 >> i):
                        motorPin[i].on()
                    else:
                        motorPin[i].off()
                    sleep(stepSpeed)
    
  5. This function continuously prompts the user to choose the motor rotation direction and controls the motor based on the input.

    def loop():
        """
        Continuously prompts the user to select the motor rotation direction
        and controls the motor based on this input.
        """
        while True:
            direction = input('Select motor direction a=anticlockwise, c=clockwise: ')
            if direction == 'c':
                print('Motor running clockwise\n')
                break
            elif direction == 'a':
                print('Motor running anti-clockwise\n')
                break
            else:
                print('Input error, please try again!')
    
        # Keep the motor rotating in the selected direction
        while True:
            rotary(direction)
    
  6. The destroy function turns off all motor pins. It’s used for a clean shutdown, ensuring that the motor stops safely when the program ends.

    def destroy():
        """
        Safely turns off all motor pins, used for clean shutdown.
        """
        for pin in motorPin:
            pin.off()
    
  7. The main program calls loop and handles keyboard interrupts (like Ctrl+C) to safely shut down the motor using destroy.

    # Main program execution
    try:
        loop()
    except KeyboardInterrupt:
        destroy()  # Handle keyboard interrupt to safely shut down the motor