Programmation embarquée avec Arduino
Bases de la programmation C/C++ sur microcontrôleur.
Introduction
Programmer une carte Arduino consiste à écrire un firmware C/C++ qui pilote un microcontrôleur AVR (UNO, Nano) ou ARM (MKR, Nano 33). L'écosystème est simple, très documenté, idéal pour prototyper.
Environnement
- Arduino IDE 2.x (moderne, autocomplete, debug).
- PlatformIO dans VS Code (multi-plateforme, gestion bibliothèques, tests).
- CLI arduino-cli pour l'intégration continue.
- Bibliothèques : Wire (I2C), SPI, Servo, WiFi (ESP), FastLED.
Structure d'un programme
#include <DHT.h>
DHT dht(4, DHT22);
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(13, OUTPUT);
}
void loop() {
float t = dht.readTemperature();
Serial.println(t);
digitalWrite(13, t > 25 ? HIGH : LOW);
delay(2000);
}
GPIO, ADC, PWM
- digitalRead / digitalWrite : 0 / 5 V.
- analogRead (10 bits sur UNO, 12 sur ESP32).
- analogWrite (PWM, 8 bits, 490 Hz).
- tone() pour piloter un buzzer.
Communication
- Serial.print() : UART USB pour debug.
- Wire.begin() : I2C multi-esclave.
- SPI.begin() : capteurs et écrans rapides.
- SoftwareSerial : port série logiciel supplémentaire.
Interruptions
attachInterrupt(digitalPinToInterrupt(2), montisr, RISING);
volatile int compteur = 0;
void montisr() { compteur++; }
Cas d'usage : bouton poussoir sans debounce logiciel, encodeur incrémental, RTC pulse.
Multitâche non bloquant
Éviter delay(), utiliser millis() :
unsigned long lastToggle = 0;
if (millis() - lastToggle > 500) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
lastToggle = millis();
}
Frameworks : Scheduler (SAMD), TaskScheduler (AVR).
Stockage
- EEPROM interne (1 kB sur UNO).
- SD Card via SPI.
- LittleFS sur ESP.
Cas concret : station météo
- DHT22 (T°/humidité), BMP280 (pression, altitude), BH1750 (lumière).
- Écran OLED 128×64 SSD1306 (I2C).
- Envoi ThingSpeak via ESP8266.
- Alim solaire 6 V + batterie Li-ion + BQ25504.
- Consommation moyenne 30 mA en deep sleep.
Bonnes pratiques
- Nommer variables clairement (
temperatureCelsius). - Séparer setup/loop en fonctions.
- Utiliser
constet#definepour les constantes. - Contrôler la mémoire (Arduino UNO n'a que 2 kB SRAM).
- Documenter le brochage.
Exemple chiffré 1 — budget temps de la boucle
Sur un UNO (ATmega328P, 16 MHz), une itération de loop() contenant une lecture DHT22 (bloquante ~250 ms), un Serial.print à 115 200 bauds (40 octets → ms) et un calcul flottant (~0,1 ms) dure ≈ 254 ms.
Fréquence d'échantillonnage maximale : Hz. Pour cadencer un asservissement à 100 Hz, il faut donc supprimer les attentes bloquantes (delay, capteurs lents) et passer à une machine à états + millis(), ou à un timer matériel.
Exemple chiffré 2 — résolution du convertisseur
CAN 10 bits, référence 5 V :
Avec un LM35 (10 mV/°C), la résolution en température vaut °C. En passant à 1,1 V interne : mV → 0,107 °C, soit un gain d'un facteur 4,5 sans changer de capteur.
Exemple chiffré 3 — consommation et autonomie
Nœud capteur sur 2 piles AA (2 400 mAh) :
| État | Courant | Durée par cycle |
|---|---|---|
| Sommeil (power-down) | 0,15 mA | 59 s |
| Mesure + calcul | 12 mA | 0,3 s |
| Émission LoRa | 45 mA | 0,7 s |
En espaçant les émissions à une toutes les 10 minutes, tombe à ~0,21 mA et l'autonomie dépasse 15 mois.
Squelette non bloquant à connaître
const unsigned long PERIODE = 100; // ms
unsigned long precedent = 0;
void loop() {
unsigned long maintenant = millis();
if (maintenant - precedent >= PERIODE) {
precedent += PERIODE; // pas de dérive cumulée
mesurer();
asservir();
}
gererCommunication(); // exécuté en continu
}
Points-clés à retenir
delay()gèle tout le programme : il est proscrit dès qu'il y a plusieurs tâches.- Toujours vérifier que le temps d'exécution de la boucle est très inférieur à la période d'échantillonnage souhaitée.
- La consommation moyenne se calcule en pondérant chaque état par sa durée : c'est elle, et non le pic, qui fixe l'autonomie.
Quiz de révision
- Question 1.
Quelle instruction Arduino déclare une broche comme sortie ?
- Question 2.
Sur Arduino UNO,
analogReadretourne une valeur entre : - Question 3.
Le protocole I2C nécessite en Arduino :
- Question 4.
Pour ne pas bloquer le microcontrôleur, on préfère à
delay(): - Question 5.
Une interruption externe attachée sur un front montant se déclenche quand :
- Question 6.
Arduino UNO dispose d'une SRAM de :
Sources et références
Ce cours est rédigé par l'équipe RévisionBac à partir du programme officiel et des sources institutionnelles ci-dessous. Elles permettent de vérifier les définitions, les chiffres et les normes citées.
- 1.Programmes et ressources du lycée général et technologique — Éduscol — Ministère de l'Éducation nationale
- 2.Bulletin officiel de l'Éducation nationale (programmes du baccalauréat) — education.gouv.fr
- 3.Documentation du langage Python — Python Software Foundation
- 4.Bonnes pratiques de cybersécurité et réseaux — ANSSI
- 5.Spécifications des protocoles réseau (RFC) — IETF
- 6.Archives et ressources documentaires — Archives nationales
Contenu vérifié et mis à jour le 08/08/2026. Les liens renvoient vers les sites officiels des éditeurs cités.
Historique éditorial
Ce chapitre est rédigé et relu par l'équipe RévisionBac, puis enrichi par les contributions validées.
- — Dernière mise à jour du cours (relecture et enrichissement)
- — Première publication de la fiche de cours