1. 项目概述与设计思路几年前我第一次看到Voronoi图那种由点集生成的自然、不规则的细胞状分割结构时就被它那种兼具数学美感和有机形态的特质吸引了。当时就在想能不能把这种算法生成的几何美感从屏幕里“拽”出来变成一个能拿在手里、会发光的实体物件这就是这个PCB灯项目最初的灵感来源。本质上我想做的不是一个简单的灯罩而是一个以PCB本身作为结构主体和艺术表达载体的“电子雕塑”。V1版本更像是一个粗糙的概念验证用四块矩形PCB当墙壁两块正方形PCB做顶和底围成一个六面体里面放上RGB LED。想法很酷但做出来问题一堆LED焊盘画错了灯珠压根装不上去几块板子拼起来后缝隙大得能塞进一张卡片光从缝里漏出来破坏了整体的视觉完整性。这些坑但凡自己动手做过硬件的朋友估计都能会心一笑。所以这个V2版本的核心目标非常明确解决V1的所有已知缺陷并优化整个制作流程让它从一个“勉强能亮”的 prototype变成一个真正可靠、精致、可供复制的作品。整个项目的技术栈围绕着“小而美”展开。主控选择了ATTiny85这颗只有8个引脚的微控制器驱动几颗WS2812B LED绰绰有余极大地简化了电路和编程。供电则采用了如今已成主流的USB Type-C接口正反插都能用告别了老式Micro-USB的烦恼。最大的挑战在于如何让作为“墙壁”的PCB在拼装时严丝合缝以及如何确保所有表面贴装元件尤其是那个微小的2020封装的WS2812B能一次焊接成功。这不仅仅是在画图软件里调整几个尺寸那么简单它涉及到对PCB制造公差、焊接工艺以及结构装配的综合性理解。2. 核心硬件设计与选型解析2.1 主控与电路架构设计选择ATTiny85作为大脑是基于项目需求的一个典型“够用就好”的决策。这个灯的核心功能就是循环切换几种灯光模式逻辑简单对算力和IO口数量要求极低。WS2812B是一种集成驱动芯片的智能RGB LED它采用单线归零码通信协议。这意味着只需要ATTiny85的一个IO口我用了Pin 0就能控制串联起来的全部四颗灯珠实现任意颜色和亮度的独立控制大大节省了宝贵的IO资源。电路原理图虽然不复杂但几个关键细节决定了项目的成败。首先是电源部分。USB Type-C口的5V电源直接进来我串联了一个M7二极管作用类似于经典的1N4007但它是SMD封装。这个二极管有两个重要作用一是防止电源反接损坏后续电路二是利用其约0.7V的正向压降将电压略微降低对ATTiny85和WS2812B来说都在安全范围内。二极管后面我放置了一个2欧姆的1206封装电阻。别小看这个电阻它是关键的限流保护元件。假设后端短路根据欧姆定律 I V/R最大电流会被限制在 5V / 2Ω 2.5A 左右这能有效保护USB电源和二极管避免灾难性故障。对于正常工作电流仅几百毫安的系统来说这个电阻上的压降可以忽略不计。按钮电路设计为低电平触发并启用了ATTiny85的内部上拉电阻。这样按钮一端接地另一端接IO口Pin 4。当按钮未按下时IO口通过内部上拉电阻接到VCC读到的是高电平按下时IO口直接接地读到低电平。这种设计省去了一个外部电阻是微控制器IO口的标准用法。注意在绘制原理图时务必确认ATTiny85的引脚定义。不同封装的引脚顺序可能不同。我使用的是SOIC-8封装需要严格按照其数据手册来连接VCC、GND、复位引脚以及用于编程和通信的引脚。2.2 PCB布局与Voronoi图案生成这是项目的艺术核心。Voronoi图本身是通过算法生成的在平面上随机或按规则散布一系列“种子点”然后平面被划分为多个区域每个区域包含距离某一特定种子点最近的所有点。我用的是电子设计自动化软件中的脚本或插件功能例如KiCad的插件或从其他图形软件导入DXF文件在PCB的铜层通常是顶层或底层生成了这种不规则的多边形网格。布局的关键考量电气隔离生成的Voronoi单元格彼此之间必须有足够的间隙Clearance这个间隙就是后来蚀刻掉铜箔的地方它保证了单元格之间是电气隔离的。我设置的间隙是0.3mm这对于大多数PCB制造商来说是安全值。连接性所有的Voronoi单元格并不是孤立的它们需要连接到一个共同的网络比如GND或VCC才能形成有效的电路。我的处理方法是在图案内部保留一些细小的“桥梁”将所有单元格连接起来而在板子边缘则通过一个较粗的边框线将所有桥梁汇总引出到焊盘。焊盘与走线用于拼接的焊盘、LED焊盘、主控焊盘等必须放置在非Voronoi图案的“实心”区域或者对图案进行局部修改留出规整的位置。电源和信号线需要从这些焊盘引出穿过或绕过Voronoi区域连接到对应位置。这时需要仔细调整走线宽度电源线要粗例如0.5mm信号线可以细例如0.2mm。2.3 V2版本的核心改进尺寸与封装V1版本的血泪教训直接塑造了V2的设计。解决拼接缝隙问题V1的矩形板和方形板尺寸是严丝合缝按理论值画的但忽略了两个现实PCB制造的公差通常±0.1mm和焊接时焊锡的“填充”占位。这导致拼装时板子互相顶住无法紧密贴合。在V2中我将两块正方形PCB顶板和底板的每条边都缩短了1mm。这样当四块矩形板夹住它们时就有了微小的调整余量通过焊接焊锡的多少可以灵活控制松紧最终实现紧密拼接。纠正LED封装错误V1直接用了不合适的LED封装导致无法焊接。V2明确指定使用WS2812B2020封装。“2020”指的是灯珠尺寸为2.0mm x 2.0mm这是非常微小的。在PCB库中创建或调用该封装时必须严格参照数据手册确保三个焊盘5V DIN/DOUT GND的位置、大小和间距完全正确。我将LED放置在顶层光线透过Voronoi图案的缝隙射出效果更好。3. PCB制造与SMT焊接工艺详解3.1 拼板设计与成本优化为了节省打样成本和运费我将两个不同的正方形PCB主控板和开关板设计在了一版面板上。这不是简单的并排放置而是采用了**“邮票孔拼板”的方式。具体做法是在两个板子之间画一条细长的分割线在这条线上间隔地放置一系列小的非金属化孔在KiCad中通常用“Edge.Cuts”层画出一排短线段。这些孔在PCB生产后板子强度在此处最弱用手或工具轻轻一掰就能分开断面相对平整。同时我还在两个板子外侧添加了工艺边**并预留了铣刀路径方便工厂加工和贴片机生产。在发给制造商时一定要在订单备注中说明这是拼板并指出如何分板。3.2 焊接准备钢网与焊膏对于2020封装的WS2812B、0402或0603封装的电阻电容手工焊接难度极大且容易损坏。因此回流焊是唯一靠谱的选择。回流焊的核心是焊锡膏和钢网。焊锡膏选择颗粒度细如Type 3、活性适中RMA型的无铅焊锡膏。从冰箱取出后需回温至室温并充分搅拌。钢网这是决定焊接质量的关键工具。钢网是一张有镂空图案的薄钢板图案对应PCB上的所有焊盘。我通常选择激光切割、电抛光的不锈钢钢网厚度为0.1mm或0.12mm。将钢网精准对齐覆盖在PCB上用刮刀将焊锡膏刮过焊膏就会通过镂空处漏印到PCB焊盘上形成均匀的膏体。实操心得如果没有定制钢网对于这种元件数量不多的板子可以用点胶瓶手动点焊锡膏。但这需要极稳的手和耐心每个焊盘上的膏体量要尽量一致否则容易导致焊接不良或桥接。这是下策但对于快速原型验证可以接受。3.3 贴片与回流焊接流程手工贴片在放大镜或台灯下使用尖头防静电镊子将元件逐一拾取并放置到对应的焊膏位置上。对于ATTiny85这类有方向的芯片要看清丝印上的圆点或缺口对准PCB封装上的标记。WS2812B也要注意方向其焊盘通常有一个缺口或色点标记对应数据输入脚。热板回流焊我使用的是自制的恒温热板。将贴好元件的PCB轻轻放在已预热的热板上。预热区热板温度逐步上升至约150°C使焊膏中的溶剂缓慢挥发避免飞溅。这个过程大约60-90秒。恒温区/活性区温度维持在150-200°C之间助焊剂被激活开始清除焊盘和元件引脚上的氧化物。持续60秒左右。回流区温度快速上升至峰值对于无铅焊锡膏峰值温度通常在230-250°C。焊锡在此温度下完全熔化变成液态在表面张力和助焊剂的作用下会“自动”包裹元件引脚并吸附到焊盘上形成光亮的焊点。看到所有焊点瞬间闪亮此过程仅几秒到十几秒即可。冷却区将PCB移离热板放在隔热垫或金属架上自然冷却。切勿用嘴吹或强制冷却以免产生热应力裂纹。焊接完成后需要立即用放大镜检查。重点看WS2812B和ATTiny85的焊点是否有桥接、虚焊或移位。对于微小的桥接可以用细头烙铁配合吸锡线或助焊剂进行修复。3.4 后焊与组装SMD元件通过回流焊搞定后剩下的就是通孔或较大的元件了。USB Type-C端口这是通孔/半贴片元件。先在焊盘上点上少量焊锡然后用烙铁固定其中一个定位脚再焊接其他引脚。注意USB-C端口有24个引脚但通常我们只用到电源和接地的那几对务必对照封装图焊接正确。SMD按钮和UC202接线端子这些也可以用烙铁手工焊接。焊接按钮时动作要快避免过热损坏内部弹片。UC202端子用于连接外部电源或调试要焊牢。最终机械组装这是见证奇迹的时刻。先给一块矩形板内侧边缘的焊盘上锡。然后将已焊好元件的主控方形板对准位置用烙铁加热矩形板的焊盘和方形板边缘的焊盘使它们熔合在一起。重复这个过程将四块矩形板和两块方形板全部焊接成一个立方体框架。在这个过程中可以灵活调整焊锡量确保板子之间既连接牢固又无过大缝隙。4. 嵌入式软件编程与灯光控制逻辑4.1 开发环境与程序烧录ATTiny85可以通过Arduino IDE进行开发这极大地降低了门槛。首先需要在IDE的“开发板管理器”中添加ATTiny85的支持通常通过安装attiny或SpenceKonde的核心包。编程器我选择的是“Arduino as ISP”也就是用另一块Arduino Uno作为烧录器。接线方式Arduino Uno作为ISPUno的 Pin 10 - ATTiny85 RESET (Pin 1)Uno的 Pin 11 - ATTiny85 MOSI (Pin 5)Uno的 Pin 12 - ATTiny85 MISO (Pin 6)Uno的 Pin 13 - ATTiny85 SCK (Pin 7)Uno的 5V - ATTiny85 VCC (Pin 8)Uno的 GND - ATTiny85 GND (Pin 4)在Arduino IDE中选择开发板为“ATtiny25/45/85”处理器为“ATtiny85”时钟为“内部8MHz”编程器选择“Arduino as ISP”。然后点击“通过编程器上传”即可将代码烧录进去。4.2 代码逻辑深度解析项目代码基于Adafruit NeoPixel库这个库封装了WS2812B的底层时序通信让我们可以专注于灯光效果。#include Adafruit_NeoPixel.h // 硬件引脚定义 #define BUTTON_PIN 4 // 按钮接在Pin 4 内部上拉 #define PIXEL_PIN 0 // WS2812B数据线接在Pin 0 #define PIXEL_COUNT 4 // 共有4颗灯珠 Adafruit_NeoPixel strip Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB NEO_KHZ800); bool oldState HIGH; // 记录按钮上一次的状态 int showType 0; // 当前显示的模式索引 void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); // 设置按钮引脚为输入并启用内部上拉电阻 strip.begin(); // 初始化NeoPixel库 strip.show(); // 初始化后立即关闭所有LED避免随机亮起 } void loop() { bool newState digitalRead(BUTTON_PIN); // 读取当前按钮状态 // 检测下降沿之前是高现在是低表示按钮被按下 if (newState LOW oldState HIGH) { delay(20); // 简单的按键消抖等待20ms避开机械抖动 newState digitalRead(BUTTON_PIN); // 再次读取确认状态 if (newState LOW) { // 确认按钮确实被按下了 showType; // 切换到下一个模式 if (showType 9) // 如果超过模式总数0-9则归零 showType 0; startShow(showType); // 执行对应的灯光显示函数 } } oldState newState; // 更新旧状态 }核心机制解读状态检测代码采用“边沿检测”而非“电平检测”。只有当按钮状态从高变低下降沿时才响应这确保了按一次只触发一次动作避免了长按时的连续触发。消抖处理delay(20)是经典的软件消抖。机械按钮在按下和弹起时触点会产生数毫秒的物理抖动导致电平快速变化。延时后再次采样可以过滤掉这些抖动得到稳定的状态。模式循环showType变量作为索引每按一次加1并在0-9之间循环。startShow()函数根据这个索引值调用不同的灯光效果函数。灯光效果函数如colorWipe颜色填充、theaterChase剧院追逐、rainbow彩虹等都是通过控制每颗LED的颜色和刷新间隔来实现的。Wheel()函数是一个经典的色彩轮函数它将一个0-255的输入值映射到一段彩虹色渐变上是生成平滑渐变色的核心。4.3 功能扩展与调试技巧增加更多效果你可以轻松地在switch-case语句中添加新的case并编写新的效果函数。例如可以添加呼吸灯效果、根据音乐节奏变化的效果等。调试如果灯不亮首先检查硬件电源是否接通USB线是否完好数据线Pin 0是否连接正确然后检查软件代码是否正确烧录引脚定义是否与实物对应可以在setup()里添加strip.setPixelColor(0, strip.Color(255,0,0)); strip.show();来测试第一颗LED是否能亮红色。功耗优化如果使用电池供电可以在灯光效果结束后调用strip.clear()和strip.show()关闭所有LED并将ATTiny85进入睡眠模式以大幅降低功耗。5. 常见问题排查与制作心得5.1 硬件组装问题排查表问题现象可能原因排查与解决方法LED完全不亮1. 电源未接通或反接。2. USB端口、二极管、限流电阻有虚焊或损坏。3. 主控ATTiny85未工作或程序未烧入。1. 用万用表测量USB端口输出电压应~5V并逐级向后测量直到LED电源引脚。2. 检查所有电源路径上的焊点重新焊接可疑点。3. 检查ATTiny85的VCC/GND尝试重新烧录一个简单的测试程序如让一个IO口闪烁。部分LED不亮或颜色异常1. WS2812B灯珠损坏。2. 数据线DIN/DOUT连接有误或虚焊。3. 灯珠焊接方向错误。1. 用已知好的灯珠替换测试。2. 用万用表蜂鸣档检查数据线从ATTiny85到第一颗LED再到后续LED的连通性。3. 确认灯珠的DIN脚是否对准了来自上一颗灯珠DOUT或主控的数据线。按钮无反应1. 按钮损坏或焊接不良。2. 按钮引脚接错应一端接地一端接IO。3. 代码中引脚定义错误或内部上拉未启用。1. 用万用表通断档测试按钮按下时是否导通。2. 检查原理图和实物接线。3. 检查代码pinMode(BUTTON_PIN, INPUT_PULLUP)是否正确。PCB拼接处缝隙大或不牢固1. 方形板尺寸未按设计缩减。2. 焊接时焊锡量不足或未完全熔合。3. 焊盘对位不准。1. 核对PCB设计文件确认方形板尺寸已调整。2. 用烙铁和足够的焊锡在拼接处内外两侧进行补焊确保焊锡浸润整个焊盘连接处。焊接后短路或芯片发烫1. 焊锡桥接导致电源与地短路。2. 元件特别是二极管、LED方向焊反。3. 电源电压过高。立即断电1. 用放大镜仔细检查所有密集焊点如ATTiny85、USB口用吸锡线清理桥接。2. 核对所有有极性元件的方向。3. 确认输入电压为5V并检查二极管是否正常接入。5.2 从V1到V2踩坑经验总结“理论尺寸”不等于“装配尺寸”这是机械设计包括PCB拼装最经典的教训。一定要为公差和装配工艺留出余量。我的1mm缩减量就是基于PCB厚度和焊锡厚度的估算实际可能因工艺不同需要微调。封装是神圣的在画PCB之前花双倍的时间确认每一个元件的封装是否正确。最好的方法是直接打开元件供应商官网的数据手册找到“Recommended PCB Land Pattern”章节照着尺寸画。自己建库时最好打印出1:1的图纸把实物元件放上去比对。回流焊是朋友对于0402、0603、SOT-23以及WS2812B-2020这类小型化元件手工焊接的成功率和美观度都无法保证。投资一张简单的恒温热板或改造一个旧电熨斗或者使用预加热台热风枪的组合能极大提升作品的专业度和制作愉悦感。测试分阶段测试不要等全部焊好了再上电。我的流程是焊接完电源部分USB口、二极管、电阻- 上电测电压 - 焊接主控并烧录测试程序如闪灯- 焊接第一颗LED并测试 - 焊接后续LED并测试。这样任何问题都能被局限在一个小范围内排查起来容易得多。这个Voronoi PCB灯V2项目从灵感迸发到问题排查完整地走通了一个硬件产品从概念到实物的闭环。它不仅仅是一个灯更是一个关于如何在约束条件下成本、尺寸、工艺通过迭代设计来解决实际工程问题的微型案例。当你按下按钮灯光透过那些不规则的几何图案柔和地洒出来时你会觉得之前所有的调试和焊接都是值得的。硬件制作的魅力就在于这种与物理世界直接交互、并最终将其掌控于手的成就感。如果你在复现过程中遇到任何问题或者有了更酷的灯光效果想法随时可以在此基础上继续探索这或许就是开源硬件和DIY精神最吸引人的地方。