OSError:[Errno 13] 权限被拒绝:'/dev/ttyACM0' - 使用从 Python 到 Arduino 的 pyserial [英] OSError: [Errno 13] Permission denied: '/dev/ttyACM0' - using pyserial from Python to Arduino

查看:42
本文介绍了OSError:[Errno 13] 权限被拒绝:'/dev/ttyACM0' - 使用从 Python 到 Arduino 的 pyserial的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境

  • Linux Mint 17.1
  • Python 2.7
  • pyserial 2.7
  • Arduino UNO rv3

期望的行为

我正在尝试从 Python 应用程序向 Arduino 发送三个值.

I'm trying to send three values from a Python application to Arduino.

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

It works when doing the following from terminal:

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

当前行为

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

It doesn't work when using the same code in a Python file ie:

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 组.这没有效果.

Due to various suggestions on the internet I also added the owner to the tty group via System Settings > Users and Groups. This had no effect.

可用串口

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

更新

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

I can force it to work under the following conditions:

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

01. Permissions for world must be set to rw ie:

sudo chmod 666 /dev/ttyACM0

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

02. Arduino IDE serial monitor needs to be open.

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

However these conditions are not sustainable as:

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

推荐答案

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

The following fleshes out some of the ideas in the first answer (I tried to add this content to that answer and accept it, but the edits were rejected). I'm not an expert in the area, so please just use this information to support your own research.

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

You can do one of the following:

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

01. Alter the permissions on /dev/ttyACM0 so that world has read and write priviliges (something you may not want to do) - although you may find they reset each time the device is plugged in eg:

sudo chmod 666 /dev/ttyACM0  

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

02. Create a rule in /etc/udev/rules.d that will set the permissions of the device (a restart will be required):

# 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"

这也将 world 的权限设置为 readwrite,您可能不想这样做.

This also sets permissions for world to read and write, which you may not want to do.

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

For more information about this approach, see these answers:

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

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

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

03. The third option, which is the option I implemented, adds the Apache user to the dialout group so that if the script is being run by Apache, then it can access the device.

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

a) Find the location of your Apache config file, then search for the User setting within that file:

# 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(如果上述情况适用):

b) Quit vim and search for APACHE_RUN_USER in /etc/apache2/envvars (if the above scenario applies):

# 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 组:

c) Add the User www-data to the dialout group:

sudo usermod -a -G dialout www-data

d) 重新启动.

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

As the Apache user has been added to the dialout group, the script should now be able to access the device.

进一步阅读

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

How to find the location of the Apache config file:

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

这篇关于OSError:[Errno 13] 权限被拒绝:'/dev/ttyACM0' - 使用从 Python 到 Arduino 的 pyserial的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆