Browse Source

array中struct读写成功

yc_t 6 years ago
parent
commit
b4d81064ea

+ 201 - 3
PLCLinker/PLCLinker/PLCLinker.cs

@@ -1,9 +1,11 @@
 using S7.Net;
+using S7.Net.Types;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Timers;
 
 namespace PLCLinker
 {
@@ -21,17 +23,213 @@ namespace PLCLinker
 
     class PLCLinker : IEquipments
     {
+        /// <summary>
+        /// PLC 连接状态flag
+        /// </summary>
+        private bool isConnected = false;
+        /// <summary>
+        /// 系统关闭flag
+        /// </summary>
+        private bool isClosing = false;
+        ///// <summary>
+        ///// 从plc获得结构化数据
+        ///// </summary>
+        //private PLCMessage plcMsg;
+        /// <summary>
+        /// 定时器
+        /// </summary>
+        System.Timers.Timer timer;
+        ///// <summary>
+        ///// 读PLC初始地址
+        ///// </summary>
+        //private int startAddr = 0;
+        ///// <summary>
+        ///// 读PLC地址长度
+        ///// </summary>
+        //private int addrLength = 110;
+        /// <summary>
+        /// PLC的IP地址
+        /// </summary>
+        private string ipString;
+        /// <summary>
+        /// PLC的端口号
+        /// </summary>
+        private Int16 rack;
+        /// <summary>
+        /// 工作站号
+        /// </summary>
+        private Int16 slot;
+        /// <summary>
+        /// PLC刷新频率,来自于配置文件
+        /// </summary>
+        private int PLC_refresh_interval;
+        /// <summary>
+        /// 无法获取配置文件时使用的PLC刷新频率
+        /// </summary>
+        private const short PLC_TIME_SCALE = 200;
+        /// <summary>
+        /// PLC S7连接对象
+        /// </summary>
         Plc plc = null;
+        /// <summary>
+        /// 停车终端结构体
+        /// </summary>
+        public ParkEndPoint pe;
+        public TestStru ts;
+        public List<byte> resultBytes;
+
         public PLCLinker()
         {
-            plc = new Plc(CpuType.S71500, "127.0.0.1", 0, 2);
+            plc = new Plc(CpuType.S71500, "192.168.0.1", 0, 1);
+            //plc = new Plc(CpuType.S71500, "127.0.0.1", 0, 1);
             ErrorCode err = plc.Open();
-            if(err == ErrorCode.ConnectionError) { Console.WriteLine("connection error"); }
+            if (err == ErrorCode.ConnectionError) { Console.WriteLine("connection error"); }
+            else { Console.WriteLine("connected"); }
+            pe = new ParkEndPoint();
+            ts = new TestStru();
+            resultBytes = new List<byte>();
+        }
+
+        public List<byte> ReadMultipleBytes(int db, int length, int startAddr = 0)
+        {
+            List<byte> resultBytes = new List<byte>();
+            int index = startAddr;
+            int remains = length;
+            while (remains > 0)
+            {
+                int maxToRead = Math.Min(remains, 200);
+                byte[] temp = plc.ReadBytes(DataType.DataBlock, db, index, maxToRead);
+                if (temp == null)
+                    return new List<byte>();
+                resultBytes.AddRange(temp);
+                remains -= maxToRead;
+                index += maxToRead;
+            }
+            return resultBytes;
+        }
+        public void WriteMultipleBytes(int db, List<byte> bytesToWrite, int startAddr = 0)
+        {
+            int index = startAddr;
+            int remains = bytesToWrite.Count();
+            while (remains > 0)
+            {
+                int maxToWrite = Math.Min(remains, 200);
+                plc.WriteBytes(DataType.DataBlock, db, index, bytesToWrite.GetRange(index, maxToWrite).ToArray());
+                index += maxToWrite;
+                remains -= maxToWrite;
+            }
+        }
+
+        public void ReadFromPLC()
+        {
+            if (plc != null)
+            {
+                int index = 0;
+                byte[] receive = new byte[256];
+                receive = plc.ReadBytes(DataType.DataBlock, 1, index, ParkEndPoint.bytesCount);
+                byte[][] subStru = new byte[pe.indices.Count][];
+                if (receive.Count() != 0)
+                {
+                    for (int i = 0; i < pe.indices.Count; i++)
+                    {
+                        subStru[i] = new byte[20];
+                        for (int j = 0; j < pe.indices[i]; j++)
+                        {
+                            subStru[i][j] = receive[index + j];
+                            //if(j == pe.indices[i] - 1)
+                            //{
+                            //    subStru[i][j + 1] = BitConverter.GetBytes('\0')[0];
+                            //    subStru[i][j + 2] = BitConverter.GetBytes('\0')[1];
+                            //}
+                        }
+                        index += pe.indices[i];
+                    }
+                    pe.endPointNo = BitConverter.ToInt32(subStru[0], 0);
+                    pe.licCode = Encoding.ASCII.GetString(subStru[1]).TrimEnd('\0');
+                    pe.unregistered = BitConverter.ToBoolean(subStru[2], 0);
+                    pe.completed = BitConverter.ToBoolean(subStru[3], 0);
+                    pe.serialNo = Encoding.ASCII.GetString(subStru[4]).TrimEnd('\0');
+                    Console.WriteLine(pe.ToString());
+                }
+            }
+        }
+        public void WriteToPLC(ParkEndPoint pe)
+        {
+            if (plc != null)
+            {
+                Console.WriteLine("write to PLC");
+                //plc.WriteClass(pe, 1);
+                byte[] sendBytes = new byte[200];
+                int index = 0;
+                byte[] temp;
+
+                temp = BitConverter.GetBytes(pe.endPointNo);
+                temp.CopyTo(sendBytes, index);
+                index += temp.Length;
+
+                temp = Encoding.ASCII.GetBytes(pe.licCode);
+                temp.CopyTo(sendBytes, index);
+                index += temp.Length;
+
+                temp = BitConverter.GetBytes(pe.unregistered);
+                temp.CopyTo(sendBytes, index);
+                index += temp.Length;
+
+                temp = BitConverter.GetBytes(pe.completed);
+                temp.CopyTo(sendBytes, index);
+                index += temp.Length;
+
+                temp = Encoding.ASCII.GetBytes(pe.serialNo);
+                temp.CopyTo(sendBytes, index);
+                index += temp.Length;
+
+                plc.WriteBytes(DataType.DataBlock, 1, 0, sendBytes);
+            }
+        }
+
+        public void ReadClassFromPLC()
+        {
+            object obj = plc.ReadClass<ParkEndPoint>(1, 0);
+            if (obj != null) { pe = (ParkEndPoint)obj; }
+            Console.WriteLine(pe.ToString());
+        }
+        public void WriteClassToPLC()
+        {
+            Console.WriteLine("write to PLC");
+            plc.WriteClass(pe, 1, 0);
         }
 
-        private void ReadFromPLC()
+        public object ReadStruFromPLC(object obj, int db, int startAddr = 0)
         {
+            Type structType = obj.GetType();
+            object returnedObj;
+            try
+            {
+                returnedObj = plc.ReadStruct(structType, db, startAddr);
+                //int numBytes = Struct.GetStructSize(structType);
+                //// now read the package
+                //var resultBytes = plc.ReadBytes(DataType.DataBlock, db, startAddr, numBytes);
 
+                //// and decode it
+                //returnedObj = Struct.FromBytes(structType, resultBytes);
+                if (returnedObj != null) { return returnedObj; }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+            }
+            return Activator.CreateInstance(structType);
+            //Console.WriteLine(ts.ToString());
+        }
+        public void WriteStruToPLC(object obj, int db, int startAddr = 0)
+        {
+            Console.WriteLine("write to PLC");
+            ErrorCode ec = ErrorCode.NoError;
+            try
+            {
+                ec = plc.WriteStruct(obj, 22, startAddr);
+            }
+            catch (Exception e) { Console.WriteLine(ec.ToString() + "," + e.Message); }
         }
 
         public AbstractMessage GetMessage()

+ 5 - 0
PLCLinker/PLCLinker/PLCLinker.csproj

@@ -32,6 +32,9 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="S7.Net">
+      <HintPath>..\..\resources\S7.Net.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -42,6 +45,8 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="entity.cs" />
+    <Compile Include="PLCLinker.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>

+ 54 - 1
PLCLinker/PLCLinker/Program.cs

@@ -1,7 +1,9 @@
-using System;
+using S7.Net.Types;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 
 namespace PLCLinker
@@ -10,6 +12,57 @@ namespace PLCLinker
     {
         static void Main(string[] args)
         {
+            PLCLinker pl = new PLCLinker();
+            Random rnd = new Random();
+            Task t = Task.Factory.StartNew(() =>
+            {
+                while (true)
+                {
+                    //pl.pe = new ParkEndPoint()
+                    //{
+                    //    endPointNo = 1,
+                    //    licCode = "011" + rnd.Next(10000, 99999).ToString(),
+                    //    //licCode = "",
+                    //    unregistered = rnd.Next(1, 3) > 1 ? true : false,
+                    //    completed = rnd.Next(1, 3) > 1 ? true : false,
+                    //    serialNo = rnd.Next(10000000, 99999999).ToString()
+                    //    //serialNo = ""
+                    //};
+                    //pl.WriteToPLC(pl.pe);
+                    //pl.ReadFromPLC();
+
+                    TerminalStru terminal1 = new TerminalStru();
+                    terminal1 = (TerminalStru)pl.ReadStruFromPLC(terminal1, 27, 0);
+                    Console.WriteLine(terminal1.ToString());
+                    Thread.Sleep(200);
+                    terminal1.terminalStatus = (short)rnd.Next(1, 6);
+                    terminal1.licenseCode = rnd.Next(3000, 9999);//"01A" + (rnd.Next(10000, 99999)).ToString();
+                    terminal1.receiptNum = rnd.Next(3000, 9999);
+                    terminal1.licVerification = (short)rnd.Next(1, 555);
+                    List<byte> bList = Struct.ToBytes(terminal1).ToList();
+                    pl.WriteMultipleBytes(27, bList, 0);
+                    //terminal1.userType = (short)rnd.Next(0, 4);
+                    //pl.WriteStruToPLC(terminal1, 27, 0);
+
+                    ////203 chars
+                    //string str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccc";
+                    ////pl.WriteMultipleBytes(1, (Encoding.ASCII.GetBytes(str)).ToList());
+                    //byte[] bytes = pl.ReadMultipleBytes(27, 50).ToArray();
+                    //string str2 = Encoding.ASCII.GetString(bytes);
+                    //Console.WriteLine(str2);
+                    //if (str == str2)
+                    //{
+                    //    Console.WriteLine("equals");
+                    //}
+                    //else
+                    //{
+                    //    Console.WriteLine("error, unequal");
+                    //}
+
+                    Thread.Sleep(2000);
+                }
+            });
+            t.Wait();
         }
     }
 }

+ 108 - 0
PLCLinker/PLCLinker/entity.cs

@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PLCLinker
+{
+    class entity
+    {
+    }
+
+    struct TerminalStru
+    {
+        public short terminalID;
+        //public bool terminalStatus;
+        //public bool btnStatus;
+        public short terminalStatus;
+        public short btnStatus;
+        public int licenseCode;
+        public int receiptNum;
+        //public bool paymentStatus;
+        //public bool licVerification;
+        public short paymentStatus;
+        public short licVerification;
+        public short parkingFee;
+        public short userType;
+        //public bool groundStatus;
+        //public bool completed;
+        public short groundStatus;
+        public short completed;
+
+        public string ToString()
+        {
+            return "[" + terminalID + "," + terminalStatus + "," + btnStatus + "," + licenseCode + "," + receiptNum + "," + paymentStatus
+                + "," + licVerification + "," + parkingFee + "," + userType + "," + groundStatus + "]";
+            //return "[" + terminalID + "," + terminalStatus + "," + btnStatus + "," + licenseCode + "," + receiptNum + "]";
+            //return "[" + paymentStatus + "," + licVerification + "," + parkingFee + "," + userType + "]";
+        }
+    }
+
+    struct TestStru
+    {
+        public bool test1;
+        public ushort test2;
+        public ushort test3;
+        public string ToString()
+        {
+            return "[" + test1.ToString() + "," + string.Format("{0:X000}", test2) + "," + string.Format("{0:X000}", test3) + "]";
+        }
+    }
+    struct ParkStru
+    {
+        public int endPointNo;
+        public string licCode;
+        public bool unregistered;
+        public bool completed;
+        public string serialNo;
+    }
+    struct FetchStru
+    {
+        public int endPointNo;
+        public string serialNo;
+        public int paymentStatus;
+        public uint fee;
+        public int userType;
+        public bool completed;
+    }
+
+    class ParkEndPoint
+    {
+        public int endPointNo;
+        public string licCode;
+        public bool unregistered;
+        public bool completed;
+        public string serialNo;
+        public const int bytesCount = 200;
+        public List<int> indices;
+        public ParkEndPoint()
+        {
+            endPointNo = 0;
+            licCode = "";
+            unregistered = true;
+            completed = false;
+            serialNo = "";
+            indices = new List<int>();
+            indices.Add(4);
+            indices.Add(8);
+            indices.Add(1);
+            indices.Add(1);
+            indices.Add(8);
+        }
+        public string ToString()
+        {
+            return "[" + endPointNo + "," + licCode + "," + unregistered.ToString() + "," + completed.ToString() + "," + serialNo + "]";
+        }
+    }
+
+    class FetchEndPoint
+    {
+        int endPointNo;
+        string serialNo;
+        int paymentStatus;
+        uint fee;
+        int userType;
+        bool completed;
+    }
+}