在散料输送现场,带式输送机的托辊数量多到让人头疼。一条两千多米的胶带机,托辊能装上千组,它们每天承受物料冲击和高速旋转,是整条线路上故障率最高的环节。传统点检基本靠人耳去听,老师傅贴着辊子站半天,凭“咔哒、沙沙”的声音判断轴承是不是坏了。可这样的做法主观性太强,现场环境噪声又大,两拨人看同一个托辊,经常判出两个结果。基于声音信号的托辊故障检测系统,本质上是把老师傅的耳朵变成一套可复现、可量化的算法:用拾音器采集托辊运行声音,在Matlab里完成去噪、分帧、特征提取和包络谱分析,最后输出“正常”或“故障”的结论。这篇文章我会从项目设计思路讲起,把硬件选型、数据采集、Matlab代码实现、常见坑全部列出来,适合正在做设备点检方案、声学故障诊断课题或者毕业设计的读者参考。
1. 整体设计思路:为什么声音能暴露托辊故障
1.1 托辊故障的声音特征从哪来
托辊故障一般分两类:轴承损坏和辊皮损伤。轴承损坏后,滚道、滚动体上出现剥落、点蚀或裂纹,旋转时会产生周期性冲击。这个冲击会激励轴承座、辊体甚至附近结构发生共振,辐射出特征明显的“咔哒”或“嗡嗡”声。辊皮严重磨损、被物料黏住或表面变形后,转动不再平稳,声音会变得低沉、杂乱。
故障信号本质上不是简单的高低音变化,而是由轴承旋转频率及其倍频调制出来的高频冲击。也就是说,坏托辊的声音会在固定时间间隔内出现“脉冲串”,而正常托辊的声音相对平稳。我们要做的,就是从一段混杂了大量背景噪声的音频里,找出这种周期性的冲击成分。
1.2 为什么选声音信号,而不是振动信号
做设备故障诊断,大家第一反应往往是振动检测。振动加速度计贴在轴承座上,确实能拿到很干净的信号,但对托辊这种场景并不实用。托辊数量太多,一条皮带上千个辊子,不可能每个都装传感器;巡检时拿手持式测振仪一个个贴探头,效率也远低于用麦克风吹扫。
声音检测的核心优势是非接触。手持拾音器或者固定几个高灵敏度麦克风,离托辊几十厘米就能采集数据,不用停机、不用贴装。缺点是环境噪声干扰严重,信噪比低。针对托辊这种转速不高(带速通常2到4米每秒)、故障信号特征明显的场景,声音方案的部署成本和效率优势非常突出。设计系统时要做的,就是通过带通滤波、包络谱分析等手段,把故障冲击从低频大噪声背景里“抠”出来。
1.3 系统整体框架和各模块分工
我设计的这套系统分四个环节:声音采集、预处理、特征提取、判断输出。声音采集用驻极体麦克风加USB声卡,进入电脑或者嵌入设备;Matlab离线处理时用audioread直接读wav文件。预处理负责去直流、带通滤波、分帧加窗。特征提取从每一帧里计算时域指标(均方根、峭度)和频域指标(包络谱)。判断环节则采用“先阈值初判、再包络谱确认”的两级策略。
为什么用两级策略而不是一把梭?因为单靠响度判断,过料、启动、胶带接头经过时都会造成误报。先靠峭度和RMS筛出“疑似帧”,再对疑似片段做包络谱分析,找故障特征频率,误报率会明显下降。这也是整套系统里我认为最有工程价值的部分。
1.4 技术选型背后的几个关键决定
采样率我定在44100Hz,也就是CD音质标准。为什么不用更低的22050Hz?托辊轴承故障冲击的高频成分可能到5kHz以上,但现场实测超过5kHz的部分衰减得很厉害,再加上驻极体麦克风高频响应有限,保留过高的频带只会放大环境干扰。44.1kHz既能覆盖有效分析频带,又与市面常见声卡、录音笔天然适配。
带通滤波范围选100到5000Hz,同样是现场权衡的结果。100Hz以下主要是电机、滚筒、减速机等大型设备的低频噪声,能量大且与托辊故障无关;5000Hz以上多为气流、风噪、电气干扰,对故障诊断没什么贡献。至于滤波器的阶数,离线分析用4阶巴特沃斯就够,在线实时处理时可以用椭圆滤波器,过渡带更窄,但要注意相位畸变。
2. 现场数据怎么采:麦克风、采样率和样本标注
2.1 麦克风选型与安装位置
数据采集是整个项目最容易翻车的地方,也是最容易被忽略的地方。很多人在实验室里用现成的音频文件跑通算法,一到现场就发现识别率直接崩盘,根源就是录音质量不过关。
麦克风我建议用带防风棉的驻极体麦克风或者测量级手持麦克风,频响范围覆盖50Hz到15kHz即可,不需要太高端的声学传感器。现场环境粉尘大、湿度高,如果做固定安装,外壳防护等级至少IP65,否则麦克风振膜一积灰,灵敏度掉得厉害。手持巡检时,离托辊20到50厘米,拾音头对着托辊轴向偏下45度,尽量避免正对电机或滚筒噪声源。
固定安装的位置要专门调。我试过把麦克风固定在托辊支架上方,离托辊大约30厘米,正对着轴承座,效果最好。但胶带托辊是转动部件,安装支架不能碰到转动位置,也不能阻挡检修通道。更稳妥的办法是先手持采集,标记最优位置后,再设计固定夹具,避免“装是装上了,音质全毁了”。
2.2 采样率、录音时长和格式
采样率前面提过,直接用44100Hz。录音时长单组样本不要短于10秒,我通常录20到30秒。别看后面分析只要几秒钟数据,现场噪声是非平稳的,过料瞬间、胶带接头经过、启动阶段,都会让信号变化很大,录太短没法覆盖各种工况。
录音格式必须用wav,位深16bit,不要用MP3。MP3等有损压缩会把高频细节和低幅值冲击抹掉,故障特征本身就很微弱,再经压缩等于自毁长城。单声道就够了,双声道文件记得在Matlab里取单列,不然后面处理时维度混乱。
另外,录音时一定要记录设备工况:带速、是否带料、环境温度、离托辊距离、托辊编号。这些现场记录是后续样本标注和阈值调整的依据。没有工况信息的音频,基本就是废数据。
2.3 样本标注与目录整理
样本标注是算法模型的天花板。故障样本从哪来?最可靠的方式是现场找“疑似托辊”采集音频,挂一个“疑似”标签,等检修拆下确认后,再更新为“外圈故障”“内圈故障”或“辊皮磨损”。千万别只凭耳朵听就标成故障,声音主观感受和实际损坏不一定对应。
Matlab里可以用audioDatastore管理音频文件,目录结构建议这样分:
data/ normal/ outer_fault/ inner_fault/ roller_abnormal/每个文件夹里按“设备编号_日期_工况序号.wav”命名,比如T12_20250108_no_load_01.wav。命名规则一定提前定好,不然样本量一大,整理起来想哭。
2.4 别忘了采集边界工况
除了稳定运行状态,还要特意录一些启动、停机、低速、过料瞬间的音频。很多算法在稳定工况下表现很好,一到非平稳阶段就频繁误报。把这些边界工况数据单独放一批,用来做鲁棒性测试,比一味追求模型在理想样本上的准确率更有意义。我当时吃过这个亏,第一次测试时算法在正常匀速段非常准,一遇到胶带接头经过就误报成故障,就是因为样本里缺少接头冲击这一类“正常但异常”的数据。
3. 信号预处理与特征提取的Matlab实现
3.1 读取音频并检查波形
先读入一段wav,看看原始数据长什么样。
[y, fs] = audioread('roll_001.wav'); y = y(:,1); % 取单声道 t = (0:length(y)-1) / fs; figure; subplot(2,1,1); plot(t, y); xlabel('时间 (s)'); ylabel('幅值'); title('原始声音波形');读文件后第一件事不是急着滤波,而是看波形。有没有削波?如果波形顶部被切平,说明录音电平太高,增益要调低;有没有大段静音或满幅噪声?这些都会影响后续特征。audioread返回的采样率fs一定要打印出来确认,声卡时钟偏差虽然小,但后面计算频率轴时差一点都不行。
3.2 去直流与带通滤波
驻极体麦克风经过声卡后,信号里往往带一个直流偏置,虽然很小,但对后面希尔伯特包络解调有影响。先把均值减掉,再做带通滤波。
fs = 44100; y = y(:) - mean(y); f_low = 100; f_high = 5000; [b, a] = butter(4, [f_low/(fs/2) f_high/(fs/2)], 'bandpass'); y_f = filter(b, a, y);butter的第二个参数是归一化截止频率,要用截止频率除以fs/2,对应的是Nyquist频率。选4阶是平衡过渡带和计算量,离线处理对相位延迟不敏感,可以放心用。如果想看得更准,可以用filtfilt做零相位滤波,但它要求输入信号长度足够,否则两端会有边界效应。
3.3 分帧加窗:短时平稳假设
声音信号是非平稳的,托辊转速也在小幅波动,直接对整段信号做FFT会糊成一片。工程上通用的做法是分帧加窗,假设每一帧几十毫秒内信号近似平稳。
frameLen = 2048; % 约46ms @44.1kHz hop = 1024; % 50%重叠 frames = buffer(y_f, frameLen, frameLen - hop, 'nodelay').'; w = hann(frameLen); frames = frames .* w;buffer函数把一维信号切成矩阵,每行一帧。第二个参数是帧长,第三个参数是重叠量,nodelay表示从开头直接取帧。用汉宁窗是为了抑制帧边缘不连续产生的频谱泄漏。如果换矩形窗,FFT谱线旁边会多出一堆虚假边瓣,找峰值时特别容易误判。
3.4 时域特征:均方根和峭度
分帧后,逐帧计算均方根(RMS)和峭度(Kurtosis)。
rms_vals = sqrt(mean(frames.^2, 2)); kurt_vals = kurtosis(frames, 1, 2);RMS反映这一帧声音的能量大小。故障托辊由于异常的冲击和摩擦,总体能量通常比正常托辊高,但不绝对。过料时物料撞击托辊,能量也很大,所以RMS只能做初判,不能单独定论。
峭度是四阶统计量,用来描述信号分布形状。正常振动噪声接近高斯分布,峭度约等于3;故障轴承的冲击信号中会频繁出现大幅度尖峰,峭度明显变大。经验值上,持续多帧峭度大于5,就要高度怀疑存在冲击性故障。但峭度对偶然的瞬态冲击也敏感,现场一个金属工具掉落都会让它爆表,所以必须配合包络谱确认。
3.5 包络谱:把冲击周期解调出来
这是整套系统最核心的一步。故障轴承的周期性冲击会激励起高频共振,直接对原始信号做FFT,看到的多是一大片高频“草”状能量,故障特征频率往往淹没在共振频带里,不好找。包络分析的思想是先取信号包络,再对包络做FFT,把“冲击每秒钟发生几次”这个低频周期信息解调出来。
env = abs(hilbert(y_f)); env_spectrum = abs(fft(env)); f_axis = (0:length(env_spectrum)-1) * fs / length(env_spectrum);完整的包络谱计算不适合对整段几分钟信号直接做,建议按帧长2048、重叠50%分段计算包络谱,然后取平均,这样能压制随机噪声,突出稳定出现的周期分量。hilbert就是希尔伯特变换,abs取解析信号的模,得到包络。
3.6 托辊轴承故障特征频率的估算
判断包络谱峰值时,不能漫无目的地找最大峰,要结合托辊参数估算故障特征频率。托辊转频(每秒转数)由带速和托辊直径决定:
fr = v / (pi * D)其中v是带速,单位m/s,D是托辊直径,单位m。比如带速2m/s,托辊直径0.108m,那么fr ≈ 2 / (3.14 * 0.108) ≈ 5.9Hz。知道了转频,如果还知道轴承参数,可以用经典的轴承故障特征频率公式估算外圈、内圈、滚动体故障频率:
外圈故障频率 BPFO = Z / 2 * fr * (1 - d / Dm * cos(alpha)) 内圈故障频率 BPFI = Z / 2 * fr * (1 + d / Dm * cos(alpha))其中Z是滚动体数量,d是滚动体直径,Dm是节径,alpha是接触角。现场拿不到这些参数时,也不用慌。我们仍然可以先算转频,然后在包络谱里寻找位于转频整数倍附近、并且重复出现的谱峰簇,这种“间隔均匀”的峰值模式是故障冲击的典型特征,比单个峰值可靠得多。
4. 故障识别逻辑与Matlab综合实现
4.1 两级判断逻辑:先初判,再确认
我最终采用的判断逻辑只有两级。第一级是帧级特征扫描,逐帧计算RMS和峭度,如果连续超过一定帧数的RMS大于阈值,或者峭度持续大于5,就把这个片段标记为“疑似故障片段”。这一步的作用是丢掉大量明显正常的音频,减少计算量。
第二级是包络谱确认。对疑似片段计算包络谱,提取谱峰频率,将这些频率与当前托辊转频及经验故障频带比对。如果包络谱在低频区出现一组等间隔谱峰,或者存在某个超过背景能量多倍的突出峰值,就判定为故障,否则判断为正常。
这个逻辑的特点是“宁缺毋滥”吗?不,它的核心是“可解释”。每一张判定图都能找到对应特征,维护人员可以回看是RMS超了,还是包络谱峰值异常,而不是面对一个黑盒模型不知所措。
4.2 一个可以直接跑的完整检测函数
下面给出一个简化但完整的Matlab函数,包含从读文件到输出判定结果的全过程。
function [flag, detail] = roll_bearing_detect(filename, fs_target) % 简化版托辊声音故障检测函数 % 输入:wav文件路径,目标采样率 % 输出:flag(0正常,1故障),detail(特征结构体) if nargin < 2 || isempty(fs_target) fs_target = 44100; end % 1. 读取音频 [y, fs] = audioread(filename); y = y(:,1); if fs ~= fs_target y = resample(y, fs_target, fs); fs = fs_target; end % 2. 去直流 + 带通滤波 y = y - mean(y); [b, a] = butter(4, [100/(fs/2), 5000/(fs/2)], 'bandpass'); y = filter(b, a, y); % 3. 分帧加窗 frameLen = 2048; hop = 1024; frames = buffer(y, frameLen, frameLen - hop, 'nodelay').'; frames = frames .* hann(frameLen)'; % 4. 时域特征 rms_vals = sqrt(mean(frames.^2, 2)); kurt_vals = kurtosis(frames, 1, 2); % 5. 第一级:疑似帧判定 rms_base = median(rms_vals); % 用中位数抗异常点 rms_thr = rms_base * 2.5; % 经验阈值,需现场标定 kurt_thr = 5; abnormal_idx = find((rms_vals > rms_thr) | (kurt_vals > kurt_thr)); % 连续10帧以上才认为是疑似片段 flag = 0; detail.rms = rms_vals; detail.kurtosis = kurt_vals; detail.abnormal_idx = abnormal_idx; if length(abnormal_idx) < 10 return; end % 6. 第二级:包络谱确认 env = abs(hilbert(y)); env_spectrum = abs(fft(env)); freq = (0:length(env_spectrum)-1) * fs / length(env_spectrum); % 只关心5Hz到500Hz的低频周期分量 band = (freq > 5) & (freq < 500); env_db = env_spectrum(band); f_band = freq(band); % 提取突出峰值 [pks, locs] = findpeaks(env_db, 'MinPeakHeight', mean(env_db) + 2*std(env_db)); detail.peak_freqs = f_band(locs); detail.peak_values = pks; if ~isempty(pks) flag = 1; end end这个函数里的阈值写得比较保守。rms_thr用了中位数的2.5倍,目的是适应不同录音增益;kurt_thr取5是业内常用经验值。但必须强调,这套阈值不是万能钥匙,现场换一套设备、换一个声场环境,大概率要重新标定。
4.3 把检测过程可视化
故障判断不能只输出0和1,现场负责人更希望看到“为什么判故障”。Matlab里可以用figure把原始波形、RMS曲线、包络谱三个图叠在一起,做成一张诊断报告图。
figure; subplot(3,1,1); plot((0:length(y_f)-1)/fs, y_f); title('带通滤波后波形'); subplot(3,1,2); frame_time = (0:length(rms_vals)-1) * hop / fs; plot(frame_time, rms_vals); hold on; plot(frame_time(abnormal_idx), rms_vals(abnormal_idx), 'r.'); title('RMS曲线,红点为疑似帧'); subplot(3,1,3); plot(f_band, env_db); hold on; for i = 1:length(locs) xline(f_band(locs(i)), '--r'); end xlabel('频率 (Hz)'); ylabel('幅度'); title('包络谱峰值标注');图中如果能同时标注估算的故障特征频率,比如用绿色竖线画在BPFO、BPFI附近,会更有说服力。可视化不仅是给算法看,更是给机电维护人员看。
4.4 进阶:用特征向量接轻量分类器
如果采集到的样本足够多,比如每个类别超过50组音频,可以考虑不写纯阈值规则,改用特征向量加分类器。每帧提取RMS、峭度、峰值因子、包络谱主峰频率等,组成特征表。
features = [rms_vals, kurt_vals, peak_ratio]; labels = [ones(sum(labels_normal),1); zeros(sum(labels_fault),1)]; mdl = fitcsvm(features, labels);但我要提醒一句:样本不均衡、特征冗余、录音工况不统一时,分类器非常容易过拟合。看起来训练集准确率99%,到了现场新数据直接崩盘。我的习惯是先用简单的阈值逻辑把项目跑通,建立完整的数据闭环,再考虑上分类器。项目是做“检测系统”,不是做“模型比赛”,稳定性永远排在第一位。
5. 常见问题与排查技巧实录
5.1 现场环境噪声太大怎么办
这是被问得最多的一个问题。声音检测天然信噪比差,现场电机、滚筒、物料摩擦声都往麦克风里钻。常规的处理顺序是:先调整采集位置,再使用带通滤波,最后考虑谱减法。
调整采集位置是零成本却最有效的一步。麦克风尽量贴近故障托辊,利用近距效应提高目标声源占比。带通滤波可以滤掉低频大能量噪声,但对同频带内的干扰无能为力。如果噪声和故障信号频带重叠,可以尝试双麦克风谱减法:一只麦克风贴近托辊采集“目标+噪声”,另一只稍远采集“环境噪声”,在频域做对消。谱减法要注意过减会破坏包络谱的周期特征,反而降低故障识别率。
5.2 故障特征频率算不准怎么办
托辊转速不是恒定的。带速波动、辊子表面磨损、负载变化都会导致转频漂移,理论计算的BPFO和相关谱峰往往对不上。解决方法是在包络谱分析前,先从原始信号里估计实际转频。
转频可以从低速段振动或声音包络的脉冲间隔估算,也可以用测速传感器同步记录。估算到转频后,在匹配谱峰时不要只看单一条谱线,而是在理论频率附近±10%的频带内寻找峰值簇。峰值簇比单峰可靠得多,因为轴承故障的冲击周期会有随机微小波动,不可能像理想模型那样严格等间隔。
5.3 录音文件太长,Matlab内存爆了怎么办
有人录了10分钟wav,44.1kHz、16bit,文件大小几十MB,Matlab直接读入再分帧可能卡死。更好的做法是先用能量检测切出含声音的片段。最简单的VAD(语音活动检测)实现就是用短时能量加一个低阈值,找到能量明显大于静音段的区间,只对这个区间做故障分析。
Matlab的audioDatastore配合read也支持逐块读入,可以用循环一帧一帧读,计算完特征就丢掉原始数据。在线实时检测环境中,这个方法几乎是必须的,不然内存占用永远不够。
5.4 为什么包络谱里总有莫名其妙的高频尖峰
高频尖峰可能来自麦克风的高频自振、声卡电磁干扰、附近变频器的高频开关噪声。一个简单办法是不要把包络谱的搜索范围设到整个频带,而是只关注5到500Hz这个故障周期所在的低频段。包络谱的意义本来就是“解调”,低频段才有周期信息,高频段解调出来的往往是噪声。
5.5 常见现象速查表
| 现象 | 可能原因 | 处理建议 |
|---|---|---|
| 正常托辊误判故障 | 胶带接头周期冲击被识别为故障脉冲 | 记录接头时间,或用视频同步剔除特征 |
| 故障托辊漏判 | 故障频率不在包络谱搜索范围内 | 调整转频估算,扩大搜索带宽 |
| 波形削波 | 麦克风增益过高 | 降低录音电平,重新采集 |
| 高频噪声严重 | 麦克风位置距电机过近 | 调整采集角度,增加防风棉 |
| RMS阈值漂移 | 录音距离不一致 | 统一采集距离,或改为归一化特征 |
5.6 误报源:哪些声音会干扰判断
胶带接头通过时,也会产生周期性冲击,听起来和坏轴承有点像。过料时大块物料砸在托辊上,形成大幅度瞬态冲击,峭度会瞬间飙高。甚至旁边工人在用扳手敲打结构件,都能触发第一级阈值。
处理误报不能只在算法里加规则,还要靠数据同步。最实用的做法是录音时用手机拍摄视频,或者在现场记录时间轴,标注哪些时刻是过料、哪些时刻是接头经过。离线分析时,把这些干扰片段单独切出来,作为“已知干扰类”进数据库。模型即使不专门训练,看到这些特征也该知道要避开。
6. 实测效果与个人体会
我在一套实际运行的散料输送线上做了两周数据采集,共收集87组有效音频,其中正常托辊52组,确认有故障的托辊35组。用上面这套“阈值初判+包络谱确认”的方法做离线识别,准确率大概在86%左右。最初只看RMS和峭度,误报率很高,大多数误报来自胶带接头和过料冲击;加入包络谱确认后,虚警明显减少。如果后续再引入转速修正和视频时间同步,准确率可以进一步接近90%以上。
踩过几次坑之后,我最大的体会是:声音故障检测最难的从来不是算法,而是样本采集和对现场噪声的理解。公式、代码、滤波器参数全都可以在教科书中找到,但麦克风放哪儿、录音录多久、怎么给样本打标签,才是真正决定系统能不能落地的部分。换句话说,先学会“听”现场,再谈“算”故障。
这套系统后续扩展空间也很大。把Matlab代码移植到嵌入式设备,用树莓派加USB声卡就能做一个在线监测节点;几个节点组网后,配合现有的设备点检系统,就能实现托辊状态趋势预警。不过别急着上复杂架构,先把一个托辊的“听觉”做好,比什么都强。