尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于STM32的超声波风速风向测量仪设计与RS485组网实现

基于STM32的超声波风速风向测量仪设计与RS485组网实现 简介本资源是一套基于STM32平台实现的超声波风速风向测量系统完整工程面向嵌入式开发初学者、气象传感项目开发者及高校课程设计实践者解决传统机械式风速风向仪精度低、易磨损、响应慢等痛点适用于环境监测、农业物联网、小型气象站等场景。压缩包共397个文件涵盖113个头文件h、74个源码文件c及大量编译中间产物o、d、crf等包含HAL库驱动如uart、spi、tim、i2c、超声波时差法测风核心算法、RS485通信协议栈及Keil MDK工程配置uvprojx、axf、hex、sct等结构完整、模块清晰便于理解传感器数据采集、处理与远传全过程。已有1088人学习下载提供可直接编译运行的实战代码、典型外设配置范例及硬件接口定义说明是掌握STM32多外设协同与物理量精密测量的优质参考工程。 很多搞气象、农业物联网、风机监测的朋友都问过我手头想做一套能测风速又能测风向的仪表市面上成品太贵开源的方案又多是测距或者单风速。去年我基于STM32做了一款带RS485输出的超声波风速风向测量仪从原理验证到风洞标定折腾了一个多月目前已经稳定跑在几个农业大棚和楼宇通风系统上。这篇就把整个项目的完整设计思路、硬件电路、固件算法、RS485通信处理和调试坑位全部梳理出来给想自己做一套的工程师当参考。这套设备的核心价值在于超声波测风没有任何机械转动部件对比传统风杯式和风标式传感器不怕冰冻、不怕沙尘、响应快而且通过RS485总线可以轻松组网一台主机挂几十个节点都没问题。它适合农业气象站、智慧城市微气象监测、港口塔吊安全报警、屋顶光伏电站风速保护这类场景。如果你手里有STM32最小系统板和两对超声波换能器跟着下面的思路完全可以自己复现一套。1. 项目整体设计与思路拆解1.1 超声波风速风向测量的核心原理先说测量原理。超声波的测量方案主要有两种时差法和相位差法。市面上绝大多数产品用的是时差法原因很简单相位差法容易受温度漂移和换能器老化影响而时差法是绝对的物理时间测量稳定性好得多。时差法听起来很高大上其实拆开就是初中物理声波在顺风时传播得快逆风时传播得慢。把一对超声波换能器面对面放置间距为L分别测量声波从左到右的传播时间t1和从右到左的传播时间t2风速v的关系可以表达为v L × (1/t1 - 1/t2) / 2如果用顺逆风时间差来算还能简化成v L × (t2 - t1) / (2 × t1 × t2)注意公式里的L是两探头之间的有效声程距离t1和t2是单向传播时间。这里有个工程细节测量出来的风速其实是沿声波传播路径的分量要得到真实水平风速和风向就需要布置两对正交的换能器一对测X轴风速分量另一对测Y轴风速分量再通过三角函数合成。风向角度的计算公式是角度 atan2(Vy, Vx) × 180 / π这里用atan2而不是atan因为atan2能正确处理四个象限的角度问题直接得出0-360度的风向角不需要额外判断象限。1.2 系统整体架构与硬件选型思路整个系统的架构分为六个模块主控MCU、超声波换能器驱动电路、接收信号调理电路、温度传感器、RS485通信电路、电源系统。主控选择STM32F103C8T6。这颗芯片几乎是国产嵌入式开发的“万金油”主频72MHz内置64KB Flash和20KB RAM价格便宜资源充裕。关键是它有两个高级定时器TIM1和TIM8支持输入捕获和PWM输出对超声波收发控制非常合适。超声波换能器选择的是40kHz的压电陶瓷探头比如TCT40-16T和TCT40-16R这种。选40kHz是因为空气中这个频率段的声波衰减相对较小发射接收灵敏度均衡而且市面上这类探头大量用于倒车雷达好买、便宜、一致性也不错。RS485收发器选了SP3485是3.3V供电的可以直接和STM32 GPIO电平对接不像MAX485那样还需要5V转3.3V电平匹配。SP3485的空闲电流只有1μA左右对低功耗场景很友好。供电方案做的是宽压输入DC 9~30V进来经MP2451降压到5V再用AMS1117降到3.3V。为什么要宽压因为工业现场供电环境五花八门常见的是12V和24V留出余量就做了宽压。1.3 为什么选择RS485作为对外通信接口很多人问为什么不用RS232或者直接走TTL串口原因很简单风速仪这种东西经常装在室外立杆上离上位机可能几百米远TTL串口几米就废了RS232也就十几米。RS485是差分信号传输抗共模干扰能力强传输距离可以达到1200米而且支持多节点组网一条双绞线总线挂32个设备加了中继还能更多。还有个重要原因RS485是半双工总线可以挂载到现成的工控系统、PLC、DTU上。很多农业物联网网关、气象数据采集器标配RS485接口用的Modbus-RTU协议。所以这个项目把RS485通信作为标准配置协议层直接走Modbus-RTU这样可以和市面上大多数上位机软件无缝对接。2. 核心硬件电路设计与实操要点2.1 超声波换能器收发电路超声波换能器收发电路是整个系统最容易翻车的地方直接决定了测量精度和信号质量。发射电路方面40kHz的换能器需要足够高的驱动电压才能产生足够强的声波信号。STM32的GPIO输出3.3V直接驱动是远不够用的实测信号衰减非常快。我用了变压器升压方案用TIM1输出40kHz的方波去驱动一个推挽MOS管对再经一个变比1:10的脉冲变压器升压到几十伏的交流脉冲加在发射换能器两端。变压器用的是EE13磁芯初级4匝、次级40匝初级并联一个4.7nF电容形成谐振。这里有个调试技巧40kHz方波经过变压器后波形会有振铃这不是坏事反而可以利用谐振让换能器获得更高的峰值电压。但要控制振铃幅度必要时在初级并联一个1kΩ电阻做阻尼。接收电路就不能直接接换能器了。接收换能器输出的信号非常微弱是微伏到毫伏级别必须先经过放大和滤波。我用的是两级放大结构第一级用高频运放AD8628做10倍放大第二级再做一个带通滤波器中心频率40kHz带宽约5kHz。信号经过带通滤波后干净很多再送入比较器LMV331整形最后输出为标准方波给STM32的TIM1输入捕获通道。这里有个容易忽略的坑接收信号在未到达真正波峰之前可能就能触发比较器翻转产生提前触发的“假波”。传统的解决办法是加自动增益控制AGC或者用固定阈值加迟滞比较。我用了一个简单方案比较器阈值不固定而是通过单片机DAC动态调节第一轮粗测时用高阈值判断出大致信号到达位置后第二轮再用低阈值精确捕获这样可以大幅提高时间测量的抗干扰能力。2.2 RS485硬件电路与保护设计RS485电路看似简单实际是在现场最容易出问题的环节。先看基本电路SP3485的RO接STM32的USART2_RXDI接USART2_TXDE和RE并联后接一个独立GPIO控制引脚。注意一定要用独立GPIO控制收发方向不要图省事把DE和TXD信号直接连在一起否则数据发送结束瞬间可能会出现方向切换毛刺。A、B两端各串一个10Ω电阻后接端子用来限制意外短路时的电流。然后A、B之间要接一个120Ω的终端匹配电阻。这里说下我的理解终端匹配电阻的作用是吸收信号在总线末端的反射如果总线上只挂了这一个设备而且线很短不接匹配电阻问题不大但如果线长超过几十米或者在总线上挂了多个设备则必须在最远两端各接一个120Ω电阻中间的设备不接。除了终端电阻A、B线各加一个TVS管SMBJ6.0CA到地共模电压超过6V就钳位。如果装在现场环境恶劣、可能遭遇雷击的场景建议前端再加一个气体放电管和PTC自恢复保险丝形成三级防护。我自己的测试板第一版没加TVS夏天打雷烧了一块后来加上再也不怕了。还有个贴心设计A线接一个上拉电阻到VCCB线接一个下拉电阻到GND两个都是5.1kΩ。这样设计的目的有两个一是总线上所有设备都处于接收状态而没有任何设备发送时保证A、B间有确定的差分电平不会出现通信状态不确定问题二是在设备上电瞬间SP3485还没初始化完成前总线电平被偏置到确定状态避免误触发干扰其他节点。2.3 电源系统与低功耗设计电源这块我用的是DC-DC加LDO两级方案。MP2451把9~30V输入降到5V效率能到85%左右然后AMS1117-3.3把5V降到3.3V给MCU和数字电路供电。模拟部分运放和比较器的供电单独加了一个LC滤波电感用10μH电容用10μF加0.1μF就是为了防止数字电路开关噪声串到模拟链路上影响测量精度。整体系统电流实测约35mA其中超声波换能器发射瞬间电流能到200mA峰值所以电源按300mA余量设计。如果以后要做电池供电版本可以考虑降低超声波发射重复频率比如每秒只测一次而不是连续测10次电流能降很多。系统里还留了一个传感器供电选项直接输出5V给外接温度传感器、气压计供电方便以后扩展。STM32内部虽然有温度传感器但精度太差我选了外接DS18B20或者SHT30实测对声速补偿非常重要后面算法部分还会细说。3. 时差法测量算法与固件实现3.1 高精度时间测量的关键实现超声波时差法成功的关键就是时间测量精度。1毫米的测距误差在风速上会体现为大约0.2m/s的误差所以时间测量至少要达到微秒级精度。STM32F103的定时器输入捕获可以做到很高精度。我把TIM2配置为72MHz计数频率即每14ns计数一次输入捕获通道CH1和CH2分别连接两个方向接收信号。当换能器A发射、换能器B接收时TIM2_CH1捕获到接收信号的时间戳反过来B发射、A接收时TIM2_CH2捕获时间戳。这两个时间戳相减再修正电子延时就得到了顺逆风的精确时间差。但驱动电路和接收电路都会引入固定延时比如滤波器相移、比较器传播延时这些延时在计算时需要校准。校准方法很朴素在无风条件下两对换能器测出来的时间差理论上应该是零如果实测有偏差就是电子延时差异把这个值存到Flash里作为校准偏移量。实际标定发现这个偏移量大概在2~5μs之间。时间戳读取之前还有个细节必须确认捕获信号对应的确实是直达波而不是反射波。工业现场的立杆、支架、箱体都会反射超声波产生多径干扰。我采用了固定窗口检测法起始发射后在设定的时间窗口内比如1ms到1.5ms对应距离3.4cm到5.1cm确认接收信号是否有效。窗口以外收到的信号都视为反射或者噪声直接丢弃。这个窗口上下限根据换能器实际间距和声速范围用公式算出来。3.2 温度补偿与声速修正超声波在空气中的传播速度受温度影响很明显公式是c 331.45 0.607 × TT为摄氏温度在零度环境下声速约为331m/s在40度环境下约为356m/s相差25m/s接近8%。如果不做温度补偿时差法测量的风速会整体偏大或者偏小。所以我在风洞标定时发现没加温度补偿的原始数据和标准风速计差得离谱温度越高偏差越大。补偿方法很简单板上放一个数字温度传感器DS18B20每次测量前读取温度值代入声速公式计算出当前温度下的声速再用这个修正后的声速参与风速计算。我这里把DS18B20贴在换能器支架的金属块上让它尽量接近探头温度。DS18B20的温度精度是±0.5℃换算成声速误差约0.3m/s换成精度更高的SHT30或PT100能进一步降低误差。还有一点一定要分清是单向声速还是等效声速。在时差法公式里风速计算时温度影响其实会部分抵消但温度补偿仍能提升低风速段的精度。实测补偿后0~10m/s范围内的误差能控制在±0.3m/s。3.3 风速风向融合算法与滤波实现有了两对正交换能器的顺逆风时间差后分别计算出X轴风速Vx和Y轴风速Vy再合成最终风速和风向。我一开始直接裸算测量值抖动很大特别是低风速时风向乱跳根本没法看。原因是换能器接收信号本身存在噪声单次测量数据毛刺多。滤波方案做了两部分。第一部分是多次测量去极值平均连续采集10组顺逆风时间差数据去掉最大值和最小值剩下的取平均。这个处理能消除偶然性的尖峰干扰。第二部分是滑动窗口平均对每组计算出的风速值再做一次窗口为5的滑动平均输出1Hz平滑后数据。风向角度的滤波比风速麻烦因为风向是角度量围绕0度附近时不能直接做算术平均。比如350度和10度算术平均是180度明显错了。这里要先用sin和cos变换把角度向量化平均风向 atan2(均值sin(θ), 均值cos(θ))。这样处理350度和10度就是0度逻辑就对了。3.4 Modbus-RTU协议栈与RS485收发实现通信协议用Modbus-RTU是目前最实用的选择。寄存器地址我做了如下分配寄存器地址内容读写属性说明0x0000瞬时风速只读单位0.01m/s0x0001瞬时风向只读单位0.1度0x0002最大风速只读单位0.01m/s0x0003平均风速只读单位0.01m/s0x0004环境温度只读单位0.1℃0x0005设备地址读写默认0x010x0006测量状态只读0正常1异常串口配置为9600、8、N、1。选9600波特率别看它慢但在工业现场这个波特率抗干扰能力最好传输距离也更远。方向控制引脚在数据帧发送前先拉高数据发完最后一字节后必须等移位寄存器全部输出完毕再拉低。用HAL库时我在HAL_UART_TxCpltCallback后再加一个50微秒延时再拉低实测能避免发送尾巴被截断。接收端用串口空闲中断加DMA。STM32F103的USART支持空闲线路检测配合DMA可以实现不定长帧接收而不占用CPU。我配置了DMA循环接收加上空闲中断标记一帧结束接收校验帧才进协议处理。这个方法处理Modbus帧特别顺手帧间有3.5字符时间间隔空闲中断正好能检测到帧尾。4. RS485组网与工业现场联调实录4.1 单机联调从串口直达上位机先做最简单的联调电脑USB转RS485模块连接设备打开串口调试助手发送03功能码读风速和风向寄存器验证数据是否正确。发命令01 03 00 00 00 02 C4 0B其中01是地址03是读保持寄存器功能码0000是起始地址0002是读2个寄存器C40B是CRC校验。设备应该返回01 03 04 0B B8 01 2E 0D 3C其中04是字节数0BB8是十六进制的3000换算成十进制风速为3000 × 0.01m/s 30.00m/s? 等等这个测试是风洞里调节的。这里提醒新手CRC计算别手算直接用网上CRC校验工具或用Python的modbus库算。第一版联调时发现返回了乱码查了半天是USB转485模块接线问题——A和B接反了。RS485是差分信号A、B接反的现象通常是收不到响应或者收到全FF。现场判断线序最靠谱的方法用万用表测A对地电压是正电压B对地是负电压或0V如果测出来的值和接法标志相反就是接反了。4.2 多节点组网的三个关键工程实践组网测试中遇到的第一个问题就是RS485上电瞬间造成整个总线瘫痪。现象是设备一上电总线上其他正在通信的设备全部无响应或者收到乱码。用示波器抓A、B间波形发现上电瞬间A、B出现一个持续几毫秒的低电平毛刺把总线拉住了。原因就是SP3485的DE引脚在MCU还没初始化时是低电平此时RE有效、DE无效本来应该处于接收态但MCU的TXD引脚往往是高电平如果DI引脚没有内部上拉发送端可能输出不确定信号。解决办法在第3.1节的电路设计里已经埋了伏笔首先是AP/B偏置电阻保证总线静态电平确定其次是STM32上电后第一步立刻初始化USART的GPIO和RS485方向控制引脚把RE/DE引脚配置为推挽输出低电平明确让芯片处于接收状态最后最好在DI引脚上加一个10kΩ上拉电阻确保MCU复位期间DI为高电平。第二个坑是组网时发现总线长度超过50米后数据误码率飙升。检查发现有的节点用的是普通非屏蔽双绞线有的用屏蔽线而且屏蔽层在中间节点被剪断了。后来统一换成带屏蔽层的双绞线屏蔽层单点接地问题解决。RS485通信线严格来说必须用特性阻抗120Ω的双绞线而且屏蔽层只能在一端接大地不能两端都接否则会形成地环路电流反而引入更多干扰。第三个坑和接地有关多个节点由不同电源供电节点之间的地电位存在压差。实测30米内两端地电位差能有1V以上超过了RS485接收器的共模输入范围一半了。有些现场更夸张地电位差能到十几伏。这会导致接收器进入不确定状态甚至损坏芯片。解决手段是使用隔离型RS485收发器比如ISO3082或者在SP3485前端加数字隔离器ADuM1201。我升级后的版本用了隔离方案从此通信稳定性提升了一个级别。4.3 三菱PLC和组态软件对接经验很多场景下这套风速仪要接入PLC或者组态屏我拿三菱FX5U PLC做了个实际对接测试。三菱PLC的RS485内置口支持Modbus-RTU主站功能用GX Works3配置一下通信协议就能直接读设备数据。三菱侧配置需要确认通信协议选Modbus-RTU波特率9600数据位8停止位1无校验。对应地风速仪侧把本机模块类型设为从站从站地址设为1波特率校验方式与PLC一致。PLC里写一条FROM指令去读风速仪保持寄存器。注意三菱PLC读取的数据默认是大端序如果发现读到的风速风向数据和串口调试助手读到的高低位互换就是字节序问题需要在PLC程序里做个SWAP指令。工控屏对接更简单大部分触摸屏软件的自带控件里都有Modbus-RTU驱动注册变量表填寄存器地址、数据类型、数据格式地址映射到画面元件。碰到有些组态软件对浮点数支持不好我一般是直接把风速和风向都按整数输出上位机自己除100换算省去一堆麻烦。5. 测量标定流程与风洞实测数据5.1 简易风洞标定环境搭建标定是整个项目中最重要也最容易忽略的一环。很多人做完样机直接信心满满地对比手机上的风速App发现误差很大原因就是没有做系统标定。我的标定环境是这样的用一台轴流风机加直径20cm的PVC管道做简易风洞。风速标准参考值用一款经过计量校准的叶轮式风速计放在管道中心测得。虽然简易风洞的流场均匀性和专业风洞没法比但用来验证算法逻辑和粗调偏差已经足够。标定步骤分三步第一步零风速标定在无风环境中测100组数据计算时间差偏移并写入Flash第二步中速标定用风机吹出约5m/s的风调整增益和阈值使测量值与风速计一致第三步高速标定用第二个风机并联或者密闭管道提高风速到10m/s以上验证高速段一致性。5.2 实际标定数据与误差分析下面是风洞标定的一组实测数据温度25℃两对换能器间距10cm标准风速(m/s)标定前测量值(m/s)标定后测量值(m/s)误差(m/s)0.00.080.020.022.01.721.95-0.055.04.614.92-0.088.07.537.96-0.0412.011.3511.95-0.05标定前的数据在不同风速点普遍偏小呈现比较稳定的比例关系。这是因为换能器间距L的实际有效值比标称值略小加上接收信号触发点不在波形的准确波峰处。标定后做了一阶线性拟合修正修正后风速 原始风速 × 1.052 0.03。这个系数存到Flash里后面批量生产时可以每台单独标定写入。风向标定是在标准0度方向用激光水平仪对准X轴换能器连线方向下旋转整个传感器支架每45度记录一次测量值与实际值的偏差得到一组表数据用于补偿。实测风向误差主要在传感器自身安装不对称2度以内的偏差在工程上是可接受的。5.3 长期稳定性与防冰防尘措施超声波风速仪一个卖点就是免维护但实际工程上还是得做一些优化。防尘方面外壳开孔处贴了透气防尘膜能挡掉柳絮、灰尘、小昆虫孔口直径小于3mm不影响声波传输。防水方面整个线路板灌了三防漆对外接口用防水航空插头整机防护等级做到IP65。防冰方面超声波风速仪最怕冻雨和结冰声波传播路径被冰堵死测量直接失效。我加了一个可选配的加热模块用24V供电的聚酰亚胺加热膜贴在外壳内壁温度低于2℃时自动开启加热功率约15W能保证结冰环境下外壳温度保持在5℃以上。配套的程序逻辑很简单读取温度寄存器如果低于2℃就打开MOS管给加热膜通电。6. 常见问题与排查技巧实录6.1 RS485通信典型故障速查表故障现象可能原因排查方法完全无响应A/B接反、地址错误、波特率不匹配万用表测A/B电压检查设备地址和主机设置通信时好时坏终端电阻缺失、线缆过长、屏蔽层未处理总线末端加120Ω电阻换屏蔽双绞线屏蔽层单端接地一上电总线就死DE控制脚电平不确定加DI上拉电阻MCU上电立即配置方向脚为低数据帧错位波特率误差、帧间隔处理不当改用9600波特率增加帧间隔判定距离近了能通远了不行缺乏匹配电阻、共模电压过高加终端电阻、使用隔离收发器偶尔收到乱码电源纹波大、干扰耦合电源加LC滤波RS485加TVS6.2 换能器信号异常的排查实录一次调试中风速数据变成了固定不动的恒定值一直显示5.4m/s风吹不吹都不变。检查发现接收信号始终能触发比较器但时间戳非常稳定明显是收到了一块杂散信号。用示波器直接看接收换能器后端波形发现40kHz接收信号很弱而发射换能器自身有一个持续衰减的振荡信号通过结构体传播到了接收端触发时刻非常固定。这个问题有两个解法一是调高比较器阈值让直达波信号高于阈值而结构传播的杂散信号低于阈值二是在信号处理中加一个时域窗口把结构传播导致的早期信号剔除掉。我最终两个办法都用上了阈值提高到100mV时间窗口从实际直达波到达前50μs才开启。修改后风速数据恢复正常手指轻轻敲击壳体也不再影响读数。另一个问题出现在设备从室外拿回室内后风速显示持续偏大。检查温度补偿发现DS18B20装在金属座上金属座经过了剧烈的日晒温度比环境空气高了很多导致声速计算偏大从而风速计算值偏高。后来把温度传感器改成探头附近但暴露在空气中的位置并且程序里对温度变化速率做了限制一阶低通时间常数30秒才消除这个问题。这个经验也提醒我温度传感器的安装位置对测量准确性影响很大一定要让传感器真实反映声波传播路径上的空气温度。6.3 批量烧录与现场维护技巧程序调试稳定后批量烧录测试过程中我发现ST-Link Utility烧录速度比J-Link快不少而且STM32F103C8T6的Flash可以在SWD模式下直接全片擦除烧录。为了防抄板量产固件我顺手开启了读保护设置选项字节为Level 1等级这样外部的调试器只能擦除不能读取Flash内容。现场维护方面我在上位机软件中做了一把调试利器通过Modbus寄存器0x0006写一个特殊值0x55AA设备会进入自检模式自动连续显示两对换能器的原始时间差、温度补偿值和信号幅度等级。这样远程排查问题时一个命令就知道问题出在换能器、信号调理电路还是算法上不需要跑到现场拆机。另外设备里还驻留了一个测试用的RS485指令地址0xFF广播读取所有设备状态。调试多节点问题时用这个广播命令可以快速发现总线上有多少设备在线不用一个个去拨地址。设备地址设置我做了两种方式硬件拨码开关和Modbus寄存器软配置默认优先用软件配置软件没配置过就读取拨码开关状态。这样既方便批量设置也能防止误改。7. 项目扩展方向与个人经验总结这个项目做完之后我的体会是超声波风速仪的难点不在原理而在工程细节。原理公式一页纸能写完但真正让数据稳定可靠的是无数个细节换能器间距标定、信号触发阈值选择、RS485场地干扰处理、温度传感器安装位置……每一个环节都是活生生的工程坑。如果新手从头做建议不要想着一次到位先把单对换能器的时差测通再扩展成两对正交方案最后再去处理通信和组网问题。后续想在这个基础上做的扩展有几个方向一是给主机加一路模拟量输出4-20mA或0-10V方便接入老的采集系统二是增加GPRS/4G DTU模块把数据直接上传到云平台做远程气象监测三是把主控升级为STM32F407用更高速的ADC和DSP做数字信号处理用互相关算法替代简单比较法低风速精度还能再上一个台阶。目前这套风速仪固件和硬件资料我还在持续整理优化已经有不少农业物联网的客户朋友在用反馈都还算稳定。有在做类似项目的朋友欢迎多交流实际现场中遇到的奇怪问题。本文还有配套的精品资源点击获取
返回列表