基于CircuitPython的交互式灯塔模型:从电容触摸到NeoPixel灯光控制
1. 项目概述:当传统手工模型遇见现代微控制器
我一直对融合物理结构与数字交互的项目情有独钟。一个静态的模型固然精美,但如果能让它“活”起来,根据你的触摸发出声音、点亮灯光,那种亲手创造的互动感是完全不同的体验。这次,我决定挑战自己,制作一个基于CircuitPython的交互式灯塔模型。这不仅仅是一个手工模型,更是一个完整的嵌入式系统原型,它集成了电容触摸感应、可编程LED灯带、音频播放以及通过电位器进行的模拟输入控制。
这个项目的核心目标,是探索如何将我们熟悉的Arduino或MicroPython生态中的交互逻辑,以一种更易上手的方式——CircuitPython——来实现,并封装进一个具有观赏性的实体模型中。最终的作品,灯塔的主体由环保的硬纸板搭建而成,内部则“藏”着一颗由Adafruit Circuit Playground Bluefruit(CPB)开发板驱动的“智能心脏”。触摸模型背面伸出的鳄鱼夹,可以触发不同的环境音效(如海浪、船笛、海鸥鸣叫),同时灯塔的“灯室”和基座会亮起对应颜色的灯光;而旋转电位器旋钮,则可以实时调节每次灯光闪烁的持续时间,从短暂的0.01秒到长达3秒。整个过程,从结构设计、电路连接到代码编写,充满了工程与艺术结合的乐趣。
无论你是对嵌入式开发感兴趣的初学者,想寻找一个综合性的入门项目;还是手工爱好者,希望为自己的作品增添一些动态的科技元素;亦或是教育工作者,在寻找一个能同时涵盖物理计算、编程和设计思维的STEAM教学案例,这个项目都能为你提供一条清晰的路径。接下来,我将毫无保留地拆解从零到一的每一个步骤,分享我在制作过程中踩过的坑和总结出的技巧。
2. 核心思路与物料清单解析
在动手之前,理清整个项目的逻辑框架和准备好合适的材料至关重要。这个灯塔模型本质上是一个典型的嵌入式交互系统,其工作流可以概括为: “感知 -> 处理 -> 执行” 。
2.1 系统交互逻辑设计
-
输入感知层 :我们采用了三种输入方式。
- 电容触摸 :这是主要的交互入口。利用CPB板内置的电容触摸感应引脚(如A2, A3, A4),连接鳄鱼夹作为触摸电极。当人体(导体)触摸电极时,会改变引脚的电容值,从而被检测为“触摸”事件。我们用它来触发不同的场景(海浪、船笛、海鸥)。
- 电位器(模拟输入) :这是一个连续调节的输入设备。电位器本质上是一个可变电阻,通过旋转旋钮改变电阻值,CPB板的模拟输入引脚(A5)会读取到一个随之变化的电压值(0-3.3V,对应数字值0-65535)。我们将这个值映射到灯光持续时间上,实现无极调节。
- 电源开关 :虽然简单,但必不可少。通过电池盒的物理开关控制整个系统的供电。
-
核心处理层 :由CPB板上的微控制器(nRF52840)和CircuitPython固件承担。它的任务是:
- 循环检测触摸引脚和电位器引脚的状态。
- 当检测到特定触摸事件时,根据预设的映射关系,决定播放哪个音频文件,以及点亮什么颜色的LED。
- 读取电位器的值,并将其转换为灯光亮起的持续时间。
- 协调音频播放和灯光控制这两个并发的输出任务。
-
输出执行层 :
- 音频输出 :通过CPB板内置的DAC和音频放大器,驱动一个微型扬声器播放存储在板载存储中的WAV格式音频文件。
- 灯光输出 :通过数字引脚(NEOPIXEL和A1)控制两路可寻址RGB LED灯带(NeoPixel)。一路用于板载的10颗LED,另一路用于外接的30颗LED灯带,实现丰富的灯光效果。
2.2 物料清单与选型考量
一份清晰的物料清单是成功的一半。下面我不仅列出所需物品,还会解释为什么选择它,以及是否有替代方案。
结构部分(手工模型) :
- 硬纸板 :主体结构材料。选择较厚、平整的瓦楞纸板,承重和定型能力更好。快递盒是绝佳的免费来源。
- 白纸 :用于覆盖纸板,提供干净的绘画基底。普通的A4打印纸即可。
- 剪刀、美工刀、直尺 :基础切割工具。美工刀配合直尺切割直线更精准。
- 胶水 :白乳胶或手工胶。白乳胶干透后强度高且不易变形,优于液体胶水。
- 红色与黑色马克笔 :用于绘制灯塔的砖纹和细节。油性马克笔在纸上附着力更强。
注意 :结构部分的核心是精确测量和稳固粘合。纸板的厚度会影响最终尺寸,在切割前最好用边角料测试一下胶水的性能和干燥时间。
电子部分(交互核心) :
- Adafruit Circuit Playground Bluefruit (CPB) 开发板 :这是项目的“大脑”。我选择CPB而非基础版Circuit Playground Express,主要是看中其蓝牙功能(为未来无线控制留出扩展空间),但其核心的GPIO、电容触摸、NeoPixel驱动、音频播放功能与Express版一致。如果你的项目不需要蓝牙,CPX是更经济的选择。
- 可寻址RGB LED灯带(NeoPixel) :一段30颗灯珠的灯带。选择WS2812B封装(即最常见的NeoPixel),其数据协议简单,仅需一条信号线即可控制所有灯珠。灯珠数量决定了灯塔灯光效果的密度,30颗是一个兼顾效果与功耗的选择。
- 微型扬声器 :一个8欧姆0.5W的小喇叭。CPB板有内置的音频放大器,可以直接驱动这类小功率扬声器,无需额外功放模块。
- 电位器 :一个10k欧姆的旋转式电位器。这个阻值范围与CPB板的模拟输入阻抗匹配良好,能提供平滑的读数变化。阻值太大(如1MΩ)读数易受干扰,太小(如100Ω)则功耗增加。
- 鳄鱼夹测试线 :3条。用于将CPB的触摸引脚引出到模型外部,作为触摸电极。选择它是因为连接方便,无需焊接。
- 导线与面包板 :若干。用于在组装测试阶段连接电位器、扬声器和LED灯带。杜邦线(公-公)最为常用。
- 3.7V锂聚合物电池 :为整个系统供电。CPB板有内置的锂电池充电和管理电路,使用非常方便。选择容量在500mAh以上的电池,以确保足够的运行时间。
- Micro USB数据线 :用于给电池充电以及上传代码和音频文件到CPB板。
3. 灯塔物理模型的结构搭建
一个稳固、美观的物理模型是电子元件的“家”。我的设计是一个六棱柱塔身加锥形屋顶的经典灯塔造型,所有尺寸均基于手头材料和个人偏好确定,你可以按比例缩放。
3.1 精确下料:从二维图纸到三维零件
所有结构件均来自硬纸板。使用直尺和铅笔精确划线是保证后续组装顺利的关键。以下是所有零件的切割清单及尺寸详解:
-
塔身主体(6片) :等腰梯形。
- 下底 :10厘米。这是塔身底面的边长。
- 上底 :7厘米。这是塔身顶面的边长,略小于下底以形成收分,使灯塔看起来更挺拔。
- 高 :23厘米。这个高度决定了灯塔的整体比例。你可以根据想要的模型大小等比例调整。
- 切割技巧 :先切出一个23cm * 10cm的长方形,再在顶部两侧各向内收1.5cm((10cm-7cm)/2)画点,连接底角与这两个点,切割出梯形。重复6次。 务必保证6片梯形尺寸完全一致 ,否则无法拼成正六棱柱。
-
塔顶平台(1片) :正六边形,中心开孔。
- 外接圆半径 :10厘米。这意味着每条边的长度也是10厘米。用圆规或利用“半径等于边长”的性质来画正六边形。
- 中心孔 :直径约2-3厘米的圆孔。用于后期穿引LED灯带线材。可以先画好六边形,再找到中心点开孔。
-
锥形屋顶(6片) :等腰三角形。
- 底边 :7.5厘米。这个尺寸需要与塔顶平台六边形的边长(10厘米)以及塔身上底(7厘米)协调。7.5厘米是一个折中值,使屋顶能覆盖平台并自然过渡。
- 腰长 :10厘米。决定屋顶的坡度。可以使用圆规,以底边中点为圆心,10cm为半径,在底边中垂线上找交点,连接底边两端点即得三角形。
-
灯室墙体(2长条,6短条) :
- 长条 :2.5厘米宽,30厘米长。共2条。它们将被弯折成六边形框架。
- 短条 :2.5厘米宽,7厘米长。共6条。作为立柱连接上下两个六边形框架。
- 计算逻辑 :灯室设计为一个小六棱柱。六边形边长为5厘米,周长30厘米,故长条需30厘米。短条高度(7厘米)决定了灯室的“窗高”。
-
屋顶瓦片(约30片) :长方形装饰件。
- 尺寸 :2厘米宽,3.5厘米长。这个尺寸是估算的,用于覆盖锥形屋顶,模拟瓦片效果。实际数量取决于屋顶面积和粘贴方式,可以边做边切。
3.2 模型组装:从零件到整体
组装顺序遵循“从下到上,从内到外”的原则,使用白乳胶粘贴,每步都需等待胶水半干定型后再进行下一步。
-
塔身拼接 :
- 取一片梯形作为正面,用美工刀刻出窗户和门洞。
- 将6片梯形侧边涂胶,用裁好的长纸条(约2-3厘米宽)像绷带一样横向粘贴,把相邻的两片粘合。先粘合所有侧边,形成一条“梯形带”,再将其首尾粘合,形成一个六棱柱筒。 关键技巧 :粘贴时在内部接缝处也贴上纸条加固,能极大增加整体强度。
-
锥形屋顶制作 :
- 将6片三角形侧边涂胶,同样用纸条从内部粘合。粘合时,底部(7.5厘米边)保持在一个平面上,顶部会自然聚拢成锥尖。如果顶部无法完美闭合,最后可以用一小块纸板封顶遮盖。
- 瓦片粘贴 :从屋顶底部开始,将长方形瓦片一片压一片(像鱼鳞)向上粘贴。这步非常耗时,但效果提升显著。建议先画好辅助线。
-
灯室搭建 :
- 取一条30厘米长条,每5厘米做一个标记,在标记处轻轻划开纸板表层(勿切断),以便弯折。沿标记弯折成正六边形,用胶水固定接口。重复制作另一个六边形。
- 将6根7厘米的短条作为立柱,垂直粘合在两个六边形框架的对应角之间,形成一个镂空的六棱柱小笼子。
- 在“笼子”内部贴上半透明的描图纸或硫酸纸,作为灯室的“玻璃窗”,能让LED光线柔和扩散。
-
总装与美化 :
- 将塔顶平台粘在塔身顶部。
- 将灯室粘在平台中央。
- 锥形屋顶最后盖上, 先不要永久粘死 ,方便后续安装和调整内部灯带。
- 美化 :用白纸覆盖所有外露的纸板。干透后,用红色马克笔和直尺,在塔身上画出规整的横线模拟砖缝,局部可以涂红,形成红白相间的经典灯塔外观。
4. CircuitPython开发环境搭建与代码精讲
这是项目的灵魂。我们将使用CircuitPython对CPB板进行编程。相比传统的Arduino C,CircuitPython使用Python语法,交互式更强,文件管理更直观,特别适合快速原型开发和教育。
4.1 准备工作:固件、驱动与编辑器
-
安装CircuitPython固件 :
- 访问Adafruit官网,找到Circuit Playground Bluefruit的页面,下载最新的UF2格式固件文件(.uf2)。
- 用USB线连接CPB到电脑。快速双击板子上的复位按钮(RESET),此时板载的NeoPixel会变成绿色,电脑上会出现一个名为
CPLAYBTBOOT的U盘。 - 将下载好的
.uf2文件拖入这个U盘。U盘会自动弹出,板子重启后,会出现一个名为CIRCUITPY的新U盘。这表明CircuitPython固件已刷写成功。
-
代码编辑器选择 :
- 推荐Mu Editor :一款专为初学者设计的开源编辑器,内置了CircuitPython模式和串行监视器。它可以直接在
CIRCUITPY盘上编辑code.py文件,保存即运行,非常方便。 - 也可以使用任何文本编辑器(如VS Code、Thonny),但需要手动保存文件到
CIRCUITPY盘。
- 推荐Mu Editor :一款专为初学者设计的开源编辑器,内置了CircuitPython模式和串行监视器。它可以直接在
4.2 核心代码逐行解析
让我们深入剖析项目中的核心代码 code.py ,理解每一部分是如何工作的。
# Megan Costello
# lighthouse art project
import time
import board
import neopixel
import digitalio
from audiopwmio import PWMAudioOut as AudioOut
from audiocore import WaveFile
import touchio
from analogio import AnalogIn
代码开头 :导入必要的库。 board 定义了板子的引脚映射; neopixel 控制LED灯带; audiopwmio 和 audiocore 负责音频播放; touchio 处理电容触摸; analogio 读取电位器模拟值。
# 预定义颜色,方便调用
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
# 可以定义更多颜色...
colors = [RED, MAGENTA, ORANGE, YELLOW, GREEN, JADE, BLUE, INDIGO, VIOLET, PURPLE, BLACK]
颜色定义 :RGB元组表示颜色。预定义常用颜色并放入列表,便于循环或随机选择。
# 初始化板载NeoPixel
pixels_pin = board.NEOPIXEL # 板载LED的数据引脚
pixels_num_of_lights = 10 # CPB板上有10颗板载LED
pixels = neopixel.NeoPixel(pixels_pin, pixels_num_of_lights, brightness=0.2, auto_write=True)
# 初始化外接LED灯带
strip_pin = board.A1 # 外接灯带的数据线接在A1引脚
strip_num_of_lights = 30
strip = neopixel.NeoPixel(strip_pin, strip_num_of_lights, brightness=0.5, auto_write=True)
灯光初始化 :创建两个NeoPixel对象,分别控制板载LED和外接灯带。 brightness 参数(0.0-1.0)非常重要,设置过高(如1.0)会导致电流激增,可能损坏板子或LED。 经验值 :板载LED亮度0.2-0.3,外接灯带根据长度和灯珠数量,0.3-0.6为宜。 auto_write=True 表示设置颜色后立即更新,无需调用 show() 。
# 初始化扬声器
speaker = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker.direction = digitalio.Direction.OUTPUT
speaker.value = True # 使能扬声器放大器
audio = AudioOut(board.SPEAKER) # 音频输出对象
音频初始化 :CPB板的扬声器需要一个使能引脚( SPEAKER_ENABLE )置为高电平来打开内置的音频放大器。然后创建音频输出对象。
# 初始化电位器(模拟输入)
potentiometer = AnalogIn(board.A5)
# 初始化电容触摸引脚
touchpad_A2 = touchio.TouchIn(board.A2)
touchpad_A3 = touchio.TouchIn(board.A3)
touchpad_A4 = touchio.TouchIn(board.A4)
touchpad = [touchpad_A2, touchpad_A3, touchpad_A4] # 放入列表便于管理
输入设备初始化 : AnalogIn 对象用于读取电位器电压值(0-65535)。 TouchIn 对象用于检测触摸。将三个触摸对象放入列表,是一种良好的编程习惯,便于后续扩展和循环检测。
# 音频文件路径和列表
path = "lighthouse-sounds/"
sounds = ["waves.wav", "shiphorn.wav", "seagulls.wav"]
资源管理 :在 CIRCUITPY 盘根目录下创建一个名为 lighthouse-sounds 的文件夹,将处理好的WAV音频文件放进去。在代码中定义路径和文件名列表,使逻辑更清晰。
def play_file(filename, color):
with open(path+filename, "rb") as wave_file:
wave = WaveFile(wave_file)
audio.play(wave)
while audio.playing:
# 在播放音频期间,让灯光闪烁
light_char(color)
核心功能函数 : play_file 函数负责播放音频和触发灯光。 with open... as 语句确保文件被正确打开和关闭。 audio.play() 是非阻塞的,它会立即返回。因此,我们用一个 while audio.playing: 循环,在音频播放的整个期间,持续调用 light_char(color) 函数来制造灯光闪烁效果。这是实现“音画同步”的关键。
def light_char(color):
# 通过电位器值决定灯光持续时间 (映射到0.01 - 3秒范围)
freq = int(potentiometer.value / (65520 / 300))
strip.fill(color)
time.sleep(freq / 100)
strip.fill(BLACK)
time.sleep(0.5)
灯光控制函数 : light_char 函数执行一次“点亮-熄灭”的闪烁。
potentiometer.value:读取当前电位器原始值(0-65520)。65520 / 300:将整个输入范围(65520)映射到300个单位。为什么是300?因为我们希望最大持续时间是3秒,即3000毫秒,但后面除以了100,所以这里用300,最终freq的范围是0-300。int(potentiometer.value / (65520 / 300)):计算得到freq值(0-300)。strip.fill(color):将外接灯带全部设置为指定颜色。time.sleep(freq / 100):点亮持续时间。freq是0-300,除以100后是0.0-3.0秒。这就是电位器控制灯光时长的秘密。strip.fill(BLACK):熄灭灯带。time.sleep(0.5):熄灭后等待0.5秒,形成闪烁节奏,避免过于急促。
while True:
touched = False
if touchpad_A3.value:
touched = True
play_file("waves.wav", RED)
if touchpad_A2.value:
touched = True
play_file("shiphorn.wav", YELLOW)
if touchpad_A4.value:
touched = True
play_file("seagulls.wav", GREEN)
if touched == False:
strip.fill(BLACK)
主循环 :这是一个典型的 事件检测循环 。
- 每次循环开始,先将
touched标志设为False。 - 依次检查三个触摸引脚。如果某个引脚被触摸(
.value为True),则:- 将
touched设为True。 - 调用
play_file函数,播放对应的音频并闪烁对应的颜色。 - 注意 :
play_file函数内部有while audio.playing循环,这意味着一旦开始播放音频,程序会阻塞在这个函数里,直到音频播完。在此期间,主循环无法检测其他触摸输入。这是一种简单的“单任务”处理。如果需要同时响应其他输入,需要考虑更复杂的中断或状态机,但对此项目已足够。
- 将
- 如果本轮循环没有任何触摸事件(
touched == False),则确保灯带是熄灭的。这行代码防止了上次触摸结束后灯光意外常亮。
4.3 音频文件处理要点
CircuitPython的 audiopwmio 库对音频文件格式有严格要求,处理不当会导致无法播放或破音。
- 格式 :必须为 WAV 格式。
- 采样率 :推荐 22050 Hz 或 16000 Hz 。过高的采样率(如44100 Hz)可能处理不过来,导致播放卡顿。
- 位深度 : 16位 。
- 声道 :必须为 单声道(Mono) 。立体声文件需要转换。
- 文件大小 :尽量小。微控制器内存和存储有限,长音频可以剪辑成短片段。
处理流程(使用免费软件Audacity) :
- 导入原始音频文件。
- 菜单栏:
轨道->重采样,将采样率改为22050 Hz。 - 如果是立体声,
轨道->立体声音轨->混音->降混为单声道。 - 选择需要的片段,裁剪。
- 菜单栏:
文件->导出->导出为WAV。 - 在导出对话框中,选择
WAV (Microsoft),编码选择16位PCM。 - 将处理好的文件放入CPB板的
lighthouse-sounds文件夹。
5. 电路连接与系统集成测试
在将电子元件塞进模型之前,必须在桌面上完成完整的电路连接和功能测试。这一步能排除大部分硬件问题。
5.1 分步连接与测试
使用面包板进行连接,确保每部分独立工作后再整合。
- CPB板供电 :使用USB线连接电脑,或接上锂电池。板载电源LED应亮起。
- 连接电位器 :
- 电位器有三个引脚:两边是电源(VCC)和地(GND),中间是滑动端(信号)。
- 将VCC接CPB的
3.3V,GND接GND,信号端接A5。 - 测试:在Mu Editor的串行监视器中,输入
>>> import analogio; >>> pot = analogio.AnalogIn(board.A5); >>> pot.value并旋转旋钮,观察数值是否在0-65520间平滑变化。
- 连接LED灯带 :
- 注意极性! WS2812B灯带有方向性,数据输入(DI)接CPB的
A1,数据输出(DO)悬空或接下一段灯带。 VCC(+5V)接CPB的VOUT引脚 ( 切勿接3.3V! ),GND接GND。 - 务必在VCC和GND之间并联一个 470µF 以上的电解电容 ,正极接VCC,负极接GND,越靠近灯带电源入口越好。这能吸收灯带快速变化时产生的电流尖峰,防止损坏CPB板。这是硬件上最重要的 避坑点 。
- 测试:运行一个简单的测试代码,如
strip.fill((255,0,0)),看灯带是否亮红色。
- 注意极性! WS2812B灯带有方向性,数据输入(DI)接CPB的
- 连接扬声器 :
- 微型扬声器两根线,不分正负,一根接CPB的
SPEAKER引脚,另一根接GND。 - 测试:播放一个简短的测试音频文件。
- 微型扬声器两根线,不分正负,一根接CPB的
- 连接电容触摸 :
- 将三条鳄鱼夹测试线的一端分别夹在CPB的
A2、A3、A4引脚上。 - 测试:在代码中设置触摸检测,触摸鳄鱼夹另一端时,让板载LED亮起或串口打印信息。
- 将三条鳄鱼夹测试线的一端分别夹在CPB的
5.2 系统集成与模型内安装
测试无误后,开始将电子系统装入灯塔模型。
- 规划布局 :将CPB板、电池、电位器、扬声器预先在塔身内部摆放,确保都能放得下,且电位器旋钮和扬声器能朝向预设的开口位置。
- 固定元件 :使用蓝丁胶、热熔胶或尼龙扎带固定元件。 注意 :避免热熔胶覆盖芯片或连接器。电池最好用胶带或扎带单独固定,防止短路。
- 走线 :
- LED灯带从塔身底部穿入,沿着内壁向上,从塔顶平台的孔穿出,最后盘绕在灯室内部。用透明胶带分段固定。
- 鳄鱼夹的线从塔身背面预先开好的小孔穿出。
- 扬声器和电位器的线也引到对应开孔处。
- 关键技巧 :所有线缆尽量整理整齐,用扎带捆好,避免相互缠绕或拉扯到焊点。
- 最终组装 :将屋顶轻轻盖上(不粘死),接通电池。进行最终的功能测试:触摸各鳄鱼夹,检查声音和灯光是否正确触发;旋转电位器,检查灯光持续时间是否变化。
6. 调试心得与进阶优化建议
在实际制作中,你几乎一定会遇到一些问题。这里分享我遇到的典型问题及解决方法,并提供一些让项目更出色的思路。
6.1 常见问题排查速查表
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
CPB板无法被电脑识别为 CIRCUITPY 盘 |
1. 固件未正确刷写 2. USB线仅供电无数据 3. 驱动问题(Windows) |
1. 重新进入UF2引导模式(双击RESET),检查绿色LED,重刷固件。 2. 更换一条确认可传输数据的USB线。 3. 在设备管理器中检查,可能需要安装Adafruit的Windows驱动。 |
| 触摸无反应 | 1. 鳄鱼夹接触不良 2. 引脚配置错误 3. 触摸灵敏度问题 |
1. 检查鳄鱼夹是否夹紧引脚和导线。 2. 确认代码中 TouchIn 使用的引脚(A2/A3/A4)与实际连接一致。 3. 尝试触摸鳄鱼夹金属部分更大面积。某些情况下,在触摸引脚和地之间连接一个1MΩ电阻能提高稳定性。 |
| LED灯带不亮或部分不亮 | 1. 电源接错(接了3.3V) 2. 缺少缓冲电容 3. 数据线接触不良 4. 灯珠损坏 |
1. 立即检查! 必须接 VOUT (~5V)。接3.3V可能导致灯带工作不正常或损坏。 2. 在灯带电源入口处并联470µF以上电容。 3. 检查数据线是否接到 A1 ,以及焊点是否牢固。 4. 如果只有一段不亮,可能是其中一颗灯珠损坏,可以尝试跳过它焊接。 |
| 灯光闪烁异常(乱色、闪烁) | 1. 电源功率不足 2. 代码逻辑错误 3. 接地不良(共地问题) |
1. 满亮度点亮所有白色灯珠电流很大。确保电池电量充足,或降低代码中的 brightness 值(如0.3)。 2. 检查 light_char 函数中的延时逻辑,确保 time.sleep 参数正确。 3. 确保CPB板的GND、灯带的GND、电位器的GND都连接在一起。 |
| 无声音或声音失真 | 1. 扬声器未使能 2. 音频格式不正确 3. 文件损坏或路径错误 |
1. 检查代码中 speaker.value = True 是否执行。 2. 严格按照4.3节要求 用Audacity转换音频:单声道、22050Hz、16位PCM WAV。 3. 检查 path 和 sounds 列表中的文件名是否与 CIRCUITPY 盘中的文件完全一致(包括大小写)。 |
| 电位器控制不灵敏或范围不对 | 1. 接线错误 2. 映射计算有误 |
1. 确认电位器中间引脚接 A5 ,两侧分别接 3.3V 和 GND 。 2. 调试:在循环中打印 potentiometer.value ,观察其实际变化范围(可能是0-65520),然后调整 light_char 函数中的映射公式 (65520/300) 。 |
6.2 项目优化与扩展思路
当基础功能实现后,你可以尝试以下升级,让灯塔更具个性:
-
灯光效果升级 :
- 流水效果 :修改
light_char函数,让灯光像海浪一样依次点亮和熄灭,而不是全部同时亮灭。可以使用for i in range(strip_num_of_lights): strip[i] = color配合循环和延时。 - 颜色渐变 :利用
adafruit_led_animation库(需单独安装),实现彩虹渐变、呼吸灯等复杂效果。 - 双区控制 :让塔身灯带和灯室灯带显示不同颜色或模式,增加层次感。
- 流水效果 :修改
-
交互模式扩展 :
- 模式切换 :增加一个按钮或通过多次触摸切换不同的灯光模式(如常亮、闪烁、渐变)。
- 光敏控制 :添加一个光敏电阻,让灯塔在环境光变暗时自动亮起“航标灯”。
- 蓝牙控制 :利用CPB的蓝牙功能,用手机App(如Adafruit的Bluefruit Connect)远程控制灯光颜色和模式,甚至发送自定义指令。
-
结构与电源优化 :
- 可充电设计 :在模型底部开一个隐蔽的Micro USB孔,方便充电而无需拆开模型。
- 磁吸式屋顶 :在屋顶和塔身接触处安装小磁铁,实现屋顶的轻松开合,方便维护内部元件。
- 美化导线 :使用彩色排线或热缩管包裹导线,让内部布线更整洁美观。
这个项目从一张硬纸板开始,到最终成为一个声光俱佳的交互式艺术品,整个过程充满了动手的乐趣和解决问题的成就感。它完美地诠释了“物理计算”的魅力——用代码去感知和控制我们身边的物理世界。最重要的是,整个框架是通用的,你完全可以将灯塔换成一座城堡、一棵魔法树,或者任何一个你想象中的场景,用同样的技术原理赋予它生命。希望这份详细的指南能帮助你顺利启航,创造出属于你自己的互动作品。如果在制作中遇到任何问题,回顾一下第六部分的排查表,或者带着具体现象去Adafruit或CircuitPython的社区寻找答案,那里有无数热心的创造者。
更多推荐


所有评论(0)