如何使用DRV8825同步两台步进电机?含代码优化需求
Hey there, let's tackle your stepper motor sync issue step by step. I've gone through your code and spotted a few key problems that are preventing your two motors from running in sync, plus some syntax bugs that'll cause runtime errors. Here's how to fix it all:
Key Issues in Your Original Code
- Duplicate Variable Definitions: You're redefining
CW,CCW, andSPRfor both motors, which overwrites the first set of values. This means both motors are using the same direction constants (no way to set them independently) and you lose clarity on which values belong to which motor. - Non-Synchronous Execution: You're running each motor in separate loops—first motor 1 runs full cycles, then motor 2 starts. To sync them, they need to step at the exact same time in a single loop.
- Missing GPIO Initialization: There's no code to set the GPIO mode (BCM/BOARD) or configure your DIR/STEP pins as outputs. Without this, the GPIO commands won't work at all.
- Syntax Errors: Typos like
GPIO.ouput(should beGPIO.output) and undefinedCW1will crash your script immediately.
Optimized Solution
1. Clean Constant & Pin Setup
Give each motor its own unique constants to avoid confusion and overwrites. We'll also add proper GPIO initialization to ensure pins are configured correctly.
2. Synchronous Loop Logic
Run both motors' step commands in the same loop iteration—this guarantees each motor takes one step at the exact same moment, keeping them perfectly synced.
3. Speed Adjustment
Motor speed is controlled by the delay between HIGH/LOW signals on the STEP pin. Smaller delay = faster rotation, but don't go lower than ~0.0005 seconds (2000 steps/sec) unless your motor driver is rated for higher speeds.
Full Working Code
from time import sleep import RPi.GPIO as GPIO # -------------------------- # Motor 1 Configuration # -------------------------- DIR_1 = 20 STEP_1 = 21 CW_1 = 1 CCW_1 = 0 SPR_1 = 2000 # Steps per full revolution for motor 1 # -------------------------- # Motor 2 Configuration # -------------------------- DIR_2 = 23 STEP_2 = 24 CW_2 = 1 CCW_2 = 0 SPR_2 = 2000 # Steps per full revolution for motor 2 # Speed control (adjust these values to change motor speed) step_delay = 0.001 # Delay between step pulses (lower = faster) def setup_gpio(): GPIO.setmode(GPIO.BCM) # Configure Motor 1 pins as outputs GPIO.setup(DIR_1, GPIO.OUT) GPIO.setup(STEP_1, GPIO.OUT) # Configure Motor 2 pins as outputs GPIO.setup(DIR_2, GPIO.OUT) GPIO.setup(STEP_2, GPIO.OUT) def sync_rotate_motors(dir_motor1, dir_motor2, total_steps): # Set direction for both motors first GPIO.output(DIR_1, dir_motor1) GPIO.output(DIR_2, dir_motor2) # Synchronous step loop: both motors step at the same time for _ in range(total_steps): # Trigger step pulse for both motors simultaneously GPIO.output(STEP_1, GPIO.HIGH) GPIO.output(STEP_2, GPIO.HIGH) sleep(step_delay) # End step pulse for both motors GPIO.output(STEP_1, GPIO.LOW) GPIO.output(STEP_2, GPIO.LOW) sleep(step_delay) try: setup_gpio() # Sync both motors clockwise for 1 full revolution print("Running both motors clockwise...") sync_rotate_motors(CW_1, CW_2, SPR_1) sleep(0.5) # Sync both motors counter-clockwise for 1 full revolution print("Running both motors counter-clockwise...") sync_rotate_motors(CCW_1, CCW_2, SPR_1) sleep(0.5) # Optional: Run motors in opposite directions (still fully synced) print("Running motors in opposite directions...") sync_rotate_motors(CW_1, CCW_2, SPR_1//2) # Half revolution sleep(0.5) finally: # Always clean up GPIO to avoid pin locking issues GPIO.cleanup() print("GPIO cleaned up. Done!")
Explanation
- Centralized Setup: The
setup_gpiofunction keeps configuration code organized and reusable. - True Synchronization: The
sync_rotate_motorsfunction handles both motors' step signals in the same loop iteration—no more staggered execution. - Direction Flexibility: You can set each motor to run in different directions while keeping their steps perfectly aligned (great for applications like gimbals or dual-axis systems).
- Safe Cleanup: The
finallyblock ensures GPIO is always reset, even if the script crashes unexpectedly.
内容的提问来源于stack exchange,提问作者Renz Garcia

