使用Arduino更新ESP8266 firmware
從Arduino 變成 USB to Serial文章已知如何將Arduino變成USB to Serial的功能,接下來利用這個方法配合Arudino程式讓ESP8266能進入UART0啟動的韌體更新模式再透過ESPTool更新韌體。
連接電路:

透過圖上提供的線路,將你的ESP8266與Arduino連接:
| ESP8266 | Arduino | 說明 |
|---|---|---|
| Vcc | 3.3V | 電源 |
| GND | GND | 接地 |
| TX | RX | 互接 |
| RX | TX | 互接 |
| GPIO0 | 2 | IO埠 |
| CH_PD | 3 | 晶片選擇 |
| RST | 4 | 重置 |
撰寫ESP8266程式碼
要讓ESP8266進入UART0啟動的更新模式至少要將GPIO0低電位、GPIO2高電位,但因GPIO2在ESP8266上電後預設為高電位,不另外接到高電位,只透過程式將連接GPIO0的PIN2輸出LOW,CH_PD連接PIN3輸出HIGH,並且將RST接入Arduino中增加一個重置ESP8266的功能
int ch_pd = 3;
int gpio0 = 2;
int rst = 4;
void setup() {
pinMode(ch_pd, OUTPUT);
pinMode(gpio0, OUTPUT);
pinMode(rst, OUTPUT);
digitalWrite(ch_pd, HIGH);
digitalWrite(gpio0,LOW);
//RESET ESP8266
digitalWrite(rst,HIGH);
delay(50);
digitalWrite(rst,LOW);
delay(200);
digitalWrite(rst,HIGH);
}
void loop()
{
}
程式寫好後將程式下載至Arudino版子,並且更新時需讓Arduino板子重新接上USB線才會讓ESP8266進入更新模式。
更新ESP8266 韌體(FW)
Linux or OS X
更新韌體的主程式名為ESPTool,由Fredrik Ahlberg開發,目前已經由樂鑫官方負責維護,丹尼使用ESPTool 1.3才能符合下面操作範例(2.0版已加入ESP32),因是python寫成的,在使用時確定你的環境已經有python,新版1.3已支援python 2.7與python 3,確定你是python哪版本:
python --version
丹尼目前的環境為:
Python 3.6.0
自行加入pySerial對應版本的Library,以Arich Linux為例:
pacman -Ss pyserial
community/python-pyserial 3.2.1-2
Multiplatform Serial Port Module for Python
community/python2-pyserial 3.2.1-2
Multiplatform Serial Port Module for Python
sudo pacman -S community/python-pyserial
安裝完成後,執行esptool.py,無錯誤產生的話會看到help說明:
esptool.py v1.3 - ESP8266 ROM Bootloader Utility
positional arguments:
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash,verify_flash,erase_flash,version}
Run esptool {command} -h for additional help
load_ram 將映像檔載入RAM中並行執行
dump_mem 轉存記憶體資料至檔案(轉存ESP資料)
read_mem 讀取記憶體指定位址並存至檔案
write_mem 讀取檔案內容並寫入至記憶體指定位址
write_flash 將檔案內容寫入至SPI Flash
run 執行Flash裡的應用程式碼
image_info 轉存可執行應用映像檔的標頭
make_image 從二進位檔建立可執行的應用
elf2image 從ELF檔建立可執行的應用
read_mac 從OTP ROM讀取MAC位址
chip_id 從OTP ROM讀取晶片資訊
flash_id 讀取Flash出廠資訊(可透過此ID得知容量大小)
read_flash 取讀SPI Flash內容
verify_flash 驗證bin與Flash
erase_flash 抹除SPI Flash
version 列印出esptool版本
optional arguments:
-h, --help show this help message and exit
--port PORT, -p PORT Serial埠名稱(Linux ttyxxx,macOS cu.xxx,Windows COMx)
--baud BAUD, -b BAUD Serial埠速度
韌體上傳命令示範:
./esptool.py -p /dev/ttyUSB0 write_flash 0x00000 v0.9.5.2\ AT\ Firmware.bin
其中-p後所接的是你的通訊埠名稱(macOS以cu.命名規則,Linux以ttyXXX,Windows以COMx),韌體寫入位址從0x00000開始,來源檔為0x00000 v0.9.5.2 AT Firmware.bin,一切順利後就會更新完成:
./esptool.py -p /dev/cu.usbmodem5d11 write_flash 0x00000 v0.9.5.2\ AT\ Firmware.bin
Connecting...
Erasing flash...
Writing at 0x0007ef00... (100 %)
Windows
Windows上有NodeMcu團隊開發的工具容易使用,根據你的環境下載版本
選擇Arduino使用的通訊埠號:

到Config頁面,每個韌體更新方式不同,依照安信可提供的韌體大小是符合整個flash大小,不需要分段更新,所以只要設定寫入從0x00000,並且選擇好對應的檔案,並將選擇它(選擇後會顯示x):

基本上這些內容只需要注意Flash size,因為ESP8266設計上是以外接SPI Flash來運作,模組一開始主要都是使用256kBytes,後來官方新增功能愈來愈多就發展到512kByte,現在幾乎都是1MBytes以上,請根據你模組上面的SPI Flash編號來判斷,通常都是25xx開頭,但Flash以bit來定義,所以會變成:
| 編號 | Flash | PC計算單位 |
|---|---|---|
| W25Q20 | 2Mbits | 256kBytes |
| GD25Q16B | 2Mbits | 256kBytes |
| W25Q40 | 4Mbits | 512kBytes |
| W25Q80 | 8Mbits | 1024kBytes |
| W25Q16 | 16Mbits | 2048KBytes |
| W25Q32 | 32Mbits | 4096kBytes |
| BG25Q32 | 32Mbits | 4096kBytes |
| GD25Q32B | 32Mbits | 4096kBytes |
1024 bits = 1k

丹尼很久以前購買的ESP-01是512kBytes的版本,在此說明一下,官方版本的韌體從SDK V1.5.0以後採用1024kBytes的容量(因新增許多AT命令造成容量過大),所以購買模組時請跟賣家確認是否超過1024kBytes的版本。一切都設定好再切至Operation的頁面按下Flash進行更新,更新過程記錄切至Log頁就能看到。
補充
目前ESP8266發展愈來愈成熟,韌體主流為1MBytes(8Mbits),安信可也提供符合新版SDK的自訂韌體供選擇,前往ESP8266 最新SDK发布查看安信可最新的自訂韌體,現在新版的韌體也建議使用樂鑫提供的ESP_DOWNLOAD_TOOL,安信可也提供燒錄說明如何为 ESP 系列模组烧录固件。
燒錄前的檢查確認避免燒錄失敗:
電壓、電流
ESP8266所使用的為3.3V電壓、電流至少大於300mA,這些來源都必需穩定,未確認USB to Serial提供的3.3V是否穩定時請勿使用,不穩定會造成燒錄到一半失敗或是無法切至燒錄模式,詳細說明請參考ESP8266 電源電路研究
確認flash size,選擇對應的韌體大小
讀取flash id
esptool.py -p /dev/ttyUSB0 -b 230400 flash_id
得到flash相關資訊:
esptool.py v1.3
Connecting....
Manufacturer: ef
Device: 4016
取得flash_id資料後重新組合為1640EF(DeviceL + DeviceH + Manufacturer),再經由Esp.cpp擷取出來的程式內容自行比對並取得內容:
uint32_t EspClass::getFlashChipSizeByChipId(void) {
uint32_t chipId = getFlashChipId();
/**
* Chip ID
* 00 - always 00 (Chip ID use only 3 byte)
* 17 - ? looks like 2^xx is size in Byte ? //todo: find docu to this
* 40 - ? may be Speed ? //todo: find docu to this
* C8 - manufacturer ID
*/
switch(chipId) {
// GigaDevice
case 0x1740C8: // GD25Q64B
return (8_MB);
case 0x1640C8: // GD25Q32B
return (4_MB);
case 0x1540C8: // GD25Q16B
return (2_MB);
case 0x1440C8: // GD25Q80
return (1_MB);
case 0x1340C8: // GD25Q40
return (512_kB);
case 0x1240C8: // GD25Q20
return (256_kB);
case 0x1140C8: // GD25Q10
return (128_kB);
case 0x1040C8: // GD25Q12
return (64_kB);
// Winbond
case 0x1640EF: // W25Q32
return (4_MB);
case 0x1540EF: // W25Q16
return (2_MB);
case 0x1440EF: // W25Q80
return (1_MB);
case 0x1340EF: // W25Q40
return (512_kB);
// BergMicro
case 0x1640E0: // BG25Q32
return (4_MB);
case 0x1540E0: // BG25Q16
return (2_MB);
case 0x1440E0: // BG25Q80
return (1_MB);
case 0x1340E0: // BG25Q40
return (512_kB);
default:
return 0;
}
}
以1640EF為例得到的資料為:
// Winbond
case 0x1640EF: // W25Q32
return (4_MB);
Winbond W25Q32 flash型號並且容量為4MBytes(32Mbits)。
確認韌體的結構
使用官方提供的分段燒錄韌體(參考ESP8266 韌體)要確定每段都有燒錄正確,官方提供的SDK目錄結構來說,AT command 韌體更新說明都會放在bin/at/README.txt
***********************BOOT MODE***********************
download:
Flash size 8Mbit: 512KB+512KB
boot_v1.2+.bin 0x00000
user1.1024.new.2.bin 0x01000
esp_init_data_default.bin 0xfc000 (optional)
blank.bin 0x7e000 & 0xfe000
Flash size 16Mbit: 512KB+512KB
boot_v1.2+.bin 0x00000
user1.1024.new.2.bin 0x01000
esp_init_data_default.bin 0x1fc000 (optional)
blank.bin 0x7e000 & 0x1fe000
Flash size 16Mbit-C1: 1024KB+1024KB
boot_v1.2+.bin 0x00000
user1.2048.new.5.bin 0x01000
esp_init_data_default.bin 0x1fc000 (optional)
blank.bin 0xfe000 & 0x1fe000
Flash size 32Mbit: 512KB+512KB
boot_v1.2+.bin 0x00000
user1.1024.new.2.bin 0x01000
esp_init_data_default.bin 0x3fc000 (optional)
blank.bin 0x7e000 & 0x3fe000
Flash size 32Mbit-C1: 1024KB+1024KB
boot_v1.2+.bin 0x00000
user1.2048.new.5.bin 0x01000
esp_init_data_default.bin 0x3fc000 (optional)
blank.bin 0xfe000 & 0x3fe000
***********************NON-BOOT MODE***********************
download
eagle.flash.bin 0x00000
eagle.irom0text.bin 0x40000
blank.bin
Flash size 4Mbit: 0x3e000 & 0x7e000
Flash size 8Mbit: 0x7e000 & 0xfe000
Flash size 16Mbit: 0x7e000 & 0x1fe000
Flash size 16Mbit-C1: 0xfe000 & 0x1fe000
Flash size 32Mbit: 0x7e000 & 0x3fe000
Flash size 32Mbit-C1: 0xfe000 & 0x3fe000
esp_init_data_default.bin (optional)
Flash size 4Mbit: 0x7c000
Flash size 8Mbit: 0xfc000
Flash size 16Mbit: 0x1fc000
Flash size 16Mbit-C1: 0x1fc000
Flash size 32Mbit: 0x3fc000
Flash size 32Mbit-C1: 0x3fc000
*NOTICE*:
UPDATE is not supported in non-boot mode
***********************************************************
Update steps
1.Make sure TE(terminal equipment) is in sta or sta+ap mode
ex. AT+CWMODE=3
OK
AT+RST
2.Make sure TE got ip address
ex. AT+CWJAP="ssid","12345678"
OK
AT+CIFSR
192.168.1.134
3.Let's update
ex. AT+CIUPDATE
+CIPUPDATE:1 found server
+CIPUPDATE:2 connect server
+CIPUPDATE:3 got edition
+CIPUPDATE:4 start start
OK
note. If there are mistakes in the updating, then break update and print ERROR.
第三方韌體請確認韌體是否整合好還是屬於分段燒錄,以安信可提供的則是已經整合好的,從位址0x00000開始燒錄就能完成。
清除flash
必要時,自行清楚所有flash內容,避免有一些未知的內容被引用:
esptool.py -p /dev/ttyUSB0 -b 230400 erase_flash
512kBytes 韌體
如果你是買512kBytes版本,丹尼提供使用官方SDK V1.3的版本整合成適合512kBytes版本使用的單一更新韌體檔案ESP8266_V1.3_FOR_512k,可以使用任何的ESP8266更新程式來更新韌體。
參考資料
ESP8266 Firmware Update with Arduino Board
安信可v0.9.5.2AT固件支持SmartLink,带0.9.5.2APK,支持OTA!
更新日誌
| 日期 | 修訂內容 |
|---|---|
| 2017/05/24 | 修正文字內容 |
| 2017/03/21 | 更新內容並增加補充項目 |
| 2016/03/28 | 更新接腳、新增Windows更新工具 |
我試了這個方法,我發現一些奇怪的地方,我是TX接TX、RX接RX,才可以用 跟你寫得不太一樣? 而且ESP8266只能接3.3V,如果照你這樣接,還可能會燒壞板子…
Arduino線路上有提供3.3V,一般使用還能勉強供ESP8266使用,至於ESP8266的RX能接收3.3V、5V的輸入,基本上不會有問題,而它的TX出來最高3.3V對於Arduino的Hi,Low準位判斷也不會有問題,可以參考參考
不好意思小弟不太懂這裡的敘述 “程式下載完成後再另外準備firmware,這裡使用的是物聯世界討論區提供的,下載後請與ESPTool放在同一個位置,並且輸入:” 輸入部分適用CMD輸入?還是python? 謝謝您
不好意思小弟想請教下這裡的敘述
“程式下載完成後再另外準備firmware,這裡使用的是物聯世界討論區提供的,下載後請與ESPTool放在同一個位置,並且輸入:./esptool.py -p /dev/cu.usbmodem5d11 write_flash 0x00000 v0.9.5.2 AT Firmware.bin “
是只適用於OS X的吧?
謝謝您
範例以OSX為主,你使用Linux、Windows必需要變更一下Serial名稱,例如: ./esptool.py -p /dev/ttyS0 write_flash 0x00000 v0.9.5.2 AT Firmware.bin
好的謝謝您!!! 不過”./esptool.py -p /dev/ttyS0 write_flash 0x00000 v0.9.5.2 AT Firmware.bin”是Windows的指令嗎? 不好意思打擾了
沒有喔!windows需要安裝windows版的python https://www.python.org/downloads/windows/
小弟那些都處理好了包括pySerial的部分 目前只差燒錄 只是不知道Windows該下甚麼指令做燒錄QAQ 不好意思QAQ
python esptool.py -p COM1 write_flash 0x00000 v0.9.5.2 AT Firmware.bin
不好意思能再請教一下嗎
usage: esptool write_flash [-h] [–flash_freq {40m,26m,20m,80m}]
[--flash_mode {qio,qout,dio,dout}] [--flash_size {4m,2m,8m,16m,32m,16m-c1,32m-c1,32m-c2}`]
[--verify] <address> <filename> [<address> <filename> ...]`esptool write_flash: error: argument
<
address> : [Errno 2] No such fil
e or directory: ‘v0.9.5.2\’
是基於甚麼原因產深的ERROR呢?謝謝您!!!
路徑參數錯了。你確認一下Firmware.bin路徑,把”v0.9.5.2 AT Firmware.bin”換成正確的
C:UsersAdminDesktopesptool-master>python esptool.py -p COM3 write_flash 0x00
000 Firmware.bin
Connecting…
A fatal error occurred: Failed to connect to ESP8266
是開始跑了,不過這ERROR說無法連結到(我的是COM3沒錯)QAQ
試試將COM3改成\.COM3
如果您是配合上面arduino使用的話,重新啟動arduino試試
好的,等等試試,謝謝您
還是不行QAQ 而且小弟的TX、RX反過來才會開始燒(藍色LED閃爍),當然還是無法燒錄,會失敗QAQ
你的失敗訊息是什麼啊?
依樣是 A fatal error occurred: Failed to connect to ESP8266 不好意思 小弟在想看看好了
windows 可以試試nodemcu提供的工具 https://github.com/nodemcu/nodemcu-flasher/tree/master/Win32/Release