Ubuntu20.04下的ESP8266環境


硬件說明

ESP8266使用的是3.3V供電, 和Arduino不一樣, ESP8266的I/O腳是不能防5V的, 連上就燒. 其輸出只有12mA, 而Arduino是20-40mA. ESP8266又一個模擬->數據的轉換器, 電壓范圍為0-1V, 高於1V的電壓可能會把片子燒掉.
ESP8266的WIFI是軟驅動, 會占用CPU時間, PWM, 中斷及I²C都是模擬的, 都會占CPU時間.

開發板選擇

參考 https://makeradvisor.com/best-esp8266-wi-fi-development-board/
常見的有ESP-01/ESP-01S, 12E/12F NodeMCU, Wemos D1 Mini這三種.

ESP-01/ESP-01S


引腳定義

ESP-01尺寸為24.75mm x 14.5mm, 適合實際部署. 現在市面上的版本都是1MB存儲. 帶4個GPIO, 其中兩個用於串口TX和RX, 板子不帶調壓, 需要自備3.3V電源. 板子不帶USB2TTL芯片, 需要自備轉接頭用於燒錄.

ESP-01和ESP-01S的區別

  1. 兩者尺寸一樣, 8個管腳定義也一樣
  2. 指示燈的管腳由ESP-01的TXD0變成了ESP-01S的GPIO2
  3. ESP-01S的IO0、RST、EN管腳增加了上拉電阻,

帶來的好處有兩個

  1. 燒錄時, 不再需要連接RST與3.3V
  2. 簡化了應用電路. 下面是兩者對比, 上面是ESP-01, 下面是ESP-01S


    可以看出ESP-01S的應用電路簡化了, 省掉了兩個上拉電阻.

ESP-01S的串口測試

不需要下載各種串口助手軟件, 直接用putty就可以了. putty的使用:

  1. 選擇serial, 填入COM編號, 例如COM5, 波特率設為115200, 直接連接.
  2. 發送命令的操作: 輸入命令例如AT, 然后回車, 然后按Ctrl+J發送.

關於Ctrl+J的說明

因為一些模塊的AT指令需要以\r\n結束, 這兩個分別代表了CRLF, 在putty中, 回車時會輸出CR, 也可以通過Ctrl+M輸出CR, 但是要輸出LF, 需要使用Ctrl+J

  • Ctrl+M : Carriage Return(“\r”)
  • Ctrl+J : Line Feed(“\n”)

如果你需要輸出上面的AT指令, 就需要這樣進行輸入 A -> T -> Ctrl+MEnter -> Ctrl+J

12E/12F NodeMCU


The ESP12-E NodeMCU Kit is one of the most used ESP8266 development boards. It features 4MB of flash memory, access to 11 GPIO pins, and one analog-to-digital converter (ADC) pin with 10 bit resolution. The board has a built-in voltage regulator and you can power up the module using the mini USB socket or the Vin pin.
引腳定義

使用12E/12F模塊自建電路時需要添加外部元件. 使用USB2TTL供電時要注意電流是否滿足, 如果USB2TTL接在了USB Hub上, 與其他USB設備共用一個USB口, 容易出現供電不足的問題, 現象就是模塊不斷重啟.

環境配置

安裝軟件

根據文檔安裝軟件, 文檔中列出需要安裝的python和python-serial是有問題的, 在Ubuntu20.04中只有python3沒有python, 而python3已經安裝, 另外沒有python-serial, 這個要在后面通過pip安裝

sudo apt install gcc git wget make libncurses-dev flex bison gperf

安裝工具鏈

tar zxvf xtensa-lx106-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz 
cd /opt/
sudo mkdir esp8266
cd esp8266/
sudo mv ~/Backup/linux/xtensa-lx106-elf .
sudo chown -R root:root xtensa-lx106-elf/
回到用戶home目錄, 將這個路徑添加到PATH
```bash
vi .profile
# append start
export PATH="$PATH:/opt/esp8266/xtensa-lx106-elf/bin"
# append end

安裝SDK

在用戶home目錄下

mkdir Esp
cd Esp/
# 這一步會下載超過190M大小的源代碼, 需要提前設置好代理
git clone --recursive https://github.com/espressif/ESP8266_RTOS_SDK.git

將IDF_PATH添加到環境變量

vi ~/.profile
# append start
export IDF_PATH="/home/milton/Esp/ESP8266_RTOS_SDK"
# append end

通過以下方式驗證

printenv IDF_PATH
printenv PATH

安裝python庫

# 如果python命令不存在, 需要提前設置好ln或alias
cd /usr/bin/
sudo ln -s python3.8 python
# 檢查python版本
python --version
# 安裝
python -m pip install --user -r $IDF_PATH/requirements.txt

連接開發板

本文使用的是一塊好幾年前購買的ESP8266 12E開發板, CH340 USB TTL, 帶Rest和Flash兩個按鈕.

直接通過microUSB線連接, 通過dmesg可以看到創建的虛擬串口為ttyUSB0

[ 4348.546767] usbcore: registered new interface driver usbserial_generic
[ 4348.546778] usbserial: USB Serial support registered for generic
[ 4348.549509] usbcore: registered new interface driver ch341
[ 4348.549994] usbserial: USB Serial support registered for ch341-uart
[ 4348.550112] ch341 2-2:1.0: ch341-uart converter detected
[ 4348.552247] usb 2-2: ch341-uart converter now attached to ttyUSB0

運行示例

get-started/hello_world

這是一個基礎的代碼示例, 運行后會輸出硬件環境信息然后進行10秒倒計時, 倒計時結束后重啟板子.

編譯步驟

到SDK目錄下, 將hello world項目復制到最上一層

cp -r ESP8266_RTOS_SDK/examples/get-started/hello_world/ .
cd hello_world/

首先執行make menuconfig, 在這里選擇菜單Serial flasher config, 設置

  • Default serial port: /dev/ttyUSB0
  • Default baud rate: 115200 baud
  • Use compressed upload: Yes
  • Flash SPI mode: DOUT
  • Flash SPI speed: 40 MHz
  • Flash size: 4MB
  • Before flashing: Reset to bootloader
  • After flashing: Hard reset after flashing
  • make monitor baud rate: 74880 bps

然后save, exit.

編譯+燒錄: make flash, 查看串口輸出make monitor, 編譯+燒錄+查看串口輸出make flash monitor

運行輸出

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 7032, room 16 
tail 8
chksum 0x9e
load 0x3ffe8408, len 24, room 0 
tail 8
chksum 0x77
load 0x3ffe8420, len 3324, room 0 
tail 12
chksum 0x32
csum 0x32
I (80) boot: ESP-IDF v3.4-4-gd4507156 2nd stage bootloader
I (81) boot: compile time 00:50:46
I (81) boot: SPI Speed      : 40MHz
I (93) boot: SPI Mode       : DOUT
I (106) boot: SPI Flash Size : 4MB
I (118) boot: Partition Table:
I (130) boot: ## Label            Usage          Type ST Offset   Length
I (152) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (176) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (199) boot:  2 factory          factory app      00 00 00010000 000f0000
I (222) boot: End of partition table
I (235) esp_image: segment 0: paddr=0x00010010 vaddr=0x40210010 size=0x1b2b8 (111288) map
0x40210010: _stext at ??:?

I (337) esp_image: segment 1: paddr=0x0002b2d0 vaddr=0x4022b2c8 size=0x06f24 ( 28452) map
I (357) esp_image: segment 2: paddr=0x000321fc vaddr=0x3ffe8000 size=0x00554 (  1364) load
I (360) esp_image: segment 3: paddr=0x00032758 vaddr=0x40100000 size=0x00080 (   128) load
I (387) esp_image: segment 4: paddr=0x000327e0 vaddr=0x40100080 size=0x04f6c ( 20332) load
I (427) boot: Loaded app from partition at offset 0x10000
Hello world!
This is ESP8266 chip with 1 CPU cores, WiFi, silicon revision 1, 4MB external flash
Restarting in 10 seconds...

peripherals/uart_echo

這個項目用於演示ESP8266對於UART0的串口數據接收和發送. 因為UART0就是用於燒錄板子的串口, 所以燒錄后, 直接monitor就能進行操作.
為了使輸入輸出更加明顯, 可以對代碼進行一些修改,

  • 20 / portTICK_RATE_MS修改為1000 / portTICK_RATE_MS, 即每20ms刷新一次變為每秒刷新一次
  • 輸出一個換行符使得定時更明顯
while (1) {
    // Read data from the UART
    int len = uart_read_bytes(UART_NUM_0, data, BUF_SIZE, 1000 / portTICK_RATE_MS);
    // Write data back to the UART
    uart_write_bytes(UART_NUM_0, (const char *) data, len);
    char* test_str = ".\n";
    uart_write_bytes(UART_NUM_0, (const char*)test_str, strlen(test_str));
}

在monitor的過程中, 可以看到對於鍵盤的輸入, 板子會每隔一秒將收集到的輸入的信息返回, 同時顯示一個回車.

wifi/getting_started/station

這個項目用於演示如何將板子接入一個帶密碼的WIFI網絡並獲得IP.

編譯步驟

  1. 先運行make menuconfig, 在界面的Example Configuration中配置SSID和password.
  2. 運行make flash monitor編譯燒錄並觀察輸出

輸出

I (43) boot: compile time 17:36:40
I (43) boot: SPI Speed      : 40MHz
I (49) boot: SPI Mode       : DOUT
I (56) boot: SPI Flash Size : 4MB
...
I (380) wifi station: ESP_WIFI_MODE_STA
I (384) system_api: Base MAC address is not set, read default base MAC address from EFUSE
I (390) system_api: Base MAC address is not set, read default base MAC address from EFUSE
phy_version: 1163.0, 665d56c, Jun 24 2020, 10:00:08, RTOS new
I (457) phy_init: phy ver: 1163_0
I (519) wifi station: wifi_init_sta finished.
I (3594) wifi:state: 0 -> 2 (b0)
I (3597) wifi:state: 2 -> 3 (0)
I (3601) wifi:state: 3 -> 5 (10)
I (3624) wifi:connected with ND2, aid = 1, channel 7, HT20, bssid = 20:76:93:43:01:40
I (7600) tcpip_adapter: sta ip: 192.168.17.111, mask: 255.255.255.0, gw: 192.168I (7605) wifi station: got ip:192.168.15.123
I (7610) wifi station: connected to ap SSID:ND2 password:12345678

如果要修改板子的hostname, 那么在事件處理的方法中加入這行
ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, "testing"));

if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
    ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, "testing"));
    esp_wifi_connect();
    ...

protocols/sockets/udp_client

這個項目演示如何通過UDP發送和接收消息

  1. 先找一台局域網機器, 假設IP為192.168.15.15, 運行UDP服務, 接收請求並直接返回
# 返回固定字符串
nc -u -l 3333 -k -c "echo \"Received\""
# 返回收到的字符串
nc -u -l 3333 -k -c "/bin/cat"
  1. 運行make menuconfig,
  • 界面的Example Configuration中配置服務器的IPv版本, IP地址和端口
  • 界面的Example Connection Configuration中配置SSID, password等WIFI連接信息
  1. 運行make flash monitor編譯燒錄並觀察輸出

評估

ESP8266以station的方式與AP建立連接, 其ping的延遲較大且不穩定, 在網絡很好的情況下結果如下, ping值延遲在24~124ms之間波動.

# first round
PING 192.168.8.232 (192.168.8.232): 56 data bytes
64 bytes from 192.168.8.232: seq=0 ttl=255 time=23.925 ms
64 bytes from 192.168.8.232: seq=1 ttl=255 time=48.103 ms
64 bytes from 192.168.8.232: seq=2 ttl=255 time=70.783 ms
64 bytes from 192.168.8.232: seq=3 ttl=255 time=94.698 ms
64 bytes from 192.168.8.232: seq=4 ttl=255 time=118.095 ms
64 bytes from 192.168.8.232: seq=5 ttl=255 time=39.515 ms
64 bytes from 192.168.8.232: seq=6 ttl=255 time=64.213 ms
64 bytes from 192.168.8.232: seq=7 ttl=255 time=88.089 ms
64 bytes from 192.168.8.232: seq=8 ttl=255 time=111.300 ms
64 bytes from 192.168.8.232: seq=9 ttl=255 time=32.766 ms
64 bytes from 192.168.8.232: seq=10 ttl=255 time=56.775 ms
64 bytes from 192.168.8.232: seq=11 ttl=255 time=80.540 ms
64 bytes from 192.168.8.232: seq=12 ttl=255 time=103.953 ms
64 bytes from 192.168.8.232: seq=13 ttl=255 time=25.493 ms
64 bytes from 192.168.8.232: seq=14 ttl=255 time=49.115 ms
64 bytes from 192.168.8.232: seq=15 ttl=255 time=73.213 ms
64 bytes from 192.168.8.232: seq=16 ttl=255 time=97.223 ms
64 bytes from 192.168.8.232: seq=17 ttl=255 time=120.821 ms
64 bytes from 192.168.8.232: seq=18 ttl=255 time=41.917 ms
64 bytes from 192.168.8.232: seq=19 ttl=255 time=66.030 ms
64 bytes from 192.168.8.232: seq=20 ttl=255 time=89.736 ms
64 bytes from 192.168.8.232: seq=21 ttl=255 time=115.033 ms
64 bytes from 192.168.8.232: seq=22 ttl=255 time=34.937 ms
64 bytes from 192.168.8.232: seq=23 ttl=255 time=58.816 ms
64 bytes from 192.168.8.232: seq=24 ttl=255 time=83.114 ms
64 bytes from 192.168.8.232: seq=25 ttl=255 time=106.258 ms
64 bytes from 192.168.8.232: seq=26 ttl=255 time=27.669 ms
64 bytes from 192.168.8.232: seq=27 ttl=255 time=51.536 ms
64 bytes from 192.168.8.232: seq=28 ttl=255 time=75.806 ms
64 bytes from 192.168.8.232: seq=29 ttl=255 time=99.316 ms
64 bytes from 192.168.8.232: seq=30 ttl=255 time=123.205 ms
64 bytes from 192.168.8.232: seq=31 ttl=255 time=44.493 ms
64 bytes from 192.168.8.232: seq=32 ttl=255 time=68.095 ms
33 packets transmitted, 33 packets received, 0% packet loss
round-trip min/avg/max = 23.925/72.260/123.205 ms

# second round
46 packets transmitted, 45 packets received, 2% packet loss
round-trip min/avg/max = 23.770/73.276/123.395 ms

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM