using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml.Linq; using DH.Commons.Base; using DH.Commons.Enums; using HslCommunication; using HslCommunication.Enthernet; using HslCommunication.Profinet.XINJE; namespace DH.Devices.PLC { public class XinJEPLCTcpNet : PLCBase { private static XinJEPLCTcpNet _instance; public static XinJEPLCTcpNet Instance { get { if (_instance == null) _instance = new XinJEPLCTcpNet(); return _instance; } } private XinJETcpNet TcpNet = new XinJETcpNet(); public override bool PLCConnect() { try { TcpNet.IpAddress = IP; TcpNet.Port = Port; TcpNet.ConnectTimeOut = 5000; TcpNet.ReceiveTimeOut = 10000; TcpNet.SleepTime = 0; TcpNet.AddressStartWithZero = true; TcpNet.IsStringReverse = false; TcpNet.DataFormat = HslCommunication.Core.DataFormat.ABCD; TcpNet.Station = 1; TcpNet.Series = XinJESeries.XD; PLCItem itemSpeed = PLCItemList.FirstOrDefault(u => u.Name == "转盘速度"); if(itemSpeed== null) { return false; } OperateResult ret = TcpNet.ConnectServer(); if (ret.IsSuccess) { Connected = true; MonitorPieces(); TurntableOpen(Convert.ToInt32(itemSpeed.Value) , true); return true; } else { return false; } } catch { return false; } } public override ushort ReadShort(string address) { try { // 读取Int变量 var result = TcpNet.ReadInt16(address); if (result.IsSuccess) { return (ushort)result.Content; } else { return 0; } } catch (Exception ex) { return 0; } } public override int ReadInt(string address) { try { // 读取Int变量 var result = TcpNet.ReadInt32(address); if (result.IsSuccess) { return result.Content; } else { return -1; } } catch (Exception ex) { return -1; } } public override float ReadFloat(string address) { try { // 读取Float变量 var result = TcpNet.ReadFloat(address); if (result.IsSuccess) { return result.Content; } else { return -1; } } catch (Exception ex) { return -1; } } public override bool ReadBool(string address) { try { // 读取Bool变量 var result = TcpNet.ReadBool(address); if (result.IsSuccess) { return result.Content; } else { return false; // 或者可以考虑返回其他的错误标识符 } } catch (Exception ex) { return false; // 或者返回其他的错误标识符 } } /// /// 写单独地址 short 值 /// /// 地址 /// 要写入的 int 值 /// 是否等待回复 public override bool WriteShort(string address, short writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { return false; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); sw.Start(); // 启动计时 do { try { var result = TcpNet.Write(address, (short)writeValue); if (result.IsSuccess) { sw.Stop(); //LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms"); return true; } } catch (Exception ex) { repeatTime--; if (repeatTime <= 0) { return false; } } } while (repeatTime > 0); sw.Stop(); return false; } /// /// 写单独地址 int 值 /// /// 地址 /// 要写入的 int 值 /// 是否等待回复 public override bool WriteInt(string address, int writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { return false; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); sw.Start(); // 启动计时 do { try { var result = TcpNet.Write(address, writeValue); if (result.IsSuccess) { sw.Stop(); return true; } } catch (Exception ex) { repeatTime--; if (repeatTime <= 0) { return false; } } } while (repeatTime > 0); sw.Stop(); return false; } /// /// 写单独地址 Dint 值 /// /// 地址 /// 要写入的 Dint 值 /// 是否等待回复 public override bool WriteDInt(string address, int writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { return false; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); sw.Start(); // 启动计时 do { try { string result = Regex.Replace(address, @"\D", ""); int r = Convert.ToInt32(result) + 1; string address1 = "HD" + r.ToString(); short high = (short)(writeValue >> 16); // 高 16 位 short low = (short)(writeValue & 0xFFFF); // 低 16 位 TcpNet.Write(address1, high); Thread.Sleep(10); var res = TcpNet.Write(address, low); if (res.IsSuccess) { sw.Stop(); return true; } } catch (Exception ex) { repeatTime--; if (repeatTime <= 0) { return false; } } } while (repeatTime > 0); sw.Stop(); return false; } /// /// 写单独地址 float 值 /// /// 地址 /// 要写入的 float 值 /// 是否等待回复 public override bool WriteFloat(string address, float writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { return false; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); sw.Start(); // 启动计时 do { try { var result = TcpNet.Write(address, writeValue); if (result.IsSuccess) { sw.Stop(); return true; } } catch (Exception ex) { repeatTime--; if (repeatTime <= 0) { return false; } } } while (repeatTime > 0); sw.Stop(); return false; } /// /// 写单独地址 bool 值 /// /// 地址 /// 要写入的 bool 值 /// 是否等待回复 public override bool WriteBool(string address, bool writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { return false; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); sw.Start(); // 启动计时 do { try { var result = TcpNet.Write(address, writeValue); if (result.IsSuccess) { sw.Stop(); return true; } } catch (Exception ex) { repeatTime--; if (repeatTime <= 0) { return false; } } } while (repeatTime > 0); sw.Stop(); Thread.Sleep(10); return false; } public override bool PLCDisConnect() { if (Connected) { TurntableStop(); var res = TcpNet.ConnectClose(); if (res.IsSuccess) { Connected = false; return true; } return false; } return false; } private void MonitorPieces() { ThreadStart ts = new ThreadStart(MonitorPiecesImpl); Thread th = new Thread(ts); th.Priority = ThreadPriority.AboveNormal; th.IsBackground = false; th.Start(); } public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning); private Dictionary piecesCountDic = new Dictionary(); private uint piecesCount = 0; /// /// int,int 轴号 捕获位置 /// public event Action OnNewPieces; public void NewPieces(int axisIndex, uint pieceNumber) { _taskFactory.StartNew(() => { Thread.CurrentThread.Priority = ThreadPriority.Highest; OnNewPieces?.Invoke(axisIndex, pieceNumber); }); } /// /// 入料监听 /// /// private void MonitorPiecesImpl() { PLCItem pLCItem= PLCItemList.FirstOrDefault(u => u.Name == "产品计数"); if (pLCItem == null) return; DateTime startTime = DateTime.Now; DateTime endTime = startTime; TimeSpan timeSpan = endTime - startTime; Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; //while (CurrentState != DeviceState.DSClose && CurrentState != DeviceState.DSExcept && CurrentState != DeviceState.DSUninit) while (Connected) { Stopwatch sw = new Stopwatch(); uint tmpPieceNumber = 0; sw.Start(); var ret = TcpNet.ReadUInt16("D1016"); sw.Stop(); if (ret.IsSuccess) { tmpPieceNumber = ret.Content; } if (ret.IsSuccess && ret.Content > piecesCount) { sw.Start(); // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 板卡{station}产品入列触发{tmpPieceNumber}"); //LogAsync(DateTime.Now, LogLevel.Information, $"转盘{0}产品入列 {piecesCountDic[0]} size:{sum}"); if (tmpPieceNumber != piecesCount + 1) { //LogAsync(DateTime.Now, LogLevel.Information, $"入列触发丢失\t{tmpPieceNumber}"); // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}\t板卡{station}产品入列触发丢失,{piecesCountDic[station]}\t{tmpPieceNumber}"); } piecesCount = tmpPieceNumber; //NewPieces(ai, piecesCountDic[station]); NewPieces(1, piecesCount); sw.Stop(); startTime = DateTime.Now; //if (idalarm) //{ // idalarm = false; // AlarmVibration(false); //} } Thread.Sleep(1); } } /// /// 转盘开启操作 /// public void TurntableOpen(int speed, bool Direction) { WriteBool("M122", true); Thread.Sleep(10); WriteBool("M10", false); Thread.Sleep(10); //速度 TcpNet.Write("HD10", (ushort)speed); Thread.Sleep(10); //方向 WriteBool("M1", Direction); Thread.Sleep(10); //使能 WriteBool("M2", true); Thread.Sleep(10); //启动 WriteBool("M0", true); Thread.Sleep(10); // _mainMotion.CurrentState = DeviceState.DSOpen; piecesCount = 0; } /// /// 转盘停止操作 /// public void TurntableStop() { WriteBool("M122", true); Thread.Sleep(50); WriteBool("M0", false); Thread.Sleep(50); WriteBool("M2", false); Thread.Sleep(50); WriteBool("M50", false); piecesCount = 0; } /// /// 计数清零 /// public void CountToZero() { WriteBool("M120", true); } } }