C#实现上位机与欧姆龙PLC通讯(FINS)

.NET
603
0
0
2023-05-23
标签   C#
目录
  • 先介绍下一些基本定义
  • 通讯协议分两种
  • FINS帧结构
  • 1、获取PLC节点地址
  • 2、命令码介绍
  • 3、I / O存储器地址标识
  • 读取DM区地址100,连续10个地址的数据
  • 总结

先介绍下一些基本定义

串行通信:通过的是PLC上的串行口RS232/RS422/485口,上位机链接系统 Hostlink系统是对于FA系统一种及优化有经济的通信方式。

适用于一台上位机与一台或者多台的PLC进行数据通信。

通讯协议分两种

1:C-mode commands

只可以通过串口进行通讯

2:Fins commands

既可以通过串口通讯也可以通过各类网络通讯(适应性较强)

本文只介绍fins通讯

fins (factory in terfave network service) 通讯协议是欧姆龙公司开发的一款自动化控制网络指令/响应系统的通讯协议;运用FINS指令可实现各种网络间的无缝通信

FINS帧结构

  • 发送命令结构 命令码2个字节
  • 响应命令结构 命令码2个字节
  • 命令码 01 01读数据
  • 命令码 01 02写数据
  • 结束码 00 00无错误

1、获取PLC节点地址

上位机和PLC建立TCP通讯之后,可以发送以下命令来获得PLC的节点地址;

帧结构见下表:

列表

Content(十六进制)

Description(说明)

46 49 4E 53

ASCII分别代表的是 F I N S

长度

00 00 00 0C

从Command之后的数据包的长度

错误代码

00 00 00 00

目前暂时没用,因为在服务器不需要检测内部错误

连接的节点地址

00000000~000000FE

分别是0~254,当设置为0时表示自动获取客户端的Fins节点地址

2、命令码介绍

详细内容说明介绍见下表:

命令内容

命令代码(MR SR)

说明

功能





访问I/O存储区

01 01

读内存区

读连续I/O存储区字的内容

访问I/O存储区

01 02

写内存区

写连续I/O存储区字的内容

访问I/O存储区

01 03

填充内存区

将相同的数据写入指定范围的I/O存储器区

访问I/O存储区

01 04

多个存储区读取

读取指定的非连续I/O存储区字

访问I/O存储区

01 05

存储区传输

将连续存储I/O存储区字内容复制到另外的I/O存储区





访问参数区

02 01

读取参数区

读取连续参数区字内容

访问参数区

02 02

写入参数区

写入连续参数区字内容

访问参数区

02 03

填充参数区

将相同数据写入到指定范围参数区域字





改变操作模式

04 01

设置CPU操作模式为RUN

将CPU单元的操作模式更改为RUN或MONITOR

改变操作模式

04 02

设置CPU操作模式为STOP

将CPU单元的操作模式更改为编程





改变操作模式

06 01

读取CPU单元状态

读取CPU单元状态





错误日志

21 01

错误清除

清除错误或错误信息

错误日志

21 02

读取错误日志

读取错误日志

错误日志

21 03

清除错误日志

清除错误日志指针

3、I / O存储器地址标识

区域

数据类型

存储区代码

存储区地址范围

存储地址

字节长度

DM

Bit

02

D0000000到D3276715

000000到7FFF0F

1

DM

Word

82

D00000到D32767

000000到7FFF00

2

鉴于我们在和PLC通讯时,一般只需要进行读取DM区寄存器操作,因为本文只介绍读取和写入DM区寄存器。其他的有需要的童鞋进行自己功能拓展。

举例:

读取DM区地址100,连续10个地址的数据

发送命令:010182006400000A

返回命令:010100000102030405060708090A

发送的命令进行说明:

  • 1、01 01代表功能码,读连续I/O存储区字的内容
  • 2、82代表进行字操作
  • 3、00 64转成十进制就是100代表的是我们要读取的起始地址
  • 4、00000A转成十进制就是10代表的是我们要读取得长度

响应的命令说明

  • 1、01 01代表功能码,读连续I/O存储区字的内容
  • 2、00 00代表结束码,当不是00 00的时候表明数据帧不对
  • 3、01 02 03 04 05 06 07 08 09 0A分别代表要读取的十个寄存器的数据值

具体协议可以查看百度文库:欧姆龙fins通讯协议

综上,结合之前的博客,C#Socket客户端:C#Socket客户端我们可以整合得到一个欧姆龙fins的类,如下所示:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace OmrEntFINS
{
    public class OmronFINS
    {
        /// <summary>
        /// 客户端连接Socket
        /// </summary>
        private Socket clientSocket;
        /// <summary>
        /// 连接状态
        /// </summary>
        public Boolean connected = false;
        /// <summary>
        /// 发送数据
        /// </summary>
        private Byte[] SendMess;
        /// <summary>
        /// 连接点
        /// </summary>
        private IPEndPoint hostEndPoint;
        /// <summary>
        /// 连接信号量
        /// </summary>
        private static AutoResetEvent autoConnectEvent = new AutoResetEvent(false);
        /// <summary>
        /// 接受到数据时的委托
        /// </summary>
        /// <param name="info"></param>
        public delegate void ReceiveMsgHandler(Byte[] info);
        /// <summary>
        /// 接收到数据时调用的事件
        /// </summary>
        public event ReceiveMsgHandler OnMsgReceived;
        /// <summary>
        /// 开始监听数据的委托
        /// </summary>
        public delegate void StartListenHandler();
        /// <summary>
        /// 开始监听数据的事件
        /// </summary>
        public event StartListenHandler StartListenThread;
        /// <summary>
        /// 发送信息完成的委托
        /// </summary>
        /// <param name="successorfalse"></param>
        public delegate void SendCompleted(bool successorfalse);
        /// <summary>
        /// 发送信息完成的事件
        /// </summary>
        public event SendCompleted OnSended;
        /// <summary>
        /// 监听接收的SocketAsyncEventArgs
        /// </summary>
        private SocketAsyncEventArgs listenerSocketAsyncEventArgs;
        int Plcport;
        public OmronFINS(String hostName, Int32 port, Int32 PLCStaion)
        {
            Plcport = PLCStaion;
            IPAddress[] addressList = Dns.GetHostAddresses(hostName);
            this.hostEndPoint = new IPEndPoint(addressList[addressList.Length - 1], port);
            this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }
        /// <summary>
        /// 连接服务端
        /// </summary>
        private bool Connect()
        {
            using (SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs())
            {
                connectArgs.UserToken = this.clientSocket;
                connectArgs.RemoteEndPoint = this.hostEndPoint;
                connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
                clientSocket.ConnectAsync(connectArgs);
                //等待连接结果
                bool autores = autoConnectEvent.WaitOne(1000);
                if (this.connected)
                {
                    listenerSocketAsyncEventArgs = new SocketAsyncEventArgs();
                    byte[] receiveBuffer = new byte[1024];//设置接收buffer区大小
                    listenerSocketAsyncEventArgs.UserToken = clientSocket;
                    listenerSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
                    listenerSocketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
                    StartListenThread();
                    // SocketExtensions.SetKeepAlive(clientSocket, 3000, 1000);
                    return true;
                }
                else
                    return false;
            }
        }
        /// <summary>
        /// 开始监听线程的入口函数
        /// </summary>
        private void Listen()
        {
            (listenerSocketAsyncEventArgs.UserToken as Socket).ReceiveAsync(listenerSocketAsyncEventArgs);
        }
        public static List<SocketAsyncEventArgs> s_lst = new List<SocketAsyncEventArgs>();
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="message"></param>
        private void Send(Byte[] message)
        {
            if (this.connected)
            {
                Byte[] sendBuffer = message;
                SocketAsyncEventArgs senderSocketAsyncEventArgs = null;// new SocketAsyncEventArgs();
                lock (s_lst)
                {
                    if (s_lst.Count > 0)
                    {
                        senderSocketAsyncEventArgs = s_lst[s_lst.Count - 1];
                        s_lst.RemoveAt(s_lst.Count - 1);
                    }
                }
                if (senderSocketAsyncEventArgs == null)
                {
                    senderSocketAsyncEventArgs = new SocketAsyncEventArgs();
                    senderSocketAsyncEventArgs.UserToken = this.clientSocket;
                    senderSocketAsyncEventArgs.RemoteEndPoint = this.hostEndPoint;
                    senderSocketAsyncEventArgs.Completed += (object sender, SocketAsyncEventArgs _e) =>
                        {
                            lock (s_lst)
                            {
                                s_lst.Add(senderSocketAsyncEventArgs);
                            }
                        };
                }
                senderSocketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
                clientSocket.SendAsync(senderSocketAsyncEventArgs);
            }
            else
            {
                this.connected = false;
            }
            SendMess = message;
        }
        /// <summary>
        /// 断开连接
        /// </summary>
        private bool Disconnect()
        {
            bool returnDis = true;
            try
            {
                this.clientSocket.Shutdown(SocketShutdown.Both);
                this.clientSocket.Close();
                //this.clientSocket.Dispose();
                //clientSocket.Disconnect(true);
                //clientSocket.Disconnect(false);
            }
            catch (Exception)
            {
                returnDis = false;
            }
            finally
            {
            }
            this.connected = false;
            return returnDis;
        }
        /// <summary>
        /// 连接的完成方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnConnect(object sender, SocketAsyncEventArgs e)
        {
            this.connected = (e.SocketError == SocketError.Success);
            autoConnectEvent.Set();
        }
        /// <summary>
        /// 接收的完成方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReceive(object sender, SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred == 0)
            {
                //Console.WriteLine("Socket is closed", Socket.Handle);
                if (clientSocket.Connected)
                {
                    try
                    {
                        clientSocket.Shutdown(SocketShutdown.Both);
                    }
                    catch (Exception)
                    {
                        //client already closed
                    }
                    finally
                    {
                        if (clientSocket.Connected)
                        {
                            clientSocket.Close();
                        }
                    }
                }
                Byte[] rs = new Byte[0];
                OnMsgReceived(rs);
                this.connected = false;
            }
            else
            {
                byte[] buffer = new byte[e.BytesTransferred];
                for (int i = 0; i < e.BytesTransferred; i++)
                {
                    buffer[i] = e.Buffer[i];
                }
                this.OnMsgReceived(buffer);
                Listen();
            }
        }
        /// <summary>
        /// 发送的完成方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSend(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                OnSended(true);
            }
            else
            {
                OnSended(false);
                this.ProcessError(e);
            }
        }
        /// <summary>
        /// 处理错误
        /// </summary>
        /// <param name="e"></param>
        private void ProcessError(SocketAsyncEventArgs e)
        {
            Socket s = e.UserToken as Socket;
            if (s.Connected)
            {
                try
                {
                    s.Shutdown(SocketShutdown.Both);
                }
                catch (Exception)
                {
                    //client already closed
                }
                finally
                {
                    if (s.Connected)
                    {
                        s.Close();
                    }
                }
                this.connected = false;
            }
            //throw new SocketException((Int32)e.SocketError);
        }
        #region IDisposable Members
        public void Dispose()
        {
            autoConnectEvent.Close();
            if (this.clientSocket.Connected)
            {
                this.clientSocket.Close();
            }
        }
        #endregion
        #region  欧姆龙通讯协议
        /// <summary>
        /// 发送命令反馈
        /// </summary>
        /// <param name="successorfalse"></param>
        void OmronFINS_OnSended(bool successorfalse)
        {
            if (!successorfalse)
            {
            }
            else
            {
            }
        }
        Byte PCS;
        Byte PLCS;
        int SendOrRev;
        int SendOrRev2;
        Byte[] SendBack;
        Byte[] RecvBack;
        /// <summary>
        /// 接受命令反馈
        /// </summary>
        /// <param name="info"></param>
        void OmronFINS_OnMsgReceived(byte[] info)
        {
            if (SendmessHas)
            {
                if (info.Length >= 24)
                {
                    if (int.Parse(info[23].ToString("X").Trim(), System.Globalization.NumberStyles.HexNumber) == Plcport)
                    {
                        PCS = info[19];
                        PLCS = info[23];
                        SendmessHas = false;
                    }
                }
            }
            else
            {
                if (info.Length > 0)//PLC连接错误NO
                {
                    if (SendOrRev2 == 1)//发送命令
                    {
                        SendBack = info;
                        SendOrRev2 = 0;
                    }
                    else if (SendOrRev == 2)//接受命令
                    {
                        RecvBack = info;
                        SendOrRev = 0;
                    }
                }
                else
                {
                    if (SendOrRev2 == 1)//发送命令
                    {
                        SendBack = new Byte[1];
                        SendBack[0] = 0x00;
                        SendOrRev2 = 0;
                    }
                    else if (SendOrRev == 2)//接受命令
                    {
                        RecvBack = new Byte[1];
                        RecvBack[0] = 0x00;
                        SendOrRev = 0;
                    }
                }
            }
        }
        void OmronFINS_StartListenThread()
        {
            this.Listen();
        }
        bool SendmessHas = false;
        /// <summary>
        /// 打开连接
        /// </summary>
        /// <returns></returns>
        public bool OpenLinkPLC()
        {
            bool Ret = false;
            this.StartListenThread += new StartListenHandler(OmronFINS_StartListenThread);
            this.OnMsgReceived += new ReceiveMsgHandler(OmronFINS_OnMsgReceived);
            this.OnSended += new SendCompleted(OmronFINS_OnSended);
            Ret = this.Connect();
            if (Ret)
            {
                SendmessHas = true;
                this.Send(GetPCAdress());
                int addNs = 0;
                while (SendmessHas && addNs < 500)
                {
                    Thread.Sleep(2);
                    addNs++;
                }
                if (addNs < 500)
                {
                    Ret = true;
                }
                else
                {
                    Ret = false;
                }
            }
            return Ret;
        }
        /// <summary>
        /// 关闭连接
        /// </summary>
        /// <returns></returns>
        public bool CloseLinkPLC()
        {
            return this.Disconnect();
        }
        /// <summary>
        /// 写入值(Word)
        /// </summary>
        /// <param name="TypeInt">起始寄存器地址</param>
        /// <param name="NumData">个数</param>
        /// <param name="IntValue"></param>
        /// <returns>true,成功;false,失败</returns>
        public bool WritePlcData(string TypeInt, int NumData, ref int[] IntValue)
        {
            bool sendRerun = false;
            if (NumData > 0)
            {
                Byte[] numData = BitConverter.GetBytes(NumData);//Use numData[0] and numData[1]
                Byte[] SendmessAge = new Byte[34 + NumData * 2];
                if (GetType(TypeInt, 0) != 0x00 && Address != null && Address.Length > 1)
                {
                    Byte[] getSendFunc = this.SetPLCvalue(PLCS, PCS, GetType(TypeInt, 0), Address[1], Address[0], 0x00, numData[1], numData[0], NumData);
                    for (int i = 0; i < 34 + NumData * 2; i++)
                    {
                        if (i < 34)
                        {
                            SendmessAge[i] = getSendFunc[i];
                        }
                        else
                        {
                            if ((i - 33) % 2 != 0)
                            {
                                Byte[] BuffInvalue = BitConverter.GetBytes(IntValue[(i - 33) / 2]);
                                SendmessAge[i] = BuffInvalue[1];
                            }
                            else
                            {
                                Byte[] BuffInvalue = BitConverter.GetBytes(IntValue[(i - 33) / 2 - 1]);
                                SendmessAge[i] = BuffInvalue[0];
                            }
                            //SendmessAge[i]
                        }
                    }
                    SendOrRev2 = 1;
                    this.Send(SendmessAge);
                    int Outtime = 0;
                    while (SendOrRev2 != 0 && this.connected && Outtime < 600)
                    {
                        Thread.Sleep(2);
                        Outtime++;
                    }
                    if (Outtime < 600 && SendBack != null)
                    {
                        try
                        {
                            //if (SendBack.Length > 1 && SendBack[26] == 0x01 && SendBack[27] == 0x02 && SendBack[28] == 0x00 && SendBack[29] == 0x00)
                            //{
                            if (SendBack.Length > 1 && SendBack[26] == 0x01 && SendBack[27] == 0x02 && SendBack[28] == 0x00)
                            {
                                sendRerun = true;
                            }
                            else
                            {
                                sendRerun = false;
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                    else
                    {
                        SendOrRev2 = 0;
                    }
                }
            }
            return sendRerun;
        }
        /// <summary>
        /// 读取值(Word)
        /// </summary>
        /// <param name="TypeInt">起始寄存器地址</param>
        /// <param name="NumData">个数</param>
        /// <param name="IntValue"></param>
        /// <returns></returns>
        public bool ReadPlcData(string TypeInt, int NumData, out int[] IntValue)
        {
            bool GetPlcRet = false;
            IntValue = new int[1];
            if (NumData > 0)
            {
                IntValue = new int[NumData];
                Byte[] numData = BitConverter.GetBytes(NumData);//Use numData[0] and numData[1]
                Byte[] RecivemessAge = new Byte[34];
                if (GetType(TypeInt, 0) != 0x00 && Address != null && Address.Length > 1)
                {
                    Byte[] getReciveFunc = this.GetPLCvalue(PLCS, PCS, GetType(TypeInt, 0), Address[1], Address[0], 0x00, numData[1], numData[0]);
                    this.Send(getReciveFunc);
                    SendOrRev = 2;
                    int Outtime = 0;
                    while (SendOrRev != 0 && this.connected && Outtime < 600)
                    {
                        Thread.Sleep(2);
                        Outtime++;
                    }
                    if (Outtime < 600 && RecvBack != null)
                    {
                        try
                        {
                            //if (RecvBack.Length > 1 && RecvBack[26] == 0x01 && RecvBack[27] == 0x01 && RecvBack[28] == 0x00 && RecvBack[29] == 0x00)
                            if (RecvBack.Length == 30 + NumData * 2 && RecvBack[26] == 0x01 && RecvBack[27] == 0x01 && RecvBack[28] == 0x00)
                            {
                                GetPlcRet = true;
                                for (int i = 0; i < NumData; i++)
                                {
                                    IntValue[i] = int.Parse(RecvBack[30 + i * 2].ToString("X").PadLeft(2, '0') + RecvBack[30 + i * 2 + 1].ToString("X").PadLeft(2, '0'), System.Globalization.NumberStyles.HexNumber);
                                }
                            }
                            else
                            {
                                GetPlcRet = false;
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                    else
                    {
                        SendOrRev = 0;
                    }
                }
            }
            return GetPlcRet;
        }
        /// <summary>
        /// 读取值(Word)
        /// </summary>
        /// <param name="TypeInt">起始寄存器地址</param>
        /// <param name="NumData">个数</param>
        /// <param name="IntValue"></param>
        /// <returns></returns>
        public bool ReadPlcDataCIO(string TypeInt, int NumData, out int[] IntValue)
        {
            bool GetPlcRet = false;
            IntValue = new int[1];
            if (NumData > 0)
            {
                IntValue = new int[NumData];
                Byte[] numData = BitConverter.GetBytes(NumData);//Use numData[0] and numData[1]
                Byte[] RecivemessAge = new Byte[34];
                if (GetType(TypeInt, 0) != 0x00 && Address != null && Address.Length > 1)
                {
                    Byte[] getReciveFunc = this.GetPLCvalue(PLCS, PCS, GetType(TypeInt, 0), Address[1], Address[0], 0x00, numData[1], numData[0]);
                    this.Send(getReciveFunc);
                    SendOrRev = 2;
                    int Outtime = 0;
                    while (SendOrRev != 0 & this.connected & Outtime < 800)
                    {
                        Thread.Sleep(2);
                        Outtime++;
                    }
                    if (Outtime < 800 && RecvBack != null)
                    {
                        //try
                        //{
                        //if (RecvBack.Length > 1 && RecvBack[26] == 0x01 && RecvBack[27] == 0x01 && RecvBack[28] == 0x00 && RecvBack[29] == 0x00)
                        if (RecvBack.Length > 30 && RecvBack[26] == 0x01 && RecvBack[27] == 0x01 && RecvBack[28] == 0x00)
                        {
                            GetPlcRet = true;
                            for (int i = 0; i < NumData; i++)
                            {
                                IntValue[i] = int.Parse(RecvBack[30 + i * 2].ToString("X").PadLeft(2, '0') + RecvBack[30 + i * 2 + 1].ToString("X").PadLeft(2, '0'), System.Globalization.NumberStyles.HexNumber);
                            }
                        }
                        else
                        {
                            GetPlcRet = false;
                        }
                        //}
                        //catch (Exception)
                        //{
                        //}
                    }
                    else
                    {
                        SendOrRev = 0;
                    }
                }
            }
            return GetPlcRet;
        }
        /// <summary>
        /// 读取值(Bit)
        /// </summary>
        /// <param name="TypeInt">起始寄存器地址</param>
        /// <param name="IntValue"></param>
        /// <returns></returns>
        public bool ReadPlcBitData(string TypeInt, out int IntValue)
        {
            bool GetPlcRet = false;
            IntValue = 0;
            Byte[] RecivemessAge = new Byte[34];
            if (GetType(TypeInt, 1) != 0x00 && Address != null && Address.Length > 1)
            {
                Byte[] getReciveFunc = this.GetPLCvalue(PLCS, PCS, GetType(TypeInt, 1), Address[1], Address[0], AddressBit[0]);
                this.Send(getReciveFunc);
                SendOrRev = 2;
                int Outtime = 0;
                while (SendOrRev != 0 & Outtime < 600)
                {
                    Thread.Sleep(2);
                    Outtime++;
                }
                if (Outtime < 600)
                {
                    if (RecvBack.Length > 1 && RecvBack[26] == 0x01 && RecvBack[27] == 0x01 && RecvBack[28] == 0x00 && RecvBack[29] == 0x00)
                    {
                        GetPlcRet = true;
                        IntValue = int.Parse(RecvBack[30].ToString("X").PadLeft(2, '0'), System.Globalization.NumberStyles.HexNumber);
                    }
                }
                else
                {
                    SendOrRev = 0;
                }
            }
            return GetPlcRet;
        }
        /// <summary>
        /// Write值(bit)
        /// </summary>
        /// <param name="TypeInt">寄存器地址(CIOX.X)</param>
        /// <returns></returns>
        public bool WriteBitPlcData(string TypeInt, int ItemValue)
        {
            bool sendRerun = false;
            Byte[] SendmessAge = new Byte[35];
            if (GetType(TypeInt, 1) != 0x00 && Address != null && Address.Length > 1)
            {
                Byte[] getSendFunc = this.WritePLCBitvalue(PLCS, PCS, GetType(TypeInt, 1), Address[1], Address[0], AddressBit[0]);
                for (int i = 0; i < 35; i++)
                {
                    if (i < 32)
                    {
                        SendmessAge[i] = getSendFunc[i];
                    }
                    else if (i == 32)
                    {
                        SendmessAge[i] = 0x00;
                    }
                    else if (i == 33)
                    {
                        SendmessAge[i] = 0x01;
                    }
                    else
                    {
                        if (ItemValue == 1)
                            SendmessAge[i] = 0x01;
                        else
                            SendmessAge[i] = 0x00;
                    }
                }
                this.Send(SendmessAge);
                SendOrRev2 = 1;
                int Outtime = 0;
                while (SendOrRev2 != 0 & Outtime < 600)
                {
                    Thread.Sleep(2);
                    Outtime++;
                }
                if (Outtime < 600)
                {
                    if (SendBack.Length > 1 && SendBack[26] == 0x01 && SendBack[27] == 0x02 && SendBack[28] == 0x00 && SendBack[29] == 0x00)
                    {
                        sendRerun = true;
                    }
                }
                else
                {
                    SendOrRev2 = 0;
                }
            }
            return sendRerun;
        }
        /// <summary>
        /// Set 值(bit)
        /// </summary>
        /// <param name="TypeInt">寄存器地址(CIOX.X)</param>
        /// <returns></returns>
        public bool SetPlcData(string TypeInt)
        {
            bool sendRerun = false;
            Byte[] SendmessAge = new Byte[35];
            if (GetType(TypeInt, 1) != 0x00 && Address != null && Address.Length > 1)
            {
                Byte[] getSendFunc = this.SetPLCBitvalue(PLCS, PCS, GetType(TypeInt, 1), Address[1], Address[0], AddressBit[0]);
                for (int i = 0; i < 35; i++)
                {
                    if (i < 34)
                    {
                        SendmessAge[i] = getSendFunc[i];
                    }
                    else
                    {
                        SendmessAge[i] = 0x00;
                    }
                }
                this.Send(SendmessAge);
                SendOrRev2 = 1;
                int Outtime = 0;
                while (SendOrRev2 != 0 & Outtime < 600)
                {
                    Thread.Sleep(2);
                    Outtime++;
                }
                if (Outtime < 600)
                {
                    if (SendBack.Length > 1 && SendBack[26] == 0x01 && SendBack[27] == 0x02 && SendBack[28] == 0x00 && SendBack[29] == 0x00)
                    {
                        sendRerun = true;
                    }
                }
            }
            return sendRerun;
        }
        /// <summary>
        /// Rest 值(bit)
        /// </summary>
        /// <param name="TypeInt">寄存器地址(CIOX.X)</param>
        /// <returns></returns>
        public bool RestPlcData(string TypeInt)
        {
            bool sendRerun = false;
            Byte[] SendmessAge = new Byte[35];
            if (GetType(TypeInt, 1) != 0x00 && Address != null && Address.Length > 1)
            {
                Byte[] getSendFunc = this.RstPLCBitvalue(PLCS, PCS, GetType(TypeInt, 1), Address[1], Address[0], AddressBit[0]);
                for (int i = 0; i < 35; i++)
                {
                    if (i < 34)
                    {
                        SendmessAge[i] = getSendFunc[i];
                    }
                    else
                    {
                        SendmessAge[i] = 0x00;
                    }
                }
                this.Send(SendmessAge);
                SendOrRev2 = 1;
                int Outtime = 0;
                while (SendOrRev2 != 0 & Outtime < 600)
                {
                    Thread.Sleep(2);
                    Outtime++;
                }
                if (Outtime < 600)
                {
                    if (SendBack.Length > 1 && SendBack[26] == 0x01 && SendBack[27] == 0x02 && SendBack[28] == 0x00 && SendBack[29] == 0x00)
                    {
                        sendRerun = true;
                    }
                }
            }
            return sendRerun;
        }
        Byte[] Address;
        Byte[] AddressBit;
        private Byte GetType(string TypeInt, int SizeofInt)
        {
            Byte ms = 0x00;
            if (TypeInt.IndexOf("D") == 0 | TypeInt.IndexOf("d") == 0)
            {
                if (SizeofInt == 0)
                {
                    ms = 0x82;
                    if (TypeInt.IndexOf(".") == -1)
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.Length - 1)));
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
                else
                {
                    ms = 0x02;
                    if (TypeInt.IndexOf(".") > 1)
                    {
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.IndexOf(".") - 1)));
                        AddressBit = BitConverter.GetBytes(int.Parse(TypeInt.Substring(TypeInt.IndexOf(".") + 1, TypeInt.Length - TypeInt.IndexOf(".") - 1)));
                    }
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
            }
            else if (TypeInt.IndexOf("CIO") == 0 | TypeInt.IndexOf("cio") == 0)
            {
                if (SizeofInt == 0)
                {
                    ms = 0xB0;
                    if (TypeInt.IndexOf(".") == -1)
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(3, TypeInt.Length - 3)));
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
                else
                {
                    ms = 0x30;
                    if (TypeInt.IndexOf(".") > 3)
                    {
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(3, TypeInt.IndexOf(".") - 3)));
                        AddressBit = BitConverter.GetBytes(int.Parse(TypeInt.Substring(TypeInt.IndexOf(".") + 1, TypeInt.Length - TypeInt.IndexOf(".") - 1)));
                    }
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
            }
            else if (TypeInt.IndexOf("W") == 0 | TypeInt.IndexOf("w") == 0)
            {
                if (SizeofInt == 0)
                {
                    ms = 0xB1;
                    if (TypeInt.IndexOf(".") == -1)
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.Length - 1)));
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
                else
                {
                    ms = 0x31;
                    if (TypeInt.IndexOf(".") > 1)
                    {
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.IndexOf(".") - 1)));
                        AddressBit = BitConverter.GetBytes(int.Parse(TypeInt.Substring(TypeInt.IndexOf(".") + 1, TypeInt.Length - TypeInt.IndexOf(".") - 1)));
                    }
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
            }
            else if (TypeInt.IndexOf("H") == 0 | TypeInt.IndexOf("h") == 0)
            {
                if (SizeofInt == 0)
                {
                    ms = 0xB2;
                    if (TypeInt.IndexOf(".") == -1)
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.Length - 1)));
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
                else
                {
                    ms = 0x32;
                    if (TypeInt.IndexOf(".") > 1)
                    {
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.IndexOf(".") - 1)));
                        AddressBit = BitConverter.GetBytes(int.Parse(TypeInt.Substring(TypeInt.IndexOf(".") + 1, TypeInt.Length - TypeInt.IndexOf(".") - 1)));
                    }
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
            }
            else if (TypeInt.IndexOf("A") == 0 | TypeInt.IndexOf("a") == 0)
            {
                if (SizeofInt == 0)
                {
                    ms = 0xB3;
                    if (TypeInt.IndexOf(".") == -1)
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.Length - 1)));
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
                else
                {
                    ms = 0x33;
                    if (TypeInt.IndexOf(".") > 1)
                    {
                        Address = BitConverter.GetBytes(int.Parse(TypeInt.Substring(1, TypeInt.IndexOf(".") - 1)));
                        AddressBit = BitConverter.GetBytes(int.Parse(TypeInt.Substring(TypeInt.IndexOf(".") + 1, TypeInt.Length - TypeInt.IndexOf(".") - 1)));
                    }
                    else
                    {
                        Address = new Byte[1];
                        AddressBit = new Byte[1];
                    }
                }
            }
            return ms;
        }
        /// <summary>
        /// Get PLC DA1 SNA1
        /// </summary>
        /// <returns></returns>
        private Byte[] GetPCAdress()
        {
            Byte[] ReturnGetPC = new Byte[20];
            ReturnGetPC[0] = 0x46;//f
            ReturnGetPC[1] = 0x49;//i
            ReturnGetPC[2] = 0x4E;//n
            ReturnGetPC[3] = 0x53;//s
            ReturnGetPC[4] = 0x00;
            ReturnGetPC[5] = 0x00;
            ReturnGetPC[6] = 0x00;
            ReturnGetPC[7] = 0x0C;
            ReturnGetPC[8] = 0x00;
            ReturnGetPC[9] = 0x00;
            ReturnGetPC[10] = 0x00;
            ReturnGetPC[11] = 0x00;
            ReturnGetPC[12] = 0x00;
            ReturnGetPC[13] = 0x00;
            ReturnGetPC[14] = 0x00;
            ReturnGetPC[15] = 0x00;
            ReturnGetPC[16] = 0x00;
            ReturnGetPC[17] = 0x00;
            ReturnGetPC[18] = 0x00;
            ReturnGetPC[19] = 0x00;
            return ReturnGetPC;
        }
        /// <summary>
        /// Read Word
        /// </summary>
        /// <param name="DA1"></param>
        /// <param name="SA1"></param>
        /// <param name="DataValue"></param>
        /// <param name="Address1"></param>
        /// <param name="Address2"></param>
        /// <param name="Address3"></param>
        /// <param name="DataNum1"></param>
        /// <param name="DataNum2"></param>
        /// <returns></returns>
        private Byte[] GetPLCvalue(Byte DA1, Byte SA1, Byte DataValue, Byte Address1, Byte Address2, Byte Address3, Byte DataNum1, Byte DataNum2)
        {
            Byte[] SendFun = new Byte[34];
            SendFun[0] = 0x46;
            SendFun[1] = 0x49;
            SendFun[2] = 0x4E;
            SendFun[3] = 0x53;
            SendFun[4] = 0x00;
            SendFun[5] = 0x00;
            SendFun[6] = 0x00;
            SendFun[7] = 0x1A;
            SendFun[8] = 0x00;
            SendFun[9] = 0x00;
            SendFun[10] = 0x00;
            SendFun[11] = 0x02;
            SendFun[12] = 0x00;
            SendFun[13] = 0x00;
            SendFun[14] = 0x00;
            SendFun[15] = 0x00;
            SendFun[16] = 0x80;
            SendFun[17] = 0x00;
            SendFun[18] = 0x02;
            SendFun[19] = 0x00;
            SendFun[20] = DA1;
            SendFun[21] = 0x00;
            SendFun[22] = 0x00;
            SendFun[23] = SA1;
            SendFun[24] = 0x00;
            SendFun[25] = 0x01;
            SendFun[26] = 0x01;
            SendFun[27] = 0x01;
            SendFun[28] = DataValue;
            SendFun[29] = Address1;
            SendFun[30] = Address2;
            SendFun[31] = Address3;
            SendFun[32] = DataNum1;
            SendFun[33] = DataNum2;
            return SendFun;
        }
        /// <summary>
        /// Write Word
        /// </summary>
        /// <param name="DA1"></param>
        /// <param name="SA1"></param>
        /// <param name="DataValue"></param>
        /// <param name="Address1"></param>
        /// <param name="Address2"></param>
        /// <param name="Address3"></param>
        /// <param name="DataNum1"></param>
        /// <param name="DataNum2"></param>
        /// <returns></returns>
        private Byte[] SetPLCvalue(Byte DA1, Byte SA1, Byte DataValue, Byte Address1, Byte Address2, Byte Address3, Byte DataNum1, Byte DataNum2, int num)
        {
            Byte[] SendFun = new Byte[34];
            SendFun[0] = 0x46;
            SendFun[1] = 0x49;
            SendFun[2] = 0x4E;
            SendFun[3] = 0x53;
            SendFun[4] = 0x00;
            SendFun[5] = 0x00;
            SendFun[6] = 0x00;
            SendFun[7] = (byte)(26 + 2 * num);
            SendFun[8] = 0x00;
            SendFun[9] = 0x00;
            SendFun[10] = 0x00;
            SendFun[11] = 0x02;
            SendFun[12] = 0x00;
            SendFun[13] = 0x00;
            SendFun[14] = 0x00;
            SendFun[15] = 0x00;
            SendFun[16] = 0x80;
            SendFun[17] = 0x00;
            SendFun[18] = 0x02;
            SendFun[19] = 0x00;
            SendFun[20] = DA1;
            SendFun[21] = 0x00;
            SendFun[22] = 0x00;
            SendFun[23] = SA1;
            SendFun[24] = 0x00;
            SendFun[25] = 0x01;
            SendFun[26] = 0x01;
            SendFun[27] = 0x02;
            SendFun[28] = DataValue;
            SendFun[29] = Address1;
            SendFun[30] = Address2;
            SendFun[31] = Address3;
            SendFun[32] = DataNum1;
            SendFun[33] = DataNum2;
            return SendFun;
        }
        /// <summary>
        /// Read Bit
        /// /// </summary>
        /// <param name="DA1"></param>
        /// <param name="SA1"></param>
        /// <param name="DataValue"></param>
        /// <param name="Address1"></param>
        /// <param name="Address2"></param>
        /// <param name="Address3"></param>
        /// <param name="DataNum1"></param>
        /// <param name="DataNum2"></param>
        /// <returns></returns>
        private Byte[] GetPLCvalue(Byte DA1, Byte SA1, Byte DataValue, Byte Address1, Byte Address2, Byte Address3)
        {
            Byte[] SendFun = new Byte[34];
            SendFun[0] = 0x46;
            SendFun[1] = 0x49;
            SendFun[2] = 0x4E;
            SendFun[3] = 0x53;
            SendFun[4] = 0x00;
            SendFun[5] = 0x00;
            SendFun[6] = 0x00;
            SendFun[7] = 0x1A;
            SendFun[8] = 0x00;
            SendFun[9] = 0x00;
            SendFun[10] = 0x00;
            SendFun[11] = 0x02;
            SendFun[12] = 0x00;
            SendFun[13] = 0x00;
            SendFun[14] = 0x00;
            SendFun[15] = 0x00;
            SendFun[16] = 0x80;
            SendFun[17] = 0x00;
            SendFun[18] = 0x02;
            SendFun[19] = 0x00;
            SendFun[20] = DA1;
            SendFun[21] = 0x00;
            SendFun[22] = 0x00;
            SendFun[23] = SA1;
            SendFun[24] = 0x00;
            SendFun[25] = 0x01;
            SendFun[26] = 0x01;
            SendFun[27] = 0x01;
            SendFun[28] = DataValue;
            SendFun[29] = Address1;
            SendFun[30] = Address2;
            SendFun[31] = Address3;
            SendFun[32] = 0x00;
            SendFun[33] = 0x01;
            return SendFun;
        }
        /// <summary>
        /// Write Bit
        /// </summary>
        /// <param name="DA1"></param>
        /// <param name="SA1"></param>
        /// <param name="DataValue"></param>
        /// <param name="Address1"></param>
        /// <param name="Address2"></param>
        /// <param name="Address3"></param>
        /// <returns></returns>
        private Byte[] WritePLCBitvalue(Byte DA1, Byte SA1, Byte DataValue, Byte Address1, Byte Address2, Byte Address3)
        {
            Byte[] SendFun = new Byte[32];
            SendFun[0] = 0x46;
            SendFun[1] = 0x49;
            SendFun[2] = 0x4E;
            SendFun[3] = 0x53;
            SendFun[4] = 0x00;
            SendFun[5] = 0x00;
            SendFun[6] = 0x00;
            SendFun[7] = 0x1B;
            SendFun[8] = 0x00;
            SendFun[9] = 0x00;
            SendFun[10] = 0x00;
            SendFun[11] = 0x02;
            SendFun[12] = 0x00;
            SendFun[13] = 0x00;
            SendFun[14] = 0x00;
            SendFun[15] = 0x00;
            SendFun[16] = 0x80;
            SendFun[17] = 0x00;
            SendFun[18] = 0x02;
            SendFun[19] = 0x00;
            SendFun[20] = DA1;
            SendFun[21] = 0x00;
            SendFun[22] = 0x00;
            SendFun[23] = SA1;
            SendFun[24] = 0x00;
            SendFun[25] = 0x01;
            SendFun[26] = 0x01;
            SendFun[27] = 0x02;
            SendFun[28] = DataValue;
            SendFun[29] = Address1;
            SendFun[30] = Address2;
            SendFun[31] = Address3;
            return SendFun;
        }
        /// <summary>
        /// Set Bit
        /// </summary>
        /// <param name="DA1"></param>
        /// <param name="SA1"></param>
        /// <param name="DataValue"></param>
        /// <param name="Address1"></param>
        /// <param name="Address2"></param>
        /// <param name="Address3"></param>
        /// <returns></returns>
        private Byte[] SetPLCBitvalue(Byte DA1, Byte SA1, Byte DataValue, Byte Address1, Byte Address2, Byte Address3)
        {
            Byte[] SendFun = new Byte[35];
            SendFun[0] = 0x46;
            SendFun[1] = 0x49;
            SendFun[2] = 0x4E;
            SendFun[3] = 0x53;
            SendFun[4] = 0x00;
            SendFun[5] = 0x00;
            SendFun[6] = 0x00;
            SendFun[7] = 0x1B;
            SendFun[8] = 0x00;
            SendFun[9] = 0x00;
            SendFun[10] = 0x00;
            SendFun[11] = 0x02;
            SendFun[12] = 0x00;
            SendFun[13] = 0x00;
            SendFun[14] = 0x00;
            SendFun[15] = 0x00;
            SendFun[16] = 0x80;
            SendFun[17] = 0x00;
            SendFun[18] = 0x02;
            SendFun[19] = 0x00;
            SendFun[20] = DA1;
            SendFun[21] = 0x00;
            SendFun[22] = 0x00;
            SendFun[23] = SA1;
            SendFun[24] = 0x00;
            SendFun[25] = 0x01;
            SendFun[26] = 0x23;
            SendFun[27] = 0x01;
            SendFun[28] = 0x01;
            SendFun[29] = 0x00;
            SendFun[30] = 0x01;
            SendFun[31] = DataValue;
            SendFun[32] = Address1;
            SendFun[33] = Address2;
            SendFun[34] = Address3;
            return SendFun;
        }
        /// <summary>
        /// RST Bit
        /// </summary>
        /// <param name="DA1"></param>
        /// <param name="SA1"></param>
        /// <param name="DataValue"></param>
        /// <param name="Address1"></param>
        /// <param name="Address2"></param>
        /// <param name="Address3"></param>
        /// <returns></returns>
        private Byte[] RstPLCBitvalue(Byte DA1, Byte SA1, Byte DataValue, Byte Address1, Byte Address2, Byte Address3)
        {
            Byte[] SendFun = new Byte[35];
            SendFun[0] = 0x46;
            SendFun[1] = 0x49;
            SendFun[2] = 0x4E;
            SendFun[3] = 0x53;
            SendFun[4] = 0x00;
            SendFun[5] = 0x00;
            SendFun[6] = 0x00;
            SendFun[7] = 0x1B;
            SendFun[8] = 0x00;
            SendFun[9] = 0x00;
            SendFun[10] = 0x00;
            SendFun[11] = 0x02;
            SendFun[12] = 0x00;
            SendFun[13] = 0x00;
            SendFun[14] = 0x00;
            SendFun[15] = 0x00;
            SendFun[16] = 0x80;
            SendFun[17] = 0x00;
            SendFun[18] = 0x02;
            SendFun[19] = 0x00;
            SendFun[20] = DA1;
            SendFun[21] = 0x00;
            SendFun[22] = 0x00;
            SendFun[23] = SA1;
            SendFun[24] = 0x00;
            SendFun[25] = 0x01;
            SendFun[26] = 0x23;
            SendFun[27] = 0x01;
            SendFun[28] = 0x01;
            SendFun[29] = 0x00;
            SendFun[30] = 0x00;
            SendFun[31] = DataValue;
            SendFun[32] = Address1;
            SendFun[33] = Address2;
            SendFun[34] = Address3;
            return SendFun;
        }
        #endregion
    }
}

至此,我们就可以用上述的类和欧姆龙PLC进行FINS通讯。