ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

多普勒雷达测速监视器:从24GHz模块到FFT算法与STM32实现

多普勒雷达测速监视器:从24GHz模块到FFT算法与STM32实现 前阵子朋友拿了个测速雷达模块给我看说想在家里装一台能显示来车速度的监视器。我第一反应是测速这活儿最靠谱的方案不是摄像头也不是地感线圈而是雷达本身。雷达测速不吃光照、不怕雨雾、甚至不需要目标配合直接利用多普勒频移就能把速度算出来交管部门用的手持测速枪、固定测速单元底层也都是这个原理。这篇就围绕“A Radar Speed Monitor”这个项目展开把它从原理到硬件到算法完整拆一遍。文章会覆盖多普勒测速原理、24GHz雷达模块选型、中频信号调理、FFT测频算法、标定方法与实测数据最后也顺带聊一下TI毫米波雷达TI Radar的进阶玩法。适合电子爱好者、嵌入式开发者也适合拿来做课程设计或智能交通方向预研的朋友。1. 项目定位一台雷达测速监视器到底在做什么1.1 这个项目的核心思路雷达测速监视器说白了就是一套“非接触式速度测量系统”。它不需要接触被测物体只要目标进入天线波束覆盖区域就能通过电磁波反射回来的频率变化反推出目标的径向速度。整个项目拆成三个部分来看就非常清晰前端感知层24GHz多普勒雷达模块负责发射微波、接收回波、混频后输出中频信号IF。这个模块是关键但不需要自己设计射频链路市面上有现成的模块可选。中间信号调理层雷达模块输出的IF信号很微弱幅度通常在微伏到毫伏级别噪声还不小。需要经过带通滤波、多级放大再送给MCU的ADC采样。后端处理层MCU里跑FFT把时域信号变到频域找到多普勒频移的峰值频率再用公式换算成速度最后显示在OLED屏幕上或输出超速报警信号。我当时选这个方案看重的是它的普适性。芯片不长眼睛但装上雷达模块就能“看见”运动的物体再加上速度解算它就从一个简单传感器升级成了完整的监视仪表。1.2 我为什么坚持用雷达做测速测速这件事市面上的方案其实不少。红外对射、地感线圈、摄像头视频识别、激光测速各有各的适用场景。但作为个人项目雷达有几个非常突出的优势不依赖光照晚上、大雾、逆光环境对雷达完全没有影响。摄像头就做不到这一点。测量直接雷达直接输出与速度相关的多普勒频移不需要经过复杂的图像识别和目标跟踪。安装灵活雷达模块体积小可以挂在墙面、立杆侧装、正对来车方向装不需要破坏路面。成本可控一颗24GHz多普勒雷达模块几十块钱加上一片STM32整体物料成本不到一百块就已经能做出一台看得见读数的测速监视器。当然雷达也不是万能的。它测量的是“径向速度”也就是目标相对雷达收发方向的速度分量如果车辆斜着经过测出来的数值会比真实车速小这个靠安装角度标定可以修正。另外雷达模块的波束角通常在几十度范围近了能照到多个目标远了目标回波又弱所以测速距离和安装高度需要实际调。说白了这套东西上限很高但下限也取决于使用者是否把细节处理好。2. 原理拆解多普勒频移与TI毫米波雷达方案2.1 多普勒效应从警笛到雷达频移多普勒效应在生活中最典型的例子是警笛。救护车朝你开过来的时候你听到的声音音调变高远离你的时候音调变低。音调本质上就是频率所以这个现象可以概括成波源与观察者之间有相对运动时观察者接收到的频率会发生变化。雷达测速用的也是这个原理只不过把声波换成了电磁波。雷达模块发射频率为 f0 的微波遇到运动目标后反射回来反射波的频率变成了 f0 fd这个 fd 就是多普勒频移。对于雷达这种“发射-反射-接收”的结构频移公式是fd 2 * v * cosθ * f0 / cfd多普勒频移单位Hzv目标运动速度单位m/scosθ目标运动方向与雷达波束方向夹角的余弦f0雷达发射频率单位Hzc光速约3×10^8 m/s为什么有个系数2因为电磁波走了“发射到目标”和“目标反射回来”两段路程。目标靠近雷达 d 的距离电磁波总路径就缩短了 2d对应的相位变化是 4πdf0/c相位对时间求导再除2π就得到了两倍频移。拿24GHz雷达来算几个实际数值你会立刻明白为什么这套系统能做得简单步行速度 1.4m/sfd 2×1.4×24.125×10^9 / 3×10^8 ≈ 225Hz车速 10km/h约2.78m/sfd ≈ 447Hz车速 100km/h约27.8m/sfd ≈ 4472Hz也就是说目标从步行到两百公里时速对应的多普勒频移基本落在 200Hz 到 9000Hz 这个区间。这个频段是音频级别的普通的音频ADC、普通的单片机就能处理成本一下就降下来了。2.2 FMCW与TI Radar原理看不懂也不影响先跑通24GHz多普勒雷达模块能测速度但测不了距离。想要同时测距测速就得换体制比如FMCW调频连续波。这里插一句TI Radar也就是德州仪器TI的毫米波雷达方案它用的正是FMCW。TI的毫米波雷达芯片比如IWR1443、AWR1443、IWR6843内部集成了完整的射频前端、ADC和DSP。它的原理是发射频率随时间线性变化的chirp信号回波信号与本地振荡器混频后得到差频IF信号。这个IF信号的频率包含了两个信息目标的距离差频频率 f_IF 正比于目标的距离目标的速度IF信号的相位在相邻chirp之间会变化这个相位变化率对应多普勒频移处理时先对一个chirp内的IF信号做FFT得到“距离维”峰值再对同一距离单元上多个chirp的相位变化做FFT得到“多普勒维”峰值这就是常说的距离-多普勒二维FFT。TI提供了一整套mmWave SDK和可视化工具把底层都封装好了我后面在进阶部分会再细说怎么把TI方案接到这个测速项目里。2.3 雷达、摄像头、地感线圈三套方案对比我经常被问到为什么不用摄像头做速度识别我理解大家都觉得摄像头方案“更智能”但它把问题变复杂了。下面这张对比表是我在实际项目中反复用到的直接说结论项目微波雷达摄像头视觉地感线圈测速方式多普勒频移 / FMCW目标检测跨帧跟踪两个线圈时间差环境适应性全天候雨雾不受影响受光照、雨雾、遮挡影响大受天气影响小安装维护灵活挂杆/侧装均可需要视野和角度定期清洁镜头必须破路埋设维修麻烦算法复杂度低FFT即可高需要目标识别与跟踪低但定位精度有限成本中低中高低但施工成本高雷达方案中间的平衡点最舒服。它不像摄像头那样依赖智能算法也不像地感线圈那样需要破坏路面同时精度又足够满足绝大多数非计费类测速场景。这也是我建议业余玩家优先选择雷达来做速度监视项目的原因。3. 系统设计硬件架构与器件选型3.1 整体链路从天线到屏幕的完整信号流一个完整的雷达测速监视器信号链路可以分成五个环节天线发射/接收 → 混频输出IF → 带通滤波 → 放大 → ADC采样/FFT → 速度显示核心判断在后面MCU不直接处理高频信号它只处理雷达模块混频后输出的“慢信号”。所以真正决定项目成败的是把IF信号调理好而不是去折腾射频。我在实际设计中把系统分成了两个板子一块是模拟前端负责滤波和放大另一块是数字主板负责采样、FFT和显示。两块板子分开的原因很简单模拟小信号和数字电路混在一起容易引入地回路噪声。如果你做一体板也要注意数字部分和模拟部分尽量分地最后单点接地。3.2 测速雷达模块选型避开新手最容易踩的坑市面上的24GHz雷达模块非常多但并不是所有叫“雷达模块”的东西都能测速。按输出类型分大致有三类多普勒IF输出模块典型代表是HB100工作在24.125GHz模块内部有振荡器和混频器输出的是与目标运动相关的模拟IF信号。这个信号需要自己放大和采样适合做测速。这是自制测速监视器最合适的模块类型。通断信号输出模块比如RCWL-0516内部已经把IF信号和阈值比较最终输出高/低电平。它的用途是人体感应、存在检测无法直接用来测速。很多新手买了类似模块回来发现拿不到多普勒信号就是被这一点坑了。带串口输出的测速雷达模块部分国内厂商直接在模块里集成DSP串口直接输出速度值和目标距离。这类模块用起来简单但价格偏高而且算法细节被封装成黑盒对于想学习原理的读者不太推荐。如果是从零开始做我建议首选HB100或同类IF输出模块。它便宜、资料多、原理透明唯一的门槛是信号放大和噪声处理但把这关过了你基本就吃透了整个雷达信号链路。装机时还有一个细节容易被忽略天线正面的波束方向。HB100的天线面是有方向性的安装时要让天线面朝向被测车道且尽量让波束主瓣与车辆行驶方向有一定夹角而不是完全垂直。完全垂直时径向速度分量趋近于零测出来会非常不准。3.3 中频信号调理电路放大倍数和带宽怎么定IF信号调理是整个项目里最容易出问题、也最需要耐心调试的环节。HB100这类模块输出的IF信号幅度小到令人怀疑人生有资料给出典型值是几十微伏到几毫伏具体取决于目标距离和反射面积。而STM32的ADC输入范围是0~3.3V中间差了至少40dB还需要把信号偏置到ADC量程中心这就必须放大。我使用的调理链路是第一级带通滤波先做无源RC高通截止频率约10Hz把低频直流漂移和热噪声滤掉再做有源低通截止频率约10kHz抑制高频干扰。第二级放大用低失调、低噪声运放做同相放大第一级增益20倍第二级增益50倍总增益1000倍60dB。两级放大比单级1000倍更稳不容易自激。第三级偏置把放大后的交流信号叠加到1.65V直流偏置上使ADC可以采集完整的正负波形。这里说一下为什么带通很关键。多普勒频移范围是200Hz到9kHz但IF输出里还有低频的人体慢速移动、模块热漂移、日光灯谐波等干扰。如果不去掉这些FFT峰值可能落在一个完全错误的位置。带宽太宽也不行高频噪声会抬高整个频谱底导致小目标的峰值淹没在噪声里。运放选型方面我试过LM358也能工作但效果不理想低频噪声偏大放大后的信号底噪不干净。后来换了MCP6002或OPA2333这类低功耗、低失调轨到轨运放明显好很多。如果你是第一次搭直接上低噪声运放能少走很多弯路。3.4 MCU、ADC采样与显示方案MCU方面STM32F103就足够跑完整的FFT不需要上太高端的芯片。我用的是STM32F103C8T6ADC 12位采样率最高1MHz而我们的信号频率不到10kHz绰绰有余。你如果只想做原型Arduino Due或ESP32也都没问题但ESP32的ADC线性度一般最好在软件里做一次校正。ADC采样频率参数直接决定FFT的频率分辨率和最大可测速度。以24GHz雷达为例计算过程是采样率 Fs 20kHz按照奈奎斯特定理最高能测量的多普勒频率是10kHz对应速度约223km/h覆盖家用车完全没问题。FFT点数 N 1024频率分辨率 Δf Fs / N ≈ 19.5Hz对应速度分辨率约0.44km/h。如果提高到 N 2048Δf ≈ 9.8Hz速度分辨率约0.22km/h。所以奈奎斯特限制的是“最大速度”FFT点数限制的是“读数精度”。想要高速且高精度就同时提高采样率和FFT点数但代价是MCU的计算量和内存占用。STM32F103的FPU都没有1024点FFT跑下来大概几十毫秒用来做秒级速度刷新完全够。显示部分我推荐0.96寸OLED直接显示“xx.x km/h”和“接近/远离”状态。另外留一个串口方便接上位机画实时频谱图调试这个在做FFT调参时非常有用。4. 实操实现从焊接到底层算法4.1 硬件调试流程与注意事项拿到板子先别急着写代码先用示波器或者至少用ADC连续采样把模拟链路调通。第一步给雷达模块供电确认工作电流正常。HB100工作电流几十毫安如果电流异常先查电源。第二步把示波器探头接在雷达模块IF引脚上用手在模块前快速挥动观察是否有几十到几百毫伏的杂乱波形。如果波形幅度太低说明放大链路可能需要提前介入或者目标距离太远。第三步接好调理电路后再用手挥动此时输出信号应该已经被放大到百毫伏甚至伏级噪声底明显抬高但不会削顶。第四步在ADC输入端用万用表量直流偏置应该稳定在1.65V左右。我踩过的一个比较大的坑是电源。雷达模块和放大电路如果直接接在USB 5V经过AMS1117降压后的电源上纹波会直接耦合进IF信号FFT频谱里会出现一大片低频毛刺甚至把多普勒峰值盖住。解决办法是给模拟部分单独用低噪声LDO供电比如LM1117或者更干净的LDO。还有就是模拟地单点接不要跟数字地大面积敷铜直接连在一起。4.2 采样与FFT代码实现软件框架不复杂难的是把FFT结果用得稳。#define FFT_SIZE 1024 #define SAMPLE_RATE 20000 float32_t fftInput[FFT_SIZE * 2]; // 实部虚部交错存放 float32_t fftOutput[FFT_SIZE]; // 幅度谱 float32_t window[FFT_SIZE]; // ADC采样完成中断里把当前值存入fftInput void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { fftInput[fftIndex] (adcValue - 2048) / 2048.0f; // 归一化到[-1,1] fftInput[fftIndex 1] 0; fftIndex 2; if (fftIndex FFT_SIZE * 2) fftIndex 0; } // 每采样满一帧执行FFT并找峰值 void processSpeedFrame(void) { // 1. 加窗抑制频谱泄漏 for (int i 0; i FFT_SIZE; i) fftInput[i * 2] * window[i]; // 2. 执行复数FFT arm_cfft_f32(arm_cfft_sR_f32_len1024, fftInput, 0, 1); arm_cmplx_mag_f32(fftInput, fftOutput, FFT_SIZE); // 3. 在有效频段内找峰值 int peakIndex 0; float peakValue 0; for (int i 5; i FFT_SIZE / 2; i) { if (fftOutput[i] peakValue) { peakValue fftOutput[i]; peakIndex i; } } if (peakValue threshold) { float freq (float)peakIndex * SAMPLE_RATE / FFT_SIZE; convertFreqToSpeed(freq); } }这段代码有两个细节要注意。加窗FFT默认假设信号是周期的如果帧数据首尾不连续频谱会泄漏峰值旁边出现一堆旁瓣。我用了汉宁窗主瓣稍微展宽但旁瓣压制效果好测速时不容易误判。找峰我把搜索范围限制在5到512之间也就是频率从100Hz到10kHz。低于100Hz的包括电源噪声、人体慢移动、热漂移直接忽略高于10kHz是奈奎斯特以上理论上不该出现有效信号。4.3 速度换算与平滑输出找到频谱峰值后速度换算其实就是一个公式void convertFreqToSpeed(float freq) { static const float C 3.0e8f; static const float F0 24.125e9f; // 雷达中心频率 float speed_mps freq * C / (2.0f * F0); float speed_kmh speed_mps * 3.6f; if (speed_kmh 1.0f) speed_kmh 0; // 低速死区避免零漂 displaySpeed(speed_kmh); // 串口输出原始freq和speed方便上位机标定 printf(freq%.1fHz speed%.1fkm/h\n, freq, speed_kmh); }读到的频率如果直接用会有一点跳变。我在工程里做了两级的平滑先用中值滤波把单帧偶发尖峰去掉连续5帧取中间值再用滑动平均输出给显示。这样显示数值不会乱跳但也不会迟钝到跟不上速度变化。一个特别容易忽略的点是“低速死区”。没有目标时FFT的噪声底可能偶尔超过阈值导致速度显示几十公里这样的离谱值。我设了1km/h死区低于这个值一律显示0仪表类设备宁可少显示也不能显示错误值误导人。4.4 标定流程与cosθ修正如果雷达模块正对着来车方向多普勒公式里的cosθ近似等于1。但实际安装时模块天线面和车道方向总是有夹角导致实测频移偏小。我的标定方法是选择一段平直路段把雷达装在固定支架上。用手机GPS测速软件记录车辆实际速度同时记录雷达显示速度。在30km/h、50km/h、80km/h几个速度点各记录几组数据。把GPS速度和雷达频移频率线性拟合得到实际的比例系数。这一步很有必要。因为雷达模块标注的中心频率24.125GHz是标称值实际模块可能偏差几十MHz这个误差会直接反映到速度计算里。与其去校准频率不如直接标定最终比例系数一次搞定。5. 实测记录与常见问题排查5.1 实测数据记录我搭好样机后在小区车道做了几组测试目标选择的是行人和低速电动车场景目标类型距离雷达读数参考值备注1步行5m5.2 km/hGPS约5.0 km/h读数稳定2慢跑5m8.8 km/h手环约9.0 km/h略有偏差3电动车10m24.6 km/hGPS约24.0 km/h误差很小4电动车20m23.1 km/hGPS约24.5 km/h距离远时底噪升高5挥手人体2m无读数无横向速度分量太小这个结果验证了两件事近距离测速精度可接受远距离时因为目标回波弱叠加噪声导致读数偏差变大。如果要做远距离测车建议提高增益并把雷达架高让天线波束尽量照射到车身侧面。5.2 常见问题速查表我把项目中遇到的高频问题整理成表方便直接对照现象可能原因解决方法无读数放大链路没通IF信号太小先用示波器/ADC观察原始IF手挥动确认读数乱跳阈值太低噪声峰值被误判提高阈值加窗增加中值滤波读数始终偏高没设低速死区小于1km/h强制显示0靠近目标反而无读数信号削顶导致频谱失真降低放大倍数或增加AGC距离远灵敏度低增益不够或天线角度偏提高放大倍数调整天线对准方向上电后频谱底噪很大电源纹波及模拟地干扰换低噪声LDO模拟地单点接地串口打印乱码波特率不匹配或电平问题检查串口设置和共地5.3 TI毫米波雷达进阶从速度监视到多目标感知基础版雷达速度监视器跑通后如果想往更专业的方向走TI的毫米波雷达平台是目前最合适的进阶路径。TI Radar的原理前面已经提过核心是FMCW体制。它发射的是线性调频的chirp信号接收端和本振混频得到一个与距离成正比的IF频率。通过在快慢两个维度分别做FFT可以同时获得目标的距离、速度和角度信息还能检测多个目标。实际操作中IWR1443和AWR1443是两款很好上手的评估板搭配DCA1000数据采集卡可以在PC端实时拿到原始ADC数据。TI官方SDK里提供了presence detection、vital signs、traffic monitoring等多个参考例程你甚至可以在无编程情况下先把实时可视化界面跑起来看到目标在地图上移动。把TI方案接入测速项目能带来的升级是全方位的多目标同时跟踪区分行人、轿车、卡车同时输出距离和速度自动排除远处无关物体更高的角度分辨率能判断目标从哪个车道经过不过TI方案门槛也高不少先要有基本的嵌入式开发基础还要理解FFT和毫米波算法。我的建议是先用24GHz多普勒模块把整个测速链路跑通再平滑过渡到TI毫米波平台这样知识体系不会断。5.4 长期使用中的几个经验这个项目我前后迭代了三版有几点经验对长期稳定运行特别重要。第一金属外壳会导致雷达天线方向图畸变。我最初把整个系统放进一个金属接线盒里结果灵敏度大幅下降。后来在天线正面开了窗口或者干脆用塑料外壳问题就消失了。第二FFT噪声底会随环境温度变化。冬天和夏天频谱底噪可能相差几个dB固定阈值在一段时期后可能失效。我在软件里加了一个底噪统计每次FFT后取非峰值频段的中位数作为噪声底阈值跟随噪声底自适应浮动半年没再误报过。第三如果有条件给系统加个实时频谱显示。调试时把FFT幅度谱通过串口画在上位机里肉眼看到峰值落在哪个频率比看数字直观得多。我用的方式是写了一个简单的Python脚本读串口数据直接绘制频谱图这也是调参时的核心工具。最后再分享一个小技巧单通道雷达模块区分不了目标靠近还是远离因为FFT只能给出幅度谱相位信息被丢了。如果能买到带I/Q两个输出的模块再做一次正交解调就能判断运动方向还可以结合两个通道的相位差计算目标的真实运动轨迹。这套扩展不复杂但需要外接一个正交采样电路是整个项目里性价比最高的升级方向之一。
返回列表