三菱PLC——FX3U系列网络通讯(MC1E)

以下代码补充说明三菱PLC——Q系列和FX3U系列通讯测试_三菱f5u 跟q系列通讯-CSDN博客

FX3U通讯类:

 public class PLC_MC_1E
    {

        Socket Client;
        private string Host;      
        string fbt = "01";//"00";未读//"01"批量读
        string plchao = "FF";
        string time = "0A00";//L_H
        string start = "";
        string A_dress = "";
        string count = "";
        string r_or_w = "";
        public PLC_MC_1E1(string host)
        {
            Host = host;         
        }
        public void Initial()
        {
            try
            {
                Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Client.SendTimeout = 10000;
                Client.ReceiveTimeout = 10000;
                Client.Connect(ConvertIP(Host));
            }
            catch (Exception ex)
            {             
                throw new Exception($"建立連接" + Host + "失敗");
            }
        }

        public void Close()
        {
            try
            {
                Client.Close();
            }
            catch (Exception ex)
            {              
                throw new Exception($"關閉連接" + Host + "失敗");
            }
        }     
        //startAddress=D100
        public void ReadBlock16(string startAddress, ref short[] addressValues)
        {
            var addrType = startAddress.Substring(0, 1);
            var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));

            fbt = "01";
            start = startAddr.ToString("X8");
            start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
            A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
            A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
            count = addressValues.Length.ToString("X2");
            r_or_w = "00";
            string str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);

            byte[] OML = new byte[str.Length / 2];

            for (int I = 0; I < OML.Length; I++)
            {
                OML[I] = Convert.ToByte(str.Substring(2 * I, 2), 16);
            }
            // 發送數據
            var recByte = SendData(OML);
            // 數據解析          
            for (int i = 0; i < addressValues.Length; i++)
            {
                string SS = recByte[2 * i + 3].ToString("x2").ToUpper();
                string FDDS = recByte[2 * i + 2].ToString("x2").ToUpper();
                addressValues[i] = Convert.ToInt16(recByte[2 * i + 3].ToString("x2").ToUpper() + recByte[2 * i + 2].ToString("x2").ToUpper(), 16);
            }
        }
        public void WriteBlock16(string startAddress, short[] addressValues)
        {
            var addrType = startAddress.Substring(0, 1);
            var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));

            byte[] bu_write = new byte[addressValues.Length * 2];
            for (int i = 0; i < addressValues.Length; i++)
            {
                bu_write[i * 2] = Convert.ToByte(addressValues[i].ToString("X4").Substring(2, 2), 16);
                bu_write[2 * i + 1] = Convert.ToByte(addressValues[i].ToString("X4").Substring(0, 2), 16);
            }
            fbt = "03";
            start = startAddr.ToString("X8");
            start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
            A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
            A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
            count = addressValues.Length.ToString("X2");
            r_or_w = "00";
            string str = "";
            str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);

            byte[] buffer = new byte[str.Length / 2 + addressValues.Length * 2];// NEWSystem.Text.Encoding.ASCII.GetBytes(str);
            for (int i = 0; i < str.Length / 2 + addressValues.Length * 2; i++)
            {
                if (i < str.Length / 2)
                {
                    buffer[i] = (byte)Convert.ToByte(str.Substring(i * 2, 2), 16);
                }
                else
                {
                    buffer[i] = Convert.ToByte(addressValues[(i - str.Length / 2) / 2].ToString("X4").Substring(2, 2), 16);
                    i++;
                    buffer[i] = Convert.ToByte(addressValues[(i - 1 - str.Length / 2) / 2].ToString("X4").Substring(0, 2), 16);

                }
            }
            string[] ASD = new string[buffer.Length];
            for (int I = 0; I < ASD.Length; I++)
            {
                ASD[I] = buffer[I].ToString("X2");
            }
            // 發送數據
            var recByte = SendData(buffer);
        }

        private int GetAddrTypeByte(string addrType)
        {
            switch (addrType)
            {
                case "D": return 17440;
                case "M": return 19744;
                case "R": return 21024;
                case "SM": return 145;
                default: return 145;
            }

        }
        public byte[] SendData(byte[] data)
        {
            var recByte = new byte[8192];

            lock (Client)
            {
                try
                {
                    ReConnection();

                    if (Client.Available > 0)
                    {
                        var buffer = new byte[8192];
                        Client.Receive(buffer);
                    }

                    Client.Send(data);

                    if (WaitTask(() => Client.Available > 0, 5) == true)
                    {
                        Client.Receive(recByte);
                    }
                    else
                    {                     
                        throw new Exception($"未接收到" + Host + "的資料回傳");

                    }
                }
                catch (Exception ex)
                {                  
                    throw new Exception($"" + ex + "");
                }
                return recByte;
            }
        }
        private void ReConnection()
        {
            try
            {
                if (Client.Connected == false)
                {
                    Client.Close();
                    Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    Client.SendTimeout = 5000;
                    Client.ReceiveTimeout = 5000;
                    Client.Connect(ConvertIP(Host));
                }
            }
            catch (Exception ex)
            {               
                throw new Exception($"重新連接" + Host + "失敗");
            }
        }
        public static bool WaitTask(Func task, double timeOutSeconds)
        {
            var startTime = DateTime.Now;

            while (true)
            {
                try
                {
                    if (DateTime.Now.Subtract(startTime).TotalSeconds > timeOutSeconds)
                    {
                        return false;
                    }
                    else
                    {
                        Thread.Sleep(10);
                    }

                    if (task.Invoke() == true)
                    {
                        return true;
                    }
                }
                catch (Exception)
                {
                    return false;
                }
            }
        }

        public static IPEndPoint ConvertIP(string host)
        {
            try
            {
                var ip = host.Split(':')[0];
                var port = host.Split(':')[1];
                return new IPEndPoint(IPAddress.Parse(ip), Convert.ToInt32(port));
            }
            catch (Exception ex)
            {
                return null;
            }
        }          
    }
本文为新封装的PLC FX3U系列网络通讯类(MC1E通讯),方便以后查阅。

你可能感兴趣的:(C#,笔记,c#)