If you cannot download code to your ESP32 and get the error message “Wrong boot mode“, then this tutorial is for you.
A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
An ESP32 essentially can be in three different modes. It can execute a program, it can be in (deep-) sleep mode, or it can be in download/flash mode to be programmed.
Before you can download code to an ESP32, the chip must be in the correct boot mode. To manually enter the firmware download or flash mode, where you can program your EPS32, you typically have to press the BOOT (or GPIO0) and EN (or RESET) buttons on your development board (more about that later).
Since this is cumbersome, many boards support an automatic bootloader, where the programming software (e.g. Arduino IDE, esptool) controls the boot mode via the USB to serial converter chip on the development board.
However, the automatic bootloader relies on a specific circuit involving the GPIO0
and ENABLE
pins of the ESP32. For some development boards this circuit is incorrect/missing and the automatic bootloader does not work properly or not at all. Which leads to the error: “Wrong boot mode detected (0x13)
“, when trying to download code to the ESP32.
The next two sections describe in more detail what is causing the downloading problem. But you can skip these, if you are only interested in the possible solutions for this problem.
How the automatic bootloader is wired and activated
An ESP32 development board typically has a USB connector, which apart from the power supply has two data lines USB_DN
and USB_DP
as shown int the schematic for the ESP32 Devkit-C below:
The USB_DN
and USB_DP
data lines are connected to a USB to serial/UART converter chip (e.g. CP2102N) that converts the USB data to serial data on the TXD
and RXD
lines. Most importantly, it also generates the signals DTR
and DSR
, which control the data flow. Again see the schematic around the CP2102N of the ESP32 Devkit-C below:
The control signals DTR
and DSR
are then fed into a “programming” circuit that is connected to the EN(ABLE)
and (GP)IO0
pins of the ESP32:
Here is the truth table that describes the function of this “programming” circuit:
But to actually make the programming work the EN
pin also needs to be connected to an RC circuit that is composed of a Resistor (R11) and a Capacitor (C9), which introduces a time delay of the EN
signal:
And this is where the core of the problem lies. Some development boards either don’t have this RC circuit or have the wrong values for the Resistor or Capacitor. More about this in the next section and for even more details read the ESP32 documentation on boot mode selection.
Why the automatic bootloader doesn’t work
To switch an ESP32 into download mode you have to change from a state where the ENABLE
pin is high and the GPIO0
pin is low, to a state where ENABLE
is low and GPIO0
is low. If you want to know all the nitty-gritty details, read this excellent post: Understanding the automatic boot loader mechanism and truth table.
The switch to download mode is time sensitive and the Datasheet for the ESP32-WROVER-E board, for instance, states:
To ensure the power supply to the ESP32 chip during power-up, it is advised to add an RC delay circuit at the
EN
pin. The recommended setting for the RC delay circuit is usually R = 10 kΩ and C = 1 µF.
However, specific parameters should be adjusted based on the power-up timing of the module and the power-up and reset sequence timing of the chip. For ESP32’s power-up and reset sequence timing diagram, please refer to Section Power Scheme in ESP32 Datasheet.The following picture shows the RC circuit (marked with a yellow rectangle) for the ESP32-WROVER-E development board. Note that the values for R1 and C3 are denoted as TBD (To Be Decided):
For some development boards this RC circuit is missing or the values for R1 and C3 are inadequate, and therefore the automatic bootloader doesn’t work. In this case, you will get the error message “Wrong boot mode detected (0x13)!
“, when trying to program the chip. Below an example error message using the Arduino IDE and trying to download code to a WEMOS Lolin 32D board:
In the next sections, I show you two manual methods to switch an ESP32 to download mode and two hardware circuits you can add to get the automatic bootloader working. It will depend on the specific development board, what works or not.
Solutions for Wrong boot mode detected
Solution 1: Press BOOT and then RESET Button
To manually switching an ESP32 board into download mode you have to first press and hold the [BOOT]
(or [IO0]
) button. Then start the download, e.g. in the Arduino IDE by pressing the arrow button. Wait until the text “Connecting…” appears. And finally press and release the [RESET]
(or [EN]
) button. The diagram below shows you the timing:
This procedure is, for instance, required to program an ESP32-cam board. It will be the same or similar for other development boards that lack the RC circuit and do not support the automatic at all.
Unfortunately there are variations on this timing. Apparently, there are board where you have to press the [BOOT]
button when you see the “Connecting…” text but not before.
Once you have finished flashing your board, it will stay in download mode until you press [RESET]
to get it booting normally again.
Finally, depending on the board the two buttons are either labelled Reset
or EN
or Enable
, and Boot
or IO0
or GPIO0
. The following picture shows the a ESP-WROOM-32 development board with the [EN]
and the [BOOT]
button:
But again, there are variations on this. For instance, the WEMOS Lolin 32D board has only a [RESET]
button.
Solution 2: Press RESET Button
For development boards such as the WEMOS Lolin 32 classic, the WEMOS Lolin 32D board or the WEMOS Lolin 32D Pro that have only a [RESET]
button (but no [BOOT]
), it is sufficient to press and release the [RESET]
button when the text “Connecting…” appears.
This will switch the WEMOS Lolin 32D and the other Lolin boards into download mode and the program will start to run, once the download is finished. While this is much better than having to juggle the [EN]
button and the [BOOT]
button, it is still not fully automatic.
Solution 3: 10kΩ Resistor between GPIO0 and GND
For the WEMOS Lolin 32 classic, the WEMOS Lolin 32D board, the WEMOS Lolin 32D Pro, their clones and probably some other boards, you can enable the automatic bootloader with a simple hardware change. Add a 10kΩ Resistor between GPIO0 and GND as shown below:
With this change you don’t have to press any buttons at all anymore when programming the board via the Arduino IDE. I tested this with the WEMOS Lolin 32D but it probably works with other Lolin boards and clones as well. Interestingly, it is not needed for the WEMOS Lolin 32 lite and clones of that board.
The disadvantage of this solution is that it permanently pulls GPIO0
to ground, so you cannot use it for IO anymore, and it may not work with some boards. A better solution is to add a Capacitor between EN
and ground (GND
) as described in the next section.
Solution 4: 1µF Capacitor between RESET/ENABLE and GND
The datasheet of the ESP32 recommends a 1µF Capacitor for the RC circuit. In some development boards this capacitor is missing or of insufficient capacitance. Adding a 1µF Capacitor between the EN/RESET pin and ground fixes this and the automatic bootloader will then work.
I tested this with the WEMOS Lolin 32 classic, the WEMOS Lolin 32D and it should work for the WEMOS Lolin 32D Pro as well. As mentioned before, it is not needed for the WEMOS Lolin 32 lite and its clones.
When adding the capacitor, watch out for the correct polarity. See the circuit shown below.
If you just need to program the board a few times you can temporarily add the capacitor on a bread board and later remove it, when the board runs permanently:
However, if you regularly want to use the board for development you can solder the capacitor permanently between the EN and the GND pins. The legs of a typical 1µF Capacitor are just long enough for this. See the picture below:
Finally, I also had a DOIT DEVIT V1 ESP32-WROOM-32 board, where the automatic bootloader did not work either. Adding the 1µF Capacitor soldered between EN and GND fixed this as well:
Other Reasons for failing to download
There can be many other reasons why your computer cannot download code to your ESP32. The Troubleshooting Guide for the ESP32 lists the following things you can try:
- Check you are passing the correct serial port on the command line.
- Check you have permissions to access the serial port, and other software (such as modem-manager on Linux) is not trying to interact with it. A common pitfall is leaving a serial terminal accessing this port open in another window and forgetting about it.
- Check the chip is receiving 3.3V from a stable power source (see Insufficient Power for more details.)
- Check that all pins are connected as described in Boot Mode Selection. Check the voltages at each pin with a multimeter, “high” pins should be close to 3.3V and “low” pins should be close to 0V.
- If you have connected other devices to GPIO pins, try removing them and see if esptool starts working.
- Try using a slower baud rate (
-b 9600
is a very slow value that you can use to verify it’s not a baud rate problem).
Conclusions
This tutorial showed you how to switch an ESP32 into download mode, which enables the programming of the ESP32. Depending on the development board this can be a fully automatic process, or requires some hardware changes to enable the automatic bootloader.
Without a schematic of the specific development board you will not know what specific capacitor or resistor is needed to fix the RC circuit. But a 1µF Capacitor or 10kΩ Resistor should work in most cases. If not, just try different values. It is unlikely that you will damage the board.
If you have any questions feel free to leave them in the comment section.
Links
- ESP32 Flashing Problems
- Boot Mode Selection
- Understanding the automatic boot loader mechanism and truth table
- Trouble using the esptool with Lolin D32 Pro and Lolin D32 boards
- ESP32 Troubleshooting Flashing
- ESP32-WROVER-E Datasheet
- ESP32 Technical Documents
- How to flash an ESP32 on production
Stefan is a professional software developer and researcher. He has worked in robotics, bioinformatics, image/audio processing and education at Siemens, IBM and Google. He specializes in AI and machine learning and has a keen interest in DIY projects involving Arduino and 3D printing.