Thursday, 29 December 2022

Using a Stepper Motor with a Raspberry Pi Pico

 

The Stepper Motor

A stepper motor is a type of electric motor that rotates in precise increments or ‘steps’ when electrical commands are applied. Stepper motors are commonly used in applications where precise positioning is required, such as in printers, scanners, and 3D printers.

I've written this short explanation as part of the much larger book 'Raspberry Pi Pico Tips and Tricks'. You can download it for free from here.

Stepper Motor Connection

Stepper motors can be classified as either unipolar or bipolar. Unipolar stepper motors have a single winding per phase and require a special type of drive circuit, while bipolar stepper motors have two windings per phase and can be driven with a more common H-bridge drive circuit.

Stepper motors operate by energizing the windings in a specific sequence, causing the rotor to rotate a precise number of degrees per step. The number of steps per revolution and the step angle (the angle of rotation per step) are typically specified by the manufacturer. Stepper motors can be controlled with a microcontroller or other type of controller, such as a motor driver or stepper motor driver.

There are several key differences between a stepper motor and a normal (also known as a brushed or brushless DC) motor:

  • Precise positioning: Stepper motors are capable of more accurate positioning because they rotate in precise increments or “steps” when electrical commands are applied. Normal motors, on the other hand, are not capable of precise positioning because they rotate continuously when powered.
  • Torque: Stepper motors typically have less continuous torque than normal motors, but they can deliver high torque in short bursts. Normal motors, on the other hand, can deliver a more consistent level of torque over a longer period of time.
  • Speed: Stepper motors have a limited speed range, typically up to several hundred RPM, depending on the model. Normal motors, on the other hand, can reach higher speeds and have a wider speed range.
  • Control: Stepper motors can be controlled with a microcontroller or other type of controller, such as a motor driver or stepper motor driver. Normal motors typically require a more complex drive circuit, such as an H-bridge, to control the speed and direction of rotation.
  • Cost: Stepper motors tend to be more expensive than normal motors of similar size and power due to their precision and control capabilities.

Putting the ‘Step’ into stepper motors

Stepper motors operate by energizing their windings in a specific sequence, causing the rotor to rotate a precise number of degrees per step. The number of steps per revolution and the step angle (the angle of rotation per step) are typically specified by the manufacturer.

  • The controller sends electrical commands to energize the windings in a specific sequence. For example, the sequence may be to energize winding A, then winding B, then winding C, and finally winding D.
  • When the windings are energized, the magnetic fields generated by the windings interact with the magnetic field of the permanent magnets in the rotor, causing the rotor to rotate a certain number of degrees.
  • The controller sends the next set of electrical commands to energize the windings in the next sequence. For example, the sequence may be to energize winding C, then winding D, then winding A, and finally winding B.
  • The process repeats, with the controller sending electrical commands to energize the windings in the specified sequence, causing the rotor to rotate a certain number of degrees each time. This results in the stepper motor turning in a precise, step-by-step manner.
Stepper Motor Sequence

The specific sequence of the windings being energized depends on the type of stepper motor (unipolar or bipolar) and the specific drive circuit being used.

Torque

Rated torque is a measure of the maximum torque that a stepper motor can produce under specified conditions. It is typically expressed in units of force times distance, such as Newton-meters (Nm) or ounce-inches (oz-in).

Rated torque determines the amount of force that the motor can generate to move a load. In general, a stepper motor with a higher rated torque will be able to move a larger or heavier load than a motor with a lower rated torque.

It is important to note that the rated torque of a stepper motor is not constant and can vary depending on factors such as operating voltage, current, speed, and temperature. In general, the rated torque of a stepper motor decreases as the speed increases, and it may also be affected by the type and size of the load being driven.

The 28BYJ-48

The 28BYJ-48 is a small, low-cost stepper motor commonly used in hobbyist and educational projects. It has a 5V operating voltage and is driven by a ULN2003A driver board (or similar stepper motor driver).

The 28BYJ-48 has a step angle of 5.625 degrees and a step resolution of 64 steps per revolution, resulting in a total of 4096 steps per revolution. It has a rated torque of 44.4 g-cm (0.6 oz-in) and a maximum no-load speed of approximately 15 RPM.

The 28BYJ-48 is a unipolar stepper motor, meaning it has a single winding per phase and requires a special type of drive circuit to operate (hence the use of the ULN2003A driver board). It is commonly used in applications such as small robotics, educational models, and DIY projects.

Connecting the Pico to the controller to the GY-521

The connection from the ULN2003A driver board to the motor is via a pre-made molex connector. Power is applied to the ULN2003A via the + and - connectors which should be connected to a 5V supply. In the connection diagram below that power is being sourced from the VBUS connector of the Raspberry Pi Pico. We need to be a little bit careful here. The 28BYJ-48 is quite power hungry (around 240mA) and typically this should come from a separate power source. However, in this case, the VBUS connector on the Pico is connected directly to the 5V supply from the USB connector and so long as that has sufficient power we should be alright. Having said that, be aware that this is a very simple motor and it will consume power even when it is standing still. If we leave it for a few minutes, we can feel it getting warm.

The power connections are as follows;

  • VBUS (Pin 40) -> +
  • GND (Pin 38) -> -

The 28BYJ-48 rotates by sending signals to its four coils in a specific sequence that switches the coils on and off in a pattern that creates a magnetic field that rotates the motor. Those four coils are controlled from four GPIO pins on the Pico. In our case we will use GPIO18, 19,20 and 21. For no reason other than they make drawing the circuit diagram below slightly prettier.

The connections are as follows;

  • GPIO18 (Pin 24) -> IN1
  • GPIO19 (Pin 25) -> IN2
  • GPIO20 (Pin 26) -> IN3
  • GPIO21 (Pin 27) -> IN4
Stepper Motor Connection

Code

The following code demonstrates the stepper motor turning in one direction;

from machine import Pin
from time import sleep

IN1 = Pin(18,Pin.OUT)
IN2 = Pin(19,Pin.OUT)
IN3 = Pin(20,Pin.OUT)
IN4 = Pin(21,Pin.OUT)

pins = [IN1, IN2, IN3, IN4]

sequence = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]

while True:
    for step in sequence:
        for i in range(len(pins)):
            pins[i].value(step[i])
            sleep(0.001)

The following code allows the motor to turn in different directions through a function call;

import time
from machine import Pin

# Constants for the stepper motor pins
IN1 = Pin(18, Pin.OUT)
IN2 = Pin(19, Pin.OUT)
IN3 = Pin(20, Pin.OUT)
IN4 = Pin(21, Pin.OUT)

# Sequence for moving the stepper motor
SEQUENCE = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]

# Function to move the stepper motor
def move_stepper(direction, steps):
    # Set the input pins
    pins = [IN1, IN2, IN3, IN4]

    # Set the direction of the sequence
    if direction == 'forward':
        sequence = SEQUENCE
    elif direction == 'backward':
        sequence = list(reversed(SEQUENCE))

    # Loop through the specified number of steps
    for i in range(steps):

        # Set the input pins based on the current step
        for j in range(len(pins)):
            pins[j].value(sequence[i%4][j])

        # Delay between steps
        time.sleep(0.005)

# Main loop
while True:
    # Move the stepper motor forward
    move_stepper('forward', 400)

    # Move the stepper motor backward
    move_stepper('backward', 400)

Don't forget, if you're looking for the book 'Raspberry Pi Pico Tips and Tricks'. You can download it for free (or donate if you wish) from here.

No comments:

Post a Comment