☰
用 HSL 重构 PLC 通信,核心是把过去“一个品牌一套库、一套异常处理”的碎片化代码,统一为 **“一个 `OperateResult` 模式、一套读写 API”** 的标准化结构
2026/10/19 2:00:53 网站建设 项目流程

用 HSL 重构 PLC 通信,核心是把过去“一个品牌一套库、一套异常处理”的碎片化代码,统一为“一个OperateResult模式、一套读写 API”的标准化结构。

重构的核心:理解OperateResult模式

HSL 所有读写操作都返回OperateResult或OperateResult<T>。你不再需要 try-catch 包裹每一次调用,而是统一检查.IsSuccess:

varresult=plc.ReadInt16("DB100.2");if(result.IsSuccess){shortvalue=result.Content;}else{// result.Message 给出失败原因}

这个设计让通信错误处理变得可预测,也便于在应用层统一封装重试逻辑。

重构案例:西门子 S7-1200/1500 视觉结果写入

以下是把之前 S7.NetPlus 的握手逻辑,重构为 HSL 实现的完整代码。

1. 连接管理类

usingHslCommunication;usingHslCommunication.Profinet.Siemens;publicclassPlcService{privateSiemensS7Net_plc;privatereadonlystring_ip;privatebool_connected;publicPlcService(stringip){_ip=ip;}publicOperateResultConnect(){// S7-1200/1500 机架0,槽1_plc=newSiemensS7Net(SiemensPLCS.S1500,_ip);varresult=_plc.ConnectServer();// 只调一次_connected=result.IsSuccess;returnresult;}publicboolIsConnected=>_connected&&_plc!=null;}

关键约束:ConnectServer()不要放在定时器里反复调用。它内部会先关闭旧连接再重建,若此时有并发读写会引发异常。正确做法是启动时连一次,后续通过每次读写的IsSuccess感知连接状态。

2. 视觉结果写入(含握手)

假设视觉结果写入 DB100,内存布局为:

地址类型用途
DB100.0BoolResultsValid(视觉→PLC)
DB100.1BoolInspectionAck(PLC→视觉)
DB100.2Int16X坐标
DB100.4Int16Y坐标
DB100.6Int16角度(×100)
publicOperateResultWriteVisionResult(shortx,shorty,shortangle){// 批量写入结果数据varr1=_plc.Write("DB100.2",x);if(!r1.IsSuccess)returnr1;varr2=_plc.Write("DB100.4",y);if(!r2.IsSuccess)returnr2;varr3=_plc.Write("DB100.6",angle);if(!r3.IsSuccess)returnr3;// 最后置握手位return_plc.Write("DB100.0",true);}publicOperateResult<bool>ReadAck(){return_plc.ReadBool("DB100.1");}

注意地址格式差异:HSL 的西门子地址写作"DB100.2",而非 S7.NetPlus 的"DB100.DBW2"。

3. 调用侧的握手流程

// 视觉检测完成后varwriteResult=plcService.WriteVisionResult(x,y,angle);if(writeResult.IsSuccess){// 等待 PLC 确认(循环检查 Ack)for(inti=0;i<10;i++){Thread.Sleep(50);varack=plcService.ReadAck();if(ack.IsSuccess&&ack.Content){// PLC 已读取,清零 ResultsValidplcService.Write("DB100.0",false);break;}}}

批量读取与字节转换

对于需要读取连续地址的场景,HSL 提供Read返回byte[],再用ByteTransform按偏移解析,避免多次网络往返:

OperateResult<byte[]>read=_plc.Read("DB100",10);// 读20字节if(read.IsSuccess){shorttemp=_plc.ByteTransform.TransInt16(read.Content,0);shortpress=_plc.ByteTransform.TransInt16(read.Content,2);intcount=_plc.ByteTransform.TransInt32(read.Content,4);}

重构后的结构性收益

相比之前的 S7.NetPlus 方案,HSL 重构带来三个实际变化:

1. 多品牌切换成本归零。若产线新增一台三菱 PLC,只需把SiemensS7Net换成MelsecMcNet,读写方法名和OperateResult检查逻辑完全一致。

2. 异步支持原生可用。HSL 提供ReadAsync/WriteAsync,返回Task<OperateResult>,便于在视觉上位机中与async/await流水线集成。

3. 错误处理统一化。不再需要为每个品牌的异常类型写不同的 catch 分支,所有通信失败都通过IsSuccess和Message表达。

需要注意的实操约束

优化块访问问题不变。HSL 的SiemensS7Net同样基于绝对地址寻址,TIA Portal 中的目标 DB 块仍需取消“优化的块访问”。

不要用 ConnectServer 做心跳检测。由于它内部会重建连接,应与读写操作互斥。连接状态直接通过读写结果判断即可。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询