You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派三轮机器人传感器数据读取与运动控制故障排查

三轮机器人前进/停止控制循环逻辑问题修复

你的核心问题是内层while循环阻塞了串口数据读取:当drive = True时,程序会进入while drive == true:的死循环,一直执行forward(),再也不会回到外层循环去读取Arduino发送的传感器数据,导致机器人一旦启动就无法响应新的距离检测结果。

同时代码里还有几处语法和逻辑错误,以下是完整的修正方案:

错误点与修正说明

  1. 循环逻辑重构:移除内层while循环,把前进动作放到主循环中,每次主循环先读取串口数据,再根据drive状态决定是否执行前进步骤,保证串口数据能被持续读取。
  2. 语法错误修正:
    • Python布尔值区分大小写,true改为True
    • ser.flush改为ser.flush()(调用方法需要加括号)
    • 关键字If改为小写if
    • 拼写错误:STEPS改为STEP3,修复引脚引用错误
    • 重复引脚操作:forward()和stop()中重复设置STEP的LOW状态,改为操作STEP3
  3. GPIO使能引脚初始化:添加EN引脚的低电平输出,启用步进电机(多数步进驱动器低电平启用)
  4. 函数优化:stop()函数无需重复设置方向,直接关闭所有步进脉冲即可;forward()中的方向设置移到初始化阶段,避免重复调用浪费资源

修正后的完整代码

import RPi.GPIO as GPIO
from time import sleep
import serial

if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.flush()  # 修正:调用flush方法
    
    # 引脚定义
    DIR = 17
    DIR2 = 24
    DIR3 = 6
    STEP = 27
    STEP2 = 23
    STEP3 = 5
    EN = 22
    EN2 = 25
    EN3 = 13
    CW = 1
    CCW = 0

    # GPIO初始化
    GPIO.setmode(GPIO.BCM)
    # 配置所有引脚为输出
    GPIO.setup(DIR, GPIO.OUT) 
    GPIO.setup(STEP, GPIO.OUT) 
    GPIO.setup(EN, GPIO.OUT) 
    GPIO.setup(DIR2, GPIO.OUT)
    GPIO.setup(STEP2, GPIO.OUT) 
    GPIO.setup(EN2, GPIO.OUT) 
    GPIO.setup(DIR3, GPIO.OUT)
    GPIO.setup(STEP3, GPIO.OUT) 
    GPIO.setup(EN3, GPIO.OUT)
    
    # 启用步进电机(低电平启用)
    GPIO.output(EN, GPIO.LOW)
    GPIO.output(EN2, GPIO.LOW)
    GPIO.output(EN3, GPIO.LOW)
    
    # 初始化前进方向
    GPIO.output(DIR, CCW)
    GPIO.output(DIR2, CW)
    GPIO.output(DIR3, CW)

    drive = False

    def forward():
        # 发送步进脉冲
        GPIO.output(STEP, GPIO.HIGH)
        GPIO.output(STEP2, GPIO.HIGH)
        GPIO.output(STEP3, GPIO.HIGH)  # 修正:STEPS改为STEP3
        sleep(0.000008)
        GPIO.output(STEP, GPIO.LOW)
        GPIO.output(STEP2, GPIO.LOW)
        GPIO.output(STEP3, GPIO.LOW)  # 修正:重复的STEP改为STEP3
        sleep(0.000008)

    def stop():
        # 停止所有步进脉冲
        GPIO.output(STEP, GPIO.LOW)
        GPIO.output(STEP2, GPIO.LOW)
        GPIO.output(STEP3, GPIO.LOW)

    try:
        while True:
            # 优先读取串口数据
            if ser.in_waiting > 0:
                line = ser.readline().decode('utf-8').rstrip('\0')
                try:
                    convert = int(line)
                    if convert < 20:
                        stop()
                        print('stop')
                        drive = False
                    else:
                        drive = True
                except ValueError:
                    # 处理串口数据格式错误
                    print(f"无效数据: {line}")
                    drive = False
            # 根据drive状态执行前进动作
            if drive:
                forward()
    finally:
        # 程序退出时清理GPIO
        GPIO.cleanup()
        ser.close()

额外说明

  • 添加了try-finally块,确保程序退出时能正确清理GPIO和关闭串口,避免引脚状态异常
  • 增加了串口数据的异常捕获,防止非整数格式的数据导致程序崩溃
  • 步进电机的延时时间(sleep(0.000008))可以根据实际电机转速需求调整,数值越小转速越快

内容的提问来源于stack exchange,提问作者Norman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:24:54