DIY光致变色与夜光时钟:用UV LED阵列驱动智能材料显示时间 1. 项目概述与核心思路几年前我在一个创客社区看到了Tucker Shannon的夜光绘图时钟那个用机械臂在夜光屏上“画”出时间的概念让我眼前一亮。但作为一个对显示效果有点“强迫症”的物理爱好者和电子DIYer我总觉得那个机械结构画出来的数字有点歪斜不够规整。于是一个念头冒了出来能不能用更直接、更“电子”的方式来实现这种光与材料交互的魔法效果我首先想到的是光致变色材料。这种材料在紫外线照射下会变色光照消失后又慢慢恢复原理是分子结构发生了可逆的光异构化反应。而夜光材料更准确说是磷光材料则是吸收光能后电子跃迁到激发态再缓慢地跃迁回基态并释放出可见光。这两种材料对紫外光UV都特别敏感。那么如果我们用UV LED作为“笔”去“书写”在由这些材料制成的“画布”上不就能实现一个干净、整齐的数字显示了吗这个DIY光致变色与夜光时钟的核心思路就是构建一个自定义的4位7段数码管显示模块但它的“发光”单元不是我们常见的红色或蓝色LED而是人眼几乎看不见的紫外LED波长约400nm。在这个UV LED阵列的前方放置一块由光致变色或夜光材料制成的屏幕。平时屏幕是透明或微微发光的。当你按下按钮UV LED阵列点亮几秒钟紫外线“激活”了屏幕材料——光致变色屏瞬间变色夜光屏则被“充能”开始发光从而清晰地显示出当前时间。随后UV LED熄灭屏幕上的数字会随着材料的特性慢慢褪色或暗去整个过程充满了动态的科技美感。这个项目非常适合对电子制作、材料科学和微控制器编程感兴趣的爱好者。它不仅仅是一个时钟更是一个探索光与物质相互作用的小型实验平台。接下来我将从材料原理、电路设计、组装调试到经验优化完整拆解这个项目的每一个细节。2. 核心材料与工作原理深度解析2.1 光敏材料光致变色与夜光的科学要玩转这个项目首先得理解你手中的“画布”是如何工作的。这直接决定了最终的显示效果和体验。光致变色材料我使用的是紫色的UV变色线材进行3D打印。它的核心是含有光致变色染料的塑料。在自然光下它呈紫色或淡色。当受到特定波长通常是UVA波长315-400nm的紫外线照射时染料分子吸收光子能量化学结构如键的旋转或异构化发生改变导致其吸收可见光的波段发生变化从而在我们眼中呈现出另一种颜色比如从紫色变为深蓝色或无色。一旦移开紫外光源分子会通过热弛豫过程缓慢地恢复到初始结构颜色也随之褪去。这个“记忆-恢复”的循环是可逆的但恢复速度受环境温度影响很大。夜光磷光材料我选用的是成品的夜光贴纸。这类材料通常掺杂了稀土元素或碱土铝酸盐。其原理是材料中的发光中心激活剂离子吸收紫外或可见光能量后电子被激发到高能级。大部分电子会直接跃迁回低能级并发光荧光但有一部分电子会落入所谓的“陷阱”能级由材料中的缺陷或共激活剂造成。这些被“困住”的电子需要吸收额外的热能才能逃逸出来再跃迁回基态并发光这个过程可以持续数分钟甚至数小时这就是我们看到的“余辉”。夜光材料的亮度和余辉时间取决于其化学成分和制备工艺。注意市面上常见的“夜光”产品很多是短余辉的荧光材料或混合了放射性物质的长效夜光材料现已少见。对于本项目选择无毒、无放射性的铝酸盐系夜光粉或成品贴纸即可余辉时间在10-30分钟的比较理想。为什么选择UV LED因为这两种材料对紫外波段的光子吸收效率最高。我们使用的5mm UV LED峰值波长一般在395-400nm处于UVA波段对人体相对安全但仍需避免直视同时能高效激发材料。相比用可见光LED背光透过LCD的方案我试过亮度损失极大直接用UV LED“正面照射”屏幕能量利用率要高得多。2.2 电子核心从时间获取到显示驱动一个时钟准确的时间是灵魂。我选择了DS3231实时时钟RTC模块。它比Arduino自带的软件时钟或DS1307等模块要精准得多内部集成了温度补偿晶体振荡器TCXO年误差可以控制在±2分钟内完全免调校。这是保证时钟“可用”而非“玩具”的关键。显示驱动方面我巧妙地“借用”了一个现成的TM1637 4位数码管模块。我们需要的不是它上面的红色数码管而是它集成好的驱动芯片和I2C背板。TM1637芯片能非常方便地通过两根线CLK, DIO接收微控制器的指令驱动多达8段×6位的LED。我们的目标就是用自己的UV LED阵列完全模拟这个4位7段数码管的电气连接从而让TM1637芯片以为它在驱动普通的数码管实则驱动了我们的UV LED阵列。主控选择了经典的Arduino Nano体积小巧引脚和性能足够。为了给UV LED阵列提供足够的驱动电压和电流我增加了一个MT3608升压模块。因为TM1637背板的LED驱动端口输出电压约比其VCC引脚低2V。如果我们希望UV LED尽可能亮就需要提高VCC。将Arduino的5V升压至7V输入给TM1637背板那么驱动引脚就能输出约5V给UV LED高于其典型工作电压3-3.4V在短时间脉冲工作下可以承受从而获得更高亮度。3. 硬件制作全流程与实操要点3.1 结构件制备3D打印的细节外壳和内部结构件通过3D打印完成这是项目美观和成功组装的基础。模型准备与打印需要打印四个核心部件。housing_front.stl和housing_back.stl时钟的外壳使用黑色PLA打印不透光能避免UV光泄漏也让外观更整洁。4digits.stl这是显示数字的“模板”或“遮罩板”。它定义了4位数字7段数码管的形状。使用白色PLA打印白色可以很好地反射和漫射从后面来的UV光让每个段之间的界限更清晰。screen.stl这是直接面对用户的屏幕。我使用紫色的光致变色PLA线材打印。打印层高建议设置在0.15-0.2mm以获得更光滑的表面减少光散射。soldering_jig.stl焊接辅助治具任何材料均可。打印后处理对于4digits.stl这个遮罩板打印完成后需要清理每个“段”内部的支撑和毛刺确保每个数字的7个段都是清晰、独立的空洞。光致变色屏幕打印后可以用细砂纸如800-1000目沾水轻轻打磨表面使其更加透光和平整。3.2 核心显示单元UV LED阵列的打造这是整个项目最耗时但也最核心的步骤目的是手工制作一个能被TM1637驱动的4位7段UV LED阵列。拆解与准备拿到一个普通的TM1637 4位数码管模块用吸锡器和电烙铁小心地将原有的红色7段数码管从绿色的I2C背板上拆焊下来。清理焊盘保留完好的背板。这个背板就是我们未来的“大脑”。定位与焊接裁切一小块万用板洞洞板大小要能覆盖原先数码管的位置并略大。将打印好的soldering_jig.stl治具放在洞洞板上治具上的孔位对应了每一位数字的每一个段共4位×7段28个点。用笔透过治具的孔在洞洞板上做好标记。在每个标记位置焊接一颗5mm的UV LED。这里有一个至关重要的细节所有LED的极性必须一致通常5mm LED长脚是阳极短脚是阴极-。我统一将阳极长脚插入标记的孔中并朝同一个方向弯曲例如全部向右弯以便后续串联。用治具辅助可以保证所有LED高度一致。在洞洞板的底部边缘焊接一排单排排针公头这排针脚的位置和间距需要与TM1637背板上原先连接数码管的焊盘位置严格对应。这排排针将作为我们自制显示模块与背板连接的接口。复杂的连线这是最考验耐心和逻辑的一步。我们需要用导线按照标准7段数码管的内部连接方式将28个UV LED连接起来并引到那排排针上。共阴连接TM1637驱动通常是共阴模式。这意味着对于每一位数字4位其7个段的阴极LED短脚是连接在一起的称为“位选”而每个段的阳极LED长脚则与所有数字的同一段连接在一起称为“段选”。具体操作段选线Segment Lines将每一位数字的“A段”的所有LED阳极长脚用导线连接起来这汇总成一条“A段”总线。同理完成B、C、D、E、F、G、DP小数点段的连接。这样我们就得到了8条“段选”总线。位选线Digit Lines将第1位数字的7个段A-G的阴极短脚用导线连接在一起这汇总成“位选1”线。同理完成第2、3、4位数字的阴极连接得到4条“位选”总线。最终这8条段选线和4条位选线需要正确地连接到我们之前焊接在洞洞板底部的那排排针上。排针的引脚定义必须与TM1637背板原焊盘的引脚定义完全匹配。务必在焊接前用万用表的导通档反复核对确保没有短路或错接。我当初因为线太多而接错了两根调试花了很久。集成与测试将焊接好排针的自制UV LED阵列像插接件一样插入TM1637背板原来安装数码管的位置确保引脚对应正确。使用杜邦线将TM1637背板的VCC、GND、CLK、DIO连接到Arduino Nano的对应引脚VCC先接5V测试。在Arduino IDE中安装TM1637库上传一个简单的测试程序例如库中自带的示例程序让显示输出“1234”。如果连接正确你应该能看到特定的UV LED段被点亮由于UV光肉眼不易见可以在黑暗环境中观察LED微弱的紫光或者用一张白纸放在上方看是否激发荧光更专业点可以用手机摄像头观察很多手机CMOS对UV敏感。测试成功后将4digits.stl遮罩板用热熔胶固定在UV LED阵列的正上方确保每个数字的段与LED的段对齐。光线处理为了让显示效果更均匀避免看到一个个孤立的LED光点需要对LED发出的光进行漫射。我的方法是在4digits.stl遮罩板的每个“段”的凹槽里填入透明的热熔胶。热熔胶凝固后形成一层漫射体能将点光源变成面光源。填充后可以用透明胶带如聚酰亚胺胶带暂时封住正面防止胶溢出待其完全冷却硬化后再撕掉。3.3 屏幕选择与处理光致变色 vs. 夜光最初我尝试用夜光PLA线材3D打印屏幕但发现打印层纹会导致严重的漫反射显示的数字边缘模糊对比度很差。因此我最终为两种材料选择了不同方案光致变色屏幕直接使用光致变色PLA打印的screen.stl。这种材料本身透光性尚可紫外线能有效穿透并激发表层材料变色。打印时尽量保证表面平整。夜光屏幕放弃3D打印改用“夜光贴纸透明亚克力板”的方案。购买一张厚度约1mm的夜光贴纸裁剪成屏幕大小粘贴在一块同样大小的透明亚克力板或塑料板我用的就是普通的透明文件夹塑料片上。塑料板对400nm紫外线的透过率很高能保证UV光高效地激发背面的夜光贴纸。这个方案获得的显示效果更锐利、亮度更高。两种屏幕可以做成可拆卸的通过卡槽或磁吸的方式固定在时钟外壳前端方便根据日夜环境切换。3.4 电路总装与安全修改DS3231的安全设置这是一个非常重要的实操心得。很多便宜的DS3231模块为了给可充电的纽扣电池充电设计了一个充电电路。但模块通常配送的是不可充电的CR2032电池。如果直接使用VCC引脚会持续向电池施加电压可能导致电池发热、漏液甚至损坏。务必在接入电路前修改这个模块。找到模块背面的一个贴片二极管或一个零欧姆电阻通常标记为“CHG”或位于电池座附近用电烙铁将其拆掉。这样就断开了充电回路。修改后再用一个全新的CR2032电池为模块断电时保持计时。整体连接将Arduino Nano、DS3231 RTC模块、TM1637背板连着我们的UV LED阵列、MT3608升压模块、轻触开关全部用热熔胶或螺丝固定在3D打印的外壳底座housing_back.stl内。按照电路图进行连线Arduino 5V - MT3608输入IN Arduino GND - MT3608输入IN-。MT3608输出OUT (调节至7V) - TM1637背板VCC MT3608输出OUT- - TM1637背板GND。TM1637背板CLK - Arduino D2 TM1637背板DIO - Arduino D3。DS3231模块的VCC - Arduino 5V GND - Arduino GND SDA - Arduino A4 SCL - Arduino A5。轻触开关一端接Arduino D4另一端接GND设置为上拉输入按下为低电平。电源整个系统可以通过Arduino Nano的USB口供电或者在外壳上开孔安装一个DC插座连接5V-12V的电源适配器。4. 软件编程与功能实现代码逻辑清晰主要实现读取时间和按钮控制显示。库准备在Arduino IDE中需要安装三个库TM1637用于驱动显示、DS3231或RTClib用于读取RTC、WireI2C通信通常已内置。设置时间首次使用需要将当前时间写入DS3231。可以上传一个简单的设置程序如DS1307RTC库中的SetTime示例编译上传后打开串口监视器按照提示操作即可。设置一次后即使断电时间也会由纽扣电池维持。主程序逻辑初始化在setup()函数中初始化串口用于调试、初始化TM1637显示对象、初始化DS3231并将按钮引脚设置为上拉输入模式。主循环每秒从DS3231读取一次当前时间时、分。检查按钮引脚状态。如果检测到按钮被按下低电平则设置一个“显示激活”标志并记录按下时刻。如果“显示激活”标志为真则调用TM1637的显示函数将时间时、分显示出来。此时UV LED阵列会根据显示的数字点亮对应的段紫外线照射屏幕。同时开始计时。我设定的是点亮5秒。5秒后将“显示激活”标志置为假并调用TM1637的关闭显示函数或显示全灭。此时UV LED全部熄灭。如果“显示激活”标志为假则保持显示关闭状态。屏幕上的数字会随着材料特性逐渐消失。// 示例代码核心逻辑片段 #include TM1637Display.h #include DS3231.h DS3231 rtc; TM1637Display display(CLK_PIN, DIO_PIN); const int buttonPin 4; bool displayActive false; unsigned long displayStartTime 0; const unsigned long displayDuration 5000; // 显示5秒 void setup() { Serial.begin(9600); rtc.begin(); display.setBrightness(7); // 设置亮度0-7 pinMode(buttonPin, INPUT_PULLUP); } void loop() { DateTime now rtc.now(); int hour now.hour(); int minute now.minute(); // 检测按钮按下 if (digitalRead(buttonPin) LOW) { displayActive true; displayStartTime millis(); delay(50); // 简单防抖 } // 控制显示 if (displayActive) { // 显示时间例如“12:34” display.showNumberDecEx(hour*100 minute, 0b01000000, true); // 中间冒号点亮 // 检查是否超时 if (millis() - displayStartTime displayDuration) { displayActive false; display.clear(); // 关闭显示 } } else { // 非激活状态可让屏幕完全“休息” // display.clear(); // 如果之前已clear这里可不操作 } delay(100); // 主循环延迟 }5. 调试优化与进阶玩法5.1 效果优化与问题排查问题显示亮度不足或不均匀。排查首先在黑暗环境下直接用手机摄像头观察UV LED阵列检查是否所有段都能正常点亮有无损坏LED或虚焊。然后检查MT3608升压模块输出电压是否稳定在7V左右注意测量TM1637背板的VCC和GND。优化电压微调适当调高MT3608输出电压至7.2V或7.5V但不要超过UV LED的极限值可以增加亮度。务必在LED点亮时测量实际加载在LED两端的电压确保不超过其最大正向电压通常5mm UV LED在3.6V左右太多否则会大幅缩短寿命。我们的设计是依靠TM1637芯片内部的恒流或限流电阻来保护LED。漫射材料热熔胶的漫射效果可能不够理想。可以尝试使用专用的光扩散剂混合环氧树脂灌封效果会更均匀像磨砂玻璃一样。LED选型尝试寻找发光强度mcd值更高的UV LED或者使用贴片式SMD的UV LED如3535或5050封装它们的光效和均匀性可能更好。问题光致变色屏幕响应慢或褪色太快。分析这主要取决于材料本身和环境温度。温度越高褪色越快。优化尝试不同品牌的光致变色线材。有些材料的变色对比度更高褪色速度更慢。也可以尝试增加UV LED的照射功率在安全范围内或照射时间。问题夜光屏幕余辉时间短。优化选择更高质量的铝酸盐长效夜光贴纸。或者在制作屏幕时将夜光粉与透明环氧树脂混合均匀涂布在透明基板上自制一个夜光层可以控制厚度和粉的浓度。5.2 进阶改进思路专业PCB设计手工连线确实繁琐且容易出错。下一步可以设计一块专用的PCB。将28个贴片UV LED如3535封装直接布局成4位7段数码管的样式并做好段选和位选的走线最后留出一个与TM1637背板兼容的接口。这样制作出来的显示模块会精致、可靠得多。自动亮度/模式切换可以增加一个光敏电阻或环境光传感器。当环境光暗时自动切换到夜光屏模式并且可以调整UV LED点亮的持续时间或亮度环境光亮时则使用光致变色屏模式。低功耗优化目前即使不显示Arduino和DS3231也在持续工作。可以修改代码让Arduino大部分时间进入深度睡眠Sleep模式仅通过按钮中断唤醒唤醒后点亮显示结束后再次进入睡眠。这样可以实现用电池长期供电。混合材料屏幕尝试将光致变色材料和夜光粉以一定比例混合制作一种“智能”屏幕它在紫外照射下立即变色同时储存光能在紫外关闭后还能持续夜光一段时间。这个项目最吸引我的地方在于它将电子编程、材料科学和手工制作以一种有趣的方式结合了起来。每一次按下按钮看到时间以这种充满物理感的方式浮现又消逝都是一种独特的体验。它不仅仅告诉你时间更向你展示了一段光与物质相互作用的微小篇章。从最初的想法到中间焊接连线的抓狂再到最后调试成功的喜悦整个过程充满了DIY的乐趣。如果你也对这种跨界的创意项目感兴趣不妨动手试一试或许你能做出比我这个原型更酷的版本。