[Résolu] Terminal ubuntu et port série

Salut a tous :slight_smile:

Ça fait maintenant quelque jours que je cherche comment faire ceci :

Je voudrais, en lignes de commandes, stocker les lignes qui viennent du port série “ttyACM0” (mon Arduino). Mon problème vient du fait qu’apparemment “cat /dev/ttyACM0” et “cat < /dev/ttyACM0” sont bloquants :confused:

Le script actuel →

#!/bin/bash

stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

while [ 1 ]
do
	message=`tail -f -n 1 /dev/ttyACM0`

	echo "$message"

        echo "DEBUG"

	if [ $message == "Une Phrase" ]
	then
		echo "It worked!!"
	fi
done

Rien ne s’affiche jamais, ni “DEBUG”, ni le contenu de $message :confused:

Merci d’avance :slight_smile:

EDIT :

Mon but final est en fait d’exécuter la commande

yes "yes" | w3m -dump "https://smsapi.free-mobile.fr/sendmsg?user=xxxxxxxx&pass=xxxxxxxxxx&msg=Un%20Message%20:)

Lorsque mon arduino envoie une chaine de caractères précise.

Si quelqu’un sait comment faire cela, même d’une autre manière que celle décrite plus haut, s’il vous plaît, dites le moi!! :slight_smile:

Bonjour,
"tail -f" est bloquant : il ne faut pas mettre l'option -f si tu veux juste la dernière ligne
Cependant, ttyACM0 est vu comme un pipe, donc il est bloquant lui aussi.

Pour éviter ça, il est possible d'utiliser la fonction read avec un timeout :

while true ; do
  read -t 1 message
 if $? -eq 0 ; then
   # $message contient des choses
 fi
done

(j'ai pas essayé en vrai -> à tester)

piif:
Bonjour,
"tail -f" est bloquant : il ne faut pas mettre l'option -f si tu veux juste la dernière ligne
Cependant, ttyACM0 est vu comme un pipe, donc il est bloquant lui aussi.

Pour éviter ça, il est possible d'utiliser la fonction read avec un timeout :

while true ; do

read -t 1 message
if $? -eq 0 ; then
  # $message contient des choses
fi
done




(j'ai pas essayé en vrai -> à tester)

Merci piif, par contre je suis vraiment très débutant en bash (d'ailleurs je n'ai quasiment rien pratiqué, je me suis servi de mes connaissances en c, les langages se ressemblent) et du coup, je comprend pas tout :confused:

Où est stocké le message?
Pourquoi "read -t 1 message" et pas "read -t 1 /dev/ttyACM0"?

Merci pour ta réponse :slight_smile:

Oups, désolé, j’ai oublié un bout :
read -t 1 message < /dev/ttyACM0

La fonction “read” prend en argument le nom de la variable dans laquelle il faut stocker le résultat
Au dela du timeout (ici 1 seconde), elle retourne un statut d’erreur
En bash, ce status est stocké dans la variable $?, donc "if [ 1 -eq 0 ]" sera vrai si ? vaut 0 c’est à dire “OK” en bash (les commandes retournent 0 pour OK et une valeur différente par status d’erreur)

En passant, j’ai l’impression que la balise code du forum a bouffé un bout : le if contient des , c’est donc bien if [ $? -eq 0 ] ; then …

Bash est une version un peu moins vieille de sh qui date des années 70. Je pense que c’est la syntaxe la plus pourrie que j’aie jamais rencontrée, faut un peu de temps pour s’y habituer :slight_smile:

piif:
Oups, désolé, j’ai oublié un bout :
read -t 1 message < /dev/ttyACM0

La fonction “read” prend en argument le nom de la variable dans laquelle il faut stocker le résultat
Au dela du timeout (ici 1 seconde), elle retourne un statut d’erreur
En bash, ce status est stocké dans la variable $?, donc “if [ $1 -eq 0 ]” sera vrai si $? vaut 0 c’est à dire “OK” en bash (les commandes retournent 0 pour OK et une valeur différente par status d’erreur)

En passant, j’ai l’impression que la balise code du forum a bouffé un bout : le if contient des , c’est donc bien if [ $? -eq 0 ] ; then …

Bash est une version un peu moins vieille de sh qui date des années 70. Je pense que c’est la syntaxe la plus pourrie que j’aie jamais rencontrée, faut un peu de temps pour s’y habituer :slight_smile:

Merci beaucoup pour ces précisions :slight_smile:

Par contre, Voici un échantillon du retour pendant que l’arduino envoie quelque chose en boucle →

no
o
o




no
no
o
o



no
o
o




o
o

L’arduino envoie “Resetting the crossin’ chrono”…

Le script affiche donc toujours seulement les deux derniers ou le dernier caractère de la ligne :confused:

De mon coté, j’utilise un programme perso comme moniteur série et j’ai souvent un problème de lignes coupées n’importe comment. Par contre, il ne manque rien.

En shell, j’ai jamais essayé, je ne sais donc pas s’il y a des choses à faire notamment dans la tonne de paramètres de la commande stty.
Peut-être que le canal est “non bloquant” contrairement à ce que je pensais et que du coup il y a des valeurs de perdues entre deux appels

si tu fais juste un tail -f /dev/ttyACM0, est-ce que tout s’affiche correctement ?

piif:
De mon coté, j'utilise un programme perso comme moniteur série et j'ai souvent un problème de lignes coupées n'importe comment. Par contre, il ne manque rien.

En shell, j'ai jamais essayé, je ne sais donc pas s'il y a des choses à faire notamment dans la tonne de paramètres de la commande stty.
Peut-être que le canal est "non bloquant" contrairement à ce que je pensais et que du coup il y a des valeurs de perdues entre deux appels

si tu fais juste un tail -f /dev/ttyACM0, est-ce que tout s'affiche correctement ?

La tonne de paramètre vient du site d'arduino (Je trouve plus le lien :/), j'avais fait un copier/coller, et si je me souviens bien, la commande servait à "initialiser" le port série... De toute façon, même sans cette ligne, j'ai exactement les même retours...

Sinon avec "tail -f /dev/ttyACM0", aucun retour... Le curseur reste sagement là où il est... :confused:

Je viens de faire quelques tests et googlé quelques bricoles pour comprendre
En fait, le tty est pas bloquant du tout, donc c'est l'inverse : le read chope ce qui passe à ce moment là, un peu au hasard

Du coup après un "stty -F /dev/tyACM0 min 10 time 20" (c'est à dire "s'arréter après 10 caractères, et attendre 2s max) ça marche un peu mieux, mais on loupe quand même pas mal de morceaux.
Bref, j'ai pas l'impression que le shell soit idéal pour faire ça.

C'est quoi ton besoin initial ? est-ce que tu ne peux pas appeler un programme en C qui fait les read() qui vont bien et renvoie un résultat "en clair" au shell appelant ?

piif:
Je viens de faire quelques tests et googlé quelques bricoles pour comprendre
En fait, le tty est pas bloquant du tout, donc c'est l'inverse : le read chope ce qui passe à ce moment là, un peu au hasard

Du coup après un "stty -F /dev/tyACM0 min 10 time 20" (c'est à dire "s'arréter après 10 caractères, et attendre 2s max) ça marche un peu mieux, mais on loupe quand même pas mal de morceaux.
Bref, j'ai pas l'impression que le shell soit idéal pour faire ça.

C'est quoi ton besoin initial ? est-ce que tu ne peux pas appeler un programme en C qui fait les read() qui vont bien et renvoie un résultat "en clair" au shell appelant ?

J'ai édité le premier message, mon but y est maintenant :slight_smile:

Le programme en c, je le veux bien, j'en rêve...

"stty -F /dev/ttyACM0 min 10 time 20" ne marche pas non plus :confused: Ca n'affiche rien...

Bon... Moi je vais dodo, j’espère avoir une bonne surprise demain!! :wink:

En tout cas merci de t'investir dans la résolution de mon problème piif :slight_smile:

PS : C'est quoi ce programme perso dont tu m'a parlé? Je pourrais peut-être l'utiliser pour faire ce que je veux faire?

Bonne nuit :slight_smile:

SomeoneInYourMind:
J'ai édité le premier message, mon but y est maintenant :slight_smile:

Donc en effet, je pense qu'un petit programme qui ne fasse que lire ce qui vient de l'arduino, et le renvoie sur la sortie standard, sans les trucs louches, ça serait pas mal.

Par contre, de mémoire, il me semble avoir essayé en C sans succès. Mais en Java y'a moyen : c'est ce que je fais dans ArdDude (le programme perso dont je parlais tout à l'heure)

Y'a moyen d'en faire une version light "juste" pour dumper le contenu de ce qui entre.

Ça serait l'occasion pour moi d'y remettre les mains car il y a des trucs qui déconnent dedans, par contre, je pourrai pas m'y mettre à très court terme.
Si tu connais java, n'hésites pas à forker le projet

À+

Si tu détaillais un peu plus ton besoin final ce serait plus simple pour t'aider.
Si c'est juste pour faire un fichier de log, tu peux aussi utiliser la fonction de capture de minicom qui fonctionne très bien avec l'arduino. Cela te permet de visualiser et en même temps capturer la ligne série dans une fenêtre terminal.
Autrement, si c'est pour exploiter des messages et les interpréter, tu peux aussi utiliser Python. il y a de nombreux exemples sur le net:
http://playground.arduino.cc/Interfacing/Python

http://www.isn.cligniez.fr/ressources/arduino-python.pdf

Eh bien MERCI BEAUCOUP a piif et fdufnews, j'ai fini par faire un script python que voici :

import serial

ser = serial.Serial()

ser.baudrate = 9600
ser.port = '/dev/ttyACM0'
ser.open()

while 1:
    line = ser.readline()
    print(line == b"Resetting the crossin' chrono\r\n")
    if line == b"Resetting the crossin' chrono\r\n":
        print("Reset!! ------- WORKS!!!!!!!!!!!!!!!!!")

Et qui marche! Il ne me reste plus qu'a chercher comment exécuter une commande bash en python ou comment écrire dans un fichier en python pour utiliser ce fichier en bash, mais Google saura me dire comment faire :slight_smile:

Encore merci a piif et fdufnews :wink:

Cool !
J'avais pas osé proposer du python, car je connais beaucoup moins que C ou Java, mais c'est sur que ça permet ce genre de chose.