If you decide the revert your Wemos D1 Mini to the factory default firmware, you will discover that it is more complicated than necessary.


Let's setup the pieces.

BINs and Offsets

The default firmware is divided into numerous pieces, at least since the firmware 2.1.0. If you were using the NodeMCU custom builds, their build packages everything into one firmware blob. The AT firmware that comes with the Espress SDK is divided into four blobs:

  • bin/boot_v1.7.bin
  • bin/at/512+512/user1.1024.new.2.bin (4MB Flash = 32Mbit, 512+512)
  • bin/esp_init_data_default.bin
  • bin/blank.bin (twice)

The specific bin/at folder contains a ''README.md'' that lists a confusing list of options for selecting offsets. The table below is a precise list of the offsets needed for the D1 Mini. Offsets are an address that another firmware blob will go when looking for the next command or just a place to write configuration variables. If the offsets are too close together, the firmware tool will complain that there are overlapping offsets. Not in the right place and they may never get found or may leave previous settings exposed.

A review of the specs for the D1 mini clocks in with 4MB (32Mbit) of flash, but the reason for 512+512 is buried somewhere. Zerythn docs say that it is a 4K sector flash chip, which is 1024+1024, but they also claim to be 80MHz clock. I have been unable to use the 80MHz clock as the firmware corrupts on my Mini. Either way, the README.md for the AT firmware breaks down the offsets like this:

SDK Firmware File Flashing Offset
bin/boot_v1.7.bin 0x0000
bin/at/512+512/user1.1024.new.2.bin 0x01000
bin/esp_init_data_default.bin 0x3fc000
bin/blank.bin 0x7e000
bin/blank.bin 0x3fe000

Script to Load the Firmware

Included below is a script to load the firmware from an Ubuntu 16.04. You should edit the ESPToolDir and FirmwareDir to match your ESPTool folder and SDK extracted download folder, respectively.

cd "$FirmwareDir" 
if [ ! -c $port ]; then
if [ ! -c $port ]; then
   echo "No device appears to be plugged in.  Stopping."
printf "Writing AT firmware to the Wemos D1 Mini in 3..."
sleep 1; printf "2..."
sleep 1; printf "1..."
sleep 1; echo "done."
echo "Erasing the flash first"
"$ESPToolDir/esptool.py" --port $port erase_flash
"$ESPToolDir/esptool.py" --chip esp8266 --port $port \
   write_flash -fm dio -ff 20m -fs detect \
   0x0000 "$FirmwareDir/bin/boot_v1.7.bin" \
   0x01000 "$FirmwareDir/bin/at/512+512/user1.1024.new.2.bin" \
   0x3fc000 "$FirmwareDir/bin/esp_init_data_default.bin"  \
   0x7e000 "$FirmwareDir/bin/blank.bin"  \
   0x3fe000 "$FirmwareDir/bin/blank.bin"
echo "Check the boot by typing: miniterm $port 74800"
echo " and then resetting.  Use Ctrl-] to quit miniterm,"

Two important flags have caused some corruption issues on one or more Wemos D1 minis. The 80MHz clock speed is one, and the script above sets it to 20MHz during flashing (-ff 20m). ESPTool apparently detects the 80MHz clock, so we've overridden the default. The second is quad vs dual IO to the flash (-fm dio). Short answer, just slow down the flash process and it goes in more reliably. It may be possible to make these both go a little faster, but most of us don't flash firmware six and seven times an hour. We don't mind waiting another 10 seconds to load a flash image.

Side Note

If you want to load another firmware blob, the above script still works, just use the first offset of 0x0000 followed by the path to your non-AT firmware blob. Likely, the other firmware includes the boot loader and other SDK-specific blobs, so none of them or their offsets will be required. Much simpler.