树莓派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
相关产品推荐
相关产品推荐

