1. 项目概述打造你的桌面深空观测站如果你和我一样既是个天文爱好者又是个硬件DIY的发烧友那么把遥远宇宙的探索成果“搬”到自己的桌面上绝对是一件充满成就感的事。詹姆斯·韦伯空间望远镜JWST作为人类目前最强大的太空之眼它的每一次数据回传都牵动着无数人的心。与其不断刷新网页查看状态不如自己动手做一个专属的、低功耗的物理状态显示器让望远镜的“体温”和状态实时呈现在眼前。这个项目的核心就是利用Adafruit MagTag这块神奇的开发板。它集成了ESP32-S2 Wi-Fi芯片和一块2.9英寸的灰度电子墨水屏天生就是为了低功耗、常显的物联网信息牌而生的。我们通过CircuitPython这种对初学者极其友好的编程语言编写一段代码让MagTag定时醒来去NASA的服务器“问”一下韦伯望远镜的最新状态数据然后把关键信息——比如各个仪器和舱段的温度——优雅地显示在电子墨水屏上。完成后它就会进入深度睡眠直到下一个刷新周期如此循环一块小电池就能撑上很久。整个流程听起来复杂但拆解开来其实就是几个清晰步骤的串联硬件准备、环境搭建、网络连接、数据抓取、界面绘制、睡眠管理。无论你是想学习物联网设备开发还是想为你的创客项目找一个有趣的切入点这个项目都能提供一条从原理到实践的完整路径。接下来我会带你一步步走通并分享我在这个过程中踩过的坑和总结出的技巧。2. 硬件选型与核心组件解析工欲善其事必先利其器。这个项目的硬件选择非常明确核心就是Adafruit MagTag。但理解为什么选它以及它周边的“配角”如何搭配能让你在后续开发和问题排查时更加得心应手。2.1 核心大脑Adafruit MagTag开发板MagTag并不是一个简单的ESP32开发板加屏幕的拼凑品而是一个高度集成、为特定场景优化的解决方案。它的核心优势在于超低功耗设计和开箱即用的显示系统。ESP32-S2芯片这是整个设备的“大脑”和“通信官”。相比经典的ESP32S2版本去掉了蓝牙专注于Wi-Fi连接并且在深度睡眠模式下的功耗控制得更好。它负责执行我们的CircuitPython代码发起网络请求并控制屏幕刷新。2.9英寸灰度电子墨水屏这是项目的“脸面”。电子墨水屏的特性是只在刷新图像时才消耗电能一旦图像显示完成即使断电画面也能持续保留。这完美契合了我们“定时更新、长期显示”的需求。MagTag的屏幕驱动已经集成在板子上我们通过CircuitPython的displayio库就能轻松控制无需关心底层时序。内置电池管理板载了锂电池充电电路和连接器你可以直接接上一块3.7V的锂聚合物电池比如常见的500mAh或更大容量的它就能脱离USB线独立工作。充电和电量监控都交给了板载芯片省去了额外设计的麻烦。四个多功能按钮板载的四个按钮标记为A、B、C、D在项目中可以作为手动触发刷新、切换显示模式或进入配置模式的入口提供了交互的可能性。实操心得购买时请注意区分版本。早期的MagTag正面为白色阻焊层可能没有预装UF2引导程序需要多一步刷机操作。而较新的版本正面为黑色通常已预装使用起来更方便。在项目资料中提到的“2025 Edition”则必须使用CircuitPython 10.x或更高版本。2.2 必要配件与选型建议除了MagTag本体你还需要准备以下几样东西USB-C数据线必须是数据线而不能是仅能充电的线。很多人在第一步就卡住电脑识别不到设备问题往往出在线上。一条质量可靠的USB-C to USB-A数据线是必备的。锂聚合物电池推荐使用Adafruit推荐的500mAh或更高容量的电池。电池容量决定了设备在两次充电间能工作的时长。根据代码中设置的睡眠时间例如每小时唤醒一次一块500mAh的电池理论上可以持续工作数周甚至数月。电池的接口通常是JST-PH 2-pin与MagTag上的插座匹配。可选配件外壳与支架Adafruit官方提供了亚克力面板和硬件套件能让你的MagTag立起来更像一个精致的桌面摆件。磁吸脚垫如果你想把它吸附在冰箱、白板等金属表面磁吸脚垫会非常方便。这些配件并非必需但它们能极大提升项目的完成度和美观性。我的建议是至少把电池配上体验一下它完全无线工作的魅力。3. 软件环境搭建与CircuitPython固件烧录硬件准备就绪后我们要为它注入“灵魂”——CircuitPython固件。这个过程相当于给一块空白的单片机安装操作系统。3.1 理解CircuitPython与MicroPythonCircuitPython是Adafruit基于MicroPython开发的一个分支它最大的特点是极致的易用性。在CircuitPython中你的代码文件code.py和库文件都存放在一个名为CIRCUITPY的U盘里。你只需要用电脑像操作普通文件一样编辑code.py板子就会自动运行最新的代码。这彻底改变了传统嵌入式开发中“编译-烧录-调试”的循环特别适合快速原型开发和教育。3.2 固件烧录的三种方法根据你的MagTag版本和电脑环境有三种方法可以安装CircuitPython。我强烈推荐第一种方法它是最简单的。方法一UF2引导程序拖放安装推荐这种方法适用于绝大多数新版MagTag。操作如同拷贝文件一样简单前往CircuitPython官网找到MagTag的页面下载最新的.UF2文件。用USB线连接MagTag和电脑。快速双击MagTag上的Reset按钮位于USB-C口旁边。如果成功电脑上会出现一个名为MAGTAGBOOT的U盘。将下载好的.UF2文件直接拖入MAGTAGBOOT盘符。完成后设备会自动重启此时会出现一个名为CIRCUITPY的新盘符。恭喜固件安装成功注意事项在Windows系统上拖放完成后可能会弹出“设备不存在”的错误。这通常是正常的因为引导程序在完成写入后会立即断开连接。只要CIRCUITPY盘符出现了就说明安装成功。如果这个错误让你困扰可以尝试更新板子的TinyUF2引导程序到最新版。方法二使用esptool通过串行引导程序安装如果你的MagTag是早期白色版本可能无法进入UF2模式。这时需要使用更底层的工具esptool。在电脑上安装Python和esptool(pip install esptool)。下载CircuitPython的.bin文件。让MagTag进入“下载模式”按住板上的“BOOT”按钮如果有或特定组合键再按一下“Reset”然后释放。使用esptool.py命令行工具指定正确的串口和.bin文件路径进行烧录。命令类似esptool.py --chip esp32s2 --port COM3 write_flash 0x1000 firmware.bin。烧录完成后按Reset键CIRCUITPY盘符应出现。方法三使用Chrome浏览器的Web Serial ESPTool这是为不熟悉命令行或Python环境的用户准备的“救星”方案。你只需要一个Chrome或Edge浏览器。打开 Web Serial ESPTool 页面。点击“Connect”并选择你的MagTag对应的串口。点击“Erase”擦除原有固件。点击“Program”并选择你下载的.bin或.uf2文件进行烧录。 这个工具的本质是一个运行在浏览器里的esptool避免了本地环境配置的麻烦。无论采用哪种方法最终目标都是让电脑上出现CIRCUITPY这个可移动磁盘。这是你后续所有操作的“工作区”。4. 网络配置与首次连接测试让设备“上网”是物联网项目的第一步。CircuitPython通过一个名为settings.toml的配置文件来管理Wi-Fi密码等敏感信息这是一个非常巧妙和安全的设计。4.1 安全配置Wi-Fisettings.toml文件详解在CIRCUITPY盘符的根目录下你会找到一个可能是空的settings.toml文件。用任何文本编辑器如VS Code、Notepad打开它。这个文件的作用是存储所有需要保密的配置信息比如Wi-Fi密码、API密钥等。这样做的好处是当你分享code.py主程序时不会不小心把密码也泄露出去。对于我们的项目最基本的配置如下CIRCUITPY_WIFI_SSID 你的Wi-Fi网络名称 CIRCUITPY_WIFI_PASSWORD 你的Wi-Fi密码请务必将双引号内的内容替换成你实际的网络信息。非常重要保存这个文件后永远不要把它上传到GitHub或其他公开代码仓库。4.2 编写并运行网络测试代码在确认settings.toml配置正确后我们需要一个简单的程序来测试网络是否连通。将下面的代码保存为CIRCUITPY盘根目录下的code.py文件。CircuitPython会自动运行这个文件。# SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries # SPDX-License-Identifier: MIT import os import wifi import socketpool import adafruit_requests import ssl import ipaddress # 测试用的URL TEXT_URL http://wifitest.adafruit.com/testwifi/index.html JSON_URL https://api.github.com/repos/adafruit/circuitpython print(MagTag 网络连接测试) print(fMAC地址: {[hex(i) for i in wifi.radio.mac_address]}) # 扫描并列出附近的Wi-Fi网络可选用于诊断 print(可用的Wi-Fi网络:) for network in wifi.radio.start_scanning_networks(): print(f\t{str(network.ssid, utf-8)}\t信号强度: {network.rssi} dBm) wifi.radio.stop_scanning_networks() # 从settings.toml读取配置并连接 ssid os.getenv(CIRCUITPY_WIFI_SSID) password os.getenv(CIRCUITPY_WIFI_PASSWORD) print(f正在连接到: {ssid}) wifi.radio.connect(ssid, password) print(f已连接到: {ssid}) print(f获取到的IP地址: {wifi.radio.ipv4_address}) # 测试网络连通性ping一个DNS服务器 ping_ip ipaddress.IPv4Address(8.8.8.8) # Google DNS ping_time wifi.radio.ping(ipping_ip) if ping_time is None: ping_time wifi.radio.ping(ipping_ip) # 再试一次 if ping_time is not None: print(fPing 8.8.8.8 耗时: {ping_time * 1000:.0f} ms) else: print(Ping 测试失败但可能仍可连接。) # 创建网络会话 pool socketpool.SocketPool(wifi.radio) requests adafruit_requests.Session(pool, ssl.create_default_context()) # 测试获取网页文本 print(f\n从 {TEXT_URL} 获取文本...) response requests.get(TEXT_URL) print(- * 40) print(response.text) print(- * 40) # 测试获取并解析JSON数据 print(f\n从 {JSON_URL} 获取JSON数据...) response requests.get(JSON_URL) data response.json() print(- * 40) print(fCircuitPython GitHub 星标数: {data[stargazers_count]}) print(- * 40) print(\n网络测试完成)将代码保存后MagTag会自动重启并运行。要查看打印信息你需要一个串口监视器。推荐使用Mu EditorCircuitPython官网推荐或者Thonny或者任何能打开串口的工具如VS Code的Serial Monitor扩展、PuTTY等。连接端口后你应该能看到类似以下的输出MagTag 网络连接测试 MAC地址: [0xde, 0xad, 0xbe, 0xef, 0x00, 0x01] 可用的Wi-Fi网络: MyHomeWiFi 信号强度: -45 dBm ... 正在连接到: MyHomeWiFi 已连接到: MyHomeWiFi 获取到的IP地址: 192.168.1.123 Ping 8.8.8.8 耗时: 23 ms ... CircuitPython GitHub 星标数: 15000 网络测试完成如果看到了IP地址和成功的网络请求恭喜你最关键的联网步骤已经打通了如果失败请按以下步骤排查检查settings.toml中的SSID和密码是否正确大小写和特殊字符尤其要注意。检查USB线是否是数据线。检查Wi-Fi是否是2.4GHz网络ESP32-S2不支持5GHz。在串口监视器中查看具体的错误信息。5. 项目文件部署与代码结构剖析网络测试通过后我们就可以开始部署真正的韦伯望远镜状态监控项目了。这个项目不仅仅是一个code.py文件它还需要特定的字体文件和库支持。5.1 获取并部署项目文件包最可靠的方式是从Adafruit学习系统的项目页面原资料中的链接下载完整的“项目文件包”Project Bundle。这个ZIP包通常包含code.py主程序文件。lib/文件夹包含所有必需的CircuitPython库文件如adafruit_requests,adafruit_display_text等。fonts/文件夹包含用于显示的定制字体文件例如LeagueSpartan-Light.bdf。部署步骤下载ZIP包并解压。将解压后得到的code.py文件、整个lib文件夹和fonts文件夹复制到你的CIRCUITPY盘根目录。如果CIRCUITPY盘上已有旧的code.py或lib文件夹请覆盖它们。完成后你的CIRCUITPY盘的文件结构应该大致如下CIRCUITPY/ ├── code.py ├── settings.toml ├── lib/ │ ├── adafruit_requests.mpy │ ├── adafruit_display_text/ │ └── ... (其他依赖库) └── fonts/ └── LeagueSpartan-Light.bdf5.2 核心代码逻辑深度解读现在让我们打开code.py像读一篇技术小说一样逐段理解作者的构思。代码虽长但结构清晰。5.2.1 初始化与配置代码开头导入必要的库并从settings.toml读取Wi-Fi配置。这里有一个关键设计如果找不到配置程序会直接抛出错误防止无意义的运行。ssid getenv(CIRCUITPY_WIFI_SSID) password getenv(CIRCUITPY_WIFI_PASSWORD) if None in [ssid, password]: raise RuntimeError(请将Wi-Fi配置置于settings.toml文件中...)接下来定义了更新间隔SLEEP_TIME默认为1小时和数据源URL。这里有一个至关重要的点原项目依赖的第三方API服务器可能已失效。代码中预留了TEST_RUN True的开关和FAKE_DATA模拟数据就是为了在开发时即使没有网络也能测试显示效果。在实际部署前你需要将TEST_RUN改为False并确保数据URL有效。根据资料提示可能需要寻找新的NASA官方JSON数据源或自行搭建解析服务器。5.2.2 显示系统的构建Group与Label这是图形界面的核心。CircuitPython的displayio库采用“显示组Group”和“标签Label”的层级结构。# 创建主显示组所有元素都放在这里面 main_group displayio.Group() # 加载自定义字体提升显示美观度 font bitmap_font.load_font(fonts/LeagueSpartan-Light.bdf)然后代码创建了多个Label对象来显示不同的数据块top_left_value: 显示望远镜“热侧”和“冷侧”的温度摄氏度。top_right_value: 显示五个核心科学仪器的温度开尔文。timestamp_val: 显示数据获取的时间戳。middle_left_name和top_center_name: 作为上述数据值的标题标签。每个Label都通过anchor_point锚点如(0,0)代表左上角和anchored_position基于锚点的绝对坐标进行精确定位。这种定位方式比直接设置x, y坐标更灵活特别是在元素大小动态变化时。5.2.3 数据获取与错误处理在if not TEST_RUN:的代码块中程序执行真正的网络操作连接Wi-Fi使用配置的SSID和密码。创建网络会话adafruit_requests.Session用于管理HTTP请求。发起GET请求向指定的NASA JSON数据URL发起请求并设置超时timeout30秒。错误处理如果连接或请求失败程序会打印错误并调用supervisor.reload()在3秒后重启。这是一个非常实用的设计因为物联网设备在无人值守时网络波动是常事自动重启是最简单的恢复手段。解析JSON成功获取响应后使用.json()方法解析数据并从中提取我们需要的温度字段。5.2.4 数据填充与屏幕刷新解析出数据后将其填充到之前创建好的Label对象的.text属性中。例如top_right_value.text {}K\n{}K\n{}K\n{}K\n{}K.format( json_data[currentState][tempInstNirCamK], json_data[currentState][tempInstNirSpecK], ...)所有数据填充完毕后通过display.root_group main_group将主显示组设置为当前显示内容。最后调用一个自定义的try_refresh()函数来更新电子墨水屏。5.2.5 深度睡眠与定时唤醒低功耗的秘诀这是本项目实现超长续航的关键。代码没有使用常见的while True循环而是在执行完一次所有任务后安排一个“闹钟”然后进入深度睡眠。# 创建一个在‘SLEEP_TIME’秒后触发的闹钟 time_alarm alarm.time.TimeAlarm(monotonic_timetime.monotonic() SLEEP_TIME) # 退出并深度睡眠直到闹钟唤醒 alarm.exit_and_deep_sleep_until_alarms(time_alarm)time.monotonic()返回一个从开机起持续递增的时间秒不受系统时间更改影响。SLEEP_TIME是之前定义的间隔如3600秒。执行alarm.exit_and_deep_sleep_until_alarms()后ESP32-S2的绝大部分电路会被关闭仅保留维持RTC实时时钟和唤醒逻辑的极微小电流功耗可以低至几十微安。当设定的时间到达硬件会自动将芯片唤醒并从程序开头重新执行code.py。这种“执行-睡眠-唤醒”的范式是电池供电物联网设备的黄金标准。5.2.6 针对E-Ink的“小心机”try_refresh函数电子墨水屏有一个物理限制两次完整刷新之间需要一定的时间间隔通常是几秒。如果代码试图过快刷新会抛出RuntimeError。原代码中的try_refresh()函数优雅地处理了这个问题def try_refresh(): try: board.DISPLAY.refresh() except RuntimeError as too_soon_error: print(too_soon_error) print(刷新过快等待10秒后重试...) time.sleep(10) board.DISPLAY.refresh()它尝试刷新如果捕获到“刷新太快”的异常就等待10秒再试一次。这种防御性编程在硬件交互中非常重要。6. 高级定制、问题排查与优化建议当你的设备成功运行起来后你可能不满足于仅仅复现。这里有一些进阶玩法和常见问题的解决方案。6.1 项目定制化改造思路更换数据源这是最大的挑战也是最大的乐趣。原API失效后你可以寻找替代API搜索是否有其他天文机构或爱好者提供了JWST状态的JSON接口。自行搭建解析服务器使用PythonFlask/Django、Node.js等写一个简单的服务定期抓取NASA官方状态页HTML解析出需要的数据然后提供干净的JSON API给你的MagTag。这需要你有一台能运行Python的服务器甚至可以是树莓派。修改为其他数据源这个项目的框架是通用的。你可以轻松地将数据源URL换成任何返回JSON的公开API比如天气预报、股票价格、加密货币行情、待办事项列表等打造属于你自己的信息牌。调整显示布局与样式修改坐标调整anchored_position的参数可以改变文字的位置。更换字体你可以使用任何.bdf格式的位图字体。在网上找到喜欢的字体用工具转换成.bdf格式放入fonts/文件夹并在代码中修改load_font的路径即可。改变颜色MagTag是灰度屏颜色用十六进制表示如0x000000黑、0xFFFFFF白、0x888888灰。调整background_color和color参数可以改变标签的背景色和文字颜色。调整更新频率修改SLEEP_TIME变量。60 * 60是一小时60 * 60 * 24是一天。更短的间隔意味着更耗电你需要权衡信息的及时性和电池续航。增加交互功能利用板载的四个按钮A, B, C, D。你可以在代码开头检查supervisor.runtime.safe_mode_reason或通过alarm.wake_alarm来判断是定时唤醒还是按钮唤醒从而实现“手动刷新”或“切换显示页面”的功能。6.2 常见问题与故障排除速查表问题现象可能原因排查步骤与解决方案电脑无法识别CIRCUITPY或MAGTAGBOOT盘符1. USB线是充电线。2. 驱动问题。3. 板子未正确进入引导模式。1.更换为可靠的数据线。2. 尝试另一台电脑或USB口。3. 确保双击Reset按钮的节奏正确快速按两下。4. 对于Windows尝试在设备管理器中查看端口。串口监视器无输出或输出乱码1. 串口波特率设置错误。2. 选错了串口。3. 代码有语法错误未运行。1. CircuitPython REPL的默认波特率是115200确保监视器设置一致。2. 在设备管理器Windows或ls /dev/tty.*Mac/Linux中确认正确的端口号。3. 检查code.py是否有语法错误查看是否有错误信息输出。网络连接失败1.settings.toml配置错误。2. Wi-Fi是5GHz。3. 网络需要网页认证如酒店、机场。4. 信号太弱。1. 仔细核对settings.toml的SSID和密码确保引号是英文的。2. 连接到2.4GHz网络。3. ESP32-S2不支持需要网页跳转认证的网络。4. 查看串口输出的RSSI信号强度-70 dBm以下较好。能连接Wi-Fi但无法获取数据1. 数据源URL失效或无法访问。2. 服务器证书问题HTTPS。3. 网络防火墙或DNS问题。1.这是原项目最常见问题。将TEST_RUN设为True测试显示功能是否正常。然后寻找可用的新数据源URL。2. 尝试在requests.get()中增加sslFalse参数不推荐仅用于测试。3. 尝试ping一个公网IP如8.8.8.8测试基础网络连通性。屏幕刷新异常或显示乱码1. 刷新间隔太短。2. 字体文件缺失或损坏。3. 内存不足。1. 确保使用了try_refresh()函数。2. 检查fonts/文件夹是否存在字体文件名是否与代码中调用的一致。3. 简化显示内容或使用更小的字体。使用import gc; gc.collect()手动回收内存。电池耗电极快1. 未进入深度睡眠。2. 睡眠时间设置太短。3. 电池本身老化或质量差。1. 检查代码最后是否执行了alarm.exit_and_deep_sleep_until_alarms()。2. 增加SLEEP_TIME。3. 测量深度睡眠时的电流应低于100µA。如果过高可能是硬件问题。设备无法从深度睡眠中唤醒1. 闹钟时间设置错误。2. 硬件故障。1. 检查SLEEP_TIME计算是否正确time.monotonic()返回的是秒。2. 尝试不使用睡眠让代码循环运行看是否正常。6.3 功耗优化与续航估算对于这类显示设备功耗主要来自三部分Wi-Fi连接/数据传输、屏幕刷新和待机睡眠。Wi-Fi活动期ESP32-S2在全力工作射频开启时电流可达100mA以上。一次网络连接和数据获取可能持续2-5秒。屏幕刷新期电子墨水屏刷新全屏时电流峰值也可能达到几十mA持续1-2秒。深度睡眠期这是绝大部分时间所处的状态。ESP32-S2在深度睡眠下电流可以低至20µA左右。做一个简单的续航估算 假设使用一块500mAh的电池。每小时唤醒一次每次活跃Wi-Fi刷新耗时5秒消耗电流平均100mA。每次活跃消耗的电量100mA * (5/3600)h ≈ 0.139 mAh。每小时睡眠59分55秒消耗电流20µA (0.02mA)。每小时睡眠消耗的电量0.02mA * (3595/3600)h ≈ 0.020 mAh。每小时总耗电约0.159 mAh。理论续航500 mAh / 0.159 mAh/h ≈ 3145小时 ≈ 131天。这只是一个理想估算实际会因网络信号强度重试会增加功耗、环境温度、电池自放电等因素缩短。但即便如此持续工作数月是完全可能的。如果将更新频率改为每天一次续航时间将以年计。7. 从项目实践中提炼的嵌入式开发思维完成这个项目后你收获的不仅仅是一个酷炫的桌面摆件更是一套适用于众多低功耗物联网IoT场景的开发模式。我们可以把这个项目的架构抽象成一个通用模板其核心流程是初始化 - 联网 - 获取数据 - 处理/显示数据 - 进入低功耗睡眠 - 定时/事件唤醒 - 重复。这个模式可以迁移到无数场景中环境监测站连接温湿度、空气质量传感器每小时上报一次数据到云端并在本地小屏显示。邮箱/快递通知器通过查询API在有新邮件或快递更新时点亮一个LED或更新屏幕提示。简易信息看板抓取新闻头条、TODO列表、倒计时等信息进行轮播显示。在开发这类项目时有几点思维至关重要状态无记忆设计由于每次唤醒都相当于重启你的代码必须假设这是“第一次运行”。所有需要持久化的配置如Wi-Fi密码应放在settings.toml或单独的配置文件里而非代码变量中。防御性编程网络是不稳定的外设可能出错。代码中必须包含充分的错误处理try...except和恢复机制如重启supervisor.reload()。原项目中处理网络失败和屏幕刷新过快的方式就是典范。功耗意识任何不必要的延迟(time.sleep)、常亮的LED、未关闭的外设都在消耗宝贵的电池电量。设计时要时刻思考“这个操作是否必要能否在睡眠前关闭”离线能力考虑网络完全不可用的情况。是否可以显示上次成功获取的数据是否可以给出一个友好的错误提示而不是白屏或乱码原项目的TEST_RUN和FAKE_DATA就是一种离线兜底策略。最后关于这个韦伯望远镜项目本身我最大的体会是开源硬件和生态的魅力在于连接。它连接了遥远的星空与你的桌面连接了复杂的航天工程与个人可及的编程乐趣也连接了全球开发者分享的代码与灵感。当屏幕上那些代表着零下两百多度的数字真实地更新时你能真切地感受到自己通过几行代码参与到了人类最前沿的宇宙探索之中。这种跨越空间的连接感正是创客项目最迷人的地方。希望这个详细的指南能帮你顺利搭建起这座连接你与星辰的小小桥梁。如果在制作过程中遇到任何新的问题不妨回到代码和原理本身耐心分析串口输出那里面通常藏着所有问题的答案。