1. 项目背景与核心价值
振动检测在工业设备维护、建筑结构健康监测、精密仪器防护等领域有着广泛应用。传统振动检测设备往往价格昂贵、体积庞大,而基于单片机的解决方案能以极低成本实现90%以上的基础检测功能。我在某风机设备制造厂担任电气工程师期间,就曾用不到200元的成本搭建出可替代上万元商用设备的振动监测系统。
这个项目的核心价值在于:
- 低成本:STC89C52单片机价格仅10元左右,配合常见传感器总成本控制在200元内
- 可定制:可根据不同场景调整检测频率范围和报警阈值
- 易部署:整体体积可做到烟盒大小,方便安装在各类设备上
- 教学价值:完整涵盖传感器应用、信号处理、人机交互等嵌入式开发核心知识点
2. 硬件系统设计
2.1 核心器件选型
单片机选择:
对比了STC89C52、STM32F103C8T6和ESP8266三种方案:
- STC89C52:8位51内核,12MHz主频,优势是价格低廉(约8元)、开发简单
- STM32F103:Cortex-M3内核,72MHz主频,带硬件乘法器适合数字滤波
- ESP8266:内置WiFi但ADC精度仅10位
最终选择STC89C52,因为:
- 振动检测不需要复杂算法,FFT运算可通过查表法实现
- 项目对实时性要求不高(采样率≤1kHz)
- 成本敏感场景下性价比最优
振动传感器选型对比表:
| 型号 | 类型 | 量程 | 灵敏度 | 价格 | 适用场景 |
|---|---|---|---|---|---|
| SW-420 | 滚珠开关 | 无具体参数 | 数字信号 | 3元 | 简易报警 |
| MMA7361 | 三轴加速度 | ±1.5g | 800mV/g | 25元 | 精密测量 |
| ADXL345 | 数字加速度 | ±16g | 3.9mg/LSB | 35元 | 工业级 |
选择MMA7361的考虑:
- 模拟输出便于获取原始波形
- 1.5g量程适合常见机械振动(风机/电机通常<0.5g)
- X/Y/Z三轴数据可识别振动方向
2.2 电路设计要点
信号调理电路:
c复制// 典型连接方式
MMA7361 → 低通滤波 → 电压跟随 → ADC输入
(RC=1kΩ+0.1μF) (LM358)
关键参数计算:
- 截止频率 fc=1/(2πRC)=1/(2×3.14×1000×0.1×10⁻⁶)≈1.6kHz
- 满足奈奎斯特采样定理(目标采样率1kHz)
电源设计陷阱:
实测发现:当使用7805线性稳压时,电机启停会导致电压波动影响ADC精度。改进方案:
- 增加1000μF电解电容滤波
- 改用TPS5430开关稳压器(成本增加5元但纹波<50mV)
3. 软件实现解析
3.1 采样策略优化
基础采样代码:
c复制#define SAMPLE_RATE 1000 // 1kHz采样率
void timer0_init() {
TMOD |= 0x01; // 模式1
TH0 = (65536 - FOSC/12/SAMPLE_RATE)/256;
TL0 = (65536 - FOSC/12/SAMPLE_RATE)%256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void timer0_isr() interrupt 1 {
TH0 = (65536 - FOSC/12/SAMPLE_RATE)/256;
TL0 = (65536 - FOSC/12/SAMPLE_RATE)%256;
adc_value = read_ADC();
buffer[counter++] = adc_value;
}
实际遇到的坑:
- 直接读取ADC值会有±5的抖动 → 采用滑动平均滤波(窗口大小=8)
- 定时器重装值计算错误导致实际采样率偏差 → 使用示波器校准
3.2 振动特征提取
简易算法实现:
- 计算有效值(RMS):
c复制float calculate_rms(uint8_t *buf, uint16_t len) { uint32_t sum = 0; for(uint16_t i=0; i<len; i++) { sum += buf[i] * buf[i]; } return sqrt(sum / (float)len); } - 峰峰值检测:
c复制uint8_t find_peak(uint8_t *buf, uint16_t len) { uint8_t max=0, min=255; for(uint16_t i=0; i<len; i++) { if(buf[i]>max) max=buf[i]; if(buf[i]<min) min=buf[i]; } return max - min; }
工业场景经验值:
- 普通电机:RMS<0.2g,峰峰值<0.5g
- 轴承磨损:出现1kHz以上高频成分
- 转子失衡:振动频率=转速/60
4. 人机交互设计
4.1 LCD界面布局方案
c复制void display_vibration() {
lcd_clear();
lcd_printf(0,0,"RMS:%.3fg",rms_value);
lcd_printf(0,1,"P-P:%.3fg",peak_value);
lcd_printf(10,0,"Freq:%dHz",dominant_freq);
// 简易频谱显示
for(uint8_t i=0;i<8;i++){
lcd_draw_column(40+i*5, 1, fft_result[i]/16);
}
}
4.2 报警功能实现
多级报警策略:
- 黄色预警:RMS连续3次>阈值1
- 红色报警:RMS>阈值2 或 峰峰值>阈值3
- 硬件输出:通过继电器控制设备停机
EEPROM参数存储:
c复制struct {
float rms_threshold;
float peak_threshold;
uint8_t alarm_enable;
} config;
void save_config() {
eeprom_write(0, (uint8_t*)&config, sizeof(config));
}
5. 现场调试经验
5.1 传感器安装要点
- 最佳位置:振动传递路径的刚性部位(如电机底座)
- 避免安装在:
- 涂漆表面(影响振动传递)
- 靠近散热孔的位置(温度影响)
- 电缆缠绕区域(电磁干扰)
5.2 典型故障排查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 读数漂移 | 电源纹波大 | 增加稳压电路输出电容 |
| 数据全零 | 传感器供电异常 | 检查VCC与GND连接 |
| 周期性干扰 | 50Hz工频干扰 | 在传感器外壳接屏蔽线 |
| LCD花屏 | 排线接触不良 | 重新压紧排线插座 |
6. 项目优化方向
硬件升级方案:
- 改用STM32F103:可实现10kHz采样率,适合高频振动分析
- 增加SD卡存储:记录振动历史数据
- 蓝牙传输:通过HC-05模块实现无线监控
算法进阶建议:
- 包络分析:检测轴承故障特征频率
c复制// 希尔伯特变换实现 void hilbert_transform(float *in, float *out, uint16_t len) { // 需配合FFT实现 } - 机器学习:使用K-means聚类识别故障模式(需上位机配合)
这个项目最让我意外的是MMA7361的温度漂移问题——在夏季车间环境(约40℃)下,零点漂移可达0.1g。后来通过以下方法改善:
- 每次启动时自动校准零点(静止状态持续3秒)
- 在软件中增加温度补偿系数
- 改用金属封装的ADXL345(成本上升但稳定性更好)