ESP32是使用非常广泛的一款微处理器,集成了WiFi和蓝牙模块,根据性能和应用场景的不同有很多不同的版本,本文是ESP32开发板在MicroPython环境下运行的快速参考,对于首次使用这个开发板在MicroPython下进行开发的应该会有一定的帮助。
下面以Espressif ESP32开发板为例进行说明。
关于安装可以参考:在 ESP32 上开始使用 MicroPython,其中还包括故障排除小节。
MicroPython REPL 位于 UART0(GPIO1=TX,GPIO3=RX)上,波特率为 115200。Tab-completion 用于查找对象的方法。粘贴模式 (ctrl-E) 可以将一大段 Python 代码粘贴到 REPL 中。
machine
模块:
import machine
machine.freq() # 获取CPU频率
machine.freq(240000000) # 将CPU频率设置为240 MHz
esp
模块:
import esp
esp.osdebug(None) # 关闭厂商O/S调试信息
esp.osdebug(0) # 把厂商O/S调试信息重定向到UART(0)
# 使用底层方法操作闪存
esp.flash_size()
esp.flash_user_start()
esp.flash_erase(sector_no)
esp.flash_write(byte_offset, buffer)
esp.flash_read(byte_offset, buffer)
esp32
模块:
import esp32
esp32.raw_temperature() # 读取MCU核心温度,单位是摄氏度
esp32.ULP() # 访问低功耗协处理器
**注意:**ESP32 中的温度传感器读数通常会高于环境温度,这是因为集成电路在运行时会变热。从睡眠状态唤醒后立即读取温度传感器的读数可将这种影响降至最低。
network
模块:
import network
wlan = network.WLAN(network.STA_IF) # 创建站点接口
wlan.active(True) # 激活接口
wlan.scan() # 扫描热点
wlan.isconnected() # 检查站点是否连接到热点
wlan.connect('ssid', 'key') # 连接到一个热点
wlan.config('mac') # 获取接口的MAC地址
wlan.ifconfig() # 获取接口的IP、子网掩码、网关和DNS地址
ap = network.WLAN(network.AP_IF) # 创建一个热点
ap.config(ssid='ESP-AP') # 设置热点的SSID
ap.config(max_clients=10) # 设置允许连接的客户端数量
ap.active(True) # 激活热点
连接本地 WiFi 网络的实用功能是:
def do_connect():
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ssid', 'key')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
网络建立后,套接字模块可用于创建和使用TCP/UDP套接字,请求模块可方便用于HTTP的请求。
调用wlan.connect()
后,设备将默认永久重试连接,即使身份验证失败或范围内没有接入点。在此状态下,wlan.status()
将返回network.STAT_CONNECTING
,直到连接成功或接口被禁用。可以通过调用wlan.config(reconnects=n)
可以改变这种状态,其中n
是所需的重连尝试次数(0 表示不会重试,-1 表示恢复默认状态,即永远尝试重连)。
要使用有线接口,必须指定引脚和模式
import network
lan = network.LAN(mdc=PIN_MDC, ...) # 设置引脚和模式
lan.active(True) # 启动网络接口
lan.ifconfig() # 获取网络的IP、子网掩码、网关和DNS地址
定义PHY
类型和接口的构造函数的关键参数有:
mdc=machine.Pin(n) # 设置 mdc 和 mdio 引脚。
mdio=machine.Pin(n) #管脚对象
power=machine.Pin(n) # 设置 PHY 设备的电源开关引脚。
phy_type=<type> # 选择 PHY 设备类型。支持的设备有 PHY_LAN8710、PHY_LAN8720、PH_IP101、PHY_RTL8201、PHY_DP83848 和 PHY_KSZ8041
phy_addr=number # PHY 设备的地址编号。
ref_clk_mode=mode # 定义ESP32的ref_clk 是输入还是输出。合适的值是 Pin.IN 和 Pin.OUT。
ref_clk=machine.Pin(n) # 定义用于 ref_clk 的引脚。
这些是常用电路板局域网接口的工作配置:
# Olimex ESP32-GATEWAY: 电源由Pin(5)控制
# Olimex ESP32 PoE and ESP32-PoE ISO: 电源由Pin(12)控制
lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5),
phy_type=network.PHY_LAN8720, phy_addr=0,
ref_clk=machine.Pin(17), ref_clk_mode=machine.Pin.OUT)
# Wireless-Tag's WT32-ETH01
lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18),
phy_type=network.PHY_LAN8720, phy_addr=1, power=None)
# Wireless-Tag's WT32-ETH01 v1.4
lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18),
phy_type=network.PHY_LAN8720, phy_addr=1,
power=machine.Pin(16))
# Espressif ESP32-Ethernet-Kit_A_V1.2
lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5),
phy_type=network.PHY_IP101, phy_addr=1)
使用time
模块:
import time
time.sleep(1) # 休眠1秒
time.sleep_ms(500) # 休眠500毫秒
time.sleep_us(10) # 休眠10微秒
start = time.ticks_ms() # 获取毫秒数
delta = time.ticks_diff(time.ticks_ms(), start) # 计算时间差
ESP32 端口有四个硬件定时器。使用 machine.Timer
类,定时器 ID 从 0 到 3(含):
from machine import Timer
tim0 = Timer(0)
tim0.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(0))
tim1 = Timer(1)
tim1.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(1))
周期以毫秒为单位。
该端口目前不支持虚拟计时器。
使用machine.Pin
类:
from machine import Pin
p0 = Pin(0, Pin.OUT) # 在GPIO0上创建输出引脚
p0.on() # 设置引脚为高电平
p0.off() # 设置引脚为低电平
p0.value(1) # 设置引脚为高电平
p2 = Pin(2, Pin.IN) # 在GPIO2上创建输入引脚
print(p2.value()) # 获取值0或1
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # 启用内部上拉电阻
p5 = Pin(5, Pin.OUT, value=1) # 在引脚创建时设置为高电平
p6 = Pin(6, Pin.OUT, drive=Pin.DRIVE_3) # 设置引脚为最大驱动能力
可用引脚范围如下(含): 0-19、21-23、25-27、32-39:0-19, 21-23, 25-27, 32-39。这些引脚与ESP32芯片的实际 GPIO 引脚编号一致。注意,许多最终用户电路板使用自己专用引脚编号(如 D0、D1…)。有关电路板逻辑引脚和芯片物理引脚之间的映射关系,请查阅电路板文档。
使用Pin()
构造函数或Pin.init()
方法的驱动关键字参数,可支持四种驱动强度,并具有不同的相应安全最大源/汇电流和近似内部驱动电阻:
Pin()
和Pin.init()
的hold=
关键字参数将启用ESP32的 "焊盘保持 "功能。设置为True
时,引脚配置(方向、上拉电阻和输出值)将被保持,任何进一步的更改(包括更改输出电平)都不会应用。设置hold=False
将立即应用任何未完成的引脚配置更改并释放引脚。在引脚已保持的情况下使用hold=True
会应用任何配置更改,然后立即重新应用保持。
注意:
这里有一个更高层次的抽象machine.Signal
,可用于反转引脚。使用on()
或value(1)
可以点亮低电平有效的LED。
使用machine.UART
:
from machine import UART
uart1 = UART(1, baudrate=9600, tx=33, rx=32)
uart1.write('hello') # 写5个字节
uart1.read(5) # 读取5个字节
ESP32 有三个硬件的UART:UART0、UART1和UART2,它们都有分配给它们的默认 GPIO,但根据您的 ESP32 变体和电路板,这些引脚可能会与嵌入式闪存、板载 PSRAM 或外设发生冲突。
任何GPIO都可用于使用GPIO矩阵的硬件UART,但可用作rx的纯输入引脚34-39除外。为避免冲突,只需在构建时提供tx和rx引脚即可。默认引脚如下。
UART0 | UART1 | UART2 | |
---|---|---|---|
tx | 1 | 10 | 17 |
rx | 3 | 9 | 16 |
PWM 可在所有输出引脚上启用。基频范围为1Hz至40MHz,但需要权衡;随着基频的增加,占空比会降低。
使用machine.PWM
类:
from machine import Pin, PWM
pwm0 = PWM(Pin(0), freq=5000, duty_u16=32768) # 从指定引脚创建PWM对象
freq = pwm0.freq() # 获取当前频率
pwm0.freq(1000) # 设置PWM频率从1Hz到40MHz
duty = pwm0.duty() # 获取当前占空比,范围0-1023 (缺省 512, 50%)
pwm0.duty(256) # 设置占空比,从0到1023,占空比为 duty/1023, (当前为 25%)
duty_u16 = pwm0.duty_u16() # 获取当前的占空比,范围0-65535
pwm0.duty_u16(2**16*3//4) # 设置占空比从0到65535,占空比为 duty_u16/65535, (当前为 75%)
duty_ns = pwm0.duty_ns() # 获取当前脉冲宽度,单位纳秒ns
pwm0.duty_ns(250_000) # 以纳秒为单位设置脉冲宽度,从 0 到 1_000_000_000/频率,(现在为 25%)
pwm0.deinit() # 关闭引脚上的PWM
pwm2 = PWM(Pin(2), freq=20000, duty=512) # 一次性创建和配置
print(pwm2) # 打印PWM设置
ESP 芯片有不同的硬件外设:
硬件规格 | ESP32 | ESP32-S2 | ESP32-C3 |
---|---|---|---|
组数(速度模式) | 2 | 1 | 1 |
每组的计时器数量 | 4 | 4 | 4 |
每组通道数 | 8 | 8 | 8 |
不同的 PWM 频率(组 * 定时器) | 8 | 4 | 4 |
PWM 通道总数(引脚,职责)(组 * 通道) | 16 | 8 | 6 |
ESP32的最大PWM通道(引脚)数为 16 个,但只有 8 个不同的 PWM 频率,其余 8 个通道的频率必须相同。另一方面,在相同频率下可以有 16 个独立的 PWM 占空比。
在 ESP32 上,DAC功能在引脚25、26上。在ESP32S2 上,17、18引脚上具有 DAC 功能。
使用DAC:
from machine import DAC, Pin
dac = DAC(Pin(25)) # 为管脚创建一个DAC对象
dac.write(128) # 设置一个原始模拟值,范围0~255,当前是50%
在 ESP32 上,32-39 引脚(ADC block 1)和 0、2、4、12-15 和 25-27 引脚(ADC block 2)上都有 ADC 功能。
使用machine.ADC
类:
from machine import ADC
adc = ADC(pin) # 为引脚上创建一个ADC对象
val = adc.read_u16() # 读取一个原始值,范围0~65535
val = adc.read_uv() # 读取一个电压模拟值,单位微伏
ADC block 2 也由WiFi使用,因此当 WiFi 处于激活状态时,尝试从block 2 引脚读取模拟值将会引发异常。
内部 ADC 基准电压通常为 1.1V,但不同封装之间略有不同。ADC 在接近基准电压时线性较差(特别是在较高衰减时),最低测量电压约为 100mV,低于或等于此值的电压读数为 0。要准确读取电压,建议使用 read_uv()
方法(见下文)。
ESP32 专用 ADC 类方法参考:
返回指定引脚的 ADC 对象。ESP32 不支持 ADC 采样的不同时序,因此不支持 sample_ns
关键字参数。
要读取高于参考电压的电压,可使用 atten
关键字参数应用输入衰减。有效值(以及近似线性测量范围)为:
ADC.ATTN_0DB
:无衰减(100mV - 950mV)ADC.ATTN_2_5DB
:2.5 分贝衰减(100mV - 1250mV)ADC.ATTN_6DB
:6 分贝衰减(150mV - 1750mV)ADC.ATTN_11DB
:11 分贝衰减(150mV - 2450mV)**注意:**输入引脚的绝对最大额定电压为 3.6V,接近这一界限可能会损坏集成电路!
这种方法利用 ADC 的已知特性和每个封装的 eFuse 值(在制造过程中设定),返回以微伏为单位的校准输入电压(衰减前)。返回值只有毫伏分辨率(即始终是 1000 微伏的倍数)。
校准仅在 ADC 的线性范围内有效。特别是,接地输入将读取高于 0 微伏的值。不过,在线性范围内,使用 read_u16()
并用常数缩放结果将获得更准确、更一致的结果。
传统方法:
该方法根据块的分辨率返回 ADC 原始值,例如 12 位分辨率为 0-4095。
等同于 ADC.init(atten=atten)。
等价于 ADC.block().init(bits=bits)。
为了兼容,ADC 对象还提供了与支持的 ADC 分辨率相匹配的常量:
ESP32 端口还支持 machine.ADC API:
返回具有给定 id(1 或 2)的 ADC 块对象,并将其初始化为指定分辨率(9 至 12 位,取决于 ESP32 系列),如果未指定,则返回支持的最高分辨率。
返回指定 ADC 引脚或通道号的 ADC 对象。不支持将 ADC 通道任意连接到 GPIO,因此指定未连接到该模块的引脚或指定不匹配的通道和引脚将引发异常。
软SPI(使用位操作)可在所有引脚上工作,通过machine.SoftSPI
类访问:
from machine import Pin, SoftSPI
# 在给定的引脚上构建一个软SPI总线
# polarity is the idle state of SCK(串行时钟Serial Clock)
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
spi.init(baudrate=200000) # 设置波特率
spi.read(10) # 读取MISO的10个字节
spi.read(10, 0xff) # 读取10个字节,同时在MOSI输出0xff
buf = bytearray(50) # 创建缓冲区
spi.readinto(buf) # 读取到给定的缓冲区(读取50个字节)
spi.readinto(buf, 0xff) # 读取到给定的缓冲区,并输出在MOSI输出0xff
spi.write(b'12345') # 向MOSI写5个字节
buf = bytearray(4) # 创建一个缓冲区
spi.write_readinto(b'1234', buf) # 写MOSI并同时读取内容到缓冲区
spi.write_readinto(buf, buf) # 写buf内容到MOSI并读取MISO内容到buf
**警告:**目前,在初始化软件 SPI 时必须指定sck
、mosi
和miso
。
有两个硬件SPI通道支持更快的传输速率(高达 80Mhz)。这些通道可用于任何支持所需方向且未使用的IO引脚(参见引脚和 GPIO),但如果未配置为默认引脚,则需要通过额外的 GPIO 多路复用层,这会影响其高速运行时的可靠性。硬件 SPI 通道在下列默认引脚之外的引脚上使用时,频率限制为40MHz。
HSPI(id=1) | VSPI(id=2) | |
---|---|---|
sck | 14 | 18 |
mosi | 13 | 23 |
miso | 12 | 19 |
硬件SPI通过machine.SPI
类访问,并且有跟上面软SPI同样的方法:
from machine import Pin, SPI
hspi = SPI(1, 10000000)
hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
软I2C(使用 bit-banging)可以工作在所有可输出引脚,通过machine.SoftI2C
类进行访问:
from machine import Pin, SoftI2C
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000)
i2c.scan() # 扫描设备
i2c.readfrom(0x3a, 4) # 从地址为0x3a的设备读取4个字节
i2c.writeto(0x3a, '12') # 想地址为0x3a的设备写入'12'
buf = bytearray(10) # 创建一个10字节的缓冲区
i2c.writeto(0x3a, buf) # 将缓冲区的内容写入外设
这里有两个两个不同的硬总线外设0和1,任何可以输出的端口都可以被用于SCL和SDA,缺省情况如下:
||I2C(0)|I2c(1)|
|scl|18|25|
|sda|19|26|
驱动程序通过machine.I2C
类进行访问,方法跟上面的软I2C相同:
from machine import Pin, I2C
i2c = I2C(0)
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
使用machine.I2S
:
from machine import I2S, Pin
i2s = I2S(0, sck=Pin(13), ws=Pin(14), sd=Pin(34), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # 创建I2S对象
i2s.write(buf) # 将音频采样缓冲区写入I2S设备
i2s = I2S(1, sck=Pin(33), ws=Pin(25), sd=Pin(32), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # 创建I2S对象
i2s.readinto(buf) # 从I2S设备填充到音频采样缓冲区
I2S类当前只有在技术预览版可用,在预览期间鼓励用户反馈问题,基于用户的反馈,I2S类相关的API实现可能会有调整。
使用machine.RTC
:
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # 设置指定的日期和时间
rtc.datetime() # 获取日期和时间
使用machine.WDT
:
from machine import WDT
# 启用超时时间为5秒的看门狗(最小为1秒)
wdt = WDT(timeout=5000)
wdt.feed()
以下代码可用于休眠、唤醒和检查复位原因:
import machine
# 检查设备是否从深度休眠被唤醒
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
# 让设备进入深度休眠模式10秒
machine.deepsleep(10000)
注意:
deepsleep()
方法时,如果没有参数将使设备处于无限期休眠状态。一些 ESP32 引脚(0、2、4、12-15、25-27、32-39)在深度睡眠期间连接到 RTC,并可使用 esp32 模块中的 wake_on_ 功能唤醒设备。在进入深度休眠状态时,具有输出功能的 RTC 引脚(除 34-39 引脚外的所有引脚)也将保留上拉或下拉电阻配置。
如果在深度休眠期间不需要上拉电阻,而且上拉电阻可能会导致电流泄漏(例如,上拉电阻通过开关连接到地),则应在进入深度休眠模式前禁用上拉电阻,以节省电能:
from machine import Pin, deepsleep
# 配置输入RTC引脚,启动时上拉
pin = Pin(2, Pin.IN, Pin.PULL_UP)
# 禁用上拉功能并让设备休眠 10 秒钟
pin.init(pull=None)
machine.deepsleep(10000)
如果使用 Pin.init() 的 hold=True 参数启用了焊盘保持,则输出配置的 RTC 引脚也将在深度休眠状态下保持其输出方向和电平。
进入深度休眠时,非 RTC GPIO 引脚将默认断开连接。非 RTC 引脚的配置(包括输出电平)可通过在引脚上启用焊盘保持和在深度休眠期间启用 GPIO 焊盘保持来保留:
from machine import Pin, deepsleep
import esp32
opin = Pin(19, Pin.OUT, value=1, hold=True) # 保持输出电平
ipin = Pin(21, Pin.IN, Pin.PULL_UP, hold=True) # 保持上拉
# 为非 RTC GPIO 启用深度休眠时的焊盘保持功能
esp32.gpio_deep_sleep_hold(True)
# 让设备休眠 10 秒
deepsleep(10000)
从休眠状态唤醒时,引脚配置(包括焊盘保持)将被保留。有关焊盘保持的进一步讨论,请参阅上文的引脚和 GPIO。
使用machine.SDCard
:
import machine, os
# Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
sd = machine.SDCard(slot=2)
os.mount(sd, '/sd') # mount
os.listdir('/sd') # list directory contents
os.umount('/sd') # eject
RMT为ESP32专用,可生成分辨率为 12.5ns 的精确数字脉冲,可以用于红外遥控器。用法如下:
import esp32
from machine import Pin
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
#通道分辨率为 100ns(1/(源频率/时钟分频))。
r.write_pulses((1, 20, 2, 40), 0) # 发送 0 表示 100 毫秒,1 表示 2000 毫秒,0 表示 200 毫秒,1 表示 4000 毫秒
OneWire 驱动程序通过软件实现,可用于所有引脚:
from machine import Pin
import onewire
ow = onewire.OneWire(Pin(12)) # 在GPIO12创建一个OneWire总线
ow.scan() # 返回总线上的设备列表
ow.reset() # 重置总线
ow.readbyte() # 读取一个字节
ow.writebyte(0x12) # 向总线写一个字节
ow.write('123') # 向总线写多个字节
ow.select_rom(b'12345678') # 根据ROM代码选择指定的设备
DS18S20 和 DS18B20 设备有专门的驱动程序:
import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(ds.read_temp(rom))
确保在数据线上加一个 4.7k 的上拉电阻。请注意,每次采样温度时都必须调用 convert_temp() 方法。
使用 neopixel 和 apa106 模块:
from machine import Pin
from neopixel import NeoPixel
pin = Pin(0, Pin.OUT) # 将GPIO0设置为NeoPixels设备
np = NeoPixel(pin, 8) # 在 GPIO0 上为 8 个像素创建 NeoPixel 驱动程序
np[0] = (255, 255, 255) # 设置第1个点为白色
np.write() # 将数据写入所有的点
r, g, b = np[0] # 获取第一个像素点的颜色
APA106 驱动程序扩展了 NeoPixel,但内部使用了不同的颜色顺序:
from apa106 import APA106
ap = APA106(pin, 8)
r, g, b = ap[0]
**警告:**默认情况下,NeoPixel 被配置为控制更常用的 800kHz 设备。在构建 NeoPixel 对象时,可以通过 timing=0 来控制其他设备(通常为 400kHz)。
有关 NeoPixel 的底层驱动,参见 machine.bitstream
。该底层驱动程序默认使用 RMT 通道,要进行配置,参见RMT.bitstream_channel
。
APA102 (DotStar) 使用不同的驱动器,它有一个额外的时钟引脚。
在machine
模块中使用TouchPad
类:
from machine import TouchPad, Pin
t = TouchPad(Pin(14))
t.read() # 触摸时返回较小的数字
TouchPad.read
返回一个与电容变化相关的值。当引脚被触摸时,通常是小数(通常为几十),而当没有触摸时,则是大数(超过一千)。不过,数值是相对的,会因电路板和周围环境的不同而变化,因此可能需要进行一些校准。
ESP32上有10个支持电容式触摸的引脚:0、2、4、12、13、14、15、27、32、33。尝试为其他引脚赋值将导致ValueError
。
请注意,触摸板可用于从睡眠状态唤醒 ESP32:
import machine
from machine import TouchPad, Pin
import esp32
t = TouchPad(Pin(14))
t.config(500) # 配置引脚触碰的阈值
esp32.wake_on_touch(True)
machine.lightsleep() # 让 MCU 进入休眠状态,直到触摸板被触摸
DHT 驱动程序由软件实现,可在所有引脚上运行:
import dht
import machine
d = dht.DHT11(machine.Pin(4))
d.measure()
d.temperature() # 例如: 23 (°C)
d.humidity() # 例如: 41 (% RH)
d = dht.DHT22(machine.Pin(4))
d.measure()
d.temperature() # 例如: 23.6 (°C)
d.humidity() # 例如: 41.3 (% RH)
WebREPL(WebSockets 上的 REPL,可通过网络浏览器访问)是 ESP32 端口的一项实验性功能。从 https://github.com/micropython/webrepl 下载 Web 客户端(托管版本可从 http://micropython.org/webrepl 获取),并通过执行以下操作进行配置:
import webrepl_setup
并按照屏幕上的说明操作。重启后,即可连接。如果禁用了开机自动启动功能,则可以使用以下命令按需运行配置的守护进程:
import webrepl
webrepl.start()
# or, start with a specific password
webrepl.start(password='mypass')
WebREPL 守护进程监听所有活动接口,这些接口可以是 STA 或 AP。这样,您就可以通过路由器(STA 接口)连接到 ESP32,或直接连接到 ESP32 的接入点。
除了终端/命令提示符访问外,WebREPL 还提供文件传输(上传和下载)功能。网络客户端有相应功能的按钮,也可以使用上面软件仓库中的命令行客户端 webrepl_cli.py
。