digitalWrite(13, HIGH) chasse fixe, gras : code à taper tel quelb italique : valeur à remplacer (b : numéro de broche)→ 127 valeur obtenue ; 1 renvoi aux explicationsVue de dessus, prise USB à gauche. Les broches SCL et SDA, près d’AREF, sont les mêmes signaux que A5 et A4. Les connecteurs de l’Uno R4 sont disposés de la même façon ; RESET redémarre le croquis, sans l’effacer.
digitalWrite(), delay()…).| Microcontrôleur | ATmega328P, 8 bits, 16 MHz |
| E/S numériques | 14, dont 6 en MLI (~) · 5 V |
| Entrées analog. | 6 (A0 à A5), 10 bits |
| Mémoires | flash 32 Ko (dont 0,5 Ko de chargeur) · SRAM 2 Ko · EEPROM 1 Ko |
| Alimentation | USB 5 V ou jack 7–12 V |
| Par broche | 20 mA au plus |
R4 Uno R4 (Minima, WiFi) : même format, même brochage ; Arm Cortex-M4 32 bits, 48 MHz, flash 256 Ko, RAM 32 Ko, USB-C, jack 6–24 V, 8 mA par broche.
// Blink : la LED clignote 1 const int LED = LED_BUILTIN; 2 void setup() { 3 pinMode(LED, OUTPUT); 4 } void loop() { 5 digitalWrite(LED, HIGH); 6 delay(1000); 7 digitalWrite(LED, LOW); delay(1000); }
/* … */ sur plusieurs lignes ;LED_BUILTIN vaut 13 sur Uno) : la broche se change en un seul endroit ;setup() s’exécute une fois, à la mise sous tension ou après RESET ;pinMode() déclare la broche en sortie ;loop() se répète sans fin, aussi vite que possible ;HIGH = 5 V : LED allumée ; LOW = 0 V : éteinte ; chaque instruction finit par ; ;delay() bloque tout le programme (solution p. 5).Un croquis est un dossier Blink/ contenant Blink.ino. L’IDE ajoute #include <Arduino.h>, déclare les fonctions (appelables avant leur définition) et fournit main(), ici simplifié :
int main() {
init(); // minuteries
setup();
for (;;) { // boucle sans fin
loop();
if (serialEventRun)
serialEventRun(); // réception
}
}COM3, COM4…).Serial.begin().Point de départ sûr : Fichier › Exemples › 01.Basics › Blink. Activer les avertissements : Fichier › Préférences › Avertissements du compilateur : Tout (Aucun par défaut).
| Ctrl+R | Vérifier / Compiler |
| Ctrl+U | Téléverser |
| Ctrl+Shift+M | Moniteur série |
| Ctrl+Shift+I | Gérer les bibliothèques |
| Ctrl+T | Formatage automatique |
| Ctrl+/ | Commenter / décommenter |
| Ctrl+F Ctrl+G | Rechercher, occurrence suivante |
| Ctrl+L | Aller à la ligne n°… |
| Ctrl+Shift+C | Copier pour le forum (Markdown) |
| Ctrl+Alt+S | Exporter les binaires compilés |
| Ctrl+N Ctrl+S | Nouveau croquis, enregistrer |
Sur Mac : Cmd au lieu de Ctrl.
| croquis | programme Arduino (sketch), fichier .ino |
| téléverser | envoyer le programme compilé dans la carte (upload) |
| chargeur d’amorçage | petit programme résident qui reçoit le croquis par USB (bootloader) |
| broche | borne de connexion (pin) : numérique 0–13, analogique A0–A5 |
| MLI | modulation de largeur d’impulsion (PWM), p. 3 |
| CAN | convertisseur analogique-numérique (ADC), p. 3 |
| GND | masse : la référence 0 V |
| bouclier | carte d’extension enfichée sur les connecteurs (shield) |
| module | petit circuit prêt à câbler : capteur, écran, relais… |
| bibliothèque | code réutilisable, chargé par #include (p. 8) |
| Tension U | V | volt : différence de « pression » entre deux points ; se mesure en parallèle |
| Intensité I | A | ampère : débit du courant ; se mesure en série |
| Résistance R | Ω | ohm : s’oppose au passage du courant |
| Puissance P | W | watt : énergie consommée par seconde |
| Capacité C | F | farad : réserve de charges d’un condensateur |
Loi d’Ohm : U = R × I · P = U × I. Série : R = R1 + R2 ; parallèle : 1/R = 1/R1 + 1/R2. Ex. : 5 V aux bornes de 220 Ω → I = 5 / 220 ≈ 22,7 mA.
Le courant ne circule que dans une boucle fermée, du + vers le −, à travers la charge. Une boucle sans résistance est un court-circuit !
R = (Ualim − ULED) / I. Ex. : 5 V, LED rouge 2 V, 15 mA → (5 − 2) / 0,015 = 200 Ω → prendre la valeur normalisée supérieure, 220 Ω → I ≈ 13,6 mA.
| Rouge | ≈ 1,8–2,2 V |
| Jaune, verte classique | ≈ 2,0–2,2 V |
| Bleue, blanche, verte vive | ≈ 2,8–3,4 V |
Valeurs typiques : lire la fiche du composant. Anode (+) : patte longue ; cathode (−) : patte courte, côté méplat. Témoin lumineux : 220 Ω à 1 kΩ.
1 2 chiffres · 3 multiplicateur · 4 tolérance (souvent or, ±5 %)
| couleur | 0–9 | × | ± |
|---|---|---|---|
| noir | 0 | ×1 | |
| marron | 1 | ×10 | ±1 % |
| rouge | 2 | ×100 | ±2 % |
| orange | 3 | ×1 k | |
| jaune | 4 | ×10 k | |
| vert | 5 | ×100 k | ±0,5 % |
| bleu | 6 | ×1 M | ±0,25 % |
| violet | 7 | ×10 M | ±0,1 % |
| gris | 8 | ±0,05 % | |
| blanc | 9 | ||
| or | ×0,1 | ±5 % | |
| argent | ×0,01 | ±10 % |
Ne Mangez Rien Ou Je Vous Brûle Votre Grande Barbe : noir → blanc. Ex. : rouge-rouge-marron = 220 Ω ; marron-noir-rouge = 1 kΩ ; jaune-violet-rouge = 4,7 kΩ ; marron-noir-orange = 10 kΩ. Série E12 : 10 12 15 18 22 27 33 39 47 56 68 82.
Convention : fil rouge pour le +, noir (ou bleu) pour la masse.
Une entrée reliée à rien flotte : elle lit n’importe quoi. On la tire vers un niveau connu. a) résistance interne (20 à 50 kΩ) activée par INPUT_PULLUP : logique inversée ; b) résistance externe de 10 kΩ vers la masse.
Bouton à 4 pattes : elles sont reliées deux à deux ; câbler deux pattes en diagonale pour être sûr.
Vs = Ve × R2 / (R1 + R2)
Symboles de la norme CEI, en usage en Europe ; aux États-Unis, la résistance est dessinée en zigzag.
| USB | 5 V de l’ordinateur, en général 500 mA au plus |
| Jack | 7 à 12 V, régulés à 5 V par la carte (Uno R4 : 6 à 24 V) |
| VIN | même plage que le jack ; ! aucune protection contre l’inversion de polarité |
| Broche 5V | sortie ; jusqu’à 1 A selon la source (doc. Arduino) ; ne pas y injecter de tension |
| Broche 3.3V | sortie de 150 mA au plus |
Faire le bilan des courants ; moteurs, servos et rubans de LED : alimentation à part.
digitalWrite() ; passif : tone().| M méga | × 1 000 000 | 1 MΩ = 1 000 kΩ |
| k kilo | × 1 000 | 4,7 kΩ = 4 700 Ω, noté 4k7 |
| m milli | ÷ 1 000 | 20 mA = 0,02 A |
| µ micro | ÷ 1 000 000 | 100 µF ; 10 µs |
| n nano | ÷ 109 | 100 nF = 0,1 µF |
| p pico | ÷ 1012 | 22 pF |
Condensateur marqué 104 : 10 suivi de 4 zéros, en pF → 100 000 pF = 100 nF.
| pinMode(b, OUTPUT) | sortie : HIGH (5 V) ou LOW (0 V) |
| pinMode(b, INPUT) | entrée sans tirage (état par défaut) |
pinMode(b, INPUT_PULLUP) entrée tirée vers 5 V par une résistance interne | |
digitalWrite(b, HIGH) mettre la sortie à 5 V | |
| digitalRead(b) | lire l’entrée : HIGH ou LOW |
digitalWrite(b, !digitalRead(b)) inverser l’état d’une sortie | |
LOW sous ≈ 1,5 V, HIGH au-dessus de ≈ 3 V ; entre les deux : indéterminé.INPUT_PULLUP !const int BOUTON = 2; // vers GND const int LED = 13; bool allumee = false; int avant = HIGH; // tour précédent void setup() { pinMode(BOUTON, INPUT_PULLUP); pinMode(LED, OUTPUT); } void loop() { int etat = digitalRead(BOUTON); if (etat == LOW && avant == HIGH) { 1 allumee = !allumee; digitalWrite(LED, allumee); delay(20); 2 } avant = etat; }
delay() p. 5.| analogRead(A0) | 0 à 1023 (CAN 10 bits) : 0 V → 0, 5 V → 1023 ; ≈ 4,9 mV par pas ; ≈ 100 µs par lecture |
| lecture * 5.0 / 1023.0 | tension en volts (1023 dans les exemples Arduino, 1024 selon la fiche technique : écart < 0,1 %) |
analogReference(INTERNAL) pleine échelle = 1,1 V (Uno R3) : plus fin pour les petites tensions | |
analogReference(EXTERNAL) pleine échelle = tension sur AREF (0 à 5 V) | |
analogReadResolution(14) : jusqu’à 14 bits (10 par défaut) ; référence interne AR_INTERNAL = 1,5 V.analogWrite(9, v) v de 0 (toujours 0 V) à 255 (toujours 5 V) ; pas besoin de pinMode |
millis()).analogWrite().int v = analogRead(A0); // 0…1023 int lum = map(v, 0, 1023, 0, 255); analogWrite(9, lum); // 0…255 int x = map(512, 0, 1023, 0, 255); → 127 int inv = map(v, 0, 1023, 255, 0); int c = constrain(lum + 50, 0, 255);
map() calcule en entiers (partie décimale tronquée) et ne borne pas : l’associer à constrain(), qui ramène la valeur entre deux bornes. Bornes d’arrivée inversées (255, 0) : sens inversé.
| tone(b, 440) | note (440 Hz) jusqu’à noTone(b) |
| tone(b, 440, 200) | pendant 200 ms, sans bloquer le programme |
| pulseIn(b, HIGH) | durée d’une impulsion en µs ; 0 si rien en 1 s |
| pulseIn(b, HIGH, 30000) | délai d’attente réduit à 30 ms |
| random(1, 7) | entier de 1 à 6 : la borne haute est exclue |
randomSeed(analogRead(A5)) graine variable : broche non câblée | |
tone() : une seule note à la fois, 31 Hz au minimum ; perturbe la MLI des broches 3 et 11 (sauf Mega).
const int DATA = 11, CLK = 12, LAT = 8;
void afficher(byte motif) { // Q7…Q0
digitalWrite(LAT, LOW);
shiftOut(DATA, CLK, MSBFIRST, motif);
digitalWrite(LAT, HIGH); // sorties
}
void setup() {
pinMode(DATA, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LAT, OUTPUT);
afficher(0b10100101); // 4 sur 8
}Un bit par sortie ; les 8 changent ensemble quand le verrou (LAT) remonte. Câblage : DS (14), SHCP (11), STCP (12) ; OE (13) à GND, MR (10) à 5 V.
const byte CAPTEUR = 2; // 2 ou 3 volatile unsigned long compte = 0; 1 void compter() { 2 compte++; } void setup() { Serial.begin(9600); pinMode(CAPTEUR, INPUT_PULLUP); attachInterrupt( digitalPinToInterrupt(CAPTEUR), compter, FALLING); } void loop() { noInterrupts(); 3 unsigned long copie = compte; interrupts(); Serial.println(copie); delay(1000); }
volatile : variable partagée avec l’interruption ;delay() n’y marche pas, millis() n’y avance pas ; éviter Serial ;Déclencheurs : LOW, CHANGE, RISING (montée), FALLING (descente). Broches : Uno R3 et R4 : 2, 3 ; Mega : 2, 3, 18 à 21 ; Nano Every, Nano ESP32 : toutes.
millis(), delay() | minuterie 0 ; MLI des broches 5 et 6 |
bibliothèque Servo | minuterie 1 : supprime la MLI de 9 et 10, même sans servo dessus |
tone() | minuterie 2 : MLI des broches 3 et 11 |
Serial | broches 0 et 1 |
SPI, Wire (I²C) | 10 à 13 ; A4 et A5 |
// Photorésistance : 5 V → A0 // 10 kΩ : A0 → GND ; LED + 220 Ω : 9 const int CAPTEUR = A0, LED = 9; const int NUIT = 300, JOUR = 400; 1 bool allumee = false; void setup() { pinMode(LED, OUTPUT); Serial.begin(9600); } void loop() { int lum = analogRead(CAPTEUR); Serial.println(lum); 2 if (lum < NUIT) allumee = true; 3 if (lum > JOUR) allumee = false; digitalWrite(LED, allumee); delay(200); }
| type | o. | valeurs |
|---|---|---|
| bool | 1 | true / false |
| char | 1 | −128 à 127 ; un caractère : 'A' |
| byte, uint8_t | 1 | 0 à 255 |
| int, int16_t | 2 | −32 768 à 32 767 ! |
| unsigned int | 2 | 0 à 65 535 |
| long, int32_t | 4 | −2 147 483 648 à 2 147 483 647 |
| unsigned long | 4 | 0 à 4 294 967 295 : millis() |
| float | 4 | ±3,4 × 1038, 6 à 7 chiffres significatifs |
| double | 4 | identique à float sur AVR ! |
Cartes 32 bits (Uno R4, ESP32…) : int = 4 octets, double = 8 octets. Pour un code portable : uint8_t, int16_t, uint32_t… (taille garantie).
| HIGH LOW true false | niveaux 1 et 0 ; valeurs booléennes |
INPUT OUTPUT INPUT_PULLUP modes de broche ; LED_BUILTIN : 13 sur Uno | |
| 0xFF 0b11111111 | 255 en hexadécimal, en binaire |
| 60000UL 100000L | suffixes : unsigned long, long |
| 3.0 1.5e3 | nombres à virgule (float) |
| 'A' "Uno" | un caractère ; une chaîne de 4 octets (zéro final) |
| const int LED = 9; | constante typée : à préférer |
| #define LED 9 | remplacement de texte, sans type ni ; |
struct Mesure { // type composé
float temp;
int humidite;
};
Mesure m = {21.5, 40};
enum Mode { ARRET, AUTO, MANUEL };
Mode mode = AUTO; // 0, 1, 2
void setup() {
m.temp = 22.0; // champ : le point
if (mode == AUTO) m.humidite = 45;
}struct regroupe des valeurs liées ; enum donne des noms à des états (voir la machine à états, p. 5).
| bitRead(x, n) | bit n de x : bitRead(10, 1) → 1 |
| bitSet bitClear bitWrite | mettre un bit à 1, à 0, à une valeur |
| bit(3) | 1 << 3 → 8 |
| lowByte highByte | octet bas, haut : 0x1234 → 0x34, 0x12 |
| x & 0x0F | masque : garder les 4 bits bas |
| x |= (1 << 3) | forcer le bit 3 à 1 |
| x &= ~(1 << 3) | forcer le bit 3 à 0 |
| + - * / % | arithmétique ; 7 / 2 → 3 (entiers) ; 7 % 2 → 1 ; 7 / 2.0 → 3.5 |
| == != < > <= >= | comparaison |
| && || ! | et, ou, non (logique) |
| & | ^ ~ << >> | et, ou, ou exclusif, inversion, décalages (bit à bit) |
| = += -= *= /= |= | affectation, affectations combinées |
| ++ -- | ajouter, retirer 1 |
| c ? a : b | vaut a si c est vrai, sinon b |
if (t > 30) {
ventiler();
} else if (t < 18) {
chauffer();
} else {
arreter();
}
switch (mode) {
case 1: clignoter(); break;
case 2: fixe(); break;
default: eteindre();
}
for (int i = 0; i < 10; i++) { // 0…9
Serial.println(i);
}
while (digitalRead(2) == HIGH) {}switch : sans break, l’exécution continue dans le cas suivant !while vide : attendre l’appui (bloquant) ; do { … } while (…); fait au moins un tour.break sort d’une boucle ; continue passe au tour suivant ; return quitte la fonction.float celsius(float f) {
return (f - 32) * 5 / 9;
}
void clignoter(int b, int fois) {
for (int i = 0; i < fois; i++) {
digitalWrite(b, HIGH); delay(100);
digitalWrite(b, LOW); delay(100);
}
}
void echanger(int &a, int &b) {
int t = a; a = b; b = t;
}return renvoie la valeur : celsius(212) → 100 ; void : ne renvoie rien.& (référence), echanger(x, y) modifie bien x et y.int total = 0; // globale void loop() { int n = 0; // locale static int k = 0; // statique n++; // vaut toujours 1 k++; // 1, 2, 3… }
Globale : visible partout, existe tout le temps. Locale : visible dans son bloc { }, recréée à chaque passage. Statique : locale qui garde sa valeur d’un appel à l’autre. Locale non initialisée : valeur imprévisible !
int broches[] = {3, 5, 6, 9};
const int N = sizeof(broches)
/ sizeof(broches[0]); // 4
for (int i = 0; i < N; i++) {
pinMode(broches[i], OUTPUT);
}
char nom[8] = "Uno"; // + '\0' final
char txt[20];
snprintf(txt, sizeof(txt), "A0=%d",
analogRead(A0));
dtostrf(21.537, 5, 1, txt); → " 21.5"
String msg = "T = "; // pratique…
msg += 21.5; // …mais gourmandbroches[4] écrase la mémoire !snprintf() ne connaît pas %f sur AVR : convertir d’abord avec dtostrf() (valeur, largeur, décimales, tampon).String : length(), toInt(), toFloat(), indexOf(), substring(), trim()… À éviter dans un programme qui tourne longtemps sur 2 Ko de SRAM.| abs(-5) min(a, b) max(a, b) | valeur absolue → 5 ; plus petit, plus grand |
| pow(2, 10) sq(3) sqrt(2) | puissance → 1024.0 ; carré → 9 ; racine carrée |
| round(2.5) | arrondi → 3 |
| sin(PI / 2) | trigonométrie en radians → 1.0 ; DEG_TO_RAD convertit les degrés |
| (int)3.9 | → 3 : la conversion en entier tronque |
| (float)7 / 2 | → 3.5 : convertir avant de diviser |
| atoi("42") | texte → entier : 42 |
| String(42) | nombre → texte "42" |
Sur AVR, abs, min, max, sq sont des macros : ne pas y écrire i++ ou un appel de fonction, évalués deux fois !
int x = 1000 * 60; → −5536 : le calcul déborde d’un int 16 bits ; écrire 1000UL * 60 | |
unsigned long t = 60 * 1000; → 4294961760 : le calcul se fait en int avant la conversion | |
1 / 3 * 3.0 → 0 : 1 / 3 est une division entière | |
if (x = 5) affectation, toujours vraie : comparer avec == | |
if (x > 3); le ; termine le if : le bloc suivant s’exécute toujours | |
a == b (float) 9.0 / 0.3 ne vaut pas exactement 30 : tester fabs(a - b) < 0.001 | |
int t = millis(); faux au bout de 32,7 s : toujours unsigned long | |
digitalwrite(…) la casse compte : digitalWrite |
Messages du compilateur correspondants : p. 8 ; avertissements à activer (p. 1).
| delay(ms) | pause bloquante : plus rien ne se passe, sauf les interruptions |
delayMicroseconds(µs) pause courte, précise de 3 à 16 383 µs | |
| millis() | ms écoulées depuis le démarrage (unsigned long) ; repasse par 0 après ≈ 49,7 jours |
| micros() | µs ; par pas de 4 µs (16 MHz) ; repasse par 0 après ≈ 71,6 min |
| 1000 | 1 s (= 1 000 000 µs) |
| 60UL * 1000 | 1 min = 60 000 ms |
| 60UL * 60 * 1000 | 1 h = 3 600 000 ms |
| 24UL * 60 * 60 * 1000 | 1 jour = 86 400 000 ms |
Le suffixe UL sur le premier nombre fait tout le calcul en unsigned long (sinon débordement, p. 4).
unsigned long t0 = micros();
analogRead(A0); // code à mesurer
unsigned long duree = micros() - t0;const int LED = 13; const unsigned long PERIODE = 500; unsigned long precedent = 0; 1 bool etat = LOW; void setup() { pinMode(LED, OUTPUT); } void loop() { unsigned long t = millis(); if (t - precedent >= PERIODE) { 2 precedent = t; etat = !etat; digitalWrite(LED, etat); } 3 lire un bouton, un capteur… }
unsigned long ;millis() repasse par 0 : avec precedent = 4 294 967 000 et t = 204, la différence vaut 500. Ne pas écrire t >= precedent + PERIODE ! ;loop() n’attend jamais : elle tourne des milliers de fois par seconde et peut tout surveiller.unsigned long tLed = 0, tMesure = 0;
void loop() {
unsigned long t = millis();
if (t - tLed >= 250) { // 250 ms
tLed = t;
digitalWrite(13, !digitalRead(13));
}
if (t - tMesure >= 2000) { // 2 s
tMesure = t;
Serial.println(analogRead(A0));
}
}const int BOUTON = 2; // vers GND const unsigned long STABLE = 30; // ms int etatStable = HIGH, dernierLu = HIGH; unsigned long tChange = 0; bool appui() { // 1 fois par appui int lu = digitalRead(BOUTON); if (lu != dernierLu) { 1 dernierLu = lu; tChange = millis(); } if (millis() - tChange >= STABLE && lu != etatStable) { etatStable = lu; 2 return etatStable == LOW; } return false; } void setup() { pinMode(BOUTON, INPUT_PULLUP); Serial.begin(9600); } void loop() { if (appui()) Serial.println("Appui"); }
Clé en main : bibliothèque Bounce2.
enum Etat { VERT, ORANGE, ROUGE };
Etat etat = VERT;
unsigned long debut = 0;
void allumer(int b) { // 9, 10 ou 11
for (int p = 9; p <= 11; p++)
digitalWrite(p, p == b);
}
void changer(Etat nouveau) {
etat = nouveau;
debut = millis();
}
void setup() {
for (int p = 9; p <= 11; p++)
pinMode(p, OUTPUT);
}
void loop() {
unsigned long dt = millis() - debut;
switch (etat) {
case VERT:
allumer(9); 1
if (dt >= 5000) changer(ORANGE);
break;
case ORANGE:
allumer(10);
if (dt >= 1000) changer(ROUGE);
break;
case ROUGE:
allumer(11);
if (dt >= 4000) changer(VERT);
break;
}
}1 À chaque tour : agir selon l’état courant, puis tester les transitions (les if). Ajouter un bouton piéton = ajouter une transition, sans rien bloquer.
| Flash 32 Ko | le programme (0,5 Ko pour le chargeur), les constantes PROGMEM ; conservée hors tension |
| SRAM 2 Ko | variables, pile des appels, tas (String) ; effacée à l’arrêt |
| EEPROM 1 Ko | réglages à conserver ; 100 000 écritures par case, 3,3 ms chacune |
Après chaque compilation, l’IDE affiche :
Le croquis utilise n octets (p%) de l'espace de stockage de programmes. Le maximum est de 32256 octets. Les variables globales utilisent n octets (p%) de mémoire dynamique, ce qui laisse n octets pour les variables locales. Le maximum est de 2048 octets.
Au-delà de 75 % de SRAM : « La mémoire disponible faible, des problèmes de stabilité pourraient survenir. » (sic). La pile a besoin de la place restante : plantages aléatoires !
Serial.println(F("Texte en flash"));
const byte t[] PROGMEM = {1, 2, 4, 8};
byte v = pgm_read_byte(&t[2]); → 4F() pour tout texte fixe passé à print() ;byte plutôt qu’int) ;String et les grands tableaux ; un écran OLED 128 × 64 réserve 1 Ko (la moitié de la SRAM !).#include <EEPROM.h>
void setup() {
EEPROM.update(0, 42); // si différent
byte v = EEPROM.read(0); → 42
float c = 21.5;
EEPROM.put(10, c); // cases 10…13
EEPROM.get(10, c); // relecture
int n = EEPROM.length(); → 1024
}update() n’écrit que si la valeur change ; put(), get() : une variable entière (ici un float, 4 octets) ; case jamais écrite : 255.loop() !#include <avr/wdt.h>
void setup() {
wdt_enable(WDTO_2S); 1
}
void loop() {
wdt_reset(); 2
// … travail normal
}loop().Propre aux microcontrôleurs AVR (Uno R3, Nano, Mega). Des redémarrages en boucle sont signalés avec l’ancien chargeur d’amorçage de certains Nano : tester avant de s’y fier.
Serial.begin(9600) ouvrir à 9 600 bauds (bits/s) ; 115200 : 12 fois plus rapide | |
| Serial.print(x) | écrire en texte, sans retour à la ligne |
Serial.println(x) puis passer à la ligne ( \r\n) | |
Serial.print(78, HEX) → 4E ; BIN → 1001110 ; DEC par défaut | |
Serial.print(1.23456) → 1.23 : 2 décimales par défaut | |
Serial.print(1.23456, 4) → 1.2346 | |
| Serial.write(65) | envoyer l’octet brut 65 (le caractère A) |
Serial.print(F("…")) texte fixe laissé en flash | |
| Serial.flush() | attendre la fin de l’envoi |
while (!Serial) {} dans setup() pour ne rien perdre.void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop() {
if (Serial.available() > 0) { 1
String c =
Serial.readStringUntil('\n'); 2
c.trim(); 3
if (c == "on")
digitalWrite(13, HIGH);
else if (c == "off")
digitalWrite(13, LOW);
else
Serial.println("Inconnu : " + c);
}
}Serial.read() en lit un (−1 s’il n’y a rien) ;Serial.setTimeout()) ; Serial.parseInt() lit un nombre ;\r (fin de ligne « Les deux, NL et CR »).Serial.begin(), sinon caractères illisibles.\n) · Retour chariot (\r) · Les deux, NL et CR.nom: :Serial.print("temp:");
Serial.print(t);
Serial.print(",hum:");
Serial.println(h);
→ temp:21.50,hum:40.00Wire.setClock(400000) : 400 kHz. Fils courts (bus prévu pour l’intérieur d’un appareil).#include <Wire.h>
void setup() { // scanner I²C
Serial.begin(9600);
Wire.begin(); // pilote du bus
for (byte a = 8; a < 120; a++) {
Wire.beginTransmission(a); 1
if (Wire.endTransmission() == 0) {
Serial.print("Module en 0x");
Serial.println(a, HEX);
}
}
}
void loop() {}1 appel à l’adresse a ; endTransmission() renvoie 0 succès · 1 données trop longues (tampon de 32 octets) · 2 adresse sans réponse · 3 donnée refusée · 4 autre erreur · 5 délai dépassé.
Wire.beginTransmission(0x68); // module Wire.write(0x00); // registre Wire.endTransmission(false); // garder Wire.requestFrom(0x68, 3); // 3 octets while (Wire.available()) { byte b = Wire.read(); }
false : redémarrage sans libérer le bus, entre l’écriture du n° de registre et la lecture.
Adresses courantes, à vérifier sur le module : LCD à adaptateur PCF8574 0x27 ou 0x3F ; OLED SSD1306 0x3C ; BME280 0x76 ou 0x77 ; horloge DS3231 et MPU-6050 0x68.
#include <SoftwareSerial.h> SoftwareSerial gps(4, 3); // RX, TX void setup() { Serial.begin(9600); // vers le PC gps.begin(9600); // vers le module } void loop() { // relais if (gps.available()) Serial.write(gps.read()); }
Un seul port logiciel écoute à la fois (listen()) ; peu fiable à haut débit. Mega : ports matériels Serial1 à Serial3.
#include <SPI.h>
const int CS = 10;
void setup() {
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH); // libre
SPI.begin();
}
byte lire(byte reg) {
SPISettings r(1000000, MSBFIRST,
SPI_MODE0); 1
SPI.beginTransaction(r);
digitalWrite(CS, LOW); // sélection
SPI.transfer(reg);
byte v = SPI.transfer(0); 2
digitalWrite(CS, HIGH);
SPI.endTransaction();
return v;
}
void loop() {}| UART | TX et RX croisés ; 1 face à 1 ; 9 600 à 115 200 bauds ; GPS, Bluetooth HC-05, ordinateur |
| I²C | SDA, SCL ; plusieurs modules (adresses) ; 100 à 400 kHz ; écrans, capteurs, horloge |
| SPI | 3 fils + 1 CS par module ; plusieurs MHz ; carte SD, écran TFT, RFID |
| 1-Wire | 1 fil + tirage 4,7 kΩ ; plusieurs (n° unique) ; ≈ 15 kbit/s ; sonde DS18B20 |
UART : le TX de l’un va au RX de l’autre ; masse commune.
HIGH (seuil ≈ 3 V), marge faible.| capteur | liaison · outil |
|---|---|
| Potentiomètre, joystick | analogique · analogRead() |
| Photorésistance (LDR) | analogique, diviseur 10 kΩ · analogRead() |
| LM35, TMP36 (température) | analogique · calcul ci-dessous |
| DHT11, DHT22 (temp., humidité) | 1 fil propre au capteur · DHT sensor library |
| DS18B20 (température, étanche) | 1-Wire + 4,7 kΩ · OneWire, DallasTemperature |
| BME280 (pression, temp., hum.) | I²C ou SPI · Adafruit BME280 Library |
| HC-SR04 (distance) | 2 broches, Trig et Echo · pulseIn() |
| HC-SR501 (présence, PIR) | numérique · digitalRead() |
| Codeur rotatif | 2 broches + bouton · interruptions |
| DS3231 (horloge) | I²C · RTClib |
| RC522 (badges RFID) | SPI, 3,3 V ! · MFRC522 |
En italique : nom exact dans le gestionnaire de bibliothèques (p. 8).
int v = analogRead(A0); float mv = v * 5000.0 / 1024; // mV float tLM35 = mv / 10; // °C float tTMP36 = (mv - 500) / 10; // °C
LM35 : 10 mV/°C, 0 mV à 0 °C. TMP36 : 10 mV/°C, 500 mV à 0 °C (750 mV → 25 °C). Plus de finesse : analogReference(INTERNAL) (1,1 V) et 1100 au lieu de 5000.
#include <DHT.h> DHT dht(2, DHT22); // broche, modèle void setup() { Serial.begin(9600); dht.begin(); } void loop() { delay(2000); 1 float h = dht.readHumidity(); // % float t = dht.readTemperature(); // °C if (isnan(h) || isnan(t)) { 2 Serial.println("Erreur"); return; } Serial.print(t); Serial.print(" °C "); Serial.print(h); Serial.println(" %"); }
isnan() : « n’est pas un nombre », lecture ratée (câblage, broche).const int TRIG = 9, ECHO = 10;
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
void loop() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH); 1
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
unsigned long d =
pulseIn(ECHO, HIGH, 30000); 2
if (d > 0) {
float cm = d * 0.0343 / 2; 3
Serial.println(cm);
}
delay(100);
}| LED, LED RVB | digitalWrite, analogWrite + résistance |
| Buzzer | actif : digitalWrite · passif : tone() |
| Servomoteur (SG90…) | Servo ; ci-contre |
| Moteur à courant continu | pont en H : L298N, L293D, TB6612FNG |
| Pas à pas 28BYJ-48 | module ULN2003 ; Stepper, AccelStepper |
| Pas à pas NEMA 17 | pilote A4988 ou DRV8825 (STEP, DIR) ; AccelStepper |
| Relais | module avec transistor et diode ; secteur : danger ! |
| Ruban WS2812B | 1 fil de données ; Adafruit NeoPixel, FastLED |
| Écran LCD 16 × 2 | LiquidCrystal (6 fils) ; adaptateur I²C : 4 fils |
| Écran OLED 128 × 64 | I²C ; Adafruit SSD1306 + Adafruit GFX Library |
#include <Servo.h>
Servo bras;
void setup() {
bras.attach(9); 1
}
void loop() {
int v = analogRead(A0);
int angle = map(v, 0, 1023, 0, 180);
bras.write(angle); 2
delay(15);
}bras.writeMicroseconds(1500) : durée d’impulsion (544 à 2 400 µs par défaut pour 0 à 180°).Fils : rouge + 5 V, noir ou marron GND, jaune, orange ou blanc : commande. Un servo tire de fortes pointes de courant : au-delà d’un ou deux, alimentation séparée, masses reliées.
| IN1 ≠ IN2 | le moteur tourne ; on inverse les deux pour changer de sens |
| IN1 = IN2 | arrêt rapide (freinage) |
| EN à LOW | roue libre |
| EN en MLI | vitesse : analogWrite(EN, 0…255) |
const int EN = 5; // broche MLI const int IN1 = 7, IN2 = 8; void moteur(int v) { // -255 à 255 digitalWrite(IN1, v > 0); digitalWrite(IN2, v < 0); analogWrite(EN, min(abs(v), 255)); } void setup() { pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); moteur(-150); // recule } void loop() {}
Moteur alimenté à part, masses reliées. Module L298N : retirer le cavalier ENA pour régler la vitesse.
#include <LiquidCrystal.h> // RS, E, D4, D5, D6, D7 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { lcd.begin(16, 2); // taille lcd.print("Bonjour !"); } void loop() { lcd.setCursor(0, 1); // 2e ligne lcd.print(millis() / 1000); lcd.print(" s"); }
Contraste : potentiomètre de 10 kΩ sur V0 (écran vide ou rectangles pleins sinon). Pas d’accents dans le jeu de caractères d’origine. Version I²C (PCF8574) : bibliothèque « LiquidCrystal I2C », dont il existe plusieurs variantes : partir de l’exemple fourni.
#include <Adafruit_NeoPixel.h> // 30 LED, données sur la broche 6 Adafruit_NeoPixel ruban(30, 6, NEO_GRB + NEO_KHZ800); void setup() { ruban.begin(); ruban.setBrightness(50); // 0…255 } void loop() { // un point qui court for (int i = 0; i < 30; i++) { ruban.clear(); ruban.setPixelColor(i, ruban.Color(255, 0, 0)); // rouge ruban.show(); 1 delay(50); } }
1 rien ne change avant show(). Jusqu’à 60 mA par LED en blanc à pleine luminosité (1,8 A pour 30) : alimentation 5 V dédiée, masses reliées, condensateur de 500 à 1 000 µF sur l’alimentation, 300 à 500 Ω sur le fil de données.
| carte | puce | E/S | num. (MLI) · ana. | flash / RAM | particularités |
|---|---|---|---|---|---|
| Uno R3 | ATmega328P · 16 MHz | 5 V | 14 (6) · 6 | 32 Ko / 2 Ko | la référence ; USB-B |
| Uno R4 Minima | RA4M1 Arm · 48 MHz | 5 V | 14 (6) · 6 | 256 Ko / 32 Ko | CNA 12 bits, CAN jusqu’à 14 bits, bus CAN ; USB-C ; 8 mA/broche |
| Uno R4 WiFi | RA4M1 + ESP32-S3 | 5 V | 14 (6) · 6 | 256 Ko / 32 Ko | + Wi-Fi, Bluetooth, matrice de 12 × 8 LED |
| Nano | ATmega328 · 16 MHz | 5 V | 14 (6) · 8 | 32 Ko / 2 Ko | 18 × 45 mm, mini-USB |
| Nano Every | ATmega4809 · 20 MHz | 5 V | 22 (5) · 8 | 48 Ko / 6 Ko | format Nano, micro-USB |
| Nano ESP32 | ESP32-S3 · 240 MHz | 3,3 V | 14 · 8 | 16 Mo / 512 Ko | Wi-Fi, Bluetooth ; MLI sur toutes les broches (5 à la fois) |
| Mega 2560 | ATmega2560 · 16 MHz | 5 V | 54 (15) · 16 | 256 Ko / 8 Ko | 4 ports série matériels |
| Leonardo | ATmega32U4 · 16 MHz | 5 V | 20 (7) · 12 | 32 Ko / 2,5 Ko | USB natif : clavier, souris |
Caractéristiques : documentation officielle (docs.arduino.cc).
#include <Nom.h> en tête du croquis ; exemples dans Fichier › Exemples.EEPROM, SoftwareSerial, SPI, Wire. Officielles : Servo, LiquidCrystal, Stepper.| DHT sensor library | DHT11, DHT22 (demande Adafruit Unified Sensor) |
| OneWire + DallasTemperature | sondes DS18B20 |
| Adafruit NeoPixel · FastLED | rubans WS2812B |
| Adafruit SSD1306 | écrans OLED (demande Adafruit GFX Library) |
| RTClib · AccelStepper | horloges DS3231 · moteurs pas à pas |
| Bounce2 · MFRC522 | anti-rebond · lecteur RFID RC522 |
https://espressif.github.io/arduino-esp32/package_esp32_index.jsonSerial.println() : afficher valeurs et étapes franchies.| Compilation (Erreur de compilation) | |
'Led' was not declared in this scope | nom mal écrit, casse (Led ≠ led), variable déclarée dans un autre bloc |
expected ';' before '}' token | point-virgule oublié en fin de ligne |
expected '}' at end of input | accolade fermante manquante |
a function-definition is not allowed here before '{' token | fonction précédente non refermée |
'Servo' does not name a type | #include oublié |
Servomoteur.h: No such file or directory | bibliothèque non installée ou nom mal écrit |
redefinition of 'void setup()' | deux onglets définissent setup() |
stray '\302' in program | caractère invisible collé depuis une page web : retaper la ligne |
warning: integer overflow in expression | calcul trop grand pour un int (p. 4) |
| Téléversement (Failed uploading) | |
programmer is not responding · not in sync | mauvais port ou mauvaise carte ; quelque chose sur la broche 0 ; certains Nano : Outils › Processor › ATmega328P (Old Bootloader) |
cannot open port COM3 | port occupé par un autre logiciel, carte débranchée, mauvais port |
Toujours lire la première erreur : les suivantes en découlent souvent.
| Aucun port dans Outils › Port | câble de charge seule ; autre câble, autre prise USB ; pilote CH340 (clone) |
| Caractères illisibles | débit du moniteur ≠ Serial.begin() |
| Rien ne s’affiche | Serial.begin() oublié ; mauvais port ; USB natif : while (!Serial) |
| La LED reste éteinte | LED à l’envers ; pinMode oublié ; mauvaise broche |
| Lecture qui change seule | entrée flottante : INPUT_PULLUP ou résistance de tirage |
| Un appui compte plusieurs fois | rebonds : anti-rebond (p. 5) |
| Redémarre quand le moteur part | chute de tension : alimentation séparée, masse commune |
| Plante après des heures | SRAM épuisée (String), int qui déborde, millis() mal comparé |
| Module I²C muet | adresse (scanner p. 6), SDA et SCL inversés, alimentation 3,3 / 5 V |
arduino-cli core update-index
arduino-cli core install arduino:avr
arduino-cli board list # cartes et ports
arduino-cli compile --fqbn arduino:avr:uno Blink
arduino-cli upload -p COM3 --fqbn arduino:avr:uno Blink
arduino-cli lib install "DHT sensor library"
arduino-cli monitor -p COM3 --config 115200delay(), puis avec millis() (p. 5).