由于项目需要C#跟欧姆龙NX系列PLC通讯,网上百度NX系列的PLC这方面的案例很少,且NXPLC不支持Fins通信,也不支持OPCUA.只能通过Ethernet/IP与其进行通信
采用CX-Compolet控件
先上图片:
实现核心代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OMRON.Compolet.CIP;
using System.Collections;
namespace Plc
{
/// <summary>
/// 欧姆龙CIPCompolet协议
/// </summary>
public class OmronCIP
{
/// <summary>
/// 软元件代码
/// </summary>
private enum CIPElementCode
{
UCMM = 0,
Class3=1
};
/// <summary>
/// 接收的等待时间
/// </summary>
private int m_nWaitingTime;
/// <summary>
/// 通信网口
/// </summary>
private NXCompolet m_TcpLink;
/// <summary>
/// 心跳时间
/// </summary>
private int HeartBeatTimer;
/// <summary>
/// 本地端口
/// </summary>
private int LocalPort;
/// <summary>
/// PLC地址
/// </summary>
private string PeerAddress;
/// <summary>
/// 接收数据超时
/// </summary>
private long ReceiveTimeLimit;
/// <summary>
/// 第二连接PLC地址
/// </summary>
private string RoutePath;
/// <summary>
/// 连接类型
/// </summary>
private int ConnectionType;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="tl">网口</param>
public OmronCIP(string peerAddress= "192.168.250.1",long receiveTimeLimit=750,int localPort=2, int connectionType =0
,int heartBeatTimer=0,string routePath= "2%192.168.250.1")
{
//变量初使化赋值
PeerAddress = peerAddress;
ReceiveTimeLimit = receiveTimeLimit;
LocalPort = localPort;
LocalPort = localPort;
ConnectionType = connectionType;
HeartBeatTimer = heartBeatTimer;
RoutePath = routePath;
//建立PLC连接变量
m_TcpLink = new NXCompolet();
m_TcpLink.ConnectionType = (OMRON.Compolet.CIP.ConnectionType)ConnectionType;
m_TcpLink.DontFragment = false;
m_TcpLink.HeartBeatTimer = HeartBeatTimer;
m_TcpLink.LocalPort = LocalPort;
m_TcpLink.PeerAddress = PeerAddress;
m_TcpLink.ReceiveTimeLimit = ReceiveTimeLimit;
m_TcpLink.RoutePath = RoutePath;
m_TcpLink.UseRoutePath = false;
}
public NXCompolet GetTcp
{
get
{
return m_TcpLink;
}
}
/// <summary>
/// 设置接收的等待时间
/// </summary>
/// <param name="nMs">超时时间,单位:S</param>
public void SetWaitingTime(int nMs)
{
int nCount = nMs;
if (nCount <= 0)
{
m_nWaitingTime = 1;
ReceiveTimeLimit = 1;
}
else
{
m_nWaitingTime = nCount;
ReceiveTimeLimit = nCount;
}
}
/// <summary>
/// 写入位
/// </summary>
/// <param name="BinaryValue"></param>
/// <param name="bVals"></param>
/// <returns></returns>
public bool WriteBit(string BinaryValue, bool bVals)
{
byte[] val;
try
{
if(bVals)
{
val = StringToByteArray("0100");
}
else
{
val = StringToByteArray("0000");
}
m_TcpLink.WriteRawData(BinaryValue, val);
return true;
}
catch(Exception ex)
{
}
return false;
}
/// <summary>
/// 写入多个位
/// </summary>
/// <param name="valueList"></param>
/// <param name="data"></param>
/// <returns></returns>
public bool WriteMultiBit(string[] valueList, bool[] data)
{
try
{
string[] varlist = valueList;
if (varlist == null || varlist.Length == 0)
{
return false;
}
for(int i= 0; i < valueList.Length; i++)
{
byte[] val;
try
{
if (data[i])
{
val = StringToByteArray("0100");
}
else
{
val = StringToByteArray("0000");
}
m_TcpLink.WriteRawData(valueList[i], val);
}
catch
{
throw new NotSupportedException();
}
}
return true;
}
catch (Exception ex)
{
}
finally
{
}
return false;
}
public bool WriteWord(string BinaryValue, string bVals)
{
try
{
string valWrite = BinaryValue;
if (valWrite.StartsWith("_"))
{
MessageBox.Show("The SystemVariable can not write!");
return false;
}
object val = RemoveBrackets(bVals);
if (m_TcpLink.GetVariableInfo(BinaryValue).Type == VariableType.STRUCT)
{
val = ObjectToByteArray(val);
}
m_TcpLink.WriteVariable(BinaryValue, val);
return true;
}
catch(Exception ex)
{
}
return false;
}
public bool WriteString(string BinaryValue, string bVals)
{
try
{
string valWrite = BinaryValue;
if (valWrite.StartsWith("_"))
{
MessageBox.Show("The SystemVariable can not write!");
return false;
}
object val = this.RemoveBrackets(bVals);
if (m_TcpLink.GetVariableInfo(BinaryValue).Type == VariableType.STRING)
{
//val = this.ObjectToByteArray(val);
}
m_TcpLink.WriteVariable(BinaryValue, val);
return true;
}
catch (Exception ex)
{
}
return false;
}
/// <summary>
/// 读取位
/// </summary>
/// <param name="BinaryValue"></param>
/// <returns></returns>
public bool ReadBit(string BinaryValue)
{
try
{
if (BinaryValue == null)
{
return false;
}
object obj = m_TcpLink.ReadRawData(BinaryValue);
VariableInfo info = m_TcpLink.GetVariableInfo(BinaryValue);
string val = this.ByteArrayToString(obj as byte[]);
if( val == "01-00")
{
return true;
}
else if(val == "00-00")
{
return false;
}
else
{
return false;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "PLC读取异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
}
return false;
}
/// <summary>
/// 读取多个位
/// </summary>
/// <param name="BinaryMultiValue"></param>
/// <param name="result"></param>
public void ReadMultiBit(string BinaryMultiValue,ref string result)
{
try
{
if (BinaryMultiValue == null)
{
return;
}
string[] varlist = BinaryMultiValue.Replace(" ", String.Empty).Split(',');
Hashtable retVals = m_TcpLink.ReadRawDataMultiple(varlist);
string multival = string.Empty;
for (int index = 0; index < varlist.Length; index++)
{
string varName = varlist[index];
string val = this.ByteArrayToString(retVals[varName] as byte[]);
multival += val + ",";
}
multival = multival.TrimEnd(',');
result = multival;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "PLC读取异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
}
return;
}
/// <summary>
/// 读取字
/// </summary>
/// <param name="BinaryValue"></param>
/// <returns></returns>
public bool ReadString(string BinaryValue,ref string result)
{
try
{
if (BinaryValue == null)
{
return false;
}
object obj = m_TcpLink.ReadVariable(BinaryValue);
if (obj == null)
{
throw new NotSupportedException();
}
VariableInfo info = m_TcpLink.GetVariableInfo(BinaryValue);
string str = GetValueOfVariables(obj);
result = str;
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "PLC读取异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
}
return false;
}
/// <summary>
/// 读取字
/// </summary>
/// <param name="BinaryValue"></param>
/// <returns></returns>
public short ReadWord(string BinaryValue)
{
try
{
if (BinaryValue == null)
{
return 0;
}
object obj = m_TcpLink.ReadVariable(BinaryValue);
if (obj == null)
{
throw new NotSupportedException();
}
VariableInfo info = m_TcpLink.GetVariableInfo(BinaryValue);
string str = GetValueOfVariables(obj);
short res = Convert.ToInt16(str);
return res;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "PLC读取异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
}
return 0;
}
/// <summary>
/// 读取多个字
/// </summary>
/// <param name="valueList"></param>
/// <param name="data"></param>
/// <returns></returns>
public bool ReadMultiWord(string[] valueList,ref short[] data)
{
try
{
string[] varlist = valueList;
if (varlist == null || varlist.Length == 0)
{
return false;
}
short[] res = new short[varlist.Length];
Hashtable retVals = m_TcpLink.ReadVariableMultiple(varlist);
string multival = string.Empty;
if (retVals == null)
{
throw new NotSupportedException();
}
for (int index = 0; index < varlist.Length; index++)
{
string varName = varlist[index];
object val = retVals[varName];
string valStr = this.GetValueOfVariables(val);
multival += valStr + ",";
res[index] = Convert.ToInt16(valStr);
}
multival = multival.TrimEnd(',');
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "PLC读取异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
}
return false;
}
/// <summary>
/// 打开设备
/// </summary>
/// <returns></returns>
public bool Open()
{
try
{
m_TcpLink.Active = true;
if (m_TcpLink.IsConnected)
{
return true;
}
else
{
m_TcpLink.Active = false;
MessageBox.Show("Connection failed !" + System.Environment.NewLine + "Please check PeerAddress.", "PLC异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "PLC异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
m_TcpLink.Active = false;
}
return false;
}
public bool IsOpen()
{
if(m_TcpLink != null)
{
return m_TcpLink.IsConnected;
}
return false;
}
/// <summary>
/// 关闭设备
/// </summary>
public void Close()
{
try
{
if (m_TcpLink.IsConnected)
{
m_TcpLink.Active = false;
}
else
{
m_TcpLink.Active = false;
MessageBox.Show("Connection failed !" + System.Environment.NewLine + "Please check PeerAddress.", "PLC异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "PLC异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
m_TcpLink.Active = false;
}
}
#region 常用功能函数
private void DisplayVariableInfomation(string str, Control con)
{
ListView listViewOfVariableNames = con as ListView;
ListViewItem item = listViewOfVariableNames.Items.Add(str);
VariableInfo info = m_TcpLink.GetVariableInfo(str);
if (info.IsArray)
{
string text = info.Type.ToString();
foreach (long num in info.NumberOfElements)
{
text += "[" + num.ToString() + "]";
}
item.SubItems.Add(text);
}
else
{
item.SubItems.Add(info.Type.ToString());
}
item.SubItems.Add(string.Empty);
}
private bool IsMustElementAccess(VariableInfo info)
{
bool toReturn = false;
if (info.IsArray)
{
if (info.Type == VariableType.STRING || info.Type == VariableType.UNION)
{
toReturn = true;
}
}
return toReturn;
}
private bool IsMustMemberAccess(VariableInfo info)
{
bool toReturn = false;
if (info.Type == VariableType.UNION)
{
toReturn = true;
}
return toReturn;
}
private String GetAccessablePath(String path)
{
String newPath = String.Empty;
newPath += path;
VariableInfo info = m_TcpLink.GetVariableInfo(path);
if (this.IsMustElementAccess(info))
{
// get only first element
for (int i = 0; i < info.Dimension; i++)
{
newPath += "[" + info.StartArrayElements[i].ToString() + "]";
}
return this.GetAccessablePath(newPath);
}
else if (this.IsMustMemberAccess(info))
{
// get only first member
newPath += "." + info.StructMembers[0].Name;
return this.GetAccessablePath(newPath);
}
else
{
return newPath;
}
}
private string GetValueOfVariables(object val)
{
string valStr = string.Empty;
if (val.GetType().IsArray)
{
Array valArray = val as Array;
if (valArray.Rank == 1)
{
valStr += "[";
foreach (object a in valArray)
{
valStr += this.GetValueString(a) + ",";
}
valStr = valStr.TrimEnd(',');
valStr += "]";
}
else if (valArray.Rank == 2)
{
for (int i = 0; i <= valArray.GetUpperBound(0); i++)
{
valStr += "[";
for (int j = 0; j <= valArray.GetUpperBound(1); j++)
{
valStr += this.GetValueString(valArray.GetValue(i, j)) + ",";
}
valStr = valStr.TrimEnd(',');
valStr += "]";
}
}
else if (valArray.Rank == 3)
{
for (int i = 0; i <= valArray.GetUpperBound(0); i++)
{
for (int j = 0; j <= valArray.GetUpperBound(1); j++)
{
valStr += "[";
for (int z = 0; z <= valArray.GetUpperBound(2); z++)
{
valStr += this.GetValueString(valArray.GetValue(i, j, z)) + ",";
}
valStr = valStr.TrimEnd(',');
valStr += "]";
}
}
}
}
else
{
valStr = this.GetValueString(val);
}
return valStr;
}
private string GetValueString(object val)
{
if (val is float || val is double)
{
return string.Format("{0:R}", val);
}
else
{
return val.ToString();
}
}
private object RemoveBrackets(string val)
{
object obj = string.Empty;
if (val.IndexOf("[") >= 0)
{
string str = val.Trim('[', ']');
str = str.Replace("][", ",");
obj = str.Split(',');
}
else
{
obj = val;
}
return obj;
}
private string ByteArrayToString(byte[] ba)
{
if (ba.Length == 0)
{
return string.Empty;
}
else
{
return BitConverter.ToString(ba);
}
}
private byte[] StringToByteArray(string hex)
{
if (hex == String.Empty)
{
return new Byte[0];
}
int byteNumber = hex.Length / 2;
byte[] bytes = new byte[byteNumber];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
private byte[] ObjectToByteArray(object obj)
{
if (obj is Array)
{
Array arr = obj as Array;
Byte[] bin = new Byte[arr.Length];
for (int i = 0; i < bin.Length; i++)
{
bin[i] = Convert.ToByte(arr.GetValue(i));
}
return bin;
}
else
{
return new Byte[1] { Convert.ToByte(obj) };
}
}
#endregion
}
}