2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > C#实现Omron欧姆龙PLC的Fins Tcp协议

C#实现Omron欧姆龙PLC的Fins Tcp协议

时间:2022-04-24 09:44:32

相关推荐

C#实现Omron欧姆龙PLC的Fins Tcp协议

最近项目需要用上位机通讯Omron PLC,使用无线网络的Fins协议,经测试通过后代码如下:

使用方法:

1、引用此命名空间;

2、实例化类FinsTcp;

3、调用连接函数conn();

4、读取写入操作(读位数据,写位数据,读字数据,写字数据 四个函数都有说明);

注意:读字数据 和 写字数据时,一个字 = 两个字节,注意字节数组长度应该是字的两倍,还有高低位变化。

————————————————

using System;using System.Collections.Generic;using System.Linq;using System.Text;using ;using .Sockets;namespace Omron{class FinsTcp{public bool connected;string ip;int port;byte[] Client = new byte[4];byte[] Server = new byte[4];//PLC和本机数据byte[] dataLeng = {0x00, 0x01 };TcpClient msender;Socket msock;#region 构造函数/// <summary>/// Fins协议Tcp连接的构造函数(PLC的IP地址、PLC端口号、本机节点)/// </summary>/// <param name="ip">IP地址</param>/// <param name="port">端口号,默认9600</param>/// <param name="fra">本机节点</param>/// <returns>实例化一个Fins协议Tcp连接</returns>public FinsTcp(string ip, int port, byte fra){//frame = Convert.ToByte(ip.Substring(ip.LastIndexOf('.')));this.ip = ip;this.port = port;Client[3] = fra;connected = false;}#endregion#region 断开连接/// <summary>/// 断开连接/// </summary>public void disconn(){if (connected){msender.Close();connected = false;}}#endregion#region 连接PLC/// <summary>/// 连接PLC/// </summary>public void conn(){if (!connected){msender = new TcpClient(ip, port);msock = msender.Client;byte[] Handshake = new byte[20];Handshake[0] = 0x46;//FHandshake[1] = 0x49;//IHandshake[2] = 0x4e;//NHandshake[3] = 0x53;//SHandshake[4] = 0;Handshake[5] = 0;Handshake[6] = 0;Handshake[7] = 0x0c;//Length长度Handshake[8] = 0;Handshake[9] = 0;Handshake[10] = 0;Handshake[11] = 0;//CommandHandshake[12] = 0;Handshake[13] = 0;Handshake[14] = 0;Handshake[15] = 0;//Error CodeHandshake[16] = 0;Handshake[17] = 0;Handshake[18] = 0;Handshake[19] = Client[3];//FINS Frame (本机节点)msock.Send(Handshake);byte[] buffer = new byte[24];msock.Receive(buffer, SocketFlags.None);byte[] buf = buffer;buf[0] = 0x46;//Fbuf[1] = 0x49;//Ibuf[2] = 0x4e;//Nbuf[3] = 0x53;//Sbuf[4] = 0;buf[5] = 0;buf[6] = 0;buf[7] = 20;buf[8] = 0;buf[9] = 0;buf[10] = 0;buf[11] = 1;buf[12] = 0;buf[13] = 0;buf[14] = 0;buf[15] = 0;if (buf == buffer){Client[0] = buffer[16];Client[1] = buffer[17];Client[2] = buffer[18];Client[3] = buffer[19];Server[0] = buffer[20];Server[1] = buffer[21];Server[2] = buffer[22];Server[3] = buffer[23];connected = true;}}}#endregion#region 读位数据/// <summary>/// 读取PLC上的位数据(内存地址、读取结果)/// </summary>/// <param name="memory">PLC的内存地址(区域.地址.位 如:CIO.1.2)</param>/// <param name="result">读取结果</param>public int readBit(string memory, ref bool result){byte[] re = new byte[1] {0x00 };int rev = SendByte(memory, true, true, ref re);if (rev == 0) result = Convert.ToBoolean(re[0]);return rev;}#endregion#region 写位数据/// <summary>/// 写入PLC上的位数据(内存地址、写入数据)/// </summary>/// <param name="memory">PLC的内存地址(区域.地址.位 如:WR.3.0)</param>/// <param name="sendBit">写入数据</param>public int writeBit(string memory, bool sendBit){Byte[] Se = new Byte[1];Se[0] = Convert.ToByte(sendBit);return SendByte(memory, true, false, ref Se, Se);}#endregion#region 读字数据/// <summary>/// 读取PLC上的位数据(内存地址、读取结果)/// </summary>/// <param name="memory">PLC的内存地址(区域.地址.字长度 如:DR.1.2)</param>/// <param name="result">读取结果</param>public int readWord(string memory, ref byte[] result){return SendByte(memory, false, true, ref result);}#endregion#region 写字数据/// <summary>/// 写入PLC上的位数据(内存地址、写入数据)/// </summary>/// <param name="memery">PLC的内存地址(区域.地址.字长度 如:WR.10.4)</param>/// <param name="sendWord">写入数据</param>public int writeWord(string memory, byte[] sendWord){return SendByte(memory, false, false, ref sendWord, sendWord);}#endregion#region PLC内存格式转换/// <summary>/// 地址格式转化/// </summary>private byte[] addsToByte(string memory, bool isBit){string[] AddrParts = memory.Split('.');byte[] CH = BitConverter.GetBytes(Convert.ToInt32(AddrParts[1]));byte[] Count = BitConverter.GetBytes(Convert.ToInt32(AddrParts[2]));byte[] Addrs = new byte[6];Addrs[1] = CH[1];Addrs[2] = CH[0];if (!isBit) //字处理 {switch (AddrParts[0]){case "CIO":Addrs[0] = 0xB0;break;case "WR":Addrs[0] = 0xB1;break;case "DM":Addrs[0] = 0x82;break;case "HR":Addrs[0] = 0xB2;break;case "TIM":Addrs[0] = 0x89;break;case "AR":Addrs[0] = 0xB3;break;case "CNT":Addrs[0] = 0x89;break;default:Addrs[0] = 0x00;break;}Addrs[3] = 0x00;Addrs[4] = Count[1];Addrs[5] = Count[0];//读写字的长度}else //位处理 {switch (AddrParts[0]){case "CIO":Addrs[0] = 0x30;break;case "WR":Addrs[0] = 0x31;break;case "DM":Addrs[0] = 0x02;break;case "HR":Addrs[0] = 0x32;break;case "TIM":Addrs[0] = 0x09;break;case "AR":Addrs[0] = 0x33;break;case "CNT":Addrs[0] = 0x09;break;default:Addrs[0] = 0x00;break;}Addrs[3] = Count[0];Addrs[4] = 0x00;Addrs[5] = 0x01;//每次读写一位}return Addrs;}#endregion#region 报文处理/// <summary>/// 报文处理/// </summary>/// <param name="memory">要读写的内存地址</param>/// <param name="isBit">位还是字</param>/// <param name="isRead">读还是写</param>/// <param name="rev">返回的数据</param>/// <param name="datas">写入的数据</param>private int SendByte(string memory, bool isBit, bool isRead, ref byte[] rev, byte[] datas = null){int dataLength;if (datas == null)dataLength = 26;elsedataLength = datas.Length + 26;byte[] SendByte = new byte[dataLength + 8];SendByte[0] = 0x46;//FSendByte[1] = 0x49;//ISendByte[2] = 0x4e;//NSendByte[3] = 0x53;//SSendByte[4] = 0;//cmd lengthSendByte[5] = 0;SendByte[6] = 0;SendByte[7] = Convert.ToByte(dataLength);SendByte[8] = 0;//frame commandSendByte[9] = 0;SendByte[10] = 0;SendByte[11] = 0x02;SendByte[12] = 0;//errSendByte[13] = 0;SendByte[14] = 0;SendByte[15] = 0;//command frame headerSendByte[16] = 0x80;//ICFSendByte[17] = 0x00;//RSVSendByte[18] = 0x02;//GCT, less than 8 network layersSendByte[19] = 0x00;//DNA, local networkSendByte[20] = Server[3];//DA1SendByte[21] = 0x00;//DA2, CPU unitSendByte[22] = 0x00;//SNA, local networkSendByte[23] = Client[3];//SA1SendByte[24] = 0x00;//SA2, CPU unitSendByte[25] = Convert.ToByte(21);//SIDSendByte[26] = 0x01;if (isRead)SendByte[27] = 0x01;elseSendByte[27] = 0x02;byte[] head = addsToByte(memory, isBit);SendByte[28] = head[0];SendByte[29] = head[1];SendByte[30] = head[2];SendByte[31] = head[3];SendByte[32] = head[4];SendByte[33] = head[5];if (datas != null){Array.Copy(datas, 0, SendByte, 34, datas.Length);}msock.Send(SendByte, SocketFlags.None);byte[] buffer = new byte[256];msock.Receive(buffer);int err = 0;if (buffer[0] != SendByte[0] || buffer[1] != SendByte[1] || buffer[2] != SendByte[2] || buffer[3] != SendByte[3]){err = 1;//the head is err}if (err == 0 && buffer[11] == 3){switch (buffer[15]){case 0x01: err = 2; break;//the head is not 'FINS'case 0x02: err = 3; break;//the data length is too long case 0x03: err = 4; break;//the command is not supported}}if (err == 0 && buffer[28] != 0 && buffer[29] != 0){err = 5; //end code errswitch (buffer[28]){case 0x00:if (buffer[29] == 0x01) err = 6;//service canceledbreak;case 0x01:switch (buffer[29]){case 0x01: err = 7; break; //local node not in networkcase 0x02: err = 8; break; //token timeoutcase 0x03: err = 9; break; //retries failedcase 0x04: err = 10; break; //too many send framescase 0x05: err = 11; break; //node address range errorcase 0x06: err = 12; break; //node address duplication}break;case 0x02:switch (buffer[29]){case 0x01: err = 13; break; //destination node not in networkcase 0x02: err = 14; break; //unit missingcase 0x03: err = 15; break; //third node missingcase 0x04: err = 16; break; //destination node busycase 0x05: err = 17; break; //response timeout}break;case 0x03:switch (buffer[29]){case 0x01: err = 18; break; //communications controller errorcase 0x02: err = 19; break; //CPU unit errorcase 0x03: err = 20; break; //controller errorcase 0x04: err = 21; break; //unit number error}break;case 0x04:switch (buffer[29]){case 0x01: err = 22; break; //undefined commandcase 0x02: err = 23; break; //not supported by model/version}break;case 0x05:switch (buffer[29]){case 0x01: err = 24; break; //destination address setting errorcase 0x02: err = 25; break; //no routing tablescase 0x03: err = 26; break; //routing table errorcase 0x04: err = 27; break; //too many relays}break;case 0x10:switch (buffer[29]){case 0x01: err = 28; break; //command too longcase 0x02: err = 29; break; //command too shortcase 0x03: err = 30; break; //elements/data don't matchcase 0x04: err = 31; break; //command format errorcase 0x05: err = 32; break; //header error}break;case 0x11:switch (buffer[29]){case 0x01: err = 33; break; //area classification missingcase 0x02: err = 34; break; //access size errorcase 0x03: err = 35; break; //address range errorcase 0x04: err = 36; break; //address range exceededcase 0x06: err = 37; break; //program missingcase 0x09: err = 38; break; //relational errorcase 0x0a: err = 39; break; //duplicate data accesscase 0x0b: err = 40; break; //response too longcase 0x0c: err = 41; break; //parameter error}break;case 0x20:switch (buffer[29]){case 0x02: err = 42; break; //protectedcase 0x03: err = 43; break; //table missingcase 0x04: err = 44; break; //data missingcase 0x05: err = 45; break; //program missingcase 0x06: err = 46; break; //file missingcase 0x07: err = 47; break; //data mismatch}break;case 0x21:switch (buffer[29]){case 0x01: err = 48; break; //read-onlycase 0x02: err = 49; break; //protected , cannot write data link tablecase 0x03: err = 50; break; //cannot registercase 0x05: err = 51; break; //program missingcase 0x06: err = 52; break; //file missingcase 0x07: err = 53; break; //file name already existscase 0x08: err = 54; break; //cannot change}break;case 0x22:switch (buffer[29]){case 0x01: err = 55; break; //not possible during executioncase 0x02: err = 56; break; //not possible while runningcase 0x03: err = 57; break; //wrong PLC modecase 0x04: err = 58; break; //wrong PLC modecase 0x05: err = 59; break; //wrong PLC modecase 0x06: err = 60; break; //wrong PLC modecase 0x07: err = 61; break; //specified node not polling nodecase 0x08: err = 62; break; //step cannot be executed}break;case 0x23:switch (buffer[29]){case 0x01: err = 63; break; //file device missingcase 0x02: err = 64; break; //memory missingcase 0x03: err = 65; break; //clock missing}break;case 0x24:if (buffer[29] == 0x01) err = 66; //table missingbreak;case 0x25:switch (buffer[29]){case 0x02: err = 67; break; //memory errorcase 0x03: err = 68; break; //I/O setting errorcase 0x04: err = 69; break; //too many I/O pointscase 0x05: err = 70; break; //CPU bus errorcase 0x06: err = 71; break; //I/O duplicationcase 0x07: err = 72; break; //CPU bus errorcase 0x09: err = 73; break; //SYSMAC BUS/2 errorcase 0x0a: err = 74; break; //CPU bus unit errorcase 0x0d: err = 75; break; //SYSMAC BUS No. duplicationcase 0x0f: err = 76; break; //memory errorcase 0x10: err = 77; break; //SYSMAC BUS terminator missing}break;case 0x26:switch (buffer[29]){case 0x01: err = 78; break; //no protectioncase 0x02: err = 79; break; //incorrect passwordcase 0x04: err = 80; break; //protectedcase 0x05: err = 81; break; //service already executingcase 0x06: err = 82; break; //service stoppedcase 0x07: err = 83; break; //no execution rightcase 0x08: err = 84; break; //settings required before executioncase 0x09: err = 85; break; //necessary items not setcase 0x0a: err = 86; break; //number already definedcase 0x0b: err = 87; break; //error will not clear}break;case 0x30:if (buffer[29] == 0x01) err = 88; //no access rightbreak;case 0x40:if (buffer[29] == 0x01) err = 89;//service abortedbreak;}}if (err == 0 && isRead) Array.Copy(buffer, 30, rev, 0, rev.Length);return err;}#endregion}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。