Quand un programme refuse de compiler ou de se téléverser, l’IDE affiche un message d’erreur. Au premier regard il paraît cryptique, mais il suit une logique : il indique le fichier, la ligne, et la nature du problème. Apprendre à le lire, c’est gagner son autonomie — se dépanner seul plutôt que rester bloqué, ou recopier l’erreur dans un moteur de recherche sans la comprendre. La grande majorité des erreurs d’un débutant se ramène à quatre ou cinq types récurrents.

Note

Quelle carte ? Les messages cités ici sont ceux de la chaîne de compilation Arduino AVR (Uno, Mega, Nano) telle qu’affichée par l’IDE 2.x. Sur ESP32 ou Teensy, les messages d’erreur du langage sont très proches (même compilateur de la famille GCC), mais ceux liés au téléversement diffèrent. Le réflexe de lecture, lui, est le même partout.

À quoi ça sert ?

Bloquer sur une erreur fait perdre un temps fou quand on ne sait pas la lire, et en débloquer une, c’est presque toujours la même poignée de causes. Savoir où regarder (le numéro de ligne), par quoi commencer (la première erreur, pas la dernière) et à quoi correspondent les messages courants transforme un mur en simple checklist.

Compilation ou téléversement : deux familles

On l’a vu dans comment s’exécute un programme : compiler et téléverser sont deux étapes distinctes, donc deux familles d’erreurs.

  • Erreur de compilation : la traduction du code en binaire échoue. C’est un problème de code (syntaxe, nom, type). Le message vient du compilateur.
  • Erreur de téléversement : le code a compilé, mais l’envoi à la carte échoue. C’est un problème de liaison (port, câble, carte). Le message vient de l’outil d’envoi (avrdude sur AVR).

Savoir à quelle famille on a affaire oriente déjà le dépannage : relire le code, ou vérifier le branchement.

Anatomie d’un message de compilation

Un message d’erreur de compilation a une forme régulière :

sketch.ino: In function 'void loop()':
sketch.ino:7:16: error: 'led' was not declared in this scope
    7 |   digitalWrite(led, HIGH);
      |                ^~~

On y lit, dans l’ordre : le fichier et la fonction concernés (loop()), puis fichier:ligne:colonne (ici ligne 7, colonne 16), le mot error:, la description, et la ligne de code fautive recopiée avec son numéro dans une gouttière. Le ^ désigne le mot exact qui pose problème, ici led et non l’appel de fonction. Deux réflexes :

  • commencer par la PREMIÈRE erreur. Une faute en entraîne souvent d’autres en cascade. Corrigez la première, recompilez, et les suivantes disparaissent fréquemment ;
  • aller voir la ligne indiquée — en gardant en tête que certaines erreurs (comme un ; manquant) sont signalées sur la ligne suivante.

Tip

Ne recopiez pas le message à la main. Quand la compilation échoue, l’IDE 2.x affiche une notification en bas à droite avec un bouton COPY ERROR MESSAGES : un clic met tout le message dans le presse-papier, prêt à coller dans un moteur de recherche ou dans une question à un camarade.

Au passage, remarquez que le même message apparaît trois fois — détaillé dans le panneau Output, résumé sur sa dernière ligne, et repris dans la notification. C’est une seule erreur, pas trois.

Panneau Output de l'IDE Arduino 2.x en bas de la fenêtre, affichant en rouge une erreur de compilation détaillée sur plusieurs lignes, et en bas à droite une notification portant un bouton COPY ERROR MESSAGES.|640

Les erreurs de compilation les plus fréquentes

expected ';' before .... Un point-virgule manque, presque toujours à la ligne précédant celle indiquée.

'xxx' was not declared in this scope. Un nom (variable, fonction) est utilisé sans avoir été déclaré : faute de frappe, #include oublié, variable déclarée plus bas, ou variable locale utilisée hors de sa portée (voir variables locales et globales).

fatal error: xxx.h: No such file or directory. Un fichier d’en-tête est introuvable : bibliothèque non installée, nom mal orthographié, ou dépendance manquante d’une bibliothèque installée (voir utiliser une bibliothèque). Le mot fatal signifie que la compilation s’arrête immédiatement : contrairement aux autres, cette erreur ne vient jamais en cascade. Elle est seule, et c’est la seule à traiter.

expected '}' at end of input. Une accolade ouvrante n’a jamais été fermée. Vérifier l’équilibre des { } (l’auto-indentation de l’IDE, Ctrl+T, aide à les repérer).

redefinition of 'xxx'. La même variable est déclarée deux fois dans la même portée.

invalid conversion from ... to .... Un type incompatible est passé là où un autre est attendu (voir le typage des variables).

Tip

Warning ≠ error. Le compilateur distingue les avertissements (warning:) des erreurs (error:). Un warning signale quelque chose de suspect mais n’empêche pas de compiler et téléverser (ex. une variable déclarée mais jamais utilisée). Une error bloque. Ne pas confondre les deux : on peut ignorer un warning le temps d’avancer, jamais une error.

Les erreurs de téléversement fréquentes

avrdude: stk500_recv(): programmer is not responding. La carte n’a pas répondu : mauvais port sélectionné, câble charge only, ou carte non reconnue. Voir le dépannage de la prise en main.

Port occupé / verrouillé. Une autre application (un moniteur série resté ouvert ailleurs, PlatformIO) tient le port : fermer l’autre fenêtre et retenter.

Messages à décoder

Plutôt qu’un sketch à lire, voici trois erreurs réelles à diagnostiquer — le code, le message tel que l’IDE l’affiche, la lecture.

Cas 1 — le point-virgule oublié. Le code :

void setup() {
  pinMode(2, OUTPUT);
}
 
void loop() {
  digitalWrite(2, HIGH)
  delay(1000);
  digitalWrite(2, LOW);
  delay(1000);
}

Le message :

Blink.ino: In function 'void loop()':
Blink.ino:6:24: error: expected ';' before 'delay'
    6 |   digitalWrite(2, HIGH)
      |                        ^
      |                        ;
    7 |   delay(1000);
      |   ~~~~~
exit status 1

Compilation error: expected ';' before 'delay'

Lecture : l’erreur est signalée ligne 6, colonne 24, et la colonne 24, c’est le caractère qui suit immédiatement la parenthèse fermante. Le compilateur désigne le vide, là où il attendait quelque chose. Il va même jusqu’à dessiner le ; manquant sur la ligne du dessous. Le ~~~~~ sous delay désigne le mot qui l’a fait trébucher : il a lu digitalWrite(2, HIGH) puis delay, sans le séparateur entre les deux. C’est le piège classique du point-virgule : la faute est à la fin de la ligne précédente, même quand le message désigne la suivante.

Cas 2 — la variable hors de sa portée. Le code :

void setup() {
int my_age = 18;
Serial.begin(115200);
 
}
void loop() {
Serial.print(my_age);
}

Le message :

Blink.ino: In function 'void loop()':
Blink.ino:7:14: error: 'my_age' was not declared in this scope
    7 | Serial.print(my_age);
      |              ^~~~~~
exit status 1

Compilation error: 'my_age' was not declared in this scope

Lecture : my_age existe, il est déclaré ligne 2, et pourtant le compilateur dit qu’il n’existe pas. C’est le piège : il est déclaré à l’intérieur de setup(), donc il naît et meurt avec elle. Arrivé dans loop(), le compilateur ne le connaît plus. Le message ne ment pas : dans cette portée, le nom n’est pas déclaré. Correction : sortir int my_age = 18; des accolades, au-dessus de setup(), pour en faire une variable globale (voir variables locales et globales).

C’est l’erreur à la lecture la plus trompeuse du lot, parce que la variable est sous vos yeux dans le fichier. Le réflexe : ne pas chercher si le nom existe, mais dans quel bloc il a été écrit.

Cas 3 — l’erreur qui n’est pas dans votre fichier. Le code :

#include <Adafruit_BMP280.h>
void setup() {}
void loop() {}

Le message :

In file included from Blink.ino:1:
...\libraries\Adafruit_BMP280_Library/Adafruit_BMP280.h:26:10: fatal error: Adafruit_Sensor.h: No such file or directory
   26 | #include <Adafruit_Sensor.h>
      |          ^~~~~~~~~~~~~~~~~~~
compilation terminated.

Lecture : trois lignes de code, et le message désigne une ligne 26 qui n’existe pas chez vous. Le In file included from est la clé. Il déroule la chaîne : votre sketch inclut Adafruit_BMP280.h, qui à sa ligne 26 inclut Adafruit_Sensor.h, introuvable. La bibliothèque a bien été installée, mais pas sa dépendance (voir utiliser une bibliothèque). Rien à corriger dans le sketch : il faut réinstaller la bibliothèque en acceptant Install all.

La leçon dépasse ce cas : le fichier nommé par une erreur n’est pas forcément le vôtre. Avant de chercher une faute dans votre code, lisez le chemin.

Pièges

Se jeter sur la dernière erreur. Quand la liste est longue, c’est la première qu’il faut lire : les suivantes en découlent souvent et s’évaporent une fois la première corrigée.

Corriger au hasard. Modifier sans avoir lu le message ni la ligne mène à empiler de nouvelles fautes. Lire d’abord, comprendre, puis corriger.

Ignorer le numéro de ligne. Le message dit où : fichier:ligne. C’est l’information la plus utile, à condition de se rappeler que le ; manquant pointe la ligne d’après.

Confondre warning et error. Voir l’encart : un warning n’empêche pas de téléverser, une error si.

Exercices

Exercice 1 — Où est la faute ?

Le compilateur affiche sketch.ino:3:3: error: expected ';' before 'delay'. Voici le code. Quelle ligne corriger, et comment ?

void loop() {
  int etat = digitalRead(2)
  delay(10);
  digitalWrite(13, etat);
}

Exercice 2 — Le nom inconnu

Message : error: 'tempo' was not declared in this scope. Donnez trois causes possibles et la correction de chacune.

Raccrochage projet

  • Étape 4 de la phase de preuve de concept — au premier sketch un peu long, les erreurs de compilation sont inévitables. Savoir les lire est ce qui fait la différence entre avancer seul et rester bloqué.
  • Phase d’intégration et tests — quand les sous-ensembles s’assemblent, les erreurs se multiplient. Une lecture méthodique des messages fait gagner un temps considérable.

Voir aussi