1. 项目概述与核心思路

最近在折腾一个挺有意思的小玩意儿,我管它叫“多频段射频标签探测器”。简单来说,这玩意儿就是一个能主动发射特定频率的无线电波,然后“听”回音的低功耗手持设备。它的核心目标,是去发现那些可能被隐藏在各种物品(比如衣物、包裹夹层)里的RFID或类似原理的射频标签,无论这些标签的工作频率是已知的(比如常见的125kHz低频、13.56MHz高频)还是未知的。

为什么会有这个需求?在一些特定的安防检查、个人隐私保护或者物品溯源验证的场景下,确认某个物体内部是否被植入了非授权的电子标签,是个很实际的问题。市面上的专业设备要么太贵,要么功能单一(只能扫几个固定频段)。所以,我就琢磨着自己动手做一个,核心思路就是“主动探测+宽频扫描+信号分析”。

整个系统的基石是一块 ESP32-PICO-KIT 开发板。选它有几个很实在的理由:第一,它内置了高速ADC和DAC,这对于我们生成扫描信号和采集响应信号至关重要,省去了外接芯片的麻烦;第二,它的双核处理器性能足够,一个核可以专心负责控制射频信号的生成与发射时序,另一个核可以实时处理ADC采集回来的数据,进行快速分析;第三,低功耗模式做得不错,适合电池供电的手持设备;第四,片上资源丰富,GPIO、SPI、I2C等接口方便我们扩展外围电路。

项目的核心工作流程可以概括为:由ESP32的DAC产生一个快速变化的电压信号,这个信号经过外围的放大和驱动电路,转换成足够强度的电流,去驱动对应的天线线圈,从而向外发射一个短暂的、特定频率的电磁脉冲。脉冲发射完毕后,系统迅速切换到“接收”模式,通过同一个天线(或配套的接收天线)拾取空间中的电磁信号,经由放大和滤波电路处理后,送入ESP32的ADC。处理器会分析在发射脉冲之后这个特定时间窗口内,ADC采集到的信号特征,寻找是否存在异常的“回波”或谐振响应,从而判断该频率点附近是否存在一个能被激发的射频标签。

2. 硬件系统设计与核心电路解析

2.1 主控与射频前端架构

整个硬件系统围绕ESP32-PICO-KIT搭建,可以分为几个关键部分:主控模块、多频段天线驱动与切换电路、信号调理(放大/滤波)电路、电源管理模块以及人机交互界面(如按键、LED指示灯、小型显示屏)。

主控模块 就是ESP32-PICO-KIT本身。我们需要充分利用其模拟和数字资源。DAC(数模转换器)用于生成频率扫描的基准波形。这里有一个关键点:为了覆盖从低频(如100kHz)到高频(如900MHz)的宽范围,直接让DAC生成这么高频的正弦波是不现实的。DAC更擅长生成低频或中频的模拟电压信号。对于高频部分,我们的策略是使用DAC生成一个控制电压,去控制一个独立的 压控振荡器(VCO) 电路,让VCO产生我们需要的高频信号。因此,硬件设计上需要支持两种信号生成路径。

天线驱动电路 是核心难点。不同频段的天线(线圈)特性差异巨大。低频段(如125kHz)通常使用多匝空心线圈,电感量大,需要较高的驱动电压和电流才能产生足够场强。高频段(如13.56MHz, UHF)则可能使用PCB天线或小尺寸贴片天线,阻抗匹配网络至关重要。我的方案是设计多个并行的驱动通道,每个通道针对一个特定频段(或频段组)进行优化。

注意:天线驱动电路,尤其是功率放大部分,是功耗大户。在设计时必须仔细计算效率,选择饱和压降低的MOSFET或专用的射频功放芯片,并做好散热考虑。盲目增大功率不仅耗电,还可能产生干扰甚至对人体有潜在影响(尽管本项目功率很小,但原则要有)。

2.2 信号链路的详细拆解

让我们深入一个典型频段(以13.56MHz为例)的信号链路,看看信号是怎么“走”完一个探测周期的。

  1. 信号生成 :对于13.56MHz,我们可以让ESP32的DAC输出一个缓变的直流电压,控制一个13.56MHz的VCO,产生一个纯净的载波。更简单(但灵活性稍差)的方法是,使用一个专用的13.56MHz射频发射芯片,ESP32通过数字引脚控制其“发射使能”,使其在极短时间(微秒级)内工作。

  2. 功率放大与天线匹配 :VCO或发射芯片输出的信号功率很小(通常毫瓦级),需要经过一个 Class E Class D 功率放大器进行放大。这类放大器效率很高,适合电池供电。放大后的信号通过一个 π型匹配网络 连接到天线。这个匹配网络由电感和电容组成,其作用是使放大器的输出阻抗与天线的输入阻抗共轭匹配,从而将最大功率传输到天线,并辐射出去。匹配网络的计算需要基于天线的实际阻抗(通常用矢量网络分析仪测量),公式为 ( Z_{match} = \sqrt{L/C} ),需要调整L和C的值使得 ( Z_{out} = Z_{in}^* )。

  3. 收发切换 :发射脉冲结束后,必须立即断开功放与天线的连接,并将天线切换到接收链路。这里需要一个高速的 射频开关(RF Switch) 。我用的是单刀双掷(SPDT)开关,由ESP32的一个GPIO控制。控制时序必须非常精确,发射时开关掷向功放端,接收时掷向低噪声放大器(LNA)端。开关的切换时间(Switching Time)必须在百纳秒级别,否则会错过标签返回的初始信号。

  4. 接收与调理 :天线接收到的信号极其微弱(可能只有微伏级)。首先经过一个 低噪声放大器(LNA) 进行初步放大,增益大约20-30dB。LNA的选择要特别注意其噪声系数(NF),越低越好,这决定了整个接收链路的灵敏度。放大后的信号会包含各种杂波,因此需要经过一个 带通滤波器(BPF) ,中心频率就是我们刚才发射的频率(13.56MHz),带宽根据标签的响应特性来定,通常几十kHz到几百kHz。滤波后的信号再经过一级或多级可变增益放大器,将信号幅度调整到适合ESP32 ADC输入的范围(通常是0-3.3V)。

  5. 模数转换与采样 :调理后的模拟信号送入ESP32的ADC引脚。这里的关键是 采样时机和采样率 。我们不是在发射的同时采样,而是在发射脉冲结束后一个非常精确的延时后开始高速采样。这个延时是为了避开发射电路的余振和开关的瞬态干扰。采样率至少需要是被探测信号最高频率分量的2倍以上(奈奎斯特定律),对于13.56MHz的标签响应(其副载波或调制频率通常在几百kHz),几MHz的采样率是必要的。ESP32的ADC在高速采样时精度会下降,需要校准和滤波算法来弥补。

2.3 电源管理与低功耗设计

既然是手持设备,续航是硬指标。系统里既有数字电路(ESP32,逻辑芯片),也有模拟电路(放大器,VCO),还有射频功放这种“电老虎”。我的电源架构是这样的:

  • 主电源 :采用单节3.7V锂聚合物电池,容量选择2000mAh以上。
  • 电源管理芯片(PMIC) :选用一颗集成充电、升/降压、多路LDO输出的PMIC。它负责:
    1. 为锂电池充电(通过USB-C接口)。
    2. 将电池电压(3.0V-4.2V)稳定升压到5V,给射频功放供电(功放通常需要稍高电压以获得更大输出功率)。
    3. 从5V或电池电压降压,得到3.3V,给ESP32、数字逻辑、低功耗模拟电路供电。
    4. 从3.3V再降压或由独立的LDO产生1.8V、1.2V等,给核心模拟器件(如VCO、LNA)供电,确保电源纯净。
  • 低功耗策略
    • ESP32大部分时间处于 Deep Sleep 模式,仅由定时器或外部中断(如按键)唤醒。
    • 射频前端电路(VCO、功放、LNA)的电源由ESP32的GPIO通过MOSFET控制,仅在探测周期内上电,脉冲式工作。
    • 所有未使用的模拟通道,其放大器的使能引脚拉低,彻底断电。
    • 在人机交互间隙,显示屏背光自动调暗或关闭。

通过以上设计,整机待机电流可以控制在100μA以下,连续工作电流取决于探测频率和占空比,但支撑数小时的工作时长是可行的。

3. 固件设计与核心算法实现

3.1 系统状态机与任务调度

固件程序采用FreeRTOS实时操作系统,这能很好地利用ESP32的双核资源。我设计了一个主状态机来管理设备的工作流程:

  1. 休眠状态 :系统起点,所有外设断电,ESP32处于Deep Sleep。
  2. 唤醒与初始化 :按键唤醒后,系统初始化基础外设(GPIO、I2C用于屏幕、ADC/DAC配置),加载预设的频率列表和扫描参数。
  3. 扫描执行状态 :这是核心状态。它又被细分为多个子任务,运行在两个核心上:
    • Core 0 (控制核心)
      • 从频率列表中取出下一个目标频率 F_target
      • 配置射频开关至发射路径。
      • 根据 F_target ,计算并设置DAC输出波形或配置VCO控制电压(通过I2C/SPI)。
      • 触发“发射使能”GPIO,产生一个宽度为 T_pulse (通常10μs - 100μs)的脉冲。
      • 延迟一个精确的 T_guard 时间(用于等待发射电路关断和振铃衰减)。
      • 切换射频开关至接收路径。
      • 启动ADC的高速采样,采样点数为 N_samples
      • 将采集到的原始ADC数据放入一个队列(Queue)中,通知Core 1。
      • 等待Core 1处理完毕的信号,然后循环至下一个频率。
    • Core 1 (处理核心)
      • 等待ADC数据队列。
      • 对收到的ADC数据块进行实时处理(算法见下文)。
      • 将处理结果(该频率点是否有响应、响应强度等)存入结果数组。
      • 发送处理完毕信号给Core 0。
  4. 结果分析状态 :当预设列表中的所有频率扫描完毕后,系统进入此状态。Core 1对全局结果数组进行分析,寻找超过阈值的峰值点,结合频率信息判断标签类型。
  5. 报警/显示状态 :如果检测到疑似标签,则触发声光报警(蜂鸣器、LED闪烁),并在屏幕上显示检测到的频率和置信度。如果没有,则显示“Clear”并提示。
  6. 返回休眠或待机 :一次扫描结束后,根据设置,要么立即返回休眠状态,要么进入一个低功耗待机状态,等待下一次手动触发。

这种双核流水线设计,确保了在Core 1处理上一个频率的数据时,Core 0已经在准备下一个频率的发射,极大地提高了扫描速度。

3.2 核心检测算法详解

标签的响应信号通常非常微弱,淹没在噪声中。简单的幅度阈值检测完全无效。我采用了以下算法组合:

  1. 数字下变频与滤波 :对于每个频率点 F_target 采集到的ADC数据 s[n] ,首先进行数字下变频。我们生成一个同频的数字本振信号 cos(2π * F_target * n / F_s) 和正交本振 sin(...) ,其中 F_s 是采样率。将 s[n] 分别与这两个本振相乘,得到I路和Q路信号。这个过程相当于把以 F_target 为中心的信号搬移到基带(零频附近)。随后,对I、Q两路数据进行低通滤波,滤除高频噪声和可能存在的镜像频率成分。这个滤波器的带宽决定了系统的有效检测带宽。

  2. 功率计算与背景扣除 :计算滤波后I/Q数据的瞬时功率: P[n] = I[n]^2 + Q[n]^2 。理论上,如果存在一个与发射频率谐振的标签,在发射脉冲结束后,其自由衰减振荡会在这个功率序列 P[n] 中形成一个逐渐衰减的“小鼓包”。为了检测它,我们需要一个参考背景。我采用的方法是:在每次探测中,采集两段数据。第一段是紧接保护时间 T_guard 后的“信号段”,第二段是再延迟一段时间后的“背景段”(此时标签响应应已完全衰减)。计算两段数据的平均功率 P_signal P_background

  3. 统计检测与阈值设定 :最关键的步骤是判断 P_signal 是否显著大于 P_background 。不能用一个固定阈值,因为环境噪声会变。我使用了一种基于标准差的动态阈值方法。首先,计算背景段功率的标准差 σ_background 。然后,定义检测量 D = (P_signal - P_background) / σ_background 。这个 D 值近似服从某种分布(在无信号时接近零均值)。通过大量实验,我确定了一个经验阈值 D_threshold (比如5或6)。当 D > D_threshold 时,就认为在该频率点检测到了显著响应。

  4. 频域辅助分析(针对未知频率) :对于“未知频率扫描”模式,我们让DAC/VCO在一个宽频带内连续扫频。这时,除了上述时域功率检测,还可以对ADC采集的整个时间序列做FFT(快速傅里叶变换),观察频谱图。一个谐振标签的响应会在频谱上产生一个尖峰。将FFT峰值检测与上述时域检测结合,可以大大提高对未知频率标签的发现概率和频率估计精度。

实操心得:算法中的参数( T_pulse , T_guard , 滤波器带宽, D_threshold )都需要在实际环境中进行大量调试和校准。最好能找来几种常见的RFID标签(低频卡、高频门禁卡、超高频标签)作为测试样本,反复调整参数,直到能稳定检出。背景噪声的统计特性会随环境(靠近电脑、手机、金属物体)变化,因此算法中可以考虑加入自适应背景估计,比如用滑动窗口的方式持续更新 P_background σ_background

3.3 频率扫描策略与未知频率探测

“已知频率”模式很简单,就是遍历一个预置列表,如[125000, 134200, 13560000, 433920000, 868000000, 915000000](单位Hz),这些是常见的RFID频点。

“未知频率”模式则复杂一些。我们的硬件能力有限,无法真正做到从DC到几GHz的连续覆盖。我的策略是分波段扫描:

  1. 低频段(100kHz - 1MHz) :使用DAC直接合成正弦波扫描。步进可以设为1kHz或更小。这个频段速度可以很快。
  2. 中高频段(1MHz - 100MHz) :使用一个宽带VCO,例如覆盖10MHz到100MHz。通过DAC输出一个缓慢上升的斜坡电压,控制VCO线性扫频。步进精度由DAC的分辨率和VCO的线性度决定。
  3. 超高频段(800MHz - 1GHz) :使用另一个UHF波段的VCO。这是功耗最大的部分,必须严格控制每次扫频的发射时间。

在未知频率模式下,扫描步进和驻留时间(在每个频率点发射-接收的时间)需要权衡。步进越小,漏掉信号的可能性越低,但总扫描时间越长。我的经验是,步进设置为预估标签带宽的1/3到1/2。驻留时间则需要保证能采集到足够多周期的信号用于分析,通常每个频率点需要几毫秒到几十毫秒。因此,完成一个宽频段扫描可能需要几十秒甚至几分钟,但这对于隐蔽检查来说是可以接受的。

4. 制作、调试与实战问题排查

4.1 PCB设计与组装要点

这个项目的硬件成功与否,一半在于PCB设计。我建议使用至少4层板:顶层(信号和射频元件)、地层(完整地平面)、电源层(分割给不同电压)、底层(更多的信号和剩余元件)。

  • 射频布局黄金法则
    • 阻抗控制 :连接到天线端口的走线,必须做50欧姆(或设计所需的阻抗)的微带线阻抗控制。计算工具可以用SI9000,板材参数要填对(FR4的介电常数Er约4.2-4.5)。
    • 最短路径 :VCO到功放、功放到匹配网络、匹配网络到天线端口、天线端口到射频开关、开关到LNA的路径,必须尽可能短!任何多余的走线都是天线,会辐射或接收干扰。
    • 接地过孔阵列 :在所有射频元件周围,特别是接地焊盘附近,密集地打接地过孔,连接到内部完整地平面。这是提供良好射频回流路径、抑制谐振的关键。
    • 电源去耦 :每个有源射频芯片(VCO, 功放, LNA)的电源引脚旁边,必须紧挨着放置一个0.1μF的陶瓷电容和一个1-10μF的钽电容或陶瓷电容。小电容滤除高频噪声,大电容提供瞬时电流。
    • 隔离 :将数字部分(ESP32、逻辑电平转换器)和模拟射频部分在布局上尽量分开,用地缝或电源分割进行隔离。晶振下面绝对不要走线。

焊接时,优先焊接射频部分。使用热风枪和合适的焊膏,对于QFN等封装的芯片,确保每个引脚都焊接良好,没有桥接。焊接完成后,在显微镜下仔细检查。

4.2 系统调试流程实录

调试必须分步进行,切忌所有电路焊完一起上电。

  1. 电源树验证 :不插任何主要芯片,先上电,用万用表测量各电压节点(5V, 3.3V, 1.8V等)是否准确、稳定。确保没有短路。

  2. 数字控制通路测试 :插入ESP32,编写一个简单程序,测试控制射频开关、功放使能、VCO调谐电压的GPIO是否能正常输出高低电平或PWM。用逻辑分析仪或示波器观察时序是否正确。

  3. VCO与发射链路调试

    • 连接VCO,设置一个固定电压,用频谱分析仪探测其输出,看频率是否正确,功率是否正常,谐波是否在可接受范围。
    • 逐级向后连接:VCO -> 功放 -> 匹配网络。每连接一级,用频谱仪观察输出频谱和功率变化。调整匹配网络的电感和电容值(可以使用可调电容/电感进行初调),使在目标频率点的输出功率最大。 此时天线先不接,接一个50欧姆的假负载! 这是安全操作,防止失配反射烧毁功放。
  4. 接收链路调试

    • 发射链路关断。从天线端口(此时仍接假负载)注入一个很小的、已知频率和功率的信号(用信号发生器),经过LNA、滤波器、放大器,最终用示波器在ADC输入引脚测量。调整各级放大器的增益,确保信号幅度在ADC量程内,且没有失真。观察滤波器的带通特性。
  5. 整机联调与算法验证

    • 接上真实天线(注意:在封闭空间或远离人体/敏感设备时进行初步测试)。
    • 放置一个已知频率的标签在附近。
    • 运行探测程序,用示波器同时抓取“功放使能”信号(发射脉冲)和ADC输入信号。你应该能在发射脉冲结束后,看到ADC信号上有一个微弱的、振荡衰减的响应。
    • 打开串口调试,观察算法输出的 P_signal , P_background , D 值。当标签靠近时, D 值应显著增大。
    • 反复调整 T_guard (消除发射泄漏)、算法阈值、滤波器参数等,直到能稳定、可靠地检测到标签,同时误报率(无标签时报警)极低。

4.3 常见问题与排查技巧速查表

在实际制作和调试中,我踩过不少坑,下面这个表格总结了一些典型问题及排查思路:

问题现象 可能原因 排查步骤与解决方案
上电后电流极大,芯片发烫 电源短路或芯片损坏。 1. 立即断电!
2. 用手触摸各芯片,找到发烫最严重的。
3. 用万用表蜂鸣档检查该芯片电源对地是否短路。
4. 检查PCB是否有焊接桥连,特别是引脚密集的芯片。
发射时,ADC采集到的全是饱和噪声 发射到接收的切换太慢,或隔离度不够,强大的发射信号直接泄漏/耦合到了接收链路。 1. 检查射频开关的控制时序,确保在ADC开始采样前,开关已完全切换到接收端。
2. 用示波器观察ADC输入引脚在发射期间的电压,如果看到大幅度的脉冲,说明有泄漏。
3. 增加发射与接收之间的物理隔离(用地平面隔开),或在接收链路前端增加一个限幅器/保护电路。
能检测近处标签,但灵敏度很低,距离稍远就失效 发射功率不足,或接收链路噪声系数太大,或天线效率低。 1. 用频谱仪+近场探头测量天线附近的场强,对比理论值。
2. 检查功放的工作电压和偏置是否正常,输出匹配网络是否调至最佳。
3. 测量接收链路的总增益和噪声系数。确保LNA是第一个有源器件,且其噪声系数足够低。
4. 优化天线设计,或更换性能更好的天线。
扫描已知频率正常,但未知频率扫描总是漏检 扫频步进太大,或每个频率点的驻留时间太短,导致“瞄”不准标签的谐振频率。 1. 使用一个已知但未录入的标签进行测试。
2. 减小扫频步进(如从100kHz降到10kHz)。
3. 增加每个频率点的采样时间,采集更多数据做平均。
4. 尝试在频域分析(FFT)模式下的分辨率,看是否能观察到宽频扫描下的峰值。
设备在特定环境(如靠近电脑)误报率高 环境中的电磁干扰(电脑、手机、开关电源)被天线接收,其强度超过了检测阈值。 1. 在算法中增加“背景学习”阶段。设备启动后,先在不发射的情况下采集一段环境噪声,估计其统计特性,动态调整检测阈值 D_threshold
2. 在硬件上,可以考虑为接收链路增加一个窄带的、可调谐的滤波器,跟随扫描频率一起变化,滤除带外干扰。
电池续航远低于预期 射频功放或VCO等模拟电路未做到按需供电,或者软件未进入深度睡眠。 1. 用电流探头测量设备在不同状态(休眠、待机、发射、接收)下的整机电流。
2. 检查所有由GPIO控制的电源开关MOSFET,确认其在关断时漏电流是否在合理范围(nA级)。
3. 确认ESP32在扫描间隙是否进入了Light Sleep或Deep Sleep模式。检查所有可能阻止睡眠的外设(如未释放的SPI总线、保持上拉的下拉中断引脚)。

最后,关于天线的选择,这是一个大学问。对于低频(125kHz),你需要一个直径很大(可能10cm以上)、匝数很多(几十上百匝)的空心线圈。对于13.56MHz,可以使用PCB螺旋天线或小型的绕线天线。对于UHF频段,通常使用PCB倒F天线(PIFA)或陶瓷贴片天线。最好的建议是: 对于你不熟悉频段的天线,直接购买成熟的商用天线模块 。自己设计天线,没有矢量网络分析仪进行调试和匹配,成功率很低,会严重拖累整个项目的性能。把精力集中在电路和算法上,天线用现成的靠谱模块,这是项目快速成功的关键。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐