OSError: [Errno 13] Permission denied: '/dev/ttyACM0' - using pyserial from Python to Arduino

Posted

技术标签:

【中文标题】OSError: [Errno 13] Permission denied: \'/dev/ttyACM0\' - using pyserial from Python to Arduino【英文标题】:OSError: [Errno 13] Permission denied: '/dev/ttyACM0' - using pyserial from Python to ArduinoOSError: [Errno 13] Permission denied: '/dev/ttyACM0' - using pyserial from Python to Arduino 【发布时间】:2015-03-07 15:00:17 【问题描述】:

环境

Linux Mint 17.1 Python 2.7 pyserial 2.7 Arduino UNO rv3

期望的行为

我正在尝试将三个值从 Python 应用程序发送到 Arduino。

从终端执行以下操作时有效:

$ python
$ import serial
$ import struct
$ ser = serial.Serial('/dev/ttyACM0', 9600)
$ ser.write(struct.pack('>3B', 255, 0, 0))

当前行为

在 Python 文件中使用相同的代码时不起作用,即:

import serial
import struct
ser = serial.Serial('/dev/ttyACM0', 9600)
ser.write(struct.pack('>3B', red_value, green_value, blue_value))

错误信息

$ sudo tail -100 /var/log/apache2/error.log
OSError: [Errno 13] Permission denied: '/dev/ttyACM0'

疑难解答

权限

申请文件:

$ ls -l
-rwxr-xr-x 1 myname mygroupname 114146 Jan  9 19:16 my_application.py

ttyACM0:

ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 Jan  9 20:12 /dev/ttyACM0

所有者所属的组:

$ groups
mygroupname adm dialout cdrom sudo dip plugdev lpadmin sambashare

由于互联网上的各种建议,我还通过系统设置 > 用户和组将所有者添加到 tty 组。这没有效果。

可用的串行端口

$ dmesg | grep tty
[    0.000000] console [tty0] enabled
[ 3390.614686] cdc_acm 3-2:1.0: ttyACM0: USB ACM device

更新

我可以强制它在以下条件下工作:

01. 世界的权限必须设置为rw 即:

sudo chmod 666 /dev/ttyACM0

02. Arduino IDE 串口监视器需要打开。

但是,这些条件是不可持续的:

每次连接 USB 时都会重置权限。 无需打开 Arduino IDE 串行监视器。

【问题讨论】:

【参考方案1】:

以下内容充实了第一个答案中的一些想法(我尝试将此内容添加到该答案并接受它,但编辑被拒绝)。我不是该领域的专家,因此请仅使用此信息来支持您自己的研究。

您可以执行以下操作之一:

01. 更改/dev/ttyACM0 的权限,使世界拥有readwrite 权限(您可能不想这样做) - 尽管您可能会发现它们每次都重置设备已插入,例如:

sudo chmod 666 /dev/ttyACM0  

02./etc/udev/rules.d 中创建一个规则来设置设备的权限(需要重启):

# navigate to rules.d directory
cd /etc/udev/rules.d
#create a new rule file
sudo touch my-newrule.rules
# open the file
sudo vim my-newrule.rules
# add the following
KERNEL=="ttyACM0", MODE="0666"

这还将世界的权限设置为readwrite,您可能不想这样做。

有关此方法的更多信息,请参阅以下答案:

https://unix.stackexchange.com/a/48596/92486

https://***.com/a/11848003/1063287

03. 第三个选项,也就是我实现的选项,将 Apache 用户添加到 dialout 组,这样如果脚本正在由 Apache 运行,则它可以访问设备.

a) 找到 Apache 配置文件的位置,然后在该文件中搜索 User 设置:

# open file in editor
sudo vim /etc/apache2/apache2.conf
# search for User setting
/User

你可能会发现类似的东西:

# These need to be set in /etc/apache2/envvars
User $APACHE_RUN_USER
Group $APACHE_RUN_GROUP

b) 退出 vim 并在 /etc/apache2/envvars 中搜索 APACHE_RUN_USER(如果上述情况适用):

# open file in editor
sudo vim /etc/apache2/envvars
# search for APACHE_RUN_USER
/APACHE_RUN_USER

你可能会发现类似的东西:

export APACHE_RUN_USER=www-data

c) 将用户 www-data 添加到 dialout 组:

sudo usermod -a -G dialout www-data

d) 重新启动。

由于 Apache 用户已添加到 dialout 组,脚本现在应该能够访问设备。

进一步阅读

如何找到 Apache 配置文件的位置:

https://***.com/a/12202042/1063287

【讨论】:

谢谢指点!在 Ubuntu 下,最终为我工作的是 askubuntu.com/a/133244/230541【参考方案2】:

文件的权限对程序运行的用户没有影响

当您以交互方式登录时,您确实有权使用 /dev/ttyACM0

当你的脚本运行时(大概是 apache 用户)它没有权限

您需要更改 /dev/ttyACM0 的权限

请参阅此处的第二个答案How can I programmatically set permissions on my char device,了解更改 udev 权限以使文件具有正确权限的示例

【讨论】:

从第二个答案sudo vim /etc/udev/udev.conf 中尝试了第一个建议,添加了default_mode="0666",关闭计算机并重新启动,权限不受影响:ls -l /dev/ttyACM0 返回:crw-rw---- 1 root dialout 166, 0 Jan 10 00:20 /dev/ttyACM0。现在正在查看第二个答案的第二个建议。 此解决方案有效:unix.stackexchange.com/a/48596/92486。 sudo vim /etc/udev/rules.d/my-newrule.rules,添加KERNEL=="ttyACM0", MODE="0666"。这为world 提供了读/写权限。但是,我不明白,当所有者是 dialout 的成员时,为什么他们一开始就没有读/写权限。 如果您通过 apache 运行脚本,那么它以 apache 用户身份运行。在 httpd.conf 中查找 User 设置。此用户必须是拨出的成员才能使用 660 权限 感谢您的澄清,我已将调查结果添加到答案中(正在审核中),并且可以确认应用程序现在按预期运行。【参考方案3】:

根据接受的答案,我可以将以下内容添加到我的 setup.sh 脚本中

printf "KERNEL==\"ttyACM0\", MODE=\"0666\"" | sudo tee /etc/udev/rules.d/si-ct.rules

【讨论】:

以上是关于OSError: [Errno 13] Permission denied: '/dev/ttyACM0' - using pyserial from Python to Arduino的主要内容,如果未能解决你的问题,请参考以下文章

OSError: [Errno 13] Permission denied: '/dev/ttyACM0' - using pyserial from Python to Arduino

Tensorboard: OSError: [Errno 22] Invalid argument

OSError:[Errno 26] 文本文件忙:'baremetrics'

如何解决:OSError: Unable to create file (unable to open file: name = ‘. et_classification.h5‘, errno = 2

OSError : [Errno 24] 打开的文件太多

Python:OSError:[Errno 2]没有这样的文件或目录:''