OSError:[Errno 13]权限被拒绝:'/ dev/ttyACM0' - 使用pyserial从Python到Arduino

use*_*287 9 pyserial linux-mint python-2.7 arduino-uno

环境

  • 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))
Run Code Online (Sandbox Code Playgroud)

当前行为

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

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

错误信息

$ sudo tail -100 /var/log/apache2/error.log
OSError: [Errno 13] Permission denied: '/dev/ttyACM0'
Run Code Online (Sandbox Code Playgroud)

故障排除

权限

申请文件:

$ ls -l
-rwxr-xr-x 1 myname mygroupname 114146 Jan  9 19:16 my_application.py
Run Code Online (Sandbox Code Playgroud)

ttyACM0:

ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 Jan  9 20:12 /dev/ttyACM0
Run Code Online (Sandbox Code Playgroud)

所有者的群组是以下成员:

$ groups
mygroupname adm dialout cdrom sudo dip plugdev lpadmin sambashare
Run Code Online (Sandbox Code Playgroud)

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

串口可用

$ dmesg | grep tty
[    0.000000] console [tty0] enabled
[ 3390.614686] cdc_acm 3-2:1.0: ttyACM0: USB ACM device
Run Code Online (Sandbox Code Playgroud)

更新

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

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

sudo chmod 666 /dev/ttyACM0
Run Code Online (Sandbox Code Playgroud)

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

然而,这些条件不可持续,因为:

  • 每次连接USB时,权限都会重置.
  • Arduino IDE串行监视器不需要打开.

use*_*287 21

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

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

01. 改变权限,/dev/ttyACM0以便世界拥有readwrite私有(你可能不想做的事情) - 尽管你可能会发现每次插入设备时它们都会重置,例如:

sudo chmod 666 /dev/ttyACM0  
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

这还为世界的权限readwrite,你可能不希望这样做.

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

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

/sf/answers/829360241/

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

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

# open file in editor
sudo vim /etc/apache2/apache2.conf
# search for User setting
/User
Run Code Online (Sandbox Code Playgroud)

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

# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
Run Code Online (Sandbox Code Playgroud)

b) 退出vim并搜索APACHE_RUN_USERin /etc/apache2/envvars(如果上述场景适用):

# open file in editor
sudo vim /etc/apache2/envvars
# search for APACHE_RUN_USER
/APACHE_RUN_USER
Run Code Online (Sandbox Code Playgroud)

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

export APACHE_RUN_USER=www-data
Run Code Online (Sandbox Code Playgroud)

c) 将用户添加www-datadialout组:

sudo usermod -a -G dialout www-data
Run Code Online (Sandbox Code Playgroud)

d) 重启.

当Apache用户已添加到dialout组中时,脚本现在应该能够访问该设备.

进一步阅读

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

/sf/answers/854142971/