Environnement
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ù:
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:
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