web-dev-qa-db-fra.com

OSError: [Errno 13] Autorisation refusée: '/ dev/ttyACM0' - utilisation de pyserial de Python à Arduino

Environnement

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

Comportement souhaité

J'essaie d'envoyer trois valeurs d'une application Python à Arduino. 

Cela fonctionne lorsque vous procédez comme suit depuis le terminal:

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

Comportement actuel

Cela ne fonctionne pas lorsque le même code est utilisé dans un fichier Python, à savoir:

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

Message d'erreur

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

Dépannage

Autorisations

Dossier de candidature:

$ 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

Groupes

Groupes dont le propriétaire est membre: 

$ groups
mygroupname adm dialout cdrom Sudo dip plugdev lpadmin sambashare

En raison de diverses suggestions sur Internet, j'ai également ajouté le propriétaire au groupe tty via Paramètres système> Utilisateurs et groupes. Cela n'a eu aucun effet. 

Ports série disponibles

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

Mettre à jour

Je peux forcer à travailler dans les conditions suivantes:

01. Les autorisations pour le monde doivent être définies sur rw c'est-à-dire:

Sudo chmod 666 /dev/ttyACM0

02. Arduino IDE le moniteur série doit être ouvert. 

Cependant, ces conditions ne sont pas durables dans la mesure où:

  • Les autorisations sont réinitialisées chaque fois que la clé USB est connectée. 
  • Le moniteur série Arduino IDE ne devrait pas nécessairement être ouvert. 
7
user1063287

Ce qui suit illustre certaines des idées de la première réponse (j'ai essayé d'ajouter ce contenu à cette réponse et de l'accepter, mais les modifications ont été rejetées). Je ne suis pas un expert dans le domaine, utilisez donc ces informations pour étayer vos propres recherches. 

Vous pouvez effectuer l’une des opérations suivantes:

01. Modifiez les autorisations sur /dev/ttyACM0 pour que monde ait les privilèges read et write (ce que vous ne voudrez peut-être pas faire) - bien que vous puissiez constater qu'elles sont réinitialisées chaque fois que le périphérique est branché, par exemple:

Sudo chmod 666 /dev/ttyACM0  

02. Créez une règle dans /etc/udev/rules.d qui définira les autorisations du périphérique (un redémarrage sera nécessaire): 

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

Cela définit également les autorisations pour monde sur read et write, ce que vous ne voudrez peut-être pas faire. 

Pour plus d'informations sur cette approche, voir les réponses suivantes:

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

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

03. La troisième option, qui est l'option que j'ai implémentée, ajoute l'utilisateur Apache au groupe dialout de sorte que, si le script est exécuté par Apache, il peut accéder au périphérique. 

a) Recherchez l'emplacement de votre fichier de configuration Apache, puis recherchez le paramètre User dans ce fichier: 

# open file in editor
Sudo vim /etc/Apache2/Apache2.conf
# search for User setting
/User

Vous pouvez trouver quelque chose comme: 

# These need to be set in /etc/Apache2/envvars
User ${Apache_RUN_USER}
Group ${Apache_RUN_GROUP}

b) Quittez vim et recherchez Apache_RUN_USER dans /etc/Apache2/envvars (si le scénario ci-dessus s'applique): 

# open file in editor
Sudo vim /etc/Apache2/envvars
# search for Apache_RUN_USER
/Apache_RUN_USER

Vous pouvez trouver quelque chose comme:

export Apache_RUN_USER=www-data

c) Ajoutez l'utilisateur www-data au groupe dialout:

Sudo usermod -a -G dialout www-data

d) Redémarrer. 

Comme l'utilisateur Apache a été ajouté au groupe dialout, le script devrait maintenant pouvoir accéder au périphérique. 

Lectures complémentaires

Comment trouver l'emplacement du fichier de configuration Apache:

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

15
user1063287

Les autorisations sur le fichier ne font aucune différence pour l'utilisateur que le programme s'exécute en tant que

Lorsque vous êtes connecté de manière interactive, vous êtes autorisé à utiliser/dev/ttyACM0

Lorsque votre script est en cours d'exécution (probablement en tant qu'utilisateur Apache), il n'est pas autorisé.

Vous devez modifier les autorisations sur le/dev/ttyACM0 

Voir la 2e réponse ici Comment puis-je définir par programme des autorisations sur mon périphérique char pour un exemple de modification des autorisations udev afin que le fichier dispose des autorisations appropriées

2
Vorsprung