Wiznet makers

ruilixin6

Published August 14, 2026 ©

106 UCC

0 VAR

0 Contests

0 Followers

0 Following

Original Link

Advanced Stepper Motor Control for Raspberry Pi Pico: A Complete Guide to Non‑Blocking Implementatio

This tutorial presents PIO-based stepper motor control on the Feng No.1 board. Different from blocking GPIO software delay driving, the independent PIO

COMPONENTS
PROJECT DESCRIPTION

PROJECT DESCRIPTION【Preliminary Note】The original hardware example in this article was written based on the RP2040. The actual hardware used in this hands-on demonstration features the W55RP20 as the main controller chip. The circuit logic and UF2 flashing operation principles are universally applicable, with only the main controller model differing. The original chip model mentioned in the circuit descriptions below is provided for reference purposes only.

PIO Stepper Motor Control

Here, we use PIO to implement single-phase drive control of a stepper motor. In short, single-phase drive control controls the energizing sequence and frequency of the stepper motor's 4 winding pairs, thereby achieving precise control of the motor's rotation angle and speed. For details, refer to the stepper motor introduction in Section 4 GPIO General Purpose Input/Output; we will not repeat it here.

As you can see, when driving a stepper motor with GPIO before, it was usually necessary to control the pin states in the main program through loops and delays. This approach blocks the main program, preventing the CPU from handling other tasks at the same time. PIO, in contrast, is an independent hardware peripheral that can run in parallel, so the main program can continue executing other tasks (such as processing sensor data, communication, etc.) while the PIO precisely controls the stepper motor.

Moreover, GPIO timing control relies on software delays (such as time.sleep_ms()), whose accuracy is limited by the operating system's scheduling and CPU load. PIO, however, can run at a fixed clock frequency, providing more precise timing control.

Here, we use the long-pin headers on the Fengya One Board - Universal Compatible Expansion Board to connect to the logic input interface on the Fengya One Board - Stepper Motor Driver Board. The pins used are shown in the following table:

ScreenShot_2026-06-09_193753_127.png

Then connect the logic output interface on the stepper motor driver board to the stepper motor:

1280X1280 (4).PNG

At the same time, turn on the DIP switches on the Fengya One Board - Stepper Motor Driver Board:

1280X1280.PNG

The overall connection is shown in the following figure:

1280X1280 (1).PNG

The following code can be found in the elegance-devkit v1\Demo\34 PIO_StepMotor folder in our resource package.

The sample code is as follows:

# Python env   : MicroPython v1.23.0
# -*- coding: utf-8 -*-        
# @Time   : 2024/7/27 1:07 PM  
# @Author : Li Qingshui            
# @File   : main.py      
# @Description : PIO experiment: control a stepper motor through PIO

# ======================================== Import related modules ========================================

# Import hardware-related modules
from machine import Pin
# Import PIO-related modules
import rp2
# Import time-related modules
import time

# ======================================== Global variables ============================================

# ======================================== Function definitions ============================================

# The @rp2.asm_pio decorator is used to define a PIO program
# Here, it sets the initial state of the 4 GPIO pins to low level; these four pins are the set pins
@rp2.asm_pio(set_init=(rp2.PIO.OUT_LOW, rp2.PIO.OUT_LOW,
                      rp2.PIO.OUT_LOW, rp2.PIO.OUT_LOW))
def step_motor() -> None:
   """
   Define the PIO program for stepper motor control.

   Args:
       None

   Returns:
       None

   Description:
       This PIO program controls the rotation of the stepper motor by setting the states of the 4 GPIO pins.
       Each pin is set to high level in turn while the other pins are set to low level, forming the single-phase control sequence of the stepper motor.
   """
   # Mark the jump destination of the program
   wrap_target()
   # Set the first pin to high level and the other pins to low level; the trailing [7] means a delay of 7 clock cycles after this instruction
   # Considering that the set instruction itself takes 1 cycle, the interval between each step of the stepper motor is 1 + 7 = 8 clock cycles
   set(pins, 0b0001)   [7]
   # Set the states of the other 3 pins in turn to form the complete single-phase control sequence of the stepper motor
   set(pins, 0b0010)   [7]
   set(pins, 0b0100)   [7]
   set(pins, 0b1000)   [7]
   # Jump the program execution back to wrap_target()
   wrap()

# ======================================== Custom classes ============================================

# ======================================== Initialization configuration ==========================================

# Delay 3s at power-up
time.sleep(3)
# Print debug information
print("FreakStudio: Using PIO to control step motor")

# Initialize the state machine instance: use state machine 0 to run the step_motor() function; the PIO execution frequency equals the system clock frequency / 2000
# Set the base pin (the first pin in the series) to GPIO 2
sm = rp2.StateMachine(0, step_motor, freq=2000, set_base=Pin(2))
sm.active(1)

# ======================================== Main program ===========================================

while True:
   pass

Here, in the PIO program, we use the set instruction to write 4-bit binary data to control the energizing of the stepper motor's 4 winding pairs (setting a pin to high level energizes 1 winding pair):

ScreenShot_2026-06-09_193833_440.png

We can also use the set instruction to write decimal 1, 2, 4, 8 or hexadecimal 0x1, 0x2, ..., with the same effect.

After flashing the code, you can see the stepper motor rotating. Through the use of the PIO peripheral, we have achieved non-blocking driving of the stepper motor:

9f458cbf-e5dc-48e5-9346-5e93cbe98c91.png
4a2f2f2b-9ac4-4c10-a913-e16398a38003.jfif

 

Documents
Comments Write