1. 为什么我要在平板上调试 ESP32
第一次接触 ESP32 的时候,我和大多数人一样,老老实实坐在电脑前,装 Arduino IDE、配串口驱动、选开发板型号、调波特率,一整套流程走下来少说二十分钟。后来项目多了,经常需要在现场改几行参数、看一段日志,总不能每次都抱着笔记本跑。尤其是做 BLE 相关的调试,设备本身就在手边,电脑反而成了累赘。
PyBLE 这个项目就是在这个背景下进入我视野的。它做的事情说起来很简单:在 Android 平板上跑一个 MicroPython 的编辑器加终端,通过 BLE 蓝牙直接连上 ESP32,让你在平板上写代码、传文件、看输出。核心关键词就是ESP32、BLE、PyBLE、MicroPython、IDE这五个。它解决的不是什么高深问题,就是“我不想开电脑”这个最朴素的诉求。
这篇文章适合谁看?如果你手上有一块刷了 MicroPython 固件的 ESP32,又恰好有一台 Android 平板,那这篇内容基本可以照着抄。如果你还没入门 ESP32,但想找一个轻量的调试方式,也可以先了解一下这套方案的边界在哪里。我会把整个链路的原理、配置步骤、踩过的坑都摊开讲,尽量让你少走弯路。
需要提前说明的是,PyBLE 不是要取代桌面 IDE。它更像是一把随身携带的螺丝刀,适合快速验证、现场调试、教学演示这类场景。真正复杂的工程还是得回到电脑上做。搞清楚这个定位,后面的内容你理解起来会顺畅很多。
2. PyBLE 到底是什么,它凭什么能跑起来
2.1 从 MicroPython 的 REPL 说起
要理解 PyBLE,得先理解 MicroPython 在 ESP32 上是怎么工作的。ESP32 刷入 MicroPython 固件后,会暴露一个交互式解释器,也就是 REPL(Read-Eval-Print Loop)。你通过串口发过去的每一行代码,它都会立即执行并返回结果。这个机制是 PyBLE 能够存在的基础。
传统方式下,REPL 走的是 UART 串口,需要 USB 线连接。而 ESP32 的 MicroPython 固件从某个版本开始,支持把 REPL 重定向到 BLE 上。具体来说,固件里内置了一个 BLE 串口服务,它模仿了 Nordic UART Service 的收发特征。平板端只要作为 BLE 中心设备连上去,往指定的特征值写数据,就相当于往 REPL 里输入代码;订阅另一个特征值的通知,就能收到执行结果。
PyBLE 做的事情,就是把这个 BLE 串口包装成一个像模像样的编辑器界面。你在平板上敲的代码,通过 BLE 发到 ESP32,ESP32 执行完把输出回传,PyBLE 再显示出来。整个过程和你在电脑上用串口终端没有本质区别,只是物理链路从 USB 换成了蓝牙。
2.2 BLE 相比串口调试的优势与代价
用 BLE 替代串口,好处很直接。第一是摆脱线缆,平板和 ESP32 之间只要在蓝牙范围内就能通信,调试一些装在外壳里或者挂在墙上的设备时特别方便。第二是平板本身有屏幕和键盘,比手机更适合写代码,又比笔记本轻便。第三是 BLE 连接不占用 USB 口,ESP32 的 USB 口可以空出来做别的用途,比如同时接传感器或者供电。
代价也很明显。BLE 的吞吐量远不如 USB 串口,传大文件会慢得让人抓狂。延迟也比有线高,输入命令后要等一小会儿才有回显。另外 BLE 连接本身有稳定性问题,距离远了、干扰多了都可能断连。所以 PyBLE 适合的是小段代码的编辑和调试,不适合传输大型固件或者做高速数据采集。
我自己的使用习惯是:日常改改配置、跑跑测试脚本用 PyBLE,涉及大量文件同步或者长时间数据记录的时候,还是老老实实插 USB 线。把工具用在合适的场景里,比强行让它干所有事要明智得多。
2.3 这套方案对硬件和固件的要求
不是所有 ESP32 都能直接配合 PyBLE 使用。首先开发板得支持 BLE,ESP32 经典款、ESP32-S3、ESP32-C3 这些都没问题,但像 ESP32-S2 这种只有 Wi-Fi 没有蓝牙的型号就不行。其次 MicroPython 固件必须是较新的版本,因为 BLE REPL 功能是后来才加进去的。我用的是 1.20 以上的版本,实测比较稳。
平板这边,Android 版本建议 8.0 以上,蓝牙要支持 BLE 4.0 及以上。大部分近几年的平板都满足这个条件。iOS 设备目前支持情况不太理想,PyBLE 主要还是面向 Android 生态。这一点在选设备的时候要提前确认,别买回来发现用不了。
固件刷写这一步是绕不过去的。你需要用 esptool 把 MicroPython 固件烧进 ESP32,具体命令后面会详细讲。烧完之后还要确认固件里 BLE REPL 是开启状态,有些固件默认是关的,需要手动改配置或者重新编译。这个细节很多人第一次会忽略,导致连不上还以为是平板的问题。
3. 从零开始搭建 BLE 调试环境
3.1 给 ESP32 刷入支持 BLE REPL 的固件
第一步是准备固件。去 MicroPython 官网下载对应你开发板型号的固件文件,注意要选带 BLE 支持的版本。以 ESP32 通用版为例,文件名通常类似esp32-20230426-v1.20.0.bin这种格式。下载下来之后,用 USB 线把 ESP32 连到电脑上。
刷写之前先确认串口设备号。Linux 和 macOS 下一般是/dev/ttyUSB0或/dev/tty.usbserial-xxx,Windows 下是COM3之类的。然后执行擦除和烧录两条命令:
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-20230426-v1.20.0.bin烧录完成后,ESP32 会自动重启,这时候 BLE REPL 应该已经可用了。但为了保险,我建议先用串口工具连上去,手动确认一下 BLE 功能是否正常。在 REPL 里输入下面几行代码:
import bluetooth ble = bluetooth.BLE() ble.active(True)如果没有报错,说明 BLE 模块工作正常。接着可以查一下当前广播状态,确认设备名和服务的 UUID。这一步很关键,因为后面平板搜索设备时要靠这些信息来识别。
注意:有些开发板的固件默认没有把 BLE REPL 编进去,需要自己用源码编译。如果你烧完固件发现
bluetooth模块导入失败,大概率就是这个原因。换一个官方预编译的固件通常能解决。
3.2 在平板上安装并配置 PyBLE
PyBLE 在应用商店里可以直接搜到,安装过程没什么好说的。打开之后界面很简洁,主要就三个区域:设备扫描列表、代码编辑区、输出终端。第一次使用需要授予蓝牙权限,Android 12 以上还要额外授予“附近设备”权限,这个权限名字变了但实质一样。
进入主界面后点扫描,正常情况下几秒钟内就能看到你的 ESP32 设备名。如果扫不到,先检查 ESP32 是否已经上电并且 BLE 处于广播状态。我遇到过一种情况是 ESP32 之前连过别的设备,广播停了,需要重启一下才会重新开始广播。
连接成功后,PyBLE 会自动识别 BLE 串口服务,你不需要手动填 UUID。这一点比某些通用 BLE 调试工具友好很多。连接建立后,编辑区就可以输入代码了,按发送按钮或者回车,代码会通过 BLE 发到 ESP32 执行,结果显示在下方终端里。
3.3 第一次连接必须验证的几件事
连接成功不代表一切正常。我习惯在正式写代码之前做几个快速验证。第一,发一个print("hello"),看终端有没有回显。第二,发import os; os.listdir(),确认文件系统能正常读取。第三,发import gc; gc.mem_free(),看一下剩余内存。这三步走完,基本能判断链路是通的。
如果print没有回显,但连接显示成功,多半是特征值订阅出了问题。PyBLE 一般会自动订阅通知特征,但偶尔会失败。这时候断开重连一次通常能解决。如果os.listdir()报错,可能是固件的文件系统没格式化,需要在串口下执行import uos; uos.VfsLfs2.mkfs(...)重新格式化。
还有一个容易忽略的点是换行符。BLE 串口对换行比较敏感,有些固件要求\r\n,有些只要\n。PyBLE 默认用的是\r\n,大部分情况下没问题。如果你发现代码发过去没反应,可以试试在设置里切换换行符格式。
4. 实际调试中的核心操作与技巧
4.1 用 PyBLE 管理 ESP32 上的文件
MicroPython 的文件系统是扁平结构,所有文件都在根目录下。PyBLE 提供了文件浏览功能,可以查看、上传、下载、删除文件。上传小文件很快,几 KB 的脚本几乎瞬间完成。但超过几十 KB 的文件就会明显变慢,因为 BLE 的传输速率有限。
我通常的做法是:在平板上直接新建一个main.py或者test.py,写完保存到 ESP32 上,然后通过 REPL 执行。这样避免了频繁上传大文件。如果确实需要传大文件,比如字体或者模型数据,我会先用 USB 传一次,之后再用 PyBLE 做小修改。
删除文件要小心。MicroPython 没有回收站,删了就没了。我一般会先用os.listdir()确认文件名,再执行删除。PyBLE 的删除操作有确认弹窗,但手快的时候还是容易点错。养成先看后删的习惯能省很多事。
4.2 在平板上写 MicroPython 代码的实用姿势
平板上的虚拟键盘打字体验肯定不如物理键盘,所以代码要尽量精简。我的经验是:把常用功能封装成函数,存在 ESP32 上,平板上只写调用逻辑。比如把传感器读取、网络连接这些固定流程写成模块,调试时只改参数。
PyBLE 的编辑器支持基本的语法高亮和自动缩进,但不要期待它有桌面 IDE 那么强大。我一般会先在电脑上把代码框架写好,传到 ESP32,然后在平板上做微调。这样既利用了电脑的输入效率,又保留了平板的便携性。
还有一个技巧是利用 REPL 的交互特性。不确定某个 API 怎么用的时候,直接在终端里敲help(模块名)或者dir(对象),比翻文档快得多。MicroPython 的内置帮助虽然简略,但足够让你回忆起关键函数名。
4.3 BLE 连接稳定性优化的几个参数
BLE 连接不稳是这套方案最大的痛点。我踩过的坑包括:距离超过五米就断、旁边有 Wi-Fi 路由器时干扰严重、平板息屏后连接被系统回收。针对这些问题,我总结了几条经验。
第一,尽量让 ESP32 和平板之间没有遮挡物。BLE 用的是 2.4GHz 频段,和 Wi-Fi 同频,金属和水的吸收很厉害。第二,如果环境里 Wi-Fi 设备多,可以尝试在 ESP32 端调整 BLE 的广播间隔和连接参数。MicroPython 里可以通过ble.gap_advertise()设置广播间隔,适当加大能提高被发现概率。
第三,平板的省电策略会杀掉后台蓝牙连接。在系统设置里把 PyBLE 加入电池优化白名单,能显著减少断连。第四,如果连接频繁断开,可以在 ESP32 端加一个看门狗,检测到 BLE 断开后自动重新广播。这个逻辑用 MicroPython 写起来也就十几行代码。
| 问题现象 | 可能原因 | 解决方向 |
|---|---|---|
| 扫描不到设备 | 广播已停止 | 重启 ESP32 或重新触发广播 |
| 连接后无回显 | 通知特征未订阅 | 断开重连,检查 PyBLE 设置 |
| 传输大文件超时 | BLE 吞吐不足 | 改用 USB 传输大文件 |
| 息屏后断连 | 系统省电策略 | 加入电池优化白名单 |
| 距离稍远就断 | 信号衰减 | 缩短距离,减少遮挡 |
5. 常见问题排查与避坑指南
5.1 连接失败的分层排查思路
连接失败是最常见的问题,但原因可能出在链路的任何一层。我的排查顺序是:先看 ESP32 端 BLE 是否激活,再看广播是否正常,然后看平板能否扫描到,最后看连接后服务是否匹配。这个顺序能帮你快速定位问题在哪一层。
ESP32 端可以用串口确认 BLE 状态。如果串口都连不上,那问题在硬件或者固件,跟 PyBLE 无关。如果串口正常但 BLE 不广播,检查代码里有没有调用ble.active(True)和ble.gap_advertise()。如果广播正常但平板扫不到,可能是平板蓝牙权限没给够,或者距离太远。
连接建立后如果服务列表为空,说明 PyBLE 没有找到预期的 BLE 串口服务。这种情况通常是固件版本不匹配,换一个官方固件试试。还有一种可能是 ESP32 同时跑了别的 BLE 服务,占用了资源,导致串口服务初始化失败。
5.2 代码执行异常的典型场景
有时候连接正常,但代码发过去执行报错。最常见的是缩进问题。MicroPython 对缩进敏感,平板上打字容易多一个空格或者少一个空格。PyBLE 的编辑器虽然会显示缩进,但复制粘贴的时候经常出问题。我的建议是尽量用四个空格,不要用 Tab。
另一个常见问题是内存不足。ESP32 的内存有限,加载大模块或者创建大数组时容易触发MemoryError。这时候可以用gc.collect()手动回收,或者把大任务拆成小步骤执行。如果经常遇到内存问题,考虑换 ESP32-S3 这类带 PSRAM 的型号。
还有一种是模块导入失败。MicroPython 的标准库和桌面 Python 差别很大,很多库没有或者名字不一样。比如time.sleep()在 MicroPython 里是time.sleep(),但json模块的功能就比桌面版少很多。写代码前先确认目标模块在 MicroPython 里是否存在。
5.3 我踩过的三个印象最深的坑
第一个坑是固件版本。我一开始用的是开发板自带的旧固件,BLE REPL 功能不完整,连上后只能发不能收。折腾了半天以为是平板问题,后来刷了新固件立刻就好了。所以固件版本一定要用新的,别偷懒。
第二个坑是平板省电。有次调试到一半去接了个电话,回来发现连接断了,代码也丢了。后来才知道是系统把 PyBLE 的后台进程杀了。把应用加入白名单后就没再出现过。这个设置藏得比较深,不同品牌平板位置不一样,需要耐心找一下。
第三个坑是 BLE 和 Wi-Fi 共存。我的项目同时用了 Wi-Fi 和 BLE,发现 BLE 连接特别不稳定。查资料才知道 ESP32 的射频是共享的,Wi-Fi 流量大的时候 BLE 会被挤掉。解决办法是错开使用时间,或者降低 Wi-Fi 的占空比。如果两个都要长时间跑,建议用双核任务分开处理。
提示:遇到诡异问题时,先用串口确认 ESP32 本身是否正常。很多看似是 PyBLE 的问题,根源其实在固件或者硬件。分层排查能省下大量时间。
6. 这套方案适合什么,不适合什么
PyBLE 加 ESP32 加 BLE 的组合,在我看来最适合三类场景。一是现场调试,设备已经装好不方便拆,用平板连上去改几个参数就走。二是教学演示,学生用平板就能看到代码执行结果,不用每人配一台电脑。三是快速原型验证,手边只有平板的时候能应急。
不适合的场景也很明确。需要高速数据传输的,比如音频流、图像处理,BLE 带宽扛不住。需要复杂工程管理的,比如多文件项目、版本控制,平板编辑器力不从心。需要长时间稳定连接的,BLE 本身就不是为这个设计的,偶尔断一下很正常。
我个人的做法是把它当成工具箱里的一件轻量工具。日常开发主力还是桌面 IDE 加 USB 串口,PyBLE 负责那些“懒得开电脑”的时刻。工具没有好坏,只有合不合适。搞清楚边界,用起来就顺手了。
最后分享一个我在实际使用中养成的习惯:每次用 PyBLE 调试完,都会把最终代码通过 USB 同步回电脑备份一份。平板上改的东西容易丢,有个备份心里踏实。这个习惯看起来笨,但帮我省过好几次重写的麻烦。