
1. 从“看不懂”到“看得懂”二进制时钟的魅力与挑战最近在整理工作室的旧物时翻出了一个多年前用Arduino和LED灯珠搭的“小玩意儿”——一个手工制作的二进制时钟。它静静地躺在角落六个LED排成两列幽幽地闪着光。我把它重新接上电看着那些明灭的光点忽然意识到这可能是最能体现“极客浪漫”和“数字本质”的桌面摆件之一了。它不像普通时钟那样直观需要你在大脑中完成一次小小的二进制解码才能知道现在是几点几分。这个过程本身就是一种乐趣。所谓二进制时钟就是用二进制数来表示时间。我们常见的十进制时间“12:34:56”在二进制时钟上会分解为时、分、秒的每一位数字再转换成二进制并用LED灯的亮1与灭0来显示。比如一个典型的6位LED二进制时钟可能会用3个LED表示小时的十位0-24个LED表示小时的个位0-9以此类推。当你习惯了这种“阅读”方式后看时间就变成了一场与逻辑电路的无声对话。为什么我要选择用手工的方式来制作它而不是直接买一个成品原因有几个。首先完全可控。从电路设计、元件选型到程序编写每一个环节都掌握在自己手中你可以决定它的精度、显示样式是24小时制还是12小时制要不要显示秒、甚至外壳材质。其次极佳的学习项目。它几乎涵盖了电子制作和嵌入式开发的入门核心微控制器编程、数字电路、实时时钟模块通信、LED驱动甚至涉及简单的电源管理。最后独一无二的成就感。当一堆散乱的元件在你的手中被赋予“生命”开始准确地报告时间时那种满足感是购买任何精致商品都无法替代的。这个项目适合谁如果你是电子爱好者、Arduino初学者想找一个有明确目标、成果酷炫且实用的项目来练手二进制时钟几乎是完美的选择。它难度适中既有挑战性又不至于让人望而却步。即使你没有任何编程或焊接基础跟着清晰的步骤也能一步步实现。而对于已经有一定经验的开发者它则是一个优化和创新的平台你可以尝试用更少的元件、更低的功耗或者加入网络对时、光感自动调光等高级功能。接下来我将以最经典的“Arduino Uno DS1307 RTC模块 直插LED”方案为例手把手带你从零开始制作一个走时精准、显示直观的桌面级二进制时钟。我们会深入每一个细节不仅告诉你“怎么做”更会解释“为什么这么做”并分享我在多次制作中积累的那些容易踩坑的经验。2. 核心元件选型为什么是它们而不是别的动手之前理清思路和选对元件同样重要。一个基础的二进制时钟系统可以拆解为四个核心部分大脑控制器、心脏时钟源、眼睛显示单元和骨架电路与电源。每一部分的选择都直接影响到最终作品的稳定性、精度和制作体验。2.1 控制器Arduino Uno稳如老狗的起点在众多微控制器中我首选Arduino Uno。原因很实在生态无敌容错率高。它的ATmega328P芯片性能对于点灯报时绰绰有余16MHz的主频和32KB的Flash内存空间足以容纳复杂的逻辑和库文件。更重要的是其庞大的社区意味着任何你遇到的问题几乎都能找到现成的解决方案或讨论。对于初学者其USB编程方式免去了专用下载器的麻烦直插式封装DIP也让焊接和更换变得异常容易——万一不小心烧了芯片花十几块钱换一颗就是不会“车毁人亡”。为什么不选更小巧的Nano或更强大的ESP32对于纯离线、功能单一的时钟Uno的板载稳压器和丰富的IO口我们最多只需要6-10个IO提供了最“省心”的体验。Nano虽然小巧但需要外接USB-TTL对新手稍显不便ESP32功能强大但功耗和复杂度对简单时钟而言是过剩的。记住一个原则在满足需求的前提下选择最简单、文档最丰富的方案。Arduino Uno就是这个平衡点。2.2 时钟源DS1307经久不衰的经典让Arduino自己计时行不行理论上可以但实际非常糟糕。Arduino内部没有真正的实时时钟RTC其millis()函数基于晶振误差大每天可能误差数秒至数十秒且断电后时间信息会丢失。因此一个专用的RTC模块是精准时钟的绝对必需品。在DS1302、DS1307、DS3231这几个常见RTC芯片中我推荐DS1307。它价格低廉接口简单I2C通信只需两根线精度足够典型误差±2分钟/月且自带56字节的NV SRAM可以用来存储一些用户设置。其配套的电池座通常使用CR2032纽扣电池可以在主电源断开后为芯片提供长达数年的持续计时真正做到“永不停歇”。DS3231精度更高±2分钟/年但价格也贵不少。对于桌面时钟DS1307的精度完全可接受性价比突出。DS1302采用三线SPI接口接线和编程稍复杂。因此DS1307在成本、易用性和精度三者间取得了最佳平衡是入门项目的理想选择。2.3 显示单元LED灯珠直观与成本的权衡显示方案有很多LED数码管、LCD屏、OLED屏甚至LED点阵。但对于二进制时钟直插式发光二极管LED是最原汁原味、也最直观的选择。每一个LED代表一个二进制位亮1灭0物理形态直接对应数字逻辑。选型要点颜色建议选择红色或黄色的LED。这两种颜色在常见的5mm直插LED中亮度高、驱动电压相对较低通常正向压降约1.8-2.2V在相同的限流电阻下比蓝色或白色LED更亮。尺寸5mm是最通用的尺寸容易购买也方便在洞洞板或定制PCB上布局。数量一个完整的“时:分:秒”二进制时钟需要6组LED时十位、时个位、分十位、分个位、秒十位、秒个位。考虑到十进制每位最大为9二进制1001需要4个LED十位最大为2二进制10或5用于分秒十位二进制0101需要2个或3个LED。一个常见的简化设计是显示“时:分”需要2434 13个LED。如果显示秒则再加347个总共20个LED。对于初版我建议先做“时:分”显示13个LED逻辑清晰接线 manageable。驱动方式每个LED需要串联一个限流电阻。电阻值通过公式R (Vcc - Vf) / If计算。其中Vcc是电源电压5VVf是LED正向压降取2VIf是期望的工作电流通常5-20mA取10mA以获得良好亮度且不刺眼。计算得R (5-2)/0.01 300Ω。选择最接近的标准值330Ω即可。电阻功率P I²R 0.01² * 330 0.033W常用的1/4W0.25W电阻绰绰有余。注意切勿将LED直接接到IO口上Arduino Uno的单个IO口最大拉电流/灌电流约为20-40mA不同型号有差异虽然驱动一个LED足够但直接驱动多个或全部LED可能损坏芯片。稳妥的做法是使用晶体管或ULN2003达林顿阵列来驱动尤其是当LED数量较多或采用共阳连接时。不过对于13个LED如果采用共阴极接法所有LED负极接地正极通过电阻接IO口并且通过程序确保同一时刻点亮的LED不超过4-5个那么直接使用IO口驱动在短期内也是可行的但并非最佳实践。我们后续电路设计会采用更规范的方案。2.4 电路与电源稳定高于一切电路连接使用面包板进行原型验证确认所有功能正常。最终制作建议使用**洞洞板万用板**进行焊接这样成品更牢固可靠。布局时尽量让走线清晰电源线和地线尽可能粗壮或使用跳线并联减少压降。电源Arduino Uno可以通过USB口供电5V也可以通过桶形插座输入7-12V直流电。对于长期运行的桌面时钟建议使用9V/12V直流电源适配器通过桶形插座供电。这样既稳定又避免了占用USB口。DS1307模块通常由Arduino的5V引脚供电其备份电池CR2032务必安装。通信协议DS1307使用I2C协议只需连接两根线SDA数据线接Arduino Uno的A4引脚SCL时钟线接A5引脚。同时接上VCC5V和GND。3. 电路设计与焊接实操从原理图到实体理解了核心元件我们就可以着手设计电路了。一个可靠的电路是项目成功的基石。3.1 电路原理图解析我们的系统包含三个主要部分Arduino Uno主控、DS1307 RTC模块、LED显示阵列。它们之间的连接关系如下Arduino与DS1307的I2C连接Arduino Uno A4 (SDA) - DS1307模块 SDAArduino Uno A5 (SCL) - DS1307模块 SCLArduino 5V - DS1307模块 VCCArduino GND - DS1307模块 GNDDS1307模块上的SQW/OUT引脚悬空即可我们不用它输出方波LED显示阵列电路共阴极设计 这是核心部分。我们以显示“小时”的两位为例十位和个位。小时十位最大值为2需要2个LED代表二进制位bit1, bit0。假设我们定义LED_H10_1高位 LED_H10_0低位。小时个位最大值为9需要4个LED代表二进制位bit3, bit2, bit1, bit0。假设LED_H1_3, LED_H1_2, LED_H1_1, LED_H1_0。连接方法共阴极所有13个LED的阴极短脚内部连接较大电极全部连接在一起并最终接到电源地GND。每个LED的阳极长脚各自串联一个330Ω的限流电阻。每个电阻的另一端分别连接到一个Arduino的数字IO引脚如引脚2~引脚12避开0、1串口引脚和A4、A5 I2C引脚。为什么用共阴极因为Arduino的IO口在设置为OUTPUT且写HIGH时其输出电流能力拉电流较弱而写LOW时吸入电流能力灌电流较强。在共阴极接法中当IO口输出HIGH5V时电流从IO口流出经电阻、LED流入GND此时IO口处于“拉电流”状态驱动能力有限。但我们可以通过程序控制让需要点亮的LED对应的IO口输出HIGH。虽然驱动能力稍弱但对于单个LED的10mA电流Arduino的IO口在HIGH状态下的拉电流能力通常是足够的典型值20mA。这种接法布线直观易于理解。重要经验在实际焊接前务必用面包板搭建整个电路并编写一个简单的测试程序例如让所有LED依次点亮。这能提前发现LED极性接反、电阻值错误、引脚定义混淆等问题避免在焊接好的洞洞板上“抓瞎”。3.2 洞洞板布局与焊接技巧确认面包板原型工作正常后就可以转移到洞洞板上进行永久性制作了。布局规划在纸上或直接用元件在洞洞板上模拟布局。原则是功能模块集中走线路径最短电源地线优先。将Arduino Uno的排母如果需要焊接或接口放在板子一侧。DS1307模块可以单独用小洞洞板焊接或者直接使用现成的模块通过排针插在主板旁边。LED的排列至关重要。为了便于“阅读”二进制时间建议将代表同一十进制位的LED排成一列并且高位在下低位在上或反之但必须统一。例如小时个位的4个LED排成一列最下面的代表2^38往上依次是4、2、1。这样当LED亮起时你从下往上加和就能快速得出十进制数。在每组LED旁边预留出焊接330Ω电阻的位置。电源和地线用粗导线或镀锡铜线在板子背面走一条“电源总线”和一条“地线总线”所有需要VCC和GND的点都从这两条总线上就近连接。焊接步骤a. 先焊接最低的元件通常是电阻和IC座如果用了的话。b. 然后焊接LED。注意所有LED的极性方向必须一致一个快速识别5mm LED极性的方法看内部较小的金属片连接的是阳极长脚较大的碗状结构连接的是阴极短脚。也可以在焊接前用万用表的二极管档测试。c. 接着焊接连接线。使用不同颜色的导线区分信号如IO线、电源红色和地黑色。尽量让走线横平竖直在背面焊接。d. 最后安装Arduino和DS1307模块。可以用排母将Arduino Uno像积木一样插在洞洞板上也可以用杜邦线连接。DS1307模块通常自带排针直接插在预留的排母上。e.焊接后检查用万用表的通断档仔细检查所有连接是否正确特别是电源和地之间有没有短路。这是烧毁元件的最大风险点。外壳设计可选但推荐一个美观的外壳能极大提升作品的质感。可以用亚克力板激光切割也可以用现成的塑料盒改造。关键是在面板上为每个LED开孔并做好标记例如在LED旁边刻上或贴上其代表的权值1, 2, 4, 8。确保外壳有开口用于电源线和可能的调校按钮。4. 软件编程让时钟“活”起来硬件是躯体软件是灵魂。我们将编写Arduino程序完成从RTC读取时间、解码为二进制、并控制LED显示的全过程。4.1 开发环境与库准备首先确保你安装了Arduino IDE1.8.x或2.x版本均可。我们需要安装一个关键的库来与DS1307通信RTClib。在Arduino IDE中点击“工具” - “管理库...”在搜索框中输入“RTClib”找到由Adafruit维护的版本进行安装。这个库封装了与DS1307、DS3231等RTC芯片通信的复杂细节让我们用简单的函数就能读写时间。4.2 核心程序逻辑拆解程序主要包含以下几个部分初始化Setup初始化串口用于调试输出时间信息。初始化I2C总线Wire.begin()。初始化RTC对象RTC_DS1307 rtc并检查RTC是否运行。如果第一次使用或电池耗尽可能需要设置初始时间。将所有控制LED的引脚设置为OUTPUT模式并初始化为LOWLED熄灭。主循环Loop从DS1307读取当前时间rtc.now()得到一个DateTime对象。从DateTime对象中提取出小时hour()和分钟minute()。如果需要秒也提取出来。时间解码将十进制的小时和分钟拆分成十位和个位然后分别转换成二进制位。LED控制根据二进制位的值0或1控制对应IO口的输出电平digitalWrite(pin, HIGH/LOW)。延时一段时间例如100毫秒然后重复。不需要延时太久因为LED的亮灭变化频率以秒为单位。4.3 关键代码片段与注释以下是程序的核心部分附有详细注释。#include Wire.h #include RTClib.h RTC_DS1307 rtc; // 创建RTC对象 // 定义LED连接的引脚。这里以13个LED时十位2个时个位4个分十位3个分个位4个为例。 // 引脚顺序从高位到低位。例如小时个位pinH1_3是最高位(8)pinH1_0是最低位(1)。 const int pinH10[] {2, 3}; // 小时十位2个LED (引脚2: 高位, 引脚3: 低位) const int pinH1[] {4, 5, 6, 7}; // 小时个位4个LED (引脚4:8, 5:4, 6:2, 7:1) const int pinM10[] {8, 9, 10}; // 分钟十位3个LED (引脚8:4, 9:2, 10:1) 因为十位最大是5 const int pinM1[] {11, 12, 13, A0}; // 分钟个位4个LED (引脚11:8, 12:4, 13:2, A0:1) 使用了一个模拟口当数字口 void setup() { Serial.begin(9600); Wire.begin(); if (!rtc.begin()) { Serial.println(找不到 RTC 模块); while (1); // 停止执行 } if (!rtc.isrunning()) { Serial.println(RTC 未运行正在设置初始时间...); // 这行代码只在第一次使用或更换电池后运行一次 // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // 设置为编译时间 // 或者手动设置一个时间例如2023年10月27日 12:00:00 // rtc.adjust(DateTime(2023, 10, 27, 12, 0, 0)); } // 初始化所有LED引脚为输出模式并默认熄灭(LOW) int allPins[] {2,3,4,5,6,7,8,9,10,11,12,13,A0}; for (int i 0; i sizeof(allPins)/sizeof(allPins[0]); i) { pinMode(allPins[i], OUTPUT); digitalWrite(allPins[i], LOW); } Serial.println(二进制时钟初始化完成); } void loop() { DateTime now rtc.now(); // 从RTC读取当前时间 int hour now.hour(); // 获取小时 (0-23) int minute now.minute(); // 获取分钟 (0-59) // 为了方便演示我们使用24小时制。如果想用12小时制可以 hour % 12; // 1. 解码小时 int hourTens hour / 10; // 小时十位 (0-2) int hourOnes hour % 10; // 小时个位 (0-9) displayBinary(hourTens, pinH10, sizeof(pinH10)/sizeof(pinH10[0])); displayBinary(hourOnes, pinH1, sizeof(pinH1)/sizeof(pinH1[0])); // 2. 解码分钟 int minuteTens minute / 10; // 分钟十位 (0-5) int minuteOnes minute % 10; // 分钟个位 (0-9) displayBinary(minuteTens, pinM10, sizeof(pinM10)/sizeof(pinM10[0])); displayBinary(minuteOnes, pinM1, sizeof(pinM1)/sizeof(pinM1[0])); // 调试输出可以通过串口监视器查看 Serial.print(时间: ); if(hour10) Serial.print(0); Serial.print(hour); Serial.print(:); if(minute10) Serial.print(0); Serial.println(minute); delay(1000); // 每秒更新一次 } // 核心函数将一个十进制数字用一组LED显示为二进制 // num: 要显示的十进制数 (0-9或0-5) // pins[]: 对应LED的引脚数组从高位到低位 // size: 数组大小即LED数量 void displayBinary(int num, const int pins[], int size) { for (int i 0; i size; i) { // 从最高位开始检查。例如size4, i0检查bit3(8), i1检查bit2(4)... // (num (size - 1 - i)) 1 这个操作是取出num的指定位 int bitValue (num (size - 1 - i)) 1; digitalWrite(pins[i], bitValue ? HIGH : LOW); // 如果该位是1则点亮LED(HIGH) } }代码关键点解析displayBinary函数是核心。它利用位操作来高效地获取一个数字的各个二进制位。(num (size - 1 - i)) 1这句代码的意思是将数字num右移(size-1-i)位然后与1进行按位与操作结果就是第i个LED对应的二进制位值0或1。这种方法比用if语句或数组查表更简洁高效。引脚定义数组pinH10,pinH1等其元素顺序必须与二进制权值从高到低对应。这是正确显示的关键。rtc.adjust()函数用于设置时间务必注意这段代码上传并运行一次将时间设置正确后就应该将其注释掉。否则每次重启时钟都会被重置为编译时间或你设定的固定时间。串口输出主要用于调试在实际使用时可以去掉以节省资源。4.4 程序上传与调试将代码上传到Arduino Uno。打开串口监视器波特率设置为9600你应该能看到当前时间打印出来。同时观察LED的亮灭模式。你可以手动计算一下当前时间比如“13:45”然后对照LED检查小时十位1 (二进制01) - 对应的两个LED应该是低位亮高位灭。小时个位3 (二进制0011) - 对应的四个LED应该是最低两位亮高两位灭。分钟十位4 (二进制100) - 对应的三个LED应该是最高位亮后两位灭。分钟个位5 (二进制0101) - 对应的四个LED应该是第1位和第3位亮从低位算起代表1和4。如果显示不正确首先检查串口输出时间是否正确。如果不正确可能是DS1307通信问题接线错误、地址冲突、库未安装。如果时间正确但LED显示错误则检查displayBinary函数中的位操作逻辑以及引脚定义数组的顺序是否与物理LED的权值顺序一致。5. 功能优化与进阶玩法一个能走时的基础二进制时钟已经完成。但作为DIY项目它的乐趣远不止于此。这里分享几个优化和进阶方向让你的时钟变得更智能、更个性。5.1 精度校准与时间设置DS1307的精度受温度影响可能每月有几分钟误差。我们需要一个方法来校准和设置时间。软件校准推荐DS1307芯片内部有一个频率调整寄存器。通过向该寄存器写入一个校准值可以微调晶振的振荡频率补偿误差。这需要你首先用高精度时钟源如手机网络时间、GPS对比你的时钟计算出日误差秒数然后通过公式转换为校准值写入。RTClib库通常提供相关函数。这是一个一次性的精细调整。硬件校准如果误差较大且规律可能是晶振本身精度不够。可以尝试更换一个更高精度的晶振如12.5ppm的。便捷时间设置我们不可能每次都修改代码来调时间。可以增加三个按钮设置、加、减。通过按钮进入设置模式依次调整时、分然后保存。这需要修改程序加入状态机和按钮消抖处理。按钮可以连接到Arduino的剩余数字引脚并启用内部上拉电阻。5.2 显示效果优化亮度调节长时间观看LED可能太刺眼。可以加入一个光敏电阻或旋转电位器通过模拟输入读取环境光强度或用户设定使用analogWrite()函数在支持PWM的引脚上输出PWM信号来控制LED亮度注意普通数字引脚只能输出HIGH/LOW需改用PWM引脚如3,5,6,9,10,11并配合三极管进行驱动。更简单的方法是在digitalWrite点亮LED后用一个极短的delayMicroseconds来控制占空比实现软件PWM但会占用CPU时间。显示模式切换增加一个按钮可以在“时分”、“分秒”、“时分秒循环”等不同显示模式间切换。整点报时/动画在检测到分钟和秒都为0时让所有LED闪烁几次或者跑一个流水灯动画增加趣味性。5.3 电源管理与低功耗设计如果你希望时钟能用电池供电运行更久低功耗设计就很重要。Arduino睡眠使用LowPower库让Arduino在两次更新显示之间进入深度睡眠SLEEP_MODE_PWR_DOWN。DS1307由备份电池供电持续计时。Arduino每秒被唤醒一次读取时间、更新显示然后继续睡眠。这可以将整体电流从几十mA降低到几个mA甚至更低。LED驱动优化采用扫描显示而非静态显示。即使显示“13:45”也不是所有13个LED都常亮。可以快速循环点亮每一组LED例如先显示小时几毫秒后显示分钟利用人眼的视觉暂留效应看起来像是同时亮的。这能显著降低平均电流。但编程会复杂一些需要用到定时器中断来保证扫描频率稳定。降压方案如果使用9V电池Arduino Uno的线性稳压器效率不高。可以考虑使用更高效的DC-DC降压模块如MP2307将电压降至5V直接给系统和LED供电。5.4 升级与变体控制器升级尝试用ATTiny85等更小的8引脚单片机来驱动制作一个超迷你的版本。这需要更精简的代码和更深入的寄存器操作知识。显示介质升级用WS2812BNeoPixel灯带或矩阵来制作。每个像素点可独立控制RGB颜色你可以用不同颜色代表不同的时间单位时、分、秒或者创造出更炫酷的动画效果。但需要学习对应的FastLED或Adafruit NeoPixel库。网络对时加入ESP8266或ESP32模块连接Wi-Fi通过NTP协议从互联网获取精确时间自动校准DS1307。这使你的时钟具备了“永远准确”的能力。外壳与美学设计一个极简主义的木质或金属外壳将LED的排列艺术化。例如做成一个圆形或矩阵用光导纤维将LED光线引到面板上形成更柔和的光点。6. 常见问题排查与维护心得即使按照步骤操作也难免会遇到问题。这里汇总了一些我踩过的坑和解决方案。6.1 LED完全不亮或部分不亮检查电源用万用表测量Arduino的5V和GND之间是否有5V电压。测量LED两端的电压点亮时应在2V左右。检查极性这是最常见的问题确认所有LED的方向一致长脚阳极通过电阻接IO口短脚阴极接地。检查电阻确认限流电阻已正确串联阻值是否为330Ω。可以用万用表测量。检查程序确认控制该LED的引脚在程序中被正确定义为OUTPUT并且在应该点亮的时候输出了HIGH。可以用串口打印出digitalRead(该引脚)的值来验证。检查焊接仔细检查LED引脚、电阻引脚与洞洞板焊盘之间的连接是否牢固有无虚焊或冷焊。6.2 时间显示错误或DS1307不工作I2C接线错误确认SDA接A4SCL接A5。线序接反会导致通信失败。上拉电阻DS1307模块通常已集成4.7kΩ的上拉电阻。如果没有需要在SDA和SCL线上各接一个4.7kΩ电阻到5V。电池没电如果主电源断开后时间丢失首先检查CR2032电池是否有电电压应高于3V。库冲突或版本问题确保安装的是正确的RTClib库。有时多个时间库可能冲突。尝试在代码最前面显式包含#include。地址冲突DS1307的I2C地址是0x68。确保总线上没有其他设备占用同一地址。可以用I2C扫描程序检查。6.3 时钟走时不准首次设置问题确认rtc.adjust()只在第一次设置时运行了一次之后已被注释掉。晶振精度DS1307使用的32.768kHz晶振本身有一定误差。这是导致长期误差的主要原因需要进行软件校准。电源干扰不稳定的电源可能会影响晶振。尝试用电池供电测试或者给电源增加滤波电容。温度影响DS1307对温度敏感。尽量将其放置在温度稳定的环境中。6.4 程序运行不稳定或复位电源不足如果LED全部点亮时电流较大可能导致Arduino的5V稳压器过载引起电压跌落和复位。确保你的电源适配器能提供足够的电流建议1A以上。对于共阴极接法同时点亮的LED数量越多总电流越大。代码逻辑错误检查是否有数组越界、死循环等问题。确保loop()函数不会因为某个操作而阻塞太久。看门狗复位如果启用了看门狗且未及时喂狗会导致复位。我们的简单程序一般不会启用看门狗。制作这样一个二进制时钟从理解原理、选购元件、焊接电路到调试程序整个过程就像完成一次微型的系统工程。它带给你的不仅仅是一个能看时间的摆设更是一段关于数字逻辑、嵌入式系统和动手创造的深刻记忆。当你在深夜看着那些由自己亲手赋予规律的明灭光点静静诉说着流逝的时光时那种连接抽象与具象的奇妙感觉或许就是DIY最大的乐趣所在。