树莓派控制WS2811 LED与音频输出权限冲突问题求助
树莓派WS2811 LED控制与音频输出权限冲突问题解决
问题概述
我在制作小型机器人时遇到权限冲突:
- 使用
rpi_ws281x库控制WS2811 LED时,必须用sudo运行脚本,否则会触发以下错误:
Traceback (most recent call last): File "/home/pi/Desktop/robot.py", line 97, in <module> strip.begin() File "/home/pi/.local/lib/python3.11/site-packages/rpi_ws281x/rpi_ws281x.py", line 143, in begin raise RuntimeError('ws2811_init failed with code {0} ({1})'.format(resp, str_resp)) RuntimeError: ws2811_init failed with code -5 (mmap() failed)
- 但通过
subprocess.call实现的音频输出,仅在不使用sudo时能正常工作,导致同一脚本无法同时满足两个功能的权限要求。
我尝试过将用户pi加入gpio和kmem组、修改/dev/gpiomem权限、添加udev规则、配置sudoers等操作,但都未解决问题。同时我注意到论坛推荐切换到带SPI的GPIO引脚,不清楚原因,恳请帮助。
已尝试操作
- 将用户
pi加入gpio和kmem组; - 执行以下命令:
sudo usermod -aG gpio www-data sudo chown root:gpio /dev/gpiomem sudo chmod g+rw /dev/gpiomem
- 在
/etc/udev/rules.d/99-custom-permissions.rules中添加:
KERNEL=="mem", GROUP="kmem", MODE="0660"
- 在sudoers文件中添加:
%pi ALL=(ALL) ALL
解决方案
1. 修复非sudo下的LED控制权限
错误代码-5(mmap失败)的核心原因是rpi_ws281x在PWM模式下需要直接访问物理内存(/dev/mem),仅加入gpio组不够,需确保以下步骤正确执行:
- 确认
pi用户已加入kmem组:
若未显示groups pikmem,执行:
注意:修改组权限后必须重新登录或重启树莓派,才能让权限生效sudo usermod -aG gpio,kmem pi - 重新加载udev规则:
sudo udevadm control --reload-rules && sudo udevadm trigger - 检查
/dev/mem权限:
应显示ls -l /dev/memcrw-rw---- 1 root kmem ...,确保kmem组有读写权限。
2. 切换到SPI引脚的原因
rpi_ws281x支持两种驱动模式:
- PWM模式(如引脚12):需要直接映射物理内存,必须root权限或特殊组权限,容易和音频(通常依赖ALSA的普通用户权限)冲突;
- SPI模式:利用Linux系统的SPI设备驱动,普通用户只需加入
spi组即可访问/dev/spidev0.0,无需sudo。
切换步骤:
- 启用树莓派SPI接口:通过
raspi-config的"Interface Options"开启SPI; - 将
pi加入spi组:sudo usermod -aG spi pi - 修改代码中的引脚配置:将原本的PWM引脚(如12)改为SPI对应的MOSI引脚(通常是引脚19),初始化
Adafruit_NeoPixel时指定对应strip类型并启用SPI模式(具体参数参考库文档)。
3. 分离进程的折中方案
如果不想修改硬件引脚,可将LED控制和音频输出拆分为两个独立脚本:
- 编写一个仅负责LED控制的脚本,用
sudo后台运行; - 主脚本以普通用户身份运行,负责音频输出,通过管道、本地socket或临时文件向LED脚本发送控制指令(比如灯光颜色、亮度)。
示例逻辑:
- LED脚本:监听本地socket,收到指令后调用
rpi_ws281x接口; - 主脚本:播放音频的同时,向socket发送LED控制命令。
内容的提问来源于stack exchange,提问作者Niggels
相关产品推荐
相关产品推荐

