Getting the unexpected makers esp32 s2 board to program from the Arduino IDE or CLI
Summary
Press the buttton marked ‘BOOT’ on the board while the board flashes.
Or:
Jumper GPIO0 to GND. After flashing, remove the jumper and press the RST button on the board.
Problem
Tyring to flash code to my shiney new Unexpected Makers feather esp32 s2 board I repeatedly get this error code:
serial.serialutil.SerialTimeoutException: Write timeout
This is thrown by the script esptool.py which is used to flash the target board.
Troubleshooting
I am using the Arduino IDE to try to build and flash a simple ‘blinky’ program.
I try using the arduino-cli command to manually build the source file and send the binary to the ESP32 S2 board.
Both methods fail with the same ‘Write timeout’ message, thrown by the file esptool.py. Fair enough, the IDE and the command line tools both use the same file, esptools.py, to program the board with.
I check that the serial port connecting my computer to the ESP32 S2 board exists using:
ls /dev/ttyA*
This returns:
/dev/ttyACM0
Unplugging the board causes this port to disappear, re-plugging it causes it to come back. So there is a serial port connection between the computer and the board.
I look for solutions on the web. On this stackoverflow answer I come across the idea of grounding GPIO0. The answer refers to an ESP8266 though. Worth a try.
I jumper GPIO0 to ground. Please see the photo below. I added the female header blocks to the board.The board programs from the Arduino IDE!
You need to press the RST button on the board after loading the code.
Unexpected Makers ESP32 S2 board with GPIO connected to GND
Explanation
I found an explanation of why this fix works in the esptool documentation
On many development boards with built-in USB/Serial, esptool.py can automatically reset the board into bootloader mode.
Not on this board.
The ESP32 will enter the serial bootloader when GPIO0 is held low on reset. Otherwise it will run the program in flash.
We need the bootloader mode, so GPIO0 needs to be held low.
Let’s think about serial port signals. One good resource is this page.
GPIO0 has an internal pullup resistor, so if it is left unconnected then it will pull high.
There we go. By default, GPIO0 is high. So we need to tie it low to get to bootloader mode.
If you are using the jumper wire between GPIO0 and GND, to get it out of bootloader mode, the jumper needs to be removed and the RST button pressed.
Once I figured this out, I noticed the little button marked BOOT on the board. Pushing this while flashing the board also works.
The simplest serial interface needs three connections. Transmit, receive and ground.
A fuller implementation of the serial interface implements extra control signals such request to send (RTS), clear to send (CTS) and data terminal ready (DTR). Explaining how a serial connection is set up and controlled is beyond the scope of this post.
Reading further into the Espressif documents:
esptool.py is not able to reset your hardware automatically in the following cases: Your hardware does not have the DTR and RTS lines connected to GPIO0 and CHIP_PU (EN)
I suspect that the Unexpected Makers board is missing the DTR connection. I stand to be corrected though.