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

寻技术 C#编程 2023年07月12日 993

先介绍下一些基本定义

串行通信:通过的是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通讯。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持寻技术。

关闭

用微信“扫一扫”