简介这份资源是一份面向工业自动化、电气控制方向学生与技术人员的PLC电机故障诊断系统设计方案文档围绕电机运行中相间短路、断相、低电压、单相接地、过负荷、过电流等典型故障给出基于西门子S7-200、S7-300、S7-400系列PLC的诊断与保护设计思路适合课程设计、毕业设计及工程入门参考。压缩包内共1个doc文件约211KB内容涵盖PLC工作原理与选型依据、I/O接口分配、系统梯形图编写以及开机检测断路器状态、启动过程循环检测故障、关机跳闸与声光报警复位等完整控制逻辑并附有摘要、关键词与目录结构便于按章节查阅。目前已有64人学习可作为理解PLC在电机故障诊断中应用方式的实用参考资料。1. 从一份 .doc 方案说起PLC 电机故障诊断到底在做什么很多做电气自动化的朋友第一次拿到“PLC电机故障诊断系统设计方案.doc”这类文档时第一反应是这不就是给电机加几个传感器、在 PLC 里写几段报警程序吗真到现场才发现事情没这么简单。电机故障诊断的核心不是“报警”而是“在故障还没把产线停掉之前把特征量从噪声里抠出来再让 PLC 做出可复现的判断”。它解决的是非计划停机、误报频繁、维修靠老师傅耳朵听这三件事适合做设备维护、产线改造、工控集成的从业者。这份方案文档通常包含系统架构、信号采集、诊断算法、PLC 程序结构和上位机交互几块。但文档是死的落地是活的。下面我按“先立住原理再动手复现”的顺序把这类方案从纸面拆到能跑的程度。中间会给出可抄的代码、参数表和踩坑记录最后收在一个具体技巧上。2. 先定架构再写代码信号链与 PLC 选型怎么定2.1 电机故障诊断的信号从哪来电机故障大致分三类电气类匝间短路、断相、三相不平衡、机械类轴承磨损、偏心、松动、负载类过载、堵转。不同故障对应不同特征量采集方案也不同。常见做法是电流信号用霍尔电流传感器或电流互感器取三相电流振动信号用压电式加速度计装在轴承座或机壳温度用 PT100 或热电偶埋在绕组或轴承附近。转速可以用编码器或接近开关。这里有个选型原则先确定要诊断哪几类故障再决定采什么信号。如果只做电气故障三相电流加电压就够了如果要做轴承早期故障振动信号是必须的而且采样率要够。很多方案文档里写“采集电流、振动、温度”但没写采样率和带宽落地时就会发现振动信号混叠诊断算法根本跑不出结果。我一般会按这个顺序定信号链列出目标故障类型查每类故障的特征频率范围反推传感器带宽和采样率确认 PLC 或采集模块能不能接这类信号。比如轴承故障特征频率通常在几百赫兹到几千赫兹按奈奎斯特采样定理采样率至少要到 10 kHz 以上。普通 PLC 的模拟量输入模块扫描周期在毫秒级根本抓不住。这时候要么加独立振动采集模块要么用带高速计数/高速采集的 PLC 或专用诊断仪。2.2 PLC 选型不是越贵越好而是看诊断任务放在哪PLC 在故障诊断系统里通常承担三个角色数据采集触发、逻辑判断与联锁、与上位机通信。诊断算法可以放在 PLC 里也可以放在上位机或边缘控制器里。如果算法简单比如只做阈值判断、三相不平衡度计算、启动电流超限那普通中型 PLC 就够了用梯形图或 SCL 写逻辑。如果要做 FFT、包络解调、特征频率提取PLC 算力通常不够常见做法是 PLC 只负责采集和转发算法在上位机或边缘计算盒子里跑。选型时重点看这几个参数项目要求说明模拟量输入通道至少 3 路电流 1 路振动 1 路温度按实际故障类型增减模拟量刷新周期≤ 1 ms电流/ ≤ 0.1 ms振动振动需高速采集通信接口以太网 RS485上位机与现场仪表程序容量留 30% 余量诊断逻辑会越加越多支持语言SCL / ST 优先比梯形图更适合算法提示如果方案文档里写“用普通 PLC 采集振动信号做 FFT”基本可以判断这份方案没有经过现场验证。振动信号要么走专用采集卡要么走带高速采集功能的模块。2.3 一个最小可跑的采集与判断流程下面用 SCL 写一个三相电流不平衡度计算和过载判断的示例。假设 PLC 已经通过模拟量通道读到三相电流值存放在Current_A、Current_B、Current_C三个 REAL 变量里单位是安培。// 三相电流不平衡度与过载判断 // 输入Current_A, Current_B, Current_C (REAL, 单位 A) // 输出Unbalance_Percent (REAL), Overload_Flag (BOOL), Fault_Code (INT) FUNCTION_BLOCK MotorDiag VAR_INPUT Current_A : REAL; // A 相电流 Current_B : REAL; // B 相电流 Current_C : REAL; // C 相电流 Rated_Current : REAL; // 电机额定电流 Unbalance_Threshold : REAL : 10.0; // 不平衡度报警阈值 % Overload_Threshold : REAL : 1.15; // 过载倍数阈值 END_VAR VAR_OUTPUT Unbalance_Percent : REAL; // 不平衡度 Overload_Flag : BOOL; // 过载标志 Fault_Code : INT; // 故障码0 正常1 不平衡2 过载3 断相 END_VAR VAR Avg_Current : REAL; // 平均电流 Max_Deviation : REAL; // 最大偏差 END_VAR // 计算平均电流 Avg_Current : (Current_A Current_B Current_C) / 3.0; // 断相判断任一相电流接近 0 且其他相有电流 IF (Current_A 0.1 AND Current_B 0.5) OR (Current_B 0.1 AND Current_C 0.5) OR (Current_C 0.1 AND Current_A 0.5) THEN Fault_Code : 3; Overload_Flag : FALSE; Unbalance_Percent : 100.0; RETURN; END_IF; // 计算最大偏差 Max_Deviation : 0.0; IF ABS(Current_A - Avg_Current) Max_Deviation THEN Max_Deviation : ABS(Current_A - Avg_Current); END_IF; IF ABS(Current_B - Avg_Current) Max_Deviation THEN Max_Deviation : ABS(Current_B - Avg_Current); END_IF; IF ABS(Current_C - Avg_Current) Max_Deviation THEN Max_Deviation : ABS(Current_C - Avg_Current); END_IF; // 不平衡度 最大偏差 / 平均电流 * 100% IF Avg_Current 0.1 THEN Unbalance_Percent : (Max_Deviation / Avg_Current) * 100.0; ELSE Unbalance_Percent : 0.0; END_IF; // 过载判断 IF Avg_Current (Rated_Current * Overload_Threshold) THEN Overload_Flag : TRUE; Fault_Code : 2; ELSIF Unbalance_Percent Unbalance_Threshold THEN Overload_Flag : FALSE; Fault_Code : 1; ELSE Overload_Flag : FALSE; Fault_Code : 0; END_IF; END_FUNCTION_BLOCK这段逻辑说明先算平均电流再做断相判断然后算不平衡度最后做过载判断。参数说明Unbalance_Threshold默认 10%这是常见工业电机的报警线实际可按电机类型调整Overload_Threshold默认 1.15 倍额定电流对应一般电机的短时过载能力。Fault_Code可以直接送 HMI 或上位机做报警显示。注意这段代码假设模拟量已经滤波和标定。如果原始信号抖动大要在前面加一阶低通滤波否则不平衡度会频繁跳变。3. 诊断算法怎么落从阈值到特征频率的实操路径3.1 阈值判断能解决多少问题很多现场故障其实用阈值就能覆盖过载、断相、三相不平衡、启动超时、温度超限。这类判断逻辑简单、响应快、容易在 PLC 里实现适合做第一层保护。但阈值判断的边界很明显它只能告诉你“现在不正常”不能告诉你“哪里不正常、还能撑多久”。比如轴承早期磨损电流和温度可能都还在正常范围但振动信号里已经出现特征频率。这时候就需要第二层诊断。我一般把诊断分两层第一层PLC 内做阈值和逻辑判断响应时间毫秒级负责联锁停机第二层上位机或边缘控制器做特征提取和模式识别响应时间秒级负责预警和维修建议。3.2 用 Python 做振动信号的包络谱分析轴承故障的特征频率计算需要知道轴承型号和转速。假设已知内圈故障特征频率 BPFI、外圈故障特征频率 BPFO、滚动体故障特征频率 BSF可以通过包络谱找这些频率成分。下面是一个用 Python 做包络谱分析的最小示例。假设已经采集到一段振动信号采样率fs数据存在vibration_data数组里。import numpy as np from scipy.signal import hilbert, butter, filtfilt from scipy.fft import fft, fftfreq def envelope_spectrum(vibration_data, fs, band_low500, band_high5000): 对振动信号做包络谱分析 :param vibration_data: 一维振动信号数组 :param fs: 采样率 Hz :param band_low: 带通滤波下限 Hz :param band_high: 带通滤波上限 Hz :return: 频率轴, 包络谱幅值 # 1. 带通滤波保留轴承故障激发的频带 nyq fs / 2.0 low band_low / nyq high band_high / nyq b, a butter(4, [low, high], btypeband) filtered filtfilt(b, a, vibration_data) # 2. 希尔伯特变换求包络 analytic_signal hilbert(filtered) envelope np.abs(analytic_signal) # 3. 对包络做 FFT n len(envelope) envelope_spectrum np.abs(fft(envelope - np.mean(envelope))) / n freq fftfreq(n, 1/fs) # 只取正频率部分 positive_mask freq 0 return freq[positive_mask], envelope_spectrum[positive_mask] # 使用示例 # fs 20000 # 采样率 20 kHz # data np.loadtxt(vibration.csv) # 假设一列振动数据 # freq, amp envelope_spectrum(data, fs) # 然后检查 BPFI、BPFO、BSF 附近是否有明显峰值逻辑说明先带通滤波把轴承故障激发的频带保留下来再用希尔伯特变换求包络最后对包络做 FFT得到包络谱。参数说明band_low和band_high要根据轴承故障特征频率所在频带调整常见范围是 500 Hz 到 5 kHzbutter的阶数 4 是经验值太高会不稳定太低滤波效果差。这段代码跑完后如果包络谱在 BPFI 或 BPFO 附近出现明显峰值就可以判断对应轴承部件有早期故障。注意实际使用时要先做转速归一化否则特征频率会随转速漂移。3.3 把诊断结果写回 PLC 的通信方式上位机算出诊断结果后需要写回 PLC 做联锁或显示。常见方式有三种方式适用场景注意点Modbus TCP中小型系统数据量小寄存器地址要规划好OPC UA多品牌设备需要语义化配置较复杂但扩展性好私有协议特定品牌 PLC依赖厂家文档移植性差我一般优先选 Modbus TCP因为大部分 PLC 都支持调试工具也多。下面是一个用 Python 通过 Modbus TCP 写诊断结果的示例。from pymodbus.client import ModbusTcpClient def write_diagnosis_result(plc_ip, plc_port, fault_code, unbalance_percent): 将诊断结果写入 PLC 保持寄存器 :param plc_ip: PLC IP 地址 :param plc_port: Modbus TCP 端口默认 502 :param fault_code: 故障码 :param unbalance_percent: 不平衡度放大 10 倍后写入 client ModbusTcpClient(plc_ip, portplc_port) client.connect() # 假设故障码写入 40001不平衡度写入 40002 # 注意不同 PLC 寄存器地址偏移不同需按实际调整 client.write_register(0, fault_code) client.write_register(1, int(unbalance_percent * 10)) client.close() # 使用示例 # write_diagnosis_result(192.168.1.10, 502, 1, 12.5)逻辑说明write_register的第一个参数是寄存器偏移地址不同 PLC 的映射不同有的从 0 开始有的从 1 开始有的需要加 40001 偏移。参数说明不平衡度放大 10 倍写入是为了保留一位小数PLC 里再除以 10 还原。注意写之前要确认 PLC 的 Modbus 从站已经启用寄存器地址没有和系统占用冲突。4. 避坑与排查这类方案落地时最容易翻车的 5 个点4.1 振动信号混叠现象是频谱一片模糊原因是没有抗混叠滤波现象采集到的振动信号做 FFT 后频谱上出现很多不存在的频率成分特征频率完全找不到。原因采样率不够或者没有加抗混叠滤波器高频成分折叠到低频。解决采样率至少是目标最高频率的 2.5 倍最好 5 倍以上在 ADC 前加硬件抗混叠滤波器截止频率设为采样率的一半以下。4.2 电流互感器选型偏大现象是小电流时不平衡度乱跳现象电机轻载时三相电流不平衡度频繁报警但实际电流很小。原因电流互感器量程选得太大轻载时输出信号很小信噪比差。解决按电机额定电流的 1.2 到 1.5 倍选互感器量程不要按最大短路电流选。如果已经装大了可以在 PLC 里做零点校准和数字滤波。4.3 PLC 扫描周期与诊断周期不匹配现象是报警延迟或漏报现象电机已经过载了但 PLC 过了好几秒才报警。原因诊断逻辑放在慢速任务里或者模拟量刷新周期太长。解决把诊断逻辑放在高速任务或中断里模拟量模块选刷新周期短的型号。如果做不到至少要把过载判断放在 10 ms 以内的任务里。4.4 特征频率算错现象是包络谱峰值对不上现象按公式算出的 BPFI、BPFO 和包络谱峰值总是差一点。原因转速测量不准或者轴承型号查错或者滑差没有考虑。解决用编码器实测转速不要用额定转速代替查轴承手册确认特征频率系数如果电机有滑差按实际转速修正。4.5 通信寄存器地址冲突现象是写进去的数据读出来不对现象上位机写故障码到 PLCHMI 上显示的值和写入值不一致。原因Modbus 寄存器地址偏移搞错或者和系统其他变量重叠。解决先读一遍 PLC 的寄存器映射表确认地址范围写之前先读一次确认没有其他程序在写同一地址用调试工具单独测试读写。5. 一个具体技巧用趋势数据做早期预警而不是等报警阈值报警是“已经坏了才报”趋势预警是“快坏了就提醒”。我一般会在上位机里对每个特征量做滑动平均和斜率计算当斜率超过设定值时提前预警。具体做法对不平衡度、振动包络谱峰值、温度这三个量各存最近 30 天的日均值。用线性回归算斜率如果连续 3 天斜率超过阈值就发预警。这样可以在故障真正触发报警前几周就安排检修。下面是一个计算趋势斜率的 Python 示例。import numpy as np def trend_slope(daily_values): 计算日均值序列的线性回归斜率 :param daily_values: 最近 N 天的日均值列表 :return: 斜率正值表示上升趋势 n len(daily_values) if n 3: return 0.0 x np.arange(n) y np.array(daily_values) # 最小二乘拟合 slope np.polyfit(x, y, 1)[0] return slope # 使用示例 # values [10.2, 10.5, 10.8, 11.1, 11.6, 12.0, 12.5] # slope trend_slope(values) # if slope 0.3: # 每天上升超过 0.3 个单位 # print(预警不平衡度呈上升趋势)逻辑说明np.polyfit(x, y, 1)做一次多项式拟合返回斜率和截距。参数说明斜率阈值要根据实际数据的波动范围定一般取历史正常波动标准差的 2 到 3 倍。注意趋势预警不能替代阈值报警两者要并行运行。我自己的习惯是每次做完一个诊断系统先跑一个月的历史数据回放看趋势预警会不会误报。如果误报多就把斜率阈值调大或者加滤波。这个步骤看起来麻烦但能省掉后面很多现场投诉。希望帮到你。本文还有配套的精品资源点击获取