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

使用方法:

1、引用此命名空间;

2、实例化类FinsTcp;

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

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.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}}

C#实现Omron欧姆龙PLC的Fins Tcp协议相关推荐

  1. 爱普生机器人与欧姆龙PLC Fins/Tcp协议驱动程序 自己开发,提供项目源码Fins/Tcp协议源码

    爱普生机器人与欧姆龙PLC Fins/Tcp协议驱动程序 自己开发,提供项目源码Fins/Tcp协议源码

  2. OMRON欧姆龙PLC如何实现远程上下载程序?

    欧姆龙(omron),是日系PLC当中市场占有率仅次于三菱的一款强大品牌,其兼具了三菱在运动控制以及西门子在总线控制上的优势,在中小型场合以及多轴控制上倍受工程师们的欢迎. 当前市面上欧姆龙PLC根据 ...

  3. 欧姆龙PLC网关BL110之41:实现欧姆龙 PLC 接入Modbus TCP 云平台

    COM口采集欧姆龙 PLC CJ/CS/CP 的配置 欧姆龙PLC网关一共有四个COM 接口, 4个COM口的配置内容一样,COM1固定为RS232,COM2.COM3和COM4是RS232/RS48 ...

  4. OMRON欧姆龙PLC与VB、C#通过以太网(FinsTCP/FinsUDP)、串口(FinsCom/HostLink)、DTU通讯的DLL

    http://blog.sina.com.cn/s/blog_16d7d3ecb0102x3qi.html 1.0 通讯组件概述 通讯组件用于PC与可编程控制器(PLC).智能仪表等进行数据通讯,适用 ...

  5. Fins TCP协议

    ** PLC通讯协议剖析及应用 ** Fins协议在TCP/IP网段上的应用 modbus协议 都完全公开的 西门子S7协议,是不公开的 三个PLC,以太网通讯/TCP通讯 西门子S7-1200 19 ...

  6. 迪文DGUS屏通过单片机转发与欧姆龙PLC(hostlink mode-c协议)实现通讯

    闲来无事,做个记录,触摸屏使用迪文DGUS-T5D2 10.1寸触摸屏,单片机STM32F013系列,欧姆龙CP1E-N40PLC,之所以通过单片机转发是因为迪文触摸屏价格的巨大优势,核算单片机成本后 ...

  7. 工业网关控制器CK-GW06-E01与欧姆龙 PLC配置说明

    工业网关控制器CK-GW06-E01是一款工业级网关控制器,以太网通信接口,支持 EtherNet IP|Modbus TCP 工业协议.可实现一拖六,同时带有六组输入 检测 IO 和六组输出控制 I ...

  8. 欧姆龙OMRON PLC之HostLink通讯协议(五)- CP1H以太网FINS/TCP通讯实例

    //写在前面: 自2010年起,本人陆续在新浪博客上面发了几篇OMRON PLC的应用笔记,曾经很疑惑阅读量异常增加,后来发现原来是这里有人转载.现将原文照发在这里,希望能帮到做工控的同行朋友们. C ...

  9. 【转】欧姆龙OMRON PLC之 CP1H 以太网FINS/TCP通讯实例

    原文:http://blog.sina.com.cn/s/blog_539cee190102wr4t.html CP1H上面的选件板插槽可以插入1-2块CP1W-CIF41模块,系统即具有了以太网功能 ...

  10. Labview Ethernetip TCP网口通讯欧姆龙PLC OmronNX1P2NJ501NJ301PLC标签通讯 CIP通讯比Fins通讯更完美

    Labview Ethernetip TCP网口通讯欧姆龙PLC OmronNX1P2NJ501NJ301PLC标签通讯 CIP通讯比Fins通讯更完美. 1.自定义变量读写 2.支持 Bool单点或 ...

最新文章

  1. vacode允许c_Visual Studio Code 配置C/C++环境
  2. E0469640.LenovoUtility_ 3.0.37.0 x64_ 5grkq8ppsg..utiltyexe指定路径不存在
  3. Barts PE Builder——Windows系统维护完全图形化攻略
  4. centos7 tomcat 设置开机启动
  5. 从硬件开始实践物联网-物联网弹幕器的灵感!
  6. 爬虫框架Scrapy的第一个爬虫示例入门教程
  7. jQuery教程03-jQuery 元素、id、.class和*全选择器
  8. 命令行shell 用于SQLite
  9. 【Linux】七种运行级别
  10. clickhouse 数据存储
  11. atomic_fetch_add
  12. 安装新版的winetricks_20170506-最新WineQQ8.9.1安装教程和常见问题解决方法
  13. 新手小白如何从0到1学会电商运营,这3个方法带你月入五位数
  14. Revisiting Spatial-Temporal Similarity: A Deep Learning Framework for Traffic Prediction
  15. mybatis的xmly文件与必依赖
  16. IB学校书单合集请收藏好
  17. 【编程语言】Lua完全自学手册
  18. 学习做视频剪辑,几分钟教会你剪辑技巧
  19. TCP/IP 之 蓟辽督师
  20. 教你查询快递物流多次收件的单号

热门文章

  1. 电脑如何录制游戏视频
  2. sumif单列求和_求和、单条件求和、多条件求和、隔列求和等实用技巧解读
  3. 【VirtualAPP 双开系列06】启动加载第三方 APP 过程
  4. 如何用数据进行产品运营
  5. 你有必要不沾计算机一段时间英语,2014新人教版八年级英语下册第一单元必背词组及句子...
  6. VMware如何开机自动启动虚拟机也启动
  7. 软件著作权登记申请容易通过吗?软著申请成功率高吗?
  8. 40163 php,【PHP】微信支付JsApi 40163错误
  9. 双耳节拍 枕头_枕头2.2.1发布
  10. 关于数据迁移:解决kettle中mysql的数据是tinyint的kettle查出来后变成boolean问题