MakerSpace Amiens · Microcontrôleurs

Découvrir le microcontrôleur

CM1 : de la puce au premier programme

Alban Petit

Au programme

  1. Un ordinateur sur une puce
  2. Sous le capot
  3. Du code à la puce
  4. Votre premier programme
2UniLaSalle Amiens

Ce que vous saurez faire

À la fin de ce cours, vous saurez :

  • dire ce qu’est un microcontrôleur, et ce qui le distingue d’un PC
  • nommer les blocs d’une puce : CPU, Flash, RAM, périphériques, bus
  • expliquer ce qu’est un registre, et à quoi sert une interruption
  • suivre le trajet du code source jusqu’à l’exécution sur la puce
  • dire pourquoi delay() pose problème dans une loop()

Fil rouge de l’atelier : un Pong 2 joueurs, puis un Snake multijoueur.

L’atelier Microcontrôleurs

3UniLaSalle Amiens

Un ordinateur sur une puce

Percevoir, décider, agir

Activité : comptez-les autour de vous

Toute la classe3 minSans PC

Combien d’ordinateurs y a-t-il dans cette pièce ?

  • Une réponse par personne, à voix haute
  • On note les chiffres au tableau, du plus petit au plus grand
5UniLaSalle Amiens

Il y en a des centaines

  • Le micro-ondes qui compte les secondes et fait tourner le plateau
  • La machine à laver qui enchaîne lavage, rinçage, essorage
  • La télécommande, les écouteurs sans fil, la manette de jeu
  • La trottinette, le thermostat, le détecteur de fumée
  • Et 50 à 150 dans une voiture récente : vitres, clignotants, airbags, injection

Aucun n’a besoin d’un « vrai » ordinateur. Ils ont besoin d’une puce à quelques euros, qui démarre instantanément et fait sa tâche en boucle.

Qu’est-ce qu’un microcontrôleur ?

6UniLaSalle Amiens

Toujours la même boucle

flowchart LR
  A["Percevoir<br/>(capteurs)"] --> B["Décider<br/>(le programme)"]
  B --> C["Agir<br/>(actionneurs)"]
  C -.-> A

Un thermostat perçoit la température, décide qu’il fait trop froid, agit en allumant le chauffage. Puis il recommence, indéfiniment.

Cette boucle, vous la retrouverez telle quelle dans votre Pong : lire le joystick, calculer la position de la balle, redessiner l’écran.

Qu’est-ce qu’un microcontrôleur ? Les capteurs

7UniLaSalle Amiens

Le « décider », c’est vous.

Le microcontrôleur ne sait rien faire tout seul. Sans programme, c’est une puce inerte : tout l’atelier consiste à écrire ce comportement.

8UniLaSalle Amiens

Le vocabulaire de l’atelier

Terme Ce que c’est Exemples du projet
Capteur Traduit une grandeur physique en signal électrique bouton, joystick, potentiomètre
Actionneur Transforme un signal électrique en action LED, écran, moteur, buzzer
Broche (pin) Une patte de la puce, reliée au monde extérieur GPIO5, GPIO1
Programme La suite d’instructions que vous écrivez main.cpp

Un bouton est un capteur, une LED est un actionneur.

Les capteurs

9UniLaSalle Amiens

Pourquoi pas un « vrai » ordinateur ?

  Ordinateur classique Microcontrôleur
Tâches Des milliers, en même temps Une seule, en boucle
Prix Plusieurs centaines d’€ Quelques euros, parfois centimes
Énergie Se branche au secteur Des mois sur une pile
Démarrage Plusieurs secondes Instantané
Système Un OS complet Aucun, en général

C’est cette sobriété qui le rend si présent : on peut en mettre partout, pour presque rien, sans y penser.

Qu’est-ce qu’un microcontrôleur ?

10UniLaSalle Amiens

Et le Raspberry Pi, alors ?

Microcontrôleur

Une seule tâche, du temps réel, très peu d’énergie, démarrage immédiat.

ESP32-S3, Arduino, STM32

Nano-ordinateur

Un vrai système d’exploitation (Linux), un écran, le réseau complet, beaucoup de mémoire.

Raspberry Pi

La question à se poser n’est pas « lequel est le plus puissant » mais « de quoi ai-je réellement besoin ». Un Raspberry Pi qui met 20 secondes à démarrer ne peut pas déclencher un airbag.

Qu’est-ce qu’un microcontrôleur ?

11UniLaSalle Amiens

Notre puce : l’ESP32-S3

Caractéristique Valeur
CPU Xtensa LX7 dual-core 32 bits, 240 MHz
RAM 512 Ko SRAM (+ 8 Mo PSRAM en option)
Flash 16 Mo, externe via SPI
GPIO 45 broches, dont 20 capables d’ADC
Tension logique 3,3 V
Connectivité Wi-Fi 802.11 b/g/n + Bluetooth 5
Prix ~8 € la carte de développement

Le sans-fil servira au projet Snake. ↓ pour le brochage de la carte.

ESP32-S3-DevKitC-1

12UniLaSalle Amiens

La fiche de la carte

12.1UniLaSalle Amiens
  3,3 V, jamais 5 V

Relier une broche GPIO directement à du 5 V (un Arduino Uno, un capteur alimenté en 5 V) peut détruire la puce de façon irréversible. C’est l’erreur la plus fréquente et la plus coûteuse de l’atelier : avant de brancher un module, cherchez sa tension d’alimentation.

GPIO et monde numérique

13UniLaSalle Amiens

Sous le capot

CPU, mémoires, périphériques, bus

Le schéma-bloc, votre carte mentale

Schéma-bloc fonctionnel de l'ESP32-S3

Chaque concept de l’atelier détaille l’une de ces briques.

Architecture d’un microcontrôleur

15UniLaSalle Amiens

Cinq briques, une seule puce

Bloc Rôle Accès logiciel
CPU Exécute les instructions une par une direct
Flash Stocke le programme (persistant) lecture à l’exécution
RAM Variables, pile d’appels (volatile) lecture/écriture rapide
Périphériques GPIO, ADC, UART, SPI, PWM via registres
Bus Relie tout le monde transparent sous Arduino

Tout est sur le même silicium : un système sur puce. Il suffit de l’alimenter.

Architecture d’un microcontrôleur

16UniLaSalle Amiens

Le CPU ne sait faire qu’une chose

Fetch

Fetch : aller chercher en Flash l’instruction suivante, à l’adresse indiquée par le compteur de programme.

17UniLaSalle Amiens

Le CPU ne sait faire qu’une chose

Fetch
→
Decode

Decode : comprendre ce que l’instruction demande, et sur quelles données.

18UniLaSalle Amiens

Le CPU ne sait faire qu’une chose

Fetch
→
Decode
→
Execute

Execute : calculer dans l’ALU, ou transférer une donnée. Puis recommencer, 240 millions de fois par seconde.

Au fond, un CPU ne fait que deux choses : calculer, et déplacer des octets d’un endroit à un autre.

Architecture d’un microcontrôleur

19UniLaSalle Amiens

240 MHz, ça veut dire quoi ?

Opération Ordre de grandeur
Un digitalWrite() quelques cycles
Une multiplication entière quelques dizaines de cycles
Redessiner un écran 240×240 en SPI quelques millions de cycles
Établir une connexion Wi-Fi plusieurs centaines de millions

À 60 images par seconde, chaque image dispose de 4 millions de cycles.

Architecture d’un microcontrôleur

20UniLaSalle Amiens

Deux cœurs, et le droit de dormir

  • L’ESP32-S3 a deux cœurs Xtensa LX7 : sous Arduino, setup()/loop() tournent sur le cœur 1, le Wi-Fi occupe le cœur 0 en arrière-plan
  • Couper l’horloge d’un périphérique inutilisé économise de l’énergie
  • Les modes veille (light sleep, deep sleep) éteignent tout ou partie de la puce
  • Le RTC continue de tourner en veille profonde pour réveiller la carte à l’heure dite

C’est ce qui permet à un capteur sur pile de tenir des mois : il dort 99,9 % du temps.

Architecture d’un microcontrôleur

21UniLaSalle Amiens

Deux mémoires, deux usages

  Flash RAM (SRAM)
Contenu Programme compilé, constantes Variables, pile, heap
Persistance Survit au reset Perdue à l’extinction
Vitesse Plus lente Très rapide
Taille 16 Mo 512 Ko

Deux espaces d’adressage séparés : une architecture Harvard modifiée.

Architecture d’un microcontrôleur

22UniLaSalle Amiens

Le glossaire des périphériques

Sigle Nom complet Rôle
GPIO General Purpose Input/Output Entrée ou sortie numérique
ADC Analog to Digital Converter Tension vers nombre
UART / I2C / SPI   Bus série
Timer Compteur matériel Événements périodiques, PWM
DMA Direct Memory Access Transfert sans le CPU
RTC Real-Time Clock Horloge, même en veille
Watchdog Chien de garde Redémarre si blocage

Chaque sigle aura sa slide au CM2 ou au CM3.

Architecture d’un microcontrôleur

23UniLaSalle Amiens
  Pas de DAC sur l'ESP32-S3

Contrairement à l’ESP32 d’origine, l’ESP32-S3 n’a pas de convertisseur numérique-analogique matériel. Pour produire une tension variable, il faudra passer par du PWM, qu’on verra au CM2.

ADC et PWM

24UniLaSalle Amiens

Le bus : une autoroute partagée

flowchart TB
  CPU["CPU (pilote le bus)"]
  BUS["Bus partagé : adresses · données · contrôle"]
  RAM["RAM"]
  PA["Périph. A<br/>(émetteur actif)"]
  PB["Périph. B<br/>(haute impédance)"]
  CPU --- BUS
  BUS --- RAM
  BUS --- PA
  BUS --- PB

Trois faisceaux : l’adresse dit à qui on parle, les données transitent, le contrôle précise « je lis » ou « j’écris ».

Architecture d’un microcontrôleur

25UniLaSalle Amiens

Un seul composant parle à la fois

Si deux périphériques poussaient une valeur en même temps sur le bus de données, l’un forçant un 0 et l’autre un 1, ce serait un court-circuit.

D’où les sorties trois états : en plus de 0 et 1, un état de haute impédance qui déconnecte électriquement le composant de la ligne.

À tout instant, un seul émetteur est actif ; tous les autres sont à l’écoute. C’est l’adresse qui désigne celui qui a le droit de répondre.

Retenez le mot haute impédance : il reviendra au CM2 avec les entrées flottantes, et au CM3 avec l’I2C.

Architecture d’un microcontrôleur

26UniLaSalle Amiens

Les registres : l’interface matériel / logiciel

Chaque périphérique se pilote par des registres : de simples cases mémoire à une adresse fixe.

  • Écrire dans un registre allume une LED
  • Lire un registre donne l’état d’un bouton
  • digitalWrite(LED, HIGH) écrit dans le bon registre

Ranger une variable et allumer une LED : la même opération, poser une valeur à une adresse.

Architecture d’un microcontrôleur

27UniLaSalle Amiens

Réagir sans attendre : l’interruption


void IRAM_ATTR surAppui() {
  compteurAppuis++;   // aussi court et rapide que possible
}

void setup() {
  attachInterrupt(digitalPinToInterrupt(BTN_PIN), surAppui, FALLING);
}

Le CPU suspend loop(), exécute la petite fonction, puis reprend exactement où il s’était arrêté.

IRAM_ATTR la place en RAM interne : sans ce mot-clé, la puce finit par planter.

Architecture d’un microcontrôleur GPIO et monde numérique

28UniLaSalle Amiens

Du code à la puce

Compiler, flasher, exécuter

Le voyage complet

flowchart LR
  A["Code source<br/>(.cpp)"] --> B["Compilateur<br/>(gcc-xtensa)"]
  B --> C["Binaire<br/>(.bin)"]
  C --> D["Flashage<br/>(USB / UART)"]
  D --> E["Exécution<br/>ESP32-S3"]

Un clic sur Upload déclenche les quatre étapes, toujours dans cet ordre. Quand quelque chose échoue, la première question est : à quelle étape ?

Du matériel au logiciel

30UniLaSalle Amiens

La toolchain Arduino-ESP32

Élément Rôle
Compilateur (gcc pour Xtensa) Traduit le C++ en instructions machine
Core Arduino Fournit pinMode(), digitalWrite(), analogRead()
Uploader (esptool) Transfère le binaire vers la Flash, par USB

L’IDE ne fait qu’orchestrer ces trois outils. Arduino IDE ou PlatformIO, la chaîne reste la même : compiler, flasher, exécuter.

PlatformIO Arduino IDE

31UniLaSalle Amiens

« Compiler » recouvre trois étapes

  1. Préprocesseur : traite les #include et les #define, colle le contenu des bibliothèques
  2. Compilation : chaque fichier C++ devient du code objet, séparément
  3. Édition de liens : tous les objets sont assemblés en un binaire, en résolvant les références

Savoir les distinguer, c’est savoir lire une erreur. C’est la compétence la plus rentable du semestre.

Du matériel au logiciel

32UniLaSalle Amiens

Lire une erreur

Message Étape Cause probable
expected ';' before ... compilation une faute de syntaxe, souvent une ligne avant
'x' was not declared compilation variable mal orthographiée, ou #include manquant
undefined reference to ... édition de liens bibliothèque absente de lib_deps
A fatal error occurred: Failed to connect flashage mauvais port, câble sans data, bouton BOOT

Corrigez la première erreur, pas les 40 suivantes.

Du matériel au logiciel

33UniLaSalle Amiens

Au reset : la séquence de démarrage

  1. ROM bootloader : gravé en usine, il lit les broches de strapping (dont GPIO0) pour choisir démarrage normal ou mode téléversement
  2. Bootloader de second niveau : chargé depuis la Flash, il initialise horloge et mémoire, choisit la partition à lancer
  3. Votre application : setup() une fois, puis loop() sans fin

C’est exactement ce que force le bouton BOOT maintenu au reset : il bloque l’étape 1 en mode téléversement.

Du matériel au logiciel

34UniLaSalle Amiens
  Le flashage échoue systématiquement ?

Dans l’ordre : vérifiez que le câble USB-C transporte des données (beaucoup de câbles ne font que charger), que le bon port est sélectionné, puis maintenez le bouton BOOT pendant les 2 premières secondes de l’upload, jusqu’à ce que Writing at... apparaisse.

Vérification de la toolchain

35UniLaSalle Amiens

Tout un programme en deux fonctions

void setup() {                      // une seule fois, au démarrage
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(115200);
}

void loop() {                       // en boucle, jusqu'à la coupure
  digitalWrite(LED_PIN, HIGH);
  delay(500);
  digitalWrite(LED_PIN, LOW);
  delay(500);
}

Pas de main() : le core Arduino l’écrit, et appelle setup() puis loop().

Du matériel au logiciel

36UniLaSalle Amiens

Pas de système d’exploitation

Sur un ordinateur, votre programme est un processus parmi d’autres. Ici, il n’y a rien autour de lui :

  • pas de multitâche : loop() tourne seul
  • pas de sleep() : un delay() bloque tout, boutons compris
  • pas d’arrêt propre : couper le courant coupe le programme net

En contrepartie, le comportement est prévisible à la milliseconde près.

Du matériel au logiciel

37UniLaSalle Amiens

Activité : trouvez le bug

En binôme3 minSans PC

void loop() {
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);

  if (digitalRead(BOUTON) == LOW) {
    tirer();
  }
}

Le joueur appuie sur le bouton. Que se passe-t-il ?

38UniLaSalle Amiens

Correction : le bouton n’est presque jamais lu

Le programme passe 1 seconde sur 1 dans les delay(). Le digitalRead() n’est atteint qu’une fois par tour.

  • Un appui court de 200 ms : vu une fois sur cinq
  • Ajoutez un écran à rafraîchir : le jeu devient injouable
  • La solution n’est pas de raccourcir le delay(), c’est de ne jamais bloquer

Du matériel au logiciel

39UniLaSalle Amiens

Ne jamais bloquer : regarder l’heure


unsigned long dernierClignotement = 0;
const unsigned long INTERVALLE = 500;   // ms
int etatLed = LOW;

void loop() {
  if (millis() - dernierClignotement >= INTERVALLE) {
    dernierClignotement = millis();
    etatLed = !etatLed;
    digitalWrite(LED_PIN, etatLed);
  }
}

On compare l’heure à une date mémorisée : rien n’est jamais figé.

Du matériel au logiciel

40UniLaSalle Amiens
  delay() reste utile

Pour une pause courte et unique (initialiser un composant, attendre au démarrage), delay() est parfaitement acceptable. C’est dans la loop(), quand plusieurs tâches doivent avancer en parallèle, qu’il faut l’éviter.

Du matériel au logiciel

41UniLaSalle Amiens

Votre premier programme

Blink, ligne par ligne

Quatre lignes qui résument le cours


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // configure la broche : écriture registre
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // 3,3 V sur la broche
  delay(500);                       // bloque le CPU : il n'y a pas d'OS
  digitalWrite(LED_BUILTIN, LOW);   // 0 V
  delay(500);
}

Architecture, registres, GPIO et absence de système d’exploitation, réunis en quatre lignes. Compilé et flashé, ce code tourne tant que la carte est alimentée.

Vérification de la toolchain

43UniLaSalle Amiens
  La LED embarquée n'est pas une simple LED

Sur l’ESP32-S3-DevKitC-1, la LED intégrée est une RGB adressable (WS2812), pas une LED monochrome. Si digitalWrite(LED_BUILTIN, ...) ne produit rien, utilisez rgbLedWrite(RGB_BUILTIN, 40, 0, 0); puis rgbLedWrite(RGB_BUILTIN, 0, 0, 0); en gardant les delay(500).

Vérification de la toolchain ESP32-S3-DevKitC-1

44UniLaSalle Amiens

Le montage le plus simple

LED rouge et résistance série sur breadboard, reliées à une carte ESP32-S3

La base du montage du Pong : boutons, joystick et écran viendront s’y ajouter.

Vérification de la toolchain

45UniLaSalle Amiens

Le fichier platformio.ini

[env:esp32-s3-devkitc-1]
platform = espressif32        ; la famille de puces
board = esp32-s3-devkitc-1    ; la carte exacte
framework = arduino           ; le core utilisé
monitor_speed = 115200        ; la vitesse du moniteur série
lib_deps =                    ; les bibliothèques, téléchargées seules
    bodmer/TFT_eSPI@^2.5.0

Tout le projet est décrit ici. C’est ce fichier, versionné dans votre repo, qui permet à quelqu’un d’autre de recompiler votre code à l’identique.

PlatformIO Installer PlatformIO

46UniLaSalle Amiens

Les raccourcis PlatformIO

Action Raccourci Où
Compiler (Build) Ctrl Alt B icône ✓, barre bleue
Téléverser (Upload) Ctrl Alt U icône →, barre bleue
Moniteur série Ctrl Alt S icône prise, barre bleue

Compiler avant de téléverser fait gagner du temps : les erreurs de syntaxe sortent sans attendre le flashage.

Installer VSCode Installer PlatformIO

47UniLaSalle Amiens

Déboguer : le moniteur série

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.printf("x=%d y=%d btn=%d\n", x, y, btn);
}

Tant qu’il n’y a pas d’écran, c’est votre seul retour visuel. Afficher une variable au bon endroit résout la moitié des bugs.

Le port série sous VSCode

48UniLaSalle Amiens
  Du charabia à l'écran ?

C’est presque toujours une vitesse qui ne correspond pas. Vérifiez que le moniteur série est réglé sur la même valeur que celle passée à Serial.begin(), en général 115200.

Le port série sous VSCode

49UniLaSalle Amiens

À retenir

  • Un µC = CPU + Flash + RAM + périphériques, sur une seule puce
  • Percevoir, décider, agir : le « décider », c’est votre programme
  • Flash = le programme (persistant), RAM = les données (volatile)
  • Les périphériques se pilotent par des registres
  • Code → compilation → édition de liens → flashage → exécution
  • Pas d’OS : delay() bloque tout, millis() ne bloque rien
  • Tension logique : 3,3 V

Architecture d’un microcontrôleur Du matériel au logiciel

50UniLaSalle Amiens

À faire de votre côté

Sur votre machine30 min

  1. Installer VSCode, puis l’extension PlatformIO
  2. Laisser PlatformIO télécharger la plateforme espressif32 : c’est long, ne le faites pas au dernier moment
  3. Parcourir le tutoriel de vérification de la toolchain pour savoir ce qui vous attend

Une chaîne de développement qui fonctionne avant de manipuler, c’est une séance entière de gagnée.

Installer VSCode Installer PlatformIO Vérification de la toolchain

51UniLaSalle Amiens
UniLaSalle Amiens, Demain commence ici