Désactiver DTR sur ttyUSB0

11

Je me connecte de Pi à une carte Arduino-clone. Le problème est que je dois désactiver la ligne DTR, afin d'empêcher Arduino de se réinitialiser lors de la connexion.

J'ai lu que sur RPi il n'est pas possible de contrôler DTR, DCD et d'autres lignes. Est-ce vrai pour RPi globalement ou uniquement pour les broches GPIO utilisées pour la communication série?

S'il est possible de désactiver le DTR sur le port USB, comment procédez-vous?

jnovacho
la source

Réponses:

6

Les propriétés d'un convertisseur série USB n'ont rien à voir avec le matériel du système d'hébergement, mais uniquement avec la puce série USB elle-même et la pile logicielle du système d'hébergement.

Le pi doit utiliser des pilotes série USB Linux en stock.

Par conséquent, vous pouvez activer / désactiver la liaison de DTR pour ouvrir / fermer le port via la méthode Linux habituelle d'effacement du hupclparamètre comme documenté sur le site Arduino et ailleurs:

stty -F /dev/ttyUSB0 -hupcl

Ou remplacer / dev / ttyUSB0 par le fichier de périphérique correspondant à votre port série USB (par exemple, le premier Uno connecté serait probablement / dev / ttyACM0)

Même en ce qui concerne le port série natif du PI, ce comportement de DTR est finalement sous le contrôle du logiciel - quiconque soutient le contraire ignore le fait que ce n'est que le pilote Linux, et non le matériel, qui a la moindre connaissance du port étant ouvert ou fermé. Le matériel du port réel peut seulement dire qu'il est en cours de lecture, d'écriture ou de reconfiguration, dont aucun n'est réellement synonyme d'ouverture du périphérique série.

Chris Stratton
la source
Est-ce que cela ne fonctionnera que tant que l'hébergeur pi ne sera pas redémarré?
user2395126
6

@ChrisStrattons post décrit comment utiliser stty -F /dev/ttyUSB0pour éviter le blocage qui se traduit par une réinitialisation. Voici un extrait pour le faire en Python:

import termios

path = '/dev/ttyACM0'

# Disable reset after hangup
with open(path) as f:
    attrs = termios.tcgetattr(f)
    attrs[2] = attrs[2] & ~termios.HUPCL
    termios.tcsetattr(f, termios.TCSAFLUSH, attrs)

ser = serial.Serial(path, 9600)
# etc.

Notez que le nombre exact peut lors du rebranchement du câble USB, donc je détecte le chemin en globbant:

try:
    path = glob.glob('/dev/ttyACM*')[0]
except IndexError:
    # retry, error out, etc.
    pass
Lekensteyn
la source
J'ai confirmé que cela fonctionne dans Ubuntu sur un ordinateur portable x86_64 générique et un Raspberry Pi 2.
Cerin
Y a-t-il une raison de l'utiliser termiospar exemple os.system("stty -F /dev/ttyUSB0 -hupcl")? De plus, btw, j'ai remarqué que cela n'empêche pas l'Arduino de se réinitialiser la première fois que vous vous y connectez après la mise sous tension du système hôte; il l'empêche de se réinitialiser lors des connexions suivantes. C'est mieux que rien. Mais j'aimerais pouvoir comprendre comment l'empêcher de basculer DTR.
Jason C
2
@JasonC Using termiosenregistre un fork / exec (appel) dans un programme externe ( stty). Je ne sais pas quoi faire à propos de la chose DTR, je pense que j'ai juste accepté cette "fonctionnalité" et ajouté une logique (poignée de main personnalisée par écriture / lecture) pour détecter si l'Arduino et l'application sur le Pi se sont synchronisés.
Lekensteyn
Ma solution ultime a été d'ajouter la commande stty au démarrage de la pi, suivie d'un écho au port pour forcer cette première réinitialisation et d'un délai de 3 secondes pour attendre la réinitialisation de l'arduino. Ensuite, je n'ai plus à y penser après cela ni à m'en soucier dans les scripts Python. Je l'ai fait dans rc.local mais partout. Le coût est de +3 secondes de temps de démarrage pi.
Jason C
3

Vous pouvez ajouter une résistance de 120 ohms (ou une combinaison pour créer une résistance de 120 ohms) entre RESETet 5Vcela empêchera la réinitialisation complète. C'est le moins invasif car d'autres solutions nécessitent de retirer une résistance ou un condensateur de la carte, cela complique les téléchargements. Ne conservez pas la résistance si vous programmez. Retirez-le.

entrez la description de l'image ici

Les cartes Leonardo ne sont pas réinitialisées même si elles DTRsont déclenchées, mais le problème commence lorsque vous devez le réinitialiser à distance, car parfois il perd la connexion à Raspberry et vous devez le réinitialiser physiquement.

Piotr Kula
la source
3
Je ne suis pas sûr que cela mérite un downvote. Il craint de le faire et n'est pas basé sur un logiciel, mais après quelques recherches, il semble être la solution matérielle de travail.
Jason C
0

Si vous utilisez la bibliothèque Seria et pySerial, vous pouvez utiliser:

ser = serial.Serial ('/ dev / ttyACM0', 9600, dsrdtr = True)

polo04
la source
-1

Vous pouvez utiliser PySerial. Voici un exemple sur le code Python:

port =serial.Serial(
    "/dev/ttyUSB0",
    baudrate=57600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    dsrdtr = False
    )

pour plus d'options, consultez Pyserial.

hsantana8
la source
1
Ce n'est pas un problème de bibliothèque. J'ai déjà essayé 4 bibliothèques différentes, toujours le même résultat - les commandes DTR sont ignorées.
jnovacho
S'il s'agit d'une déclaration précise de quelque chose qui fonctionne sur un autre Linux, cela devrait également fonctionner sur le pi, car le matériel pi n'héberge que des logiciels linux génériques , et n'est pas uniquement impliqué.
Chris Stratton
1
Ça ne marche pas. Sous Linux, cela provoque toujours la réinitialisation de l'Arduino.
Cerin
1
Peut confirmer que cela ne fonctionne pas sur n'importe quelle version du Pi et de l'Arduino que j'ai (je ne sais pas, désolé, je ne sais rien de ces choses, je ne veux pas savoir, on m'a juste donné un système pour déboguer du code sur, heh.) Aussi, je ne sais pas si c'est lié, mais les stty -F /dev/ttyUSB0 -cdtrdsrrapports invalid argument: -cdtrdsr.
Jason C