1. 项目概述与核心思路我一直对全息技术着迷它不仅仅是科幻电影里的炫酷特效更是一门严谨的光学工程。市面上的“伪全息”方案比如佩珀尔幻象或者基于视觉暂留的旋转LED虽然效果不错但总感觉少了点“真东西”的灵魂。所以当决定动手做一个全息时钟时我的目标很明确做一个基于真实透射全息图的、能显示数字的玩意儿让每个数字段都像真的悬浮在空中一样。这个项目的核心是把传统的7段数码管显示用全息技术重新“翻译”一遍。传统数码管是物理发光而这里每个数字段a到g都是一个独立的透射全息图。这些全息图被记录在特殊的感光板上当用特定角度的白光LED从背后照射时就能再现出记录时“物体”一个发光的灯罩薄膜的光场看起来就像光从板子后面凭空“长”了出来。整个系统的大脑是一块ESP32开发板它负责从网络获取精确时间并控制28个LED4位数每段1个的亮灭从而驱动这些全息“像素”显示出当前的时分。听起来复杂但拆解开来无非是光学、机械、电子和固件四个部分的精密耦合。光学部分负责“造像”机械结构负责“固定”电子部分负责“驱动”固件负责“指挥”。下面我就把这几个月从原理摸索到实践落地的全过程包括踩过的坑和总结的经验毫无保留地分享出来。2. 全息原理与Litiholo套件初探2.1 透射全息图的核心原理在动手之前必须搞清楚我们到底在做什么。全息术Holography的本质是记录并再现物体的完整光波前包括振幅和相位信息。这不同于普通照相后者只记录强度振幅。我们制作的是透射全息图。其基本原理分为两步记录和再现。记录过程需要两束相干的激光通常来自同一激光器。一束叫物光它照射到物体上经物体反射或透射后携带着物体的信息到达全息干板。另一束叫参考光它直接照射到干板上。这两束光在干板处相遇发生干涉形成极其精细的、明暗相间的干涉条纹图案。这个图案被干板上的感光材料记录了下来。它记录的不仅是光的强弱更是两束光相遇时的相位差这个相位差编码了物体的三维信息。再现过程用一束与参考光相同波长和角度的光称为再现光照射制作好的全息图。全息图上记录的干涉条纹相当于一个复杂的光栅当再现光通过时会发生衍射。其中一级衍射光波前恰好与当初的物光波前一模一样。当我们的眼睛接收到这个重建的波前时就会“看到”原来物体所在的位置有一个立体的虚像仿佛物体就在那里。在这个时钟项目中我们的“物体”是一个被均匀照亮的、特定形状7段数码管的段形状的漫射体灯罩薄膜。我们记录下它的光波前。再现时我们用普通的白光LED去照射全息图由于LED光谱较宽我们看到的再现像会带有彩虹色这正是白光再现透射全息图的特征之一。注意全息记录对稳定性要求极高。任何微小的振动甚至声波导致光路变化超过半个波长对于红光约316纳米干涉条纹就会模糊记录就会失败。这就是为什么实验常在深夜、光学平台上进行。2.2 Litiholo套件实战与避坑指南对于没有光学实验背景的爱好者Litiholo的套件是一个绝佳的入门选择。它把复杂的激光器、光学元件和化学药水都打包好了让你能专注于体验全息记录的过程。我拿到套件后严格按照说明书做了第一次测试。套件里包含一个玩具小车作为物体。过程大致是在暗室环境套件配了暗袋将激光器和干板架设好保持绝对安静和静止约几分钟进行曝光然后用配套的药水进行显影、定影。第一次尝试就成功了这让我有点意外。因为套件里的激光器只是个简单的二极管激光用金属弹簧散热支架也是亚克力激光切割的非常“业余”。但这恰恰证明在严格控制振动和环境光的前提下入门级设备也能做出真正的全息图。关键操作心得预热激光器即使是这种简易激光器开机后亮度也会有一个短暂的稳定过程。我的习惯是提前打开至少5-10分钟再进行光路调整和曝光。绝对黑暗任何杂散光都是敌人。确保暗袋拉链完全闭合或者在一个真正的暗房里操作。曝光过程中连手机屏幕的光都不能有。“一动不如一静”调整好光路、放好干板后最好的姿势就是保持不动甚至屏住呼吸几秒钟直到曝光完成。地面震动是最大的威胁远离走动的人和马路。药水温度显影和定影药水对温度敏感。室温20-25°C下操作效果最好。太冷反应慢太热可能使药水失效或损伤乳剂。这次成功给了我极大的信心但也让我意识到套件的局限性它的支架是为标准物体设计的无法方便地录制我们需要的、多个特定形状且位置精确的“段”。因此自定义光路和机械结构势在必行。3. 定制化全息记录系统搭建3.1 光路设计与机械结构为了录制7段数码管形状的全息图我需要一个可重复、可精确定位的光学系统。套件的水平布局不适合我设计了一个垂直光路。整个系统核心是一个3D打印的黑色支架。激光器从底部以45度角向上照射。在光路中自上而下依次是全息干板感光面朝下面向激光。物体玻璃板位于干板正下方上面贴有切成段形状的白色自粘灯罩薄膜。这层薄膜的作用是作为一个理想的漫射体将激光均匀地散射开照亮整个“段”的形状。激光束从下方45度角入射同时照亮干板和物体。为什么选择垂直布局和45度角垂直布局使得放置和更换干板、物体板更加方便也更容易实现旋转。45度角是透射全息中一个常见的参考光角度能在记录效率和再现像亮度之间取得较好的平衡。更重要的是后续用LED再现时我们也需要从类似的角度照射垂直布局为LED的安装提供了天然的空间。机械设计要点材料全部使用哑光黑色PLA打印。黑色是为了最大限度地吸收杂散光防止其在内部反射形成噪声哑光表面进一步防止镜面反射。稳定性结构件设计得足够厚重连接处采用卡扣和螺丝双重固定确保在长时间曝光中不会因自身应力产生形变或晃动。旋转机构干板架和物体板架必须能作为一个整体在水平面内进行精确的旋转。我设计了带刻度的旋转盘每次旋转51.4度360/7以确保7个段能均匀地记录在一张干板上。旋转的中心必须与光路中心对齐否则再现时各段的位置会错乱。3.2 分段记录流程与实战细节一张全息干板上要记录7个独立的段这需要用到空间复用技术。简单说就是每次只让干板的一小部分感光记录一个段其他部分用遮光板光圈挡住。详细记录步骤一次深呼吸般的操作激光预热打开激光器稳定至少5分钟。预对齐在不放入干板的情况下打开室内微弱的蓝光LED全息干板对蓝光不敏感调整激光光斑确保它能均匀覆盖物体板上的“段”形状区域。黑暗准备关闭所有灯只留那盏对着墙的微弱蓝光。用黑色卡纸挡住激光束。放置干板在暗袋或全黑环境下取出全新的全息干板注意不要触碰感光面以正确方向放入支架。干板有玻璃的一面通常朝外背对激光感光乳剂面朝内对着物体。绝对黑暗关闭蓝光LED。此时应伸手不见五指。开始曝光迅速而平稳地移开遮挡激光的卡纸。开始计时我的设置是5分钟。这5分钟内你必须像雕塑一样保持静止。任何咳嗽、脚步声都可能导致前功尽弃。结束曝光时间到迅速用卡纸挡回激光束。打开蓝光LED。旋转准备按照预定顺序例如从段“a”开始将干板架和物体板架整体旋转到下一个位置。调整光圈只让下一个“段”对应的干板区域暴露。重复重复步骤5-8直到7个段全部记录完毕。化学处理将曝光后的干板在完全黑暗中取出立即进行显影、漂白、定影、水洗和干燥。Litiholo的套件药水是一步到位的简化了流程。核心难点与技巧振动隔离我选择在凌晨后操作并将整个装置放在厚重的花岗岩板上石板下垫了海绵。这能有效隔离大部分建筑和环境振动。激光稳定性我后来换用了工作用的单频红色激光二极管并加了恒流驱动和更大的散热片光强和波长稳定性远好于套件激光器。但对于套件激光确保供电电压稳定是关键。光圈制作我用黑色卡纸手工切割了精确的开口。更优的方案是使用光阑但卡纸成本低易于调整。关键是边缘要整齐不能有毛边衍射。4. 时钟的机械与电子系统实现4.1 结构设计与3D打印时钟的外壳和内部支架全部由哑光黑色PLA通过FDM 3D打印机完成。设计上分为左右两个完全对称的“半钟”每个半钟容纳两位数字。这样设计便于打印、组装和维修。主要结构部件底座板承载所有其他部件的基板。两个半钟的底座板通过燕尾榫结构咬合无需螺丝即可牢固连接且保证了拼接的精度。全息板支架用于固定四片录制好的全息干板。设计有卡槽确保干板以精确的角度和位置插入这是再现像能否对齐的关键。LED支架/PCB背板用于安装定制PCB和LED。每个数字对应一块背板上面有精确的孔位确保28个LED的每一个都能对准其对应的全息“段”的中心。背板通过卡扣和螺丝固定在底座上。顶盖覆盖住ESP32主控板和驱动板起保护和美观作用。冒号支架位于两半钟中间用于安装两个作为时间分隔冒号“:”的LED。这个部件我用双色打印完成主体黑色光导部分使用透明PLA让光更柔和。打印与后处理经验层高与填充使用0.15mm层高以获得更光滑的表面尤其是与全息板接触的斜面。填充率25%足够保证强度同时节省材料和时间。防止翘曲打印大面积底板时一定要使用热床并确保粘贴牢固我用的美纹纸胶带加胶水否则边缘翘曲会导致整个结构不平。哑光黑的选择普通的黑色PLA打印出来也有光泽会反射杂散光干扰全息像。务必选择真正的哑光Matte黑色PLA或者对成品进行哑光喷漆处理。4.2 定制PCB设计与LED驱动逻辑用28根飞线去控制28个LED是一场噩梦不仅混乱而且可靠性极差。设计定制PCB是让项目从“实验原型”走向“成品”的关键一步。PCB设计思路 我的目标是复现商用4位7段数码管的电气连接方式这样就能直接使用现成的驱动芯片和库。商用数码管内部采用动态扫描多路复用来减少引脚使用。对于共阴极数码管所有段的阴极连接在一起位选而每个段的阳极是独立的。我将这个逻辑移植到PCB上每块PCB对应一个数字位上面焊接7个LED对应a-g段。这7个LED的阴极负极全部连接在一起引出一个“位选”引脚。每个LED的阳极正极单独引出连接到“段选”引脚。PCB边缘设计成排母接口这样两块PCB可以像积木一样堆叠插接位选和段选信号通过排针/排母自动级联完全省去了连接两个数字位之间的导线。设计踩坑实录 第一版PCB犯了一个低级错误我把LED的封装画反了导致LED安装后极性颠倒。无奈之下只能用刀在PCB上割线再用飞线修补非常狼狈。教训在投板生产前务必用实物LED在打印出来的1:1图纸上比对或者使用EDA软件的3D预览功能反复检查封装方向。4.3 主控与驱动电路集成主控选择了Adafruit的Feather ESP32 V2。选择它有三个原因1) 体积小巧集成度高2) ESP32自带Wi-Fi便于实现NTP网络授时3) Adafruit为其提供了完美的配套组件——4-Digit 7-Segment LED Matrix Display FeatherWing。这个“翅膀板”本质上是一个已经焊好HT16K33驱动芯片的转接板。HT16K33正是专门驱动LED点阵/数码管的I2C芯片它内部集成了扫描逻辑和显存我们只需要通过I2C告诉它哪个LED该亮它就会自动处理多路复用的繁琐细节大大减轻了MCU的负担。连接方式将FeatherWing插到Feather ESP32主板上。FeatherWing上引出了标准的14引脚7段数码管接口尽管我们只用到其中一部分。我们自制的、模仿商用数码管接口的PCB通过杜邦线连接到这个FeatherWing的对应引脚上。这样一来从软件角度看我们的“全息数码管”和一块普通的4位红色7段数码管没有任何区别所有复杂的LED控制逻辑都被硬件抽象掉了。电源考虑28个白光LED全亮时电流不小。ESP32的USB口或3.3V引脚可能无法提供足够电流。我的方案是PCB的VCC直接从外部5V电源接入而位选/段选信号来自FeatherWing3.3V电平。HT16K33是开漏输出可以承受5V因此用3.3V信号控制5V供电的LED完全没有问题。只需在PCB的VCC和GND之间加一个滤波电容即可。5. 软件实现与网络授时5.1 开发环境与库依赖代码在Arduino IDE中开发主要依赖以下库这些库都可以通过Arduino的库管理器轻松安装Adafruit_LEDBackpack用于控制HT16K33驱动芯片这是显示的核心。Adafruit_GFXLEDBackpack库的图形基础依赖。WiFiManager一个极其好用的库。它让设备在首次启动时进入AP模式你可以用手机连接到一个特定的Wi-Fi热点然后通过网页配置它连接到你家的Wi-Fi。无需在代码里硬编码SSID和密码。NTPClient用于从网络时间协议服务器获取精确的UTC时间。5.2 核心代码逻辑剖析代码结构清晰主要包含初始化、Wi-Fi连接、时间获取和显示刷新几个部分。#include Wire.h #include Adafruit_GFX.h #include Adafruit_LEDBackpack.h #include WiFiManager.h #include NTPClient.h #include WiFiUdp.h Adafruit_7segment matrix Adafruit_7segment(); // 创建显示对象 WiFiUDP ntpUDP; // 设置NTP服务器和时区偏移例如东八区为8*3600秒 NTPClient timeClient(ntpUDP, pool.ntp.org, 8*3600, 60000); void setup() { Serial.begin(115200); matrix.begin(0x70); // HT16K33的I2C地址通常是0x70 // 使用WiFiManager WiFiManager wm; // 如果配置失败比如第一次启动它会自动进入AP模式 bool res wm.autoConnect(HoloClockAP, password); if(!res) { Serial.println(Failed to connect); // 这里可以增加一个错误显示比如显示“----” ESP.restart(); } timeClient.begin(); // 启动NTP客户端 matrix.println(INIT); // 显示初始化完成提示 matrix.writeDisplay(); delay(1000); } void loop() { timeClient.update(); // 更新NTP时间 int currentHour timeClient.getHours(); int currentMinute timeClient.getMinutes(); // 将时分组合成一个四位数例如14:35 - 1435 int displayNumber (currentHour * 100) currentMinute; // 打印到数码管drawColon参数控制中间的冒号点亮 matrix.print(displayNumber, DEC); matrix.drawColon(true); // 点亮冒号 matrix.writeDisplay(); // 将缓存写入驱动芯片真正点亮LED delay(1000); // 每秒更新一次 }关键点解析时区处理NTPClient的第三个参数是时区偏移以秒为单位。8*3600即代表UTC8北京时间。这是需要根据你所在地修改的唯一参数。显示格式matrix.print()函数会将一个整数显示在4位数码管上。我们将小时和分钟合并成一个四位数非常巧妙。例如下午2点35分就是1435。冒号控制drawColon(true/false)是Adafruit_7segment库提供的特有函数用于控制中间冒号的亮灭。我们可以让它每秒闪烁一次增加生动性。低功耗考虑在实际代码中我添加了在整点后的一段时间内调低LED亮度通过matrix.setBrightness()的逻辑以减少夜间光污染。5.3 调试与测试模式在组装完成但尚未连接网络时一个测试模式非常有用。我写了一个简单的计数器循环让数字从0000滚动到9999这样可以快速验证所有28个LED及其对应的全息段是否工作正常有无连接错误。void testAllSegments() { for (int i 0; i 10000; i) { matrix.print(i); matrix.writeDisplay(); delay(50); } }6. 总装、调试与效果优化6.1 系统集成与布线这是最需要耐心的一步顺序很重要焊接LED与PCB先将LED插入3D打印的支架孔中注意正负极方向通常LED长脚为正。然后将定制PCB对准引脚扣上从背面焊接。焊完一个数字位后立刻通电测试这7个段是否正常。连接两个数字位通过排针排母将两块代表十位和个位的PCB连接起来。确保连接牢固。安装机械结构将两个半钟的底座通过燕尾榫合体。依次插入全息板支架、已焊接LED的PCB背板。安装主控将Feather ESP32与FeatherWing组合体放入底座的预留位置盖上顶盖。飞线连接这是最繁琐的。需要用杜邦线将4块PCB代表4个数字位的14个引脚7段选4位选电源地连接到FeatherWing的对应插口。强烈建议使用不同颜色的线区分功能如红色VCC黑色GND其他颜色对应段。先根据原理图制作一个连接表每接一根线划掉一项。线缆留出合适余量用细扎带分组捆扎固定在底座内侧避免杂乱。6.2 效果评估与问题排查组装完成后通电你可能会遇到以下典型问题及解决方案问题现象可能原因排查与解决思路某个数字位的所有段都不亮该位PCB的位选共阴极信号未接通或短路检查连接该位“位选”引脚到FeatherWing的导线。用万用表通断档测量。所有数字的同一段都不亮如所有“a”段该段的段选信号线断路检查连接该“段选”引脚到FeatherWing的导线。某个LED常亮或不受控LED正负极接反或PCB上该LED的驱动三极管/线路短路断电检查焊接点是否有桥接。确认LED方向。显示的数字乱码或部分段异常亮I2C地址冲突或通信不良导线接触不良导致信号串扰确认HT16K33地址正确通常0x70。检查I2CSDA, SCL连接是否牢固。重新插拔所有杜邦线。全息像暗淡、模糊或有重影LED与记录时激光的角度/位置不匹配环境光太强微调LED支架的角度确保LED光斑能均匀覆盖全息图对应区域。在较暗环境下观看。再现像有彩虹色但边缘发虚记录时物体灯罩薄膜与干板距离或角度有误差LED不是点光源这是系统固有局限。尝试使用更小尺寸、发光角度更集中的LED。确保记录时光路严格垂直。关于LED颜色的选择我最初使用了白光LED因为它能产生彩虹色的全息像看起来很“科幻”。但实测下来红色LED的亮度和对比度远超白光LED。因为全息干板对记录时使用的红色激光最敏感用同色系的红色LED再现衍射效率最高像最亮。白光LED光谱宽只有其中红色成分被有效衍射其他颜色成分成了背景杂光降低了对比度。所以如果追求最佳显示效果强烈推荐使用红色LED。6.3 光学像质提升的思考在最终成品中垂直的段看起来有些倾斜或变形。这暴露了本项目的一个根本性挑战再现光源与记录光源的匹配问题。记录时使用的是高度准直、方向单一的激光。再现时使用的是发散角较大、尺寸非理想的LED。LED发出的光不是从一个理想的点发出而是从一个面发出且光线发散。这导致再现光波前与参考光波前不完全一致从而引起像差表现为图像模糊、变形或位置偏移。理论上的改进方向使用更小的LED选择芯片尺寸更小的LED使其更接近点光源。添加准直透镜在每个LED前增加一个微型准直透镜使发出的光更接近平行光。这会大幅增加硬件复杂度和调校难度。在记录光路中引入透镜这是原作者在文末提到的进阶想法。如果在记录时让物光先通过一个透镜例如让物体位于透镜焦点产生平行光或位于两倍焦距产生倒立实像那么再现时像的位置和清晰度会对光源的位置和大小不那么敏感容错率更高。但这需要更精密的光学设计和调试。尽管存在这些光学上的不完美但这个项目成功地验证了将真实全息技术应用于动态显示的可能性。当你在昏暗的房间里看到几个发着微光、仿佛悬浮在玻璃板后的数字静静跳动时那种融合了精密工程与奇妙光学的成就感是任何普通显示器都无法给予的。整个项目从光学原理学习开始历经机械设计、电路板绘制、嵌入式编程到最后的总装调试是一次完整的跨学科工程实践。它教会我的不仅是技术更是一种解决问题的方法论将复杂目标分解为可实现的模块尊重每一门学科光学、机械、电子的基本原理在妥协中寻找最优解。
基于透射全息与ESP32的全息时钟:从光学原理到工程实现
发布时间:2026/6/12 21:32:13
1. 项目概述与核心思路我一直对全息技术着迷它不仅仅是科幻电影里的炫酷特效更是一门严谨的光学工程。市面上的“伪全息”方案比如佩珀尔幻象或者基于视觉暂留的旋转LED虽然效果不错但总感觉少了点“真东西”的灵魂。所以当决定动手做一个全息时钟时我的目标很明确做一个基于真实透射全息图的、能显示数字的玩意儿让每个数字段都像真的悬浮在空中一样。这个项目的核心是把传统的7段数码管显示用全息技术重新“翻译”一遍。传统数码管是物理发光而这里每个数字段a到g都是一个独立的透射全息图。这些全息图被记录在特殊的感光板上当用特定角度的白光LED从背后照射时就能再现出记录时“物体”一个发光的灯罩薄膜的光场看起来就像光从板子后面凭空“长”了出来。整个系统的大脑是一块ESP32开发板它负责从网络获取精确时间并控制28个LED4位数每段1个的亮灭从而驱动这些全息“像素”显示出当前的时分。听起来复杂但拆解开来无非是光学、机械、电子和固件四个部分的精密耦合。光学部分负责“造像”机械结构负责“固定”电子部分负责“驱动”固件负责“指挥”。下面我就把这几个月从原理摸索到实践落地的全过程包括踩过的坑和总结的经验毫无保留地分享出来。2. 全息原理与Litiholo套件初探2.1 透射全息图的核心原理在动手之前必须搞清楚我们到底在做什么。全息术Holography的本质是记录并再现物体的完整光波前包括振幅和相位信息。这不同于普通照相后者只记录强度振幅。我们制作的是透射全息图。其基本原理分为两步记录和再现。记录过程需要两束相干的激光通常来自同一激光器。一束叫物光它照射到物体上经物体反射或透射后携带着物体的信息到达全息干板。另一束叫参考光它直接照射到干板上。这两束光在干板处相遇发生干涉形成极其精细的、明暗相间的干涉条纹图案。这个图案被干板上的感光材料记录了下来。它记录的不仅是光的强弱更是两束光相遇时的相位差这个相位差编码了物体的三维信息。再现过程用一束与参考光相同波长和角度的光称为再现光照射制作好的全息图。全息图上记录的干涉条纹相当于一个复杂的光栅当再现光通过时会发生衍射。其中一级衍射光波前恰好与当初的物光波前一模一样。当我们的眼睛接收到这个重建的波前时就会“看到”原来物体所在的位置有一个立体的虚像仿佛物体就在那里。在这个时钟项目中我们的“物体”是一个被均匀照亮的、特定形状7段数码管的段形状的漫射体灯罩薄膜。我们记录下它的光波前。再现时我们用普通的白光LED去照射全息图由于LED光谱较宽我们看到的再现像会带有彩虹色这正是白光再现透射全息图的特征之一。注意全息记录对稳定性要求极高。任何微小的振动甚至声波导致光路变化超过半个波长对于红光约316纳米干涉条纹就会模糊记录就会失败。这就是为什么实验常在深夜、光学平台上进行。2.2 Litiholo套件实战与避坑指南对于没有光学实验背景的爱好者Litiholo的套件是一个绝佳的入门选择。它把复杂的激光器、光学元件和化学药水都打包好了让你能专注于体验全息记录的过程。我拿到套件后严格按照说明书做了第一次测试。套件里包含一个玩具小车作为物体。过程大致是在暗室环境套件配了暗袋将激光器和干板架设好保持绝对安静和静止约几分钟进行曝光然后用配套的药水进行显影、定影。第一次尝试就成功了这让我有点意外。因为套件里的激光器只是个简单的二极管激光用金属弹簧散热支架也是亚克力激光切割的非常“业余”。但这恰恰证明在严格控制振动和环境光的前提下入门级设备也能做出真正的全息图。关键操作心得预热激光器即使是这种简易激光器开机后亮度也会有一个短暂的稳定过程。我的习惯是提前打开至少5-10分钟再进行光路调整和曝光。绝对黑暗任何杂散光都是敌人。确保暗袋拉链完全闭合或者在一个真正的暗房里操作。曝光过程中连手机屏幕的光都不能有。“一动不如一静”调整好光路、放好干板后最好的姿势就是保持不动甚至屏住呼吸几秒钟直到曝光完成。地面震动是最大的威胁远离走动的人和马路。药水温度显影和定影药水对温度敏感。室温20-25°C下操作效果最好。太冷反应慢太热可能使药水失效或损伤乳剂。这次成功给了我极大的信心但也让我意识到套件的局限性它的支架是为标准物体设计的无法方便地录制我们需要的、多个特定形状且位置精确的“段”。因此自定义光路和机械结构势在必行。3. 定制化全息记录系统搭建3.1 光路设计与机械结构为了录制7段数码管形状的全息图我需要一个可重复、可精确定位的光学系统。套件的水平布局不适合我设计了一个垂直光路。整个系统核心是一个3D打印的黑色支架。激光器从底部以45度角向上照射。在光路中自上而下依次是全息干板感光面朝下面向激光。物体玻璃板位于干板正下方上面贴有切成段形状的白色自粘灯罩薄膜。这层薄膜的作用是作为一个理想的漫射体将激光均匀地散射开照亮整个“段”的形状。激光束从下方45度角入射同时照亮干板和物体。为什么选择垂直布局和45度角垂直布局使得放置和更换干板、物体板更加方便也更容易实现旋转。45度角是透射全息中一个常见的参考光角度能在记录效率和再现像亮度之间取得较好的平衡。更重要的是后续用LED再现时我们也需要从类似的角度照射垂直布局为LED的安装提供了天然的空间。机械设计要点材料全部使用哑光黑色PLA打印。黑色是为了最大限度地吸收杂散光防止其在内部反射形成噪声哑光表面进一步防止镜面反射。稳定性结构件设计得足够厚重连接处采用卡扣和螺丝双重固定确保在长时间曝光中不会因自身应力产生形变或晃动。旋转机构干板架和物体板架必须能作为一个整体在水平面内进行精确的旋转。我设计了带刻度的旋转盘每次旋转51.4度360/7以确保7个段能均匀地记录在一张干板上。旋转的中心必须与光路中心对齐否则再现时各段的位置会错乱。3.2 分段记录流程与实战细节一张全息干板上要记录7个独立的段这需要用到空间复用技术。简单说就是每次只让干板的一小部分感光记录一个段其他部分用遮光板光圈挡住。详细记录步骤一次深呼吸般的操作激光预热打开激光器稳定至少5分钟。预对齐在不放入干板的情况下打开室内微弱的蓝光LED全息干板对蓝光不敏感调整激光光斑确保它能均匀覆盖物体板上的“段”形状区域。黑暗准备关闭所有灯只留那盏对着墙的微弱蓝光。用黑色卡纸挡住激光束。放置干板在暗袋或全黑环境下取出全新的全息干板注意不要触碰感光面以正确方向放入支架。干板有玻璃的一面通常朝外背对激光感光乳剂面朝内对着物体。绝对黑暗关闭蓝光LED。此时应伸手不见五指。开始曝光迅速而平稳地移开遮挡激光的卡纸。开始计时我的设置是5分钟。这5分钟内你必须像雕塑一样保持静止。任何咳嗽、脚步声都可能导致前功尽弃。结束曝光时间到迅速用卡纸挡回激光束。打开蓝光LED。旋转准备按照预定顺序例如从段“a”开始将干板架和物体板架整体旋转到下一个位置。调整光圈只让下一个“段”对应的干板区域暴露。重复重复步骤5-8直到7个段全部记录完毕。化学处理将曝光后的干板在完全黑暗中取出立即进行显影、漂白、定影、水洗和干燥。Litiholo的套件药水是一步到位的简化了流程。核心难点与技巧振动隔离我选择在凌晨后操作并将整个装置放在厚重的花岗岩板上石板下垫了海绵。这能有效隔离大部分建筑和环境振动。激光稳定性我后来换用了工作用的单频红色激光二极管并加了恒流驱动和更大的散热片光强和波长稳定性远好于套件激光器。但对于套件激光确保供电电压稳定是关键。光圈制作我用黑色卡纸手工切割了精确的开口。更优的方案是使用光阑但卡纸成本低易于调整。关键是边缘要整齐不能有毛边衍射。4. 时钟的机械与电子系统实现4.1 结构设计与3D打印时钟的外壳和内部支架全部由哑光黑色PLA通过FDM 3D打印机完成。设计上分为左右两个完全对称的“半钟”每个半钟容纳两位数字。这样设计便于打印、组装和维修。主要结构部件底座板承载所有其他部件的基板。两个半钟的底座板通过燕尾榫结构咬合无需螺丝即可牢固连接且保证了拼接的精度。全息板支架用于固定四片录制好的全息干板。设计有卡槽确保干板以精确的角度和位置插入这是再现像能否对齐的关键。LED支架/PCB背板用于安装定制PCB和LED。每个数字对应一块背板上面有精确的孔位确保28个LED的每一个都能对准其对应的全息“段”的中心。背板通过卡扣和螺丝固定在底座上。顶盖覆盖住ESP32主控板和驱动板起保护和美观作用。冒号支架位于两半钟中间用于安装两个作为时间分隔冒号“:”的LED。这个部件我用双色打印完成主体黑色光导部分使用透明PLA让光更柔和。打印与后处理经验层高与填充使用0.15mm层高以获得更光滑的表面尤其是与全息板接触的斜面。填充率25%足够保证强度同时节省材料和时间。防止翘曲打印大面积底板时一定要使用热床并确保粘贴牢固我用的美纹纸胶带加胶水否则边缘翘曲会导致整个结构不平。哑光黑的选择普通的黑色PLA打印出来也有光泽会反射杂散光干扰全息像。务必选择真正的哑光Matte黑色PLA或者对成品进行哑光喷漆处理。4.2 定制PCB设计与LED驱动逻辑用28根飞线去控制28个LED是一场噩梦不仅混乱而且可靠性极差。设计定制PCB是让项目从“实验原型”走向“成品”的关键一步。PCB设计思路 我的目标是复现商用4位7段数码管的电气连接方式这样就能直接使用现成的驱动芯片和库。商用数码管内部采用动态扫描多路复用来减少引脚使用。对于共阴极数码管所有段的阴极连接在一起位选而每个段的阳极是独立的。我将这个逻辑移植到PCB上每块PCB对应一个数字位上面焊接7个LED对应a-g段。这7个LED的阴极负极全部连接在一起引出一个“位选”引脚。每个LED的阳极正极单独引出连接到“段选”引脚。PCB边缘设计成排母接口这样两块PCB可以像积木一样堆叠插接位选和段选信号通过排针/排母自动级联完全省去了连接两个数字位之间的导线。设计踩坑实录 第一版PCB犯了一个低级错误我把LED的封装画反了导致LED安装后极性颠倒。无奈之下只能用刀在PCB上割线再用飞线修补非常狼狈。教训在投板生产前务必用实物LED在打印出来的1:1图纸上比对或者使用EDA软件的3D预览功能反复检查封装方向。4.3 主控与驱动电路集成主控选择了Adafruit的Feather ESP32 V2。选择它有三个原因1) 体积小巧集成度高2) ESP32自带Wi-Fi便于实现NTP网络授时3) Adafruit为其提供了完美的配套组件——4-Digit 7-Segment LED Matrix Display FeatherWing。这个“翅膀板”本质上是一个已经焊好HT16K33驱动芯片的转接板。HT16K33正是专门驱动LED点阵/数码管的I2C芯片它内部集成了扫描逻辑和显存我们只需要通过I2C告诉它哪个LED该亮它就会自动处理多路复用的繁琐细节大大减轻了MCU的负担。连接方式将FeatherWing插到Feather ESP32主板上。FeatherWing上引出了标准的14引脚7段数码管接口尽管我们只用到其中一部分。我们自制的、模仿商用数码管接口的PCB通过杜邦线连接到这个FeatherWing的对应引脚上。这样一来从软件角度看我们的“全息数码管”和一块普通的4位红色7段数码管没有任何区别所有复杂的LED控制逻辑都被硬件抽象掉了。电源考虑28个白光LED全亮时电流不小。ESP32的USB口或3.3V引脚可能无法提供足够电流。我的方案是PCB的VCC直接从外部5V电源接入而位选/段选信号来自FeatherWing3.3V电平。HT16K33是开漏输出可以承受5V因此用3.3V信号控制5V供电的LED完全没有问题。只需在PCB的VCC和GND之间加一个滤波电容即可。5. 软件实现与网络授时5.1 开发环境与库依赖代码在Arduino IDE中开发主要依赖以下库这些库都可以通过Arduino的库管理器轻松安装Adafruit_LEDBackpack用于控制HT16K33驱动芯片这是显示的核心。Adafruit_GFXLEDBackpack库的图形基础依赖。WiFiManager一个极其好用的库。它让设备在首次启动时进入AP模式你可以用手机连接到一个特定的Wi-Fi热点然后通过网页配置它连接到你家的Wi-Fi。无需在代码里硬编码SSID和密码。NTPClient用于从网络时间协议服务器获取精确的UTC时间。5.2 核心代码逻辑剖析代码结构清晰主要包含初始化、Wi-Fi连接、时间获取和显示刷新几个部分。#include Wire.h #include Adafruit_GFX.h #include Adafruit_LEDBackpack.h #include WiFiManager.h #include NTPClient.h #include WiFiUdp.h Adafruit_7segment matrix Adafruit_7segment(); // 创建显示对象 WiFiUDP ntpUDP; // 设置NTP服务器和时区偏移例如东八区为8*3600秒 NTPClient timeClient(ntpUDP, pool.ntp.org, 8*3600, 60000); void setup() { Serial.begin(115200); matrix.begin(0x70); // HT16K33的I2C地址通常是0x70 // 使用WiFiManager WiFiManager wm; // 如果配置失败比如第一次启动它会自动进入AP模式 bool res wm.autoConnect(HoloClockAP, password); if(!res) { Serial.println(Failed to connect); // 这里可以增加一个错误显示比如显示“----” ESP.restart(); } timeClient.begin(); // 启动NTP客户端 matrix.println(INIT); // 显示初始化完成提示 matrix.writeDisplay(); delay(1000); } void loop() { timeClient.update(); // 更新NTP时间 int currentHour timeClient.getHours(); int currentMinute timeClient.getMinutes(); // 将时分组合成一个四位数例如14:35 - 1435 int displayNumber (currentHour * 100) currentMinute; // 打印到数码管drawColon参数控制中间的冒号点亮 matrix.print(displayNumber, DEC); matrix.drawColon(true); // 点亮冒号 matrix.writeDisplay(); // 将缓存写入驱动芯片真正点亮LED delay(1000); // 每秒更新一次 }关键点解析时区处理NTPClient的第三个参数是时区偏移以秒为单位。8*3600即代表UTC8北京时间。这是需要根据你所在地修改的唯一参数。显示格式matrix.print()函数会将一个整数显示在4位数码管上。我们将小时和分钟合并成一个四位数非常巧妙。例如下午2点35分就是1435。冒号控制drawColon(true/false)是Adafruit_7segment库提供的特有函数用于控制中间冒号的亮灭。我们可以让它每秒闪烁一次增加生动性。低功耗考虑在实际代码中我添加了在整点后的一段时间内调低LED亮度通过matrix.setBrightness()的逻辑以减少夜间光污染。5.3 调试与测试模式在组装完成但尚未连接网络时一个测试模式非常有用。我写了一个简单的计数器循环让数字从0000滚动到9999这样可以快速验证所有28个LED及其对应的全息段是否工作正常有无连接错误。void testAllSegments() { for (int i 0; i 10000; i) { matrix.print(i); matrix.writeDisplay(); delay(50); } }6. 总装、调试与效果优化6.1 系统集成与布线这是最需要耐心的一步顺序很重要焊接LED与PCB先将LED插入3D打印的支架孔中注意正负极方向通常LED长脚为正。然后将定制PCB对准引脚扣上从背面焊接。焊完一个数字位后立刻通电测试这7个段是否正常。连接两个数字位通过排针排母将两块代表十位和个位的PCB连接起来。确保连接牢固。安装机械结构将两个半钟的底座通过燕尾榫合体。依次插入全息板支架、已焊接LED的PCB背板。安装主控将Feather ESP32与FeatherWing组合体放入底座的预留位置盖上顶盖。飞线连接这是最繁琐的。需要用杜邦线将4块PCB代表4个数字位的14个引脚7段选4位选电源地连接到FeatherWing的对应插口。强烈建议使用不同颜色的线区分功能如红色VCC黑色GND其他颜色对应段。先根据原理图制作一个连接表每接一根线划掉一项。线缆留出合适余量用细扎带分组捆扎固定在底座内侧避免杂乱。6.2 效果评估与问题排查组装完成后通电你可能会遇到以下典型问题及解决方案问题现象可能原因排查与解决思路某个数字位的所有段都不亮该位PCB的位选共阴极信号未接通或短路检查连接该位“位选”引脚到FeatherWing的导线。用万用表通断档测量。所有数字的同一段都不亮如所有“a”段该段的段选信号线断路检查连接该“段选”引脚到FeatherWing的导线。某个LED常亮或不受控LED正负极接反或PCB上该LED的驱动三极管/线路短路断电检查焊接点是否有桥接。确认LED方向。显示的数字乱码或部分段异常亮I2C地址冲突或通信不良导线接触不良导致信号串扰确认HT16K33地址正确通常0x70。检查I2CSDA, SCL连接是否牢固。重新插拔所有杜邦线。全息像暗淡、模糊或有重影LED与记录时激光的角度/位置不匹配环境光太强微调LED支架的角度确保LED光斑能均匀覆盖全息图对应区域。在较暗环境下观看。再现像有彩虹色但边缘发虚记录时物体灯罩薄膜与干板距离或角度有误差LED不是点光源这是系统固有局限。尝试使用更小尺寸、发光角度更集中的LED。确保记录时光路严格垂直。关于LED颜色的选择我最初使用了白光LED因为它能产生彩虹色的全息像看起来很“科幻”。但实测下来红色LED的亮度和对比度远超白光LED。因为全息干板对记录时使用的红色激光最敏感用同色系的红色LED再现衍射效率最高像最亮。白光LED光谱宽只有其中红色成分被有效衍射其他颜色成分成了背景杂光降低了对比度。所以如果追求最佳显示效果强烈推荐使用红色LED。6.3 光学像质提升的思考在最终成品中垂直的段看起来有些倾斜或变形。这暴露了本项目的一个根本性挑战再现光源与记录光源的匹配问题。记录时使用的是高度准直、方向单一的激光。再现时使用的是发散角较大、尺寸非理想的LED。LED发出的光不是从一个理想的点发出而是从一个面发出且光线发散。这导致再现光波前与参考光波前不完全一致从而引起像差表现为图像模糊、变形或位置偏移。理论上的改进方向使用更小的LED选择芯片尺寸更小的LED使其更接近点光源。添加准直透镜在每个LED前增加一个微型准直透镜使发出的光更接近平行光。这会大幅增加硬件复杂度和调校难度。在记录光路中引入透镜这是原作者在文末提到的进阶想法。如果在记录时让物光先通过一个透镜例如让物体位于透镜焦点产生平行光或位于两倍焦距产生倒立实像那么再现时像的位置和清晰度会对光源的位置和大小不那么敏感容错率更高。但这需要更精密的光学设计和调试。尽管存在这些光学上的不完美但这个项目成功地验证了将真实全息技术应用于动态显示的可能性。当你在昏暗的房间里看到几个发着微光、仿佛悬浮在玻璃板后的数字静静跳动时那种融合了精密工程与奇妙光学的成就感是任何普通显示器都无法给予的。整个项目从光学原理学习开始历经机械设计、电路板绘制、嵌入式编程到最后的总装调试是一次完整的跨学科工程实践。它教会我的不仅是技术更是一种解决问题的方法论将复杂目标分解为可实现的模块尊重每一门学科光学、机械、电子的基本原理在妥协中寻找最优解。