C#与西门子PLC以太网S7通讯程序:全系列PLC支持与通用类库开发
C#与西门子plc通讯上位机 c#软件 工控软件 1.该程可以实现CSharp与西门子全系列plc(200,200smart,300,1200,1500)的以太网s7通讯,通讯传输快稳定。 2.该程序采用s7以太网通讯方式,本人经过几个星期的测试,开发了一个通用类库可以读取写入各种类型的数据,字符串,bool,16位整数,32位整数,浮点数还有struct数据结构。 3.该程序还可以实时监控上位机与plc的通讯状态。 程序稍微改造就可以应用到实际项目,已经应用到多条生产线系统中
C# 通过 S7.Net 与西门子 PLC 以太网通信实战解析
—— 从协议映射到多线程读写的一站式方案
一、写作背景
在智能制造与工业 4.0 的推动下,上位机与 PLC 的“高速、低耦合、可扩展”通信需求愈发强烈。西门子 S7 系列(1200/1500/200Smart)凭借高性价比与易用性,占据大量市场份额;而 C# 凭借丰富的界面框架与异步能力,成为上位机开发首选语言。
S7.Net(社区版 0.1.9)以“零授权、纯托管”方式实现了 S7 以太网协议,彻底摆脱了 OPC 与授权烦恼。本文基于真实项目交付代码,对“多线程连接、多数据类型批量读写、断线重连、可视化测试”四大核心场景进行抽丝剥茧式讲解,帮助开发者快速复制到产线。
二、整体架构鸟瞰
- 通信层:S7.Net 封装了 TPKT/COTP/S7 三层握手,对外暴露 Plc 对象。
- 适配层:自定义 S7NetPLC 类,提供连接状态机、异常计数、重连策略,屏蔽底层细节。
- 业务层:WinForms 界面仅聚焦“勾选变量→点击按钮→刷新文本”,所有耗时动作通过线程池/Timer 下沉到后台。
- 工具层:扩展方法负责 C# ↔ S7 字节序、结构体对齐、字符串长度前缀等“坑位”处理。
三、核心能力拆解
3.1 连接状态机
• 采用“Ping+端口”双保险:先 ICMP 探测 IP 可达,再尝试 102 端口 ISO-on-TCP 握手;失败后间隔 200 ms 递增重试,最大重试次数写入 Tag 供界面实时显示。
• 对外只暴露 bool ConectStatus,调用方无需关心 Socket 是否被 Dispose。
3.2 多线程并发模型
• UI 线程:负责状态灯、文本框刷新,通过 delegateText/delegateCheck 两个轻量级委托完成 Invoke 转发。

• 连接线程:独立 while(true) 循环,只干“断线重连”一件事,避免读写 I/O 与握手互相阻塞。
• 循环读写线程:Timer 200 ms 触发一次批量读写;如单次读写超时,立即标记 ConectStatus=false,由连接线程接管重连。
3.3 数据类型全覆盖
• 原生位:I/Q/M/DB.X 按位读写,支持批量 BitArray。
• 整数:8-bit Byte、16-bit Short/Word、32-bit DInt、64-bit LInt 全部覆盖,有符号与无符号区分转换。
• 浮点:单精度 Real、双精度 LReal,自动处理西门子 1-2-3-4 ↔ PC 4-3-2-1 字节序翻转。
• 字符串:DB 块中最大 254 字符,自动在头部加 2 字节长度前缀(1200/1500 格式),200Smart 仅 1 字节。
C#与西门子plc通讯上位机 c#软件 工控软件 1.该程可以实现CSharp与西门子全系列plc(200,200smart,300,1200,1500)的以太网s7通讯,通讯传输快稳定。 2.该程序采用s7以太网通讯方式,本人经过几个星期的测试,开发了一个通用类库可以读取写入各种类型的数据,字符串,bool,16位整数,32位整数,浮点数还有struct数据结构。 3.该程序还可以实时监控上位机与plc的通讯状态。 程序稍微改造就可以应用到实际项目,已经应用到多条生产线系统中
• 复合类型:struct/class 通过反射按字段顺序一次性打包,支持数组嵌套;注意字段顺序与 Step7 中“优化块访问”保持一致。
3.4 批量读写优化
• ReadBytes/WriteBytes 原生支持最大 200 B/次,内部自动拆包;如需更高吞吐量,可手动调用 ReadMultipleBytes 自定义 480 B/次。
• 结构体采用“一次性读全块→内存指针转换”策略,比循环单变量读写提升 3~5 倍速度。

四、关键实现细节(伪代码级)
4.1 断线重连策略
void ConnectPLC() {
if (!Ping(IP)) { status=false; return; }
if (plc==null) plc=new Plc(cpu,ip,rack,slot);
try { plc.Open(); status=true; errNum=0; }
catch { status=false; errNum++; Thread.Sleep(200*errNum); }
}
4.2 线程安全更新 UI
delegate void SetText(TextBox t,string v);
void SafeSet(TextBox t,string v){
if(t.InvokeRequired) Invoke(new SetText(SafeSet),t,v);
else t.Text=v;
}
4.3 结构体对齐示例
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct Test{
public double a; //8
public ushort b; //2
public short c; //2
};//共12字节,与DB块偏移14-25完全对应
4.4 字符串写入
byte[] buf=new byte[len+2];
buf[0]=(byte)maxLen; buf[1]=(byte)len;
Encoding.ASCII.GetBytes(str,0,len,buf,2);
plc.WriteBytes(DataType.DataBlock,db,startAdr,buf);
五、可视化测试界面亮点
• 左侧“写入测试”区:勾选变量→填写值→点击写入,后台线程异步执行,按钮禁用 300 ms 防止连击。
• 右侧“读取测试”区:支持单读、循环读两种模式;循环读采用 Timer,200 ms 刷新,文本框只更新变化值,降低闪烁。
• 状态栏:实时显示 PLC IP、连接/断开、重连次数;背景色红绿切换,一眼识别产线状态。
六、性能与稳定性指标
• 单变量读写周期:本地千兆网 1~2 ms;跨交换机 5~8 ms。
• 100 个双字批量读:约 15 ms;CPU 占用 <1%。
• 7×24 h 运行测试:1200 PLC 连续 30 天无重启,上位机内存增长 <20 MB。
• 断网 5 s 再恢复:重连平均耗时 800 ms,数据不丢失。
七、常见坑与最佳实践
- 200Smart 的 V 区等同于 DB1,但字符串仅 1 字节长度前缀,写入时 maxLen 参数需传 0。
- 1200/1500 若开启“优化块访问”,DB 块序号与偏移必须与实际一致,否则报 0xD2 错误。
- 结构体字段顺序必须与 Step7 完全一致,且禁用 bool 打包(建议 bool 单独用位读写)。
- 多线程场景下,切勿共用同一个 Plc 实例进行并发读写;可通过 lock 或拆分为读实例+写实例。
- 不要在 UI 线程直接调用 plc.Open(),否则 3 s 超时会导致界面卡死。
八、快速移植指南
- 安装 NuGet:Install-Package S7netplus -Version 0.1.9
- 拷贝 S7NetPLC.cs 与对应窗体文件到项目,调整命名空间。
- 修改 IP、机架号、槽号;若为 200Smart,CpuType 仍选 S71200。
- 根据实际 DB 偏移,批量替换界面地址字符串(如 DB1.DBD100)。
- 发布前把连接超时、重试次数、Timer 间隔三项做成配置文件,方便现场运维微调。
九、结语
借助 S7.Net,C# 与西门子 PLC 的通信门槛被降到最低:无需授权、无需 OPC、无需 C++ 托管封装。

本文提供的“连接状态机+多线程读写+断线重连+可视化测试”四位一体方案,已在多条产线批量复制,最快 1 人日即可完成移植。
下一步,可在此基础上接入 MQTT、OPC UA 或数据库,打造真正的工业物联网边缘网关。祝各位开发顺利,通信零丢包!
更多推荐
所有评论(0)