Aller au contenu
Académie JediSith · Programmation

Anatomie d'un programme

En une phrase : un programme Arduino a toujours deux parties, setup() qui s'exécute une fois au démarrage et loop() qui se répète à l'infini ; il range ses informations dans des variables et prend des décisions avec if.

Du texte à la carte : le voyage d'un programme

Ce que tu écris dans l'IDE est du texte, dans un langage appelé C++. L'ESP32, lui, ne comprend que des suites de 0 et de 1. Il y a donc trois étapes :

📝ton texteC++ dans l'IDE⚙️compiler ✓traduction en 0 et 1🔌téléverser →par le câble USB🧠mémoire flashde l'ESP32▶️exécutionau démarrage
Du texte que tu lis à la carte qui l'exécute.
Étape Bouton Ce qui se passe
1. Compiler ✓ Vérifier l'IDE traduit ton texte en langage machine, et signale les fautes
2. Téléverser → Téléverser le programme traduit part par le câble USB dans la mémoire flash de l'ESP32
3. Exécuter (automatique) la carte redémarre et lance ton programme

Le programme reste dans la carte

La mémoire flash ne s'efface pas quand on débranche. Rebranche la carte demain, sur n'importe quel chargeur USB : ton programme redémarre tout seul. Il n'est remplacé que par le prochain téléversement.

Le squelette

#define LED 2                  // un nom pour un nombre : plus lisible que « 2 »

void setup() {                 // UNE fois, au démarrage (ou après le bouton EN)
  pinMode(LED, OUTPUT);        // la broche 2 devient une sortie
  Serial.begin(115200);        // on ouvre la discussion avec l'ordinateur
}

void loop() {                  // puis ceci, encore et encore, pour toujours
  digitalWrite(LED, HIGH);     // allume
  delay(500);
  digitalWrite(LED, LOW);      // éteint
  delay(500);
}
Morceau Son rôle
// … un commentaire : ignoré par la carte, écrit pour les humains
setup() la préparation : régler les broches, démarrer la communication
loop() le cœur : ce qui se répète tant que la carte est allumée
pinMode(broche, OUTPUT) déclare une broche comme sortie (elle va envoyer 0 V ou 3,3 V)
digitalWrite(broche, HIGH / LOW) met la broche à 3,3 V ou à 0 V, voir le PWM
Serial.println("…") écrit une ligne dans le moniteur série : l'ESP32 te parle
{ … } les accolades regroupent les instructions d'un bloc
; termine chaque instruction, comme un point à la fin d'une phrase
▶démarragesetup()une seule foisloop()encore et encore↻ à l'infini, tant que la carte est alluméebouton EN ourebranchement :on recommence ici
Le chemin que suit l'ESP32 : setup() une fois, puis loop() en boucle.

Le moniteur série, ton meilleur allié

Un programme ne fait pas ce que tu veux ? Ajoute des Serial.println(...) aux endroits clés pour savoir où il passe et ce que valent les variables. C'est comme ça que travaillent tous les développeurs : on appelle ça déboguer.

Les variables : des boîtes avec un nom

Une variable est une boîte qui garde une valeur, et qu'on peut changer en cours de route.

100vitesseintfalseradarbool45210debutunsigned long3.3tensionfloatune étiquette (le nom), une forme de boîte (le type), un contenu (la valeur)
Chaque variable est une boîte : son nom sur l'étiquette, son type dit ce qu'on peut y ranger, et sa valeur peut changer.
int vitesse = 100;             // un nombre entier (négatif ou positif)
bool radar = false;            // vrai (true) ou faux (false)
unsigned long debut = 0;       // un très grand nombre positif (pour le temps)
float tension = 3.3;           // un nombre à virgule (avec un POINT en C++ !)
const int ZONE_MORTE = 100;    // « const » : une constante, qui ne changera jamais
Type Ce qu'il range Sur l'ESP32 Exemple de l'atelier
int un nombre entier de −2 147 483 648 à 2 147 483 647 la vitesse, un numéro de scénario
byte un petit entier positif de 0 à 255 une couleur
bool vrai ou faux true / false le radar activé ou non
unsigned long un grand nombre positif de 0 à environ 4,3 milliards les millisecondes de millis()
float un nombre à virgule environ 7 chiffres précis une tension, une moyenne

Modifier une variable

vitesse = 150;          // on remplace la valeur
vitesse = vitesse + 25; // on ajoute 25 à ce qu'il y avait
vitesse += 25;          // pareil, en plus court
compteur++;             // ajoute 1

Où vit une variable ?

  • Déclarée en haut du programme, hors de toute fonction : elle est globale, tout le programme la voit, et elle garde sa valeur d'un tour de loop() à l'autre.
  • Déclarée dans une fonction ou un bloc { } : elle est locale, elle n'existe que là, et elle est recréée à chaque passage.
le programme entierint compteur = 0;← globale : visible partout, garde sa valeurvoid loop() { … }int temp = 5;← locale : n'existe que dans loop(),recréée à chaque tour
Une variable vit dans la « pièce » où elle est déclarée : en haut du programme, tout le monde la voit ; dans loop(), elle disparaît à la fin du tour.

Le compteur qui reste à 1

Si tu écris int compteur = 0; à l'intérieur de loop(), il est remis à 0 à chaque tour : il ne dépassera jamais 1. Un compteur qui doit durer se déclare en haut, hors de loop().

Prendre des décisions : if

vitesse vaut 350vitesse > 300 ?oui« Trop vite ! »nonautre chosela suite du programme
Un if, c'est un carrefour : selon la réponse à la question, le programme prend un chemin ou l'autre, puis les deux chemins se rejoignent.
if (vitesse > 300) {
  Serial.println("Trop vite !");
} else if (vitesse == 0) {
  Serial.println("À l'arrêt");
} else {
  Serial.println("Vitesse normale");
}
Comparaison Se lit Exemple
== est égal à scenario == 3
!= est différent de manette != nullptr
< > plus petit, plus grand y < -400
<= >= plus petit ou égal, plus grand ou égal vitesse >= 25
&& et : les deux doivent être vrais manette && manette->isConnected()
|| ou : au moins un doit être vrai fort > 10 || doux > 10
! non : l'inverse !radar

Le piège du = et du ==

= range une valeur (vitesse = 0 met la vitesse à zéro). == compare (vitesse == 0 demande « la vitesse vaut-elle zéro ? »). Écrire if (vitesse = 0) est une erreur classique : la condition ne fait pas ce que tu crois, et la vitesse est remise à zéro au passage !

Les messages d'erreur les plus courants

Quand la compilation échoue, l'IDE affiche un message en orange. Pas de panique : il indique presque toujours la ligne du problème (ou celle juste après).

Message Ce qu'il veut dire Solution
expected ';' before … il manque un point-virgule ajouter ; à la fin de la ligne d'avant
'xxx' was not declared in this scope ce nom est inconnu faute de frappe ? majuscule ? variable déclarée ailleurs ?
expected '}' at end of input une accolade ouverte n'est jamais fermée compter les { et les }
fatal error: xxx.h: No such file or directory une bibliothèque manque, ou la mauvaise carte est choisie installer la bibliothèque, vérifier la carte

Majuscules et minuscules

Pour le C++, led, Led et LED sont trois noms différents. digitalwrite (sans majuscule au W) n'existe pas !

Mise en pratique : le compteur de clignotements

Modifie le programme de la mission 0 pour qu'il compte ses clignotements :

#define LED 2
int compteur = 0;                      // globale : elle garde sa valeur

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  compteur++;
  Serial.print("Clignotement n°");    // print : sans retour à la ligne
  Serial.println(compteur);            // println : avec retour à la ligne

  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);

  if (compteur % 10 == 0) {            // % = le reste de la division
    Serial.println("10 de plus ! Pause d'une seconde.");
    delay(1000);
  }
}

compteur % 10 donne le reste de la division par 10 : il vaut 0 pour 10, 20, 30… C'est l'astuce classique pour faire quelque chose « tous les N tours ».

Exercices

1. Qu'affiche ce programme dans le moniteur série ?
int x = 5;
void setup() {
  Serial.begin(115200);
  x = x * 2;
  x += 3;
  Serial.println(x);
}
void loop() {}
Réponse

5 × 2 = 10, puis 10 + 3 = 13. Il l'affiche une seule fois (c'est dans setup()), et loop() vide ne fait rien.

2. Trouve les 3 erreurs
void setup() {
  pinmode(2, OUTPUT)
  Serial.begin(115200);
}
void loop() {
  if (etat = true) {
    digitalWrite(2, HIGH);
  }
}
Réponse
  1. pinmode → pinMode (majuscule au M).
  2. Il manque le ; à la fin de la ligne pinMode.
  3. etat n'est jamais déclarée (bool etat = true; en haut), et etat = true devrait être etat == true (ou simplement if (etat)).
3. Quelle condition écrire pour « le joystick est poussé vers le haut ET le bouton ✕ est appuyé » ?

if (manette->axisY() < -400 && manette->a()) { … } (vers le haut, Y est négatif).

À retenir

  • Compiler (✓), téléverser (→), et le programme reste dans la carte.
  • setup() : une fois. loop() : pour toujours.
  • Une variable a un type, un nom et une valeur ; globale en haut, locale dans un bloc.
  • if décide ; = range, == compare.

Où ça sert dans l'atelier

Pour aller plus loin