Le moniteur série et la mise au point
Ce que ce chapitre apporte 5 points
- Envoyer au moniteur série des valeurs lisibles, avec leur nom et leur unité.
- Présenter des mesures sous une forme que le traceur série transforme en courbes.
- Recevoir une commande envoyée depuis l'ordinateur.
- Calculer ce que coûte un affichage, et l'empêcher de fausser le rythme du programme.
- Mettre au point un programme en affichant l'état au bon endroit.
Une carte Arduino n'a ni écran ni débogueur pas à pas. Pour savoir ce que fait réellement un programme, il ne reste qu'un fil : la liaison série, qui envoie du texte à l'ordinateur et peut en recevoir. La démarche, elle, est la même que sur un ordinateur, et le chapitre Déboguer plutôt que deviner la décrit avec les outils qui manquent ici : formuler une hypothèse, choisir la valeur qui la tranche, l'observer à l'endroit exact où elle compte. Bien employée, elle suffit à trouver la plupart des défauts. Mal employée, elle en crée, parce que chaque message prend du temps et change le rythme du programme qu'on observe. Le chapitre contient aussi un aide-mémoire des fonctions de base, à garder ouvert pendant les montages.
Écrire lisiblement
Un nombre seul dans le moniteur ne dit rien : 27 peut être une température, un compteur ou une broche. Une ligne utile porte le nom de la valeur et son unité.
Ce chapitre passe de 9 600 à 115 200 bauds, pour une raison donnée plus bas, dans la section sur le coût d'un affichage. Régler le moniteur série sur la même valeur avant de téléverser : un moniteur resté à 9 600 n'affiche que des caractères illisibles.
Serial.print(valeur, 1) fixe le nombre de décimales d'un nombre à virgule. println ajoute une fin de ligne, print non : une ligne se compose de plusieurs print et se termine par un println.
Le traceur série
L'environnement Arduino propose aussi un traceur série, qui dessine des courbes au lieu d'afficher du texte. Il attend une ligne par instant, chaque valeur précédée de son nom et de deux-points, les valeurs séparées par une virgule.
Voir une mesure franchir un seuil sur une courbe en dit plus long qu'une colonne de nombres : on y lit le bruit, les pics isolés, la vitesse de variation.
1.Quelle différence entre Serial.print et Serial.println ?
2.Quel format le traceur série attend-il pour dessiner deux courbes ?
Recevoir une commande
Le moniteur série permet aussi d'envoyer du texte vers la carte. Serial.available() rend le nombre d'octets reçus en attente, Serial.read() en lit un.
1 puis Entrée envoie '1' suivi d'un ou deux caractères de fin de ligne. Un programme qui traiterait chaque caractère reçu comme une commande réagirait deux ou trois fois. Ne réagir qu'aux caractères attendus, comme ci-dessus, règle la question.
Que rend Serial.available() ?
Ce que coûte un affichage
La liaison série transmet un caractère en dix bits. À 9 600 bauds, cela fait environ 960 caractères par seconde. Dans ce chapitre, la longueur d'une ligne compte toujours sa fin de ligne : println ajoute deux caractères, \r et \n. Une ligne de vingt caractères, ces deux-là compris, met donc près de 21 ms à partir.
Tant que les messages sont rares, ce délai passe inaperçu : Serial.print range les caractères dans une mémoire d'envoi de 64 octets sur l'Uno et rend la main aussitôt, pendant que la liaison les transmet. Placé à chaque tour de loop(), il limite le programme à une cinquantaine de tours par seconde, dès que cette mémoire est pleine, ce qu'un peu plus de trois lignes de vingt caractères suffisent à faire, et que Serial.print attend qu'elle se vide. Un anti-rebond, un clignotement réglé avec millis() changent alors de comportement, et ce changement n'existe que tant que la trace est active.
1.À 9600 bauds, combien de caractères passent environ par seconde ?
2.Pourquoi une trace placée à chaque tour de loop() peut-elle changer le comportement d'un programme ?
Mettre au point
Afficher au hasard produit beaucoup de texte et peu d'information. La démarche efficace est celle d'une enquête.
- Formuler une hypothèse précise : « le compteur est remis à zéro », « le bouton n'est jamais lu comme enfoncé ».
- Choisir la valeur qui confirme ou infirme cette hypothèse, et l'afficher à l'endroit exact où elle compte : juste avant le test, juste après l'affectation.
- Afficher le temps avec la valeur,
millis(), quand le défaut dépend du rythme. - Lire, conclure, retirer la trace, ou la couper par une constante, avant de passer à l'hypothèse suivante.
setup(), compteurs et horodatages à zéro. Une trace qui semble recommencer ne signale donc pas forcément un défaut.Chaque texte entre guillemets d'un
Serial.print occupe aussi de la mémoire vive, dont l'Uno n'a que 2 Ko. Écrire Serial.print(F("temperature = ")) laisse ce texte dans la mémoire du programme et épargne la mémoire vive.
int, qui plafonne à 32 767, au lieu de unsigned long.Le saut vers une valeur négative n'est pas un hasard : dépassé, l'entier repart de sa plus petite valeur, parce que le bit qui porte le signe se retrouve allumé. Le chapitre Les types et leur taille du parcours C montre ce mécanisme sur un entier de 4 octets, et c'est exactement le même sur les 2 octets de l'Uno, avec une limite soixante-cinq mille fois plus proche.
Aide-mémoire
| Structure et temps | Rôle |
|---|---|
setup() | exécutée une fois au démarrage |
loop() | exécutée indéfiniment |
delay(ms) | suspend tout le programme |
millis() | millisecondes depuis le démarrage, en unsigned long |
millis() - derniere >= intervalle | test d'intervalle, juste au retour à zéro |
| Broches | Rôle |
|---|---|
pinMode(b, OUTPUT) | broche en sortie |
pinMode(b, INPUT_PULLUP) | entrée avec tirage interne : enfoncé se lit LOW |
digitalWrite(b, HIGH) / LOW | impose 5 V ou 0 V |
digitalRead(b) | rend HIGH ou LOW |
analogRead(A0) | rend de 0 à 1023 pour 0 à 5 V |
analogWrite(b, v) | PWM de 0 à 255, broches 3, 5, 6, 9, 10, 11 |
| Calculs utiles | Formule |
|---|---|
| Lecture vers tension | tension = lecture × 5 / 1023 |
| PWM vers tension moyenne | tension = 5 × valeur / 255 |
| Changement d'échelle | map(x, 0, 1023, 0, 255), calcul entier, non borné |
| Borner | constrain(x, min, max) |
| Résistance d'une LED | R = (5 − tension de la LED) / courant |
| Types | Taille | Plage |
|---|---|---|
bool | 1 octet | true, false |
byte | 1 octet | 0 à 255 |
int | 2 octets | -32 768 à 32 767 |
unsigned long | 4 octets | 0 à environ 4,3 milliards |
float | 4 octets | 6 à 7 chiffres significatifs |
| Liaison série | Rôle |
|---|---|
Serial.begin(115200) | ouvre la liaison, même débit dans le moniteur |
Serial.print(v) / println(v) | envoie, sans ou avec fin de ligne |
Serial.print(x, 2) | un nombre à virgule avec deux décimales |
Serial.available() | nombre d'octets reçus en attente |
Serial.read() | lit un octet reçu |
Mettre en pratique
Un programme exécute Serial.print("t="); Serial.print(millis()); Serial.print(" compteur="); Serial.println(compteur); à chaque tour de loop(), à 9600 bauds. Au bout d'une minute, millis() s'écrit en cinq chiffres et compteur en quatre. Combien de tours par seconde fait loop() au plus ?
La ligne compte 2 + 5 + 10 + 4 = 21 caractères, plus les deux de fin de ligne ajoutés par println : 23 caractères, soit 230 bits. À 9 600 bauds : ms par ligne. loop() est limitée à environ 42 tours par seconde, une fois la mémoire d'envoi remplie.
Passer à 115 200 bauds ramène la ligne à 2 ms environ. Mieux encore : n'afficher qu'à intervalle régulier, avec millis().
La commande '1' allume bien la LED, mais le moniteur affiche aussi une réponse pour chaque touche Entrée. Le programme écrit else Serial.println("commande inconnue"). Pourquoi ?
Entrée envoie un ou deux caractères de fin de ligne, '\n' et parfois '\r'. Chacun est lu par Serial.read(), ne correspond ni à '1' ni à '0', et déclenche le message.
Deux corrections : régler le moniteur pour qu'il n'envoie pas de fin de ligne, ou, plus robuste, ignorer silencieusement les caractères '\n' et '\r' avant de signaler une commande inconnue.
Un clignotement réglé avec millis() fonctionne. Une trace ajoutée à chaque tour, à 9600 bauds, le rend irrégulier. Que se passe-t-il ?
Chaque ligne bloque le programme une vingtaine de millisecondes pendant l'envoi. Le test d'intervalle n'est plus évalué qu'une quarantaine de fois par seconde : un basculement prévu à 500 ms peut n'être vu qu'à 520 ms, et l'écart varie d'un cycle à l'autre.
La trace a modifié le rythme de ce qu'elle observe. On l'espace dans le temps, on augmente le débit, ou on la coupe par une constante une fois l'information obtenue.
Chapitre révisé en octobre 2026 · Une erreur dans ce chapitre ?
Dans la bibliothèque d'exercices
Ce qu'une ligne affichée coûte en temps, et ce qu'une trace bien posée révèle.
- Ce que le moniteur affiche vraimentNiveau 2
- Le prix d'une ligne affichéeNiveau 3
- La trace qui retombeNiveau 3