Przeglądaj źródła

读写PLC终端与车位数据库测试通过

yc_t 6 lat temu
rodzic
commit
29adb12314

+ 379 - 156
PLCLinker/PLCLinker/PLCLinker.cs

@@ -3,94 +3,189 @@ using S7.Net.Types;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using System.Timers;
 
 namespace PLCLinker
 {
-    public class AbstractMessage
+    interface PLCS7
     {
-
+        void PLCConnect(CpuType cpu, string ip, short rack, short slot);
+        void PLCDisconnect();
+        bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami);
+        List<object> ReadFromPLC(PLCDataType whichToRead, int index);
     }
-    interface IEquipments
+    public enum PLCDataType
     {
-        void Start();
-        void Stop();
-        void SetMessage(AbstractMessage abstractMsg);
-        AbstractMessage GetMessage();
+        terminal,
+        central,
+        parkingSpace
     }
-
-    class PLCLinker : IEquipments
+    public abstract class AbstractPLCLinker : PLCS7
     {
+        protected const int mainBlockOffset = 18;
+        protected const int parkingSpaceOffset = 18;
         /// <summary>
         /// PLC 连接状态flag
         /// </summary>
-        private bool isConnected = false;
+        protected bool isConnected = false;
         /// <summary>
         /// 系统关闭flag
         /// </summary>
-        private bool isClosing = false;
-        ///// <summary>
-        ///// 从plc获得结构化数据
-        ///// </summary>
-        //private PLCMessage plcMsg;
+        protected bool isClosing = false;
         /// <summary>
-        /// 定时器
+        /// plc中cpu类型
         /// </summary>
-        System.Timers.Timer timer;
-        ///// <summary>
-        ///// 读PLC初始地址
-        ///// </summary>
-        //private int startAddr = 0;
-        ///// <summary>
-        ///// 读PLC地址长度
-        ///// </summary>
-        //private int addrLength = 110;
+        protected CpuType cpu;
         /// <summary>
         /// PLC的IP地址
         /// </summary>
-        private string ipString;
+        protected string ip;
         /// <summary>
         /// PLC的端口号
         /// </summary>
-        private Int16 rack;
+        protected Int16 rack;
         /// <summary>
         /// 工作站号
         /// </summary>
-        private Int16 slot;
+        protected Int16 slot;
         /// <summary>
-        /// PLC刷新频率,来自于配置文件
+        /// 终端DB块iD
         /// </summary>
-        private int PLC_refresh_interval;
+        protected int terminalDB;
         /// <summary>
-        /// 无法获取配置文件时使用的PLC刷新频率
+        /// 中心DB块iD
         /// </summary>
-        private const short PLC_TIME_SCALE = 200;
+        protected int centralDB;
         /// <summary>
-        /// PLC S7连接对象
+        /// 车位DB块ID
+        /// </summary>
+        protected int parkingSpaceDB;
+        /// <summary>
+        /// 终端个数
         /// </summary>
-        Plc plc = null;
+        protected int terminalCount;
         /// <summary>
-        /// 停车终端结构体
+        /// 停车位个数
         /// </summary>
-        public ParkEndPoint pe;
-        public TestStru ts;
-        public List<byte> resultBytes;
+        protected int parkingSpaceCount;
+        /// <summary>
+        /// PLC S7连接对象
+        /// </summary>
+        protected static Plc plc = null;
 
-        public PLCLinker()
+        public void PLCConnect(CpuType cpu, string ip, short rack, short slot)
         {
             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"); }
             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)
+        public void PLCDisconnect()
+        {
+            if (plc != null)
+            {
+                plc.Close();
+            }
+        }
+
+        public abstract List<object> ReadFromPLC(PLCDataType whichToRead, int index);
+
+        public abstract bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami);
+    }
+
+    public class PLCLinker : AbstractPLCLinker
+    {
+        ///// <summary>
+        ///// 从plc获得结构化数据
+        ///// </summary>
+        //private PLCMessage plcMsg;
+
+        /// <summary>
+        /// PLC刷新频率,来自于配置文件
+        /// </summary>
+        private int PLC_refresh_interval;
+        /// <summary>
+        /// 无法获取配置文件时使用的PLC刷新频率
+        /// </summary>
+        private const short PLC_TIME_SCALE = 200;
+        //************************************** 方法区 *************************************
+        public void test()
+        {
+            Random rnd = new Random();
+            Task t = Task.Factory.StartNew(() =>
+            {
+                while (true)
+                {
+                    TerminalStru terminal1 = new TerminalStru();
+                    terminal1 = (TerminalStru)ReadStruFromPLC(terminal1, 27, 0);
+                    Console.WriteLine(terminal1.ToString());
+                    Thread.Sleep(200);
+                    terminal1.terminalStatus = (short)rnd.Next(1, 6);
+                    terminal1.licenseCodeA = rnd.Next(3000, 9999);
+                    terminal1.receiptNum = rnd.Next(3000, 9999);
+                    terminal1.licVerification = (short)rnd.Next(1, 555);
+                    WriteStruToPLC(terminal1, 27, 0);
+                    //List<byte> bList = Struct.ToBytes(terminal1).ToList();
+                    //WriteMultipleBytes(27, bList, 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();
+        }
+        /// <summary>
+        /// PLCLinker构造函数
+        /// </summary>
+        /// <param name="cpu"></param>
+        /// <param name="ip"></param>
+        /// <param name="rack"></param>
+        /// <param name="slot"></param>
+        /// <param name="terminalDB"></param>
+        /// <param name="centralDB"></param>
+        /// <param name="parkingSpaceDB"></param>
+        public PLCLinker(CpuType cpu, string ip, short rack, short slot, int terminalDB, int centralDB, int parkingSpaceDB, int terminalCount, int parkingSpaceCount)
+        {
+            this.cpu = cpu;
+            this.ip = ip;
+            this.rack = rack;
+            this.slot = slot;
+            this.terminalDB = terminalDB;
+            this.centralDB = centralDB;
+            this.parkingSpaceDB = parkingSpaceDB;
+            this.terminalCount = terminalCount;
+            this.parkingSpaceCount = parkingSpaceCount;
+            PLCConnect(cpu, ip, rack, slot);
+        }
+        /// <summary>
+        /// 读取指定数据块中多个字节
+        /// </summary>
+        /// <param name="db"></param>
+        /// <param name="length"></param>
+        /// <param name="startAddr"></param>
+        /// <returns></returns>
+        private List<byte> ReadMultipleBytes(int db, int length, int startAddr = 0)
         {
             List<byte> resultBytes = new List<byte>();
             int index = startAddr;
@@ -98,161 +193,289 @@ namespace PLCLinker
             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;
+                try
+                {
+                    byte[] temp = plc.ReadBytes(DataType.DataBlock, db, index, maxToRead);
+                    if (temp == null)
+                        return new List<byte>();
+                    resultBytes.AddRange(temp);
+                    remains -= maxToRead;
+                    index += maxToRead;
+                }
+                catch { }
             }
             return resultBytes;
         }
-        public void WriteMultipleBytes(int db, List<byte> bytesToWrite, int startAddr = 0)
+        /// <summary>
+        /// 写入指定数据块中多个字节
+        /// </summary>
+        /// <param name="db"></param>
+        /// <param name="bytesToWrite"></param>
+        /// <param name="startAddr"></param>
+        /// <returns></returns>
+        private ErrorCode 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)
+            try
             {
-                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)
+                while (remains > 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());
+                    int maxToWrite = Math.Min(remains, 200);
+                    ErrorCode ec = plc.WriteBytes(DataType.DataBlock, db, index, bytesToWrite.GetRange(index, maxToWrite).ToArray());
+                    index += maxToWrite;
+                    remains -= maxToWrite;
+                    if (!ec.Equals(ErrorCode.NoError)) { return ec; }
                 }
             }
+            catch (Exception e) { Console.WriteLine(e.Message); }
+            return ErrorCode.NoError;
         }
-        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);
-        }
-
-        public object ReadStruFromPLC(object obj, int db, int startAddr = 0)
+        /// <summary>
+        /// 从PLC中读取结构体
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <param name="db"></param>
+        /// <param name="startAddr"></param>
+        /// <returns></returns>
+        private 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);
+                //returnedObj = plc.ReadStruct(structType, db, startAddr);
+                int numBytes = Struct.GetStructSize(structType);
+                var resultBytes = plc.ReadBytes(DataType.DataBlock, db, startAddr, numBytes);
+                returnedObj = Struct.FromBytes(structType, resultBytes);
                 if (returnedObj != null) { return returnedObj; }
             }
             catch (Exception e)
             {
                 Console.WriteLine(e.Message);
             }
-            return Activator.CreateInstance(structType);
+            return null;
             //Console.WriteLine(ts.ToString());
         }
-        public void WriteStruToPLC(object obj, int db, int startAddr = 0)
+        /// <summary>
+        /// 向PLC中写入结构体
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <param name="db"></param>
+        /// <param name="startAddr"></param>
+        private ErrorCode WriteStruToPLC(object obj, int db, int startAddr = 0)
         {
             Console.WriteLine("write to PLC");
             ErrorCode ec = ErrorCode.NoError;
             try
             {
-                ec = plc.WriteStruct(obj, 22, startAddr);
+                //ec = plc.WriteStruct(obj, 22, startAddr);
+                List<byte> bList = Struct.ToBytes(obj).ToList();
+                ec = WriteMultipleBytes(db, bList, startAddr);
             }
             catch (Exception e) { Console.WriteLine(ec.ToString() + "," + e.Message); }
+            return ec;
         }
-
-        public AbstractMessage GetMessage()
+        private short BytesRevert(short num)
         {
-            throw new NotImplementedException();
+            byte[] temp = BitConverter.GetBytes(num);
+            Array.Reverse(temp);
+            return BitConverter.ToInt16(temp, 0);
         }
-
-        public void SetMessage(AbstractMessage abstractMsg)
+        private int BytesRevert(int num)
         {
-            throw new NotImplementedException();
+            byte[] temp = BitConverter.GetBytes(num);
+            Array.Reverse(temp);
+            return BitConverter.ToInt32(temp, 0);
         }
 
-        public void Start()
+        /// <summary>
+        /// 读取PLC数据块
+        /// </summary>
+        /// <param name="whichToRead"></param>
+        /// <param name="index"></param>
+        /// <returns></returns>
+        public override List<object> ReadFromPLC(PLCDataType whichToRead, int index)
         {
-            throw new NotImplementedException();
+            //更新设备状态
+            isConnected = plc.IsConnected;
+            List<object> result = new List<object>();
+            if (isConnected)
+            {
+                switch (whichToRead)
+                {
+                    case PLCDataType.central:
+                        object obj = ReadStruFromPLC(new MainBlockStru(), centralDB);
+                        if (obj != null) { result.Add(obj); }
+                        break;
+                    case PLCDataType.terminal:
+                        TerminalStru ts = new TerminalStru();
+                        //index 在合理范围读取单一元素,否则全部读取
+                        if (index > 0 && index < terminalCount)
+                        {
+                            obj = ReadStruFromPLC(ts, terminalDB, Struct.GetStructSize(ts.GetType()) * (index - 1));
+                            if (obj != null) { result.Add(obj); }
+                        }
+                        else
+                        {
+                            for (int i = 0; i < terminalCount; i++)
+                            {
+                                obj = ReadStruFromPLC(ts, terminalDB, Struct.GetStructSize(ts.GetType()) * i);
+                                if (obj != null) { result.Add(obj); }
+                            }
+                        }
+                        break;
+                    case PLCDataType.parkingSpace:
+                        ParkingSpaceStru pss = new ParkingSpaceStru();
+                        //index 在合理范围读取单一元素,否则全部读取
+                        if (index > 0 && index < parkingSpaceCount)
+                        {
+                            obj = ReadStruFromPLC(pss, parkingSpaceDB, Struct.GetStructSize(pss.GetType()) * (index - 1));
+                            if (obj != null) { result.Add(obj); }
+                        }
+                        else
+                        {
+                            for (int i = 0; i < parkingSpaceCount; i++)
+                            {
+                                obj = ReadStruFromPLC(pss, parkingSpaceDB, Struct.GetStructSize(pss.GetType()) * i);
+                                if (obj != null) { result.Add(obj); }
+                            }
+                        }
+                        break;
+                    default:
+                        Console.WriteLine("wrong type");
+                        break;
+                }
+            }
+            return result;
         }
-
-        public void Stop()
+        /// <summary>
+        /// 写入PLC,其中可写入但不需写入字段请赋值为-1
+        /// </summary>
+        /// <param name="abstractPLCMsg"></param>
+        /// <param name="whoami"></param>
+        /// <returns></returns>
+        public override bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami)
         {
-            if (plc != null)
+            //更新设备状态
+            isConnected = plc.IsConnected;
+            if (abstractPLCMsg == null)
+                return false;
+            if (isConnected)
             {
-                plc.Close();
+                if (abstractPLCMsg.GetType().Equals(typeof(TerminalStru)))
+                {
+                    TerminalStru ts = (TerminalStru)abstractPLCMsg;
+                    if (ts.terminalID < 0 || ts.terminalID >= terminalCount) { return false; }
+                    int offset = 36 * (ts.terminalID - 1);
+                    if (whoami.Equals(PLCDataType.central))
+                    {
+                        if (ts.paymentStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 22 + offset, BitConverter.GetBytes(BytesRevert(ts.paymentStatus))); }
+                        if (ts.licVerification != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 24 + offset, BitConverter.GetBytes(BytesRevert(ts.licVerification))); }
+                        if (ts.parkingFee != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 26 + offset, BitConverter.GetBytes(BytesRevert(ts.parkingFee))); }
+                        if (ts.userType != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 28 + offset, BitConverter.GetBytes(BytesRevert(ts.userType))); }
+                    }
+                    else if (whoami.Equals(PLCDataType.terminal))
+                    {
+                        if (ts.btnStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 4 + offset, BitConverter.GetBytes(BytesRevert(ts.btnStatus))); }
+                        if (ts.terminalStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 4 + offset, BitConverter.GetBytes(BytesRevert(ts.terminalStatus))); }
+                        if (ts.licenseCodeA != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 6 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeA))); }
+                        if (ts.licenseCodeB != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 10 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeB))); }
+                        if (ts.licenseCodeC != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 14 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeC))); }
+                        if (ts.receiptNum != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 18 + offset, BitConverter.GetBytes(BytesRevert(ts.receiptNum))); }
+                    }
+                }
+                else if (abstractPLCMsg.GetType().Equals(typeof(MainBlockStru)) && whoami.Equals(PLCDataType.central))
+                {
+                    //只允许中控写入,且中控只允许写入号牌获取状态
+                    MainBlockStru mbs = (MainBlockStru)abstractPLCMsg;
+                    byte[] temp = BitConverter.GetBytes(BytesRevert(mbs.licenseReceived));
+                    ErrorCode ec = plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset, temp);
+                    if (!ec.Equals(ErrorCode.NoError)) { return false; }
+                }
+                else if (abstractPLCMsg.GetType().Equals(typeof(ParkingSpaceStru)) && whoami.Equals(PLCDataType.central))
+                {
+                    //只允许中控写入,中控只允许写车位状态
+                    ParkingSpaceStru pss = (ParkingSpaceStru)abstractPLCMsg;
+                    int offset = 24 * (pss.parkingSpace - 1) + parkingSpaceOffset;
+                    byte[] temp = BitConverter.GetBytes(BytesRevert(pss.spaceStatus));
+                    ErrorCode ec = plc.WriteBytes(DataType.DataBlock, parkingSpaceDB, offset, temp);
+                    if (!ec.Equals(ErrorCode.NoError)) { return false; }
+                }
+                else { return false; }
             }
+            else { return false; }
+            return true;
         }
+
+        //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);
+        //    }
+        //}
+
+
+
     }
 }

+ 43 - 40
PLCLinker/PLCLinker/Program.cs

@@ -1,4 +1,5 @@
-using S7.Net.Types;
+using S7.Net;
+using S7.Net.Types;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -12,54 +13,56 @@ namespace PLCLinker
     {
         static void Main(string[] args)
         {
-            PLCLinker pl = new PLCLinker();
+            PLCLinker pl = new PLCLinker(CpuType.S71500, "192.168.0.1", 0, 1, 18, 22, 20, 6, 200);
             Random rnd = new Random();
             Task t = Task.Factory.StartNew(() =>
             {
                 while (true)
                 {
-                    //pl.pe = new ParkEndPoint()
+                    ////读终端块数据
+                    //List<object> tList = pl.ReadFromPLC(PLCDataType.terminal, 0);
+                    //foreach (var term in tList)
                     //{
-                    //    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");
+                    //    Console.WriteLine(((TerminalStru)term).ToString());
                     //}
-                    //else
+                    ////模拟中控与终端写数据
+                    //TerminalStru tsCentral = new TerminalStru
                     //{
-                    //    Console.WriteLine("error, unequal");
-                    //}
+                    //    terminalID = 1,
+                    //    paymentStatus = (short)rnd.Next(100,999),
+                    //    licVerification = -1,
+                    //    parkingFee = (short)rnd.Next(100, 999),
+                    //    userType = (short)rnd.Next(100, 999)
+                    //};
+                    //TerminalStru tsTerminal = new TerminalStru
+                    //{
+                    //    terminalID = 1,
+                    //    terminalStatus = (short)rnd.Next(100, 999),
+                    //    btnStatus = 49,
+                    //    licenseCodeA = (short)rnd.Next(100, 999),
+                    //    licenseCodeB = -1,
+                    //    licenseCodeC = (short)rnd.Next(100, 999),
+                    //    receiptNum = (short)rnd.Next(100, 999)
+                    //};
+                    //pl.WriteToPLC(tsCentral, PLCDataType.central);
 
-                    Thread.Sleep(2000);
+                    //读车位表信息
+                    List<object> psList = pl.ReadFromPLC(PLCDataType.parkingSpace, 1);
+                    psList.AddRange(pl.ReadFromPLC(PLCDataType.parkingSpace, 2));
+                    foreach (var ps in psList)
+                    {
+                        Console.WriteLine(((ParkingSpaceStru)ps).ToString());
+                    }
+                    //写入车位状态信息
+                    ParkingSpaceStru pss = new ParkingSpaceStru
+                    {
+                        parkingSpace = (short)rnd.Next(1, 3),
+                        receiptNum = 987654321,
+                        spaceStatus = (short)rnd.Next(0, 3)
+                    };
+                    pl.WriteToPLC(pss, PLCDataType.central);
+                    Console.WriteLine("写入状态值");
+                    Thread.Sleep(200);
                 }
             });
             t.Wait();

+ 71 - 57
PLCLinker/PLCLinker/entity.cs

@@ -10,32 +10,85 @@ namespace PLCLinker
     {
     }
 
+    /// <summary>
+    /// 终端数据块结构体
+    /// </summary>
     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 terminalStatus;//终端写入
+        public short btnStatus;//终端写入
+        public int licenseCodeA;//终端写入
+        public int licenseCodeB;//终端写入
+        public int licenseCodeC;//终端写入
+        public int receiptNum;//终端写入
+        public short paymentStatus;//中控写入,22
+        public short licVerification;//中控写入
+        public short parkingFee;//中控写入
+        public short userType;//中控写入
+        public short coordX;//PLC
+        public short coordY;//PLC
         public short groundStatus;
-        public short completed;
 
         public string ToString()
         {
-            return "[" + terminalID + "," + terminalStatus + "," + btnStatus + "," + licenseCode + "," + receiptNum + "," + paymentStatus
+            return "[" + terminalID + "," + terminalStatus + "," + btnStatus + "," + licenseCodeA + "," + licenseCodeB + "," + licenseCodeC + "," + receiptNum + "," + paymentStatus
                 + "," + licVerification + "," + parkingFee + "," + userType + "," + groundStatus + "]";
-            //return "[" + terminalID + "," + terminalStatus + "," + btnStatus + "," + licenseCode + "," + receiptNum + "]";
-            //return "[" + paymentStatus + "," + licVerification + "," + parkingFee + "," + userType + "]";
+        }
+    }
+
+    /// <summary>
+    /// 中控与PLC交互使用数据块的结构体
+    /// </summary>
+    struct MainBlockStru
+    {
+        public short terminalID;
+        public short numMachineLaunch;
+        public short sweepLaserLaunch;
+        public short wheelbaseLaserLaunch;
+        public short scram;
+        public short ready;
+        public short parkingRunning;
+        public short fetchingRunning;
+        public short sweepLaserStatus;
+        public short licenseReceived;//中控可写
+        public short localAutoMode;
+        public short remoteMode;
+        public short localManualMode;
+        public short processStopped;
+        public short groundAStatus;
+        public short groundBStatus;
+        public short groundCStatus;
+        public short arriveAAndOpen;
+        public short arriveBAndOpen;
+        public short arriveCAndOpen;
+        public short leaveAAndOpen;
+        public short leaveBAndOpen;
+        public short leaveCAndOpen;
+        public short processCompleted;
+    }
+
+    /// <summary>
+    /// 车位单元结构体
+    /// </summary>
+    struct ParkingSpaceStru
+    {
+        public short parkingSpace;
+        public short length;
+        public short width;
+        public short height;
+        public short floorNo;
+        public short coordX;
+        public short coordY;
+        public int receiptNum;
+        public short spaceStatus;
+        public short frontWheelbase;
+        public short rearWheelbase;
+
+        public override string ToString()
+        {
+            return "[" + parkingSpace + "," + length + "," + width + "," + height + "," + floorNo + "," + coordX + "," + coordY + "," + receiptNum
+                + "," + spaceStatus + "," + frontWheelbase + "," + rearWheelbase + "]";
         }
     }
 
@@ -66,43 +119,4 @@ namespace PLCLinker
         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;
-    }
 }