2023-09-05
md
Installing the AT Firmware on an ESP-01S

ESP-01 image How hard can it be to install the ESP-AT firmware onto an ESP-01? It was not all that clear to me how to proceed. Consequently, it has taken more than a year since the release of the first version of this post which showed how to install ESP-AT version 1.7.5, to release this second version which contains instructions on installing ESP-AT version 2.2.1. These are the currently newest versions of ESP-AT that are based on the ESP8266 NonOS SDK and the ESP8266 RTOS SDK respectively.

The tiny ESP-01 board which came with Espressif's version of the AT firmware was among the first boards with an Espressif chip used in the hobbyist world. The original version of the ESP-01 had 512 Kbytes of flash memory, but it was quickly upgraded to 1 MBytes. These newer boards with more flash memory are often labelled ESP-01S (see Differences between ESP-01 and ESP-01S). Currently, a version of ESP-AT can be installed on ESP8266 boards with 1 MB of flash memory. As far as I know, there is no support for ESP-AT on modules with less than 1 MByte of flash memory. Indeed, the full version of ESP-AT requires 2 MB of flash memory and consequently the versions installed on the ESP-01S do not have all the features of the full versions.

If you are not old enough to remember configuring modems with Hayes AT commands and are wondering what AT firmware is all about, see What is ESP-AT. And no, I am not going to explain what a modem is!

Table of contents

  1. Basics: Serial Connection with the ESP01
  2. Updating Older Versions to ESP-AT Version 1.7.5
  3. Installing esptool.py and at.py
  4. Installing ESP-AT Version 1.7.5
  5. Installing ESP-AT Version 2.2.1
  6. About the esptool.py Parameters
  7. Other Implementations
  8. Which Version?

Basics: Serial Connection with the ESP01 toc

Serial monitor in Arduino IDEESP8266 module programmer As can be seen on the left, four general-purpose input/output pins (GPIO0 to GPIO3), the chip enable and reset pins, ground and the Vcc input are connected to the eight pin header at the bottom of the board. GPIO1 and GPIO3 are used as the TX and RX signals of a serial (UART) peripheral. For most a serial to USB adapter will be required to connect a computer to the ESP01 board. Although the header is standard 0.1" the ESP01 is not breadboard compatible so it will be necessary to set up some sort of a jig to connect to the ESP01 and to program it. There are many tutorials on that subject on the Web. I chose the easy way out, preferring to use a relatively inexpensive bare ESP8266 module programmer that happens to handle ESP01 boards. Make sure to plug the ESP01 into the ESP-01S socket with the antenna up in the same orientation as shown on the left. It is easy to upload new firmware to the board with the command line esptool.py utility from Espressif without having to worry about pressing buttons to put the board into programming mode. Of course, the programmer also acts as a USB to serial converter.

The Arduino IDE will not be used here, but if it is installed then its Serial Monitor can be used to send AT commands and receive the output from the AT firmware on the ESP01. Set the baud to 115200 and Both NL & CR for line ending.

Serial monitor in Arduino IDE

Similarly, the serial terminal in PlatformIO can be used to communicate with PlatformI0. Create a new project and use the following settings in the project configuration file (platformio.ini).

[env:esp01_1m] platform = espressif8266 board = esp01_1m framework = arduino monitor_speed = 115200 monitor_eol = CRLF monitor_echo = no monitor_port = /dev/ttyUSB1 upload_port = /dev/ttyUSB1

Serial monitor in PlatformIO

Alternatively, a stand-alone terminal program can be used. On my Linux machine, I use cu (actually opencu). It is a very light serial terminal emulator and, consequently, so basic that the line feed character has to be entered with the Ctrl+J keyboard combination after pressing the Enter key (or Ctrl+M combination) the at the end of each command.

michel@hp:~$ cu -l /dev/ttyUSB1 Enter Connected to /dev/ttyUSB1 (speed 115200) AT Enter Ctrl+J OK AT+GMR Ctrl+M Ctrl+J AT version:1.7.5.0(Oct 20 2021 19:14:04) SDK version:3.0.5(b29dcd3) compile time:Oct 20 2021 20:13:50 Bin version(Wroom 02):1.7.5 OK

Because it is very tedious to type, the end of line characters will not be shown from now on.

Updating Older AT Versions to Version 1.7.5 toc

If the ESP01 is currently running a stock version of ESP-AT version 1.7.4, it is possible to update to version 1.7.5 (see Update steps).

AT+CWMODE_CUR=1 OK AT+CWLAP +CWLAP:(3,"Welcome!!",-84,"18:90:88:56:3d:c6",1,33,0,4,4,7,0) +CWLAP:(3,"",-87,"d6:e2:cb:4d:71:fa",6,32767,0,4,4,7,0) +CWLAP:(5,"",-89,"d6:e2:cb:4d:71:fe",6,32767,0,4,4,7,0) +CWLAP:(3,"Playtek",-47,"f7:ae:42:42:43:44",11,32767,0,4,4,7,1) +CWLAP:(3,"",-84,"fa:5e:42:43:6b:13",11,32767,0,4,4,7,0) +CWLAP:(5,"",-86,"fa:5e:42:43:6b:17",11,32767,0,4,4,7,0) OK AT+CWJAP="Playtek","12345678" adjust name and password as needed WIFI CONNECTED WIFI GOT IP OK AT+CIFSR +CIFSR:STAIP,"192.168.1.143" +CIFSR:STAMAC,"a0:20:93:30:31:32" OK AT+GMR AT version:1.7.4.0(May 11 2020 19:13:04) SDK version:3.0.4(9532ceb) compile time:May 27 2020 10:12:17 Bin version(Wroom 02):1.7.4 OK AT+CIUPDATE +CIPUPDATE:1 +CIPUPDATE:2 +CIPUPDATE:3 +CIPUPDATE:4 be patient, it takes a couple of minutes OK WIFI DISCONNECT ets Jan 8 2013,rst cause:1, boot mode:(3,6) load 0x40100000, len 816, room 16 tail 0 chksum 0x8d load 0x3ffe8000, len 788, room 8 tail 12 chksum 0xcf ho 0 tail 12 room 4 load 0x3ffe8314, len 288, room 12 tail 4 chksum 0xcf csum 0xcf 2nd boot version : 1.2 SPI Speed : 80MHz SPI Mode : SPI Flash Size : 8Mbit jump to run user2 correct flash map �cl`{�o$ ... �crd;l ready WIFI CONNECTED WIFI GOT IP AT+GMR AT version:1.7.5.0(Oct 20 2021 19:14:04) SDK version:3.0.5(b29dcd3) compile time:Oct 20 2021 20:13:50 Bin version(Wroom 02):1.7.5 OK

I power cycled the ESP-01 just to make sure that everything worked.

It does not appear that there is an upgrade path beyond 1.7.5. The AT+CIUPDATE command did nothing useful when the firmware is already at version 1.7.5. Later it may be possible to update if there's ever a newer version created in the ESP8266 NonOS environment. I cannot say if this approach works older versions of the firmware but it was not possible to update AT version 1.3.0 in this fashion.

The advantage of this approach is that the update only requires a terminal emulator to enter AT commands on the ESP01 and a functioning connection from the ESP to the Internet to download the update. If it is not possible to perform on over-the-air update to the desired version of ESP-AT, then new firmware will have to be uploaded to the board over the USB connection.

Installing esptool.py and at.py toc

There are utilities that can upload firmware to the ESP that provide a graphical interface and that may be more convivial than the command line utility esptool.py from Espressif. However the latter is a Python script that should run on Windows, Mac OS and Linux. Furthermore it is simpler to document how to use it in a written text. As if often the case, there are many ways to install the utility (see ), I prefer to do it within a Python virtual environment. I am still using virtual environment schema that I put in place in 2017 ( and which has been described in other posts on this side. There is no need to repeat any of that.

michel@hp:~$ mkvenv ve_esptool creating virtual environment /home/michel/ve_esptool updating virtual environment /home/michel/ve_esptool michel@hp:~$ ve ve_esptool (ve_esptool) michel@hp:~$ pip install esptool Collecting esptool Using cached esptool-4.6.2-py3-none-any.whl Collecting bitstring>=3.1.6 (from esptool) Obtaining dependency information for bitstring>=3.1.6 from https://files.pythonhosted.org/packages/f8/36/e0053ec177e193d719455d3d74877a075b1b58addd50b853b738a687aa3c/bitstring-4.1.1-py3-none-any.whl.metadata Using cached bitstring-4.1.1-py3-none-any.whl.metadata (5.4 kB) Collecting cryptography>=2.1.4 (from esptool) Obtaining dependency information for cryptography>=2.1.4 from https://files.pythonhosted.org/packages/46/74/f9eba8c947f57991b5dd5e45797fdc68cc70e444c32e6b952b512d42aba5/cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl.metadata Using cached cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl.metadata (5.2 kB) Collecting ecdsa>=0.16.0 (from esptool) Using cached ecdsa-0.18.0-py2.py3-none-any.whl (142 kB) Collecting pyserial>=3.0 (from esptool) Using cached pyserial-3.5-py2.py3-none-any.whl (90 kB) Collecting reedsolo<1.8,>=1.5.3 (from esptool) Using cached reedsolo-1.7.0-py3-none-any.whl (32 kB) Collecting PyYAML>=5.1 (from esptool) Obtaining dependency information for PyYAML>=5.1 from https://files.pythonhosted.org/packages/29/61/bf33c6c85c55bc45a29eee3195848ff2d518d84735eb0e2d8cb42e0d285e/PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata Using cached PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (2.1 kB) Collecting bitarray<3.0.0,>=2.8.0 (from bitstring>=3.1.6->esptool) Obtaining dependency information for bitarray<3.0.0,>=2.8.0 from https://files.pythonhosted.org/packages/5b/81/938e947b54e6e1eee683c069fb19d35ee0c292fc91d7b10eaab84611439b/bitarray-2.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata Using cached bitarray-2.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (32 kB) Collecting cffi>=1.12 (from cryptography>=2.1.4->esptool) Using cached cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB) Collecting six>=1.9.0 (from ecdsa>=0.16.0->esptool) Using cached six-1.16.0-py2.py3-none-any.whl (11 kB) Collecting pycparser (from cffi>=1.12->cryptography>=2.1.4->esptool) Using cached pycparser-2.21-py2.py3-none-any.whl (118 kB) Using cached bitstring-4.1.1-py3-none-any.whl (56 kB) Using cached cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl (4.3 MB) Using cached PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (705 kB) Using cached bitarray-2.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (286 kB) Installing collected packages: reedsolo, pyserial, bitarray, six, PyYAML, pycparser, bitstring, ecdsa, cffi, cryptography, esptool Successfully installed PyYAML-6.0.1 bitarray-2.8.1 bitstring-4.1.1 cffi-1.15.1 cryptography-41.0.3 ecdsa-0.18.0 esptool-4.6.2 pycparser-2.21 pyserial-3.5 reedsolo-1.7.0 six-1.16.0 (ve_esptool) michel@hp:~$ esptool.py version esptool.py v4.6.2 4.6.2

If ESP-AT version 2+ is desired then another utility named at.py is needed.

(ve_esptool) michel@hp:~$ wget https://github.com/espressif/esp-at/raw/master/tools/at.py -O ve_esptool/bin/at.py --2023-09-06 17:32:39-- https://github.com/espressif/esp-at/raw/master/tools/at.py ... 2023-09-06 17:32:40 (2,35 MB/s) - ‘ve_esptool/bin/at.py’ enregistré [62528/62528] (ve_esptool) michel@hp:~$ chmod +x ve_esptool/bin/at.py (ve_esptool) michel@hp:~$ ls -l ve_esptool/bin/at.py checking that at.py is executable -rwxrwxr-x 1 michel michel 62528 sep 6 17:32 ve_esptool/bin/at.py (ve_esptool) michel@hp:~$ at.py version v1.0-dev

Installing ESP-AT Version 1.7.5 toc

Following the second suggestion from Robert Oostenveld in Restoring the AT firmware on the ESP8266 (September 22, 2018), I went to the latest version of the ESP8266 NonOS repository which is now two years old. There is a warning stressing that the ESP8266_NONOS_SDK is now deprecated.

Starting from December 2019, We will not add any new features to the ESP8266 NonOS SDK. We will only fix critical bugs in the ESP8266 NonOS SDK. We will only maintain the master branch of ESP8266 NonOS SDK, which is a continuously bug-fix version based on v3.0. This means: All other released branches will not be updated. All the future versions will be released from only the master branch mentioned above. It is suggested that the ESP8266_RTOS_SDK, instead of ESP8266 NonOS SDK, be used for your projects.

Nevertheless the bin/at/ directory contains the Nano version of ESP-AT 1.7.4 which supports an SSL library with fewer ciphers but which fits on 1 MB of flash memory which corresponds to the amount of flash on "newer" versions of the ESP-01 sometimes identified as the ESP-01S . The "normal" version of the AT firmware requires at least 2 MB of flash, so it cannot be installed on the EPS-01. That version of AT is in the master branch of the repository which corresponds to version 3.0.4 of the SDK. As it happens there is a version 3.0.5 branch which contains version 1.7.5 of the AT firmware, which as of now is the latest version of AT within the NOOS SDK.

I only needed three binary files from the repository.

I created a directory to contain the V1.75 binaries and downloaded the files into it.

(ve_esptool) michel@hp:~$ mkdir -p ve_esptool/ESP-AT/v1.7.5 (ve_esptool) michel@hp:~$ cd ve_esptool/ESP-AT/v1.7.5/ (ve_esptool) michel@hp:~$~/ve_esptool/ESP-AT/v1.7.5$ wget https://github.com/espressif/ESP8266_NONOS_SDK/raw/release/v3.0.5/bin/boot_v1.7.bin https://github.com/espressif/ESP8266_NONOS_SDK/raw/release/v3.0.5/bin/esp_init_data_default_v08.bin https://github.com/espressif/ESP8266_NONOS_SDK/raw/release/v3.0.5/bin/at/512%2B512/user1.1024.new.2.bin

Then I created a text file named upload.txt which contains the name of the binary files to flash to the ESP01 along with the address at which they are to be placed in the flash memory.

write_flash --erase-all --flash_mode qio --flash_freq 40m --flash_size 1MB 0x00000 boot_v1.7.bin 0x01000 user1.1024.new.2.bin 0xfc000 esp_init_data_default_v08.bin

The last three lines are pulled from the Flash size 8Mbit: 512KB+512KB section in the AT documentation in the repository. The first line contains upload parameters for the esptool.py utility

(ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v1.7.5$ ls boot_v1.2.bin esp_init_data_default_v05.bin upload.txt user1.1024.new.2.bin (ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v1.7.5$ esptool.py -p /dev/ttyUSB1 -b 115200 @upload.txt esptool /dev/ttyUSB1 -b 115200 write_flash -e --flash_mode qio --flash_freq 40m --flash_size 1MB 0x00000 boot_v1.2.bin 0x01000 user1.1024.new.2.bin 0xfc000 esp_init_data_default_v05.bin esptool.py v4.6.2 Serial port /dev/ttyUSB1 Connecting.... Detecting chip type... Unsupported detection protocol, switching and trying again... Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: a0:20:a6:30:e3:35 Uploading stub... Running stub... Stub running... Configuring flash size... Erasing flash (this may take a while)... Chip erase completed successfully in 2.1s Flash params set to 0x0020 Compressed 1936 bytes to 1461... Wrote 1936 bytes (1461 compressed) at 0x00000000 in 0.2 seconds (effective 86.4 kbit/s)... Hash of data verified. Compressed 413924 bytes to 297091... Wrote 413924 bytes (297091 compressed) at 0x00001000 in 26.2 seconds (effective 126.2 kbit/s)... Hash of data verified. Compressed 128 bytes to 75... Wrote 128 bytes (75 compressed) at 0x000fc000 in 0.1 seconds (effective 19.1 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...

Just to make sure, reset the ESP-01 or turn power to it off then back on. It should show up as the same device/COM port as before. Open a serial connection to the board and verify that AT commands are executed and get the version.

michel@hp:~$ cu -l /dev/ttyUSB0 -s 115200 Connected. AT OK AT+GMR AT version:1.7.5.0(Oct 20 2021 19:14:04) SDK version:3.0.5(b29dcd3) compile time:Oct 20 2021 20:13:45 Bin version(Wroom 02):1.7.5 OK

That's a confirmation that version 1.7.5 (October 20, 2021) of the AT firmware is now running on the ESP-01S.

Alternate installation

The ESP-AT resources page has the following entry: ESP8266 NonOS AT Bin V1.7.5 (2021.10.18). It contains a link to a ZIP archive https://www.espressif.com/sites/default/files/ap/ESP8266_NonOS_AT_Bin_V1.7.5_1.zip. Using that source to upload using upload.txt from above installs the following version.

  AT version:1.7.5.0(Oct  9 2021 09:26:04)
  SDK version:3.0.5(b29dcd3)
  compile time:Oct 15 2021 18:05:30
  Bin version(Wroom 02):1.7.5

It is a few days older than the version downloaded from the GitHub repository.


Installing EST-AT Version 2.2.1 toc

In the Released Firmware page of the ESP-AT User Guide, there is an important note.

Note: Espressif has not released a separate version for the 1 MB ESP8285/8266 series of chips, but you can refer to How to Download the Latest Temporary Version of AT Firmware from GitHub and choose to download the 1 MB firmware on the CI (Continuous Integration) of GitHub (Please switch to release/v2.2.0.0_esp8266 branch and download esp8285-1MB-at under the Artifacts page). ESP-WROOM-02 Series v2.2.1.0 ESP8266-IDF-AT_V2.2.1.0.zip (Recommended) v2.2.0.0 ESP8266-IDF-AT_V2.2.0.0.zip v2.1.0.0 ESP8266-IDF-AT_V2.1.0.0.zip v2.0.0.0 ESP8266-IDF-AT_V2.0.0.0.zip

Following those instructions, I downloaded esp8285-1MB-at.zip. There is no point in giving a link, the file is quickly removed after being generated. Be aware that it is necessary to have an account on GitHub to generate this file. Here is the content of the archive.

michel@hp:~/ve_esptool/ESP-AT/v2.2.1$ tree . ├── at_customize.bin ├── bootloader │   └── bootloader.bin ├── customized_partitions │   ├── client_ca.bin │   ├── client_cert.bin │   ├── client_key.bin │   ├── factory_param.bin │   ├── factory_param_ESP8266_1MB.bin │   ├── mqtt_ca.bin │   ├── mqtt_cert.bin │   └── mqtt_key.bin ├── download.config ├── esp-at.bin ├── esp-at.elf ├── esp-at.map ├── factory │   ├── factory_ESP8266_1MB.bin │   └── factory_parameter.log ├── flasher_args.json ├── ota_data_initial.bin ├── partition_table │   └── partition-table.bin └── sdkconfig 4 directories, 20 files

I changed the first line of download.config to make it the same as in upload.txt and then proceeded to upload the firmware.

(ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v2.2.1$ esptool.py -p /dev/ttyUSB1 -b 115200 @download.config esptool /dev/ttyUSB1 -b 115200 write_flash --erase-all --flash_mode qio --flash_freq 40m --flash_size 1MB 0x8000 partition_table/partition-table.bin 0x9000 ota_data_initial.bin 0x0 bootloader/bootloader.bin 0x20000 esp-at.bin 0x18000 at_customize.bin 0x1A000 customized_partitions/client_cert.bin 0x1B000 customized_partitions/client_key.bin 0x1C000 customized_partitions/client_ca.bin 0x1D000 customized_partitions/mqtt_cert.bin 0x1E000 customized_partitions/mqtt_key.bin 0x1F000 customized_partitions/mqtt_ca.bin 0x19000 customized_partitions/factory_param.bin esptool.py v4.6.2 Serial port /dev/ttyUSB1 Connecting.... Detecting chip type... Unsupported detection protocol, switching and trying again... Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: a0:20:a6:30:e3:35 Uploading stub... Running stub... Stub running... Configuring flash size... Erasing flash (this may take a while)... Chip erase completed successfully in 2.1s Compressed 3072 bytes to 103... Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 410.4 kbit/s)... Hash of data verified. Compressed 8192 bytes to 31... Wrote 8192 bytes (31 compressed) at 0x00009000 in 0.1 seconds (effective 651.0 kbit/s)... Hash of data verified. Flash params set to 0x0020 Compressed 10864 bytes to 7283... Wrote 10864 bytes (7283 compressed) at 0x00000000 in 0.8 seconds (effective 109.1 kbit/s)... Hash of data verified. Compressed 873952 bytes to 547597... Wrote 873952 bytes (547597 compressed) at 0x00020000 in 48.3 seconds (effective 144.8 kbit/s)... Hash of data verified. Compressed 3072 bytes to 151... Wrote 3072 bytes (151 compressed) at 0x00018000 in 0.1 seconds (effective 359.6 kbit/s)... Hash of data verified. Compressed 2344 bytes to 1487... Wrote 2344 bytes (1487 compressed) at 0x0001a000 in 0.2 seconds (effective 103.2 kbit/s)... Hash of data verified. Compressed 3368 bytes to 2526... Wrote 3368 bytes (2526 compressed) at 0x0001b000 in 0.3 seconds (effective 87.4 kbit/s)... Hash of data verified. Compressed 2344 bytes to 1499... Wrote 2344 bytes (1499 compressed) at 0x0001c000 in 0.2 seconds (effective 87.8 kbit/s)... Hash of data verified. Compressed 1168 bytes to 895... Wrote 1168 bytes (895 compressed) at 0x0001d000 in 0.1 seconds (effective 71.4 kbit/s)... Hash of data verified. Compressed 1692 bytes to 1322... Wrote 1692 bytes (1322 compressed) at 0x0001e000 in 0.2 seconds (effective 80.7 kbit/s)... Hash of data verified. Compressed 1172 bytes to 914... Wrote 1172 bytes (914 compressed) at 0x0001f000 in 0.2 seconds (effective 59.1 kbit/s)... Hash of data verified. Compressed 4096 bytes to 81... Wrote 4096 bytes (81 compressed) at 0x00019000 in 0.1 seconds (effective 365.8 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...

While the uploading appears to proceed correctly, something goes wrong and the blue communication LED remains on even after a power cycle. It was possible to connect to the ESP serial port, but only garbage was received at all plausible baud and AT commands were ignored. Quite recently Arnaud Baixas described the same situation in the Espressif ESP-AT Forum when using the esp8285-1MB-at.zip from a slightly older commit. Unfortunately, no one has offered a solution to our common problem. In the first version of this post, I left it at that. This time around, I was a bit more diligent. Searching the ESP-AT GitHub repository, I found a Sept 2022 issue entitled v2.2.0.0_esp8266 无法启动 #668 which translates to v2.2.0.0_esp8266 Unable to start #668. Ustccw commented that

  Log output should come from GPIO2, not the download port.
  Could you please double check your hardware connection.

Luckily GPIO02 is available on the ESP-01S, so I connected another serial to USB adapter to that pin, opened a terminal and reset the board. Here is the log after some formatting of the output.

michel@hp:~$ cu -l /dev/ttyUSB2 Connected to /dev/ttyUSB2 (speed 115200) pressed the reset button #��no� d`�l�l n{���g �l`s��n I (44) boot: ESP-IDF v3.4-67-g82d8ba2c 2nd stage bootloader I (44) boot: compile time 04:06:34 I (44) boot: SPI Speed : 80MHz I (47) boot: SPI Mode : DOUT I (51) boot: SPI Flash Size : 2MB I (55) boot: Partition Table: I (59) boot: ## Label Usage Type ST Offset Length I (66) boot: 0 otadata OTA data 01 00 00009000 00002000 I (73) boot: 1 nvs WiFi data 01 02 00010000 00008000 I (81) boot: 2 at_customize unknown 40 00 00018000 00008000 I (88) boot: 3 factory factory app 00 00 00020000 000e0000 I (96) boot: End of partition table I (100) boot: Defaulting to factory image I (104) esp_image: segment 0: paddr=0x00020010 vaddr=0x40220010 size=0xb34cc (734412) map I (113) esp_image: segment 1: paddr=0x000d34e4 vaddr=0x402d34dc size=0x1bedc (114396) map I (122) esp_image: segment 2: paddr=0x000ef3c8 vaddr=0x3ffe8000 size=0x00768 ( 1896) load I (131) esp_image: segment 3: paddr=0x000efb38 vaddr=0x40100000 size=0x00080 ( 128) load I (139) esp_image: segment 4: paddr=0x000efbc0 vaddr=0x40100080 size=0x059f0 ( 23024) load I (148) boot: Loaded app from partition at offset 0x20000 phy_version: 1163.0, 665d56c, Jun 24 2020, 10:00:08, RTOS new module_name:ESP8266_1MB max tx power=78,ret=0 2.2.1

According to ustccw's reply to techrah who had almost the same log output, this shows that the firmware is good. Again, ustccw suggests checking the hardware connection. The same day, techrah reported that after carefully reading the information he found two solutions to the problem. So I read hardware connection for the ESP8266, this time with my eyes open, and found that the uploaded ESP-AT switches the serial peripheral (UART0) to different I/O pins. How odd; this didn't happen in V1.7.5 or earlier. On second thought, this made sense if ESP-AT is loaded onto an ESP8266 module with more exposed pins. One would probably want to use a different pair of pins to connect to another MCU that wants to use the ESP to communicate via Wi-Fi without having to deal with a USB connector. But on the ESP-01 there's no such possibility.

It looked like it would be necessary to recompile ESP-AT to undo this and techrah did say where the change had to be made. Of course, I am lazy and don't want to install the ESP-IDF and learn all the intricacies of compiling such a complex program as ESP-AT. Again, ustccw saved the day by pointing out that there is a utility, at.py that can modify the UART configuration in the firmware binary file. So I first planed to read the uploaded firmware from flash memory with esptool, apply the change to the downloaded binary file with at.py and then write the modified binary file back to flash memory with esptool. Then on a hunch, I successfully altered factory/factory_ESP8266_1MB.bin with at.py and uploaded that.

(ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v2.2.1$ at.py modify_bin -tx 1 -rx 3 -cts 13 -rts 15 -in factory/factory_ESP8266_1MB.bin --output espat_esp01s.bin Namespace(operation='modify_bin', platform=None, module_name=None, tx_power=None, uart_num=None, start_channel=None, channel_number=None, country_code=None, baud=None, tx_pin=1, rx_pin=3, cts_pin=13, rts_pin=15, tx_control_pin=None, rx_control_pin=None, server_ca=None, server_cert=None, server_key=None, client_ca0=None, client_ca1=None, client_cert0=None, client_cert1=None, client_key0=None, client_key1=None, mqtt_ca=None, mqtt_cert=None, mqtt_key=None, wpa2_ca=None, wpa2_cert=None, wpa2_key=None, gatts_cfg0=None, gatts_cfg1=None, gatts_cfg2=None, gatts_cfg3=None, gatts_cfg4=None, gatts_cfg5=None, gatts_cfg6=None, gatts_cfg7=None, gatts_cfg8=None, gatts_cfg9=None, gatts_cfg10=None, gatts_cfg11=None, gatts_cfg12=None, gatts_cfg13=None, gatts_cfg14=None, gatts_cfg15=None, gatts_cfg16=None, gatts_cfg17=None, gatts_cfg18=None, gatts_cfg19=None, gatts_cfg20=None, gatts_cfg21=None, gatts_cfg22=None, gatts_cfg23=None, gatts_cfg24=None, gatts_cfg25=None, gatts_cfg26=None, gatts_cfg27=None, gatts_cfg28=None, gatts_cfg29=None, gatts_cfg30=None, parameter_offset=None, input='factory/factory_ESP8266_1MB.bin', output='esp8266_1mb.bin') Modify the binary firmware where the parameters are stored in partitions... factory parameter entry address: 0x19000 raw parameters: (64764, 3, 0, 78, 0, 1, 13, b'C', b'N', b'\x00', b'\x00', 115200, 15, 13, 3, 1, 5, -1, 65535, b'P', b'L', b'A', b'T', b'F', b'O', b'R', b'M', b'_', b'E', b'S', b'P', b'8', b'2', b'6', b'6', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'E', b'S', b'P', b'8', b'2', b'6', b'6', b'_', b'1', b'M', b'B', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00') new parameters: (64764, 3, 0, 78, 0, 1, 13, b'C', b'N', b'\x00', b'\x00', 115200, 1, 3, 13, 15, 5, -1, 65535, b'P', b'L', b'A', b'T', b'F', b'O', b'R', b'M', b'_', b'E', b'S', b'P', b'8', b'2', b'6', b'6', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'E', b'S', b'P', b'8', b'2', b'6', b'6', b'_', b'1', b'M', b'B', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00') New esp-at firmware successfully generated! ----> /home/michel/ve_esptool/ESP-AT/v2.2.1/esp8266_1mb.bin (ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v2.2.1$ ls -l esp8266_1mb.bin -rw-rw-r-- 1 michel michel 1048576 sep 6 20:40 esp8266_1mb.bin

It turns out that at.py was well documented. Once again RTFM!

So now it's just a matter of uploading the modified file to the ESP01.

(ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v2.2.1$ esptool.py -p /dev/ttyUSB1 -b 115200 write_flash -e -fm qio -ff 40m -fs 1MB 0 espat_esp01.bin esptool.py v4.6.2 Serial port /dev/ttyUSB1 Connecting.... Detecting chip type... Unsupported detection protocol, switching and trying again... Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: a0:20:a6:30:e3:35 Uploading stub... Running stub... Stub running... Configuring flash size... Erasing flash (this may take a while)... Chip erase completed successfully in 2.1s Flash params set to 0x0020 Compressed 1048576 bytes to 564899... Wrote 1048576 bytes (564899 compressed) at 0x00000000 in 49.9 seconds (effective 168.1 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...

The log output was different after resetting the ESP01.

I (43) boot: ESP-IDF v3.4-67-g82d8ba2c 2nd stage bootloader I (43) boot: compile time 04:06:34 I (43) qio_mode: Enabling default flash chip QIO I (48) boot: SPI Speed : 40MHz I (52) boot: SPI Mode : QIO I (56) boot: SPI Flash Size : 1MB I (60) boot: Partition Table: I (63) boot: ## Label Usage Type ST Offset Length I (70) boot: 0 otadata OTA data 01 00 00009000 00002000 I (78) boot: 1 nvs WiFi data 01 02 00010000 00008000 I (85) boot: 2 at_customize unknown 40 00 00018000 00008000 I (93) boot: 3 factory factory app 00 00 00020000 000e0000 I (100) boot: End of partition table I (104) boot: Defaulting to factory image I (109) esp_image: segment 0: paddr=0x00020010 vaddr=0x40220010 size=0xb34cc (734412) map I (117) esp_image: segment 1: paddr=0x000d34e4 vaddr=0x402d34dc size=0x1bedc (114396) map I (126) esp_image: segment 2: paddr=0x000ef3c8 vaddr=0x3ffe8000 size=0x00768 ( 1896) load I (135) esp_image: segment 3: paddr=0x000efb38 vaddr=0x40100000 size=0x00080 ( 128) load I (144) esp_image: segment 4: paddr=0x000efbc0 vaddr=0x40100080 size=0x059f0 ( 23024) load I (153) boot: Loaded app from partition at offset 0x20000 phy_version: 1163.0, 665d56c, Jun 24 2020, 10:00:08, RTOS new module_name:ESP8266_1MB max tx power=78,ret=0 2.2.1

The SPI speed (frequency) and mode appear correct. And again, it looks like version 2.2.1 is loaded. Testing with the same serial I/O pins as used to upload the firmware confirmed this.

(ve_esptool) michel@hp:~/ve_esptool/ESP-AT/v2.2.1$ cu -l /dev/ttyUSB1 Connected to /dev/ttyUSB1 (speed 115200) AT OK AT+GMR AT version:2.2.2.0-dev(952f658 - ESP8266 - Nov 23 2022 06:37:28) SDK version:v3.4-67-g82d8ba2c compile time(38991f7):Jul 21 2023 04:07:04 Bin version:2.2.1(ESP8266_1MB) OK AT+CWMODE=1 OK AT+CWLAP +CWLAP:(3,"Welcome!!",-84,"18:90:88:56:3d:c6",1,33,0,4,4,7,0) +CWLAP:(3,"",-87,"d6:e2:cb:4d:71:fa",6,32767,0,4,4,7,0) +CWLAP:(5,"",-89,"d6:e2:cb:4d:71:fe",6,32767,0,4,4,7,0) +CWLAP:(3,"Playtek",-47,"f7:ae:42:42:43:44",11,32767,0,4,4,7,1) +CWLAP:(3,"",-84,"fa:5e:42:43:6b:13",11,32767,0,4,4,7,0) +CWLAP:(5,"",-86,"fa:5e:42:43:6b:17",11,32767,0,4,4,7,0) +CWLAP:(3,"COROBRUN-2",-57,"ec:be:dd:e6:ac:be",1,-1,-1,4,4,7,1) OK AT+CWJAP="Playtek","12345678" WIFI CONNECTED WIFI GOT IP OK AT+CIFSR +CIFSR:STAIP,"192.168.1.205" +CIFSR:STAMAC,"10:20:30:40:50:60" OK AT+PING="192.168.1.1" +PING:2 OK AT+PING="google.com" +PING:25 OK AT+CWQAP WIFI DISCONNECT

On Getting the ESP-AT for the ESP-01S

Not everyone has a GitHub account, and without it, it will be difficult to get the latest esp8285-1MB-at.zip. Consequently, I have made the modified binary espat_esp01.bin available from my account in the other_releases repository. Understand that this is really only for those that want to try ESP8266-AT on an ESP-01S. The file, created on September 5, 2023, will not be updated as new versions of ESP-AT are made available, so that it will soon be necessary to use the procedure described above to get an up-to-date version of the firmware.

The file can be downloaded by clicking on the file name and then on the download icon at the right edge. It can also be obtained with the command line utilities wget or curl with the -L parameter

michel@hp:~$ wget https://github.com/sigmdel/other_releases/raw/main/espat_esp01.bin or michel@hp:~$ curl -L https://github.com/sigmdel/other_releases/raw/main/espat_esp01.bin

About the esptool.py Parameters toc

Which are the valid flash parameters for the ESP-01S? It was confusing; in some examples flash_mode was set to dout and others to dio. Similarly, flash_freq was set at 40m or 80m. Making things worse, it did not seem to matter much what value was set. Espressif has documented the flash_mode options in SPI Flash Modes. Here is the performance summary provided on that page.

OptionMode NamePins UsedSpeed (ESP device)
qioQuad I/O4 pins used for address & dataFastest.
qoutQuad Output4 pins used for data.Approx 15% slower than qio.
dioDual I/O2 pins used for address & dataApprox 45% slower than qio.
doutDual Output2 pins used for data.Approx 50% slower than qio.

As for flash_freq it is the frequency of the SPI clock signal, a square wave, generated by the ESP which is used by the flash memory. Since the latter synchronizes date reads and writes with that clock, the higher frequency is preferable. Basically then flash_mode=quio and flash_freq=80m is the best setting possible. The only trouble is that the flash memory must support those settings and there is no guarantee that the actual chip on a given ESP-01S does. Espressif provides the following advice: In general, choose the fastest option for flash_mode [and presumably for flash_freq] that works with your device. Not all devices support all modes. That's the kind of advice that many find frustrating, especially when installing new firmware for the first time on a new piece of hardware.

In the Why don't quio & qout modes work in my Espressif chip/module? FAQ, Espressif says Look up the flash chip datasheet to see which modes it supports. You can identify the flash chip visually, or by using the esptool.py flash_id command. I cannot make out the markings on the chip so I looked at the flash id.

(ve_esptool) michel@hp:~$ esptool.py -p /dev/ttyUSB1 -b 115200 flash_id ... Manufacturer: e0 Device: 4014 Detected flash size: 1MB

Unfortunately I could not find the manufacturer based on the 0xE0 id number. Given this lack of information, I should have used flash_mode=dout and flash_freq=40m for the first upload of ESP-AT. Once that was found to work, the optimal values should have been ascertained by systematically uploading the firmware with increasingly more performant values for the mode and then for the frequency. Of course, I didn't do that. Instead I flashed a "hello world" program with PlatformIO which has a specific board definition which we saw in the first section of this post. Then I copied the flash memory to a file with esptool.py read_flash in order to read the parameters used by PlatformIO.

(ve_esptool) michel@hp:~/ve_esptool/ESP-AT$ esptool.py -p /dev/ttyUSB1 -b 460800 read_flash 0 ALL PIO_hello.bin ... Read 1048576 bytes at 0x00000000 in 25.4 seconds (330.8 kbit/s)... Hard resetting via RTS pin... (ve_esptool) michel@hp:~/ve_esptool/ESP-AT$ esptool.py image_info --version 2 PIO_hello.bin esptool.py v4.6.2 File size: 1048576 (bytes) Detected image type: ESP8266 ESP8266 image header ==================== Image version: 1 Entry point: 0x4010f480 Segments: 2 Flash size: 1MB Flash freq: 40m Flash mode: QIO

I could have gotten the same information much more quickly by reading the board definition file .../.platformio/platforms/espressif8266/boards/esp01_1m.json.

{ "build": { "arduino": { "ldscript": "eagle.flash.1m256.ld" }, "core": "esp8266", "extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01", "f_cpu": "80000000L", "f_flash": "40000000L", "flash_mode": "qio", "mcu": "esp8266", "variant": "generic" }, ...

So I have shown the values flash_mode=dout and flash_freq=40m through out this post because they worked with two ESP-01S in my possession. The higher 80m frequency seems to work with at least one of the modules but I have not methodically tested that.

Other Implementations toc

As already said, I had failed to install version 2.1.1 (or more accurately I had failed to realize that the firmware was correctly installed and that the I/O pins used for the serial link had been switched) when I wrote the first version of this post. As a consequence I looked for other implementations of the AT style firmware. It may not be pertinent any more but here are the two possibilities that I found


Which Version? toc

Finally, there is a manual for ESP-AT version 1.7.5: ESP8266 Non-OS AT Instruction Set Version 3.0.5 Espressif Systems 2021. The ESP-AT User Guide should apply to version 2.2.0 on ESP8266. The command sets are quite similar but not exactly the same. The AT Command Set Comparison page lists the differences between the AT commands supported by the old NONOS-AT version and those by the new ESP-AT version. This may be misleading for those interested in running ESP-AT on the ESP-01 because it can only run cut-down versions (Nano) of the V1.7.5 and V2.1.1. I could not find a comparison table between the full version and the Nano version of the AT command sets.

At a glance, it is difficult to ascertain which version should be used. Version 1.7.5 is compiled against the deprecated ESP8266_NonOS SDK, while the newer version is compiled against the ESP8266_RTOS SDK also called ESP-IDF. Espressif is unambiguous, NonOS-AT is not recommended [...] for ESP8266 series of chips since its base SDK, ESP8266_NONOS_SDK, is no longer updated while ESP-AT is the recommended version [because it] supports all series of chips and [has] a richer set of commands compared with NonOS-AT. From the casual user/hobbyist point of view, this is not necessarily very important. The AT firmware turns an ESP board into a self-contained serial to Wi-Fi converter. If the AT command set is nearly the same then it may not matter.