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

树莓派4多进程模式下PWM控制失效问题求助

解决思路

1. 明确多进程与线程的GPIO/PWM资源差异

线程共享同一进程的GPIO上下文,PWM对象可以直接复用;但multiprocessing创建的子进程拥有独立的地址空间,父进程初始化的PWM实例无法被子进程继承——因为PWM依赖的内核定时器、GPIO资源是进程私有,子进程无法访问父进程已分配的这些资源。

2. 子进程内独立初始化PWM

不要在父进程中创建PWM对象后传递给子进程,必须在每个需要使用PWM的子进程内部单独完成GPIO初始化和PWM创建:

def motor_control_proc():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(MOTOR_PWM_PIN, GPIO.OUT)
    motor_pwm = GPIO.PWM(MOTOR_PWM_PIN, 1000)  # 子进程内单独初始化PWM
    motor_pwm.start(0)
    # 后续PWM控制逻辑

3. 排查多进程下的GPIO资源冲突

  • 如果混用RPi.GPIO和pigpio:pigpio通过守护进程管理GPIO,进程间可共享句柄;但RPi.GPIO的PWM是进程私有,子进程必须独立初始化RPi.GPIO,且父进程不要提前调用GPIO.cleanup(),否则会释放子进程的GPIO资源。
  • 避免多个子进程同时操作同一个PWM引脚,这会导致资源竞争,无有效信号输出。

4. 验证PWM信号的实际输出

用示波器或逻辑分析仪直接测量PWM引脚:

  • 无波形输出:说明子进程的PWM初始化未生效,检查子进程内的GPIO设置代码是否执行;
  • 有波形但设备无响应:排查电机/灯光的驱动电路(比如H桥使能引脚是否正确置高,电源是否正常)。

5. 用单进程专门处理PWM输出(推荐)

通过进程间通信(IPC)让单个子进程负责所有PWM控制,其他进程仅发送指令,避免资源竞争:

from multiprocessing import Process, Queue

def pwm_handler(control_queue):
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(MOTOR_PIN, GPIO.OUT)
    pwm = GPIO.PWM(MOTOR_PIN, 1000)
    pwm.start(0)
    
    while True:
        cmd = control_queue.get()
        if cmd == "exit":
            break
        if isinstance(cmd, int):
            pwm.ChangeDutyCycle(cmd)
    
    pwm.stop()
    GPIO.cleanup()

# 主进程逻辑
cmd_queue = Queue()
pwm_proc = Process(target=pwm_handler, args=(cmd_queue,))
pwm_proc.start()

# 发送控制指令
cmd_queue.put(30)  # 设置30%占空比
# 退出时发送指令
cmd_queue.put("exit")
pwm_proc.join()

6. 检查进程权限与资源清理

  • 确保所有进程以root权限运行(GPIO操作需要权限);
  • 在子进程内部处理GPIO资源清理,不要依赖父进程的GPIO.cleanup(),避免子进程资源被提前释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 02:36:08