Flashing an ESP32 is a two-minute job when it goes well. This page covers the normal path, the parts that trip people up, and what to do when it does not go well.
- An ESP32 development board — see which one to buy
- A USB cable that carries data. This is the single most common cause of a board that "does not show up". Many cables sold with phones and power banks have only the two power wires. If nothing appears when you plug the board in, change the cable first.
- Python 3.8 or newer on your computer. The installer checks and tells you how to get it if it is missing.
You do not need ESP-IDF, a compiler, Arduino, or any development environment. The firmware is already built.
Plug the board in, then run one line.
curl -fsSL https://raw.githubusercontent.com/AliAkrami1375/DRouter-Firmware/main/install.sh | bashOpen PowerShell (press Start, type powershell, press Enter) and run:
irm https://raw.githubusercontent.com/AliAkrami1375/DRouter-Firmware/main/install.ps1 | iexIf Windows refuses to run the script, it is the execution policy. Allow it for this session only:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
irm https://raw.githubusercontent.com/AliAkrami1375/DRouter-Firmware/main/install.ps1 | iexThat setting reverts when you close the window; it does not change anything permanently.
Worth knowing, since you are piping a script from the internet into a shell:
- Checks for Python 3.8+ and stops with instructions if it is missing.
- Creates an isolated Python environment in
~/.drouter(%USERPROFILE%\.drouteron Windows) and installsesptool— Espressif's official flashing tool — into it. Nothing is installed system-wide, nothing needssudoor administrator rights, and no existing Python setup is touched. - Lists your serial ports and picks the one that looks like an ESP32, recognising the usual USB-serial chips (CP210x, CH340, FTDI) and Espressif's built-in USB. If more than one is plausible, it asks.
- Asks the board what chip it is rather than guessing.
- Downloads the matching firmware and verifies it against its published SHA-256. A mismatch aborts before anything is written. It looks in the GitHub release first, and falls back to the copy kept in this repository under
firmware/— either way the checksum is checked. - Writes the images at the offsets recorded by the build that produced them, then clears the OTA boot selector so the board starts what was just installed.
To remove everything the installer put on your computer, delete ~/.drouter. The firmware on the board is unaffected.
./install.sh --dry-run --chip esp32s3Downloads, verifies and prints the exact offsets it would write — without touching the board.
Both installers accept the same options, in their platform's style:
| What you want | Linux / macOS | Windows |
|---|---|---|
| Choose the port yourself | ./install.sh --port /dev/ttyUSB0 |
.\install.ps1 -Port COM5 |
| Wipe settings and accounts too | ./install.sh --erase |
.\install.ps1 -Erase |
| Install a specific release | ./install.sh --version v0.2.0 |
.\install.ps1 -FirmwareVersion v0.2.0 |
| Install a file you downloaded | ./install.sh --file drouter-esp32s3-v0.1.0.zip |
.\install.ps1 -File drouter-esp32s3-v0.1.0.zip |
| Flash more slowly (flaky cables) | ./install.sh --baud 115200 |
.\install.ps1 -Baud 115200 |
| Just list the serial ports | ./install.sh --list-ports |
.\install.ps1 -ListPorts |
Most boards need a driver for their USB-serial chip. Look at the small chip next to the USB socket, or read what your operating system reports.
| Chip on the board | Windows | macOS | Linux |
|---|---|---|---|
| CP2102 / CP2104 (Silicon Labs) | Download the driver | Download the driver | Built in |
| CH340 / CH9102 (WCH) | Download the driver | Download the driver | Built in |
| FTDI FT232 | Usually automatic | Built in | Built in |
| Native USB (ESP32-S3, C3, C6) | Automatic | Automatic | Built in |
Reboot after installing a driver on Windows, or at least unplug and replug the board.
Linux gives serial devices to the dialout group. Add yourself once:
sudo usermod -aG dialout $USERThen log out and back in — group membership only applies to new sessions. A reboot works too.
To check whether it took effect:
groups | grep dialoutIf you would rather not change groups, you can open the port for a single session:
sudo chmod a+rw /dev/ttyUSB0That resets when the board is unplugged.
Most development boards reset themselves into the bootloader automatically, and you never think about it. Some — bare modules, some clones, boards with an unusual auto-reset circuit — need to be told by hand.
If the installer says "the board did not answer":
- Hold down the BOOT button (sometimes labelled IO0 or FLASH).
- While still holding it, tap RESET (sometimes EN).
- Let go of BOOT.
- Run the installer again.
The board is now sitting in its bootloader waiting for firmware, and will stay there until it is reset again.
If you would rather not run a script from the internet, or you are on a machine that cannot:
# 1. install esptool however you like
python3 -m pip install --user esptool
# 2. download the zip for your chip from the releases page
# https://github.com/AliAkrami1375/DRouter-Firmware/releases
unzip drouter-esp32s3-v0.1.0.zip -d drouter
# 3. check what the bundle expects — offsets come from the build itself
cat drouter/manifest.json
# 4. write every image at the offset that file gives, for example:
python3 -m esptool --chip esp32s3 --port /dev/ttyUSB0 --baud 460800 \
write_flash --flash_mode dio --flash_freq 40m --flash_size detect \
0x0 drouter/bootloader.bin \
0x8000 drouter/partition-table.bin \
0x19000 drouter/ota_data_initial.bin \
0x20000 drouter/drouter.binota_data_initial.bin is the boot selector, and writing it is what points the
board at the image you just installed. Do not skip it.
Always take the offsets from the manifest.json inside the zip rather than copying them from here — they are recorded by the build that produced those exact images, and they differ between chips.
Verify what you downloaded first:
sha256sum -c SHA256SUMS.txt --ignore-missing- Look for a Wi-Fi network called DRouter and join it. It is open until you set a password.
- Open http://192.168.4.1/ (or http://drouter.local/).
- The first password you type becomes the admin password.
Continue with Getting started.
Run the same command again. It fetches the newest release and writes it.
Settings, accounts and traffic counters live in a separate area of flash (NVS) that an update never writes to, so an upgrade keeps everything. Use --erase when you want a genuinely clean board.
See Troubleshooting — it covers boards that will not appear, ports that will not open, flashes that fail partway, and boards that come up on the wrong firmware.