上周在客户现场调一套基于树莓派 Pico 的采集设备,主程序跑到最后一个状态机就崩,手边只有一台安卓手机和一条 OTG 转接线。那会儿我脑子里闪过一排方案:装串口调试助手、装 IDE、找一台 Ubuntu 笔记本……全都不现实。后来我发现,MicroPython 生态里早就有了一条"浏览器即 IDE"的路线,不需要在手机上装任何 App,也不需要装驱动,打开 Chrome 连上 USB 就能直接调试树莓派 Pico。这篇文章就把这条路线的原理、工具选型和我在手机端实测的完整过程写清楚。如果你的工作也经常带着板子跑现场,或者你手头只有 iPad / 安卓平板,这篇文章应该能帮你省下不少折腾时间。
1. 为什么会盯上"浏览器里跑 IDE"这条路线
1.1 传统手机调试方案的真实痛点
先说我踩过的传统方案。拿树莓派 Pico 调试这个场景来说,Thonny 在电脑上确实好用,但它在手机上没有官方支持,安卓上装个 Linux 模拟器再跑 Thonny 属于自虐;有人推荐用 Termux 配串口读写,可你需要手动烧 pyserial、解决 USB 权限,还要适配 MicroPython 的 REPL 交互,光是输入多行代码就够呛。更常见的是用各种"串口调试助手"App,它们普遍的问题是:只能收发十六进制或纯文本,无法做文件上传,也没有代码编辑器,调试 main.py 这种带缩进的脚本时基本等于废的。
另外一个容易忽略的问题是驱动。Windows 上 Pico 的虚拟串口虽然免驱,但安卓手机会把 USB 设备按照 usb serial 类识别,有些 App 根本不识别。就算识别了,还要处理权限弹窗、OTG 供电不稳、后台断连等一堆问题。结论是:在手机端调试 MicroPython,最省力的方式不是去适配"手机上的串口软件",而是绕开本地 App,让浏览器直接接管串口。
1.2 为什么浏览器方案能成立
如果你对 Web 技术停留在"网页只能显示静态内容"的印象,那得更新一下认知了。Chrome 从 89 版本开始正式支持 Web Serial API,浏览器可以直接枚举、打开系统串口,并通过 JavaScript 进行读写。这意味着你可以把整个编辑器、REPL 终端、文件树全部写到网页里,用户打开页面后点击授权,浏览器就把 USB 设备"交"给网页,所有操作都在本地完成,不需要中间代理,也不需要额外装驱动。
这条思路对树莓派 Pico 特别友好。Pico 使用的 RP2040 芯片,MicroPython 固件里默认通过板载 USB 实现一个虚拟串口设备(USB CDC),电脑和手机把它识别成一个串口端口。浏览器 Web Serial 操作的就是这个端口。所以整条链路就是"Pico 通过 USB 线连手机 → Chrome 打开在线 IDE → 授权串口 → 直接跑代码",听起来复杂,实际用起来就是插线、连接、写代码。
1.3 浏览器 IDE 解决了哪三类人的问题
我总结下来,这条路线真正受益的人群有三类。第一类是硬件工程师,出差现场只需要改个小逻辑或者看传感器数据,身边只有手机;第二类是教育场景的老师和学生,学校机房如果浏览器统一管制装软件困难,直接打开网页就能写 Pico 程序;第三类是喜欢折腾的极客,想用 iPad 这种轻办公设备连开发板。这三类人都不是专业做 Web 前端的,但都可以从浏览器 IDE 中受益,因为这套方案降低了"环境搭建"的门槛,把精力全部留给业务代码。
2. 手机浏览器连 Pico 的关键原理:Web Serial 与虚拟串口
2.1 RP2040 的 USB 虚拟串口是怎么被浏览器识别的
树莓派 Pico 上电后,MicroPython 固件会在 USB 枚举时声明一个"通信设备类(CDC)"接口,主机侧看到的就是一个标准的串口设备。在 Windows 上它显示为 COM 口,在 Linux 上是 /dev/ttyACM0,在安卓上它就是 USB 子系统的 CDC ACM 设备。Chrome 的 Web Serial API 拿到这个设备的读写权限后,本质上做的是和任何串口调试工具完全一样的事情:设置波特率、发送字节流、接收字节流。
需要注意一点,Pico 的 MicroPython 固件在虚拟串口上有个特殊行为:只有 DTR(数据终端就绪)信号被拉高时,REPL 才会真正开始输出提示符,否则串口常常是"黑屏"状态。这也就是为什么很多人第一次用浏览器 IDE 连接后,终端区域什么都没有。许多 Web IDE 在连接时会自动设置 DTR,但如果碰到连接后空白,你要知道去手动切换 DTR 状态,而不是怀疑设备坏了。
2.2 Web Serial API 的使用边界和安全限制
Web Serial API 不是一个全能串口工具,它有几个硬性约束,一定要提前了解。首先,它要求页面必须是 HTTPS 环境或者 localhost 本地环境,纯 HTTP 的服务器上 API 会被禁用,所以在手机上访问在线 IDE 时,网站必须支持 HTTPS,否则授权弹窗根本出现不了。其次,打开串口的操作必须发生在用户手势里,比如点击按钮的响应函数中,浏览器不允许网页在后台偷偷打开串口。还有,一个串口设备同一时间只能被一个页面上下文占用,如果手机上后台还挂着别的调试页面,新的连接就会失败。
在安卓端还要注意版本问题。Web Serial 在桌面 Chrome 上已经比较成熟,安卓端则是 Chrome 123 之后才进入可用状态。如果你用的浏览器是某些国产套壳内核,或者系统自带的旧版 WebView,很可能连 API 都不存在。比较稳妥的办法是直接用 Google Chrome 稳定版,并在地址栏输入 chrome://version 确认版本号够新。iOS 上的 Safari 目前仍然不支持 Web Serial,想要在 iPhone 或 iPad 上走这条路线,基本只能考虑用支持 Web Serial 的第三方浏览器内核,或者绕道 WebREPL。
2.3 既然有蓝牙串口,为什么不走蓝牙通道
有人会问:手机和 Pico 之间用 USB 太局限,如果给 Pico 加一个 HC-06 蓝牙模块,再在浏览器里用 Web Bluetooth API 不也一样吗?理论上是可行的,但实际操作起来坑更多。Web Bluetooth 需要设备支持 BLE GATT 服务,而 HC-06 这类经典蓝牙串口模块并不支持 GATT,BLE 模块则要额外写服务端固件。相比之下,USB CDC 是 MicroPython 官方在底层就封装好的,没有任何额外协议成本,稳定性和兼容性都更好。蓝牙更适合"设备已经跑起来后的无线运维"场景,这个我们放到最后一部分再展开。
3. 现成方案对比:PyMakr 与 WebREPL 怎么选
3.1 PyMakr:功能最完整的浏览器端 MicroPython IDE
这次手机调试的主力工具我选的是 PyMakr。它是一个纯网页的 MicroPython 开发环境,页面里集成了文件管理、代码编辑器、REPL 终端、绘图工具和多个设备的切换功能。它走的正是 Web Serial 这条链路,Pico 通过 USB 连到手机后,直接点击网页上的 Connect 按钮,在系统弹窗中选择 USB Serial 设备即可。
PyMakr 最大的优势是"零安装"和"功能闭环"。在电脑上你可能已经习惯了 Thonny 的文件树和 REPL 一体化,PyMakr 基本把这一套搬到了浏览器里。树莓派 Pico 插上手机后,你可以在网页的文件区看到板子上的 boot.py、main.py,可以直接编辑并保存到设备,也可以右键上传本地文件。对调试来说,"上传 main.py 后自动软复位运行"这个功能特别重要,因为它复现了 Thonny 中最常用的流程——改代码、同步、看日志。
3.2 WebREPL:更适合 Pico W 和 ESP 系列
WebREPL 是 MicroPython 官方固件中提供的另一个远程调试协议,它不走 USB 串口,而是让设备通过 WiFi 启动一个 WebSocket 服务,默认端口 8266。浏览器打开 webrepl.html 页面,输入设备 IP 和密码就能进入一个交互式 REPL。这个方案最大的优点是"无线且不占串口",设备放在远处也能调试,特别适合已经固定安装的采集节点。
但 WebREPL 对基础版树莓派 Pico(RP2040 无 WiFi 版)并不友好,因为普通 Pico 没有无线网卡,你需要外接 ESP32/ESP8266 做桥接,或者直接用 Pico W。这一点是选型时的分水岭。我自己的使用习惯是:手头是普通 Pico 且需要在现场快速改代码时,无条件用 PyMakr;如果手头是 Pico W,且主要问题是"设备在墙上装好了,只想远程看日志",那 WebREPL 是更优解。
3.3 两套方案的核心参数对比
| 对比项 | PyMakr | WebREPL |
|---|---|---|
| 连接方式 | USB 串口(Web Serial) | WiFi WebSocket |
| 手机端前置条件 | Android Chrome 123+,支持 OTG | 手机与设备同一局域网 |
| 必需硬件 | 普通 Pico 即可 | Pico W 或 ESP32/ESP8266 才能原生使用 |
| 文件上传能力 | 支持可视化文件管理 | 官方页面仅支持文件传输,但体验较弱 |
| 代码编辑器 | 内置,带语法高亮 | 无独立编辑器,主要靠复制粘贴 |
| 典型调试场景 | 现场插线改程序 | 远程运维、看日志 |
从表格能看出,两者并不是替代关系,而是互补关系。对于核心问题"不装软件、手机上调试树莓派 Pico"来说,PyMakr 是更直接的一站式答案;而 WebREPL 的价值在于"设备装好以后的远程访问",可以作为一个进阶选项。
4. 手机实际操作全流程:从授权到跑通 LED
4.1 硬件和系统准备
在开始之前,你需要确认几样东西:
- 一台支持 USB OTG 的安卓手机,一般来说近几年主流旗舰和中端机都支持。
- 一条 OTG 转接线,如果你手头只有电脑上用的普通 USB 数据线,还需要一个 Type-C 转 USB-A 的转接头。
- 树莓派 Pico 以及一根标准 Micro-USB / Type-C 数据线(取决于你手里的 Pico 版本)。
- Chrome 浏览器,建议升级到最新稳定版。
比较坑的一点是,很多手机在插上设备后默认只开启充电模式,你的通知栏会弹出一个"USB 连接方式"的选项,需要手动选择"传输文件"或者"MTP"模式。有的系统里还藏着一个"USB 调试"的总开关,如果插上后 Pico 完全没有供电,先去手机设置里确认 OTG 开关是否打开。这个环节我在两台手机上都遇到过,不处理的话浏览器根本枚举不到设备。
4.2 Chrome 授权串口的完整流程
打开浏览器访问 PyMakr 的在线页面,点击页面左下方的 Connect 按钮。这时 Chrome 会弹出一个设备授权窗口,列出所有当前可用的串口设备。选择树莓派 Pico 对应的端口后,页面会显示连接状态,终端区域会跳出 MicroPython 的>>>提示符。
这里有个细节:安卓手机上的弹窗文字可能与设备实际名称对不上。Pico 在固件里通常会把设备描述为 "Board in FS mode" 或 "Raspberry Pi Pico",但也有些第三方固件会把它命名为其他字符串。如果不确定,可以先拔掉 USB,观察弹窗里哪一项消失了,再插回去确认。另一种笨办法是直接在设备列表里逐个测试,连接失败也没有副作用,重新点 Connect 就行。
4.3 文件管理、上传代码与 REPL 调试
连接成功后,左侧会显示设备文件系统。Pico 的 MicroPython 文件系统默认有 boot.py 和 main.py 两个文件。你可以直接点击文件在右侧编辑,保存时会自动覆盖设备上的旧文件。如果要上传一个全新的脚本,用文件区的 Upload 功能选中本地文件即可。
这里要重点说一个我刚开始时不太习惯、但用顺后觉得非常合理的设计:PyMakr 的代码编辑器修改内容后不会自动同步到设备,你需要手动执行上传或运行操作。在执行运行命令时,它会通过 REPL 的粘贴模式(paste mode)把整段代码发给 Pico,这个模式保证了缩进和空行不会被串口终端逐字解释破坏。在手机端没有键盘快捷键的情况下,直接点击界面上的 Run 按钮同样会进入这个流程。
跑通一个小实验是验证环境最好的方式。我现场写了一个 LED 闪烁程序:
from machine import Pin import time led = Pin("LED", Pin.OUT) while True: led.toggle() time.sleep(0.5)在 PyMakr 编辑器输入这段代码,点击运行,Pico 板载 LED 就会以 0.5 秒的间隔闪烁。看到这个结果,基本说明整条链路已经通了。如果想停止循环,在 REPL 终端点击中断按钮,或者发送 Ctrl+C 组合键,Pico 会抛出一个 KeyboardInterrupt 并退出循环。
4.4 读取 ADC 和传感器数据验证调试能力
光跑 LED 还不够,调试的核心是看数据。我现场给 Pico 接了一个电位器,读取它的 ADC 值。PyMakr 的绘图面板可以实时把数据画成波形,这比串口助手一行行刷数据直观得多。代码很简单:
from machine import Pin, ADC import time adc = ADC(Pin(26)) while True: print(adc.read_u16()) time.sleep(0.05)点击绘图区域的开始按钮后,波形会随着电位器旋钮的变化实时更新。这一步验证的不只是"能不能连上",而是"在手机浏览器里做实时数据监控是否可行"。实测下来,50ms 一次的采样在网页上绘制波形没有明显卡顿,对于定位传感器异常、观察信号趋势来说完全够用。
5. 踩坑记录:手机浏览器调试 Pico 的常见问题
5.1 连接后终端空白,没有任何提示符
这个问题的根因我在前面已提到,多半是 DTR 信号没有拉高。PyMakr 有时会因为上一次异常断开,没有正确重置串口状态。解决办法是点击连接状态区域的 DTR 按钮,强制切换一次信号,或者先断开连接,拔掉 USB 线重新插。如果反复都不行,还有一个排查方向:在电脑上用 Thonny 连接同一块板子。如果电脑上能看到 REPL,说明 Pico 和固件没问题,问题只出在手机端串口状态,重新插拔基本能解决;如果电脑上也没提示符,那要检查固件本身,可能处于异常运行状态,需要进入 BOOTSEL 刷机模式重新烧录 MicroPython。
5.2 上传 main.py 后自动运行失败,或运行的是旧代码
这是新手最容易懵的场景。MicroPython 的上电流程是:先执行 boot.py,再执行 main.py。如果 main.py 里写了死循环且没有异常保护,Pico 上电后就会一直卡在循环里,REPL 无法进入交互模式。更麻烦的是,你在网页上修改代码时可能因为运行卡死而无法正常同步。
遇到这种情况,手动复位是标准解法。按住 Pico 上的 RESET 按钮不放,同时用软件发送 Ctrl+C,争取进入 REPL 提示符,然后马上删除或修改 main.py。如果你不想让异常卡住启动流程,可以在 main.py 外层包一个 try-except 并在异常时输出错误信息:
import sys def main(): while True: pass if __name__ == "__main__": try: main() except Exception as e: sys.print_exception(e)这种做法在调试阶段非常有用,至少你能在 REPL 里看到异常堆栈,而不是面对一块毫无反应、不断复位的板子。
5.3 授权弹窗不出现,或点击后没有可选设备
授权弹窗不出现的原因通常能锁定到三个方向。第一个是页面协议不对,确认地址栏是 HTTPS,不是 http;第二个是 Chrome 版本过低,安卓 Web Serial 支持从 Chrome 123 才开始稳定,建议直接更新到最新版;第三个是系统层面的 USB 权限没给,很多手机在插上 OTG 设备后默认不弹授权,需要在系统设置里找到"OTG 连接"或"USB 配件"类目,手动允许 Chrome 访问。
点击后没有可选设备,则要怀疑 OTG 线供电不足。树莓派 Pico 在纯 USB 供电下电流需求不高,但劣质 OTG 线会导致设备的枚举失败。我踩过一次:一根一转多的转接头上插着 Pico、手机充电线和其他外设,结果 Chrome 永远只能看到一个乱码设备。后来换成单口 OTG 线,问题立刻消失。建议现场常备一根高质量单口 OTG 线,别在这个环节较劲。
5.4 连接不稳定,亮屏时正常,锁屏或切换 App 后掉线
手机端调试的另一个大坑是后台进程被系统回收。Chrome 一旦在后台被冻结,Web Serial 连接就会断掉,而且多数情况下重新连接后 REPL 状态会被打断。我的解决方式是:在调试期间把屏幕超时时间调到最长,打开 Chrome 的"后台运行"权限,再关闭系统的省电模式对 Chrome 的优化限制。
如果你是在高通平台手机上调试,还有一个隐蔽问题:部分厂商会启用"USB 省电"或"锁屏后暂停 USB 充电",这会导致 USB 总线被重置。去设置里把"USB 供电"相关选项关掉,能显著降低掉线概率。这个坑没有特别系统的资料,基本是靠现场挨个试设置项才发现的。
5.5 手机软键盘影响 REPL 输入,如何处理特殊按键
在手机端使用 REPL 输入 Ctrl+C、Ctrl+D 这类快捷键很痛苦,因为软键盘上没有 Control 键。PyMakr 界面上有一些对应的操作按钮,但如果你用的其他 WebREPL 页面没有这些按钮,就要自己想办法。我的建议是:尽量在编辑器里写好代码整体运行,不要试图在 REPL 里逐行敲入复杂逻辑;如果确实需要中断运行,优先点页面上的中断按钮,而不是去按手机键盘。
对中文注释的问题多说一句。Pico 的 REPl 输出默认使用 UTF-8,大部分情况下中文能正常打印,但如果你在手机编辑器中复制了来自网页的代码,可能带进全角空格或不可见字符。粘贴后如果报 SyntaxError,优先检查引号、空格和缩进是否都是半角字符。
6. 还能怎么玩:从浏览器调试到远程设备管理
6.1 用 Pico 搭建局域网 Web 控制台
浏览器调试解决了"开发期"的问题,而"运维期"的问题可以用类似思路再进一步。我给现场设备写过一个小型 Web 控制台:Pico W 上跑一个 MicroPython 的 Web 服务器,网页里放了 GPIO 开关按钮、传感器读数区域和一段简单的状态日志。手机浏览器直接访问设备 IP,不需要装任何 App,就能远程控制继电器和查看温度。
这意味着浏览器不仅是 IDE,也可以是设备的管理界面。对使用普通 Pico 的场景,你可以外接一个 ESP8266 作为串口转 WiFi 模块,把数据转发到网页端。不过这条路配置复杂度会高不少,适合 Arduino 或 MicroPython 基础不错的人。
6.2 用浏览器脚本做简单的自动化冒烟测试
调试不只是"人盯着 REPL 看",还可以写一段脚本批量做回归检查。Web Serial 的 API 比较底层,但你可以在页面控制台里用 JavaScript 直接发送串口指令并比对返回值。比如给 Pico 发送一个自定义命令让它在某个 GPIO 上输出高电平,然后通过另一个引脚读取反馈,这就构成了一个最基本的自动化测试闭环。我写过一段非常简易的示例:
const port = await navigator.serial.requestPort(); await port.open({ baudRate: 115200 }); const writer = port.writable.getWriter(); const encoder = new TextEncoder(); await writer.write(encoder.encode("print(1+1)\r\n"));这段代码的作用是让浏览器直接向 Pico 发送一行 MicroPython 指令,并把计算结果读回来。如果把类似的命令封装成带 pass/fail 判断的函数,再配合浏览器端的定时器,就能实现一个很轻量的自动化测试。对于生产线上的固件验证场景,这套思路比每台设备都开一个 Thonny 客户端靠谱得多。
6.3 手机同时管理多块 Pico 的现场用法
如果你在现场同时调试多块板子,可以充分利用 Chrome 的多标签页机制,每个标签页打开一个 PyMakr 页面,分别授权不同的 USB 设备。不过受限于手机 USB 口的数量,你需要一个 USB HUB。操作时先把所有 Pico 都插到 HUB 上,再在标签页里逐个连接,注意区分设备名,建议在外壳上用不同颜色的标签做标记。我在一次环境监测的项目里同时接了 3 块 Pico,分别采集温湿度、气压和光照,三个标签页并行查看数据时,现场排错的效率比之前用电脑循环切换串口还要高。
写在最后的实际操作经验
这套浏览器 IDE 方案在我的工作流里已经稳定运行了一段时间。现在出差我会常备一根 OTG 线,包里永远放着一块刷好 MicroPython 的 Pico,遇到客户现场需要快速验证逻辑,直接打开手机 Chrome 就能处理。最有价值的并不是"不用装软件"这个表层的便利,而是它把开发环境的复杂度完全屏蔽掉了,让注意力回到设备本身。如果你经常带着板子跑现场,或者想让学生用最低的摩擦成本接触 MicroPython,这条路线值得花一个晚上试一遍。记得先确认 Chrome 版本和 OTG 线质量,这两个基础条件满足后,整个体验会顺畅得超出预期。