[C#] 使用HslCommunication访问施耐德寄存器
如下访问关系示例
施耐德地址 | Hsl访问方法 | Hsl地址参数 |
MW5037 | ReadUint16 | 5037 |
MX16102.0 | ReadUint16 | 8051 |
MD2242 | ReadUint16 | 4484 |
MB40440 | ReadString | 20220 |
MW5037:直接过滤字符,使用Hsl访问5037即可,不需要额外加40000
MX16102.0:属于Byte类型,仅有0~7;按Byte与Uint16关系换算为8051,读取8051值后按Bit位得出T/F值;8051.0~7对应16102.0~7,8051.8~F对应16103.0~7
MD2242:属于Uint32类型,按Uint32与Uint16关系换算为4484
MB40440:属于Byte类型,施耐德字符串以ascii形式存储在MB寄存器中, 按Byte与Uint16关系换算为20220;读取MW20220得到MB40440+MB40441;如果地址为MB40441,需要读取20220后截取低八位
MD类型实际测试发现问题,按图例理解:
施耐德 | HslCommunication | ||
地址 | 值 | ReadUint16(20216,2) | ReadUint32(20216,1) |
MD10108 | 3 | [3,0] | [196608] |
MD10108 | 65538 | [2,1] | [65538] |
一段格式转换方法
public class SoMacAddr { public string type;//MW public string value;//8051 public int rate;//长度倍率 public int bit_pos;//指示是否访问bit位 } /// <summary> /// 将寄存器地址MW000转换为Modbus_Tcp地址 /// </summary> public SoMacAddr GetTcpAddr(string addr) { var res = new SoMacAddr(); if(int.TryParse(addr,out res.rate))//是40100格式地址 { res.value = addr; res.rate = 1; res.bit_pos = 0; return res; } if (addr.Length < 3) throw new Exception($"访问Modbus Tcp地址错误!"); res.type = addr.Substring(0, 2).ToUpper(); res.value = addr.Substring(2); res.rate = 1; res.bit_pos = -1; int dot_pos = res.value.IndexOf("."); if (dot_pos > 0)//有逗点格式 { string bit_tmp = res.value.Substring(dot_pos + 1); if(!int.TryParse(bit_tmp, out res.bit_pos)) throw new Exception($"访问Modbus Tcp地址错误!"); res.value = res.value.Substring(0, dot_pos); } int value_tmp; if (!int.TryParse(res.value, out value_tmp)) throw new Exception($"访问Modbus Tcp地址错误!"); switch (res.type) { //case "MD": // res.rate = 2; // res.value = (value_tmp * 2).ToString(); // break; case "MW": res.value = (value_tmp).ToString(); break; case "MX": case "ML": if (1 == value_tmp % 2) res.bit_pos += 8; value_tmp /= 2;//舍弃余数 res.value = value_tmp.ToString(); break; default: throw new Exception($"不支持的地址!"); } return res; }
Hsl访问示例(使用ModbusTcpNet)
private ModbusTcpNet plc_Modbus = null; private string plc_Ip; private int plc_Port = 502; public SoMacHelper(string ip, int port) { plc_Ip = ip; plc_Port = port; plc_Modbus = new ModbusTcpNet(plc_Ip, plc_Port); } public override bool Open() { var res = false; plc_Modbus.ConnectTimeOut = 800; var plc_Result = plc_Modbus.ConnectServer(); res = plc_Result.IsSuccess; return res; } public override bool ReadUint16(string addr, int lenth, out UInt16[] value) { bool res = false; value = null; var opera_addr = GetTcpAddr(addr); OperateResult<UInt16[]> r = plc_Modbus.ReadUInt16(opera_addr.value, (UInt16)(lenth * opera_addr.rate)); if (r.IsSuccess) { value = r.Content; } res = r.IsSuccess; return res; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!