Yahoo refuse tous les emails du site. Si vous avez une adresse chez un autre prestataire, c'est le moment de l'utiliser ;)

En cas de soucis, n'hésitez pas à aller faire un tour sur la page de contact en bas de page.

Le traceur série Arduino sur le banc de test

Les vrais logiciels de développement ont des courbes

Image d'entête

par skywodd | | Licence (voir pied de page)

Catégories : Tutoriels Arduino Dossiers | Mots clefs : Arduino Genuino Série Serial Plotter Traceur

Cet article n'a pas été mis à jour depuis un certain temps, son contenu n'est peut être plus d'actualité.


Dans ce tutoriel / dossier, je vous propose de parler du traceur série inclus dans les récentes versions du logiciel de développement Arduino. Dans cet article, nous étudierons son fonctionnement, ses avantages et ses limites.

Sommaire

Bonjour à toutes et à tous !

Dans un des tous premiers articles du site, qui présenté la conversion analogique / numérique avec une carte Arduino / Genuino, je vous avais parlé en bonus d'une fonctionnalité toute récente, incluse dans les dernières versions du logiciel de développement Arduino : le traceur série.

J'avais à l'époque ajouté en remarque qu'aucune documentation n'existait sur le sujet et qu'il s'agissait d'une fonctionnalité expérimentale.

Après maintenant plusieurs mois d'utilisation de la dernière version du logiciel de développement Arduino, je pense qu'il est grand temps de faire le point sur cette petite nouveauté et de gratter la surface pour voir ce qu'il se cache réellement en dessous.

Je suis donc parti en éclaireur, fouillant dans le code source du logiciel Arduino pour trouver le code en charge de la partie correspondant au traceur série. Après moult recherches et cul-de-sac, j'ai fini par trouver ce que je cherchais et la lecture du code source m'a révélé pas mal de choses intéressantes dont je vais vous parler aujourd'hui.

La version du code étudiée dans le cadre de cet article date du 8 janvier 2016, soit un peu plus de trois mois. Au moment où j'écris ces lignes, il s'agit de la version la plus récente disponible sur le github du projet Arduino.

Thèse

Capture d'écran du traceur série pour l'exemple AnalogReadSerial

Capture d'écran du traceur série

Le but du traceur série est simple : afficher sous forme de graphique une série de valeurs numériques reçues par le port série du PC.

En développement Arduino, il est très classique d'envoyer des valeurs sur le port série pour les afficher ensuite dans le moniteur série côté PC. Cependant, un simple affichage texte manque souvent de lisibilité. C'est pourquoi les développeurs du projet Arduino ont eu la bonne idée d'intégrer dans le logiciel Arduino un traceur série; permettant d'afficher ces même données sous une forme de courbes graphiques, bien plus lisible.

On dit souvent qu'une image vaut mieux qu'une centaine de mots. Dans le cas d'une série de valeurs numériques, c'est encore plus vrai. Cette fonctionnalité est donc très intéressante. Cependant, on dit aussi qu'un mauvais graphique est pire que de ne pas avoir de graphique du tout.

Utilisation

Le traceur série est extrêmement simple à utiliser.

Il suffit dans le code, d'envoyer sur le port série une série de valeurs numériques (nombres entiers ou à virgule) séparées par des espaces, des tabulations ou des virgules et se terminant par un retour chariot ("\n").

Exemple :

1
2
1, 2, 3, 4
1, 2, 3, 4

Chaque nouvelle ligne déclenche la création d'une nouvelle série de points sur le graphique. Une ligne = une série de points et une valeur = une courbe, on ne peut pas faire plus simple.

N.B. Le format standard en informatique avec un point virgule comme séparateur n'est pas supporté. De plus, le traceur série ne gère que des nombres entiers ou à virgule, positifs ou négatifs.

Voici un exemple de code utilisable avec le traceur série, celui-ci affiche quatre courbes en fonction des 4 entrées analogiques A0, A1, A2 et A3 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print(analogRead(A0));
  Serial.print(", ");
  Serial.print(analogRead(A1));
  Serial.print(", ");
  Serial.print(analogRead(A2));
  Serial.print(", ");
  Serial.print(analogRead(A3));
  Serial.println();

  delay(100);
}

L'extrait de code ci-dessus est disponible en téléchargement sur cette page (le lien de téléchargement en .zip contient le projet Arduino prêt à l'emploi).

Antithèse

Capture d'écran du traceur série du logiciel Arduino avec 8 voies

Capture d'écran du traceur série du logiciel Arduino avec 8 voies

Le premier problème, celui qui saute aux yeux, c'est le manque flagrant de fonctionnalités basiques.

Pas de texte de légende, pas de curseur pour naviguer dans les courbes, pas d'export en format image ou tableur. Rien, nada, niet.

Même le plus ancien des oscilloscopes analogiques était fourni avec une grille pour lire les valeurs des courbes sur l'écran. Ici, il manque clairement des graduations, un curseur ou même une simple grille de mesure !

Tracer des graphiques pour le plaisir de tracer des graphiques n'a aucun intérêt. Un simple curseur avec deux traits en croix serait un bon début. Avoir ensuite un affichage avec une petite infobulle contenant le numéro du point de données et la valeur associée serait encore mieux.

Quand je regarde la capture d'écran ci-dessus, même en sachant d'où provient la mesure, je suis bien incapable d'en tirer la moindre information utile. La courbe A monte, la courbe B descend, de combien ? Impossible à dire, il n'y a pas vraiment d'échelle et aucun curseur ou graduation (deux valeurs sur un axe n'est pas une graduation).

Le second problème provient d'un choix graphique peu judicieux.

1
2
3
4
5
6
7
8
# GUI - PLOTTING
plotting.bgcolor = #ffffff
plotting.color = #ffffff
plotting.graphcolor.size = 4
plotting.graphcolor.00 = #2c7bb6
plotting.graphcolor.01 = #fdae61
plotting.graphcolor.02 = #d7191c
plotting.graphcolor.03 = #abd9e9

L'apparence du logiciel Arduino est contrôlée par un simple fichier texte nommé "theme.txt". Dans ce fichier, on retrouve toutes les constantes utilisées par le logiciel pour l'affichage, dont la liste des couleurs utilisables pour les courbes du traceur série.

Cette liste se résume par défaut à seulement quatre couleurs, celle de la charte graphique du site Arduino. Nul doute qu'un graphiste a eu son mot à dire sur le sujet.

Capture d'écran du traceur série du logiciel Arduino avec 16 voies

Capture d'écran du traceur série du logiciel Arduino avec 16 voies

Malheureusement, cela signifie qu'il n'est possible d'afficher que 4 courbes avec des couleurs différentes, les courbes supplémentaires se retrouvent ensuite dans une même couleur. Sans légende et avec des couleurs en double, triple ou plus, le graphique ne veut plus rien dire. Regardez la capture ci-dessus, comment suis-je censé savoir à quelle courbe correspond quelle valeur !? C'est impossible !

Si c'était le seul problème, cela serait vite réglé. Il suffirait d'ajouter une dizaine de couleurs dans le fichier texte (la taille de la liste est modifiable). Malheureusement, ce petit souci est une goutte d'eau dans une mer de problèmes.

1
private final static int BUFFER_CAPACITY = 500; 

La ligne ci-dessus est un extrait du code source qui gère l'affichage des courbes. Cette ligne définit le nombre de points que chaque courbe peut stocker.

En interne, le stockage des points de mesure des courbes est réalisé au moyen d'une mémoire tampon FIFO, aussi appelée "liste glissante". Quand la taille spécifiée (ici 500 points) est atteinte, chaque nouveau point de mesure supprime un ancien point en début de liste. L'affichage est donc "glissant", vers la gauche.

Cela signifie qu'à tout instant, seuls 500 points de mesure par courbe peuvent être affiché. Si le but est d'afficher un signal lent, comme la décharge d'une batterie, il faudra bien prendre en compte cette petite particularité, sous peine de perdre son temps et ses données de mesure.

Ce nombre de points de mesure affichable est codé en dure dans le logiciel, impossible donc de le modifier, pas même en passant par le fichier de configuration de l'affichage. Grrrrrrr.

1
Ticks ticks = new Ticks(minY, maxY, 3); 

De même, le nombre de graduations sur l'axe vertical est codé en dure dans le logiciel. Et ce nombre est limité à seulement trois graduations ! Cela signifie qu'avec un nombre positif puis négatif, vous aurez les deux extrêmes et le zéro …

J'en arrive ensuite au plus croustillant, amis développeurs Java, accrochez-vous à vos sièges, vous êtes sur le point de découvrir l'implémentation la plus naïve possible d'un parseur CSV) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public void message(final String s) {
    messageBuffer.append(s);
    while (true) {
      int linebreak = messageBuffer.indexOf("\n");
      if (linebreak == -1) {
        break;
      }

      String line = messageBuffer.substring(0, linebreak);
      messageBuffer.delete(0, linebreak + 1);

      line = line.trim();
      String[] parts = line.split("[, \t]+");
      if(parts.length == 0) {
        continue;
      }

      int validParts = 0;
      for(int i = 0; i < parts.length; ++i) {
        try {          
          double value = Double.valueOf(parts[i]);
          if(i >= graphs.size()) {
            graphs.add(new Graph(validParts));
          }
          graphs.get(validParts).buffer.add(value);
          validParts++;
        } catch (NumberFormatException e) {
          // ignore
        }
      }
    }

    SwingUtilities.invokeLater(SerialPlotter.this::repaint);
  }

PS : Mention spéciale pour la magnifique boucle infinie en milieu de code et le // ignore au niveau de la gestion des erreurs qui se retrouvent du coup absolument partout dans le reste du code, copier-coller oblige.

Je cherche toujours à comprendre ce qui a bien pu passer par la tête des développeurs de l'équipe Arduino. Pourquoi réinventer la roue et faire leur propre code de gestion des fins de lignes (qui au passage ne supporte que les retours chariot au format UNIX "\n") ? Pourquoi utiliser une expression régulière aussi bête qu'erronée pour séparer les valeurs ?

Quand on a besoin de manipuler des données au format CSV, la pire chose à faire est de tenter d'écrire son propre système de traitement "simpliste". Le format CSV est trivial en apparence, mais complexe en réalité, les développeurs Arduino n'ont manifestement pas compris cela.

Les lignes de textes sont découpées en morceaux au moyen de l'expression régulière suivante : [, \t]+. En français, celle-ci veut dire : (découpe sur) n'importe quelle série d’un ou plus caractères de la liste suivante : virgule, espace, tabulation.

Vous voyez où est le problème ?

Un indice : "un ou plus caractères de la liste suivante : virgule, …"

A vouloir faire trop simple, on fait souvent des bêtises. Ainsi, aux yeux du traceur série, toutes ces lignes contiennent seulement trois valeurs :

1
2
3
4
5
6
1 2 3
1        2        3 
1,2,3
1,,,,,2,,,,,3
1, 2, 3
1, , , , , 2, , , , , 3 

En partiel d'informatique, cela aurait donné lieu à un magnifique zéro sur la copie de l'élève. De plus, à cause de cette façon naïve de traiter les lignes de texte, il est impossible de faire des courbes discontinues avec des points manquants.

A ce stade j'ai envie de hurler : "Y a-t-il un développeur dans l'assistance !?".

N.B. Je tiens quand même à rappeler que le projet Arduino n'est pas un simple projet Open source géré par des bénévoles. C'est une véritable "machine à sous" contrôlée par l'entreprise Arduino qui génère une belle quantité d'argent par an et dispose d'un nombre conséquent d'employés et de développeurs.

PS : Tout le logiciel Arduino est codé de la même façon, c'est un véritable massacre. Il y a quelques années, je participais activement au debug du logiciel Arduino, mais à force de voir mes tickets de bugs rester sans suite j'ai abandonné. C'est bête à dire, surtout de la part de quelqu'un qui travaille principalement avec l'environnement Arduino, mais l'équipe Arduino s'intéresse de plus en plus à votre portefeuille qu'à vous et à vos besoins.

Malaise

Des graphiques sans légendes, aucun moyen de faire une mesure propre, seulement 4 couleurs de courbes par défaut, un affichage glissant de taille fixe, aucun moyen d'export et des bugs à la pelle, voila qui n'est pas très glorieux …

On pourrait se dire "c'est une version de test, ça va s'améliorer", mais j'ai bien peur que cela se termine comme avec le moniteur série : comme un simple gadget vaguement utile, mais trop simpliste pour être un véritable outil.

Que l'on me comprenne bien, le moniteur série est utile, mais il manque cruellement de fonctionnalités. Il n'est pas possible d'avoir un affichage hexadécimal, octal ou mixte (hexadécimal + texte). Il ne supporte pas le standard VT100 qui permettrait de faire des interfaces textuelles. Il n'est même pas possible de changer le mode de communication du port série, juste sa vitesse !

Quand on met en parallèle l'état actuel du traceur série et celui du moniteur série, on se rend compte que les deux vont dans la même direction : la sur-simplicité à l'excès.

J'entends déjà venir les commentaires du style "oui, mais si tu as besoin de tout ça tu n'as qu'à utiliser un vrai terminal série !". Certes, je pourrais passer par un émulateur de terminal complet, de la même façon que je pourrai passer par un logiciel de "plotting" (traçage) série indépendante. Seulement, pourquoi inclure un outil dans un logiciel si celui si n'est pas réellement utilisable. C'est une pure perte de temps pour les développeurs du projet Arduino dans ce cas.

Tout n'est pas perdu cependant, les choses évoluent, le code aussi, les prochaines versions seront peut être meilleures, ou pas, wait and see comme on dit.

Conclusion

Ce tutoriel / dossier est désormais terminé.

Si ce tutoriel / dossier vous a plu, n'hésitez pas à le commenter sur le forum, à le diffuser sur les réseaux sociaux et à soutenir le site si cela vous fait plaisir.