树莓派 + 步进电机 + 超声波模块 = 智能硬件项目的黄金搭配!本篇文章带你完整掌握如何用 Raspberry Pi 5 控制两种常见步进电机,同时集成超声波模块实现测距
【树莓派5】实现 电机PID闭环调速 & 舵机控制(代码封装+详细代码+调试
在物联网和机器人项目中,步进电机作为一种可精准控制的电机类型,广泛用于机械臂、履带车、自动化系统等项目中。而树莓派5的强大性能和丰富的GPIO接口,使其成为控制步进电机的理想平台。
本文将详细介绍如何使用树莓派5控制两种类型的步进电机:
42步进电机(通过 D36A 驱动控制,PWM 调速)
28BYJ-48 步进电机(通过 ULN2003 驱动控制)
并介绍如何集成超声波测距模块(如 HC-SR04)实现简单的测距
步进电机是一种将电脉冲信号转化为角位移的执行元件。与普通电机不同的是,它不是连续旋转的,而是**“一步一步”前进**,这使得它非常适合应用在精确控制的位置、速度、角度的系统中。
树莓派5(已安装系统、配置好GPIO库)
42步进电机 + D36A 驱动板
28BYJ-48步进电机 + ULN2003驱动板
超声波模块 HC-SR04
面包板、杜邦线、电源模块等
D36A 引脚 | 功能 | 接树莓派 GPIO |
---|---|---|
PUL | PWM控制信号 | GPIO17 |
DIR | 控制方向 | GPIO27 |
ENA | 使能(低电平有效) | GPIO22 |
from gpiozero import PWMOutputDevice, DigitalOutputDevice
import time
pul = PWMOutputDevice(17, frequency=500)
dir = DigitalOutputDevice(27)
ena = DigitalOutputDevice(22)
# 正转
dir.on()
ena.on()
try:
pul.value = 0.5 # 占空比 50%
time.sleep(5)
# 提高速度
pul.frequency = 1000
time.sleep(5)
# 降低速度
pul.frequency = 200
time.sleep(5)
finally:
pul.off()
ena.off()
IN 引脚 | 接树莓派 GPIO |
---|---|
IN1 | GPIO17 |
IN2 | GPIO18 |
IN3 | GPIO27 |
IN4 | GPIO22 |
from gpiozero import OutputDevice
import time
class StepperMotor:
def __init__(self, in1_pin, in2_pin, in3_pin, in4_pin):
# 初始化四个控制引脚
self.in1 = OutputDevice(in1_pin)
self.in2 = OutputDevice(in2_pin)
self.in3 = OutputDevice(in3_pin)
self.in4 = OutputDevice(in4_pin)
# 全步进模式步进序列
self.step_sequence = [
[1, 0, 0, 0], # A
[0, 1, 0, 0], # B
[0, 0, 1, 0], # C
[0, 0, 0, 1] # D
]
self.current_step = 0
def rotate(self, steps, direction=1, delay=0.001):
"""
控制电机旋转指定步数
steps: 步数
direction: 1表示顺时针, -1表示逆时针
delay: 每步之间的延迟(秒),全步进模式通常需要更长的延迟
"""
for i in range(steps):
# 应用步进序列到引脚
pins = [self.in1, self.in2, self.in3, self.in4]
for i in range(4):
pins[i].value = self.step_sequence[self.current_step%4][i]
time.sleep(delay)
# 更新当前步骤
self.current_step = (self.current_step + i*direction)
def stop(self):
"""停止电机并释放所有引脚"""
pins = [self.in1, self.in2, self.in3, self.in4]
for pin in pins:
pin.value = 0
# 使用示例
if __name__ == "__main__":
# 定义连接到TB6612的GPIO引脚
# 请根据实际连接修改这些引脚号
IN1 = 17 # GPIO引脚号
IN2 = 21
IN3 = 27
IN4 = 22
# 创建步进电机对象
motor = StepperMotor(IN1, IN2, IN3, IN4)
try:
print("顺时针旋转...")
motor.rotate(500, direction=1) # 顺时针旋转100步
time.sleep(1) # 暂停1秒
print("逆时针旋转...")
motor.rotate(100, direction=-1) # 逆时针旋转100步
except KeyboardInterrupt:
print("程序被用户中断")
finally:
motor.stop() # 确保电机停止
print("程序结束")
模块引脚 | 接 GPIO |
---|---|
Trig | GPIO23 |
Echo | GPIO24 |
from gpiozero import DistanceSensor
import time
sensor = DistanceSensor(echo=24, trigger=23, max_distance=2.0)
try:
while True:
distance = sensor.distance * 100 # cm
print(f"距离: {distance:.1f} cm")
time.sleep(1)
finally:
sensor.close()
你可以根据
distance
的值来控制电机是否运行、是否加速等。
你可以将这些模块组合,构建更复杂的项目:
控制对象 | 驱动方式 | 控制手段 | 调速方法 |
---|---|---|---|
42 步进电机 | D36A | PWM + DIR + ENA | 改变 PWM 频率 |
28BYJ-48 步进电机 | ULN2003 | 相位控制序列 | 改变步进延时 |
HC-SR04 | 无驱动 | DistanceSensor | 自动测距 |
使用 gpiozero
能极大简化开发流程,非常适合初学者学习硬件控制逻辑。