1. 项目概述:拆解一台廉价激光测距仪
手头有一台从Lidl超市买的Parkside PLEM 50 C3激光测距仪,这东西便宜,量程标称50米,精度据说有±2毫米。对于搞嵌入式开发或者硬件黑客来说,这种消费电子产品的内部往往藏着有趣的秘密——它的核心测距模块是怎么工作的?数据又是如何传递到屏幕上显示的?这次的目标就是把它彻底拆开,从物理结构到通信协议,完整地逆向一遍,最终目的是理解其工作原理,并尝试将这个激光测距模块剥离出来,集成到我们自己的项目里,比如做个自动测距小车或者智能卷尺。整个过程就像一场硬件侦探游戏,需要用到万用表、逻辑分析仪这些工具,一步步追踪信号的流向,破解数据的含义。
2. 核心原理:飞行时间(TOF)测距法
2.1 TOF的基本物理模型
激光测距仪,无论是昂贵的工业级设备还是我们手上这种几十欧元的消费级产品,其核心测距原理绝大多数都基于飞行时间法。这个概念听起来高大上,其实理解起来很直观:就是测量一束光跑一个来回所花的时间。具体来说,设备内部的激光二极管会发射一个极其短暂的光脉冲,这个脉冲以光速(约每秒30万公里)飞向目标物体,经物体表面反射后,一部分光会返回到设备上的接收传感器(通常是光电二极管或APD雪崩光电二极管)。微控制器(MCU)的核心任务,就是精确计量从发射脉冲到接收到回波信号之间的时间间隔 Δt。
得到这个时间后,计算距离就很简单了:距离 = (光速 × Δt) / 2。之所以要除以2,是因为Δt是光“去”又“回”的总时间,而我们只需要单程的距离。这里就引出了第一个关键点:时间测量的精度直接决定了距离测量的精度。光速太快了,对于1毫米的测距精度,要求系统能分辨出大约6.7皮秒(6.7×10⁻¹²秒)的时间差。这对于低成本MCU来说是天文数字,因此这类设备内部通常会有一颗专门的时钟发生器芯片,为时间数字转换器(TDC)或相关计时电路提供稳定、高频的时钟基准,这也是为什么我们在模块上会发现一颗MS5351M这样的时钟发生器。
2.2 廉价方案中的工程折衷
在高端激光雷达中,可能会使用更精密的相位检测法或采用特殊的光学设计。但在PLEM 50 C3这类低成本设备中,就是最直接的脉冲式TOF。为了控制成本,它必须在性能上做出妥协。例如,激光功率不会太高,以保证安全并降低功耗,但这限制了测程和在强光下的性能。接收端可能没有复杂的滤波放大电路,容易受到环境光干扰。MCU的运算能力也有限,可能采用多次测量取平均等软件算法来提升稳定性和抑制噪声,这会导致测量速度不是特别快。理解这些折衷,有助于我们在逆向和复用模块时,设定合理的性能预期。
3. 设备拆解与初步侦察
3.1 安全拆解与结构分析
拆解任何电子设备的第一步永远是安全断电,确保电池已取出。PLEM 50 C3的外壳通常由几个卡扣和螺丝固定,需要耐心使用塑料撬棒和合适的螺丝刀,避免暴力损坏外壳或内部排线。打开后,整个设备可以清晰地分为三个主要部分:
- 显示屏模块:一块普通的段码LCD屏幕,通过一条柔性的斑马条或FPC排线与主板连接。
- 键盘PCB:上面只有按键、一些被动元件(电阻、电容)和连接器,没有发现任何主控芯片。这说明所有智能部分都集中在第三个模块上。
- 激光测距模块:这是本次逆向的核心。它是一个相对独立的子板,集成了激光发射器、接收传感器、光学透镜、主控MCU以及相关的电源和时钟电路。
这种设计非常模块化,对于我们来说是个好消息,意味着激光测距功能在物理和电气上相对独立,有可能被单独驱动。
3.2 电路探查与接口猜测
拆开后,我用数字显微镜(如果有的话,非常有用)仔细观察了激光模块的PCB。首先吸引我的是一个4Pin的接头,上面赫然印着“RX”和“TX”字样。这强烈暗示它是一个UART(通用异步收发传输器)接口。很多工程师的第一反应可能就是:太好了,直接接上USB转TTL串口模块,看看它吐什么数据。但实际测试却让人失望——无论尝试常见的波特率(9600, 115200等),这个接口都寂静无声。这可能是因为该接口仅用于工厂生产测试或固件烧录,在正常用户模式下不启用,或者需要特定的唤醒命令序列。
既然“明面”上的UART走不通,就需要更系统地探查。使用万用表的蜂鸣档,我开始追踪激光模块与键盘板、屏幕之间的所有连接线。这是一个需要耐心的工作,目的是绘制出模块与外部世界连接的最小引脚图。很快我发现,连接屏幕的排线上,除了电源和背光引脚,只有两根线(在图片中我标记为紫色和黄色)直接通向了主控MCU的区域。两根线、双向通信——这个配置立刻让人联想到两种常见的串行协议:I2C和SPI。SPI通常需要至少4根线(CS, SCK, MOSI, MISO),而I2C只需要两根(SDA数据线, SCL时钟线)。因此,这两根线极大概率就是I2C总线。
4. 协议捕获:使用逻辑分析仪嗅探I2C
4.1 焊接测试点与设备连接
猜测需要验证。我在那两根疑似I2C的线上小心翼翼地焊接了细导线作为测试点。这需要一些焊接技巧,因为排线引脚和PCB焊盘都很细小,建议使用尖头烙铁、细焊锡丝和助焊剂,并注意防静电和热损伤。焊接好后,将这两根线分别连接到逻辑分析仪的通道0(假设为SCL)和通道1(假设为SDA)。同时,为了稳定供电并方便测量,我没有使用电池,而是使用一个可调稳压电源,设置为3V(与两节AAA电池电压一致)为整个设备供电。
注意:在焊接和探测时,务必确保设备完全断电。焊接测试线时动作要快,避免长时间加热损坏焊盘或芯片。逻辑分析仪的地线一定要与被测设备的地(通常是电池负极或电源滤波电容的负极)可靠连接,这是保证信号捕获准确的前提。
4.2 捕获与分析通信波形
我使用的是Saleae Logic系列逻辑分析仪,配合其官方软件Logic 2。在软件中设置正确的采样率(对于低速I2C,1MHz或2MHz足够)和通道阈值后,开始录制。然后,按下测距仪的开机键和测量键。
逻辑分析仪屏幕上立刻出现了规整的方波信号!通过软件的I2C协议分析器,指定SDA和SCL通道后,软件自动将波形解码成了具体的I2C数据包。这证实了我们的猜测:屏幕确实是一个I2C从设备。
分析捕获到的数据流,可以看到一个清晰的模式:
- 设备上电后,主控MCU(作为I2C主设备)会先向屏幕发送一系列初始化数据包,可能是用于配置屏幕的对比度、显示模式等。
- 当按下测量键时,MCU会进行一轮激光测距。
- 测距计算完成后,MCU会通过I2C总线,向屏幕的地址发送新的数据包,更新屏幕上的数字。
- 屏幕有时也会向MCU发送数据(地址不同),这可能是屏幕驱动芯片的状态回读或按键扫描信息(如果按键矩阵也通过屏幕芯片管理的话)。
5. 数据解码:从十六进制到实际距离
5.1 定位关键数据包
仅仅看到有数据在传输还不够,我们需要找到哪个数据包对应着距离数值的传输。通过对比“按下测量键”这个动作前后数据流的变化,可以锁定在测量完成后,MCU发出的一连串数据包。在这些数据包中,我注意到一些数据包以固定的字节0xC0开头,紧随其后的另一个字节则在每次测量时发生变化。这很像是一种数据帧结构,0xC0可能是命令字或寄存器地址,表示“更新显示数据”,而后面的字节就是具体的显示内容。
为了验证,我进行了“黑盒测试”:测量几个已知的、精确的距离(例如,利用卡尺固定一个5.000米的基准),同时捕获此时的I2C数据,记录下0xC0后面跟随的那个字节。通过对比不同距离下的这个字节,就能寻找其与显示数字之间的映射关系。
5.2 利用现有成果与解码函数
逆向工程中,善于利用社区成果能事半功倍。在搜索芯片资料时,我幸运地发现了Pavel Rybnicek在GitHub上分享的针对同款设备的ESPHome组件代码(esphome-parkside-plem-50-c3)。这大大加速了进程。他的代码里包含了一个关键的解码函数decode_digit_last_line。
这个函数揭示了一个重要细节:屏幕上显示的每一位数字(包括小数点),实际上是由两个字节(digit1和digit2)共同编码的。函数通过一个switch-case语句,将两个字节组合成的16位数值映射到对应的字符(如“0”、“.5”、“-”等)。例如,数值0x141A对应字符“5”,0x1E1A对应字符“.6”。这种编码方式很可能是为了直接驱动段码LCD的各个段位,两个字节的每一位对应LCD的一个段。
5.3 解码实践与验证
以我捕获到的一个数据包序列为例,假设它代表距离“5.568”米。解码过程如下:
- MCU会依次发送多个以
0xC0开头的数据包,每个包更新屏幕上的一个数字位。 - 第一个包数据为
0xC0后跟0x14和0x1A(实际传输中可能是两个独立的I2C数据字节)。组合0x141A,查解码函数,得到字符“5”。 - 第二个包数据对应
0x1E1A,解码为“.6”。注意,这里的小数点是和数字“6”绑定在一起的,说明屏幕的驱动芯片是以“带小数点的数字”为单位来控制的。 - 后续包依次解码出“5”和“8”。
- 将这些字符按顺序组合,就得到了“5.568”的显示字符串。
通过这种方式,我们完全破解了MCU与屏幕之间的通信协议。这意味着,如果我们想绕过原装屏幕,可以直接用一块单片机(如Arduino、ESP32)模拟MCU,按照这个协议格式向原装屏幕发送数据,就能控制它显示任意内容。反之,如果我们想用自己的屏幕,就需要理解MCU发送的原始距离数据格式——这可能需要进一步分析测量完成后、屏幕更新前,MCU内部是否通过I2C向其他地址(可能是它自己内部的某个虚拟从设备)暂存了原始数据,或者需要通过其他方式(如拦截MCU与传感器之间的信号)来获取。
6. 核心芯片分析与系统架构推测
6.1 主控MCU与时钟系统
在模块上,除了激光管和接收管,最显眼的是两颗较大的芯片。主控MCU型号印着“NM002 2129”,这是一个没有公开数据手册的定制或小众芯片,增加了逆向难度。它很可能是一颗集成了模拟前端(用于接收回波信号放大)、时间数字转换(TDC)逻辑和通用微控制器内核的SoC。这种高度集成正是降低成本的关键。
另一颗芯片MS5351M则是一颗通过I2C配置的时钟发生器。它的存在至关重要。TOF测距需要极高精度的时间基准,MCU内部的主时钟可能稳定性或精度不够。MS5351M可以产生一个非常稳定和精确的高频时钟信号,提供给MCU内部的TDC单元,作为测量时间间隔的“尺子”,从而保证测距精度。通过I2C配置它,MCU可以在不同模式(如高精度模式、低功耗模式)下调整时钟特性。
6.2 整体系统工作流程推测
基于以上分析,我们可以勾勒出整个系统的工作流程:
- 用户触发:按下测量键,键盘PCB上的按键信号通过连接线送达主控MCU的GPIO。
- 发射与接收:MCU控制激光驱动器发射一个短脉冲激光,同时启动内部高精度计时器。接收端的光电传感器接收到微弱的回波后,经过模拟放大和整形电路,产生一个数字脉冲信号送给MCU。
- 时间计算:MCU的TDC单元测量发射触发与回波到达之间的时间差Δt。
- 距离解算:MCU中的固件程序根据公式
距离 = (c * Δt) / 2计算距离,并结合可能的温度补偿、多次平均等算法进行校准,得到最终结果。 - 数据格式化:将计算出的浮点距离值,按照屏幕驱动芯片要求的格式,转换为一系列段码编码字节。
- 通信与显示:MCU通过I2C总线,按照特定的帧格式(以
0xC0命令字开头),将编码后的字节依次发送到屏幕驱动芯片(I2C地址0x3F)。屏幕驱动芯片根据这些数据点亮相应的LCD段码,显示出距离数字。 - 可能的反馈:屏幕驱动芯片可能通过I2C(以地址0x60)向MCU报告状态或传输按键信息(如果按键矩阵接在屏幕芯片上)。
7. 复用模块的挑战与可行路径
7.1 完全逆向驱动
最彻底的复用方式是“取而代之”,即用自己的单片机完全接管激光测距模块。这需要:
- 破解供电与使能:找到模块的电源引脚(通常是VCC和GND)以及激光发射的使能信号线。可能需要分析模块与主板连接的所有引脚定义。
- 模拟发射时序:研究原MCU驱动激光管的脉冲波形(宽度、电流),用自己的MCU精准复现。
- 解读回波信号:接收端的输出信号是模拟还是数字?如果是模拟信号,需要设计匹配的放大和比较电路,将其转换为单片机可识别的数字脉冲。这部分的逆向难度最大,需要示波器观察真实信号形态。
- 实现计时算法:在自己的MCU上实现高精度计时(可能需利用硬件定时器输入捕获功能)和距离解算。
这条路径技术挑战高,但能获得最大控制权和灵活性。
7.2 “寄生”式数据窃取
更取巧的方式是“寄生”在原系统上。思路是:让原设备正常工作,但我们用自己的单片机也连接到那根I2C总线上,作为一个“窃听者”。由于I2C总线是开放集电极结构,支持多主多从,我们可以将自己的单片机配置为I2C从设备,并监听地址0x3F(屏幕地址)的数据。当原MCU向屏幕发送距离数据时,我们的单片机也能同时接收到。我们只需解析0xC0后面的数据包,利用已有的解码函数,就能实时获取测量出的距离值,然后通过串口发送给电脑,或者用我们自己的OLED屏幕显示出来。
这种方法相对简单,无需处理复杂的模拟激光驱动和回波接收,风险小,但依赖于原机MCU和测距功能必须完好。
7.3 直接利用屏幕接口
如果我们只对原装屏幕感兴趣,可以丢弃原MCU和激光模块,只保留屏幕。然后,根据我们破解的I2C协议,用自己的单片机(如ESP32)模拟原MCU,直接向屏幕发送编码好的数据,就能驱动它显示我们想要的任何信息,把它变成一个通用的段码LCD显示器。
8. 实操心得与避坑指南
8.1 工具与焊接技巧
- 逻辑分析仪是必备品:对于数字协议逆向,一个哪怕是最基础的8通道逻辑分析仪也比单纯用示波器猜协议高效得多。Saleae Logic或国产的DSLogic都是好选择。
- 细线焊接:焊接排线或细小测试点时,使用吸锡线或助焊膏能极大提升成功率和美观度。先给焊盘上一点锡,然后用烙铁头同时加热焊盘和细导线头,待锡熔化后移开烙铁。使用放大镜或显微镜检查有无短路。
- 电源稳定性:逆向时使用可调稳压电源代替电池,可以方便地监测设备工作电流,并在出现短路等意外时快速断电。
8.2 协议分析策略
- 由简入繁:先识别电源和地,再找规律性最强的时钟信号(如SCL),最后分析数据信号(SDA)。
- 对比分析:多进行几次不同状态下的捕获(如开机、待机、测量中、测量完成),对比数据流的差异,是定位关键指令和数据的有效方法。
- 善用搜索:芯片型号、板号甚至设备型号加上“reverse engineering”、“schematic”、“datasheet”等关键词进行搜索,很可能发现前人留下的宝贵资料。
8.3 安全与注意事项
- 激光安全:尽管是消费级产品,激光仍可能对眼睛造成伤害。在逆向过程中,尽量避免直视激光发射口,尤其是在拆开外壳后。
- 静电防护:处理CMOS芯片和精细PCB时,佩戴防静电手环或在防静电垫上操作。
- 心理准备:逆向工程很可能“变砖”。在动手前要想好,设备损坏的风险是否可以接受。最好从已经闲置或损坏的设备开始练手。
这次对Parkside激光测距仪的逆向,从一个简单的拆解 curiosity 开始,到运用逻辑分析仪破解I2C协议,再到理解其TOF测距的系统架构,是一个典型的硬件逆向案例。它展示了如何通过“外部观察-接口探测-协议捕获-数据分析”的流程,一步步揭开消费电子产品黑盒。最终获得的不仅是控制一个屏幕或读取一个距离值的能力,更是一种对嵌入式系统如何协同工作的深刻理解。当你下次看到任何带有数字显示的小设备,或许都会忍不住想,它的内部是不是也藏着一条等待被解读的I2C总线呢?