first commit

This commit is contained in:
2025-03-07 09:06:46 +08:00
parent 4a54a0b9f5
commit f6f5517d40
121 changed files with 5388 additions and 0 deletions

View File

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="HslCommunication">
<HintPath>..\libs\HslCommunication.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

81
DH.XinJEPLC/PLCBase.cs Normal file
View File

@ -0,0 +1,81 @@
using System.IO.Ports;
using DH.Commons.Enums;
using HslCommunication;
namespace DH.Devices.PLC
{
public class PLCBase
{
/// <summary>
/// 连接状态
/// </summary>
public bool connected = false;
/// <summary>
/// 类型
/// </summary>
public EnumPLCType PLCType=EnumPLCType.XD_网口;
/// <summary>
/// 串口号
/// </summary>
public string portName="COM1";
/// <summary>
/// 波特率
/// </summary>
public int baudRate = 9600;
/// <summary>
/// 数据位
/// </summary>
public int dataBit = 8;
/// <summary>
/// 停止位
/// </summary>
public StopBits stopBit = (StopBits)Enum.Parse(typeof(StopBits), "One");
/// <summary>
/// 奇偶效验位
/// </summary>
public Parity parity = (Parity)Enum.Parse(typeof(Parity), "None");
/// <summary>
/// IP地址
/// </summary>
public string IP = "192.168.6.6";
/// <summary>
/// 端口号
/// </summary>
public int Port = 502;
/// <summary>
/// 初始化
/// </summary>
/// <returns></returns>
public virtual bool PLCConnect() { return false; }
public virtual bool PLCDisConnect() { return false; }
public virtual ushort ReadShort(string address) { return 0; }
public virtual int ReadInt(string address) { return 0; }
public virtual float ReadFloat(string address) { return 0; }
public virtual bool ReadBool(string address) { return false; }
public virtual bool WriteShort(string address, short value, bool waitForReply = true) { return false; }
public virtual bool WriteInt(string address, int value, bool waitForReply = true) { return false; }
public virtual bool WriteDInt(string address, int value, bool waitForReply = true) { return false; }
public virtual bool WriteFloat(string address, float value, bool waitForReply = true) { return false; }
public virtual bool WriteBool(string address, bool value, bool waitForReply = true) { return false; }
}
}

View File

@ -0,0 +1,540 @@
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.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;
OperateResult ret = TcpNet.ConnectServer();
if (ret.IsSuccess)
{
connected = true;
MonitorPieces();
TurntableOpen(18000,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()
{
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);
}
}
}