La Uno se réinitialise à chaque ouverture de /dev/ttyUSB0 par mon script Pi
Traduit de Español par IA ·
Je débute un peu, désolé si c’est évident. J’ai un clone d’Arduino Uno (puce CH340) branché en USB sur un Raspberry Pi. La Uno compte les impulsions de l’interrupteur à lames (reed) de mon compteur de gaz et affiche une ligne toutes les 10 s, et un script Python sur le Pi lit ces lignes et les envoie à Hermetry.Problème : à chaque démarrage du script Python (et cron le relance s’il plante), la Uno se réinitialise. Le compteur d’impulsions repart à 0 et les premières secondes de données série sont perdues. Sur la carte dans Hermetry, je vois d’étranges chutes du total de gaz.
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=2)
# La LED de la Uno clignote, la ligne "boot" arrive, count=0
J’ai lu que c’est la ligne DTR. Comment désactiver DTR sur ttyUSB0 pour que le Pi arrête de réinitialiser l’Arduino ?
Bit of a beginner so sorry if this is obvious. I have an Arduino Uno clone (CH340 chip) plugged into a Raspberry Pi with USB. The Uno counts pulses from my gas meter’s reed switch and prints a line every 10 s, and a Python script on the Pi reads the lines and sends them to Hermetry.
Problem: every time the Python script starts (and it gets restarted by cron if it crashes), the Uno resets. The pulse count goes back to 0 and the first few seconds of serial are lost. On the board in Hermetry I get these weird drops in the gas total.
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=2)
# Uno LED blinks, "boot" line comes in, count=0
I read it’s the DTR line. How do I turn DTR off on ttyUSB0 so the Pi stops resetting the Arduino?
Traduit de English par IA ·
La solution la plus simple : ne redémarre pas le script. Lance-le comme service systemd avec Restart=always, ouvre le port une seule fois et ne le ferme jamais.
Easiest fix: don’t restart the script. Run it as a systemd service with Restart=always, open the port once and never close it.
Traduit de English par IA ·
Qu’est-ce que DTR ? J’ai le même type de montage pour un compteur d’eau
What is DTR? I have the same kind of setup for a water meter
Traduit de English par IA ·
DTR est l’une des anciennes lignes de contrôle de modem. Sur l’Uno, elle passe par un condensateur de 100 nF vers la broche de reset, afin que l’IDE puisse réinitialiser la carte avant un téléversement. Tout programme qui ouvre le port bascule DTR, et la carte se réinitialise. J’ai lutté contre ce problème sur un compteur de lignes au travail l’an dernier.Côté logiciel, deux choses à faire ensemble :
stty -F /dev/ttyUSB0 -hupcl # don't drop DTR when the port closes
ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 9600
ser.timeout = 2
ser.dtr = False
ser.open()
Attention : sous Linux, le pilote peut encore activer DTR un instant lors de la toute première ouverture après le démarrage. Cela réduit donc les réinitialisations, sans toujours les supprimer.La solution sûre passe par le matériel : un condensateur de 10 µF entre RESET et GND sur l’Uno, la borne négative sur GND. Il absorbe l’impulsion de reset. Il faut ensuite le retirer (ou appuyer sur reset à la main au bon moment) lorsque vous téléversez un nouveau firmware.Quant aux pertes dans votre total : enregistrez aussi le compteur dans l’EEPROM toutes les quelques minutes, ou faites envoyer à l’Uno un total cumulé depuis le flashage plutôt que depuis le démarrage. Une réinitialisation ne vous coûtera alors que quelques impulsions, et non tout le total.
DTR is one of the old modem control lines. On the Uno it goes through a 100 nF capacitor to the reset pin, so the IDE can reset the board before an upload. Any program that opens the port toggles DTR, so the board resets. I fought this on a line counter at work last year.
Software side, two things together:
stty -F /dev/ttyUSB0 -hupcl # don't drop DTR when the port closes
ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 9600
ser.timeout = 2
ser.dtr = False
ser.open()
Be warned that on Linux the driver may still raise DTR for a moment on the very first open after boot, so this reduces resets, it doesn’t always kill them.
The sure fix is hardware: a 10 µF capacitor between RESET and GND on the Uno, minus to GND. That swamps the reset pulse. You then have to pull it out (or press reset by hand at the right moment) when you upload new firmware.
And for the drops in your total: also keep the count in EEPROM every few minutes, or have the Uno send a running total since it was flashed instead of since boot. A reset then costs you a few pulses, not the whole total.
Traduit de English par IA ·
+1 pour l’envoi d’un total. Si tu as un jour besoin de la consommation par heure, l’API d’historique et les graphiques peuvent la calculer à partir du compteur.
+1 on sending a total. If you ever need consumption per hour, the history API and charts can work it out from the counter.
Traduit de English par IA ·
Merci James. -hupcl seul ne suffisait pas, la première ouverture après un redémarrage réinitialisait toujours la carte, comme tu l’avais dit. J’ai ajouté le condensateur de 10 µF (avec une étiquette sur la carte indiquant « retirer pour téléverser », je l’avais déjà appris à mes dépens) et les réinitialisations ont disparu. J’ai aussi déplacé le script vers systemd, comme l’a suggéré twilson. Tout est stable maintenant.
Thanks James. -hupcl alone wasn’t enough, the first open after a reboot still reset it, like you said. Put the 10 µF cap on (with a label on the board saying « remove to upload », learned that the hard way already) and the resets are gone. Also moved the script to systemd like twilson said. Total is stable now.
- Vous devez être connecté pour répondre à ce sujet.
Rejoignez la discussion
Connectez-vous pour poser et répondre à des questions, aimer les messages utiles et marquer la réponse qui a résolu votre problème. Chaque contribution rapporte des points et des niveaux.

