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

参考

posted on 2021-04-19 01:25  Milton  阅读(1539)  评论(0编辑  收藏  举报

导航