MicroPython介绍

概述

   MicroPython 是为 MCU 等资源受限环境提供精简和高效的 Python3 实现。它包括了 Python3 标准库的一个子集并且针对 MCU 进行了优化。

   MicroPython 提供了完全的 Python 解析器环境,用户可以在 REPL 中 直接执行命令,也可以导入并运行内置文件系统中的脚本。REPL 提供了命令行环境的通用特性,包括自动补全自动缩进历史记录复制粘贴等。

下载固件

ESP8266 为例,参考ESP8266 NodeMCU 介绍

启动流程

在启动时,会首先执行在内部冻结模块中的 _boot.py 脚本,该脚本会负责在FlashROM中挂载文件系统,如果文件系统不可用,它会进行模块的首次载入并创建文件系统。该部分的启动行为不能被用户修改(即使从源代码构建,也不要去修改它,除非你知道自己在做什么)。

冷冻模块(frozen module)是用Python编写的模块,其编译字节代码对象由 Python 的Freeze Utility纳入了定制的 Python 解释器中。

一旦文件系统被挂载,就可以找到其中的boot.py脚本并执行。它会负责启动WebREPL 后台服务(默认不启动)以及其他服务。该脚本可以被用户修改,例如用户可以修改一些参数或者增加其他后台服务。

未修改的 boot.py,类似下面的脚本:

1
2
3
4
5
6
7
8
9
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import uos, machine
#uos.dupterm(None, 1) # disable REPL on UART(0)
import gc
import webrepl
webrepl.start()
gc.collect()

最后,运行用户程序 main.py,如果该脚本存在于文件系统中 (并且由 boot.py 导入并执行入口函数)。

REPL

串口 REPL

可以通过 UART0 (GPIO1-TX,GPIO0-RX)获得REPL,例如通过USB->TTL转换器连接到 UART0,并使用串口工具通信:

$ picocom /dev/ttyUSB0 -b115200

连接成功后,会得到类似下面的输出:

1
2
3
MicroPython v1.20.0 on 2023-04-26; ESP module with ESP8266
Type "help()" for more information.
>>>

WebREPL

WebREPL 允许用户通过连接 WiFi 后在浏览器中获得 Python 命令行。WebREPL 的客户端可以通过浏览器访问:WebREPL Client

在此之前,用户需要使用 串口 REPL 启用WebREPL后台服务,并设置访问密码。在串口命令行中,执行下面的命令:

1
import webrepl_setup

并根据提示,进行相后续的相关配置(例如访问密码)。

配置完成并重新启动后,会得到下面类似的启动信息:

1
2
3
4
5
6
WebREPL server started on http://192.168.4.1:8266/
Started webrepl in normal mode

MicroPython v1.20.0 on 2023-04-26; ESP module with ESP8266
Type "help()" for more information.
>>>

其中 192.168.4.1是 MicroPython 启动的 AP(无线热点) 中的局部 IP 地址,因此用户需要连接 AP(MicroPython-xxxxx)后才能访问该地址。如果用户已经配置 ESP8266 连接上了一个路由器,则可以不需要再连接 MicroPython AP。

通过浏览器访问 WebREPL Server,会得到类型下面的界面:

输入前面配置的密码,就可以看到熟悉的命令行提示符 >>>

连接 WiFi

连接 WiFi 的命令如下:

1
2
3
4
import network
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('<your SSID>', '<your key>')

如果 AP 不再使用,可以关闭它:

1
2
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)

为了在启动时自动连接 WiFi,用户可以将下面的代码放到 boot.py中:

1
2
3
4
5
6
7
8
9
10
def do_connect():
import network
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect('<ssid>', '<key>')
while not sta_if.isconnected():
pass
print('network config:', sta_if.ifconfig())