机器人推杆的核心控制逻辑是通过改变电机运转方向、调节运行速度、控制运行时长来实现推杆的伸缩动作,Python可以结合不同的硬件接口完成对应的控制逻辑编写。

硬件准备与环境配置
根据推杆驱动方式的不同,需要的硬件和Python依赖也有所区别:
- 若使用树莓派直接控制推杆驱动板,需要准备树莓派4B、推杆驱动模块、12V推杆电机,安装
RPi.GPIO库,安装命令为pip install RPi.GPIO - 若使用串口控制独立的推杆控制器,需要准备USB转串口模块、串口通信型推杆控制器,安装
pyserial库,安装命令为pip install pyserial - 通用准备:推杆供电电源、杜邦线若干,确保硬件接线牢固,避免短路烧坏设备
基于树莓派GPIO的控制实现
这种方式通过树莓派的GPIO引脚输出高低电平,控制驱动模块的方向引脚,同时输出PWM信号调节速度,实现推杆的伸缩控制。
硬件接线说明
驱动模块的IN1、IN2引脚分别连接到树莓派的GPIO17、GPIO18,PWM引脚连接到GPIO27,驱动模块电源端接12V外接电源,输出端与推杆电机接线对应连接。
代码实现
import RPi.GPIO as GPIO
import time
# 引脚定义
IN1_PIN = 17
IN2_PIN = 18
PWM_PIN = 27
PWM_FREQ = 1000 # PWM频率,单位Hz
def init_gpio():
# 设置GPIO模式为BCM
GPIO.setmode(GPIO.BCM)
# 设置引脚为输出模式
GPIO.setup(IN1_PIN, GPIO.OUT)
GPIO.setup(IN2_PIN, GPIO.OUT)
GPIO.setup(PWM_PIN, GPIO.OUT)
# 创建PWM对象,初始占空比0
pwm = GPIO.PWM(PWM_PIN, PWM_FREQ)
pwm.start(0)
return pwm
def push_rod_forward(pwm, speed=50, duration=2):
# 推杆伸出,IN1高电平,IN2低电平
GPIO.output(IN1_PIN, GPIO.HIGH)
GPIO.output(IN2_PIN, GPIO.LOW)
# 设置PWM占空比,控制速度
pwm.ChangeDutyCycle(speed)
time.sleep(duration)
# 停止输出
pwm.ChangeDutyCycle(0)
def push_rod_backward(pwm, speed=50, duration=2):
# 推杆缩回,IN1低电平,IN2高电平
GPIO.output(IN1_PIN, GPIO.LOW)
GPIO.output(IN2_PIN, GPIO.HIGH)
pwm.ChangeDutyCycle(speed)
time.sleep(duration)
pwm.ChangeDutyCycle(0)
def stop_rod():
# 停止推杆,两个方向引脚都输出低电平
GPIO.output(IN1_PIN, GPIO.LOW)
GPIO.output(IN2_PIN, GPIO.LOW)
if __name__ == "__main__":
try:
pwm_obj = init_gpio()
print("推杆开始伸出")
push_rod_forward(pwm_obj, speed=60, duration=3)
time.sleep(1)
print("推杆开始缩回")
push_rod_backward(pwm_obj, speed=60, duration=3)
stop_rod()
finally:
GPIO.cleanup()基于串口通信的控制实现
很多成熟的推杆控制器支持串口指令控制,这种方式不需要直接操作GPIO,只需要按照控制器的协议发送指令即可,通用性更强。
控制协议说明
假设控制器支持的指令格式为:0x01 0x02 0x03 0x04表示伸出,0x01 0x02 0x03 0x05表示缩回,0x01 0x02 0x03 0x00表示停止,波特率为9600,数据位8,停止位1,无校验。
代码实现
import serial
import time
# 串口配置,根据实际情况修改端口号,Linux下为/dev/ttyUSB0,Windows下为COM3
SERIAL_PORT = "/dev/ttyUSB0"
BAUD_RATE = 9600
def init_serial():
# 打开串口
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
if ser.is_open:
print("串口打开成功")
else:
print("串口打开失败")
return ser
def send_command(ser, cmd_bytes):
# 发送指令
ser.write(cmd_bytes)
time.sleep(0.1)
def rod_forward(ser):
# 发送伸出指令
cmd = bytes([0x01, 0x02, 0x03, 0x04])
send_command(ser, cmd)
print("已发送伸出指令")
def rod_backward(ser):
# 发送缩回指令
cmd = bytes([0x01, 0x02, 0x03, 0x05])
send_command(ser, cmd)
print("已发送缩回指令")
def rod_stop(ser):
# 发送停止指令
cmd = bytes([0x01, 0x02, 0x03, 0x00])
send_command(ser, cmd)
print("已发送停止指令")
if __name__ == "__main__":
ser_obj = init_serial()
try:
rod_forward(ser_obj)
time.sleep(3)
rod_stop(ser_obj)
time.sleep(1)
rod_backward(ser_obj)
time.sleep(3)
rod_stop(ser_obj)
finally:
ser_obj.close()调试注意事项
- 首次运行代码前,先断开推杆电源,测试引脚输出或串口指令是否符合预期,避免误操作损坏硬件
- PWM占空比建议从低到高逐步调试,过高的占空比可能导致驱动模块过载
- 如果需要精准控制推杆行程,可以搭配限位开关,在代码中读取开关状态实现自动停止
- 长时间运行的控制逻辑建议添加异常处理,避免程序崩溃后推杆持续运行