4、信号预处理:去直流、滤波(低通/带通)、去噪、归一化、滑动窗口分割、数据增强方法

电机振动信号在进入STM32端侧模型之前,必须经过系统化的预处理链路。原始振动数据由加速度传感器(如ADXL345、MPU6050或IIS3DWB)采集,通常包含传感器偏置、工频干扰、机械噪声以及环境随机扰动。若将这些原始信号直接送入神经网络或阈值判断器,模型极易被直流分量和高频毛刺误导,导致误报率显著上升。本章围绕端侧部署的算力与存储约束,系统讲解去直流、滤波、去噪、归一化、滑动窗口分割与数据增强六大环节,并给出适用于STM32F4/H7系列的工程化实现路径。

STM32端侧振动信号预处理链路 加速度传感器 IIS3DWB / ADXL345 去直流 高通滤波 / 均值减除 滤波 低通 / 带通 FIR 去噪 小波 / 中值 / 移动平均 归一化 Min-Max / Z-score 滑动窗口分割 256点 / 50%重叠 数据增强 加噪 / 缩放 / 时移 特征提取 / 模型推理 时域 / 频域 / 轻量级CNN 预处理顺序:传感器 → 去直流 → 滤波 → 去噪 → 归一化 → 窗口分割 → 增强 → 推理

上图展示了端侧振动信号预处理的完整链路。在实际工程中,每个环节的参数选择都直接影响后续模型的识别精度与实时性。下面逐一展开各步骤的核心原理、实现方法与STM32适配策略。

4.1 去直流:消除传感器偏置与重力分量

核心原理:加速度传感器输出的原始信号通常包含一个接近常数的直流偏置,该偏置来源于传感器自身的零g偏移(Zero-g Offset)以及安装姿态引入的重力分量。对于旋转电机而言,重力在传感器各轴上的投影是缓慢变化的,但相对于高频振动信号而言可视为直流。若不去除直流,后续的FFT频谱分析中0Hz处会出现巨大能量峰,掩盖低频故障特征(如转频、边频带)。

判断方法与操作流程:在STM32上实现去直流有两种常用方式:

  • 均值减除法:对一段静态数据(如256点)求平均值,然后从每个采样点中减去该均值。适用于信号平稳、电机转速恒定的场景。
  • 一阶高通滤波器:采用IIR结构,传递函数为 y[n] = α(y[n-1] + x[n] - x[n-1]),其中α = 1/(1+2πfc/fs),fc为截止频率(通常取5~10Hz),fs为采样率。该法实时性更好,适合连续数据流。
// STM32 一阶高通滤波实现(fc=5Hz, fs=2000Hz)
#define ALPHA 0.9844f  // α = 1/(1+2π*5/2000)
float highpass_filter(float x, float *y_prev, float *x_prev) {
    float y = ALPHA * (*y_prev + x - *x_prev);
    *y_prev = y;
    *x_prev = x;
    return y;
}
经验提示:对于电池供电的无线传感器节点,去直流环节还能有效降低信号幅值范围,使得ADC采样精度利用率更高。建议在去直流后再进行增益调整,避免信号削顶。

4.2 滤波:低通与带通设计

核心原理:电机振动信号的有效频带通常集中在10Hz~5kHz之间。低于10Hz的分量多为转速波动或安装松动引起的低频漂移;高于5kHz的分量多为齿轮啮合高频噪声或传感器谐振。因此,根据故障类型选择合适的滤波器至关重要:

故障类型 特征频带 推荐滤波器 STM32实现方式
轴承外圈/内圈故障 1kHz~4kHz 带通(1k~4k) FIR 64阶,系数离线生成
转子不平衡/不对中 10Hz~500Hz 低通(截止500Hz) IIR Butterworth 4阶
齿轮断齿/磨损 2kHz~6kHz 带通(2k~6k) FIR 128阶,需DMA传输

案例拆解:某工业风机轴承故障诊断项目中,原始采样率设为20kHz,但STM32F407的CPU主频仅168MHz。若直接使用128阶FIR滤波器,每个采样点需128次乘加运算,20kHz采样率下需2.56M MAC/s,CPU占用率约15%,尚可接受。但若同时运行FFT和神经网络推理,则需将采样率降至8kHz,并采用64阶FIR,将CPU占用率控制在8%以内。

风险提示:IIR滤波器虽然计算量小,但存在相位非线性问题,可能扭曲故障特征波形。对于需要保持波形形状的时域特征提取(如峰值、峭度),建议使用FIR滤波器或采用零相位滤波(离线处理时)。

4.3 去噪:小波变换与中值滤波

核心原理:振动信号中的噪声主要来自电磁干扰、机械摩擦和传感器热噪声。传统低通滤波在去除噪声的同时也会削弱故障特征的高频成分。小波变换通过多分辨率分析,能在保留信号突变特征的同时抑制噪声。但在STM32上实现完整的小波包分解计算量过大,实际工程中常采用以下折中方案:

  1. 中值滤波:对滑动窗口内的数据排序取中值,能有效去除脉冲噪声(如电磁干扰尖峰),窗口长度取3~7点。
  2. 移动平均平滑:对信号进行N点滑动平均,等效于低通滤波,但计算简单,适合实时处理。
  3. 小波阈值去噪(离线):在PC端使用Python PyWavelets对采集的数据进行离线去噪,生成干净的数据集用于模型训练;端侧推理时不再做小波去噪,以节省算力。
// STM32 中值滤波(窗口=5)
uint16_t median_filter5(uint16_t *buf) {
    // 冒泡排序取中值,实际工程可用插入排序优化
    for (int i=0; i<4; i++)
        for (int j=0; j<4-i; j++)
            if (buf[j] > buf[j+1]) {
                uint16_t tmp = buf[j]; buf[j] = buf[j+1]; buf[j+1] = tmp;
            }
    return buf[2];
}
实战要点:在端侧部署时,建议将去噪环节分为两级:前端硬件RC低通(截止频率10kHz)滤除高频干扰,软件中值滤波(窗口3)去除脉冲噪声。这种组合方式在STM32上仅消耗约2%的CPU资源,却能显著提升信噪比。

4.4 归一化:让特征尺度统一

核心原理:不同电机、不同安装位置、不同负载下,振动信号的幅值差异可能达到10倍以上。若直接使用原始幅值训练模型,大振幅样本会主导损失函数,导致模型对小振幅故障不敏感。归一化将所有样本映射到统一尺度,常用方法包括:

  • Min-Max归一化:将数据线性映射到[0,1]区间,公式为 x' = (x - x_min) / (x_max - x_min)。需预先统计全局最小/最大值,适合离线训练。
  • Z-score标准化:使数据均值为0、标准差为1,公式为 x' = (x - μ) / σ。对异常值鲁棒性更好,适合在线推理。
  • 值最大归一化:将数据除以最大值,映射到[-1,1],适合振动信号这种正负对称的波形。

STM32实现策略:由于端侧无法预知全局最大最小值,推荐使用Z-score标准化。在系统初始化时,采集一段静态数据(如1秒)计算均值μ和标准差σ,之后实时计算标准化值。若电机工况变化较大,可每隔10分钟动态更新μ和σ。

// STM32 Z-score 归一化(浮点运算)
float zscore_normalize(float x, float mean, float std) {
    return (x - mean) / std;
}
// 注意:std需加极小值防止除零,如 std + 1e-6f
经验提示:对于STM32F4系列,浮点运算单元(FPU)已支持硬件浮点,但建议将μ和σ预先转换为定点数(Q15格式)以提升速度。例如将σ缩放为2的幂次,用移位代替除法。

4.5 滑动窗口分割:构造时间序列样本

核心原理:振动信号是连续时间序列,而模型训练需要固定长度的输入样本。滑动窗口分割将长序列切分为多个重叠或非重叠的短片段,每个片段作为一个独立样本。窗口长度和重叠率直接影响样本数量与时间分辨率:

参数 推荐值 说明
窗口长度 256点(0.128s@2kHz) 包含至少10个旋转周期(电机转速1500rpm时)
重叠率 50% 增加样本数量,缓解数据不足
步长 128点 窗口长度×(1-重叠率)

操作流程:在STM32上实现滑动窗口时,采用环形缓冲区(Circular Buffer)管理数据流。DMA持续将ADC数据写入缓冲区,当缓冲区中新增128个新数据时,取出最近256个点作为一个窗口样本,送入特征提取模块。这种机制保证了实时性,且内存占用仅需256×2字节(16位ADC)。

// 环形缓冲区实现(简化版)
#define BUF_SIZE 256
int16_t ring_buf[BUF_SIZE];
uint16_t write_idx = 0;

void add_sample(int16_t val) {
    ring_buf[write_idx] = val;
    write_idx = (write_idx + 1) % BUF_SIZE;
}

// 当write_idx每增加128时,触发一次窗口处理
void process_window(void) {
    int16_t window[256];
    uint16_t start = (write_idx + BUF_SIZE - 256) % BUF_SIZE;
    for (int i=0; i<256; i++) {
        window[i] = ring_buf[(start + i) % BUF_SIZE];
    }
    // 送入特征提取或模型推理
}
常见误区:窗口长度过短(如64点)会导致频率分辨率不足(Δf = fs/N = 2000/64 = 31.25Hz),无法区分相邻的故障特征频率;窗口过长(如1024点)则增加推理延迟,且样本数量减少。需根据电机转速和故障特征频率综合确定。

4.6 数据增强:扩充样本多样性

核心原理:工业场景中,故障样本往往稀缺(如轴承磨损初期数据难以采集)。数据增强通过对原始样本施加微小变换,生成语义不变的新样本,提升模型泛化能力。针对振动信号,常用增强方法包括:

  • 加性高斯白噪声:向信号添加SNR=20~30dB的噪声,模拟不同噪声环境。
  • 时间缩放:将信号在时间轴上拉伸或压缩5%~10%,模拟转速波动。
  • 幅值缩放:随机乘以0.8~1.2的系数,模拟负载变化。
  • 时间平移:将窗口在原始序列上随机偏移,增加样本多样性。
  • 频谱扰动:在频域对特定频带进行小幅增益调整,模拟不同共振特性。

案例拆解:在某电机轴承故障诊断项目中,原始采集数据为正常样本2000个、外圈故障样本150个、内圈故障样本120个。通过以下增强策略将故障样本扩充至每类1000个:

  1. 对每个故障样本添加SNR=25dB的高斯噪声,生成3个变体;
  2. 对每个变体进行时间缩放(0.95倍和1.05倍),生成2个变体;
  3. 对每个结果进行幅值缩放(0.9倍和1.1倍),生成2个变体。

最终每类故障样本数 = 150 × 3 × 2 × 2 = 1800个(外圈),120 × 3 × 2 × 2 = 1440个(内圈)。训练后的模型在真实测试集上准确率从82.3%提升至94.7%,且过拟合现象显著减少。

工程注意:数据增强应在PC端离线完成,增强后的数据集用于训练模型。STM32端侧推理时不做增强,仅执行去直流、滤波、归一化和窗口分割。增强参数(如噪声SNR、缩放范围)需根据实际工况调整,避免过度增强导致样本失真。

4.7 预处理链路整体调优与验证

核心原理:预处理各环节并非独立,参数之间存在耦合。例如,滤波截止频率会影响去噪效果,归一化参数会影响窗口分割后的数据分布。因此,需要建立一套完整的验证流程:

验证步骤 方法 通过标准
1. 静态测试 采集电机停机时的数据,检查去直流后均值是否接近0 均值值 < 0.01g
2. 频谱验证 对滤波后的信号做FFT,检查特征频率是否清晰 故障特征频率幅值 > 噪声底3倍
3. 实时性测试 用定时器测量预处理耗时 总耗时 < 采样周期的一半
4. 模型对比 分别用原始信号和预处理后信号训练模型 预处理后准确率提升 > 5%

总结复盘:在STM32端侧实现振动信号预处理,核心原则是“在算力与效果之间取平衡”。去直流和滤波是基础,必须保证;去噪和归一化根据场景选择;滑动窗口分割是连接信号与模型的桥梁;数据增强在离线阶段完成。建议在项目初期先搭建PC端Python预处理流水线,验证各环节参数的有效性,再移植到STM32上。移植时优先使用定点数运算和查表法优化耗时函数,确保系统实时性。

最终建议:将预处理模块封装为独立函数库,输入为ADC原始数据指针,输出为归一化后的窗口样本。这样便于单元测试和后续复用。同时,在STM32上保留调试接口(如串口打印预处理后的波形数据),便于现场调参和故障排查。