using HslCommunication; using HslCommunication.Core; using HslCommunication.Profinet.Omron; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace PLCCommunication { // 摘要: // 欧姆龙PLC通讯类,采用Fins-Tcp通信协议实现,支持的地址信息参见api文档信息。 // Omron PLC communication class is implemented using Fins-Tcp communication protocol. // For the supported address information, please refer to the api document information. // // 言论: // 实例化之后,使用之前,需要初始化三个参数信息,具体见三个参数的说明:HslCommunication.Profinet.Omron.OmronFinsNet.SA1,HslCommunication.Profinet.Omron.OmronFinsNet.DA1,HslCommunication.Profinet.Omron.OmronFinsNet.DA2 // 第二个需要注意的是,当网络异常掉线时,无法立即连接上PLC,PLC对于当前的节点进行拒绝,如果想要支持在断线后的快速连接,就需要将 HslCommunication.Profinet.Omron.OmronFinsNet.IsChangeSA1AfterReadFailed设置为True,详细的可以参考 // HslCommunication.Profinet.Omron.OmronFinsNet.IsChangeSA1AfterReadFailed // 如果在测试的时候报错误码64,经网友 上海-Lex 指点,是因为PLC中产生了报警,如伺服报警,模块错误等产生的,但是数据还是能正常读到的,屏蔽64报警或清除plc错误可解决 // 地址支持的列表如下: // 地址名称 – 地址代号 – 示例 – 地址进制 – 字操作 – 位操作 – 备注 – // DM Area – D – D100,D200 – 10 – √ – √ – – // CIO Area – C – C100,C200 – 10 – √ – √ – – // Work Area – W – W100,W200 – 10 – √ – √ – – // Holding Bit Area – H – H100,H200 – 10 – √ – √ – – // Auxiliary Bit Area – A – A100,A200 – 10 – √ – √ – – // EM Area – E – E0.0,EF.200,E10.100 – 10 – √ – √ – – public partial class OmronPLCUI : UserControl { /// /// 批量读取PLC数据委托 /// /// /// /// public delegate void ReceiveHandler(int Index, string msg, OperateResult resByte); public event ReceiveHandler ReceiveEvent; /// /// 读取PLC心跳消息状态至主窗口委托 /// /// public delegate void UpHeartBeatHandler(bool b); public event UpHeartBeatHandler UpHeartBeatEvent; /// /// 保存配置事件委托 /// /// /// public delegate void SaveParamsHandler(int plcIndex, int trgIndex); public event SaveParamsHandler SaveParamsEvent; public int Index; /// /// 欧姆龙Fins协议 /// public HslCommunication.Profinet.Omron.OmronCipNet omronCipNet = null; public HslCommunication.Profinet.Omron.OmronFinsNet omronFinsNet = null; /// /// 是否链接PLC /// private bool _isConnected = false; /// /// 是否开启心跳消息 /// private bool _heartBeat = false; /// /// 断线后是否更换SA1的值 /// private bool _changesa1 = false; /// /// 心跳消息寄存器地址 /// private string _heartAddr = "100"; /// /// /// public Dictionary dicJobToTrgParams = new Dictionary(); /// /// /// public List lstTrgUI = new List(); /// /// /// public List lstTgrParams = new List(); /// /// /// public PLCConfig PlcConfig = new PLCConfig(); /// /// /// public CancellationTokenSource mCTSRecv = new CancellationTokenSource(); public CancellationTokenSource mCTSHeart = new CancellationTokenSource(); private ManualResetEvent resetEventRecv = new ManualResetEvent(true); private ManualResetEvent resetEventHeart = new ManualResetEvent(true); /// /// /// public bool IsConnected { get { return _isConnected; } set { _isConnected = value; if (_isConnected) { //lblConnectStatus.ForeColor = Color.Green; lblConnectStatus.Image = Properties.Resources.green; } else { lblConnectStatus.Image = Properties.Resources.red; } } } /// /// /// public bool IsRun { get; set; } = false; /// /// /// private string CurrentTime => DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff"); public bool HeartBeat { get { return _heartBeat; } set { _heartBeat = value; } } public bool ChangeSA1 { get { return _changesa1; } set { _changesa1 = value; } } public string HeartAddr { get { return _heartAddr; } set { _heartAddr = value; txtHeartAddr.Text = value.ToString(); } } /// /// 读取PLC数据线程等待时间 /// public int ScanTime { get; set; } = 100; public int JobCount { get; set; } /// /// PLCIP地址 /// public string IP { get; set; } /// /// PLC端口 /// public int Port { get; set; } public bool DispCurrent { get; set; } = false; public OmronPLCUI() { InitializeComponent(); omronCipNet = new OmronCipNet(); omronCipNet.ConnectTimeOut = 2000; omronFinsNet = new OmronFinsNet(); omronFinsNet.ConnectTimeOut = 2000; PanelTest.Enabled = false; } public OmronPLCUI(PLCConfig plcConfig) : this() { PlcConfig = plcConfig; Index = plcConfig.Index; IP = plcConfig.IP; Port = plcConfig.Port; JobCount = plcConfig.JobCount; ScanTime = plcConfig.ScanTime; HeartBeat = plcConfig.HeartBeat; ChangeSA1 = plcConfig.ChangeSA1; lstTgrParams = plcConfig.lstTgrParams; _heartAddr = plcConfig.HeartAddr; InitialTiggerModule(lstTgrParams); cboReadType.DataSource = Enum.GetNames(typeof(VarType)); cboReadType.SelectedIndex = 0; if (HeartBeat) { cbHeartBeat.Checked = true; } else { cbHeartBeat.Checked = false; } txtIP.Text = PlcConfig.IP.Trim(); txtPort.Text = PlcConfig.Port.ToString(); txtHeartAddr.Text = PlcConfig.HeartAddr; txtSolt.Text = PlcConfig.Solt.ToString(); InitialAndConnect(); Task HeartTask = Task.Factory.StartNew(delegate { CheckHeart(); }, mCTSHeart.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); if (!IsRun) { resetEventRecv.Reset(); } SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); } private void MelsecPLCUI_Load(object sender, EventArgs e) { List ipv4_ips = GetLocalIpAddress("InterNetwork");//获取ipv4类型的ip //string da = ipv4_ips[0].LastIndexOf('.')-1; } //List ips = GetLocalIpAddress("");//获取本地所有ip //List ipv4_ips = GetLocalIpAddress("InterNetwork");//获取ipv4类型的ip //List ipv6_ips = GetLocalIpAddress("InterNetworkV6");//获取ipv6类型的ip /// /// 获取本机所有ip地址 /// /// "InterNetwork":ipv4地址,"InterNetworkV6":ipv6地址 /// ip地址集合 public static List GetLocalIpAddress(string netType) { string hostName = Dns.GetHostName(); //获取主机名称 IPAddress[] addresses = Dns.GetHostAddresses(hostName); //解析主机IP地址 List IPList = new List(); if (netType == string.Empty) { for (int i = 0; i < addresses.Length; i++) { IPList.Add(addresses[i].ToString()); } } else { //AddressFamily.InterNetwork表示此IP为IPv4, //AddressFamily.InterNetworkV6表示此地址为IPv6类型 for (int i = 0; i < addresses.Length; i++) { if (addresses[i].AddressFamily.ToString() == netType) { if (addresses[i].ToString().Contains("192")) { IPList.Add(addresses[i].ToString()); } } } } return IPList; } public void InitialTiggerModule(List lstTrgParams) { tabConTrgUI.TabPages.Clear(); for (int i = 0; i < lstTrgParams.Count; i++) { TriggerUI triggerUI = new TriggerUI(lstTrgParams[i]); tabConTrgUI.TabPages.Add(lstTrgParams[i].ThreadName); Panel panel = new Panel(); tabConTrgUI.TabPages[i].Controls.Add(panel); panel.Dock = DockStyle.Fill; panel.Controls.Add(triggerUI); triggerUI.Dock = DockStyle.Fill; triggerUI.TrgParamChangeEvent += TriggerUI_TrgParamChangeEvent; lstTrgUI.Add(triggerUI); } } private void TriggerUI_TrgParamChangeEvent(int tgrIndex) { OnSaveParams(Index, tgrIndex); } public bool Connect() { if (!IPAddress.TryParse(txtIP.Text, out IPAddress address)) { AddLog(lstRecv, 1, "PLCIP地址格式不正确"); return false; } if (!int.TryParse(txtPort.Text, out int port)) { AddLog(lstRecv, 1, "端口号格式不正确"); return false; } if (!byte.TryParse(txtSolt.Text, out byte solt)) { AddLog(lstRecv, 1, "PLC插槽号设置错误!"); return false; } string str = ""; omronCipNet.IpAddress = address.ToString(); omronCipNet.Port = port; omronCipNet.Slot = solt; omronCipNet.ConnectClose(); omronFinsNet.IpAddress = address.ToString(); omronFinsNet.Port = 9600; omronFinsNet.DA2 = 0; omronFinsNet.ByteTransform.DataFormat = DataFormat.CDAB; omronFinsNet.ByteTransform.IsStringReverseByteWord = true; omronFinsNet.ConnectTimeOut = 2000; omronFinsNet.ReceiveTimeOut = 2000; omronFinsNet.ConnectClose(); try { omronCipNet.ConnectTimeOut = 2000; OperateResult connect = omronCipNet.ConnectServer(); if (connect.IsSuccess) { IsConnected = true; BtnDisConnect.Enabled = true; BtnConnect.Enabled = false; str = StringResources.Language.ConnectedSuccess; AddLog(lstRecv, 0, StringResources.Language.ConnectedSuccess); omronFinsNet.ConnectTimeOut = 2000; OperateResult connectFins = omronFinsNet.ConnectServer(); return true; } else { IsConnected = false; str = StringResources.Language.ConnectedFailed; AddLog(lstRecv,1, StringResources.Language.ConnectedFailed); } } catch (Exception ex) { str = ex.Message; IsConnected = false; AddLog(lstRecv, 1, ex.Message); } //LogManagerControl.AddLog($"{str}", LogAddtype.local, Logtype.Message); return false; } /// /// 对PLC进行链接 /// /// /// private void BtnConnect_Click(object sender, EventArgs e) { Connect(); } /// /// 与LC断开链接 /// /// /// private void BtnDisConnect_Click(object sender, EventArgs e) { ConnectClose(); } /// /// 断开PLC的链接 /// public void ConnectClose() { omronCipNet.ConnectClose(); BtnDisConnect.Enabled = false; BtnConnect.Enabled = true; lblConnectStatus.Image = Properties.Resources.red; IsConnected = false; AddLog(lstRecv, 0, "断开连接"); } /// /// 界面测试复选框 /// /// /// private void cbTest_CheckedChanged(object sender, EventArgs e) { if (cbTest.Checked) { PanelTest.Enabled = true; } else { PanelTest.Enabled = false; } } /// /// 读取PLC数据 /// /// /// private void BtnReadTest_Click(object sender, EventArgs e) { if (!IsConnected) { AddLog(lstRecv, 1, "未连接到PLC,请检查连接状态"); return; } if (txtReadAddrTest.Text.Trim() == "") { AddLog(lstRecv, 1, "读取地址不能为空"); return; } if (txtReadTestLength.Text.Trim() == "") { AddLog(lstRecv, 1, "读取长度不能为空"); return; } try { switch ((VarType)Enum.Parse(typeof(VarType), cboReadType.SelectedItem.ToString(), false)) { case VarType.Bit: DemoUtils.ReadResultRender(omronCipNet.ReadBool(txtReadAddrTest.Text, ushort.Parse(txtReadTestLength.Text.Trim())), txtReadAddrTest.Text, txtReadResultTest); break; case VarType.Short: DemoUtils.ReadResultRender(omronCipNet.ReadInt16(txtReadAddrTest.Text, ushort.Parse(txtReadTestLength.Text.Trim())), txtReadAddrTest.Text, txtReadResultTest); break; case VarType.Int: DemoUtils.ReadResultRender(omronCipNet.ReadInt32(txtReadAddrTest.Text, ushort.Parse(txtReadTestLength.Text.Trim())), txtReadAddrTest.Text, txtReadResultTest); break; case VarType.Float: DemoUtils.ReadResultRender(omronCipNet.ReadFloat(txtReadAddrTest.Text, ushort.Parse(txtReadTestLength.Text.Trim())), txtReadAddrTest.Text, txtReadResultTest); break; case VarType.String: DemoUtils.ReadResultRender(omronCipNet.ReadString(txtReadAddrTest.Text, ushort.Parse(txtReadTestLength.Text.Trim())), txtReadAddrTest.Text, txtReadResultTest); break; case VarType.Byte: DemoUtils.ReadResultRender(omronCipNet.Read(txtReadAddrTest.Text, ushort.Parse(txtReadTestLength.Text.Trim())), txtReadAddrTest.Text, txtReadResultTest); break; } } catch (Exception ex) { AddLog(lstRecv, 1, "读取失败,请检查地址类型或连接状态" + ex.Message); } } /// /// 写入PLC数据 /// /// /// private void BtnWriteTest_Click(object sender, EventArgs e) { if (!IsConnected) { AddLog(lstRecv, 1, "未连接到PLC,请检查连接状态"); return; } if (txtReadAddrTest.Text.Trim() == "") { AddLog(lstRecv, 1, "写入地址不能位空"); return; } if (txtReadTestLength.Text.Trim() == "") { AddLog(lstRecv, 1, "写入长度不能为空"); return; } try { VarType varType = (VarType)Enum.Parse(typeof(VarType), cboReadType.SelectedItem.ToString(), false); switch (varType) { case VarType.Bit: { string type = txtWriteValue.Text.Trim().Substring(0, 1); if (type != "D" && type != "W") { MessageBox.Show("暂只支持D,W存储区"); break; } bool[] boolArray = GetBoolArray(txtWriteValue.Text.Trim()); DemoUtils.WriteResultRender(() => omronCipNet.Write(txtReadAddrTest.Text.Trim(), boolArray), txtReadAddrTest.Text.Trim()); break; } case VarType.Short: { short[] shortArray = GetShortArray(txtWriteValue.Text.Trim()); DemoUtils.WriteResultRender(() => omronCipNet.Write(txtReadAddrTest.Text.Trim(), shortArray), txtReadAddrTest.Text.Trim()); break; } case VarType.Int: { int[] intArray = GetIntArray(txtWriteValue.Text.Trim()); DemoUtils.WriteResultRender(() => omronCipNet.Write(txtReadAddrTest.Text.Trim(), intArray), txtReadAddrTest.Text.Trim()); break; } case VarType.Float: { float[] floatArray = GetFloatArray(txtWriteValue.Text.Trim()); DemoUtils.WriteResultRender(() => omronCipNet.Write(txtReadAddrTest.Text.Trim(), floatArray), txtReadAddrTest.Text.Trim()); break; } case VarType.Byte: { DemoUtils.WriteResultRender(() => omronCipNet.Write(txtReadAddrTest.Text.Trim(), txtWriteValue.Text.Trim()), txtReadAddrTest.Text.Trim()); break; } case VarType.String: { DemoUtils.WriteResultRender(() => omronCipNet.Write(txtReadAddrTest.Text.Trim(), txtWriteValue.Text.Trim()), txtReadAddrTest.Text.Trim()); break; } } } catch (Exception ex) { AddLog(lstRecv, 1, "写入失败,请检查地址类型或连接状态" + ex.Message); } } /// /// 开启 /// public void InitialAndConnect() { Task RecvTask = Task.Factory.StartNew(delegate { GetMelsecValue(); }, mCTSRecv.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); } /// /// 链接PLC状态 /// /// public void OmronStart(bool status) { if (status) { resetEventRecv.Set(); } else { resetEventRecv.Reset(); } } /// /// 循环读取PLC数据 /// private void GetMelsecValue() { while (true) { if (mCTSRecv.Token.IsCancellationRequested) { return; } resetEventRecv.WaitOne(); if (IsRun) { if (IsConnected) { OperateResult resByte = null; for (int i = 0; i < JobCount; i++) { StringBuilder res = new StringBuilder(string.Empty); switch (lstTrgUI[i].TrgParams.TriggerType) { case VarType.Bit: res.Append(omronCipNet.ReadBool(lstTrgUI[i].TrgParams.TriggerAddr).Content.ToString()); break; case VarType.Short: res.Append(omronCipNet.ReadInt16(lstTrgUI[i].TrgParams.TriggerAddr).Content.ToString()); break; case VarType.Int: res.Append(omronCipNet.ReadInt32(lstTrgUI[i].TrgParams.TriggerAddr).Content.ToString()); break; case VarType.Float: res.Append(omronCipNet.ReadFloat(lstTrgUI[i].TrgParams.TriggerAddr).Content.ToString()); break; case VarType.String: res.Append(omronCipNet.ReadString(lstTrgUI[i].TrgParams.TriggerAddr, Convert.ToUInt16(txtReadTestLength.Text.Trim())).Content.ToString()); break; case VarType.Byte: resByte = omronCipNet.Read(lstTrgUI[i].TrgParams.TriggerAddr, Convert.ToUInt16(txtReadTestLength.Text.Trim())); res.Append(HslCommunication.BasicFramework.SoftBasic.ByteToHexString(resByte.Content)); break; } if (lstTrgUI[i].TrgParams.IsRead) { resByte = omronCipNet.Read(lstTrgUI[i].TrgParams.ReadAddr, Convert.ToUInt16(lstTrgUI[i].TrgParams.ReadLength)); //res.Append(HslCommunication.BasicFramework.SoftBasic.ByteToHexString(resByte.Content)); } if (DispCurrent) { AddLog(lstRecv, 0, lstTrgUI[i].TrgParams.TriggerAddr + "-->" + res.ToString()); } if (res.ToString() == lstTrgUI[i].TrgParams.TriggerCmd) { AddLog(lstTrgCmd, 0, $"{lstTrgUI[i].TrgParams.TriggerAddr}-->{res}"); } OnReceive(i + 1, res.ToString(), resByte); Thread.Sleep(5); } Thread.Sleep(ScanTime); } else if (HeartBeat) { Thread.Sleep(5000); if (!IPAddress.TryParse(txtIP.Text, out IPAddress address)) { AddLog(lstRecv, 1, "PLCIP地址格式不正确"); return; } if (!int.TryParse(txtPort.Text, out int port)) { AddLog(lstRecv, 1, "端口号格式不正确"); return; } if (!byte.TryParse(txtSolt.Text, out byte solt)) { AddLog(lstRecv, 1, "PLC单元设置错误"); break; } omronCipNet.IpAddress = address.ToString(); omronCipNet.Port = port; omronCipNet.Slot = solt; omronCipNet.ConnectTimeOut = 2000; OperateResult connect = omronCipNet.ConnectServer(); if (connect.IsSuccess) { Invoke((Action)delegate { IsConnected = true; BtnDisConnect.Enabled = true; BtnConnect.Enabled = false; lblConnectStatus.Image = Properties.Resources.red; }); } } else { Thread.Sleep(10000); } } else { Thread.Sleep(2000); } } AddLog(lstRecv, 1, "端口号格式不正确"); } /// /// 心跳消息 /// private void CheckHeart() { while (!mCTSHeart.Token.IsCancellationRequested) { if (IsRun) { if (HeartBeat) { try { Thread.Sleep(1000); OperateResult result = omronCipNet.Write(HeartAddr, (short)1); if (result.IsSuccess) { OnUpHeartBeat(true); AddLog(lstSend, 0, $"心跳 {txtHeartAddr.Text}-> {1}"); continue; } Invoke((Action)delegate { OnUpHeartBeat(false); IsConnected = false; BtnConnect.Enabled = true; BtnDisConnect.Enabled = false; //lblConnectStatus.IsFlash = false; //lblConnectStatus.LedStatus = false; }); AddLog(lstSend, 2, $"心跳 {txtHeartAddr.Text}-> {1}失败"); } catch (Exception ex) { Invoke((Action)delegate { OnUpHeartBeat(false); IsConnected = false; BtnConnect.Enabled = true; BtnDisConnect.Enabled = false; //lblConnectStatus.IsFlash = false; //lblConnectStatus.LedStatus = false; }); AddLog(lstSend, 2, ex.Message); } } else { Thread.Sleep(1000); } } } } /// /// 对PLC某寄存器清零 /// /// /// public void ClearReg(string iAddr, VarType varType) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); return; } switch (varType) { case VarType.Bit: omronCipNet.Write(iAddr, false); break; case VarType.Float: omronCipNet.Write(iAddr, 0f); break; case VarType.Short: omronCipNet.Write(iAddr, (short)0); break; case VarType.Int: omronCipNet.Write(iAddr, 0); break; case VarType.String: omronCipNet.Write(iAddr, 0); break; } } /// ///读取BOOL值 /// /// /// public bool ReadBoolDReg(string iAddr) { bool result = false; try { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { result = omronCipNet.ReadBool(iAddr).Content; AddLog(lstResWrite, 0, $"{iAddr} --> {result.ToString()}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } /// ///读取String值 /// /// /// public string ReadStringDReg(string iAddr) { string result = ""; try { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { result = omronCipNet.ReadString(iAddr).Content; AddLog(lstResWrite, 0, $"{iAddr} --> {result}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } /// /// 读取16位整数 /// /// /// public short ReadshortDReg(string iAddr) { short result = 0; try { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { result = omronCipNet.ReadInt16(iAddr).Content; AddLog(lstResWrite, 0, $"{iAddr} --> {result.ToString()}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } /// /// 读取32位整数 /// /// /// public int ReadIntDReg(string iAddr) { int result = 0; try { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W" && type != "H") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { result = omronCipNet.ReadInt32(iAddr).Content; AddLog(lstResWrite, 0, $"{iAddr} --> {result.ToString()}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } /// /// 读取浮点数 /// /// /// public float ReadFloatDReg(string iAddr) { float result = 0; try { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W" && type != "H") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { result = omronCipNet.ReadFloat(iAddr).Content; AddLog(lstResWrite, 0, $"{iAddr} --> {result.ToString()}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } /// /// 读取byte /// /// 数据地址 /// 读取长度 /// public byte[] Readbyte(string iAddr, ushort lenght) { byte[] result = null; try { //string type = iAddr.Substring(0, 1); //if (type != "D" && type != "R") //{ // AddLog(lstSend, 2, "暂只支持D,R存储区"); //} if (IsConnected) { result = omronCipNet.Read(iAddr, lenght).Content; AddLog(lstResWrite, 0, $"{iAddr} --> {result?.ToString()}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } public byte[] ReadByteFins(string iAddr, ushort length) { byte[] result = null; try { //string type = iAddr.Substring(0, 1); //if (type != "D" && type != "R") //{ // AddLog(lstSend, 2, "暂只支持D,R存储区"); //} if (IsConnected) { result = omronFinsNet.Read(iAddr, length).Content; OperateResult barray = omronFinsNet.ReadBool(iAddr, length); AddLog(lstResWrite, 0, $"{iAddr} --> {result?.ToString()}"); } } catch (Exception ex) { AddLog(lstResWrite, 2, $"{iAddr} --> {ex.Message}"); } return result; } /// /// 写入byte数组 /// /// /// public void WriteDReg(string iAddr, byte[] Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); //OperateResult result = omronCipNet.WriteTag(iAddr,210, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } public void WriteDReg(string iAddr, float Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); //OperateResult result = omronCipNet.WriteTag(iAddr,210, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } /// /// 写入单个int类型数据 /// /// /// public void WriteDReg(string iAddr, string Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } /// /// 写入单个int类型数据 /// /// /// public void WriteDReg(string iAddr, int Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } /// /// 批量写入int类型数据 /// /// /// public void WriteDReg(string iAddr, int[] Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } /// /// 批量写入ushort类型数据 /// /// /// public void WriteDReg(string iAddr, short[] Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); if (result.IsSuccess) { for (int i = 0; i < Value.Length; i++) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value[i]}"); } } else { for (int i = 0; i < Value.Length; i++) { AddLog(lstResWrite, 2, $"{iAddr} --> {Value[i]}"); } } } } /// /// 写入单个Short类型数据 /// /// /// public void WriteDReg(string iAddr, short Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } /// /// 写BOOL /// /// /// public void WriteDReg(string iAddr, bool Value) { string type = iAddr.Substring(0, 1); if (type != "D" && type != "W") { AddLog(lstSend, 2, "暂只支持D,W存储区"); } else if (IsConnected) { OperateResult result = omronCipNet.Write(iAddr, Value); if (result.IsSuccess) { AddLog(lstResWrite, 0, $"{iAddr} --> {Value}"); } else { AddLog(lstResWrite, 2, $"{iAddr} --> {Value}"); } } } /// /// 是否启用心跳消息 /// /// /// private void cbHeartBeat_CheckedChanged(object sender, EventArgs e) { if (cbHeartBeat.Checked) { HeartBeat = true; } else { HeartBeat = false; } } /// /// 保存配置 /// /// /// private void btnSaveConfig_Click(object sender, EventArgs e) { try { PlcConfig.Index = Index; PlcConfig.IP = txtIP.Text.Trim(); PlcConfig.Port = Convert.ToInt32(txtPort.Text.Trim()); PlcConfig.HeartBeat = cbHeartBeat.Checked; PlcConfig.HeartAddr = txtHeartAddr.Text.Trim(); PlcConfig.JobCount = JobCount; PlcConfig.ScanTime = ScanTime; PlcConfig.Solt= Convert.ToInt32(txtSolt.Text.Trim()); OnSaveParams(Index, 0); AddLog(lstRecv, 0, "保存参数成功"); } catch (Exception ex) { AddLog(lstRecv, 1, "保存参数失败" + ex.Message); } } /// /// 日志显示 /// /// /// /// private void AddLog(ListView lstView, int type, string info) { ListViewItem lst = new ListViewItem(" " + CurrentTime, type); lst.SubItems.Add(info); if (base.InvokeRequired) { Invoke((Action)delegate { lstView.Items.Insert(0, lst); if (lstView.Items.Count > 2000) { lstView.Items.Clear(); } }); } else { if (lstView.Items.Count > 2000) { lstView.Items.Clear(); } lstView.Items.Insert(0, lst); } } /// /// /// /// /// private bool[] GetBoolArray(string val) { try { List Result = new List(); if (val.Contains(',')) { string[] str = Regex.Split(val, ",", RegexOptions.IgnoreCase); string[] array = str; foreach (string item in array) { Result.Add(item.ToLower() == "true" || item.ToLower() == "1"); } } else { Result.Add(val.ToLower() == "true" || val.ToLower() == "1"); } return Result.ToArray(); } catch (Exception) { return null; } } private short[] GetShortArray(string val) { try { List Result = new List(); if (val.Contains(',')) { string[] str = Regex.Split(val, ",", RegexOptions.IgnoreCase); string[] array = str; foreach (string item in array) { Result.Add(Convert.ToInt16(item)); } } else { Result.Add(Convert.ToInt16(val)); } return Result.ToArray(); } catch (Exception) { return null; } } private int[] GetIntArray(string val) { try { List Result = new List(); if (val.Contains(',')) { string[] str = Regex.Split(val, ",", RegexOptions.IgnoreCase); string[] array = str; foreach (string item in array) { Result.Add(Convert.ToInt32(item)); } } else { Result.Add(Convert.ToInt32(val)); } return Result.ToArray(); } catch (Exception) { return null; } } private float[] GetFloatArray(string val) { try { List Result = new List(); if (val.Contains(',')) { string[] str = Regex.Split(val, ",", RegexOptions.IgnoreCase); string[] array = str; foreach (string item in array) { Result.Add(Convert.ToSingle(item)); } } else { Result.Add(Convert.ToSingle(val)); } return Result.ToArray(); } catch (Exception) { return null; } } /// /// 清除消息 /// /// /// private void btnClearRecv_Click(object sender, EventArgs e) { lstRecv.Items.Clear(); } /// /// 数据接受委托事件 /// /// /// /// public void OnReceive(int Index, string msg, OperateResult resByte) { if (this.ReceiveEvent != null) { this.ReceiveEvent(Index, msg, resByte); } } /// /// 心跳消息委托事件 /// /// public void OnUpHeartBeat(bool b) { if (this.UpHeartBeatEvent != null) { this.UpHeartBeatEvent(b); } } /// /// 保存信息委托事件 /// /// /// public void OnSaveParams(int plcIndex, int trgIndex) { if (this.SaveParamsEvent != null) { this.SaveParamsEvent(plcIndex, trgIndex); } } /// /// 关闭读取PLC数据 /// public void Shutdown() { if (omronCipNet != null) { try { mCTSRecv.Cancel(); mCTSHeart.Cancel(); } catch (Exception) { } } } /// /// 链接PLC开始启动 /// /// /// private void btnStart_Click(object sender, EventArgs e) { if (!IsRun) { Connect(); OmronStart(true); IsRun = true; btnStart.Text = "停止"; } else { ConnectClose(); OmronStart(false); IsRun = false; btnStart.Text = "启动"; } } /// /// /// /// /// private void cbDispCurrent_CheckedChanged(object sender, EventArgs e) { if (cbDispCurrent.Checked) { DispCurrent = true; } else { DispCurrent = false; } } /// /// 心跳消息赋值 /// /// /// private void txtHeartAddr_TextChanged(object sender, EventArgs e) { _heartAddr = txtHeartAddr.Text; } private void button1_Click(object sender, EventArgs e) { //OperateResult operateResult = omron_finsnet.ReadCpuUnitData(); //if (operateResult.IsSuccess) //{ // txtReadResultTest.Text = operateResult.Content.ToJsonString(); //} //else //{ // MessageBox.Show("read failed:" + operateResult.Message); //} } } }