CircuitPython嵌入式图片幻灯片:从BMP处理到交互控制的完整实践
1. 项目概述:在微控制器上玩转图片幻灯片
如果你手头有一块像Adafruit PyPortal、PyGamer这样的开发板,除了跑跑例程、点个灯,有没有想过让它变成一个精致的数字相框,或者一个酷炫的展示终端?今天要聊的,就是如何用CircuitPython,在资源有限的微控制器上,轻松实现一个图片幻灯片播放器。这听起来可能有点“大材小用”,但恰恰是这种将复杂功能简单化的实践,最能体现嵌入式开发的魅力——用最少的资源,实现直观、有趣的应用。
CircuitPython作为MicroPython的“亲民版”,其核心价值就是让嵌入式开发变得像在电脑上写Python脚本一样简单。你不需要复杂的交叉编译环境,只需把代码文件拖拽到设备上名为CIRCUITPY的U盘里,它就能运行。而adafruit_slideshow这个库,则把图片解码、显示切换、定时控制这些底层脏活累活都封装好了,暴露给开发者的就是一个简洁易懂的接口。这意味着,即使你刚接触硬件,只要会几句Python,也能在半小时内让屏幕动起来,展示你的摄影作品、项目截图或者表情包合集。
这个项目非常适合那些想给硬件项目增加可视化展示功能的开发者、教育工作者,或是任何想用硬件创造一点小乐趣的爱好者。它不涉及复杂的电路焊接,核心是软件配置和资源管理。接下来,我会带你从零开始,拆解每一个步骤,并分享我在实践中积累的、官方文档里可能不会细说的那些“坑”和技巧。
2. 核心思路与硬件选型解析
2.1 为什么选择CircuitPython和adafruit_slideshow?
在嵌入式领域,我们通常用C/C++进行开发,追求极致的性能和内存控制。但对于快速原型开发、教育或艺术创作,这种开发方式的门槛较高。CircuitPython的出现改变了这一点。它本质上是一个在微控制器上运行的Python 3解释器,提供了硬件底层(GPIO、I2C、SPI、显示器等)的简单抽象。你写的code.py文件会被自动执行,修改后保存即可生效,这种“保存即运行”的体验极大地提升了迭代速度。
adafruit_slideshow库是这个生态中的一颗明珠。它专为在内存和处理器性能都受限的环境下显示图片序列而优化。其核心原理是:在初始化时,它并不会一次性将所有图片加载到宝贵的内存(RAM)中,而是维护一个文件列表。当需要显示下一张图片时,它才从存储(通常是板载的Flash或SD卡,映射为CIRCUITPY驱动器)中读取对应的BMP文件,解码并渲染到帧缓冲区,最后输出到屏幕。这种“按需加载”的策略,是能在只有几百KB内存的设备上流畅播放图片的关键。
注意:这里有一个非常重要的限制。由于微控制器有限的处理能力,
adafruit_slideshow库(以及CircuitPython的显示系统)通常只支持未经压缩的BMP格式图片。JPEG、PNG等格式需要复杂的解压缩算法,会消耗大量内存和计算时间,在大多数低端微控制器上难以实时处理。因此,图片预处理是项目成功的前提。
2.2 硬件平台选择与考量
原文档提到了几款Adafruit的板卡,它们都是绝佳的选择,但各有侧重:
- Adafruit PyPortal:这是本项目的“顶配”选择。它集成了320x240分辨率的彩色触摸屏、Wi-Fi模块、音频解码器,并且内置了足够的Flash存储(通常8MB以上)。它的处理器性能也更强,处理图片切换更从容。如果你想要一个功能丰富的网络相框,PyPortal是首选。
- Adafruit PyGamer / PyBadge:这两款板子更偏向于手持游戏设备,屏幕为160x128。它们体积小巧,带有方向键和按钮,这意味着你不仅可以做幻灯片,还可以轻松扩展功能,比如用按键控制幻灯片切换速度、暂停/播放。对于需要交互的展示场景,它们非常合适。
- Hallowing M0/M4 Express / Monster M4sk:这些板子通常带有方形或圆形屏幕(128x128或240x240),设计上更具个性,常用于可穿戴设备或艺术装置。用它们来做幻灯片,成品会显得非常酷炫。
选型核心建议:
- 看屏幕:首先确定你需要的屏幕尺寸和形状。320x240能展示更多细节,160x128则更省电、刷新更快。
- 看内存:运行CircuitPython和图形库需要一定的RAM(运行内存)。PyPortal(ATSAMD51)通常有192KB+的RAM,而基于SAMD21的板子(如一些M0 Express)可能只有32KB RAM。对于幻灯片应用,建议选择RAM不少于64KB的板子,以确保有足够空间处理图像帧缓冲区。
- 看存储:图片文件会占用大量空间。板载的Flash(即
CIRCUITPY驱动器)容量从2MB到8MB不等。你需要估算你的图片总大小。一张320x240的24位色BMP图片,体积约为320 * 240 * 3 bytes ≈ 225KB。即使只有10张,也需要约2.2MB空间。如果图片较多,强烈建议为板子配备一个SD卡扩展板,并将图片放在SD卡上。
3. 环境搭建与软件部署详解
3.1 CircuitPython固件刷写实战
拿到一块新板子,第一步是让它运行CircuitPython。这个过程通常被称为“刷固件”,但在CircuitPython世界里,它简单得像复制文件。
操作步骤与原理剖析:
- 下载固件:访问 circuitpython.org/downloads ,根据你的板子型号(例如“Adafruit PyPortal”)找到对应的
.uf2文件。.uf2是UF2格式的固件文件,这是一种由微软设计的、专用于USB大容量存储设备刷机的格式,其特点是无需专用刷写工具,直接拖拽即可。 - 进入引导加载模式:
- 用一条可靠的数据USB线连接板和电脑。很多手机充电线只有电源线,没有数据线,务必确认。
- 大部分Adafruit板子通过快速双击复位(Reset)按钮进入引导模式。此时,板载的RGB NeoPixel LED通常会变成绿色(如果变红,通常意味着USB连接有问题)。同时,电脑上会出现一个名为
XXXBOOT(如PYPORTALBOOT)的U盘。 - 实操心得:双击复位键需要一点节奏感,不是越快越好。如果一次没成功,多试几次。有时需要先单机一下,看到LED闪烁后再快速双击。这是硬件交互的第一个小门槛,耐心点。
- 拖拽刷写:将下载好的
.uf2文件直接拖入XXXBOOT盘符。拖入后,BOOT盘符会消失,稍等片刻,会出现一个新的名为CIRCUITPY的盘符。这个过程就是板子的引导加载程序(bootloader)将UF2文件写入内部Flash,并启动其中的CircuitPython固件。 - 验证:打开
CIRCUITPY盘,你会看到一个boot_out.txt文件。用记事本打开它,里面会显示当前运行的CircuitPython版本号。如果看到这个,恭喜你,环境就绪。
3.2 库文件与项目代码部署
CircuitPython的库管理非常直观。库文件就是预编译的.mpy文件或Python源码.py文件,需要放在CIRCUITPY盘下的lib文件夹内。
获取库文件包:再次访问 circuitpython.org/libraries ,下载与你的CircuitPython主版本号匹配的“库文件包”(Library Bundle)。这是一个ZIP压缩包。
提取所需库:解压这个ZIP包,里面按库名分好了文件夹。对于本项目,你只需要一个文件:在
lib文件夹里找到adafruit_slideshow.mpy。部署到设备:
- 在
CIRCUITPY根目录下,新建一个名为lib的文件夹(如果不存在)。 - 将
adafruit_slideshow.mpy文件复制到CIRCUITPY/lib/目录下。 - 重要提示:
lib文件夹的名字必须是全小写。CircuitPython在导入模块时对路径大小写敏感,这是Unix/Linux系统的惯例。
- 在
编写主程序:
- 在
CIRCUITPY根目录下,用任何文本编辑器(推荐VS Code、Thonny或记事本)创建一个新文件,命名为code.py。这是CircuitPython设备启动后自动执行的主程序文件。 - 将以下代码复制进去:
# SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries # # SPDX-License-Identifier: MIT import board from adafruit_slideshow import PlayBackOrder, SlideShow # 创建幻灯片对象 slideshow = SlideShow( board.DISPLAY, # 使用板载默认显示器 folder="/images", # 图片存放目录 loop=True, # 循环播放 order=PlayBackOrder.ALPHABETICAL, # 按文件名字母顺序播放 dwell=5 # 每张图片显示5秒 ) while slideshow.update(): pass - 保存文件。保存后,CircuitPython解释器会检测到
code.py文件变化并自动重启运行。此时如果你的/images目录下还没有图片,可能会报错或显示黑屏,这是正常的。
- 在
部署阶段常见问题排查:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
提示ModuleNotFoundError: No module named 'adafruit_slideshow' | 1.lib文件夹未创建或名称不正确。2. adafruit_slideshow.mpy文件未放入lib文件夹,或放错了位置。3. 库文件版本与CircuitPython固件版本不兼容。 | 1. 检查CIRCUITPY根目录下是否存在小写lib文件夹。2. 确认 .mpy文件在CIRCUITPY/lib/内,而不是lib的子文件夹里。3. 重新下载匹配版本的库文件包。 |
提示AttributeError: 'module' object has no attribute 'DISPLAY' | 你使用的板子没有预定义board.DISPLAY,或者你使用了自定义接线屏幕。 | 对于PyPortal、PyGamer等官方板,这不应该发生。如果使用自定义屏幕,你需要先初始化显示总线(如displayio库),然后将显示对象传给SlideShow。 |
保存code.py后设备不断重启 | 代码中存在语法错误或运行时错误,导致程序崩溃,CircuitPython自动重启后再次运行错误代码,陷入循环。 | 连接串口终端(如Thonny、Mu编辑器或screen/putty),查看重启时输出的错误信息。通常错误信息会明确指出问题行。 |
4. 图片素材的准备与处理核心
这是项目成败的关键一步,也是最容易出问题的地方。微控制器不是电脑,无法实时处理任意尺寸和格式的图片。
4.1 格式与尺寸的硬性要求
- 格式:必须为BMP(位图)格式。并且需要是24位RGB或8位索引色的非压缩BMP。在保存时,图像处理软件里可能会有“Windows位图”、“BMP”等选项,务必不要选择“RLE压缩”或“高级格式”。
- 尺寸:图片的像素尺寸必须严格匹配或小于你设备屏幕的分辨率。
adafruit_slideshow库不会缩放图片。如果你放入一张大于屏幕的图片,它只会显示图片左上角与屏幕大小匹配的那一部分。这通常不是你想要的效果。
主流板子的屏幕分辨率如下表所示,请务必以此为准处理图片:
| 设备型号 | 屏幕分辨率(宽x高) | 屏幕方向 | 备注 |
|---|---|---|---|
| PyPortal | 320 x 240 | 横向 | 最常用的展示尺寸 |
| PyGamer, PyBadge (LC) | 160 x 128 | 横向 | 手持设备经典尺寸 |
| Hallowing M0 Express | 128 x 128 | 纵向 | 方形屏,注意方向 |
| Monster M4sk, HalloWing M4 | 240 x 240 | 方形 | 方形屏 |
| CLUE, PyRuler | 240 x 240 | 方形 | 其他方形屏设备 |
4.2 使用GIMP进行批量处理(实战技巧)
虽然Photoshop等软件也能处理,但GIMP免费、开源且跨平台,是首选。这里分享一个高效的批量处理流程。
安装GIMP:从官网下载并安装。
准备原始图片:将所有想展示的图片放在一个文件夹里。
使用批处理插件:GIMP本身功能强大,但原生批处理稍显复杂。我们可以利用其“导出”功能和简单的脚本思路,或者使用“BIMP”这类批处理插件。这里介绍一个手动与自动结合的高效方法:
- 第一步:统一裁剪/缩放。打开一张图片,点击菜单
图像->画布大小或图像->缩放图像。将单位设为“像素”,输入目标宽度和高度(如320和240)。注意:缩放图像会改变图片内容比例,可能变形;画布大小是添加或裁剪画布。通常我们先缩放图像到目标尺寸(保持长宽比),然后再用画布大小将画布精确调整到目标分辨率,多出的部分用背景色填充(对于横向图片,上下可能会有黑边或白边)。 - 第二步:记录动作。完成一张图片的调整后,先不着急处理下一张。我们可以思考如何将这个过程自动化。虽然GIMP没有直接的“动作”记录,但我们可以用“导出”来简化。
- 第三步:批量导出。更实用的方法是,先用手动方式处理好一张作为模板,记住所有步骤。然后,对于大量图片,可以使用GIMP的“文件”->“打开为图层”功能,一次性打开多张图片。然后对每一个图层(即每一张图片)执行相同的缩放/裁剪操作。最后,使用“文件”->“导出为”->选择BMP格式,GIMP可以让你选择导出所有图层为单独的文件,并自动命名。这是最接近批处理的方法。
- 一个更程序员友好的方法:如果你熟悉命令行,强烈推荐使用ImageMagick工具。一行命令即可完成批量缩放和格式转换,极其高效。例如,将当前目录所有JPG转换为320x240的BMP,并保持宽高比,不足处用黑色填充:
这条命令会读取所有magick mogrify -path ./output -format bmp -resize 320x240^ -gravity center -extent 320x240 -background black *.jpg.jpg文件,缩放到至少320或240(^符号),然后通过-extent和-gravity将图片扩展到精确的320x240,并用黑色填充多余部分,最后输出到./output文件夹为BMP格式。
- 第一步:统一裁剪/缩放。打开一张图片,点击菜单
命名与排序:将处理好的BMP文件按你想要的播放顺序命名。
adafruit_slideshow默认按文件名字母顺序播放。一个推荐的做法是使用数字前缀,如01_sunset.bmp,02_mountain.bmp,03_city.bmp。这样在文件管理器中也能直观排序。
4.3 将图片传输到设备
- 在
CIRCUITPY根目录下,创建一个名为images的文件夹(全小写)。 - 将你处理好的、尺寸正确的BMP图片全部复制到
CIRCUITPY/images/目录下。 - 安全弹出设备(或直接拔线,CircuitPython设备对此相对宽容),然后重新上电。此时,你的幻灯片应该开始自动播放了!
重要经验:图片文件的总大小,加上CircuitPython系统、库文件和代码,不能超过
CIRCUITPY驱动器的可用容量。你可以通过查看驱动器属性来确认剩余空间。如果图片太多,考虑使用SD卡。这时,你需要修改代码中的folder参数,例如folder="/sd/images",并确保已正确初始化和挂载SD卡(通常需要额外的库和初始化代码)。
5. 代码深度定制与高级玩法
基础的幻灯片跑起来后,我们来看看adafruit_slideshow库提供的丰富参数,如何让它更符合你的需求。
5.1 核心参数详解与配置
回顾一下创建SlideShow对象的代码:
slideshow = SlideShow( board.DISPLAY, folder="/images", loop=True, order=PlayBackOrder.ALPHABETICAL, dwell=5, fade_effect=True, auto_advance=True, direction=1 )让我们逐一拆解这些参数,并分享一些配置心得:
board.DISPLAY: 这是硬件抽象,指向板载的默认显示器。对于绝大多数Adafruit开发板,这行代码无需改动。folder: 指定图片目录。路径是相对于CIRCUITPY根目录的。如果你想用SD卡,且SD卡挂载在/sd,那么可以设为folder="/sd/slideshow_images"。loop(布尔值): 是否循环播放。True表示播完最后一张后回到第一张继续。False则只播放一轮就停止。对于数字相框,通常设为True。order(枚举): 播放顺序。有两个选项:PlayBackOrder.ALPHABETICAL: 按文件名字母顺序。这是最可控的顺序,通过文件名就能管理。PlayBackOrder.RANDOM: 随机播放。每次切换到下一张时随机选择,可能会有重复,直到所有图片都播放过。这能增加新鲜感。
dwell(整数): 每张图片显示的时长,单位是秒。默认是3秒。文档示例用了60秒,对于欣赏图片可能太长,5-10秒是比较舒适的间隔。你可以根据场景调整,比如展览展示可以设长些(30秒),动态展示可以设短些(2秒)。fade_effect(布尔值):这是一个提升观感的关键参数!当设为True时,在图片切换的瞬间,屏幕背光会有一个淡出淡入的过渡效果。这能有效避免生硬的“硬切”,让幻灯片切换显得非常平滑、专业。除非有特殊需求(比如追求极致的切换速度),否则强烈建议保持True。auto_advance(布尔值): 是否自动播放。如果设为False,则幻灯片不会自动切换,你需要通过外部事件(如按键)来调用slideshow.advance()或slideshow.reverse()手动控制上一张/下一张。这对于交互式展示非常有用。direction(整数): 播放方向。1为正向(默认),-1为反向。可以和手动控制结合使用。
5.2 实现交互控制:用按键操控幻灯片
让幻灯片响应物理按键,立刻就让项目变得生动起来。我们以PyGamer为例,它上面有方向键和A/B按钮。
import board import digitalio from adafruit_slideshow import PlayBackOrder, SlideShow, PlayBackDirection # 初始化按键 button_up = digitalio.DigitalInOut(board.BUTTON_UP) button_up.direction = digitalio.Direction.INPUT button_up.pull = digitalio.Pull.UP # 使用板上拉电阻,按键按下时为低电平 button_down = digitalio.DigitalInOut(board.BUTTON_DOWN) button_down.direction = digitalio.Direction.INPUT button_down.pull = digitalio.Pull.UP button_a = digitalio.DigitalInOut(board.BUTTON_A) button_a.direction = digitalio.Direction.INPUT button_a.pull = digitalio.Pull.UP # 创建幻灯片对象,关闭自动播放 slideshow = SlideShow( board.DISPLAY, folder="/images", loop=True, order=PlayBackOrder.ALPHABETICAL, dwell=60, # 自动播放间隔设长,实际由按键控制 auto_advance=False, # 关键:关闭自动播放 fade_effect=True ) last_up_state = button_up.value last_down_state = button_down.value last_a_state = button_a.value while True: # 更新幻灯片状态(处理淡入淡出等效果) slideshow.update() # 检测按键,实现消抖(简单延时法) current_up = button_up.value current_down = button_down.value current_a = button_a.value if not current_up and last_up_state: # 检测到下降沿(按下) slideshow.direction = PlayBackDirection.FORWARD slideshow.advance() # 下一张 while not button_up.value: # 等待按键释放,简单消抖 pass last_up_state = current_up if not current_down and last_down_state: slideshow.direction = PlayBackDirection.BACKWARD slideshow.advance() # 上一张(因为direction是BACKWARD) while not button_down.value: pass last_down_state = current_down if not current_a and last_a_state: # 按下A键切换播放顺序(顺序/随机) if slideshow.order == PlayBackOrder.ALPHABETICAL: slideshow.order = PlayBackOrder.RANDOM print("切换到随机播放") else: slideshow.order = PlayBackOrder.ALPHABETICAL print("切换到顺序播放") while not button_a.value: pass last_a_state = current_a这段代码实现了:
- 上键:播放下一张。
- 下键:播放上一张。
- A键:在“顺序播放”和“随机播放”模式间切换。
按键消抖的重要性:机械按键在按下和释放的瞬间会产生快速的电压抖动,程序可能会误判为多次按下。上面的代码使用了“等待按键释放”的简单消抖方法。对于更严谨的应用,可以使用时间戳记录按下时间,忽略短时间内的重复状态变化。
5.3 高级主题:动态内容与网络更新
如果你用的是PyPortal这类带有Wi-Fi功能的板子,那么幻灯片的想象力可以大大扩展。
思路一:从网络下载最新图片你可以编写代码,让PyPortal定期连接到一个指定的URL(比如你的个人服务器、云存储或公开的API),下载最新的图片到SD卡或内部存储的/images目录,然后刷新幻灯片列表。这需要用到adafruit_requests、ssl等网络库。注意,下载的图片格式可能需要转换,可以在服务器端预先处理好为BMP,或者在板子上进行简单的格式转换(如果资源允许)。
思路二:显示动态信息叠加层幻灯片不一定是纯粹的图片。你可以结合displayio库,在图片上层叠加显示文字信息,比如时间、天气、传感器读数等。这需要你创建一个displayio.Group,将slideshow对象(它本身是一个TileGrid)和文本标签(label)添加到同一个组中,然后显示这个组。这样就能实现“带字幕的幻灯片”。
import board import displayio from adafruit_display_text import label from adafruit_bitmap_font import bitmap_font from adafruit_slideshow import SlideShow # 创建显示组 main_group = displayio.Group() # 创建并添加幻灯片 slideshow = SlideShow(board.DISPLAY, folder="/images", auto_advance=True, dwell=10) main_group.append(slideshow) # 创建并添加文本标签 font = bitmap_font.load_font("/fonts/Helvetica-Bold-16.bdf") # 需要字体文件 text_area = label.Label(font, text="Hello!", color=0xFFFFFF) text_area.x = 10 text_area.y = 220 main_group.append(text_area) # 显示这个组 board.DISPLAY.show(main_group) # 主循环中,可以更新文本内容 while True: # slideshow.update() 现在由displayio自动处理 # 这里可以更新text_area.text,例如显示当前时间 # time_text = "Time: ..." # text_area.text = time_text pass这种方法的挑战在于图层管理和内存使用,但能创造出效果更丰富的展示。
6. 故障排除与性能优化实录
在实际操作中,你几乎一定会遇到一些问题。下面是我踩过的一些坑和解决方案。
6.1 常见错误与解决方法速查表
| 问题现象 | 可能原因 | 解决方案与深度分析 |
|---|---|---|
| 屏幕黑屏,无显示 | 1. 电源不足。 2. 背光未开启。 3. 代码未正确指向显示器。 4. 图片目录为空或不存在。 | 1. 确保使用足额电流的USB口或电源适配器,屏幕耗电较大。 2. 有些板子背光需要代码控制(如 board.DISPLAY.brightness = 1.0),但adafruit_slideshow通常会处理。可以检查库源码或尝试手动设置。3. 确认 board.DISPLAY适用于你的板子。对于非标准连接,需要手动初始化displayio。4. 检查 /images文件夹是否存在,且内部有.bmp文件。 |
提示OSError: [Errno 2] No such file/directory | 指定的folder路径错误,或该路径下没有.bmp文件。 | 仔细检查路径拼写,区分大小写。CircuitPython运行在类Unix系统上,路径是大小写敏感的。确保路径以/开头。 |
| 图片显示不全,只显示一角 | 图片尺寸大于屏幕分辨率。 | 严格按照屏幕分辨率预处理图片。这是最常见的问题之一。 |
| 图片颜色异常或花屏 | 1. BMP格式不兼容(如32位带Alpha通道,或压缩格式)。 2. 图片色深不匹配。 | 1. 确保保存为“24位位图(RGB)”或“8位位图”。在GIMP中导出时,取消所有“高级选项”和压缩。 2. 有些屏幕可能是16位色(RGB565),但库会处理转换。如果问题依旧,尝试用更简单的画图工具另存为BMP。 |
| 幻灯片播放卡顿,切换缓慢 | 1. 图片文件太大(尽管尺寸正确,但可能是24位色,体积大)。 2. 存储介质读取慢(如SD卡质量差)。 3. 板子处理器性能瓶颈。 | 1. 尝试将图片转换为8位索引色BMP,可以大幅减小文件体积和内存占用,加快加载速度。在GIMP中,选择“图像”->“模式”->“索引色”。 2. 使用Class 10或以上的高速SD卡,并确保格式化为FAT32。 3. 对于M0核心的板子,性能有限是正常的。可以尝试减少 dwell时间,让切换看起来更“有意为之”而非卡顿。或者升级到M4核心的板子(如PyPortal Titano)。 |
| 设备运行一段时间后崩溃或重启 | 内存泄漏或堆碎片化。在长时间运行且不断加载/释放图片资源的程序中可能出现。 | 1. 确保使用.mpy格式的库文件,它比.py文件更节省内存。2. 尽量减少在循环中创建新的对象(如字符串、列表)。 3. 如果问题频繁,可以考虑定期(如每播放100张图片)执行一次软重启( microcontroller.reset()),但这会影响体验。更根本的方法是优化代码和图片资源。 |
6.2 内存与存储优化技巧
在资源受限的设备上,优化就是生命线。
- 使用
.mpy库文件:始终使用从库包中获取的预编译.mpy文件,而不是.py源文件。.mpy是字节码,加载更快,占用内存更少。 - 优化图片:
- 尺寸是第一位:绝对不要超过屏幕分辨率。
- 降低色深:许多展示图片用256色(8位)足以表现。将24位色BMP转为8位色,文件大小能减少约三分之二。在GIMP中转换时,可以选择“生成最佳调色板”,质量损失很小。
- 裁剪无用区域:如果图片边缘有大片纯色区域,将其裁剪掉,然后用代码或预处理将其放到正确位置。但这需要修改显示逻辑,更复杂。
- 使用SD卡:如果图片库很大,务必使用SD卡。将
CIRCUITPY驱动器的空间留给代码和库。同时,高速SD卡(Class 10/UHS-I)的读取速度远高于板载Flash,能提升切换流畅度。 - 精简代码:移除不必要的
import,避免在全局作用域创建大型数据结构。在函数内部局部变量会在函数结束后被回收。
6.3 调试心得:串口输出是你的好朋友
当程序不按预期运行时,别猜,看输出。通过串口终端(如Thonny、Mu编辑器、PuTTY或screen /dev/ttyACM0 115200)连接你的CircuitPython设备。任何未捕获的异常和print()语句的输出都会在这里显示。
在代码关键位置添加print语句,例如:
print(f“正在加载图片列表从目录: {folder}“) print(f“找到 {len(file_list)} 张图片”) print(f“当前显示: {current_filename}“)这能帮你清晰地了解程序的执行流,快速定位是图片加载失败、路径错误还是逻辑问题。
最后,玩转硬件项目的乐趣在于动手和调试。从让第一张图片显示出来,到实现流畅的自动播放,再到加入酷炫的交互和网络功能,每一步的突破都会带来巨大的成就感。这个CircuitPython幻灯片项目是一个完美的起点,它简单到足以让新手入门,又开放到能让高手尽情发挥。希望这些详细的步骤和踩坑经验,能帮你少走弯路,更快地创造出属于你自己的精彩展示。
