1. 项目概述
最近在完成一个工厂自动化改造项目时,我深度使用了西门子S7-1200 PLC作为控制核心。这个项目有几个技术难点特别值得分享:需要同时处理多种工业通讯协议、控制不同类型的伺服电机,还要实现多台PLC之间的数据交互。经过一个多月的调试和优化,最终实现了稳定运行。下面我就把这套方案的实现细节和踩过的坑完整记录下来。
2. 硬件配置清单
2.1 核心设备选型
- 主控制器:西门子S7-1215C DC/DC/DC(6ES7215-1AG40-0XB0)
- 扩展模块:
- CM1241 RS485通讯模块(6ES7241-1CH32-0XB0)
- SM1223 16点数字量输入/16点输出(6ES7223-1PH32-0XB0)
- 伺服系统:
- 台达B2系列伺服驱动器(ASD-B2-0421-L)x4
- 西门子V90 PN伺服驱动器(6SL3210-5FB10-1UF1)x2
- 其他设备:
- 安川GP180机器人(MOTOMAN-GP180)x1
- 米铱激光位移传感器(optoNCDT 1700)x4
2.2 网络拓扑设计
整个系统的网络架构采用分层设计:
code复制[上层]
├── 工程师站(博图V15.1)
│
[控制层]
├── PLC1(S7-1215C)
│ ├── PROFINET网络
│ │ ├── 机器人控制器
│ │ └── V90伺服驱动器
│ └── RS485总线
│ └── 位移传感器群
└── PLC2(S7-1215C)
└── 通过OUC与PLC1通讯
3. 关键技术实现
3.1 机器人PROFINET通讯
3.1.1 GSD文件处理
安川机器人作为PROFINET设备接入,需要先导入其GSDML文件。这里有几个关键点:
- 获取正确的GSDML文件版本(本例使用Yaskawa_2.32.gsdml)
- 在TIA Portal中通过"选项→安装设备描述文件(GSD)"导入
- 在硬件目录的"其他现场设备→PROFINET IO→Devices→Yaskawa"下会出现机器人模块
特别注意:某些新版GSD文件可能与旧版TIA Portal不兼容。我们最初使用安川提供的V2.4版本GSD导致硬件组态时报错,回退到V2.32后解决。
3.1.2 硬件组态配置
在设备视图中添加机器人模块后,需要配置:
- IP地址(本例为192.168.1.10)
- 设备名称(必须与机器人控制器内设置一致)
- 输入/输出地址区(建议预留足够空间)
典型的I/O映射配置:
plaintext复制输入地址:IB256-IB271(16字节)
输出地址:QB256-QB271(16字节)
3.1.3 通讯程序实现
使用TSEND_C/TRCV_C功能块实现TCP通讯:
stl复制// 发送数据块
"Robot_Send"(REQ:=#Send_Trigger,
CONT:=TRUE,
CONNECT:=#TCON_Param,
DATA:=P#DB10.DBX0.0 BYTE 10,
LEN:=10);
// 接收数据块
"Robot_Recv"(EN_R:=TRUE,
CONT:=TRUE,
CONNECT:=#TCON_Param,
DATA:=P#DB11.DBX0.0 BYTE 12);
关键参数说明:
- TCON_Param需要配置机器人IP(192.168.1.10)和端口号(2000)
- 数据块DB10和DB11的结构体定义必须与机器人程序严格对应
- 建议添加心跳包检测机制,超时未收到数据触发报警
3.2 伺服控制系统实现
3.2.1 脉冲控制台达B2伺服
四台台达B2伺服采用PTO(脉冲串输出)控制,配置要点:
- 在工艺对象中添加新轴
- 选择"脉冲发生器(PTO)"类型
- 配置硬件输出:
- 脉冲输出:Q0.0(Axis1)、Q0.2(Axis2)、Q0.4(Axis3)、Q0.6(Axis4)
- 方向信号:Q0.1、Q0.3、Q0.5、Q0.7
- 设置电子齿轮比:
- 伺服侧:P1-44/P1-45=10000(10000脉冲/转)
- PLC侧:每转脉冲数设为10000
运动控制程序示例:
stl复制// 轴使能
"MC_Power_Axis1"(Enable:=TRUE,
Axis:=#Axis1,
Status=>#Axis1_Status);
// 回原点
"MC_Home_Axis1"(Execute:=#Home_Cmd,
Axis:=#Axis1,
Position:=0.0);
// 绝对定位
"MC_MoveAbsolute_Axis1"(Execute:=#Move_Cmd,
Axis:=#Axis1,
Position:=#Target_Pos,
Velocity:=500.0);
3.2.2 PROFINET控制V90伺服
两台西门子V90通过PROFINET通讯控制,配置流程:
- 在硬件目录中添加V90 PN设备
- 分配设备名称(通过TIA Portal或PRONETA工具)
- 配置报文类型:标准报文3(PZD-4/4)
- 设置控制字/状态字映射地址
关键参数设置:
plaintext复制控制字1:QW100(Axis5)、QW102(Axis6)
状态字1:IW100(Axis5)、IW102(Axis6)
位置反馈:ID104(Axis5)、ID108(Axis6)
3.2.3 混合控制注意事项
-
负载均衡:
- 脉冲控制会占用CPU较多资源
- 建议将脉冲轴的运动规划放在不同OB块中执行
-
同步问题:
- 使用"MC_Syncronize"功能块实现多轴同步
- 特别注意脉冲轴与PN轴的响应时间差异
-
急停处理:
- 所有轴必须配置统一的急停信号
- 建议使用"MC_Reset"功能块统一复位
3.3 PLC间开放式通讯
3.3.1 连接配置
两台S7-1200通过OUC(开放式用户通讯)交换数据,配置步骤:
- 在DB中创建TCON_IP连接参数块
- 定义连接属性:
- 连接类型:TCP
- 本地/远程端口号:2001(PLC1)、2002(PLC2)
- 本地/远程IP地址:192.168.1.1(PLC1)、192.168.1.2(PLC2)
连接参数块结构示例:
stl复制STRUCT
InterfaceId : INT := 64; // 硬件标识符
ID : INT := 1;
ConnectionType : INT := 11; // TCP连接
ActiveEstablished : INT := 1; // 主动建立
RemoteAddress : ARRAY [1..4] OF BYTE := [192,168,1,2];
RemotePort : INT := 2002;
LocalPort : INT := 2001;
END_STRUCT
3.3.2 数据传输实现
PLC1发送程序:
stl复制"TSEND_DB"(REQ:=#Send_Trigger,
CONT:=TRUE,
CONNECT:=#OUC_Connection,
DATA:=P#DB50.DBX0.0 BYTE 50,
LEN:=50,
DONE=>#Send_Done);
PLC2接收程序:
stl复制"TRCV_DB"(EN_R:=TRUE,
CONT:=TRUE,
CONNECT:=#OUC_Connection,
DATA:=P#DB60.DBX0.0 BYTE 50,
RCVD_LEN=>#Recv_Len);
3.3.3 性能优化技巧
-
数据打包:
- 将多个变量打包成UDT结构体传输
- 减少通讯次数,提高效率
-
心跳检测:
- 定期发送心跳包(如1秒间隔)
- 超时未收到数据触发重连机制
-
数据校验:
- 添加CRC校验字段
- 重要数据采用应答确认机制
3.4 Modbus RTU轮询实现
3.4.1 硬件配置
使用CM1241 RS485模块连接4个位移传感器:
- 接线方式:A+/B-端子并联连接
- 终端电阻:首尾设备启用120Ω终端电阻
- 通讯参数:
- 波特率:19200bps
- 数据位:8位
- 停止位:1位
- 校验位:无
3.4.2 轮询程序设计
采用状态机实现分时轮询:
stl复制CASE #Modbus_State OF
0: // 空闲状态
IF #Start_Polling THEN
#Modbus_State := 1;
#Current_Slave := 1;
END_IF;
1: // 准备请求
#MB_ADDR := #Slave_List[#Current_Slave];
#DATA_ADDR := 40001; // 起始地址
#DATA_LEN := 2; // 读取2个寄存器
#Modbus_State := 2;
2: // 发送请求
"MB_MASTER_DB"(REQ:=TRUE,
MB_ADDR:=#MB_ADDR,
DATA_ADDR:=#DATA_ADDR,
DATA_LEN:=#DATA_LEN,
DATA_PTR:=#MB_DATA_IN,
DONE=>#MB_Done);
IF #MB_Done THEN
#Modbus_State := 3;
END_IF;
3: // 处理响应
IF #MB_Error = 0 THEN
// 数据转换处理
#Sensor_Value[#Current_Slave] :=
"Scale"(IN:=#MB_DATA_IN[1],
HI_LIM:=1000.0,
LO_LIM:=0.0);
END_IF;
// 切换下一从站
#Current_Slave := #Current_Slave + 1;
IF #Current_Slave > 4 THEN
#Current_Slave := 1;
END_IF;
#Modbus_State := 1;
END_CASE;
3.4.3 异常处理机制
-
超时设置:
- 每个从站设置500ms超时
- 超时后自动跳过该站
-
错误计数:
- 记录每个从站的连续错误次数
- 超过阈值(如3次)触发报警
-
数据校验:
- 检查返回数据长度是否符合预期
- 验证数据合理性(如范围检查)
4. 系统优化经验
4.1 CPU负载管理
S7-1215C在运行多个通讯协议时CPU负载可能达到80%以上,通过以下方法优化:
-
任务周期调整:
- 将Modbus轮询放在OB35(100ms周期)
- 运动控制放在OB30(10ms周期)
- 通讯处理放在OB1(主循环)
-
程序结构优化:
- 使用"LADDR"参数代替"P#"指针
- 减少复杂数学运算,尽量使用查表法
-
内存使用技巧:
- 将频繁访问的数据放在DB而非M区
- 使用优化的数据类型(如USINT代替INT)
4.2 诊断功能实现
完善的诊断功能可以大幅减少调试时间:
-
通讯状态监控:
- 记录各通讯接口的错误计数器
- 实现自动重连机制
-
设备健康检查:
- 定期检测伺服使能状态
- 监控机器人通讯心跳
-
报警管理系统:
- 分级报警(警告/错误/严重)
- 带时间戳的报警历史记录
4.3 维护便利性设计
-
参数集中管理:
- 将所有设备参数放在专用DB中
- 提供HMI界面修改关键参数
-
程序注释规范:
- 每个网络添加功能说明
- 重要变量添加单位注释
-
调试接口:
- 预留测试功能块
- 添加手动操作模式
5. 常见问题解决方案
5.1 通讯类问题
问题1:PROFINET设备频繁掉线
- 检查网线质量和连接器状态
- 验证设备名称是否冲突
- 调整PROFINET更新时间(建议≥8ms)
问题2:Modbus RTU通讯不稳定
- 确认终端电阻配置正确
- 检查总线是否有接地问题
- 降低波特率测试(如9600bps)
5.2 运动控制类问题
问题1:脉冲轴出现位置偏差
- 检查伺服驱动器的电子齿轮比设置
- 验证PLC脉冲输出是否被干扰
- 增加原点校正频率
问题2:V90伺服使能失败
- 检查控制字bit0(脉冲使能)
- 验证PROFINET报文配置
- 查看驱动器的报警代码
5.3 系统集成问题
问题1:多协议导致CPU过载
- 优化程序扫描周期
- 考虑升级到S7-1217C
- 将部分功能转移到HMI执行
问题2:数据同步不及时
- 检查通讯周期设置
- 增加数据校验机制
- 考虑使用全局数据块
6. 项目总结与建议
经过这个项目的实战,我总结了几个关键经验:
-
协议混合使用时,一定要做好负载测试。我们最初没有考虑Modbus轮询对系统的影响,导致运动控制偶尔出现卡顿。后来通过调整任务周期解决了这个问题。
-
设备选型要留有余量。这个项目最后CPU负载长期在65%左右,如果再增加功能就可能需要升级硬件。建议类似项目直接选择S7-1217C。
-
标准化编程很重要。我们建立了统一的FB/DB模板,后续维护和新功能开发效率提高了至少50%。
-
文档必须实时更新。特别是GSD文件版本、IP地址分配等关键信息,一定要有专人维护变更记录。
对于准备实施类似项目的同行,我的建议是:
- 前期充分做好通讯负载评估
- 购买正版GSD文件和技术支持
- 预留至少20%的时间用于系统联调
- 建立完善的报警和诊断系统
这个项目的完整程序框架和硬件配置清单我已经整理成标准化文档,后续类似项目可以直接套用,能节省至少30%的开发时间。