1. 项目概述当传统工艺遇上现代创客几年前我在一个日本工艺展上第一次见到真正的障子灯Shoji Lamp那种由木框和和纸构成的、散发着柔和暖光的灯具其宁静雅致的氛围感让我印象深刻。但作为一个硬件开发者我脑子里冒出的第一个念头是“能不能用现代的技术比如可编程的LED和3D打印来复刻并升级这种体验” 这个想法最终催生了今天要分享的这个项目——一个基于CircuitPython和3D打印的智能LED障子灯。这个项目本质上是一个融合了嵌入式编程、3D建模打印和工业设计的综合性创客作品。它的核心是一块Adafruit的Circuit Playground Express开发板上面集成了10颗可独立寻址的NeoPixel LED。我们通过CircuitPython编写程序让这些LED能够响应一个迷你红外遥控器的指令实现开关、十种颜色切换以及无极调光。而灯体的“灵魂”——那些展现几何光影的面板则是通过多色3D打印技术实现的其设计灵感来源于“不可能图形”在灯光透射下会产生奇妙的立体错觉。整个灯体的框架完全采用燕尾榫这一传统木工结构所有零件通过3D打印实现精准的卡扣配合无需一颗螺丝或一滴胶水就能牢固组装。无论你是刚接触微控制器和CircuitPython想找一个有趣的项目练手还是资深创客希望探索3D打印结构与电子结合的更多可能性亦或是单纯想为书桌增添一件独一无二、充满科技感的装饰品这个项目都能带给你从代码、建模到实体组装的完整乐趣。接下来我将从设计思路、硬件选型、代码解析、打印组装到调试优化毫无保留地拆解整个制作过程。2. 核心硬件与设计思路解析在动手之前理解整个项目的设计逻辑和硬件选型背后的原因至关重要。这能帮助你在未来进行修改或创作自己的变体时做出更合理的决策。2.1 主控板为什么是Circuit Playground Express市面上微控制器开发板琳琅满目从Arduino Uno到ESP32选择非常多。但这个项目我强烈推荐使用Adafruit的Circuit Playground Express后文简称CPX原因有以下几点高度集成开箱即用CPX板载了10颗NeoPixel LED、运动传感器、温度传感器、光线传感器、蜂鸣器、按键和电容触摸引脚。对于本项目我们主要用到NeoPixel和红外接收器引脚。这意味着你不需要为了点亮LED而额外焊接任何电阻或连接线极大简化了硬件准备降低了入门门槛和出错概率。对CircuitPython的完美支持CPX是Adafruit为推广CircuitPython而设计的旗舰板之一。其UF2引导加载程序使得刷入固件像拖放文件一样简单。板载的USB接口既能供电也能进行串行通信方便代码调试。充足的GPIO与专用引脚板子边缘的多个鳄鱼夹友好型焊盘和大引脚孔方便连接外部设备。更重要的是它有一个标记为IR_RX即REMOTEIN的引脚专门优化用于连接红外接收器配合adafruit_irremote库可以非常稳定地解码红外信号这是我们实现遥控功能的基础。注意虽然原项目使用CPX但理论上任何支持CircuitPython和NeoPixel库的板子如QT Py RP2040、Feather RP2040等都可以适配。你需要自行解决红外接收器的连接和供电并修改代码中的引脚定义。2.2 光学与结构设计从“和纸”到“多色PLA”传统障子灯的光源是蜡烛或灯泡光线透过和纸变得均匀、柔和。在现代LED项目中要实现类似效果需要解决两个问题点光源的扩散和色彩的呈现。面板材质选择——半透明PLA使用普通的白色PLA打印面板光线会显得生硬、有强烈的“灯珠感”。而采用半透明TranslucentPLA打印材料本身就像一层柔光罩能将板载的10个点状LED光源混合成一片均匀的面光。这是实现“柔和氛围光”的关键。多色打印与几何设计原项目面板的魔力在于其“不可能图形”设计。通过3D建模软件可以创建出看似三维立体、实则二维的几何图案。利用多色3D打印技术如Bambu Lab AMS、Prusa MMU用不同颜色的半透明PLA在同一层中打印出图案的不同部分。当背光点亮时不同颜色的区域会透出相应色彩的光线从而在视觉上强化了图形的立体感和层次感。例如用青色线条勾勒图形边缘品红色填充部分区域在黄色背光下会呈现出丰富的色彩过渡。无紧固件框架——燕尾榫的魅力为了致敬传统木工整个灯架采用了滑动燕尾榫连接。这种结构的优势在于自锁紧梯形截面的榫头滑入榫槽后在垂直方向拉开的方向上非常牢固。便于组装与拆卸纯粹靠滑动完成连接无需工具也方便未来更换面板或维修内部电路。对3D打印友好只要打印机校准得当打印出的榫卯结构可以做到严丝合缝摩擦力恰到好处。设计时预留了合理的公差通常约0.2mm的间隙确保了组装顺滑又不松动。2.3 红外遥控系统简单可靠的交互方案为什么选择红外遥控而不是蓝牙或Wi-Fi成本与复杂度一个迷你红外遥控器和接收头总价极低且电路连接简单仅需VCC GND Signal三根线。CPX板载了红外接收电路连这三根线都省了。功耗红外接收器待机功耗极低适合这种常电插USB供电的桌面设备。交互直观实体按键有明确的触感和布局对于调光、换色这种简单操作比在手机APP上滑动更加直接和快捷。抗干扰与定向性红外信号需要指向性操作避免了误触。虽然易受强光干扰但在室内灯光环境下完全可靠。本项目使用的Adafruit迷你遥控器采用的是NEC编码协议这也是最通用的红外协议之一。adafruit_irremote库已经封装好了解码逻辑我们只需要关心每个按键对应的命令值即可。3. 软件环境搭建与代码深度剖析硬件是骨架软件是灵魂。这部分我们将完成从给CPX刷入CircuitPython到理解每一行控制代码的整个过程。3.1 CircuitPython固件安装与开发环境下载固件访问CircuitPython官网找到Circuit Playground Express的页面下载最新的.uf2固件文件。请务必下载“稳定版”Stable而非测试版。进入引导加载模式使用一条可靠的数据线很多手机充电线只能充电无法传输数据这是新手最常见的坑将CPX连接到电脑。快速双击板子中央的复位Reset按钮。此时所有10颗LED会变成绿色电脑上会出现一个名为CPLAYBOOT的U盘。如果LED变红说明进入引导模式失败请更换USB线或接口重试。刷入固件将下载好的.uf2文件直接拖入CPLAYBOOT盘符。盘符会自动消失稍等片刻会出现一个名为CIRCUITPY的新盘符。这表明CircuitPython系统已经成功运行。现在你的CPX已经变成一个可以通过Python文件控制的设备了。你可以用任何文本编辑器推荐VS Code、Mu Editor或Thonny打开CIRCUITPY盘里的code.py文件进行编辑保存后代码会自动重启运行。3.2 项目代码库与依赖管理原项目提供了一个“项目包”Project Bundle里面包含了主程序code.py和必需的库文件夹lib。这是CircuitPython项目分发的标准方式。获取库文件你需要将lib文件夹完整地复制到CIRCUITPY盘的根目录。里面必须包含adafruit_irremote.mpy和neopixel.mpy等库文件。.mpy是CircuitPython的编译库格式可以节省内存和提升加载速度。代码结构解析让我们逐段分析code.py理解其工作原理。# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries # SPDX-License-Identifier: MIT import adafruit_irremote import board import neopixel import pulseio # 初始化NeoPixel对象控制板载10颗LED pixels neopixel.NeoPixel(board.NEOPIXEL, 10) # 初始化红外脉冲输入监听REMOTEIN引脚最大脉冲序列长度120空闲状态为高电平 pulsein pulseio.PulseIn(board.REMOTEIN, maxlen120, idle_stateTrue) # 创建通用红外解码器对象 decoder adafruit_irremote.GenericDecode() last_command None # 用于存储上一个命令处理重复按键信号 brightness_up 95 # 遥控器“上”箭头键的解码值 brightness_down 79 # 遥控器“下”箭头键的解码值关键点pulseio.PulseIn是底层硬件捕获红外信号脉冲宽度的模块。idle_stateTrue表示红外接收器在无信号时输出高电平这是最常见的情况。maxlen120设置了缓冲区大小需要足够大以容纳完整的NEC协议信号帧。# 命令-颜色映射字典键是红外命令值值是(R, G, B)元组 command_to_color { 247: (255, 0, 0), # 按键1 - 红色 119: (255, 40, 0), # 按键2 - 橙色 (红少量绿) 183: (255, 150, 0), # 按键3 - 黄色 (红较多绿) 215: (0, 255, 0), # 按键4 - 绿色 87: (0, 255, 120), # 按键5 - 青绿色 151: (0, 255, 255), # 按键6 - 青色 231: (0, 0, 255), # 按键7 - 蓝色 103: (180, 0, 255), # 按键8 - 紫色 (蓝红) 167: (255, 0, 20), # 按键9 - 品红色 (红蓝) 207: (255, 255, 255),# 按键0 - 白色 127: (0, 0, 0), # 播放/暂停键 - 关闭所有LED }核心逻辑这个字典是整个项目的“大脑”。它定义了遥控器上每个数字键对应的颜色。RGB值每个分量范围是0-255。你可以随意修改这些RGB值来定制你自己的颜色方案。例如将247: (255, 0, 0)改成247: (255, 100, 100)按键1就会发出粉红色的光。while True: # 主循环 pulses decoder.read_pulses(pulsein, max_pulse5000) command None try: # 尝试解码捕获到的脉冲序列 code decoder.decode_bits(pulses) # NEC协议解码后通常为4个值的列表我们取第3个作为命令码 if len(code) 3: command code[2] print(Decoded:, command) # 串口打印用于调试 except adafruit_irremote.IRNECRepeatException: # 捕获到重复码用户长按按键使用上一个有效命令 command last_command except adafruit_irremote.IRDecodeException: # 解码失败可能是噪声忽略 pass if not command: # 如果没有获取到有效命令跳过本次循环 continue last_command command # 保存当前命令供处理重复码时使用 # 命令执行逻辑 if command brightness_up: pixels.brightness 0.1 # 亮度增加10% elif command brightness_down: pixels.brightness - 0.1 # 亮度减少10% elif command in command_to_color: pixels.fill(command_to_color[command]) # 填充对应颜色循环详解decoder.read_pulses()会等待并读取红外接收器引脚上的脉冲信号。解码成功后的code可能是一个类似[0, 0, 95, 0]的列表。对于这个遥控器第三个值95才是区分不同按键的唯一命令码。这就是为什么用command code[2]。IRNECRepeatException异常处理非常关键。当用户长按遥控器按键时红外协议为了节能在发送一次完整信号后会只发送一个简短的“重复码”。这个异常处理确保了长按调光时亮度能持续变化。亮度调节pixels.brightness的范围是0.0到1.0。每次加减0.1提供了10个亮度级别操作感比较舒适。实操心得如果你使用的是其他品牌的红外遥控器其命令码很可能不同。你可以在循环中保留print(“Decoded:”, command)这一行然后打开串口监视器如Mu Editor的串行界面按下遥控器按键观察打印出的数值。用这个数值去更新brightness_up、brightness_down和command_to_color字典中的键即可完成适配。4. 3D打印实战从模型处理到完美成品电子部分准备就绪后我们来攻克物理载体的制作。3D打印的质量直接决定了最终作品的观感和组装体验。4.1 模型准备与切片设置原项目提供了已摆放好的3MF文件这是最方便的方式。3MF格式不仅包含模型还能保存切片设置、打印板布局和多材料信息。下载与检查下载提供的3MF文件集。你会看到主要有两类文件用于打印框架的Stile and Rails Set.3mf包含4个立柱和7根横梁以及多个独立的面板文件。框架打印材料建议使用黑色PLA。黑色能最大程度隐藏框架让视觉焦点集中在发光面板上。普通PLA即可无需特殊材料。层高与填充层高0.2mm能在保证强度的同时获得较好的表面质量。填充率建议15%-20%对于这种小尺寸结构件完全足够。关键是要确保壁厚Wall Count/Thickness足够通常2-3圈壁厚以保证燕尾榫部位的强度。支撑框架零件基本都是垂直方向打印通常不需要支撑。但请仔细在切片预览中旋转检查确保任何悬垂角度都不超过60度。面板打印多色核心打印机要求你需要一台支持多色打印的FDM打印机例如配备Bambu Lab AMS、Prusa MMU或类似涂鸦系统的设备。材料选择核心是半透明PLA。原方案使用了黑框架色、半透明洋红、半透明黄、半透明青四种颜色。你可以自由搭配。半透明材料对打印温度敏感建议先打印温度塔测试找到光泽度最高、层间结合最好的温度。切片关键设置** purge to infill / 擦料塔**多色打印必然产生废料。务必启用“擦料塔”或“废料桶”功能让换色时的 purge 料吐到指定区域而不是污染模型。** flush into object’s infill**这是一个高级但好用的功能。它允许将换色时的 purge 料少量注入到当前模型的内部填充中既能减少外部擦料塔的体积又能利用废料加强模型内部。对于这些面板填充率可以适当调高如25%来容纳 purge 料。** 打印速度**打印半透明材料时适当降低外壁打印速度如40mm/s有助于提高层间融合和透光均匀性减少“圈纹”感。4.2 打印后处理与质量检查打印完成后的处理决定了组装的顺滑度。去除支撑与清理小心地移除所有支撑材料。对于面板上细小的几何图案内部可能需要使用镊子或精密剪钳进行清理。榫卯结构测试这是最重要的一步。不要急着组装整个框架。先取一根横梁Rail和一个立柱Stile尝试进行滑动组装。理想状态在不用蛮力的情况下可以平滑地滑动到底且结合后没有明显的晃动感。太紧如果难以插入或需要大力敲击说明榫头过大或榫槽过小。可以使用细砂纸如600目轻轻打磨榫头的两个斜面**注意只打磨斜面不要打磨顶部平面**。每次打磨一点点反复测试。太松如果结合后晃动说明间隙过大。在3D打印中修复“太松”比“太紧”困难。可以考虑在榫槽内部薄薄地涂一层丙烯酸哑光剂或UV树脂待其干透后增加摩擦力。但更好的办法是调整切片软件的“水平扩展补偿”Horizontal Expansion参数略微负值如-0.05mm可以让模型外轮廓更“胖”一点从而让榫头变大。这需要重新打印测试。面板透光测试在组装前将打印好的面板扣在CPX的LED上通电测试透光效果。观察颜色是否均匀图案是否清晰。如果某处透光性太差可能是该处打印层厚不均或填充过密可以考虑在切片软件中对该区域单独设置更低的填充率。5. step-by-step 组装全流程与技巧有了打印完美的零件和烧录好代码的CPX组装过程就像拼搭一个精致的立体拼图。请按照顺序操作并注意以下细节。5.1 框架底座组装零件辨识清点所有框架零件4个完全一样的立柱Stile6个标准横梁Rail1个带USB线槽的特殊横梁Cable Rail。区分Cable Rail的简单方法是它的一侧有一个半圆形的缺口。组装下横梁将一个立柱竖直放置榫槽开口朝上。取一根标准横梁确保其内部的中心凹槽朝上侧面的卡扣凸点nubs朝向框架内侧。将横梁的燕尾榫头对准立柱的榫槽水平滑动进去。听到轻微的“咔嗒”声或感觉到阻力增大即表示滑到底了。重复此步骤将四根下横梁分别安装到四个立柱上形成一个底部方形框架。检查用手轻轻扭动框架应感觉牢固。所有横梁的凹槽应朝上形成一条连续的“轨道”所有凸点应朝向框架中心。5.2 安装底板与主控板定位底板取出底板Bottom Panel。你会发现它有一侧的两个卡扣较短double tabs另一侧的两个卡扣是正常长度。将短卡扣侧对准带有Cable Rail的那一边。这是因为Cable Rail上有USB缺口需要底板这一侧提供额外的安装空间。卡入底板将整个框架倒置让横梁的凹槽朝下。把底板对准框架中心先让长卡扣侧对准对应的横梁凸点向下按压使其卡入。然后稍微用力将短卡扣侧也压入对应的凸点。你会听到清晰的“咔哒”声。确保底板四周与横梁紧密贴合。安装CPX这是整个组装中最需要耐心的一步。将CPX的Micro USB接口朝向Cable Rail一侧。先将PCB板一侧USB口对侧的安装孔扣在底板中央的两个塑料卡扣standoffs下。关键技巧由于PCB板是硬的而3D打印的底板有轻微弹性。用手指轻轻向下压并向外侧微弯底板装有卡扣的部分创造出一个间隙然后将PCB板的另一侧滑入其对应的卡扣下。松开手指让底板回弹PCB板应被牢固地卡在四个定位柱上且不会晃动。切勿使用蛮力以免掰断底板的卡扣。5.3 嵌入面板与封顶插入透光面板将四块打印好的多色面板分别从框架上方沿着立柱内侧的竖向凹槽滑入。确保面板完全下落到底坐在底板的边缘上。面板的图案方向可根据个人喜好调整。安装上横梁取出剩余的四根标准横梁。注意此时它们的凸点应朝向框架外侧与下横梁相反。这是因为它们最终要与顶盖Top Cover的内侧卡扣结合。同样水平滑动将上横梁安装到立柱上压住面板的上边缘。连接电源与测试在安装顶盖前进行通电测试将USB线穿过Cable Rail的缺口插入CPX。接通电源电脑USB口或5V适配器CPX上的LED应亮起默认颜色通常是绿色。使用红外遥控器测试开关、换色和调光功能是否全部正常。这一步至关重要避免全部装好后才发现问题需要返工。完成组装将顶板Top Panel放入顶盖Top Cover的凹槽内。然后将整个灯体框架对准顶盖内侧的四个卡扣垂直向下按压直到所有卡扣都锁紧在横梁外侧的凸点上。翻转灯体大功告成。6. 故障排除与进阶优化指南即使按照指南操作你也可能会遇到一些小问题。这里汇总了常见问题及其解决方案。6.1 电子与代码相关问题问题现象可能原因排查步骤与解决方案CPX连接电脑后无CIRCUITPY盘符1. USB线仅能充电2. 固件未正确刷入3. 驱动问题Windows1. 更换已知良好的数据线。2. 双击Reset键确认LED变绿后拖入UF2文件。3. 在设备管理器中检查是否有未知设备尝试重新安装Adafruit驱动。LED不亮或无法控制1. 代码未上传或错误2. 库文件缺失3. 红外接收问题1. 检查CIRCUITPY盘根目录是否有code.py和lib文件夹。2. 确认lib文件夹内有adafruit_irremote.mpy和neopixel.mpy。3. 打开串口监视器按遥控器看是否有“Decoded: xx”输出。无输出则检查遥控器电池或是否对准接收器在CPX中心附近。遥控反应迟钝或误触发1. 环境强光干扰如阳光、节能灯2. 遥控器电量不足3. 代码解码错误1. 避免在强红外光源下使用。2. 更换遥控器电池。3. 在代码中增加time.sleep(0.1)在循环末尾防止误读信号抖动。颜色显示不正确command_to_color字典中的RGB值错误对照串口打印的命令码检查字典中的键值是否正确对应。修改RGB元组值调整颜色。6.2 3D打印与机械问题问题现象可能原因排查步骤与解决方案榫卯太紧无法组装1. 打印机挤出过度/线宽补偿不足2. 模型公差设计对您的打印机偏小1. 校准打印机挤出步骤E-steps和流量Flow Rate。2.最佳实践在切片软件中找到“水平尺寸补偿”Horizontal Expansion为框架零件设置一个负值如-0.1mm。这会让模型整体向内收缩一点点使榫头变小榫槽变大。需要小幅度测试。榫卯太松框架晃动1. 打印机挤出不足2. 零件收缩或翘曲1. 校准挤出步骤确保挤出量充足。2. 增加“水平尺寸补偿”为正值如0.05mm。3. 在榫头表面涂一层薄薄的指甲油或专用模型胶水干后增加厚度。面板透光不均有明暗条纹1. 打印层厚不均2. 填充图案导致光影不均3. 壁厚太薄1. 确保打印机Z轴稳定使用更小的层高如0.16mm。2. 尝试更换填充图案“同心圆”或“闪电”填充的透光效果通常比网格更均匀。3. 增加模型壁厚如3-4圈。多色面板换色处脏污1. 擦料塔体积不足2. Flush volume purge 量设置过低1. 增大擦料塔体积或启用“废料桶”。2. 在切片软件中增加换色时的 purge 量确保旧颜色被完全排出。6.3 创意扩展与进阶玩法这个项目的框架是一个非常好的平台你可以在此基础上进行无限扩展动态灯光模式修改CircuitPython代码让灯光不再只是单色。你可以实现色彩渐变、呼吸灯、根据音乐节奏变化通过麦克风传感器甚至简单的动画效果。neopixel库支持对每一颗LED单独赋值这打开了巨大的创意空间。传感器交互利用CPX板载的传感器。例如用光线传感器实现自动调光环境光变暗时灯自动调亮。用加速度计实现敲击控制轻拍灯体切换模式。自定义面板设计使用Fusion 360、Blender或Tinkercad等软件设计属于自己的面板图案。可以是星座、城市剪影、喜爱的角色轮廓甚至是镂空的文字。只需将设计导出为STL在切片软件中与提供的面板模型进行布尔运算切割即可。无线升级与网络控制如果你换用支持Wi-Fi的开发板如ESP32-S2/S3可以编写Web服务器代码通过手机浏览器就能控制灯光无需遥控器。甚至可以接入智能家居平台。电源一体化使用一个5V的USB电池供电模块将其嵌入底座就可以摆脱线缆将灯放在任何地方。这个项目最吸引我的地方在于它完美地诠释了“创客”精神用可及的技术将传统的审美以个性化的方式重新表达。从一行行代码的编写到看着打印机一层层构筑出实体最后将两者结合按下遥控器点亮灯光的那一刻所有的调试和打磨都变得值得。它不仅仅是一盏灯更是一个由你亲手赋予生命的、光与影的小小世界。希望你在制作过程中也能享受到这种创造的乐趣。如果在实践中遇到任何本文未覆盖的古怪问题不妨去相关的创客社区分享那里总有热心的高手愿意和你一起探讨。