Bases · 17 min de lecture

Commandes Arduino : liste, syntaxe, exemples et erreurs

Commandes Arduino expliquées : pinMode, digitalWrite, analogRead, analogWrite, millis, Serial, map, tone, pulseIn et attachInterrupt, avec exemples et erreurs.

Les commandes Arduino sont des fonctions toutes prêtes qui disent à la carte quoi faire : pinMode() transforme une broche en sortie, digitalWrite() allume une LED, analogRead() lit un capteur et Serial.println() envoie un message à l'ordinateur. La plupart des programmes Arduino ne sont en réalité qu'une vingtaine de commandes de base combinées de différentes façons. Une fois que tu as bien compris ces commandes et leur signification, tu peux lire n'importe quel code, du clignotement d'une LED à la voiture robot, et écrire ton propre projet de zéro.

Dans ce guide, nous avons regroupé les commandes Arduino les plus utilisées en quatre catégories : entrées-sorties, temps, mathématiques et communication. Pour chaque commande, tu trouveras la syntaxe, la signification des paramètres, un court exemple qui compile et fonctionne sur un Arduino Uno, et l'erreur que les débutants commettent le plus souvent. Dans les dernières parties, nous verrons aussi comment ces mêmes commandes se comportent différemment sur l'ESP32 et quels sont leurs équivalents MicroPython sur le Raspberry Pi Pico.

Carte Arduino Uno avec ses broches numériques et analogiques
Arduino Uno : les broches numériques 0–13, les entrées analogiques A0–A5 et les broches PWM marquées d'un ~ suffisent pour tester toutes les commandes de cet article.

Qu'est-ce qu'une commande Arduino et comment un programme s'exécute-t-il ?

Le code Arduino repose sur le C/C++ ; la plupart de ce que l'on appelle des « commandes » sont en fait des fonctions que le cœur Arduino met à ta disposition. Une fonction reçoit des paramètres entre parenthèses (par exemple un numéro de broche et une valeur), et certaines renvoient un résultat : digitalRead() donne l'état d'une broche, millis() le temps écoulé. Chaque programme Arduino contient deux fonctions obligatoires : setup() ne s'exécute qu'une seule fois à la mise sous tension ou au reset de la carte, puis loop() se répète à l'infini. Les préparatifs comme le réglage des broches et Serial.begin() vont dans setup(), et ce qui doit se faire en continu va dans loop().

Arduino (C++)
1// Her Arduino programı bu iki fonksiyondan oluşur / Every Arduino sketch has these two functions
2void setup() {
3  // Açılışta ya da resetten sonra bir kez çalışır / Runs once at power-up or after reset
4  pinMode(13, OUTPUT);      // dahili LED pini çıkış / built-in LED pin as output
5}
6
7void loop() {
8  // Sonsuza kadar tekrar eder / Repeats forever
9  digitalWrite(13, HIGH);   // LED'i yak / turn the LED on
10  delay(500);               // 500 ms bekle / wait 500 ms
11  digitalWrite(13, LOW);    // LED'i söndür / turn the LED off
12  delay(500);
13}

Retenir trois règles dès le départ t'évite beaucoup d'erreurs de compilation : les commandes sont sensibles à la casse (si tu écris digitalwrite, tu obtiens l'erreur « 'digitalwrite' was not declared in this scope »), chaque instruction se termine par un point-virgule, et le texte s'écrit entre guillemets doubles alors qu'un caractère seul s'écrit entre apostrophes. Pour les types de variables et les structures comme if et for, jette un œil aux bases de la programmation Arduino.

Liste des commandes Arduino : tableaux par catégorie

Les quatre tableaux ci-dessous résument presque toutes les commandes que tu utiliseras dans tes projets de tous les jours. Le premier groupe rassemble les commandes d'entrées-sorties : elles définissent le rôle d'une broche, lui appliquent une tension ou y lisent une valeur. Tu peux voir les numéros de broches de ta carte dans l'outil Pinout.

CommandeSyntaxeÀ quoi elle sertExemple
pinModepinMode(broche, mode)Met une broche en entrée ou en sortiepinMode(13, OUTPUT);
digitalWritedigitalWrite(broche, valeur)Met une broche à HIGH (5 V) ou à LOW (0 V)digitalWrite(13, HIGH);
digitalReaddigitalRead(broche)Lit si une broche est à HIGH ou à LOWint b = digitalRead(2);
analogReadanalogRead(broche)Convertit une tension de 0–5 V en un nombre de 0 à 1023int v = analogRead(A0);
analogWriteanalogWrite(broche, valeur)Génère un signal PWM de 0 à 255analogWrite(9, 128);
analogReferenceanalogReference(type)Choisit la tension de référence d'analogReadanalogReference(INTERNAL);
tone / noTonetone(broche, fréquence, durée)Produit un son par signal carré ; noTone l'arrêtetone(8, 440, 500);
pulseInpulseIn(broche, valeur, délaiMax)Mesure la durée d'une impulsion en µspulseIn(10, HIGH, 30000);
shiftOutshiftOut(brocheDonnées, brocheHorloge, ordre, octet)Envoie un octet bit par bit (par exemple vers un 74HC595)shiftOut(11, 12, MSBFIRST, 255);
attachInterruptattachInterrupt(interruption, fonction, mode)Appelle une fonction dès qu'une broche changeattachInterrupt(digitalPinToInterrupt(2), say, FALLING);

Le deuxième groupe rassemble les commandes de temps. Comprendre la différence entre delay(), qui attend, et millis() ou micros(), qui mesurent le temps, est la clé d'un programme fluide.

CommandeSyntaxeÀ quoi elle sertAttention
delaydelay(ms)Attend le nombre de millisecondes indiquéLe programme s'arrête pendant ce temps
delayMicrosecondsdelayMicroseconds(us)Attend quelques microsecondesPrécis entre 3 et 16383 µs
millismillis()Renvoie les millisecondes écoulées depuis le démarrageunsigned long ; repart de zéro au bout d'environ 49,7 jours
microsmicros()Renvoie les microsecondes écoulées depuis le démarragePas de 4 µs sur l'Uno, débordement au bout d'environ 70 minutes

Le troisième groupe rassemble les commandes mathématiques ; elles servent à convertir une mesure de capteur vers une autre plage, à la limiter ou à générer un nombre aléatoire. Le quatrième groupe, celui des commandes de communication, permet à la carte d'échanger des données avec l'ordinateur et d'autres appareils.

CommandeSyntaxeÀ quoi elle sertExemple de résultat
mapmap(x, deMin, deMax, versMin, versMax)Convertit une plage en une autremap(512, 0, 1023, 0, 255) → 127
constrainconstrain(x, bas, haut)Maintient une valeur entre deux limitesconstrain(300, 0, 255) → 255
min / maxmin(a, b) / max(a, b)Renvoie la plus petite ou la plus grande valeurmin(7, 3) → 3
absabs(x)Valeur absolueabs(-12) → 12
pow / sqrt / sqpow(base, exposant), sqrt(x), sq(x)Puissance, racine carrée, carrépow(2, 10) → 1024.0
randomrandom(min, max)Entier aléatoire (max non inclus)random(1, 7) → de 1 à 6
randomSeedrandomSeed(graine)Change le point de départ de la suite aléatoirerandomSeed(analogRead(A3));
CommandeÀ quoi elle sertExemple
Serial.begin(vitesse)Ouvre le port série au débit en bauds indiquéSerial.begin(9600);
Serial.print(donnée)Affiche la donnée et reste sur la même ligneSerial.print(temperature);
Serial.println(donnée)Affiche la donnée et passe à la ligneSerial.println("Bonjour");
Serial.available()Renvoie le nombre d'octets en attente de lectureif (Serial.available() > 0)
Serial.read()Lit un octet, renvoie -1 s'il n'y a pas de donnéeschar c = Serial.read();
Serial.readStringUntil(c)Lit du texte jusqu'à un caractère donnéString s = Serial.readStringUntil('\n');
Serial.parseInt()Extrait un entier du texte reçuint n = Serial.parseInt();
Serial.write(octet)Envoie un octet brutSerial.write(65); // 'A'
Wire.begin()Démarre le bus I2C (Wire.h)Wire.begin();
SPI.begin()Démarre le bus SPI (SPI.h)SPI.begin();

pinMode() : définir le rôle d'une broche

pinMode(broche, mode) indique si une broche numérique est une entrée ou une sortie, et s'écrit généralement une seule fois dans setup(). Il existe trois modes : OUTPUT met la broche en sortie (pour piloter une LED, un buzzer ou un relais), INPUT en fait une entrée à haute impédance (pour les montages avec une résistance de pull-up ou de pull-down externe), et INPUT_PULLUP la met en entrée en reliant au 5 V une résistance interne d'environ 20–50 kΩ. Les broches analogiques (A0–A5) peuvent aussi servir de broches numériques avec pinMode ; par exemple, pinMode(A0, OUTPUT) est une commande valide.

Si tu oublies pinMode(broche, OUTPUT) et que tu utilises digitalWrite(broche, HIGH), la broche ne devient pas une sortie ; sur l'Uno, cette commande active seulement la résistance de pull-up interne. La LED s'allume, mais très faiblement, car le courant doit traverser une résistance de 20–50 kΩ. Si ta LED éclaire peu, la première chose à vérifier est la ligne pinMode dans setup().

digitalWrite() et digitalRead() : sortie et entrée numériques

digitalWrite(broche, HIGH) porte une broche de sortie à 5 V sur l'Uno, et digitalWrite(broche, LOW) la ramène à 0 V. Tirer jusqu'à 20 mA d'une broche ne pose pas de problème (le maximum absolu est de 40 mA) ; branche toujours une LED avec une résistance, dont tu peux trouver la valeur avec le calculateur de résistance pour LED. digitalRead(broche) regarde la tension sur la broche et renvoie HIGH ou LOW ; sur l'Uno, tout ce qui dépasse environ 3 V compte comme HIGH et tout ce qui est sous 1,5 V comme LOW. Dans l'exemple ci-dessous, la LED intégrée s'allume quand tu appuies sur le bouton-poussoir relié à D2 :

Arduino (C++)
1const int BUTON_PIN = 2;   // buton: bir ucu D2, diğer ucu GND / button: one leg to D2, the other to GND
2const int LED_PIN = 13;    // dahili LED / built-in LED
3
4void setup() {
5  pinMode(BUTON_PIN, INPUT_PULLUP);   // dahili pull-up direnci açık / internal pull-up resistor enabled
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  int durum = digitalRead(BUTON_PIN); // HIGH ya da LOW döner / returns HIGH or LOW
11  if (durum == LOW) {                 // pull-up ile basılı = LOW / with pull-up, pressed = LOW
12    digitalWrite(LED_PIN, HIGH);
13  } else {
14    digitalWrite(LED_PIN, LOW);
15  }
16}

Avec INPUT_PULLUP, la logique est inversée : bouton relâché, la broche lit HIGH grâce à la résistance interne ; bouton appuyé, elle lit LOW car elle est reliée à GND. Si tu branches le bouton sans résistance en mode INPUT, la broche reste flottante et digitalRead() renvoie des valeurs au hasard ; approcher la main peut même changer le résultat. Pour les rebonds et les bonnes façons de câbler un bouton, consulte comment brancher un bouton sur Arduino.

analogRead() et analogWrite() : lecture analogique et PWM

analogRead(broche) utilise un convertisseur 10 bits (CAN, ou ADC en anglais) pour transformer une tension de 0 à 5 V sur les broches A0–A5 en un nombre de 0 à 1023. Une lecture prend environ 100 µs, soit à peu près 10 000 mesures par seconde. Pour convertir le nombre en tension, on utilise valeur × 5,0 / 1023 ; une lecture de 512 correspond par exemple à environ 2,5 V. La tension de référence se change avec analogReference() : l'option INTERNAL utilise la référence interne de 1,1 V de l'Uno et améliore la résolution pour les petites tensions. Tous les détails sur la résolution et la référence sont dans CAN et conversion analogique-numérique.

Malgré son nom, analogWrite(broche, valeur) ne produit pas une vraie tension analogique. Elle allume et éteint la broche très rapidement pour créer un signal PWM : 0 signifie toujours éteint, 255 toujours allumé et 127 allumé à peu près la moitié du temps. C'est cette moyenne qui fait qu'une LED nous paraît à demi lumineuse et qu'un moteur tourne lentement. Sur l'Uno, seules les broches 3, 5, 6, 9, 10 et 11, marquées d'un ~ sur la carte, fournissent du PWM ; la fréquence est de 490 Hz sur la plupart d'entre elles et de 980 Hz sur les broches 5 et 6. analogWrite() met elle-même la broche en sortie, donc pinMode n'est pas obligatoire. Le code ci-dessous règle la luminosité d'une LED avec un potentiomètre et affiche la mesure avec la tension dans le moniteur série ; pour le rapport cyclique et la fréquence, consulte Qu'est-ce que le PWM ?.

Arduino (C++)
1const int POT_PIN = A0;   // potansiyometrenin orta bacağı / potentiometer wiper
2const int LED_PIN = 9;    // ~9 PWM pini + 220 ohm direnç / ~9 PWM pin + 220 ohm resistor
3
4void setup() {
5  Serial.begin(9600);
6}
7
8void loop() {
9  int ham = analogRead(POT_PIN);         // 0-1023 arası / between 0 and 1023
10  float volt = ham * (5.0 / 1023.0);     // sayıyı gerilime çevir / convert the reading to volts
11  analogWrite(LED_PIN, ham / 4);         // 0-1023 -> 0-255 PWM parlaklığı / 0-1023 -> 0-255 PWM brightness
12
13  Serial.print(F("Ham / raw: "));
14  Serial.print(ham);
15  Serial.print(F("  Gerilim / voltage: "));
16  Serial.print(volt, 2);                 // 2 ondalık basamak / 2 decimal places
17  Serial.println(F(" V"));
18  delay(200);
19}
Sur une broche sans PWM, analogWrite() ne peut pas produire de valeurs intermédiaires : elle met la broche à LOW pour les valeurs inférieures à 128 et à HIGH à partir de 128. Les broches A0–A5 de l'Uno ne font pas de PWM non plus, et l'Uno R3 classique n'a pas de vraie sortie analogique (CNA) ; écrire analogWrite(A0, 100) ne te donnera pas 2 V. Si tu as besoin d'une vraie tension analogique, utilise une carte dotée d'un CNA (comme l'Uno R4, qui en a un sur A0) ou ajoute un filtre RC sur une sortie PWM.

delay(), millis() et micros() : commandes de temps

delay(ms) attend le nombre de millisecondes indiqué et, pendant ce temps, aucune autre ligne de loop() ne s'exécute ; delay(1000) est une pause complète d'une seconde. Pour de courtes attentes de l'ordre de la microseconde, il existe delayMicroseconds(), précise entre 3 et 16383 µs. millis(), elle, n'attend pas : elle renvoie le temps écoulé depuis le démarrage de la carte, en millisecondes. Stocke toujours le résultat dans une variable de type unsigned long : avec un int, sur l'Uno, la valeur déborde dès qu'elle dépasse 32 767, soit au bout d'environ 33 secondes, et ta temporisation se dérègle. millis() repart de zéro environ tous les 49,7 jours ; la méthode par soustraction ci-dessous continue de fonctionner correctement même lors de ce débordement.

Arduino (C++)
1const int LED_PIN = 13;
2const unsigned long ARALIK = 500;   // yanıp sönme aralığı (ms) / blink interval (ms)
3unsigned long oncekiZaman = 0;      // son değişim anı / time of the last toggle
4
5void setup() {
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  unsigned long simdi = millis();
11  if (simdi - oncekiZaman >= ARALIK) {               // taşmada da doğru çalışır / safe across overflow
12    oncekiZaman = simdi;
13    digitalWrite(LED_PIN, !digitalRead(LED_PIN));    // LED'i tersine çevir / toggle the LED
14  }
15  // Burada buton, sensör ve ekran işleri de yapılabilir / button, sensor and display tasks can run here
16}

Avec ce modèle, loop() ne s'arrête jamais : pendant que la LED continue de clignoter, tu peux lire un bouton, mesurer un capteur et mettre à jour un écran dans la même boucle. micros() fonctionne de la même façon en microsecondes ; sur l'Uno, elle avance par pas de 4 µs et déborde au bout d'environ 70 minutes. Nous expliquons en détail comment exécuter plusieurs tâches à la fois dans Arduino millis() au lieu de delay().

Serial.begin(), Serial.print() et Serial.read() : communication série

Les commandes Serial permettent à l'Arduino de dialoguer avec ton ordinateur par le câble USB, et ce sont tes meilleurs outils de débogage. Serial.begin(9600) ouvre le port série à 9600 bits par seconde ; si la vitesse du moniteur série ne correspond pas, tu verras des caractères bizarres à l'écran. Serial.print() affiche la donnée et reste sur la même ligne, tandis que Serial.println() passe à la ligne après l'affichage. Un second paramètre permet de choisir le format : Serial.print(78, HEX) affiche « 4E », Serial.print(78, BIN) affiche « 1001110 » et Serial.print(3.14159, 3) affiche « 3.142 » (les nombres décimaux s'affichent par défaut avec 2 chiffres après la virgule). Écrire les textes fixes dans F("...") fait gagner de la place dans les 2 Ko de RAM de l'Uno.

Pour lire des données, tu vérifies d'abord avec Serial.available() si des octets attendent dans le tampon ; le tampon de réception de l'Uno fait 64 octets. Serial.read() prend un seul octet dans ce tampon et renvoie -1 s'il n'y a rien à lire. Le code ci-dessous allume et éteint la LED avec les caractères 1 et 0 que tu envoies depuis le moniteur série :

Arduino (C++)
1const int LED_PIN = 13;
2
3void setup() {
4  Serial.begin(9600);                    // Seri Monitör de 9600 olmalı / Serial Monitor must be 9600 too
5  pinMode(LED_PIN, OUTPUT);
6  Serial.println(F("1: LED açık / on, 0: LED kapalı / off"));
7}
8
9void loop() {
10  if (Serial.available() > 0) {          // tamponda bayt var mı? / any bytes waiting?
11    char c = Serial.read();              // ilk baytı al / read the first byte
12    if (c == '1') {                      // '1' karakteri, 1 sayısı değil / the character '1', not the number 1
13      digitalWrite(LED_PIN, HIGH);
14      Serial.println(F("LED açık / on"));
15    } else if (c == '0') {
16      digitalWrite(LED_PIN, LOW);
17      Serial.println(F("LED kapalı / off"));
18    }
19    // '\n' ve '\r' gibi diğer karakterler atlanır / other characters such as '\n' and '\r' are ignored
20  }
21}

Remarque que la comparaison se fait avec '1' (entre apostrophes, donc un caractère) : le 1 que tu tapes au clavier correspond au nombre 49 dans la table ASCII, c'est pourquoi la condition c == 1 n'est jamais vraie. Pour les nombres de plusieurs chiffres, tu peux utiliser Serial.parseInt(), et pour récupérer une ligne entière, Serial.readStringUntil('\n'). Pour les réglages de fin de ligne du moniteur série, le débit en bauds et le traceur série, consulte utiliser le moniteur série Arduino.

map() et constrain() : mettre à l'échelle et limiter des valeurs

map(valeur, deMin, deMax, versMin, versMax) fait passer un nombre d'une plage à une autre de façon proportionnelle. La formule derrière est : (x − deMin) × (versMax − versMin) / (deMax − deMin) + versMin. Par exemple, map(512, 0, 1023, 0, 255) donne 127 et non 127,6, car map() travaille uniquement avec des entiers et supprime la partie décimale. En inversant la plage d'arrivée, tu obtiens une relation inverse : map(x, 0, 1023, 255, 0). map() ne limite pas le résultat ; si l'entrée sort de la plage indiquée, la sortie en sort aussi. C'est pourquoi on l'associe le plus souvent à constrain(x, bas, haut).

Arduino (C++)
1const int LDR_PIN = A0;   // LDR + 10k gerilim bölücü / LDR + 10k voltage divider
2const int LED_PIN = 9;    // ~9 PWM pini / ~9 PWM pin
3
4void setup() {
5  pinMode(LED_PIN, OUTPUT);
6}
7
8void loop() {
9  int isik = analogRead(LDR_PIN);           // odada ölçülen aralık ~200-800 / measured range in the room ~200-800
10  int pwm = map(isik, 200, 800, 255, 0);    // karanlıkta parlak, aydınlıkta sönük / bright in the dark, dim in the light
11  pwm = constrain(pwm, 0, 255);             // aralık dışı değerleri kes / clip out-of-range values
12  analogWrite(LED_PIN, pwm);
13  delay(20);
14}

Dans cet exemple, la LDR donne des valeurs entre 200 et 800 dans la pièce. Si la mesure tombe à 100 la nuit, map() calcule 297 ; sans constrain(), analogWrite() recevrait cette valeur hors de la plage 0–255. Sur l'Uno, une telle valeur donne des résultats différents et inattendus selon la broche : sur les broches 3, 5, 6 et 11, qui utilisent des timers 8 bits, 297 déborde et se comporte comme 41, si bien que la LED s'éteint presque en pleine obscurité au lieu de briller fort. Comme constrain(), min(), max() et abs() sont définies comme des macros sur l'Uno, ne mets pas x++ ni un autre appel de fonction entre les parenthèses : l'expression peut être évaluée plusieurs fois et donner des résultats inattendus. Pour le câblage de la LDR, consulte capteur de lumière LDR.

tone() et noTone() : produire un son avec un buzzer

tone(broche, fréquence, durée) génère sur une broche un signal carré avec un rapport cyclique de 50 % et fait sonner un buzzer passif ou un petit haut-parleur à cette fréquence. La durée s'exprime en millisecondes et elle est facultative ; sans elle, le son continue jusqu'à ce que tu appelles noTone(broche). Un détail important : tone() n'attend pas, elle lance le son et passe aussitôt à la ligne suivante. Pour jouer des notes à la suite, il te faut donc un delay() au moins aussi long que la note après chaque appel à tone(), sinon tu n'entends que la dernière.

Arduino (C++)
1const int BUZZER_PIN = 8;   // pasif buzzer'ın + ucu / passive buzzer + leg
2
3void setup() {
4  int notalar[] = {262, 294, 330, 349, 392};   // Do Re Mi Fa Sol (Hz) / C D E F G (Hz)
5  for (int i = 0; i < 5; i++) {
6    tone(BUZZER_PIN, notalar[i], 200);         // 200 ms çal / play for 200 ms
7    delay(250);                                // tone() beklemez, sen bekle / tone() does not wait, so you do
8  }
9  noTone(BUZZER_PIN);                          // sesi kapat / stop the sound
10}
11
12void loop() {
13}
  • Limites de fréquence : Sur l'Uno, impossible de générer un son en dessous de 31 Hz, et la limite haute est de 65 535 Hz ; avec un buzzer, la plage utile va d'environ 100 à 5000 Hz.
  • Un seul son : Une seule broche peut jouer un son à la fois ; pour en jouer un sur une autre broche, tu dois d'abord arrêter le précédent avec noTone().
  • Conflit avec le PWM : Sur l'Uno, tone() utilise le Timer2, donc analogWrite() sur les broches 3 et 11 est perturbé pendant qu'un son est joué.
  • Buzzer actif : Comme il possède son propre oscillateur, sa fréquence ne peut pas être changée avec tone() ; il suffit de l'allumer et de l'éteindre avec digitalWrite(). Les différences sont expliquées dans Qu'est-ce qu'un buzzer ?.

pulseIn() : mesurer la durée d'une impulsion

pulseIn(broche, HIGH) attend que la broche passe à HIGH, mesure combien de temps elle y reste et renvoie le résultat en microsecondes ; elle peut mesurer des impulsions de 10 µs à 3 minutes. Son usage le plus connu est le capteur de distance à ultrasons HC-SR04 : le capteur fournit une impulsion aussi longue que le temps d'aller-retour du son. Le son se propage dans l'air à environ 343 m/s, soit 0,0343 cm/µs ; comme le trajet est un aller-retour, distance = durée × 0,0343 / 2.

Arduino (C++)
1const int TRIG_PIN = 9;
2const int ECHO_PIN = 10;
3
4void setup() {
5  Serial.begin(9600);
6  pinMode(TRIG_PIN, OUTPUT);
7  pinMode(ECHO_PIN, INPUT);
8}
9
10void loop() {
11  digitalWrite(TRIG_PIN, LOW);
12  delayMicroseconds(2);
13  digitalWrite(TRIG_PIN, HIGH);            // 10 µs tetik darbesi / 10 µs trigger pulse
14  delayMicroseconds(10);
15  digitalWrite(TRIG_PIN, LOW);
16
17  unsigned long sure = pulseIn(ECHO_PIN, HIGH, 30000UL);   // en fazla 30 ms bekle / wait at most 30 ms
18  if (sure == 0) {
19    Serial.println(F("Menzil dışı / out of range"));
20  } else {
21    float mesafe = sure * 0.0343 / 2.0;    // ses hızı 343 m/s, gidiş-dönüş / speed of sound 343 m/s, round trip
22    Serial.print(mesafe, 1);
23    Serial.println(F(" cm"));
24  }
25  delay(100);
26}

Le troisième paramètre, le délai maximal (timeout), est très important. Sans lui, pulseIn() attend 1 seconde quand aucune impulsion n'arrive et renvoie 0 ; si le fil du capteur se débranche, tout le programme se fige une seconde à chaque tour de boucle. Un timeout de 30000 µs correspond à environ 5 mètres, ce qui suffit pour les 4 mètres de portée du HC-SR04. Pour le câblage et la précision du capteur, consulte capteur de distance HC-SR04.

attachInterrupt() : réagir instantanément avec les interruptions

attachInterrupt(digitalPinToInterrupt(broche), fonction, mode) exécute la fonction que tu lui donnes à l'instant même où une broche change, quoi que loop() soit en train de faire. Cette fonction s'appelle une routine de service d'interruption (ISR). Le mode peut prendre quatre valeurs : RISING se déclenche au passage de LOW à HIGH, FALLING au passage de HIGH à LOW, CHANGE à chaque changement et LOW tant que la broche reste à LOW. Sur l'Uno et la Nano, seules les broches D2 et D3 peuvent déclencher une interruption de cette façon ; sur la Mega, tu peux utiliser les broches 2, 3, 18, 19, 20 et 21. C'est idéal pour ne rater ni un encodeur qui tourne vite, ni les impulsions d'un anémomètre, ni un appui très bref sur un bouton.

Arduino (C++)
1const int BUTON_PIN = 2;            // Uno'da kesme pinleri: 2 ve 3 / interrupt pins on the Uno: 2 and 3
2volatile unsigned long sayac = 0;   // ISR'de değişen değişken volatile olmalı / variables changed in an ISR must be volatile
3
4void say() {                        // kesme fonksiyonu (ISR): kısa tut / interrupt service routine: keep it short
5  sayac++;
6}
7
8void setup() {
9  Serial.begin(9600);
10  pinMode(BUTON_PIN, INPUT_PULLUP);
11  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), say, FALLING);   // HIGH'dan LOW'a geçişte / on a HIGH-to-LOW edge
12}
13
14void loop() {
15  noInterrupts();                   // 4 baytlık değeri güvenle kopyala / copy the 4-byte value safely
16  unsigned long kopya = sayac;
17  interrupts();
18
19  Serial.print(F("Basma sayısı / presses: "));
20  Serial.println(kopya);
21  delay(500);
22}
Déclare en volatile toute variable que tu modifies dans une ISR et garde la fonction aussi courte que possible. Dans une ISR, delay() ne fonctionne pas, millis() n'avance pas et Serial.print() peut bloquer le programme ; mets simplement à jour un drapeau ou un compteur et fais le vrai travail dans loop(). Les boutons mécaniques rebondissent, le compteur peut donc augmenter plusieurs fois pour un seul appui ; la solution aux rebonds et tous les détails sur les interruptions sont dans les interruptions Arduino.

random() et randomSeed() : générer des nombres aléatoires

random(max) renvoie un entier aléatoire entre 0 et max−1, et random(min, max) un entier entre min et max−1 ; la borne supérieure n'est pas incluse dans le résultat. Pour un dé de 1 à 6, on écrit donc random(1, 7). L'Arduino ne produit pas de vrai hasard : il calcule une suite de nombres avec une formule fixe, et si tu n'appelles pas randomSeed(), tu verras les mêmes nombres dans le même ordre à chaque démarrage de la carte. Utiliser comme graine le bruit d'une broche analogique non connectée règle le problème en pratique :

Arduino (C++)
1void setup() {
2  Serial.begin(9600);
3  randomSeed(analogRead(A3));     // boştaki A3 pininin gürültüsü / noise from the unconnected A3 pin
4}
5
6void loop() {
7  int zar = random(1, 7);         // 1-6 arası; üst sınır dahil değil / 1 to 6; the upper bound is exclusive
8  Serial.print(F("Zar / dice: "));
9  Serial.println(zar);
10  delay(1000);
11}

Les commandes Arduino sur l'ESP32 : à quoi faire attention

L'ESP32 se programme dans l'IDE Arduino avec les mêmes commandes, et la plupart des codes de cet article fonctionnent directement une fois les numéros de broches modifiés. Mais comme le matériel est différent, certaines commandes se comportent autrement. La différence la plus importante est la tension : les broches de l'ESP32 fonctionnent en 3,3 V, digitalWrite(broche, HIGH) fournit 3,3 V, et il ne faut pas relier directement des signaux 5 V aux broches. Pour mieux connaître la carte, consulte Qu'est-ce que l'ESP32 ?.

CommandeArduino UnoESP32
digitalWrite(broche, HIGH)5 V3,3 V
analogRead()10 bits, 0–1023, A0–A512 bits, 0–4095 ; Wi-Fi actif, seulement les broches ADC1 (GPIO 32–39)
analogWrite()Uniquement les broches ~ (3, 5, 6, 9, 10, 11), 490/980 HzPresque tous les GPIO capables de sortie ; fréquence via ledcAttach(broche, fréquence, résolution)
attachInterrupt()Uniquement D2 et D3Tous les GPIO ; on ajoute IRAM_ATTR à l'ISR
tone()Utilise le Timer2, perturbe le PWM sur 3 et 11Fonctionne avec le périphérique LEDC
Serial.begin()Généralement 9600Généralement 115200 (les messages de démarrage utilisent aussi cette vitesse)
delay()Bloque complètement le processeurRend la main à FreeRTOS ; le Wi-Fi continue de tourner en arrière-plan
Arduino (C++)
1const int POT_PIN = 34;     // ADC1 pini, Wi-Fi açıkken de okur / ADC1 pin, works with Wi-Fi on
2const int LED_PIN = 2;      // çoğu DevKit'te dahili LED / onboard LED on most DevKits
3const int BUTON_PIN = 4;    // butonun diğer ucu GND / other button leg to GND
4
5volatile bool basildi = false;
6
7void IRAM_ATTR butonISR() { // ESP32'de ISR IRAM'e yerleşmeli / on the ESP32 the ISR should live in IRAM
8  basildi = true;
9}
10
11void setup() {
12  Serial.begin(115200);
13  pinMode(BUTON_PIN, INPUT_PULLUP);
14  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), butonISR, FALLING);   // her GPIO kesme destekler / every GPIO supports interrupts
15}
16
17void loop() {
18  int ham = analogRead(POT_PIN);                     // 0-4095 (12 bit)
19  analogWrite(LED_PIN, map(ham, 0, 4095, 0, 255));   // 8 bit PWM / 8-bit PWM
20  if (basildi) {
21    basildi = false;
22    Serial.println("Butona basıldı / button pressed");
23  }
24  Serial.println(ham);
25  delay(200);
26}

Comme analogRead() renvoie des valeurs de 0 à 4095 sur l'ESP32, la plage de map() change en conséquence. Le mot-clé IRAM_ATTR devant l'ISR place le code dans la mémoire interne rapide ; sans lui, la carte peut dans certains cas redémarrer avec une « Guru Meditation Error ». Les mesures analogiques de l'ESP32 ne sont pas linéaires près des extrémités de la plage (autour de 0 V et de 3,3 V) ; si tu as besoin d'une mesure plus précise, la fonction analogReadMilliVolts() renvoie une valeur calibrée en millivolts.

Raspberry Pi Pico : les équivalents MicroPython des commandes Arduino

Si tu programmes le Raspberry Pi Pico avec l'IDE Arduino (cœur arduino-pico), toutes les commandes de cet article fonctionnent sous le même nom ; analogRead() renvoie 10 bits par défaut et analogWrite() produit un PWM à 1 kHz. Le Pico s'utilise toutefois surtout avec MicroPython. Les commandes s'y écrivent avec des objets des modules machine et time ; la logique reste la même, seule la syntaxe change. Les broches du Pico sont elles aussi en 3,3 V, et ses entrées analogiques sont les broches GP26, GP27 et GP28. Pour commencer, consulte Qu'est-ce que le Raspberry Pi Pico ?.

Commande ArduinoÉquivalent MicroPythonRemarque
pinMode(15, OUTPUT)led = Pin(15, Pin.OUT)L'objet Pin se crée une seule fois
pinMode(14, INPUT_PULLUP)btn = Pin(14, Pin.IN, Pin.PULL_UP)Résistance de pull-up interne
digitalWrite(15, HIGH)led.value(1)led.on() fonctionne aussi
digitalRead(14)btn.value()Renvoie 0 ou 1
analogRead(A0)ADC(26).read_u16()Renvoie de 0 à 65535
analogWrite(15, 128)PWM(Pin(15)).duty_u16(32768)Rapport cyclique de 0 à 65535
delay(500)time.sleep_ms(500)time.sleep(0.5) fonctionne aussi
millis()time.ticks_ms()Pour les écarts, time.ticks_diff()
Serial.println(x)print(x)S'affiche dans la console de Thonny
tone(broche, 440)pwm.freq(440) et pwm.duty_u16(32768)Pour couper le son, duty_u16(0)
pulseIn(broche, HIGH, 30000)machine.time_pulse_us(broche, 1, 30000)Renvoie une valeur négative en cas de timeout
attachInterrupt(...)btn.irq(trigger=Pin.IRQ_FALLING, handler=f)f reçoit l'objet broche en paramètre
random(1, 7)random.randint(1, 6)La borne supérieure est incluse
map() / constrain()Pas intégrées, tu les écris toi-mêmePour constrain : min(max(x, 0), 255)
MicroPython
1from machine import Pin, ADC, PWM
2import time
3
4led = PWM(Pin(15))                       # pinMode + analogWrite karşılığı / pinMode + analogWrite equivalent
5led.freq(1000)                           # 1 kHz PWM
6buton = Pin(14, Pin.IN, Pin.PULL_UP)     # INPUT_PULLUP karşılığı / INPUT_PULLUP equivalent
7pot = ADC(26)                            # GP26 = ADC0
8
9def map_deger(x, giris_min, giris_max, cikis_min, cikis_max):   # Arduino map() karşılığı / Arduino map() equivalent
10    return (x - giris_min) * (cikis_max - cikis_min) // (giris_max - giris_min) + cikis_min
11
12onceki = time.ticks_ms()                 # millis() karşılığı / millis() equivalent
13while True:
14    ham = pot.read_u16()                 # 0-65535 (analogRead)
15    led.duty_u16(ham)                    # parlaklık / brightness (analogWrite)
16    if buton.value() == 0:               # digitalRead; basılı = 0 / pressed = 0
17        print("Butona basıldı / button pressed")
18    if time.ticks_diff(time.ticks_ms(), onceki) >= 1000:   # saniyede bir / once a second
19        onceki = time.ticks_ms()
20        print("Yüzde / percent:", map_deger(ham, 0, 65535, 0, 100))
21    time.sleep_ms(50)                    # delay(50)

Comme le montre le tableau, random.randint(1, 6) en MicroPython inclut la borne supérieure et donne le même résultat que random(1, 7) sur Arduino ; time.ticks_diff() offre la même protection contre le débordement que la soustraction avec millis(). Ce sont justement ces petites différences qui sèment le plus de confusion quand on passe d'une plateforme à l'autre. Pour les autres commandes de base de MicroPython, jette un œil aux bases de MicroPython.

Idées de projets avec ces commandes

  • Feu tricolore : Allume trois LED l'une après l'autre avec pinMode(), digitalWrite() et delay() ; nous l'expliquons pas à pas dans feu tricolore avec Arduino.
  • Dé électronique : Génère un nombre de 1 à 6 avec random() et, à l'appui sur le bouton, affiche le résultat avec des LED ou sur un afficheur 7 segments.
  • Radar de recul : Mesure la distance avec pulseIn(), transforme-la en intervalle de bips avec map() et émets une alerte sonore avec tone().
  • Veilleuse automatique : Lis la lumière avec analogRead() et règle la luminosité d'analogWrite() avec map() et constrain().
  • Télécommande par port série : Pilote une LED, un relais ou un servomoteur avec des ordres envoyés depuis l'ordinateur grâce à Serial.read().
  • Test de réflexes : Allume une LED à un moment aléatoire avec random() et mesure ton temps de réaction à la milliseconde près avec attachInterrupt() et millis().

Erreurs fréquentes et solutions

ErreurSymptômeSolution
pinMode() oubliéLa LED éclaire très faiblement ou pas du toutÉcris pinMode(broche, OUTPUT) dans setup()
Bouton sans résistance en mode INPUTdigitalRead() renvoie des 0 et des 1 au hasardUtilise INPUT_PULLUP ; appuyé se lit LOW
Faute de frappe dans le nom de la commande'digitalwrite' was not declared in this scopeRespecte les majuscules et minuscules : digitalWrite
Débit en bauds différentCaractères bizarres dans le moniteur sérieRègle le moniteur série sur la même vitesse que Serial.begin()
analogWrite() sur une broche sans PWMLa LED est seulement allumée à fond ou éteinteUtilise une broche marquée ~ (3, 5, 6, 9, 10, 11)
millis() stocké dans un intLa temporisation se dérègle au bout d'environ 33 secondesUtilise unsigned long
Dé avec random(1, 6)Le 6 ne sort jamaisÉcris random(1, 7) ; la borne supérieure est exclue
Attendre des décimales de map()Le résultat est toujours entier, les petites variations disparaissentSi besoin, écris ta propre formule en float
pulseIn() sans timeoutSans capteur, chaque tour de boucle se fige 1 secondePasse 30000 en troisième paramètre
delay() ou Serial dans une ISRLe programme se bloque ou se comporte bizarrementDans l'ISR, change seulement un drapeau volatile
Si tu n'es pas sûr de ce que fait exactement une commande, écris un petit programme de test et affiche le résultat avec Serial.println() ; dans l'IDE Arduino 2, tu peux aussi faire un clic droit sur le nom de la commande et choisir « Aller à la définition » pour voir son code source. Si ton code ne compile pas, la première ligne du message d'erreur indique généralement où se trouve le problème ; les messages les plus courants et leurs solutions sont dans erreurs de compilation Arduino.

Les commandes de cet article sont les briques de base de la plupart des projets que tu réaliseras avec un Arduino ; le reste, ce sont surtout des fonctions supplémentaires apportées par les bibliothèques. Tester chaque commande une fois dans son propre petit montage et voir le résultat dans le moniteur série te permet de retenir bien mieux qu'en apprenant par cœur. Dans l'application BlueGrays, tu trouveras pas à pas, avec schémas de câblage et code commenté, des projets qui utilisent ces commandes, comme allumer une LED, commander une LED avec un bouton, mesurer la lumière avec une LDR, régler la fréquence d'un buzzer, mesurer une distance avec le HC-SR04 et un projet de dé.

Questions fréquentes

Quelles sont les commandes Arduino les plus utilisées ?

Les plus courantes sont pinMode(), digitalWrite(), digitalRead(), analogRead(), analogWrite(), delay(), millis(), Serial.begin() et Serial.println(). Ajoute map() pour mettre des valeurs à l'échelle, tone() pour le son, pulseIn() pour les capteurs de distance et attachInterrupt() pour les interruptions, et tu peux écrire presque tous tes projets de débutant.

Dans quel langage s'écrivent les commandes Arduino ?

Le code Arduino repose sur le C et le C++ ; le cœur Arduino ajoute au langage des fonctions toutes prêtes comme pinMode() et digitalWrite(). Les commandes sont en anglais, sensibles à la casse, et chaque instruction se termine par un point-virgule. L'ESP32 et le Raspberry Pi Pico peuvent aussi se programmer en MicroPython si tu préfères.

Quelle est la différence entre digitalWrite et analogWrite ?

digitalWrite() met une broche dans l'un de deux états seulement : HIGH (5 V sur l'Uno) ou LOW (0 V). analogWrite() allume et éteint la broche très vite pour créer un signal PWM de 0 à 255, ce qui permet de régler la luminosité d'une LED ou la vitesse d'un moteur. Sur l'Uno, analogWrite() ne fonctionne que sur les broches marquées d'un ~.

Que signifient void setup et void loop ?

setup() est la fonction qui s'exécute une fois à la mise sous tension ou au reset de la carte ; on y place les préparatifs comme pinMode() et Serial.begin(). loop() est la fonction qui se répète sans fin une fois setup() terminée. Le mot void placé devant indique que ces fonctions ne renvoient aucune valeur.

Quelle est la différence entre Serial.print et Serial.println ?

Serial.print() affiche la donnée et laisse le curseur sur la même ligne, si bien que la donnée suivante s'ajoute juste à côté. Serial.println() envoie ensuite les caractères de fin de ligne (\r\n), donc la donnée suivante commence sur une nouvelle ligne. Pour afficher plusieurs valeurs côte à côte sur une ligne, on utilise d'abord print(), puis println() à la fin.

À quoi sert la fonction map d'Arduino ?

map() convertit proportionnellement un nombre d'une plage vers une autre ; par exemple, elle transforme la valeur 0–1023 d'analogRead() en plage 0–255 pour analogWrite() ou en 0–180 degrés pour un servo. Elle ne travaille qu'avec des entiers et ne limite pas le résultat, il est donc conseillé de l'associer à constrain() pour gérer les entrées hors plage.

Voir tous les projets
Clignotement d'une LED
#1Débutant

Clignotement d'une LED

Projet d'entrée basique qui allume et éteint une seule LED à certains intervalles avec Arduino. Enseigne l'utilisation des fonctions digitalWrite et delay.

4.6(171)
903
Allumer une LED avec un bouton-poussoir (Push)
#9Débutant

Allumer une LED avec un bouton-poussoir (Push)

Projet de commande instantanée (push) qui allume la LED lorsque le bouton est pressé et l'éteint lorsqu'il est relâché. Enseigne l'utilisation de la lecture de bouton et de l'expression conditionnelle

4.9(112)
190
Mesurer l'intensité lumineuse avec une LDR
#11Débutant

Mesurer l'intensité lumineuse avec une LDR

Projet qui mesure l'intensité de la lumière ambiante à l'aide d'un capteur LDR et l'affiche sur un moniteur série. Enseigne les bases de la lecture de capteurs analogiques et de la communication série

4.6(78)
124
Réglage de la fréquence avec buzzer
#14Intermédiaire

Réglage de la fréquence avec buzzer

Projet interactif avec 4 boutons qui permettent d'augmenter et de diminuer la fréquence du buzzer, de l'allumer et de l'éteindre. Enseigne la lecture de plusieurs boutons et le contrôle variable.

4.6(68)
112
HC-SR04 Mesure de la distance (affichage en série)
#27Débutant

HC-SR04 Mesure de la distance (affichage en série)

Le capteur ultrasonique HC-SR04 permet de mesurer la distance et d'afficher le résultat en cm sur le moniteur série. Il enseigne le principe du calcul de la distance à l'aide d'une onde sonore.

4.6(44)
66
Chenillard K2000 à vitesse réglable
#8Intermédiaire

Chenillard K2000 à vitesse réglable

Projet avec potentiomètre qui peut ajuster la vitesse de l'animation LED K2000 en temps réel. Il combine une entrée analogique et un contrôle en boucle bidirectionnel.

4.5(59)
115
Utilisation d'un servomoteur avec un potentiomètre
#36Débutant
Premium

Utilisation d'un servomoteur avec un potentiomètre

Projet qui contrôle le moteur servo en temps réel en convertissant la valeur du potentiomètre dans la plage 0-180°. apprend la fonction map() et l'intégration analogique-servo.

4.6(37)
51
Projet de dé électronique
#79Intermédiaire
Premium

Projet de dé électronique

Projet de dé qui génère un nombre aléatoire entre 1 et 6 à chaque pression sur le bouton et l'affiche sur un écran à 7 segments. Grâce au mécanisme de rebond, un seul résultat est produit en une seule

5.0(48)
67