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

树莓派4B多进程控制小车电机动力不足问题求助

问题分析与解决方案

核心原因

multiprocessing创建的子进程会复制父进程的内存空间,但GPIO和PWM对象是和硬件寄存器绑定的专属资源,子进程里的power_a、power_b只是父进程对象的空副本,并没有真正和硬件建立有效连接。调用ChangeDutyCycle时,这些副本无法正确控制电机的占空比,最终导致电机功率不足。

线程版正常是因为所有线程共享同一进程的资源,GPIO/PWM对象从始至终都是有效的。

解决方案

方案1:在Flask服务进程内重新初始化GPIO和PWM

把GPIO配置、PWM初始化逻辑移到start_server函数里,让子进程自己创建有效的硬件连接,不要复用父进程的资源:

def start_server(shared_allowed_movement):
    global local_allowed_movement, power_a, power_b, in1, in2, en_a, in3, in4, en_b
    
    local_allowed_movement = shared_allowed_movement
    
    # 子进程内单独初始化GPIO与PWM
    in1 = 23
    in2 = 24
    en_a = 25
    in3 = 17
    in4 = 27
    en_b = 22
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(in1,GPIO.OUT)
    GPIO.setup(in2,GPIO.OUT)
    GPIO.setup(en_a,GPIO.OUT)
    GPIO.output(in1,GPIO.LOW)
    GPIO.output(in2,GPIO.LOW)

    GPIO.setup(in3,GPIO.OUT)
    GPIO.setup(in4,GPIO.OUT)
    GPIO.setup(en_b,GPIO.OUT)
    GPIO.output(in3,GPIO.LOW)
    GPIO.output(in4,GPIO.LOW)

    power_a = GPIO.PWM(en_a,1000)
    power_b = GPIO.PWM(en_b,1000)
    power_a.start(1)
    power_b.start(1)
    
    app.run(host='192.168.100.36', port=8000, threaded=True)

同时删除主进程里的GPIO/PWM初始化代码,避免父进程提前占用硬件资源。

方案2:用进程间通信委托专门进程处理电机控制

创建独立的电机控制进程,Flask进程只负责接收请求并通过队列发送指令,由控制进程执行实际的GPIO操作:

def motor_control_process(command_queue):
    # 初始化GPIO和PWM
    in1 = 23
    in2 = 24
    en_a = 25
    in3 = 17
    in4 = 27
    en_b = 22
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(in1,GPIO.OUT)
    GPIO.setup(in2,GPIO.OUT)
    GPIO.setup(en_a,GPIO.OUT)
    GPIO.output(in1,GPIO.LOW)
    GPIO.output(in2,GPIO.LOW)

    GPIO.setup(in3,GPIO.OUT)
    GPIO.setup(in4,GPIO.OUT)
    GPIO.setup(en_b,GPIO.OUT)
    GPIO.output(in3,GPIO.LOW)
    GPIO.output(in4,GPIO.LOW)

    power_a = GPIO.PWM(en_a,1000)
    power_b = GPIO.PWM(en_b,1000)
    power_a.start(1)
    power_b.start(1)
    
    while True:
        command = command_queue.get()
        if command == 'forward':
            power_a.ChangeDutyCycle(50)
            power_b.ChangeDutyCycle(50)
            GPIO.output(in1,GPIO.LOW)
            GPIO.output(in2,GPIO.HIGH)
            GPIO.output(in3,GPIO.LOW)
            GPIO.output(in4,GPIO.HIGH)
        elif command == 'backward':
            power_a.ChangeDutyCycle(50)
            power_b.ChangeDutyCycle(50)
            GPIO.output(in1,GPIO.HIGH)
            GPIO.output(in2,GPIO.LOW)
            GPIO.output(in3,GPIO.HIGH)
            GPIO.output(in4,GPIO.LOW)
        # 其他指令(右转、左转、停止)同理处理

# 主函数调整
if __name__ == '__main__':    
    manager = multiprocessing.Manager()
    shared_allowed_movement = manager.Value("c", "no restriction")
    command_queue = manager.Queue()
    
    server_process = multiprocessing.Process(target=start_server, args=(shared_allowed_movement, command_queue))
    motor_process = multiprocessing.Process(target=motor_control_process, args=(command_queue,))
    boundary_detection_process = multiprocessing.Process(target=boundary_detection, args=(shared_allowed_movement,))
    
    motor_process.start()
    server_process.start()
    boundary_detection_process.start()
    
    server_process.join()
    boundary_detection_process.join()
    motor_process.join()

然后修改Flask路由函数,不再直接操作GPIO,而是往队列里发送指令:

@app.route('/move_forward', methods=['POST'])
def move_forward():
    global local_allowed_movement
    
    if local_allowed_movement.value == 'no restriction':
        command_queue.put('forward')
        return jsonify({"message": "Car moving forward"})

额外修复点

move_stop函数里的power_a.start(1)是错误用法,start()只需要调用一次,调整占空比应该用ChangeDutyCycle:

@app.route('/move_stop', methods=['POST'])
def move_stop():
    power_a.ChangeDutyCycle(1)
    power_b.ChangeDutyCycle(1)
    GPIO.output(in1,GPIO.LOW)
    GPIO.output(in2,GPIO.LOW)
    GPIO.output(in3,GPIO.LOW)
    GPIO.output(in4,GPIO.LOW)
    return jsonify({"message": "Car stopped"})

验证步骤

  1. 优先测试方案1,去掉主进程的GPIO初始化逻辑,在Flask进程内重新初始化,观察电机功率是否恢复。
  2. 如果问题仍存在,检查树莓派电源供应:多进程运行会增加功耗,确保电源能提供5V 3A以上的稳定电流。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 10:52:03