Files
1440WGJ/PLCCommunication/OmronPLCUI.cs
T

1473 lines
50 KiB
C#
Raw Normal View History

2026-07-14 13:55:17 +08:00
using HslCommunication;
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;
/// <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;
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();
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);
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;
2026-08-17 10:41:22 +08:00
AddLog(lstResWrite, 0, $"{iAddr} --> {result?.ToString()}");
2026-07-14 13:55:17 +08:00
}
}
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);
//}
}
}
}