Files
2026-09-08 14:11:48 +08:00

1518 lines
52 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
/// <summary>
/// 批量读取PLC数据委托
/// </summary>
/// <param name="Index"></param>
/// <param name="msg"></param>
/// <param name="resByte"></param>
public delegate void ReceiveHandler(int Index, string msg, OperateResult<byte[]> resByte);
public event ReceiveHandler ReceiveEvent;
/// <summary>
/// 读取PLC心跳消息状态至主窗口委托
/// </summary>
/// <param name="b"></param>
public delegate void UpHeartBeatHandler(bool b);
public event UpHeartBeatHandler UpHeartBeatEvent;
/// <summary>
/// 保存配置事件委托
/// </summary>
/// <param name="plcIndex"></param>
/// <param name="trgIndex"></param>
public delegate void SaveParamsHandler(int plcIndex, int trgIndex);
public event SaveParamsHandler SaveParamsEvent;
public int Index;
/// <summary>
/// 欧姆龙Fins协议
/// </summary>
public HslCommunication.Profinet.Omron.OmronCipNet omronCipNet = null;
public HslCommunication.Profinet.Omron.OmronFinsNet omronFinsNet = null;
/// <summary>
/// 是否链接PLC
/// </summary>
private bool _isConnected = false;
/// <summary>
/// 是否开启心跳消息
/// </summary>
private bool _heartBeat = false;
/// <summary>
/// 断线后是否更换SA1的值
/// </summary>
private bool _changesa1 = false;
/// <summary>
/// 心跳消息寄存器地址
/// </summary>
private string _heartAddr = "100";
/// <summary>
///
/// </summary>
public Dictionary<string, TriggerParams> dicJobToTrgParams = new Dictionary<string, TriggerParams>();
/// <summary>
///
/// </summary>
public List<TriggerUI> lstTrgUI = new List<TriggerUI>();
/// <summary>
///
/// </summary>
public List<TriggerParams> lstTgrParams = new List<TriggerParams>();
/// <summary>
///
/// </summary>
public PLCConfig PlcConfig = new PLCConfig();
/// <summary>
///
/// </summary>
public CancellationTokenSource mCTSRecv = new CancellationTokenSource();
public CancellationTokenSource mCTSHeart = new CancellationTokenSource();
private ManualResetEvent resetEventRecv = new ManualResetEvent(true);
private ManualResetEvent resetEventHeart = new ManualResetEvent(true);
/// <summary>
///
/// </summary>
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;
}
}
}
/// <summary>
///
/// </summary>
public bool IsRun { get; set; } = false;
/// <summary>
///
/// </summary>
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();
}
}
/// <summary>
/// 读取PLC数据线程等待时间
/// </summary>
public int ScanTime { get; set; } = 100;
public int JobCount { get; set; }
/// <summary>
/// PLCIP地址
/// </summary>
public string IP { get; set; }
/// <summary>
/// PLC端口
/// </summary>
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<string> ipv4_ips = GetLocalIpAddress("InterNetwork");//获取ipv4类型的ip
//string da = ipv4_ips[0].LastIndexOf('.')-1;
}
//List<string> ips = GetLocalIpAddress("");//获取本地所有ip
//List<string> ipv4_ips = GetLocalIpAddress("InterNetwork");//获取ipv4类型的ip
//List<string> ipv6_ips = GetLocalIpAddress("InterNetworkV6");//获取ipv6类型的ip
/// <summary>
/// 获取本机所有ip地址
/// </summary>
/// <param name="netType">"InterNetwork":ipv4地址,"InterNetworkV6":ipv6地址</param>
/// <returns>ip地址集合</returns>
public static List<string> GetLocalIpAddress(string netType)
{
string hostName = Dns.GetHostName(); //获取主机名称
IPAddress[] addresses = Dns.GetHostAddresses(hostName); //解析主机IP地址
List<string> IPList = new List<string>();
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<TriggerParams> 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;
}
/// <summary>
/// 对PLC进行链接
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnConnect_Click(object sender, EventArgs e)
{
Connect();
}
/// <summary>
/// 与LC断开链接
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnDisConnect_Click(object sender, EventArgs e)
{
ConnectClose();
}
/// <summary>
/// 断开PLC的链接
/// </summary>
public void ConnectClose()
{
omronCipNet.ConnectClose();
BtnDisConnect.Enabled = false;
BtnConnect.Enabled = true;
lblConnectStatus.Image = Properties.Resources.red;
IsConnected = false;
AddLog(lstRecv, 0, "断开连接");
}
/// <summary>
/// 界面测试复选框
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void cbTest_CheckedChanged(object sender, EventArgs e)
{
if (cbTest.Checked)
{
PanelTest.Enabled = true;
}
else
{
PanelTest.Enabled = false;
}
}
/// <summary>
/// 读取PLC数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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);
}
}
/// <summary>
/// 写入PLC数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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);
}
}
/// <summary>
/// 开启
/// </summary>
public void InitialAndConnect()
{
Task RecvTask = Task.Factory.StartNew(delegate { GetMelsecValue(); }, mCTSRecv.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
/// <summary>
/// 链接PLC状态
/// </summary>
/// <param name="status"></param>
public void OmronStart(bool status)
{
if (status)
{
resetEventRecv.Set();
}
else
{
resetEventRecv.Reset();
}
}
/// <summary>
/// 循环读取PLC数据
/// </summary>
private void GetMelsecValue()
{
while (true)
{
if (mCTSRecv.Token.IsCancellationRequested)
{
return;
}
resetEventRecv.WaitOne();
if (IsRun)
{
if (IsConnected)
{
OperateResult<byte[]> 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, "端口号格式不正确");
}
/// <summary>
/// 心跳消息
/// </summary>
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);
}
}
}
}
/// <summary>
/// 对PLC某寄存器清零
/// </summary>
/// <param name="iAddr"></param>
/// <param name="varType"></param>
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;
}
}
/// <summary>
///读取BOOL值
/// </summary>
/// <param name="iAddr"></param>
/// <returns></returns>
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;
}
/// <summary>
///读取String值
/// </summary>
/// <param name="iAddr"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 读取16位整数
/// </summary>
/// <param name="iAddr"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 读取32位整数
/// </summary>
/// <param name="iAddr"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 读取浮点数
/// </summary>
/// <param name="iAddr"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 读取byte
/// </summary>
/// <param name="iAddr">数据地址</param>
/// <param name="lenght">读取长度</param>
/// <returns></returns>
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;
}
/// <summary>
/// 写入byte数组
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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}");
}
}
}
/// <summary>
/// 写入单个int类型数据
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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}");
}
}
}
/// <summary>
/// 写入单个int类型数据
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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}");
}
}
}
/// <summary>
/// 批量写入int类型数据
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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}");
}
}
}
/// <summary>
/// 批量写入ushort类型数据
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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]}");
}
}
}
}
/// <summary>
/// 写入单个Short类型数据
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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}");
}
}
}
/// <summary>
/// 写BOOL
/// </summary>
/// <param name="iAddr"></param>
/// <param name="Value"></param>
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}");
}
}
}
/// <summary>
/// 是否启用心跳消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void cbHeartBeat_CheckedChanged(object sender, EventArgs e)
{
if (cbHeartBeat.Checked)
{
HeartBeat = true;
}
else
{
HeartBeat = false;
}
}
/// <summary>
/// 保存配置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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);
}
}
/// <summary>
/// 日志显示
/// </summary>
/// <param name="lstView"></param>
/// <param name="type"></param>
/// <param name="info"></param>
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);
}
}
/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
private bool[] GetBoolArray(string val)
{
try
{
List<bool> Result = new List<bool>();
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<short> Result = new List<short>();
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<int> Result = new List<int>();
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<float> Result = new List<float>();
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;
}
}
/// <summary>
/// 清除消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnClearRecv_Click(object sender, EventArgs e)
{
lstRecv.Items.Clear();
}
/// <summary>
/// 数据接受委托事件
/// </summary>
/// <param name="Index"></param>
/// <param name="msg"></param>
/// <param name="resByte"></param>
public void OnReceive(int Index, string msg, OperateResult<byte[]> resByte)
{
if (this.ReceiveEvent != null)
{
this.ReceiveEvent(Index, msg, resByte);
}
}
/// <summary>
/// 心跳消息委托事件
/// </summary>
/// <param name="b"></param>
public void OnUpHeartBeat(bool b)
{
if (this.UpHeartBeatEvent != null)
{
this.UpHeartBeatEvent(b);
}
}
/// <summary>
/// 保存信息委托事件
/// </summary>
/// <param name="plcIndex"></param>
/// <param name="trgIndex"></param>
public void OnSaveParams(int plcIndex, int trgIndex)
{
if (this.SaveParamsEvent != null)
{
this.SaveParamsEvent(plcIndex, trgIndex);
}
}
/// <summary>
/// 关闭读取PLC数据
/// </summary>
public void Shutdown()
{
if (omronCipNet != null)
{
try
{
mCTSRecv.Cancel();
mCTSHeart.Cancel();
}
catch (Exception)
{
}
}
}
/// <summary>
/// 链接PLC开始启动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 = "启动";
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void cbDispCurrent_CheckedChanged(object sender, EventArgs e)
{
if (cbDispCurrent.Checked)
{
DispCurrent = true;
}
else
{
DispCurrent = false;
}
}
/// <summary>
/// 心跳消息赋值
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtHeartAddr_TextChanged(object sender, EventArgs e)
{
_heartAddr = txtHeartAddr.Text;
}
private void button1_Click(object sender, EventArgs e)
{
//OperateResult<OmronCpuUnitData> operateResult = omron_finsnet.ReadCpuUnitData();
//if (operateResult.IsSuccess)
//{
// txtReadResultTest.Text = operateResult.Content.ToJsonString();
//}
//else
//{
// MessageBox.Show("read failed:" + operateResult.Message);
//}
}
}
}