Guides · 24 min de lecture

ESP32 Brownout Detector was triggered : causes et solutions

ESP32 Brownout detector was triggered et redémarrages en boucle : alimentation, câble, condensateur, codes rst, Guru Meditation, Task WDT et Exception Decoder.

Le message ESP32 Brownout detector was triggered signifie que la tension d'alimentation de la carte est passée un instant sous une limite sûre et que la puce a redémarré pour se protéger. Le problème ne vient presque jamais du code, mais de l'alimentation : un port USB faible, un câble fin et long, un régulateur trop juste, ou des servos et des rubans LED alimentés par la même ligne que l'ESP32. La deuxième grande raison pour laquelle un ESP32 redémarre sans arrêt, ce sont les plantages logiciels ; dans ce cas le moniteur série affiche des lignes comme Guru Meditation Error, task_wdt ou Stack canary.

La bonne nouvelle : l'ESP32 te dit lui-même pourquoi il a redémarré, à condition de savoir lire ses messages. Dans ce guide, tu vas d'abord apprendre à reconnaître les codes rst des lignes de démarrage et les messages d'erreur, puis régler le brownout pour de bon grâce à l'alimentation, au câble et à un condensateur. Ensuite, nous verrons les erreurs Guru Meditation comme LoadProhibited et StoreProhibited, le débordement de pile, les pointeurs nuls et les délais du watchdog, et tu remonteras un plantage jusqu'à la ligne de code avec ESP Exception Decoder. Pour finir, nous regarderons les broches de strapping (GPIO0, 2, 12 et 15) qui peuvent perturber le démarrage.

Carte de développement ESP32 DevKit
Carte de développement ESP32 : les 5 V de l'USB sont abaissés à 3,3 V par le régulateur de la carte. La plupart des problèmes de brownout viennent de chutes brèves sur cette ligne 3,3 V.

Pourquoi l'ESP32 redémarre-t-il sans arrêt ? Lis d'abord le message

Avant de commencer le diagnostic, ouvre le moniteur série à 115200 bauds et appuie sur le bouton EN de la carte. À chaque démarrage, le chargeur d'amorçage en ROM de l'ESP32 affiche d'abord une ligne de date comme "ets Jun 8 2016 00:22:57", puis une ligne du type rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT). La partie rst indique pourquoi la carte a redémarré, la partie boot dans quel mode elle a démarré. Si la carte tourne en boucle, tu trouveras juste au-dessus de ces lignes le message d'erreur, les dernières paroles de l'exécution précédente. Le tableau résume les messages que tu verras et par où commencer :

Ce que tu vois dans le moniteur sérieSignificationOù chercher
Brownout detector was triggeredLa tension d'alimentation est passée sous le seuilAlimentation, câble, condensateur
Guru Meditation Error: Core 1 panic'ed (LoadProhibited)Le code a voulu lire à une adresse invalidePointeur nul, limites d'un tableau
Guru Meditation Error: Core 1 panic'ed (StoreProhibited)Le code a voulu écrire à une adresse invalidePointeur nul, tampon qui déborde
Stack canary watchpoint triggered (loopTask)La pile (stack) d'une tâche est pleineGrands tableaux locaux, récursivité
task_wdt: Task watchdog got triggeredUne tâche n'a pas libéré le processeur pendant plus de 5 secondesBoucles sans pause, tâches bloquées
Interrupt wdt timeout on CPU0 / CPU1Une interruption ou des interruptions désactivées ont dépassé 300 msISR trop longue, Serial dans une ISR
boot:0x3 (DOWNLOAD_BOOT...) waiting for downloadLa carte a démarré en mode programmationGPIO0 à LOW au démarrage
invalid header ou flash read errLa mémoire flash n'a pas pu être lueGPIO12 à HIGH au démarrage, téléversement interrompu

Que signifie "Brownout detector was triggered" et d'où vient-il ?

Un brownout est une baisse de tension brève, sans coupure complète. L'ESP32 contient un détecteur de brownout qui surveille l'alimentation en permanence ; dans le core Arduino, son seuil est réglé au niveau le plus bas, environ 2,43 V. Dès que la tension passe sous cette valeur, la puce protège la radio et la mémoire flash, écrit "Brownout detector was triggered" dans le moniteur série et redémarre. La raison est simple : à basse tension, la flash peut être mal lue, les données enregistrées peuvent être corrompues et le processeur peut exécuter des instructions au hasard. Le détecteur fait redémarrer proprement la carte au lieu de la laisser se comporter de façon imprévisible. Le module ESP32-WROOM-32 est conçu pour fonctionner entre 3,0 et 3,6 V ; quand la ligne atteint 2,43 V, elle a donc quitté la zone sûre depuis longtemps.

Après un message de brownout, la ligne de démarrage affiche rst:0xc (SW_CPU_RESET) ou rst:0x3 (SW_RESET) selon la version du core Arduino, car l'interruption du détecteur écrit le message puis redémarre la puce par logiciel. Ne te laisse pas tromper : ce même code note dans la mémoire de la puce que la cause était un brownout, et esp_reset_reason() renvoie ESP_RST_BROWNOUT. Quand c'est la remise à zéro matérielle du brownout qui agit, la ligne indique rst:0xf (RTCWDT_BROWN_OUT_RESET). Dans les cores 3.x, basés sur ESP-IDF 5, cette ligne est devenue un message de journal (log) de niveau info (I BOD: Brownout detector was triggered). Comme les bibliothèques précompilées du core Arduino n'écrivent que les messages de niveau erreur, elle n'apparaît le plus souvent pas du tout et la carte redémarre en silence ; si tu vois un rst:0x3 ou rst:0xc inexpliqué au démarrage, vérifie la cause du redémarrage avec le croquis de diagnostic plus bas. Pour comprendre pourquoi la tension chute, il faut regarder le courant consommé par l'ESP32 :

État de fonctionnementCourant typique (puce ESP32)
Sommeil profond (minuterie RTC active)Environ 10 µA
Sommeil léger (light sleep)Environ 0,8 mA
Wi-Fi coupé, processeur à 240 MHz30–68 mA
Réception Wi-Fi (RX)95–100 mA
Émission Wi-Fi, 802.11b, 19,5 dBmEnviron 240 mA
Calibration radio au démarrage et moment de la connexionPeut dépasser 400 mA lors de pics de quelques microsecondes

Cet écart est le cœur du problème : tant que ton code n'active pas le Wi-Fi, la carte tourne tranquillement à environ 50 mA, mais à la ligne WiFi.begin() le courant est multiplié par cinq ou six en quelques microsecondes. Si l'alimentation, le câble et le régulateur ne suivent pas cette demande soudaine, la tension s'effondre. C'est pourquoi Espressif recommande pour l'ESP32 une alimentation capable de fournir au moins 500 mA. Le symptôme est bien connu : la carte démarre, écrit quelques lignes dans le moniteur série, redémarre au moment où le Wi-Fi ou le Bluetooth se lance, et cela tourne en boucle sans fin. La même chose peut arriver quand un servo bouge, qu'un relais commute ou qu'un ruban LED passe au blanc.

Les causes les plus fréquentes du brownout

  • Câble USB fin ou long : les fils d'alimentation fins des câbles bon marché peuvent atteindre 0,5 Ω aller-retour. D'après la loi d'Ohm, un pic de 400 mA perd 0,2 V dans un tel câble.
  • Port USB faible ou hub : les ports des claviers et des écrans, les hubs non alimentés et les ports en façade de certains ordinateurs portables laissent chuter la tension lors des pics de courant.
  • Chute de tension du régulateur : l'AMS1117 de la plupart des cartes a besoin de 1,0 à 1,3 V d'écart entre son entrée et sa sortie. Si la tension sur la broche 5V descend sous environ 4,3 V, la sortie ne peut plus tenir 3,3 V.
  • Brancher une batterie directement : une batterie lithium de 3,7 V sur la broche 5V fait tomber la sortie sous 3 V à cause de la chute du régulateur ; deux piles AA passent vite sous le minimum de l'ESP32 en charge.
  • La broche 3.3V de l'Arduino Uno : il est conseillé de ne tirer qu'environ 50 mA de cette broche ; c'est loin d'être suffisant pour un ESP32 avec le Wi-Fi actif.
  • Charges sur la même ligne : si des servos, des relais, un buzzer, des moteurs à courant continu ou un ruban WS2812B sont alimentés par le même 5 V que l'ESP32, chaque mouvement tire la tension vers le bas.
  • Breadboard et fils de connexion : les contacts lâches et les fils dupont fins ajoutent un peu de résistance à chaque connexion ; faire passer l'alimentation par la breadboard aggrave le problème.
  • ESP32-CAM : quand la caméra, le Wi-Fi et la LED flash fonctionnent en même temps, le courant monte beaucoup ; cette carte veut du 5 V et au moins 2 A. Plus de détails dans le guide ESP32-CAM.
Lire 3,3 V sur un multimètre ne veut pas dire que l'alimentation est solide. Un multimètre ne fait que quelques mesures par seconde et affiche une valeur proche d'une moyenne, alors que les chutes qui provoquent un brownout durent de quelques microsecondes à quelques millisecondes et n'apparaissent jamais à l'écran. Seul un oscilloscope peut les montrer. Si tu n'en as pas, applique les solutions suivantes dans l'ordre et vérifie après chaque étape si l'erreur a disparu. Les bases de la mesure sont dans Comment utiliser un multimètre.

Solution 1 : améliore l'alimentation et le câble

La première étape, et la plus efficace, consiste à renforcer l'alimentation. Branche la carte avec un câble de données court, épais et dont tu es sûr, directement sur un port USB à l'arrière de ton ordinateur ou sur un chargeur 5 V d'au moins 1 A. Les ports USB 2.0 sont prévus pour fournir 500 mA et les ports USB 3.0, 900 mA ; les 500 mA recommandés par Espressif sont pile la limite d'un port USB 2.0, et dès qu'on ajoute les pertes du câble, les ennuis commencent. Si changer seulement de câble règle l'erreur, sa résistance était très probablement en cause. Tu peux calculer la tension perdue dans un câble avec V = I × R grâce à l'outil Loi d'Ohm.

Régulateur de tension AMS1117 3,3 V
AMS1117-3.3 : le régulateur de la plupart des cartes ESP32. Il a besoin de 1,0 à 1,3 V d'écart entre entrée et sortie ; si la broche 5V descend sous environ 4,3 V, sa sortie ne peut plus tenir 3,3 V.
Montage d'alimentationRisque de brownoutRemarque
Câble court et épais, port USB arrièreFaibleLa solution la plus simple pendant le développement
Câble long et fin, port en façade ou hubÉlevéLa résistance du câble fait chuter la tension lors des pics
Chargeur 5 V d'au moins 1 A sur la broche 5V ou VINFaibleRecommandé pour les projets permanents
Source 3,3 V toute prête directement sur la broche 3V3Dépend de la sourceDoit fournir au moins 500 mA et ne jamais dépasser 3,6 V
Batterie lithium 3,7 V via l'AMS1117ÉlevéSous environ 4 V côté batterie, la sortie descend sous 3 V
Batterie lithium avec régulateur 3,3 V à faible chute (LDO) ou buck-boostFaibleFournit 3,3 V stables même quand la batterie se décharge
Deux piles AA directement sur la broche 3V3Très élevéEn charge, la tension passe vite sous le minimum de l'ESP32

Les projets sur batterie demandent de la prudence. Un accu lithium comme le 18650 donne 4,2 V chargé et environ 3,0 V déchargé. Cette plage ne convient ni à un branchement direct sur la broche 3V3 (4,2 V dépasse la limite de 3,6 V) ni à la broche 5V avec son AMS1117. La bonne solution consiste soit à envoyer la batterie sur la broche 5V via un module élévateur (boost) 5 V, soit à alimenter directement la ligne 3V3 avec un régulateur LDO à faible chute capable de fournir au moins 500 mA (par exemple ME6211 ou HT7833) et un condensateur. Tu peux estimer l'autonomie de ton projet avec l'outil Autonomie de batterie et découvrir le circuit de charge dans le guide du module de charge TP4056.

Solution 2 : ajoute un condensateur entre 3V3 et GND

Un condensateur agit comme un petit réservoir qui fournit lui-même l'énergie pendant un pic de courant, le temps que le régulateur et le câble réagissent. Place entre les broches 3V3 et GND, aussi près que possible de la carte, un condensateur électrolytique de 100 à 470 µF et, à côté, un condensateur céramique de 100 nF. L'électrolytique couvre les chutes de l'ordre de la milliseconde, le céramique les variations très brèves à haute fréquence. Tu peux estimer l'effet avec ΔV = I × Δt / C : même si un condensateur de 470 µF fournit à lui seul 200 mA de plus pendant 200 µs, la tension ne baisse que de 0,085 V. Le marquage 104 sur un condensateur céramique signifie 100 nF ; tu peux décoder les autres avec l'outil Code des condensateurs.

Différents condensateurs
Sur les condensateurs électrolytiques, la patte longue est le pôle positif (+) et va sur 3V3 ; la patte du côté de la bande sur le boîtier va sur GND. Pour la ligne 3,3 V, un modèle de 6,3 V ou 10 V suffit.
Ne monte jamais un électrolytique à l'envers : il chauffe, gonfle et peut éclater. Si tu le branches sur la ligne 5V, choisis-en un d'au moins 10 V. Les très gros condensateurs (1000 µF et plus) tirent un fort courant de charge à la mise sous tension, ce qui peut solliciter un instant le port USB et ralentir la montée de la ligne 3,3 V ; sur 3V3, 470 µF suffisent pour la plupart des projets. Le fonctionnement des condensateurs est expliqué dans Qu'est-ce qu'un condensateur ?

Solution 3 : alimente à part les servos, les moteurs et les rubans LED

Même si l'ESP32 lui-même est bien alimenté, les charges branchées sur la même ligne peuvent faire chuter la tension. Même un petit servo comme le SG90 tire quelques centaines de mA en démarrant ; une LED WS2812B consomme environ 60 mA en blanc maximal, donc un ruban de 30 LED peut monter à 1,8 A. Alimente ces charges non pas par la broche 5V ou 3V3 de l'ESP32, mais par une source 5 V séparée ; tu peux par exemple abaisser un chargeur 12 V à 5 V avec un module abaisseur LM2596. La règle la plus importante est de relier les GND des deux sources ; sans masse commune, la ligne de signal n'a pas de référence et le servo ou le ruban se comporte au hasard. Nous détaillons ce sujet dans Ton Arduino redémarre tout seul ? et GND et masse commune.

Module abaisseur (buck) LM2596
Module abaisseur LM2596 : il abaisse efficacement 12 V en 5 V et convient parfaitement pour alimenter des charges comme des servos, des relais ou des rubans LED séparément de l'ESP32. Sa sortie se règle avec un potentiomètre ajustable ; règle-la sur 5 V au multimètre avant de brancher quoi que ce soit.
Tu peux aussi adoucir les pics de courant par logiciel. Démarre le Wi-Fi avant de faire bouger les servos ou d'allumer le ruban LED ; limite la luminosité du ruban avec setBrightness() ; actionne les servos et les relais à quelques centaines de millisecondes d'intervalle plutôt que tous en même temps. Réduire la puissance d'émission Wi-Fi avec WiFi.setTxPower() diminue aussi le courant de pointe ; détails dans L'ESP32 ne se connecte pas au WiFi.

Désactiver le détecteur de brownout, est-ce une solution ?

La "solution" la plus souvent proposée sur Internet consiste à couper le détecteur en une seule ligne. Le code ci-dessous désactive le détecteur en remettant à zéro le registre de brownout de l'ESP32, et le message d'erreur disparaît. Mais les chutes de tension continuent ; simplement, plus personne ne te prévient. N'utilise ce code que pour le diagnostic : si la carte fonctionne bien avec le détecteur coupé, tu as la confirmation que le problème vient bien de l'alimentation. Supprime ensuite la ligne et répare l'alimentation.

C++ (Arduino IDE)
1#include "soc/soc.h"
2#include "soc/rtc_cntl_reg.h"
3
4void setup() {
5  // YALNIZ TEŞHİS İÇİN: brownout dedektörünü kapat / DIAGNOSIS ONLY: disable the brownout detector
6  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
7
8  Serial.begin(115200);
9  Serial.println("Brownout dedektoru kapali / brownout detector disabled");
10}
11
12void loop() {
13}
Ne laisse pas le détecteur désactivé en permanence. WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0) ne fait pas que masquer l'avertissement : il désactive aussi la remise à zéro matérielle du détecteur et son rôle de couper la flash et la radio en cas de sous-tension, si bien que la puce continue de tourner sans protection bien en dessous de son minimum de 3,0 V. Quand la tension passe sous 2,4 V, les données écrites dans la flash (Preferences, EEPROM, LittleFS), voire le programme lui-même pendant une mise à jour OTA, peuvent être corrompues, le Wi-Fi peut tomber sans raison apparente et la carte peut cette fois planter avec des erreurs Guru Meditation ou se figer complètement. Le réglage n'est pas permanent : la puce réactive le détecteur à chaque démarrage, la ligne doit donc être la première de setup(), et dès que tu la supprimes, la protection revient. Ce registre existe sur l'ESP32 classique, le S2, le S3 et le C3 ; les modèles récents comme l'ESP32-C6 ne l'ont pas et le code ne compile pas. La vraie solution est toujours de réparer l'alimentation.

Codes rst : l'ESP32 te dit pourquoi il a redémarré

La valeur rst: affichée par la ROM à chaque démarrage indique comment s'est terminée l'exécution précédente. Lors d'un démarrage normal, la valeur boot est 0x13 (SPI_FAST_FLASH_BOOT), c'est-à-dire que la carte lance son programme depuis la flash. Le tableau résume les codes que tu rencontreras le plus souvent. Les codes de la ROM ne suffisent pas toujours : ESP.restart() et le redémarrage après un Guru Meditation apparaissent tous deux avec le code 0xc, et un brownout s'affiche en 0xc ou en 0x3 selon la version du core. Pour les distinguer, utilise le croquis avec esp_reset_reason() de la section suivante.

Code rstNomSignification
0x1POWERON_RESETPremière mise sous tension ou appui sur le bouton EN
0x3SW_RESETLe logiciel a réinitialisé tout le système numérique ; les versions récentes du core l'affichent aussi après un brownout
0x5DEEPSLEEP_RESETLa carte s'est réveillée du sommeil profond (normal)
0x7 / 0x8TG0WDT_SYS_RESET / TG1WDT_SYS_RESETUn watchdog de groupe de minuteries a réinitialisé le système matériellement ; les interruptions sont restées désactivées trop longtemps ou même le gestionnaire de panique n'a pas pu s'exécuter
0x9RTCWDT_SYS_RESETLe watchdog du RTC a réinitialisé le cœur numérique
0xcSW_CPU_RESETRedémarrage logiciel : ESP.restart(), après un Guru Meditation ou après un brownout dans le core Arduino
0xfRTCWDT_BROWN_OUT_RESETRéinitialisation matérielle par brownout : tension d'alimentation instable
0x10RTCWDT_RTC_RESETLe watchdog du RTC a réinitialisé toute la puce, RTC compris ; s'observe surtout sur les cartes qui se bloquent au démarrage

Croquis de diagnostic : afficher la cause du redémarrage, la mémoire et la pile

Téléverse le code ci-dessous comme croquis séparé, ou ajoute ses lignes dans le setup() et le loop() de ton projet à problème. À chaque démarrage, la carte écrit dans le moniteur série la cause du redémarrage en texte lisible, le nombre de démarrages et l'état de la mémoire. Le compteur marqué RTC_DATA_ATTR est stocké dans la mémoire RTC : il survit donc aux redémarrages logiciels et au sommeil profond, et n'est remis à zéro que lorsque l'alimentation est complètement coupée. Si le compteur augmente toutes les quelques secondes, tu sais tout de suite que la carte est coincée dans une boucle de redémarrages.

C++ (Arduino IDE)
1#include <esp_system.h>
2
3RTC_DATA_ATTR uint32_t bootCount = 0;   // yazılım resetinde korunur / survives software resets
4
5// Reset nedenini okunabilir yazıya çevir / turn the reset reason into readable text
6const char* reasonText(esp_reset_reason_t r) {
7  switch (r) {
8    case ESP_RST_POWERON:   return "POWERON: guc acilisi ya da EN / power-on or EN button";
9    case ESP_RST_SW:        return "SW: ESP.restart()";
10    case ESP_RST_PANIC:     return "PANIC: Guru Meditation";
11    case ESP_RST_INT_WDT:   return "INT_WDT: kesme watchdog'u / interrupt watchdog";
12    case ESP_RST_TASK_WDT:  return "TASK_WDT: gorev watchdog'u / task watchdog";
13    case ESP_RST_WDT:       return "WDT: diger watchdog / other watchdog";
14    case ESP_RST_DEEPSLEEP: return "DEEPSLEEP: derin uykudan uyanma / deep sleep wake-up";
15    case ESP_RST_BROWNOUT:  return "BROWNOUT: gerilim dusmesi / supply voltage dropped";
16    default:                return "UNKNOWN: bilinmiyor / unknown";
17  }
18}
19
20void setup() {
21  Serial.begin(115200);
22  delay(1000);                          // Seri Monitör'ün açılmasını bekle / wait for the Serial Monitor
23  bootCount++;
24  Serial.printf("Acilis sayisi / boot count: %u\n", (unsigned)bootCount);
25  Serial.printf("Reset nedeni / reset reason: %s\n", reasonText(esp_reset_reason()));
26}
27
28void loop() {
29  // Bellek durumu / memory status
30  Serial.printf("Bos heap / free heap: %u B, en dusuk / minimum: %u B, en buyuk blok / largest block: %u B\n",
31                (unsigned)ESP.getFreeHeap(), (unsigned)ESP.getMinFreeHeap(), (unsigned)ESP.getMaxAllocHeap());
32  // loopTask yığınında hiç kullanılmamış en küçük alan / smallest unused space on the loopTask stack
33  Serial.printf("loopTask bos yigin / free stack: %u B\n", (unsigned)uxTaskGetStackHighWaterMark(NULL));
34  delay(5000);
35}

Les valeurs affichées dans la boucle révèlent aussi des problèmes silencieux. Si le tas libre (free heap) baisse un peu à chaque tour, ton programme a une fuite de mémoire et la carte finira par planter. Si le plus grand bloc est bien plus petit que le tas libre, la mémoire est fragmentée ; cela vient généralement d'objets String qui grossissent et rétrécissent sans cesse dans la boucle. Si la pile libre de loopTask descend sous quelques centaines d'octets, le débordement de pile n'est pas loin. Si la cause du redémarrage est BROWNOUT, concentre-toi sur les sections sur l'alimentation ; si c'est PANIC, TASK_WDT ou INT_WDT, sur les sections logicielles qui suivent.

Qu'est-ce qu'un Guru Meditation Error ? Lis le rapport de plantage ligne par ligne

Un Guru Meditation Error est le rapport de plantage qu'affiche le gestionnaire de panique quand le processeur de l'ESP32 rencontre une erreur dont il ne peut pas se remettre ; le nom vient de l'écran d'erreur des anciens ordinateurs Amiga. Le rapport fait peur au premier abord, mais seules quelques lignes comptent. Core 1 indique sur quel cœur l'erreur s'est produite : avec Arduino, setup() et loop() tournent sur le cœur 1, et la pile Wi-Fi sur le cœur 0. Le nom entre parenthèses est le type d'exception. À la fin du rapport, la carte écrit "Rebooting..." et redémarre ; tu verras rst:0xc sur la ligne de démarrage.

LigneSignification
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.Le code du cœur 1 a voulu lire à une adresse invalide et l'erreur n'a pas été interceptée
PC : 0x400d1a2cAdresse de l'instruction qui a planté ; si elle commence par 0x400d, ton code ou une bibliothèque s'exécutait depuis la flash
EXCCAUSE: 0x0000001cCode de l'exception ; 0x1c, soit 28, signifie LoadProhibited
EXCVADDR: 0x00000000Adresse à laquelle on a voulu accéder ; 0 ou un très petit nombre désigne un pointeur nul
Backtrace: 0x400d1a29:0x3ffb2270 0x400d0f6e:0x3ffb2290 ...Chaîne d'appels ; chaque paire a la forme PC:SP et le décodeur la traduit en ligne de code
ELF file SHA256: ...Empreinte du programme qui a planté ; le décodeur a besoin exactement de la même compilation
Rebooting...Le gestionnaire de panique redémarre la puce par logiciel

LoadProhibited, StoreProhibited et les autres types d'exception

ExceptionEXCCAUSEQue s'est-il passé ?Cause fréquente
LoadProhibited28 (0x1c)Lecture à une adresse invalidePointeur nul ou non initialisé, objet supprimé
StoreProhibited29 (0x1d)Écriture à une adresse invalideÉcriture via un pointeur nul, tampon qui dépasse le tableau
InstrFetchProhibited20 (0x14)Lecture d'instruction à une adresse invalidePointeur de fonction ou callback non assigné
IllegalInstruction0 (0x0)Instruction invalidePile corrompue, return oublié dans une fonction qui doit renvoyer une valeur
LoadStoreAlignment9 (0x9)Accès mémoire non alignéConvertir de force un tableau d'octets en un type comme uint32_t*
IntegerDivideByZero6 (0x6)Division entière par zéroDiviser par un compteur qui peut valoir zéro
Unhandled debug exception-Exception de débogageStack canary watchpoint triggered : débordement de pile
Interrupt wdt timeout on CPU0/CPU1-Le watchdog des interruptions a expiréISR trop longue, Serial ou delay dans une ISR
Cache disabled but cached memory region accessed-Accès à du code en flash pendant que la flash était occupéeFonction d'interruption sans IRAM_ATTR

La plus courante de ces erreurs est l'utilisation d'un pointeur nul. NULL correspond à l'adresse 0, et sur l'ESP32 il n'y a pas de mémoire lisible autour de l'adresse 0 : lire là où pointe un pointeur vide provoque donc LoadProhibited, y écrire provoque StoreProhibited. Dans ce cas, EXCVADDR est un indice parfait : 0x00000000 désigne le pointeur lui-même, et de petites valeurs comme 0x00000004 ou 0x00000010 un champ à l'intérieur d'un pointeur vide (NULL plus la position du champ). Dans les projets Arduino, la cause la plus fréquente est une fonction qui renvoie NULL pour dire "pas trouvé", valeur ensuite utilisée sans vérification. Dans l'exemple ci-dessous, strstr() renvoie NULL s'il ne trouve pas le texte ; sans vérification, la carte plante avec EXCVADDR 0x00000005.

C++ (Arduino IDE)
1const char* response = "temp=23.5;hum=40";   // sunucudan gelen yanıt / reply from a server
2
3void setup() {
4  Serial.begin(115200);
5  delay(500);
6
7  // YANLIŞ: "pres=" yoksa strstr NULL döner ve kart çöker (EXCVADDR 0x00000005)
8  // WRONG: if "pres=" is missing strstr returns NULL and the board crashes (EXCVADDR 0x00000005)
9  // float pressure = atof(strstr(response, "pres=") + 5);
10
11  // DOĞRU: işaretçiyi kullanmadan önce NULL kontrolü yap / RIGHT: check for NULL before using the pointer
12  const char* found = strstr(response, "pres=");
13  if (found != nullptr) {
14    float pressure = atof(found + 5);
15    Serial.println(pressure);
16  } else {
17    Serial.println("pres alani bulunamadi / pres field not found");
18  }
19}
20
21void loop() {
22}
Prends quelques bonnes habitudes contre les pointeurs nuls : initialise les pointeurs avec nullptr dès leur déclaration, vérifie la valeur de retour des fonctions begin() des bibliothèques, remets un pointeur à nullptr après avoir fait delete sur un objet et assure-toi que l'indice est inférieur à la taille du tableau quand tu écris dedans. Si tu règles les avertissements du compilateur sur Tous dans Fichier > Préférences de l'IDE Arduino, tu verras un return oublié et les erreurs du même genre dès la compilation.

Débordement de pile : l'erreur "Stack canary watchpoint triggered"

Sur l'ESP32, chaque tâche (task) possède une pile (stack) de taille fixe, où sont stockés les variables locales, les appels de fonctions et les adresses de retour. Avec Arduino, la tâche loopTask qui exécute setup() et loop() a une pile de 8192 octets. Déclarer un tableau local de 10 000 octets dans loop(), une fonction qui s'appelle elle-même (récursive) ou une fonction de bibliothèque avec beaucoup de variables locales dépasse cette limite. À la fin de la pile se trouve une zone de garde (canary) ; quand la pile l'atteint, la carte écrit Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception) et juste en dessous Debug exception reason: Stack canary watchpoint triggered (loopTask). Le nom entre parenthèses est celui de la tâche dont la pile a débordé. Le même problème apparaît parfois sous la forme ***ERROR*** A stack overflow in task loopTask has been detected. Voici comment le régler :

  • Sors les grands tableaux de la pile : déclare le tableau en global ou ajoute static devant ; il est alors placé dans la RAM permanente et non sur la pile.
  • Agrandis la pile de loopTask : écris SET_LOOP_TASK_STACK_SIZE(16 * 1024); tout en haut du croquis pour porter la pile de loop() à 16 Ko.
  • Donne assez de place à tes tâches : sur l'ESP32, la taille de pile passée à xTaskCreate et xTaskCreatePinnedToCore s'exprime en octets, et non en mots (words) comme avec FreeRTOS sur d'autres plateformes. 1024 octets ne suffisent même pas pour une tâche qui utilise Serial.printf ; commence avec 4096.
  • Mesure : uxTaskGetStackHighWaterMark(NULL) renvoie, en octets, la plus petite quantité de pile que la tâche n'a encore jamais utilisée ; si elle descend sous quelques centaines d'octets, agrandis la pile.
  • Évite la récursivité : transforme les fonctions qui s'appellent elles-mêmes en boucles ou limite leur profondeur.

Watchdog des tâches : l'erreur "task_wdt: Task watchdog got triggered"

Un watchdog (chien de garde) est une minuterie qui détecte un programme bloqué et sauve la carte. Le watchdog des tâches (Task WDT) de l'ESP32 attend que les tâches qui lui sont inscrites donnent signe de vie à intervalles réguliers. Dans le core Arduino, il surveille par défaut la tâche inactive (IDLE) du cœur 0, avec un délai de 5 secondes. Si une tâche du cœur 0 ne libère pas le processeur pendant 5 secondes, la tâche IDLE ne peut pas s'exécuter et le moniteur série affiche un message qui commence par E (10257) task_wdt: Task watchdog got triggered. Viennent ensuite la liste des tâches qui n'ont pas réarmé le watchdog à temps (le plus souvent - IDLE (CPU 0)) puis, sous Tasks currently running:, les tâches en cours d'exécution à cet instant. Dans le core Arduino, cela déclenche une panique avec la ligne task_wdt: Aborting. et la carte redémarre.

Les causes les plus fréquentes sont : une boucle placée sur le cœur 0 avec xTaskCreatePinnedToCore sans le moindre vTaskDelay(), une boucle while qui attend la réponse d'un capteur sans délai maximal, ou des delay() et des opérations longues dans les fonctions de rappel (callbacks) de bibliothèques comme AsyncWebServer. Dans ce dernier cas, tu verras la tâche async_tcp dans la liste à la place d'IDLE. La solution consiste à découper les longs traitements en petits morceaux et à ajouter de courtes attentes comme vTaskDelay(1) dans les boucles. La fonction loop() elle-même n'est pas surveillée par défaut ; si tu veux, appelle enableLoopWDT() dans setup() pour que la carte redémarre aussi quand loop() reste bloquée plus de 5 secondes. Couper le watchdog avec disableCore0WDT() masque l'erreur mais ne corrige pas le code bloqué. Pour en savoir plus sur les tâches et les cœurs, consulte FreeRTOS et double cœur sur l'ESP32. Le code ci-dessous montre une structure de tâche correcte et les précautions contre le débordement de pile :

C++ (Arduino IDE)
1SET_LOOP_TASK_STACK_SIZE(16 * 1024);   // loop() yığını 8 KB yerine 16 KB / loop() stack 16 KB instead of 8 KB
2
3volatile uint32_t sampleCount = 0;
4
5// 0. çekirdekte çalışan görev / task running on core 0
6void sensorTask(void* parameter) {
7  for (;;) {
8    sampleCount = sampleCount + 1;       // sensörünü burada oku / read your sensor here
9    vTaskDelay(pdMS_TO_TICKS(10));       // IDLE görevine sıra ver, task_wdt tetiklenmez / let IDLE run, no task_wdt
10  }
11}
12
13void setup() {
14  Serial.begin(115200);
15  // Yığın boyutu bayt cinsindendir: 4096 bayt / stack size is in bytes: 4096 bytes
16  xTaskCreatePinnedToCore(sensorTask, "sensorTask", 4096, NULL, 1, NULL, 0);
17}
18
19void loop() {
20  static uint8_t buffer[10000];          // static: yığında değil kalıcı RAM'de / static: in RAM, not on the stack
21  memset(buffer, 0, sizeof(buffer));
22
23  Serial.printf("Ornek / samples: %u, loopTask bos yigin / free stack: %u B\n",
24                (unsigned)sampleCount, (unsigned)uxTaskGetStackHighWaterMark(NULL));
25  delay(1000);
26}

Interrupt wdt timeout et IRAM_ATTR : plantages dans les interruptions

Le watchdog des interruptions (Interrupt WDT) est bien plus impatient : si une routine d'interruption (ISR) ou un morceau de code avec les interruptions désactivées dépasse 300 ms, la carte plante avec Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1). Utiliser Serial.print, delay(), l'I2C ou le Wi-Fi dans une ISR est la cause la plus fréquente. La mémoire flash est un autre piège : pendant que Preferences, EEPROM ou LittleFS écrivent dans la flash, le cache de la flash est coupé un instant. Si une interruption arrive à ce moment et que sa fonction se trouve en flash, la carte affiche Cache disabled but cached memory region accessed. La solution consiste à marquer les ISR avec IRAM_ATTR pour les placer en RAM et à n'y lever qu'un drapeau ; le vrai travail est fait dans loop(). Les variables partagées entre une ISR et loop() doivent être volatile.

C++ (Arduino IDE)
1const int BUTTON_PIN = 27;              // buton GPIO 27 ile GND arasında / button between GPIO 27 and GND
2volatile bool buttonPressed = false;    // ISR ile loop arasında paylaşılan bayrak / flag shared by the ISR and loop
3uint32_t pressCount = 0;
4
5void IRAM_ATTR onButton() {             // IRAM_ATTR: fonksiyon flaşta değil RAM'de durur / the function lives in RAM, not flash
6  buttonPressed = true;                 // yalnızca bayrak kaldır, Serial yok / only set a flag, no Serial
7}
8
9void setup() {
10  Serial.begin(115200);
11  pinMode(BUTTON_PIN, INPUT_PULLUP);
12  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), onButton, FALLING);
13}
14
15void loop() {
16  if (buttonPressed) {
17    buttonPressed = false;
18    pressCount++;
19    Serial.printf("Butona basildi / button pressed: %u\n", (unsigned)pressCount);   // yavaş iş burada / slow work here
20  }
21}

Traduire le Backtrace en ligne de code avec ESP Exception Decoder

Les adresses de la ligne Backtrace ne disent rien à elles seules ; l'outil qui les traduit en fichier, fonction et numéro de ligne de ton code source s'appelle ESP Exception Decoder. Dans l'ancien IDE Arduino 1.8, c'était un module ajouté au menu Outils. Dans l'IDE Arduino 2, on utilise une extension de la communauté qui porte le même nom :

  1. Télécharge le fichier avec l'extension .vsix dans la section Releases du projet dankeboy36/esp-exception-decoder sur GitHub. Pour l'IDE Arduino 2, choisis une version 1.x ; les nouvelles versions 2.x sont prévues pour VS Code.
  2. Ferme l'IDE Arduino et copie le fichier dans %UserProfile%\.arduinoIDE\plugins sous Windows ou dans ~/.arduinoIDE/plugins sous macOS et Linux ; crée le dossier s'il n'existe pas.
  3. Ouvre l'IDE et le croquis qui plante, compile-le avec Vérifier et téléverse-le sur la carte.
  4. Ouvre le moniteur série et attends que le plantage se reproduise.
  5. Ouvre la palette de commandes avec Ctrl+Maj+P (Cmd+Shift+P sous macOS) et lance ESP Exception Decoder: Show Decoder Terminal.
  6. Copie dans le moniteur série le bloc Guru Meditation avec la ligne Backtrace et colle-le dans le terminal qui s'ouvre ; l'outil affiche chaque adresse avec le nom du fichier, la fonction et le numéro de ligne.

Si tu ne peux pas installer l'extension, tu peux faire la même chose à la main. Le menu Sketch > Export Compiled Binary dépose un fichier avec l'extension .elf dans le dossier build, à l'intérieur du dossier du croquis. La commande xtensa-esp32-elf-addr2line -pfiaC -e sketch.ino.elf 0x400d1a29 0x400d0f6e de la chaîne d'outils de l'ESP32 traduit ces adresses en noms de fonctions et numéros de ligne. Si tu utilises PlatformIO, il suffit d'ajouter la ligne monitor_filters = esp32_exception_decoder dans le fichier platformio.ini ; le rapport de plantage est alors décodé automatiquement dans le moniteur série.

Le décodeur ne donne un résultat juste qu'avec le fichier .elf de exactement la même compilation que celle qui a planté. Si tu modifies une seule ligne et recompiles, les adresses se décalent et la sortie indique de mauvaises lignes. Si la ligne Backtrace se termine par CORRUPTED, la pile est endommagée ; c'est généralement le signe d'un débordement de pile ou d'un tampon qui a dépassé ses limites.

Broches de strapping : comment GPIO0, GPIO2, GPIO12 et GPIO15 perturbent le démarrage

Au démarrage, l'ESP32 regarde le niveau de certaines broches pour décider comment démarrer. Ce sont les broches de strapping, et seul leur niveau au moment de la réinitialisation compte ; une fois le démarrage terminé, elles s'utilisent comme des GPIO normales. Le problème survient quand un capteur, un bouton ou un module branché dessus tire la broche au mauvais niveau au démarrage. La carte ne lance alors pas son programme, passe en mode programmation ou ne peut pas lire la flash ; vu de l'extérieur, cela ressemble aussi à "l'ESP32 ne démarre pas" ou à "il redémarre sans arrêt". Tu peux voir le brochage complet de ta carte dans l'outil Pinout.

BrocheRésistance interneRôle au démarrageQue se passe-t-il au mauvais niveau ?
GPIO0Pull-upLOW active le mode programmation (download), HIGH le démarrage normalboot:0x3 (DOWNLOAD_BOOT) et waiting for download ; le programme ne s'exécute pas
GPIO2Pull-downDoit être à LOW ou flottante pour entrer en mode programmation ; sans effet au démarrage normalUn circuit qui la tire à HIGH empêche le téléversement
GPIO12 (MTDI)Pull-downChoisit la tension de la flash : LOW 3,3 V, HIGH 1,8 VÀ HIGH, une flash 3,3 V est mal alimentée ; la carte ne démarre pas ou entre dans une boucle de redémarrages
GPIO15 (MTDO)Pull-upÀ LOW, rend muets les messages de démarrage de la ROMLes lignes de démarrage n'apparaissent pas dans le moniteur série, le diagnostic devient plus difficile
GPIO5Pull-upDéfinit la temporisation SDIOPose rarement problème sur les cartes de développement
Une résistance de pull-up, un relais ou un module capteur sur GPIO12 qui met la broche à HIGH au démarrage est la raison la plus cachée pour laquelle un ESP32 ne démarre pas du tout. Si tu dois utiliser cette broche, assure-toi que le module la laisse à LOW au moment du démarrage. Autre possibilité : la commande espefuse.py set_flash_voltage 3.3V fournie avec esptool grave la tension de la flash de façon permanente dans un eFuse et supprime l'effet de GPIO12 au démarrage ; mais cette opération est irréversible et ne doit être faite que sur des modules avec une flash 3,3 V (comme l'ESP32-WROOM-32).

Les cartes plus récentes ont d'autres broches de strapping : sur l'ESP32-S3, ce sont GPIO0, GPIO3, GPIO45 et GPIO46 qui influencent le démarrage, et sur l'ESP32-C3, GPIO2, GPIO8 et GPIO9. L'ESP32-S3 utilise les mêmes noms d'exception Xtensa que l'ESP32 classique. Sur l'ESP32-C3 à cœur RISC-V, en revanche, tu verras Load access fault au lieu de LoadProhibited et Store access fault au lieu de StoreProhibited, et le registre MTVAL joue le rôle d'EXCVADDR. Le message de brownout est le même sur tous les modèles.

ESP32 et Raspberry Pi Pico avec MicroPython

Si tu programmes l'ESP32 en MicroPython, le brownout se produit exactement de la même façon, car le problème est matériel et non logiciel. Les erreurs du code Python, elles, apparaissent sous forme de Traceback lisible au lieu d'un Guru Meditation, et la carte plante rarement. Tu peux lire la cause du redémarrage avec machine.reset_cause(), mais attention : la version de MicroPython pour ESP32 ne renvoie pas de valeur propre au brownout, elle le signale comme PWRON_RESET, au même titre qu'une mise sous tension. Si la carte redémarre sans cesse avec PWRON_RESET alors que tu n'y touches pas, soupçonne à nouveau l'alimentation. Le code ci-dessous est destiné à l'ESP32 ; sur le Raspberry Pi Pico, le module machine connaît moins de types de redémarrage. Sur le Pico, le régulateur buck-boost de l'entrée VSYS fonctionne avec toute tension entre 1,8 et 5,5 V, si bien que les problèmes de brownout y sont beaucoup plus rares ; pour découvrir la carte, lis Qu'est-ce que le Raspberry Pi Pico ?

MicroPython
1import machine, gc, time
2
3# Reset nedenleri (ESP32 için) / reset causes (for ESP32)
4causes = {
5    machine.PWRON_RESET: "PWRON: guc acilisi ya da brownout / power-on or brownout",
6    machine.HARD_RESET: "HARD: cokme ya da machine.reset() / crash or machine.reset()",
7    machine.WDT_RESET: "WDT: watchdog",
8    machine.DEEPSLEEP_RESET: "DEEPSLEEP: derin uykudan uyanma / deep sleep wake-up",
9    machine.SOFT_RESET: "SOFT: Ctrl+D ile yazilim reseti / soft reset with Ctrl+D",
10}
11print("Reset nedeni / reset cause:", causes.get(machine.reset_cause(), "bilinmiyor / unknown"))
12
13while True:
14    gc.collect()                                     # çöp toplayıcıyı çalıştır / run the garbage collector
15    print("Bos RAM / free RAM:", gc.mem_free(), "bayt / bytes")
16    time.sleep(5)

Erreurs fréquentes et solutions

SymptômeCause probableSolution
Brownout detector was triggered au démarrage du Wi-FiLe câble, le port ou le régulateur ne suit pas le pic de courantCâble court et épais, chargeur 1 A, 470 µF + 100 nF entre 3V3 et GND
Redémarrage quand un servo tourne ou qu'un relais commuteLa charge partage la ligne d'alimentation de l'ESP32Alimente la charge avec une source 5 V séparée et relie les GND
Les redémarrages commencent quand la batterie se vide un peuChute de tension de l'AMS1117Utilise un LDO ou un convertisseur buck-boost
Guru Meditation, EXCVADDR 0x00000000Pointeur nulVérifie le pointeur avant de l'utiliser
Stack canary watchpoint triggered (loopTask)La pile de loop() est pleineRends les grands tableaux static ou utilise SET_LOOP_TASK_STACK_SIZE
task_wdt: - IDLE (CPU 0)Boucle sans pause sur le cœur 0Ajoute vTaskDelay dans la boucle
Interrupt wdt timeout on CPU1ISR trop longueNe lève qu'un drapeau dans l'ISR, utilise IRAM_ATTR
Carte muette, boot:0x3 et waiting for downloadGPIO0 à LOW au démarrageRetire le circuit sur GPIO0 et appuie sur EN
La carte ne démarre pas du tout, erreur de lecture de la flashGPIO12 à HIGH au démarrageDéplace le pull-up ou le module de GPIO12 vers une autre broche
Failed to connect to ESP32 au téléversementGPIO2 à HIGH ou la carte n'entre pas en mode programmationLibère GPIO2 et maintiens BOOT enfoncé au début du téléversement
Respecte l'ordre pendant le diagnostic : change d'abord le câble et l'alimentation, ajoute ensuite le condensateur, puis alimente à part les servos et les LED. Si les redémarrages continuent une fois le message de brownout disparu, regarde la cause du redémarrage dans le croquis de diagnostic et passe aux sections logicielles. Si tu règles Outils > Core Debug Level sur Verbose, le core de l'ESP32 affiche des messages bien plus détaillés sur le Wi-Fi et les événements système. Pour les problèmes de téléversement, jette aussi un œil à Impossible de téléverser un croquis sur l'Arduino.

Ta carte est stable : et maintenant ?

  • Appareil économe sur batterie : avec le deep sleep de l'ESP32, endors la carte entre deux mesures et descends à quelques microampères.
  • Mises à jour sans fil : téléverse ton code sans câble USB grâce à l'OTA sur ESP32.
  • Tableau de bord en temps réel : suis les données des capteurs en direct dans le navigateur avec WebSocket sur ESP32.
  • Envoyer des notifications : avec un bot Telegram sur ESP32, reçois sur ton téléphone la cause du redémarrage à chaque fois que la carte redémarre.
  • Spectacle lumineux : pilote en toute sécurité un ruban WS2812B NeoPixel avec une alimentation séparée.

La plupart des problèmes de redémarrage de l'ESP32 sont soit un souci d'alimentation, soit quelques lignes de code fautives ; quand tu lis correctement le message, les deux se règlent vite. Pour revoir les bases de la carte, jette un œil à Qu'est-ce que l'ESP32 ? Dans l'application BlueGrays, tu trouveras des projets ESP32 avec des LED, des servos, des rubans NeoPixel, la connexion Wi-Fi, un serveur web, les mises à jour OTA et le deep sleep, chacun avec son schéma de câblage et son code pas à pas, pour essayer dans de vrais projets les techniques d'alimentation et de diagnostic apprises ici.

Questions fréquentes

Comment corriger ESP32 Brownout detector was triggered ?

Cette erreur signifie que la tension d'alimentation de l'ESP32 est passée un instant sous environ 2,43 V. Utilise d'abord un câble USB court et épais avec une source 5 V d'au moins 1 A, puis ajoute un condensateur électrolytique de 100 à 470 µF et un céramique de 100 nF entre 3V3 et GND. Alimente les charges comme les servos, les relais et les rubans LED avec une source séparée et relie les GND.

Pourquoi mon ESP32 redémarre-t-il en boucle ?

Les causes les plus fréquentes sont une alimentation insuffisante (brownout), des plantages logiciels (Guru Meditation), des délais du watchdog et des broches de strapping au mauvais niveau au démarrage. Ouvre le moniteur série à 115200 bauds et appuie sur EN ; le dernier message avant le redémarrage et le code rst au démarrage indiquent la cause. La fonction esp_reset_reason() permet aussi de la lire depuis ton code.

Que veut dire Guru Meditation Error LoadProhibited ?

Cela signifie que le code de l'ESP32 a voulu lire à une adresse mémoire invalide. Si EXCVADDR vaut 0 ou un très petit nombre, un pointeur nul a presque sûrement été utilisé. Colle la ligne Backtrace dans ESP Exception Decoder pour trouver le fichier et la ligne de l'erreur.

Peut-on désactiver le détecteur de brownout de l'ESP32 ?

Oui, avec la ligne WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0), mais cela ne fait que faire taire l'alerte. Comme les chutes de tension continuent, les données en flash peuvent être corrompues et la carte peut planter avec d'autres erreurs. Ne l'utilise que brièvement pour confirmer que le problème vient de l'alimentation.

Comment corriger ESP32 Task watchdog got triggered ?

Ce message signifie qu'une tâche surveillée n'a pas libéré le processeur pendant 5 secondes ; avec Arduino, la liste montre généralement la tâche IDLE du cœur 0. Ajoute vTaskDelay() dans les boucles de tes propres tâches, utilise des délais maximaux quand tu attends un capteur et évite delay() ou les opérations longues dans les callbacks du serveur web. Couper le watchdog masque l'erreur mais n'en corrige pas la cause.

Quelle alimentation faut-il pour un ESP32 ?

Espressif recommande pour l'ESP32 une alimentation capable de fournir au moins 500 mA ; en pratique, un chargeur 5 V de 1 A laisse une marge sûre. Si tu utilises un ESP32-CAM ou ajoutes des charges comme des servos ou des rubans LED, choisis une source de 2 A ou plus et alimente si possible ces charges par une ligne séparée.

Voir tous les projets
Clignotement LED avec ESP32
#103Débutant

Clignotement LED avec ESP32

Enseigne l'utilisation de base des sorties GPIO avec l'ESP32. Nous obtenons un effet de clignotement en allumant et éteignant une LED à partir de la broche numérique. Version ESP32 du projet blink classique sur Arduino UNO ; les commandes de base de blink dans l'environnement Arduino restent les mêmes, mais le brochage et les niveaux GPIO de 3,3 V de l'ESP32 diffèrent de ceux de l'Arduino UNO.

4.7(37)
99
Connexion Wi-Fi STA ESP32 (avec écran LCD)
#127Avancé

Connexion Wi-Fi STA ESP32 (avec écran LCD)

Dans ce projet, nous connectons l'ESP32 au réseau Wi-Fi domestique en mode Station (STA) de manière sécurisée et tolérante aux pannes. Nous isolons SSID/mot de passe dans un fichier secrets.h pour empêcher leur fuite sur Git, mettons en place une reconnexion automatique, et affichons le niveau RSSI et l'adresse IP sur un écran LCD I2C. La LED intégrée sert d'indicateur d'état.

4.4(21)
34
Servomoteur ESP32 (commande par potentiomètre)
#118Intermédiaire
Premium

Servomoteur ESP32 (commande par potentiomètre)

Dans ce projet, nous contrôlons un servomoteur SG90 à l'aide d'un potentiomètre. Nous réglons l'angle du servomoteur en mappant la valeur analogique lue par le potentiomètre sur une plage de 0 à 180 degrés. La bibliothèque ESP32Servo génère des signaux de servomoteur sur les GPIO appropriés de l'ESP32 pouvant fonctionner en sortie ; ce projet utilise GPIO 18. Il s'agit d'une méthode de contrôle fondamentale pour les bras robotiques, les cardans de caméra et les mécanismes de portes automatiques.

4.3(29)
42
Contrôle d'une bande NeoPixel WS2812B avec l'ESP32
#126Intermédiaire
Premium

Contrôle d'une bande NeoPixel WS2812B avec l'ESP32

Les LED adressables WS2812B (NeoPixel) sont des LED RGB intelligentes pouvant être contrôlées en série via une seule broche de données. Dans ce projet, nous allons contrôler une bande WS2812B de 8 LED à l'aide de la bibliothèque Adafruit_NeoPixel afin de créer une animation fluide représentant un arc-en-ciel. Bien que le niveau logique 3,3 V de l'ESP32 fonctionne sans problème avec la plupart des composants WS2812B, nous présenterons une solution comprenant une résistance en série de 470 Ω et un

4.9(19)
30
Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)
#129Avancé

Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)

Dans ce projet, nous transformons l'ESP32 en un serveur web asynchrone que vous pouvez contrôler depuis votre téléphone ou votre ordinateur connecté au même réseau Wi-Fi. Grâce à la bibliothèque ESPAsyncWebServer, le serveur peut traiter plusieurs requêtes simultanément (contrairement au classique WebServer.h qui se bloque sur une seule requête). Depuis votre navigateur, vous pourrez vous connecter à l'adresse IP de l'ESP32, puis allumer et éteindre la LED co

4.8(16)
26
Mode veille profonde de l'ESP32 — Économie de batterie (OLED + compteur RAM RTC)
#135Avancé
Premium

Mode veille profonde de l'ESP32 — Économie de batterie (OLED + compteur RAM RTC)

Le mode « Deep Sleep » de l'ESP32 réduit la consommation de courant à environ 10 µA en désactivant le processeur et la plupart des périphériques, ce qui revêt une importance cruciale pour les appareils IoT fonctionnant sur batterie. Dans ce projet, nous utilisons trois sources de réveil différentes : une minuterie (timer, 15 s), une broche externe (EXT0 — bouton GPIO 33) et un capteur tactile (T0/GPIO 4). Les variables marquées avec RTC_DATA_ATTR sont conservées pendant le mode Deep Sleep — le

4.3(10)
16
Mise à jour OTA de l'ESP32 — Installation sans fil du firmware (avec écran LCD)
#132Avancé
Premium

Mise à jour OTA de l'ESP32 — Installation sans fil du firmware (avec écran LCD)

Dans ce projet, vous allez apprendre à installer un nouveau firmware sur l'ESP32 via Wi-Fi, sans câble USB. Grâce à la bibliothèque ArduinoOTA, l'ESP32 devient visible sur le réseau et apparaît automatiquement sous le nom bluegrays-ota dans l'onglet « Network port » de l'IDE Arduino. La première installation s'effectue via USB, puis toutes les mises à jour se font sans fil — une fonctionnalité essentielle pour les appareils sur le terrain. L'écran LCD I2C affiche l'état du Wi-Fi, l'adresse I

4.6(14)
22
Système d'Alarme de Mouvement ESP32 (PIR + Buzzer + LED + Telegram)
#145Avancé
Premium

Système d'Alarme de Mouvement ESP32 (PIR + Buzzer + LED + Telegram)

Un système d'alarme de sécurité intelligent qui active le buzzer et la LED lorsque le capteur PIR détecte un mouvement, tout en envoyant une notification instantanée au propriétaire via Telegram. Il intègre un délai d'attente de 30 secondes pour limiter la fréquence des alarmes répétées ; ce mécanisme ne vérifie pas la validité des détections du capteur PIR et n'élimine pas les faux déclenchements. Idéal pour la sécurité domestique, la surveillance de garage, d'entrepôts ou de bureaux. Avec l'ES

0.0(0)
9