1. 项目概述:当传统手工模型遇见现代微控制器

我一直对融合物理结构与数字交互的项目情有独钟。一个静态的模型固然精美,但如果能让它“活”起来,根据你的触摸发出声音、点亮灯光,那种亲手创造的互动感是完全不同的体验。这次,我决定挑战自己,制作一个基于CircuitPython的交互式灯塔模型。这不仅仅是一个手工模型,更是一个完整的嵌入式系统原型,它集成了电容触摸感应、可编程LED灯带、音频播放以及通过电位器进行的模拟输入控制。

这个项目的核心目标,是探索如何将我们熟悉的Arduino或MicroPython生态中的交互逻辑,以一种更易上手的方式——CircuitPython——来实现,并封装进一个具有观赏性的实体模型中。最终的作品,灯塔的主体由环保的硬纸板搭建而成,内部则“藏”着一颗由Adafruit Circuit Playground Bluefruit(CPB)开发板驱动的“智能心脏”。触摸模型背面伸出的鳄鱼夹,可以触发不同的环境音效(如海浪、船笛、海鸥鸣叫),同时灯塔的“灯室”和基座会亮起对应颜色的灯光;而旋转电位器旋钮,则可以实时调节每次灯光闪烁的持续时间,从短暂的0.01秒到长达3秒。整个过程,从结构设计、电路连接到代码编写,充满了工程与艺术结合的乐趣。

无论你是对嵌入式开发感兴趣的初学者,想寻找一个综合性的入门项目;还是手工爱好者,希望为自己的作品增添一些动态的科技元素;亦或是教育工作者,在寻找一个能同时涵盖物理计算、编程和设计思维的STEAM教学案例,这个项目都能为你提供一条清晰的路径。接下来,我将毫无保留地拆解从零到一的每一个步骤,分享我在制作过程中踩过的坑和总结出的技巧。

2. 核心思路与物料清单解析

在动手之前,理清整个项目的逻辑框架和准备好合适的材料至关重要。这个灯塔模型本质上是一个典型的嵌入式交互系统,其工作流可以概括为: “感知 -> 处理 -> 执行”

2.1 系统交互逻辑设计

  1. 输入感知层 :我们采用了三种输入方式。

    • 电容触摸 :这是主要的交互入口。利用CPB板内置的电容触摸感应引脚(如A2, A3, A4),连接鳄鱼夹作为触摸电极。当人体(导体)触摸电极时,会改变引脚的电容值,从而被检测为“触摸”事件。我们用它来触发不同的场景(海浪、船笛、海鸥)。
    • 电位器(模拟输入) :这是一个连续调节的输入设备。电位器本质上是一个可变电阻,通过旋转旋钮改变电阻值,CPB板的模拟输入引脚(A5)会读取到一个随之变化的电压值(0-3.3V,对应数字值0-65535)。我们将这个值映射到灯光持续时间上,实现无极调节。
    • 电源开关 :虽然简单,但必不可少。通过电池盒的物理开关控制整个系统的供电。
  2. 核心处理层 :由CPB板上的微控制器(nRF52840)和CircuitPython固件承担。它的任务是:

    • 循环检测触摸引脚和电位器引脚的状态。
    • 当检测到特定触摸事件时,根据预设的映射关系,决定播放哪个音频文件,以及点亮什么颜色的LED。
    • 读取电位器的值,并将其转换为灯光亮起的持续时间。
    • 协调音频播放和灯光控制这两个并发的输出任务。
  3. 输出执行层

    • 音频输出 :通过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 精确下料:从二维图纸到三维零件

所有结构件均来自硬纸板。使用直尺和铅笔精确划线是保证后续组装顺利的关键。以下是所有零件的切割清单及尺寸详解:

  1. 塔身主体(6片) :等腰梯形。

    • 下底 :10厘米。这是塔身底面的边长。
    • 上底 :7厘米。这是塔身顶面的边长,略小于下底以形成收分,使灯塔看起来更挺拔。
    • :23厘米。这个高度决定了灯塔的整体比例。你可以根据想要的模型大小等比例调整。
    • 切割技巧 :先切出一个23cm * 10cm的长方形,再在顶部两侧各向内收1.5cm((10cm-7cm)/2)画点,连接底角与这两个点,切割出梯形。重复6次。 务必保证6片梯形尺寸完全一致 ,否则无法拼成正六棱柱。
  2. 塔顶平台(1片) :正六边形,中心开孔。

    • 外接圆半径 :10厘米。这意味着每条边的长度也是10厘米。用圆规或利用“半径等于边长”的性质来画正六边形。
    • 中心孔 :直径约2-3厘米的圆孔。用于后期穿引LED灯带线材。可以先画好六边形,再找到中心点开孔。
  3. 锥形屋顶(6片) :等腰三角形。

    • 底边 :7.5厘米。这个尺寸需要与塔顶平台六边形的边长(10厘米)以及塔身上底(7厘米)协调。7.5厘米是一个折中值,使屋顶能覆盖平台并自然过渡。
    • 腰长 :10厘米。决定屋顶的坡度。可以使用圆规,以底边中点为圆心,10cm为半径,在底边中垂线上找交点,连接底边两端点即得三角形。
  4. 灯室墙体(2长条,6短条)

    • 长条 :2.5厘米宽,30厘米长。共2条。它们将被弯折成六边形框架。
    • 短条 :2.5厘米宽,7厘米长。共6条。作为立柱连接上下两个六边形框架。
    • 计算逻辑 :灯室设计为一个小六棱柱。六边形边长为5厘米,周长30厘米,故长条需30厘米。短条高度(7厘米)决定了灯室的“窗高”。
  5. 屋顶瓦片(约30片) :长方形装饰件。

    • 尺寸 :2厘米宽,3.5厘米长。这个尺寸是估算的,用于覆盖锥形屋顶,模拟瓦片效果。实际数量取决于屋顶面积和粘贴方式,可以边做边切。

3.2 模型组装:从零件到整体

组装顺序遵循“从下到上,从内到外”的原则,使用白乳胶粘贴,每步都需等待胶水半干定型后再进行下一步。

  1. 塔身拼接

    • 取一片梯形作为正面,用美工刀刻出窗户和门洞。
    • 将6片梯形侧边涂胶,用裁好的长纸条(约2-3厘米宽)像绷带一样横向粘贴,把相邻的两片粘合。先粘合所有侧边,形成一条“梯形带”,再将其首尾粘合,形成一个六棱柱筒。 关键技巧 :粘贴时在内部接缝处也贴上纸条加固,能极大增加整体强度。
  2. 锥形屋顶制作

    • 将6片三角形侧边涂胶,同样用纸条从内部粘合。粘合时,底部(7.5厘米边)保持在一个平面上,顶部会自然聚拢成锥尖。如果顶部无法完美闭合,最后可以用一小块纸板封顶遮盖。
    • 瓦片粘贴 :从屋顶底部开始,将长方形瓦片一片压一片(像鱼鳞)向上粘贴。这步非常耗时,但效果提升显著。建议先画好辅助线。
  3. 灯室搭建

    • 取一条30厘米长条,每5厘米做一个标记,在标记处轻轻划开纸板表层(勿切断),以便弯折。沿标记弯折成正六边形,用胶水固定接口。重复制作另一个六边形。
    • 将6根7厘米的短条作为立柱,垂直粘合在两个六边形框架的对应角之间,形成一个镂空的六棱柱小笼子。
    • 在“笼子”内部贴上半透明的描图纸或硫酸纸,作为灯室的“玻璃窗”,能让LED光线柔和扩散。
  4. 总装与美化

    • 将塔顶平台粘在塔身顶部。
    • 将灯室粘在平台中央。
    • 锥形屋顶最后盖上, 先不要永久粘死 ,方便后续安装和调整内部灯带。
    • 美化 :用白纸覆盖所有外露的纸板。干透后,用红色马克笔和直尺,在塔身上画出规整的横线模拟砖缝,局部可以涂红,形成红白相间的经典灯塔外观。

4. CircuitPython开发环境搭建与代码精讲

这是项目的灵魂。我们将使用CircuitPython对CPB板进行编程。相比传统的Arduino C,CircuitPython使用Python语法,交互式更强,文件管理更直观,特别适合快速原型开发和教育。

4.1 准备工作:固件、驱动与编辑器

  1. 安装CircuitPython固件

    • 访问Adafruit官网,找到Circuit Playground Bluefruit的页面,下载最新的UF2格式固件文件(.uf2)。
    • 用USB线连接CPB到电脑。快速双击板子上的复位按钮(RESET),此时板载的NeoPixel会变成绿色,电脑上会出现一个名为 CPLAYBTBOOT 的U盘。
    • 将下载好的 .uf2 文件拖入这个U盘。U盘会自动弹出,板子重启后,会出现一个名为 CIRCUITPY 的新U盘。这表明CircuitPython固件已刷写成功。
  2. 代码编辑器选择

    • 推荐Mu Editor :一款专为初学者设计的开源编辑器,内置了CircuitPython模式和串行监视器。它可以直接在 CIRCUITPY 盘上编辑 code.py 文件,保存即运行,非常方便。
    • 也可以使用任何文本编辑器(如VS Code、Thonny),但需要手动保存文件到 CIRCUITPY 盘。

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 函数执行一次“点亮-熄灭”的闪烁。

  1. potentiometer.value :读取当前电位器原始值(0-65520)。
  2. 65520 / 300 :将整个输入范围(65520)映射到300个单位。为什么是300?因为我们希望最大持续时间是3秒,即3000毫秒,但后面除以了100,所以这里用300,最终 freq 的范围是0-300。
  3. int(potentiometer.value / (65520 / 300)) :计算得到 freq 值(0-300)。
  4. strip.fill(color) :将外接灯带全部设置为指定颜色。
  5. time.sleep(freq / 100) :点亮持续时间。 freq 是0-300,除以100后是0.0-3.0秒。这就是电位器控制灯光时长的秘密。
  6. strip.fill(BLACK) :熄灭灯带。
  7. 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)

主循环 :这是一个典型的 事件检测循环

  1. 每次循环开始,先将 touched 标志设为 False
  2. 依次检查三个触摸引脚。如果某个引脚被触摸( .value True ),则:
    • touched 设为 True
    • 调用 play_file 函数,播放对应的音频并闪烁对应的颜色。
    • 注意 play_file 函数内部有 while audio.playing 循环,这意味着一旦开始播放音频,程序会阻塞在这个函数里,直到音频播完。在此期间,主循环无法检测其他触摸输入。这是一种简单的“单任务”处理。如果需要同时响应其他输入,需要考虑更复杂的中断或状态机,但对此项目已足够。
  3. 如果本轮循环没有任何触摸事件( touched == False ),则确保灯带是熄灭的。这行代码防止了上次触摸结束后灯光意外常亮。

4.3 音频文件处理要点

CircuitPython的 audiopwmio 库对音频文件格式有严格要求,处理不当会导致无法播放或破音。

  1. 格式 :必须为 WAV 格式。
  2. 采样率 :推荐 22050 Hz 16000 Hz 。过高的采样率(如44100 Hz)可能处理不过来,导致播放卡顿。
  3. 位深度 16位
  4. 声道 :必须为 单声道(Mono) 。立体声文件需要转换。
  5. 文件大小 :尽量小。微控制器内存和存储有限,长音频可以剪辑成短片段。

处理流程(使用免费软件Audacity)

  1. 导入原始音频文件。
  2. 菜单栏: 轨道 -> 重采样 ,将采样率改为22050 Hz。
  3. 如果是立体声, 轨道 -> 立体声音轨 -> 混音 -> 降混为单声道
  4. 选择需要的片段,裁剪。
  5. 菜单栏: 文件 -> 导出 -> 导出为WAV
  6. 在导出对话框中,选择 WAV (Microsoft) 编码 选择 16位PCM
  7. 将处理好的文件放入CPB板的 lighthouse-sounds 文件夹。

5. 电路连接与系统集成测试

在将电子元件塞进模型之前,必须在桌面上完成完整的电路连接和功能测试。这一步能排除大部分硬件问题。

5.1 分步连接与测试

使用面包板进行连接,确保每部分独立工作后再整合。

  1. CPB板供电 :使用USB线连接电脑,或接上锂电池。板载电源LED应亮起。
  2. 连接电位器
    • 电位器有三个引脚:两边是电源(VCC)和地(GND),中间是滑动端(信号)。
    • 将VCC接CPB的 3.3V ,GND接 GND ,信号端接 A5
    • 测试:在Mu Editor的串行监视器中,输入 >>> import analogio; >>> pot = analogio.AnalogIn(board.A5); >>> pot.value 并旋转旋钮,观察数值是否在0-65520间平滑变化。
  3. 连接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)) ,看灯带是否亮红色。
  4. 连接扬声器
    • 微型扬声器两根线,不分正负,一根接CPB的 SPEAKER 引脚,另一根接 GND
    • 测试:播放一个简短的测试音频文件。
  5. 连接电容触摸
    • 将三条鳄鱼夹测试线的一端分别夹在CPB的 A2 A3 A4 引脚上。
    • 测试:在代码中设置触摸检测,触摸鳄鱼夹另一端时,让板载LED亮起或串口打印信息。

5.2 系统集成与模型内安装

测试无误后,开始将电子系统装入灯塔模型。

  1. 规划布局 :将CPB板、电池、电位器、扬声器预先在塔身内部摆放,确保都能放得下,且电位器旋钮和扬声器能朝向预设的开口位置。
  2. 固定元件 :使用蓝丁胶、热熔胶或尼龙扎带固定元件。 注意 :避免热熔胶覆盖芯片或连接器。电池最好用胶带或扎带单独固定,防止短路。
  3. 走线
    • LED灯带从塔身底部穿入,沿着内壁向上,从塔顶平台的孔穿出,最后盘绕在灯室内部。用透明胶带分段固定。
    • 鳄鱼夹的线从塔身背面预先开好的小孔穿出。
    • 扬声器和电位器的线也引到对应开孔处。
    • 关键技巧 :所有线缆尽量整理整齐,用扎带捆好,避免相互缠绕或拉扯到焊点。
  4. 最终组装 :将屋顶轻轻盖上(不粘死),接通电池。进行最终的功能测试:触摸各鳄鱼夹,检查声音和灯光是否正确触发;旋转电位器,检查灯光持续时间是否变化。

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 项目优化与扩展思路

当基础功能实现后,你可以尝试以下升级,让灯塔更具个性:

  1. 灯光效果升级

    • 流水效果 :修改 light_char 函数,让灯光像海浪一样依次点亮和熄灭,而不是全部同时亮灭。可以使用 for i in range(strip_num_of_lights): strip[i] = color 配合循环和延时。
    • 颜色渐变 :利用 adafruit_led_animation 库(需单独安装),实现彩虹渐变、呼吸灯等复杂效果。
    • 双区控制 :让塔身灯带和灯室灯带显示不同颜色或模式,增加层次感。
  2. 交互模式扩展

    • 模式切换 :增加一个按钮或通过多次触摸切换不同的灯光模式(如常亮、闪烁、渐变)。
    • 光敏控制 :添加一个光敏电阻,让灯塔在环境光变暗时自动亮起“航标灯”。
    • 蓝牙控制 :利用CPB的蓝牙功能,用手机App(如Adafruit的Bluefruit Connect)远程控制灯光颜色和模式,甚至发送自定义指令。
  3. 结构与电源优化

    • 可充电设计 :在模型底部开一个隐蔽的Micro USB孔,方便充电而无需拆开模型。
    • 磁吸式屋顶 :在屋顶和塔身接触处安装小磁铁,实现屋顶的轻松开合,方便维护内部元件。
    • 美化导线 :使用彩色排线或热缩管包裹导线,让内部布线更整洁美观。

这个项目从一张硬纸板开始,到最终成为一个声光俱佳的交互式艺术品,整个过程充满了动手的乐趣和解决问题的成就感。它完美地诠释了“物理计算”的魅力——用代码去感知和控制我们身边的物理世界。最重要的是,整个框架是通用的,你完全可以将灯塔换成一座城堡、一棵魔法树,或者任何一个你想象中的场景,用同样的技术原理赋予它生命。希望这份详细的指南能帮助你顺利启航,创造出属于你自己的互动作品。如果在制作中遇到任何问题,回顾一下第六部分的排查表,或者带着具体现象去Adafruit或CircuitPython的社区寻找答案,那里有无数热心的创造者。

更多推荐