|
@@ -1,9 +1,11 @@
|
|
using S7.Net;
|
|
using S7.Net;
|
|
|
|
+using S7.Net.Types;
|
|
using System;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Threading.Tasks;
|
|
|
|
+using System.Timers;
|
|
|
|
|
|
namespace PLCLinker
|
|
namespace PLCLinker
|
|
{
|
|
{
|
|
@@ -21,17 +23,213 @@ namespace PLCLinker
|
|
|
|
|
|
class PLCLinker : IEquipments
|
|
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;
|
|
Plc plc = null;
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 停车终端结构体
|
|
|
|
+ /// </summary>
|
|
|
|
+ public ParkEndPoint pe;
|
|
|
|
+ public TestStru ts;
|
|
|
|
+ public List<byte> resultBytes;
|
|
|
|
+
|
|
public PLCLinker()
|
|
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();
|
|
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()
|
|
public AbstractMessage GetMessage()
|