VSCode et PlatformIO : port série

Lire et tracer les données du port série avec PlatformIO et TelePlot

VSCode et PlatformIO : port série

Utiliser le moniteur série de PlatformIO puis l'extension TelePlot pour visualiser en temps réel des courbes de données envoyées via le port série.

Durée :
Difficulté :
Documentation réalisée à 90% 90
Créée par :  Alban Petit

Introduction

Présentation

La majorité des cartes de développement pour microcontrôleur actuelles sont capables de communiquer en série via l’USB (c’est le cas de l’Arduino Uno et de la XIAO ESP32S3). Il est donc possible de recevoir et d’envoyer des instructions via ce port et de les afficher sur un terminal de l’ordinateur hôte.

Pour ce faire, nous allons établir une communication série entre le µC et le PC.

La liaison série permet une communication point-à-point grâce à deux voies :

  • TX (transmission) : la voie qui transmet le message à son interlocuteur ;
  • RX (réception) : la voie qui reçoit les messages de l’interlocuteur.

Les voies sont associées à des broches précises du µC (sur la XIAO ESP32S3, l’UART matériel est sur D6 pour TX et D7 pour RX ; ces broches sont libres sur breadboard, mais pas sur la carte de la console de l’atelier Microcontrôleurs, où elles servent au bouton SW2 et à l’écran) : pour relier deux cartes, il ne faut pas oublier de croiser les fils de communication, comme dans cet exemple :

schema

  Sur la XIAO ESP32S3

La XIAO n’a pas de puce USB-série : Serial passe directement par l’USB natif de l’ESP32-S3, et il n’y a aucun fil TX/RX à croiser. Conséquence : le port disparaît un instant à chaque reset ou upload, et les messages envoyés dans les toutes premières millisecondes de setup() peuvent être perdus. Voir la fiche XIAO ESP32S3.

Afin de communiquer, les deux périphériques doivent être synchronisés sur la même vitesse de transmission appelée bauds.

Si vous souhaitez en savoir plus sur la liaison série : La liaison série (Zeste de Savoir)

Premier exemple

Dans notre exemple, nous allons envoyer une trame (un sinus) et nous allons l’afficher sur le moniteur série.

Le code utilisé sera le suivant :

#include <Arduino.h>

float i = 0;

void setup()
{
  Serial.begin(115200);
  delay(1500);   // USB natif : laisse le temps au PC de rouvrir le port
}

void loop()
{
  i += 0.1;
  Serial.print("sin:");
  Serial.println(sin(i));
  delay(10);
}
  • Serial.begin(115200) : initialise une communication série à 115200 bauds
  • delay(1500) : sur la XIAO, le port série disparaît à chaque reset ; sans cette pause, les premiers messages de setup() partent avant que le PC ne l’ait rouvert, et sont perdus
  • Serial.print("sin:") : envoie sur le port série la chaîne de caractères "sin:"
  • Serial.println(sin(i)) : envoie sur le port série le résultat de l’opération sin(i) avec un retour à la ligne à la fin

En savoir plus sur l’utilisation du port série dans le framework Arduino : référence Arduino : Serial

Pour que le moniteur série puisse lire le port série, il faut donner à PlatformIO la vitesse de la communication avec la ligne monitor_speed = 115200 du fichier de configuration platformio.ini :

[env:seeed_xiao_esp32s3]
platform = espressif32
board = seeed_xiao_esp32s3
framework = arduino
monitor_speed = 115200

La configuration seeed_xiao_esp32s3 active déjà ARDUINO_USB_CDC_ON_BOOT=1 : c’est ce qui fait passer Serial par le connecteur USB-C, sans câble ni adaptateur supplémentaire.

Vous pouvez ensuite ouvrir le Serial Monitor dans la barre de menu en bas à gauche :

Le moniteur série s’ouvre et vous affiche l’ensemble des données transmises entre votre carte et votre ordinateur.

  Téléverser, puis écouter

Un téléversement ferme le moniteur série, puisque le port disparaît pendant le flashage. La commande Upload and Monitor du menu PlatformIO enchaîne les deux et rouvre le moniteur dès que la carte redémarre. Si la carte plante, ajoutez monitor_filters = esp32_exception_decoder au platformio.ini : voir Déboguer un programme embarqué.

Problème : les données sont transmises toutes les 10 ms. Elles sont donc difficiles à suivre et à interpréter dans le terminal série.

Nous allons donc voir par la suite comment améliorer la lecture du port série dans le cas d’un grand nombre de données et d’une fréquence d’envoi importante.

TelePlot

TelePlot est un outil d’affichage de courbes télémétriques développé par Alexandre Bremer. À l’origine, l’application affichait des données reçues en paquets UDP ; elle a été adaptée en extension VSCode pour afficher des données provenant d’un port série.

L’extension est encore en développement. Merci de reporter les bugs directement sur le repo GitHub lié au projet.

Installation

L’extension s’installe simplement via le gestionnaire d’extensions de VSCode.

Une fois l’installation réalisée, l’extension est accessible via le bouton du menu inférieur gauche .

Possibilités

L’extension s’intègre directement à l’interface de VSCode lors de son ouverture et s’utilise en tant qu’onglet. L’interface permet :

  • D’afficher plusieurs courbes séparément
  • D’afficher un moniteur série textuel contenant les données qui ne sont pas liées à des graphiques
  • D’afficher des statistiques sur les graphes
  • De choisir l’échelle d’affichage en X
  • De zoomer sur une courbe
  • D’exporter les données (au format JSON pour le moment)

Enfin, toutes les données sont horodatées, et un curseur affiche précisément les valeurs reçues à l’instant pointé.

Utilisation

Afin d’afficher des courbes dans TelePlot, il est nécessaire, comme pour l’Arduino IDE, de respecter un certain nombre de spécificités.

a. Moniteur textuel seul

Pour afficher une donnée dans le moniteur textuel, il suffit juste d’envoyer la donnée sur le port série comme sous Arduino.

void loop()
{
  i += 0.1;
  Serial.print("loop - i=");
  Serial.println(i);
  delay(10);
}

Dans ce cas, seul l’affichage textuel sera actif et les trames s’afficheront dans ce terminal.

b. Courbes seules

Pour afficher une courbe dans TelePlot, nous allons utiliser le caractère > juste avant le label de la courbe afin d’indiquer à l’outil que la prochaine valeur envoyée sera liée à un graphe du label correspondant. On terminera l’envoi de données par un retour chariot à l’aide de la fonction println() par exemple.

void loop()
{
  i += 0.1;

  Serial.print(">sin:");
  Serial.println(sin(i));

  Serial.print(">cos:");
  Serial.println(cos(i));

  delay(10);
}

Ici, les deux courbes sin et cos sont affichées et le terminal textuel est masqué.

c. Courbes et données

Il est également possible d’afficher les courbes et les données en même temps en combinant les deux codes précédents.

void loop()
{
  i += 0.1;

  Serial.print("loop - i=");
  Serial.println(i);

  Serial.print(">sin:");
  Serial.println(sin(i));

  Serial.print(">cos:");
  Serial.println(cos(i));

  delay(10);
}

d. Fonction d’aide

Sur ESP32, Serial.printf() formate toute une ligne en un seul appel, comme le printf du C. La fonction d’aide tient alors en une ligne :

void teleplot(const char* label, float value)
{
  Serial.printf(">%s:%.3f\n", label, value);
}

void loop()
{
  i += 0.1;
  teleplot("sin", sin(i));
  teleplot("cos", cos(i));
  delay(10);
}
  • const char* label : le nom de la courbe, par exemple "sin"
  • float value : la valeur à afficher
  • %s insère le texte, %.3f le nombre avec trois décimales, \n termine la ligne

Le label est un const char* plutôt qu’un String : un String réserve de la mémoire dans le tas à chaque appel, ce qui finit par le fragmenter sur un programme qui tourne longtemps.

Sources

Besoin d'aide ?