DHDHSoftware/DH.Devices.PLC/XinJEPLCTcpNet.cs
2025-03-24 15:21:16 +08:00

554 lines
16 KiB
C#

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; // 或者返回其他的错误标识符
}
}
/// <summary>
/// 写单独地址 short 值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue">要写入的 int 值</param>
/// <param name="waitForReply">是否等待回复</param>
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;
}
/// <summary>
/// 写单独地址 int 值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue">要写入的 int 值</param>
/// <param name="waitForReply">是否等待回复</param>
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;
}
/// <summary>
/// 写单独地址 Dint 值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue">要写入的 Dint 值</param>
/// <param name="waitForReply">是否等待回复</param>
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;
}
/// <summary>
/// 写单独地址 float 值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue">要写入的 float 值</param>
/// <param name="waitForReply">是否等待回复</param>
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;
}
/// <summary>
/// 写单独地址 bool 值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue">要写入的 bool 值</param>
/// <param name="waitForReply">是否等待回复</param>
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<ushort, uint> piecesCountDic = new Dictionary<ushort, uint>();
private uint piecesCount = 0;
/// <summary>
/// int,int 轴号 捕获位置
/// </summary>
public event Action<int, uint> OnNewPieces;
public void NewPieces(int axisIndex, uint pieceNumber)
{
_taskFactory.StartNew(() =>
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
OnNewPieces?.Invoke(axisIndex, pieceNumber);
});
}
/// <summary>
/// 入料监听
/// </summary>
/// <param name="axisIndex"></param>
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);
}
}
/// <summary>
/// 转盘开启操作
/// </summary>
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;
}
/// <summary>
/// 转盘停止操作
/// </summary>
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;
}
/// <summary>
/// 计数清零
/// </summary>
public void CountToZero()
{
WriteBool("M120", true);
}
}
}