Merge branch 'KM' of https://gitea.star-rising.cn/xiaohuimin/DHDHSoftware into KM
This commit is contained in:
commit
77b75050b2
@ -1,117 +1,169 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using Newtonsoft.Json;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace DH.Commons.Helper
|
namespace DH.Commons.Helper
|
||||||
{
|
{
|
||||||
public static class SchemeHelper
|
public static class SchemeHelper
|
||||||
{
|
{
|
||||||
private const string SchemesKey = "Schemes";
|
private const string DefaultSchemeName = "默认方案";
|
||||||
private const string CurrentSchemeKey = "CurrentScheme";
|
private static readonly string ConfigFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schemes.json");
|
||||||
private const char Separator = '|';
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方案配置数据结构
|
||||||
|
/// </summary>
|
||||||
|
private class SchemeConfig
|
||||||
|
{
|
||||||
|
public List<string> Schemes { get; set; } = new List<string>();
|
||||||
|
public string CurrentScheme { get; set; } = DefaultSchemeName;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化配置(首次运行时调用)
|
/// 初始化配置(首次运行时调用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
// 如果Schemes不存在,创建空键
|
if (!File.Exists(ConfigFilePath))
|
||||||
if (!SystemConfigHelper.KeyExists(SchemesKey))
|
|
||||||
{
|
{
|
||||||
SystemConfigHelper.SetValue(SchemesKey, "");
|
var defaultConfig = new SchemeConfig
|
||||||
}
|
{
|
||||||
|
Schemes = new List<string> { DefaultSchemeName },
|
||||||
// 如果CurrentScheme不存在,创建空键
|
CurrentScheme = DefaultSchemeName
|
||||||
if (!SystemConfigHelper.KeyExists(CurrentSchemeKey))
|
};
|
||||||
{
|
SaveConfig(defaultConfig);
|
||||||
SystemConfigHelper.SetValue(CurrentSchemeKey, "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取所有方案(自动处理空值)
|
/// 获取所有方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<string> GetAllSchemes()
|
public static List<string> GetAllSchemes()
|
||||||
{
|
{
|
||||||
var schemeString = SystemConfigHelper.GetValue(SchemesKey, "");
|
var config = LoadConfig();
|
||||||
return string.IsNullOrEmpty(schemeString)
|
return config.Schemes ?? new List<string>();
|
||||||
? new List<string>()
|
|
||||||
: new List<string>(schemeString.Split(Separator));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加新方案(自动初始化处理)
|
/// 添加新方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void AddScheme(string schemeName)
|
public static void AddScheme(string schemeName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(schemeName))
|
if (string.IsNullOrWhiteSpace(schemeName))
|
||||||
throw new ArgumentException("方案名称无效");
|
throw new ArgumentException("方案名称无效");
|
||||||
|
|
||||||
var schemes = GetAllSchemes();
|
var config = LoadConfig();
|
||||||
|
|
||||||
if (schemes.Contains(schemeName))
|
if (config.Schemes.Contains(schemeName))
|
||||||
throw new InvalidOperationException($"方案 {schemeName} 已存在");
|
throw new InvalidOperationException($"方案 {schemeName} 已存在");
|
||||||
|
|
||||||
schemes.Add(schemeName);
|
config.Schemes.Add(schemeName);
|
||||||
SaveSchemes(schemes);
|
SaveConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置当前方案(空值安全处理)
|
/// 设置当前方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetCurrentScheme(string schemeName)
|
public static void SetCurrentScheme(string schemeName)
|
||||||
{
|
{
|
||||||
var schemes = GetAllSchemes();
|
var config = LoadConfig();
|
||||||
|
|
||||||
if (!schemes.Contains(schemeName))
|
if (!config.Schemes.Contains(schemeName))
|
||||||
throw new KeyNotFoundException($"方案 {schemeName} 不存在");
|
throw new KeyNotFoundException($"方案 {schemeName} 不存在");
|
||||||
|
|
||||||
SystemConfigHelper.SetValue(CurrentSchemeKey, schemeName);
|
config.CurrentScheme = schemeName;
|
||||||
|
SaveConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前方案(默认值处理)
|
/// 获取当前方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string GetCurrentScheme()
|
public static string GetCurrentScheme()
|
||||||
{
|
{
|
||||||
var current = SystemConfigHelper.GetValue(CurrentSchemeKey, "");
|
var config = LoadConfig();
|
||||||
return !string.IsNullOrEmpty(current) ? current : "默认方案";
|
return !string.IsNullOrEmpty(config.CurrentScheme)
|
||||||
|
? config.CurrentScheme
|
||||||
|
: DefaultSchemeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SaveSchemes(List<string> schemes)
|
|
||||||
{
|
|
||||||
var schemeString = schemes.Count > 0
|
|
||||||
? string.Join(Separator.ToString(), schemes)
|
|
||||||
: "";
|
|
||||||
SystemConfigHelper.SetValue(SchemesKey, schemeString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除指定方案(自动同步当前方案状态)
|
/// 删除指定方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="schemeName">要删除的方案名称</param>
|
|
||||||
/// <exception cref="ArgumentException">当方案名称为空时抛出</exception>
|
|
||||||
/// <exception cref="KeyNotFoundException">当方案不存在时抛出</exception>
|
|
||||||
public static void DeleteScheme(string schemeName)
|
public static void DeleteScheme(string schemeName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(schemeName))
|
if (string.IsNullOrWhiteSpace(schemeName))
|
||||||
throw new ArgumentException("方案名称无效");
|
throw new ArgumentException("方案名称无效");
|
||||||
|
|
||||||
var schemes = GetAllSchemes();
|
var config = LoadConfig();
|
||||||
|
|
||||||
if (!schemes.Contains(schemeName))
|
if (!config.Schemes.Contains(schemeName))
|
||||||
throw new KeyNotFoundException($"方案 {schemeName} 不存在");
|
throw new KeyNotFoundException($"方案 {schemeName} 不存在");
|
||||||
|
|
||||||
// 删除前检查是否是当前方案
|
// 如果是当前方案,需要先切换
|
||||||
bool isCurrent = GetCurrentScheme() == schemeName;
|
if (config.CurrentScheme == schemeName)
|
||||||
|
{
|
||||||
|
var otherScheme = config.Schemes.FirstOrDefault(s => s != schemeName);
|
||||||
|
if (otherScheme != null)
|
||||||
|
{
|
||||||
|
config.CurrentScheme = otherScheme;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.CurrentScheme = DefaultSchemeName;
|
||||||
|
if (!config.Schemes.Contains(DefaultSchemeName))
|
||||||
|
{
|
||||||
|
config.Schemes.Add(DefaultSchemeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 执行删除操作
|
config.Schemes.Remove(schemeName);
|
||||||
schemes.Remove(schemeName);
|
SaveConfig(config);
|
||||||
SaveSchemes(schemes);
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载配置文件
|
||||||
|
/// </summary>
|
||||||
|
private static SchemeConfig LoadConfig()
|
||||||
|
{
|
||||||
|
if (!File.Exists(ConfigFilePath))
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(ConfigFilePath);
|
||||||
|
return JsonConvert.DeserializeObject<SchemeConfig>(json) ?? new SchemeConfig();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 如果读取失败,返回默认配置
|
||||||
|
return new SchemeConfig
|
||||||
|
{
|
||||||
|
Schemes = new List<string> { DefaultSchemeName },
|
||||||
|
CurrentScheme = DefaultSchemeName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存配置文件
|
||||||
|
/// </summary>
|
||||||
|
private static void SaveConfig(SchemeConfig config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||||
|
File.WriteAllText(ConfigFilePath, json);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 处理保存失败的情况
|
||||||
|
throw new InvalidOperationException("保存方案配置失败", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using DH.Commons.Base;
|
using DH.Commons.Base;
|
||||||
using DH.Commons.Enums;
|
using DH.Commons.Enums;
|
||||||
|
using DH.Commons.Helper;
|
||||||
using DH.Commons.Models;
|
using DH.Commons.Models;
|
||||||
using HslCommunication;
|
using HslCommunication;
|
||||||
using HslCommunication.Enthernet;
|
using HslCommunication.Enthernet;
|
||||||
@ -37,6 +38,8 @@ namespace DH.Devices.PLC
|
|||||||
public event Action<LogMsg> OnLog;
|
public event Action<LogMsg> OnLog;
|
||||||
private XinJETcpNet TcpNet = new XinJETcpNet();
|
private XinJETcpNet TcpNet = new XinJETcpNet();
|
||||||
|
|
||||||
|
private TaskFactory _taskFac = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
|
||||||
|
|
||||||
public override bool PLCConnect()
|
public override bool PLCConnect()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -82,7 +85,7 @@ namespace DH.Devices.PLC
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Connected = false;
|
Connected = false;
|
||||||
LogAsync(DateTime.Now, LogLevel.Error, $"{IP}:{Port}PLC连接失败!失败原因:{ex.ToString()}");
|
LogAsync(DateTime.Now, LogLevel.Error, $"{IP}:{Port}PLC连接失败!失败原因:{ex.ToString()}");
|
||||||
@ -182,7 +185,7 @@ namespace DH.Devices.PLC
|
|||||||
LogAsync(DateTime.Now, LogLevel.Error, $"PLC未连接,地址{address}");
|
LogAsync(DateTime.Now, LogLevel.Error, $"PLC未连接,地址{address}");
|
||||||
throw new Exception($"PLC未连接,地址{address}");
|
throw new Exception($"PLC未连接,地址{address}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -258,7 +261,8 @@ namespace DH.Devices.PLC
|
|||||||
public override bool ReadBool(string address)
|
public override bool ReadBool(string address)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{ if (Connected)
|
{
|
||||||
|
if (Connected)
|
||||||
{
|
{
|
||||||
// 读取Bool变量
|
// 读取Bool变量
|
||||||
var result = TcpNet.ReadBool(address);
|
var result = TcpNet.ReadBool(address);
|
||||||
@ -343,7 +347,7 @@ namespace DH.Devices.PLC
|
|||||||
|
|
||||||
public override bool WriteUInt16(string address, UInt16 writeValue, bool waitForReply = true)
|
public override bool WriteUInt16(string address, UInt16 writeValue, bool waitForReply = true)
|
||||||
{
|
{
|
||||||
if (Connected)
|
if (Connected)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(address))
|
if (string.IsNullOrEmpty(address))
|
||||||
{
|
{
|
||||||
@ -472,13 +476,13 @@ namespace DH.Devices.PLC
|
|||||||
{
|
{
|
||||||
throw new Exception($"PLC未连接,地址{address}");
|
throw new Exception($"PLC未连接,地址{address}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 写单独地址 float 值
|
/// 写单独地址 float 值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -534,7 +538,7 @@ namespace DH.Devices.PLC
|
|||||||
/// <param name="waitForReply">是否等待回复</param>
|
/// <param name="waitForReply">是否等待回复</param>
|
||||||
public override bool WriteBool(string address, bool writeValue, bool waitForReply = true)
|
public override bool WriteBool(string address, bool writeValue, bool waitForReply = true)
|
||||||
{
|
{
|
||||||
if(Connected)
|
if (Connected)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(address))
|
if (string.IsNullOrEmpty(address))
|
||||||
{
|
{
|
||||||
@ -570,17 +574,17 @@ namespace DH.Devices.PLC
|
|||||||
LogAsync(DateTime.Now, LogLevel.Error, $"PLC未连接,地址{address}");
|
LogAsync(DateTime.Now, LogLevel.Error, $"PLC未连接,地址{address}");
|
||||||
throw new Exception($"PLC未连接,地址{address}");
|
throw new Exception($"PLC未连接,地址{address}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool PLCDisConnect()
|
public override bool PLCDisConnect()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (Connected)
|
if (Connected)
|
||||||
{
|
{
|
||||||
|
|
||||||
var res = TcpNet.ConnectClose();
|
var res = TcpNet.ConnectClose();
|
||||||
if (res.IsSuccess)
|
if (res.IsSuccess)
|
||||||
{
|
{
|
||||||
@ -598,7 +602,7 @@ namespace DH.Devices.PLC
|
|||||||
|
|
||||||
private void MonitorPieces()
|
private void MonitorPieces()
|
||||||
{
|
{
|
||||||
|
|
||||||
ThreadStart ts = new ThreadStart(MonitorPiecesImpl);
|
ThreadStart ts = new ThreadStart(MonitorPiecesImpl);
|
||||||
Thread th = new Thread(ts);
|
Thread th = new Thread(ts);
|
||||||
th.Priority = ThreadPriority.AboveNormal;
|
th.Priority = ThreadPriority.AboveNormal;
|
||||||
@ -617,7 +621,9 @@ namespace DH.Devices.PLC
|
|||||||
/// int,int 轴号 捕获位置
|
/// int,int 轴号 捕获位置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<int, uint> OnNewPieces;
|
public event Action<int, uint> OnNewPieces;
|
||||||
|
private System.Threading.Timer timer;
|
||||||
|
private System.Threading.TimerCallback timerCallback;
|
||||||
|
|
||||||
|
|
||||||
public void NewPieces(int axisIndex, uint pieceNumber)
|
public void NewPieces(int axisIndex, uint pieceNumber)
|
||||||
{
|
{
|
||||||
@ -631,14 +637,47 @@ namespace DH.Devices.PLC
|
|||||||
public async Task HeartbeatAsync1()
|
public async Task HeartbeatAsync1()
|
||||||
{
|
{
|
||||||
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "心跳地址");
|
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "心跳地址");
|
||||||
|
#if false
|
||||||
|
|
||||||
|
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
|
||||||
|
if (pLCItem == null)
|
||||||
|
return;
|
||||||
while (Connected)
|
while (Connected)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
if (pLCItem == null)
|
{
|
||||||
return;
|
LogAsync(DateTime.Now, LogLevel.Information, $"心跳\t");
|
||||||
WriteBool(pLCItem.Address, true);
|
|
||||||
await Task.Delay(900); // 非阻塞,等待1秒
|
WriteBool(pLCItem.Address, true);
|
||||||
|
await Task.Delay(2000); // 非阻塞,等待1秒
|
||||||
|
}
|
||||||
|
catch (Exception ex) { }
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
timerCallback = (object? state) =>
|
||||||
|
{
|
||||||
|
timer.Change(2000, 2000);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
//WriteBool(pLCItem.Address, true);
|
||||||
|
WriteBool("M31", true);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Error, $"心跳:{ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
timer = new System.Threading.Timer(
|
||||||
|
timerCallback, null, 0, 2000);
|
||||||
|
|
||||||
|
timer.Change(2000, 2000);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 入料监听
|
/// 入料监听
|
||||||
@ -647,7 +686,7 @@ namespace DH.Devices.PLC
|
|||||||
private void MonitorPiecesImpl()
|
private void MonitorPiecesImpl()
|
||||||
{
|
{
|
||||||
|
|
||||||
PLCItem pLCItem= PLCItemList.FirstOrDefault(u => u.Name == "产品计数");
|
PLCItem pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "产品计数");
|
||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
return;
|
return;
|
||||||
string Count = pLCItem.Address;
|
string Count = pLCItem.Address;
|
||||||
@ -661,8 +700,8 @@ namespace DH.Devices.PLC
|
|||||||
Stopwatch sw = new Stopwatch();
|
Stopwatch sw = new Stopwatch();
|
||||||
uint tmpPieceNumber = 0;
|
uint tmpPieceNumber = 0;
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
||||||
// var ret = TcpNet.ReadUInt16("D1016");
|
// var ret = TcpNet.ReadUInt16("D1016");
|
||||||
var ret = TcpNet.ReadUInt32(Count);
|
var ret = TcpNet.ReadUInt32(Count);
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
@ -678,13 +717,13 @@ namespace DH.Devices.PLC
|
|||||||
//LogAsync(DateTime.Now, LogLevel.Information, $"转盘{0}产品入列 {piecesCountDic[0]} size:{sum}");
|
//LogAsync(DateTime.Now, LogLevel.Information, $"转盘{0}产品入列 {piecesCountDic[0]} size:{sum}");
|
||||||
if (tmpPieceNumber != piecesCount + 1)
|
if (tmpPieceNumber != piecesCount + 1)
|
||||||
{
|
{
|
||||||
LogAsync(DateTime.Now, LogLevel.Information, $"入列触发丢失\t{tmpPieceNumber}");
|
LogAsync(DateTime.Now, LogLevel.Information, $"入列触发丢失\t{tmpPieceNumber}");
|
||||||
// Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}\t板卡{station}产品入列触发丢失,{piecesCountDic[station]}\t{tmpPieceNumber}");
|
// Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}\t板卡{station}产品入列触发丢失,{piecesCountDic[station]}\t{tmpPieceNumber}");
|
||||||
|
|
||||||
}
|
}
|
||||||
piecesCount = tmpPieceNumber;
|
piecesCount = tmpPieceNumber;
|
||||||
//NewPieces(ai, piecesCountDic[station]);
|
//NewPieces(ai, piecesCountDic[station]);
|
||||||
NewPieces(1, piecesCount);
|
NewPieces(1, piecesCount);
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
startTime = DateTime.Now;
|
startTime = DateTime.Now;
|
||||||
//if (idalarm)
|
//if (idalarm)
|
||||||
@ -695,7 +734,7 @@ namespace DH.Devices.PLC
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,19 +742,19 @@ namespace DH.Devices.PLC
|
|||||||
{
|
{
|
||||||
//启用心跳
|
//启用心跳
|
||||||
OpenHeartbeat(true);
|
OpenHeartbeat(true);
|
||||||
// LogAsync(DateTime.Now, LogLevel.Information, $"启用心跳");
|
// LogAsync(DateTime.Now, LogLevel.Information, $"启用心跳");
|
||||||
//状态复位
|
//状态复位
|
||||||
StatusReset();
|
StatusReset();
|
||||||
//LogAsync(DateTime.Now, LogLevel.Information, $"状态复位");
|
//LogAsync(DateTime.Now, LogLevel.Information, $"状态复位");
|
||||||
//关闭定位
|
//关闭定位
|
||||||
VisionPos(false);
|
VisionPos(false);
|
||||||
// LogAsync(DateTime.Now, LogLevel.Information, $"关闭定位");
|
// LogAsync(DateTime.Now, LogLevel.Information, $"关闭定位");
|
||||||
//写入流程加载点位配置
|
//写入流程加载点位配置
|
||||||
InitProcessAction();
|
InitProcessAction();
|
||||||
//LogAsync(DateTime.Now, LogLevel.Information, $"写入流程加载点位配置");
|
//LogAsync(DateTime.Now, LogLevel.Information, $"写入流程加载点位配置");
|
||||||
//计数清零
|
//计数清零
|
||||||
CountToZero();
|
CountToZero();
|
||||||
// LogAsync(DateTime.Now, LogLevel.Information, $"计数清零");
|
// LogAsync(DateTime.Now, LogLevel.Information, $"计数清零");
|
||||||
//停止转盘
|
//停止转盘
|
||||||
TurnStart(false);
|
TurnStart(false);
|
||||||
//LogAsync(DateTime.Now, LogLevel.Information, $"停止转盘");
|
//LogAsync(DateTime.Now, LogLevel.Information, $"停止转盘");
|
||||||
@ -725,16 +764,18 @@ namespace DH.Devices.PLC
|
|||||||
//开启入料监听
|
//开启入料监听
|
||||||
MonitorPieces();
|
MonitorPieces();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void StartProcess()
|
public void StartProcess()
|
||||||
{
|
{
|
||||||
//状态复位
|
//状态复位
|
||||||
StatusReset();
|
StatusReset();
|
||||||
// LogAsync(DateTime.Now, LogLevel.Information, $"状态复位");
|
// LogAsync(DateTime.Now, LogLevel.Information, $"状态复位");
|
||||||
//关闭定位
|
//关闭定位
|
||||||
VisionPos(false);
|
VisionPos(false);
|
||||||
// LogAsync(DateTime.Now, LogLevel.Information, $"关闭定位");
|
// LogAsync(DateTime.Now, LogLevel.Information, $"关闭定位");
|
||||||
//写入流程启动点位配置
|
//写入流程启动点位配置
|
||||||
StartProcessAction();
|
StartProcessAction();
|
||||||
PLCItem? pLCItem = ConfigModel.GlobalList?
|
PLCItem? pLCItem = ConfigModel.GlobalList?
|
||||||
@ -743,7 +784,7 @@ namespace DH.Devices.PLC
|
|||||||
.Where(it => it.Name == "挡料电机回原点速度").FirstOrDefault();
|
.Where(it => it.Name == "挡料电机回原点速度").FirstOrDefault();
|
||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
{
|
{
|
||||||
throw new Exception( $"未找到挡料电机回原点速度地址,请检查该地址是否存在于点位表!");
|
throw new Exception($"未找到挡料电机回原点速度地址,请检查该地址是否存在于点位表!");
|
||||||
}
|
}
|
||||||
PLCItem? pLCItem1 = ConfigModel.GlobalList?
|
PLCItem? pLCItem1 = ConfigModel.GlobalList?
|
||||||
.FirstOrDefault()?
|
.FirstOrDefault()?
|
||||||
@ -792,17 +833,26 @@ namespace DH.Devices.PLC
|
|||||||
//转盘启动
|
//转盘启动
|
||||||
TurnStart(true);
|
TurnStart(true);
|
||||||
}
|
}
|
||||||
|
public void StopProcess()
|
||||||
|
{
|
||||||
|
StatusReset();
|
||||||
|
VisionPos(false);
|
||||||
|
CountToZero();
|
||||||
|
StopProcessAction();
|
||||||
|
TurnStart(false);
|
||||||
|
// LogAsync(DateTime.Now, LogLevel.Information, $"PLC断开连接");
|
||||||
|
}
|
||||||
public void CloseProcess()
|
public void CloseProcess()
|
||||||
{
|
{
|
||||||
StatusReset();
|
StatusReset();
|
||||||
VisionPos(false);
|
VisionPos(false);
|
||||||
CountToZero();
|
CountToZero();
|
||||||
TurnStart(false);
|
TurnStart(false);
|
||||||
TurnEnable(false);
|
TurnEnable(false);
|
||||||
|
StopProcessAction();
|
||||||
OpenHeartbeat(false);
|
OpenHeartbeat(false);
|
||||||
PLCDisConnect();
|
PLCDisConnect();
|
||||||
// LogAsync(DateTime.Now, LogLevel.Information, $"PLC断开连接");
|
// LogAsync(DateTime.Now, LogLevel.Information, $"PLC断开连接");
|
||||||
}
|
}
|
||||||
public void InitProcessAction() =>
|
public void InitProcessAction() =>
|
||||||
ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.InitProcessList?.ToList() ?? new List<PLCItem>());
|
ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.InitProcessList?.ToList() ?? new List<PLCItem>());
|
||||||
@ -875,7 +925,7 @@ namespace DH.Devices.PLC
|
|||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
return;
|
return;
|
||||||
WriteBool(pLCItem.Address, b);
|
WriteBool(pLCItem.Address, b);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -888,7 +938,7 @@ namespace DH.Devices.PLC
|
|||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
return;
|
return;
|
||||||
WriteUInt16(pLCItem.Address, (ushort)speed);
|
WriteUInt16(pLCItem.Address, (ushort)speed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -968,12 +1018,16 @@ namespace DH.Devices.PLC
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int timeout = 5000;
|
int timeout = 60000;
|
||||||
int elapsedTime = 0;
|
int elapsedTime = 0;
|
||||||
int checkInterval = 100;
|
int checkInterval = 100;
|
||||||
MotorToZero(false);
|
MotorToZero(false);
|
||||||
// 检查是否不在原点,如果不在,则回原点
|
Thread.Sleep(300);
|
||||||
|
|
||||||
|
MotorClockwise(false);
|
||||||
|
Thread.Sleep(300);
|
||||||
|
MotorCounterclockwise(false);
|
||||||
|
Thread.Sleep(300);
|
||||||
|
|
||||||
MotorSpeed(speed); // 速度
|
MotorSpeed(speed); // 速度
|
||||||
Thread.Sleep(300);
|
Thread.Sleep(300);
|
||||||
@ -984,22 +1038,34 @@ namespace DH.Devices.PLC
|
|||||||
|
|
||||||
|
|
||||||
// 等待回到原点
|
// 等待回到原点
|
||||||
while (!ReadMotorToZero())
|
while (true)
|
||||||
{
|
{
|
||||||
if (elapsedTime >= timeout)
|
if (elapsedTime >= timeout)
|
||||||
{
|
{
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Error, $"超时");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ReadMotorRealPos() == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
Thread.Sleep(checkInterval);
|
Thread.Sleep(checkInterval);
|
||||||
elapsedTime += checkInterval;
|
elapsedTime += checkInterval;
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
|
MotorToZero(false);
|
||||||
|
Thread.Sleep(200);
|
||||||
|
MotorClockwise(false);
|
||||||
|
Thread.Sleep(200);
|
||||||
|
MotorCounterclockwise(false);
|
||||||
// 无论是刚回到原点还是已经在原点,执行目标位置、速度和方向设置
|
// 无论是刚回到原点还是已经在原点,执行目标位置、速度和方向设置
|
||||||
MotorSpeed(speed);
|
// MotorSpeed(speed);
|
||||||
|
|
||||||
|
|
||||||
|
Thread.Sleep(300);
|
||||||
|
MotorPos(pos); // 目标位置
|
||||||
|
Thread.Sleep(300);
|
||||||
if (direction)
|
if (direction)
|
||||||
{
|
{
|
||||||
MotorClockwise(true); // 顺时针转动
|
MotorClockwise(true); // 顺时针转动
|
||||||
@ -1010,11 +1076,27 @@ namespace DH.Devices.PLC
|
|||||||
MotorCounterclockwise(true); // 逆时针转动
|
MotorCounterclockwise(true); // 逆时针转动
|
||||||
|
|
||||||
}
|
}
|
||||||
Thread.Sleep(30);
|
|
||||||
MotorPos(pos); // 目标位置
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
|
|
||||||
|
|
||||||
|
int timeout1 = 60000;
|
||||||
|
int elapsedTime1 = 0;
|
||||||
|
int checkInterval1 = 100;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (elapsedTime1 >= timeout1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadMotorRealPos() == pos)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.Sleep(checkInterval1);
|
||||||
|
elapsedTime1 += checkInterval1;
|
||||||
|
}
|
||||||
|
Thread.Sleep(1500);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1024,61 +1106,84 @@ namespace DH.Devices.PLC
|
|||||||
/// False: 逆时针
|
/// False: 逆时针
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="u"></param>
|
/// <param name="u"></param>
|
||||||
public void FeedingMotor( bool direction,int speed,int pos)
|
public void FeedingMotor(bool direction, int speed, int pos)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int timeout = 5000;
|
int timeout = 10000;
|
||||||
int elapsedTime = 0;
|
int elapsedTime = 0;
|
||||||
int checkInterval = 100;
|
int checkInterval = 100;
|
||||||
|
|
||||||
BarrierToZero(false);
|
BarrierToZero(false);
|
||||||
|
Thread.Sleep(300);
|
||||||
// 检查是否不在原点,如果不在,则回原点
|
// 检查是否不在原点,如果不在,则回原点
|
||||||
|
BarrierClockwise(false);
|
||||||
|
Thread.Sleep(300);
|
||||||
|
BarrierCounterclockwise(false);
|
||||||
|
Thread.Sleep(300);
|
||||||
BarrierToZeroSpeed(speed); // 速度
|
BarrierToZeroSpeed(speed); // 速度
|
||||||
Thread.Sleep(300);
|
Thread.Sleep(300);
|
||||||
// 发送回原点指令
|
// 发送回原点指令
|
||||||
BarrierToZero(true);
|
BarrierToZero(true);
|
||||||
Thread.Sleep(1000); // 给设备一些时间响应
|
Thread.Sleep(300); // 给设备一些时间响应
|
||||||
|
|
||||||
// 等待回到原点
|
// 等待回到原点
|
||||||
while (!ReadBarrierToZero())
|
while (true)
|
||||||
|
{
|
||||||
|
if (elapsedTime >= timeout)
|
||||||
{
|
{
|
||||||
if (elapsedTime >= timeout)
|
break;
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.Sleep(checkInterval);
|
|
||||||
elapsedTime += checkInterval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ReadBarrierRealPos() == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.Sleep(checkInterval);
|
||||||
|
elapsedTime += checkInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 无论是刚回到原点还是已经在原点,执行目标位置、速度和方向设置
|
// 无论是刚回到原点还是已经在原点,执行目标位置、速度和方向设置
|
||||||
BarrierSpeed(speed);
|
BarrierSpeed(speed);
|
||||||
|
Thread.Sleep(300);
|
||||||
|
|
||||||
|
|
||||||
if (direction)
|
if (direction)
|
||||||
{
|
{
|
||||||
BarrierClockwise(true); // 顺时针转动
|
BarrierClockwise(true); // 顺时针转动
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BarrierCounterclockwise(true); // 逆时针转动
|
BarrierCounterclockwise(true); // 逆时针转动
|
||||||
|
|
||||||
}
|
}
|
||||||
Thread.Sleep(30);
|
Thread.Sleep(300);
|
||||||
BarrierPos(pos); // 目标位置
|
BarrierPos(pos); // 目标位置
|
||||||
Thread.Sleep(2000);
|
Thread.Sleep(300);
|
||||||
|
int timeout1 = 10000;
|
||||||
|
int elapsedTime1 = 0;
|
||||||
|
int checkInterval1 = 100;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (elapsedTime1 >= timeout1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadBarrierRealPos() == pos)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.Sleep(checkInterval1);
|
||||||
|
elapsedTime1 += checkInterval1;
|
||||||
|
}
|
||||||
|
Thread.Sleep(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 转盘清料
|
/// 转盘清料
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1106,7 +1211,8 @@ namespace DH.Devices.PLC
|
|||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
//开启心跳
|
//开启心跳
|
||||||
Task.Run(async () => await HeartbeatAsync1());
|
//Task.Run(async () => await HeartbeatAsync1());
|
||||||
|
_taskFac.StartNew(async () => await HeartbeatAsync1());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,7 +1222,7 @@ namespace DH.Devices.PLC
|
|||||||
int Register = (int)((productNumber - 1) % 30);
|
int Register = (int)((productNumber - 1) % 30);
|
||||||
currentRegister = 411 + Register;
|
currentRegister = 411 + Register;
|
||||||
WriteUInt16($"D{currentRegister}", value);
|
WriteUInt16($"D{currentRegister}", value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1155,6 +1261,20 @@ namespace DH.Devices.PLC
|
|||||||
WriteBool(pLCItem.Address, b);
|
WriteBool(pLCItem.Address, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取挡料电机实时位置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int ReadBarrierRealPos()
|
||||||
|
{
|
||||||
|
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机实时位置");
|
||||||
|
if (pLCItem == null)
|
||||||
|
{
|
||||||
|
throw new Exception("未找到挡料电机实时位置点位");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReadInt16(pLCItem.Address);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取 挡杆回原点状态
|
/// 读取 挡杆回原点状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1169,7 +1289,7 @@ namespace DH.Devices.PLC
|
|||||||
// throw new Exception("未找到挡料电机回原点点位");
|
// throw new Exception("未找到挡料电机回原点点位");
|
||||||
//}
|
//}
|
||||||
//挡料电机传感器感应点
|
//挡料电机传感器感应点
|
||||||
return ReadBool("X11");
|
return ReadBool("X11");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1180,7 +1300,7 @@ namespace DH.Devices.PLC
|
|||||||
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机回原点速度");
|
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机回原点速度");
|
||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
return;
|
return;
|
||||||
WriteUInt32(pLCItem.Address, (uint)speed);
|
WriteInt32(pLCItem.Address, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1192,7 +1312,7 @@ namespace DH.Devices.PLC
|
|||||||
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机位置");
|
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机位置");
|
||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
return;
|
return;
|
||||||
WriteUInt16(pLCItem.Address, (ushort)value);
|
WriteInt16(pLCItem.Address, (short)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1253,12 +1373,13 @@ namespace DH.Devices.PLC
|
|||||||
/// <exception cref="Exception"></exception>
|
/// <exception cref="Exception"></exception>
|
||||||
public bool ReadMotorToZero()
|
public bool ReadMotorToZero()
|
||||||
{
|
{
|
||||||
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "相机步进原点");
|
//PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "相机步进原点");
|
||||||
if (pLCItem == null)
|
//if (pLCItem == null)
|
||||||
{
|
//{
|
||||||
throw new Exception("未找到挡料电机回原点点位");
|
// throw new Exception("未找到挡料电机回原点点位");
|
||||||
}
|
//}
|
||||||
return ReadBool(pLCItem.Address);
|
//return ReadBool(pLCItem.Address);
|
||||||
|
return ReadBool("X10");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1271,7 +1392,7 @@ namespace DH.Devices.PLC
|
|||||||
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "相机步进位置");
|
PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "相机步进位置");
|
||||||
if (pLCItem == null)
|
if (pLCItem == null)
|
||||||
return;
|
return;
|
||||||
WriteUInt16(pLCItem.Address, (ushort)value);
|
WriteInt32(pLCItem.Address, (ushort)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1285,7 +1406,7 @@ namespace DH.Devices.PLC
|
|||||||
{
|
{
|
||||||
throw new Exception("未找到相机步进实时位置");
|
throw new Exception("未找到相机步进实时位置");
|
||||||
}
|
}
|
||||||
return ReadInt16(pLCItem.Address);
|
return ReadInt32(pLCItem.Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
<ApplicationIcon>assets\favicon.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +23,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="assets\favicon.ico" />
|
||||||
<Content Include="db\config.json">
|
<Content Include="db\config.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
3
DHSoftware/LoginWindow.Designer.cs
generated
3
DHSoftware/LoginWindow.Designer.cs
generated
@ -53,6 +53,7 @@
|
|||||||
iptName.PlaceholderText = "请输入用户名";
|
iptName.PlaceholderText = "请输入用户名";
|
||||||
iptName.Size = new Size(227, 37);
|
iptName.Size = new Size(227, 37);
|
||||||
iptName.TabIndex = 1;
|
iptName.TabIndex = 1;
|
||||||
|
iptName.Text = "user";
|
||||||
//
|
//
|
||||||
// iptPwd
|
// iptPwd
|
||||||
//
|
//
|
||||||
@ -62,6 +63,7 @@
|
|||||||
iptPwd.PlaceholderText = "请输入密码";
|
iptPwd.PlaceholderText = "请输入密码";
|
||||||
iptPwd.Size = new Size(227, 37);
|
iptPwd.Size = new Size(227, 37);
|
||||||
iptPwd.TabIndex = 2;
|
iptPwd.TabIndex = 2;
|
||||||
|
iptPwd.Text = "123";
|
||||||
iptPwd.UseSystemPasswordChar = true;
|
iptPwd.UseSystemPasswordChar = true;
|
||||||
//
|
//
|
||||||
// button_cancel
|
// button_cancel
|
||||||
@ -101,7 +103,6 @@
|
|||||||
Name = "LoginWindow";
|
Name = "LoginWindow";
|
||||||
StartPosition = FormStartPosition.CenterScreen;
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
Text = "登录界面";
|
Text = "登录界面";
|
||||||
|
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -632,49 +632,7 @@ namespace DHSoftware
|
|||||||
segmented1.Items.Remove(itemToHide);
|
segmented1.Items.Remove(itemToHide);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadScheme()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//方案配置初始化
|
|
||||||
SchemeHelper.Initialize();
|
|
||||||
//读取方案列表
|
|
||||||
List<string> list = SchemeHelper.GetAllSchemes();
|
|
||||||
string CurrentScheme = "默认方案";
|
|
||||||
//如果是空,新增默认数据
|
|
||||||
if (list == null || list.Count <= 0)
|
|
||||||
{
|
|
||||||
list = new() { CurrentScheme };
|
|
||||||
//显示到方案列表
|
|
||||||
sltProjects.Items.Clear();
|
|
||||||
|
|
||||||
sltProjects.Items.Add(CurrentScheme);
|
|
||||||
//保存到方案配置
|
|
||||||
SchemeHelper.AddScheme(CurrentScheme);
|
|
||||||
SchemeHelper.SetCurrentScheme(CurrentScheme);
|
|
||||||
//新构建配置文件
|
|
||||||
ConfigHelper.InitializeScheme(CurrentScheme);
|
|
||||||
|
|
||||||
sltProjects.SelectedIndex = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (string s in list)
|
|
||||||
{
|
|
||||||
sltProjects.Items.Add(s);
|
|
||||||
}
|
|
||||||
CurrentScheme = SchemeHelper.GetCurrentScheme();
|
|
||||||
sltProjects.SelectedValue = CurrentScheme;
|
|
||||||
}
|
|
||||||
SystemModel.CurrentScheme = CurrentScheme;
|
|
||||||
//加载当前方案配置
|
|
||||||
ConfigHelper.LoadConfig();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AntdUI.Message.error(this, ex.Message, autoClose: 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConnectCamera()
|
public void ConnectCamera()
|
||||||
{
|
{
|
||||||
@ -973,7 +931,36 @@ namespace DHSoftware
|
|||||||
lblUPH.Text = UPM.ToString();
|
lblUPH.Text = UPM.ToString();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
public void LoadScheme()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 初始化方案配置(会自动创建默认方案)
|
||||||
|
SchemeHelper.Initialize();
|
||||||
|
|
||||||
|
// 读取方案列表
|
||||||
|
var schemes = SchemeHelper.GetAllSchemes();
|
||||||
|
sltProjects.Items.Clear();
|
||||||
|
|
||||||
|
// 绑定方案到下拉列表
|
||||||
|
foreach (var scheme in schemes)
|
||||||
|
{
|
||||||
|
sltProjects.Items.Add(scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置当前选中的方案
|
||||||
|
string currentScheme = SchemeHelper.GetCurrentScheme();
|
||||||
|
sltProjects.SelectedValue = currentScheme;
|
||||||
|
SystemModel.CurrentScheme = currentScheme;
|
||||||
|
|
||||||
|
// 加载当前方案配置
|
||||||
|
ConfigHelper.LoadConfig();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AntdUI.Message.error(this, ex.Message, autoClose: 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
private void BtnDeleteProject_Click(object? sender, EventArgs e)
|
private void BtnDeleteProject_Click(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -983,29 +970,21 @@ namespace DHSoftware
|
|||||||
var result = AntdUI.Modal.open(this, "删除警告!", "确认要删除该方案吗?", TType.Warn);
|
var result = AntdUI.Modal.open(this, "删除警告!", "确认要删除该方案吗?", TType.Warn);
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
string schemeToDelete = sltProjects.Text;
|
||||||
int selectedIndex = sltProjects.SelectedIndex;
|
int selectedIndex = sltProjects.SelectedIndex;
|
||||||
|
|
||||||
// 删除当前选中项
|
// 删除方案(SchemeHelper会自动处理当前方案的切换)
|
||||||
SchemeHelper.DeleteScheme(sltProjects.Text);
|
SchemeHelper.DeleteScheme(schemeToDelete);
|
||||||
ConfigHelper.DeleteSchemeConfig(sltProjects.Text);
|
ConfigHelper.DeleteSchemeConfig(schemeToDelete);
|
||||||
AntdUI.Message.success(this, $"删除方案{sltProjects.Text}成功!", autoClose: 3);
|
|
||||||
sltProjects.Items.RemoveAt(selectedIndex);
|
|
||||||
// 自动选择下一个(如果存在)
|
|
||||||
if (sltProjects.Items.Count > 0)
|
|
||||||
{
|
|
||||||
// 如果删除的不是最后一项,则选中原位置的新项,否则选中最后一项
|
|
||||||
sltProjects.SelectedIndex = selectedIndex < sltProjects.Items.Count
|
|
||||||
? selectedIndex
|
|
||||||
: sltProjects.Items.Count - 1;
|
|
||||||
|
|
||||||
SystemModel.CurrentScheme = sltProjects.Text;
|
// 刷新UI
|
||||||
SchemeHelper.SetCurrentScheme(SystemModel.CurrentScheme);
|
LoadScheme();
|
||||||
//加载当前方案配置
|
|
||||||
ConfigHelper.LoadConfig();
|
AntdUI.Message.success(this, $"删除方案{schemeToDelete}成功!", autoClose: 3);
|
||||||
}
|
|
||||||
else
|
// 如果没有方案了,提示用户
|
||||||
|
if (sltProjects.Items.Count == 0)
|
||||||
{
|
{
|
||||||
sltProjects.SelectedIndex = -1; // 清空选择
|
|
||||||
AntdUI.Modal.open(this, "空方案警告!", "当前方案全部删除,需重启程序!", TType.Warn);
|
AntdUI.Modal.open(this, "空方案警告!", "当前方案全部删除,需重启程序!", TType.Warn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1021,18 +1000,23 @@ namespace DHSoftware
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (sltProjects.Items.Count == 0 || sltProjects.SelectedIndex == -1) return;
|
if (sltProjects.Items.Count == 0 || sltProjects.SelectedIndex == -1) return;
|
||||||
if (SystemModel.CurrentScheme == sltProjects.Text)
|
|
||||||
|
string selectedScheme = sltProjects.Text;
|
||||||
|
|
||||||
|
if (SystemModel.CurrentScheme == selectedScheme)
|
||||||
{
|
{
|
||||||
AntdUI.Message.warn(this, "当前已是该方案,无需重复载入!", autoClose: 3);
|
AntdUI.Message.warn(this, "当前已是该方案,无需重复载入!", autoClose: 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//修改当前软件当前方案
|
|
||||||
SystemModel.CurrentScheme = sltProjects.Text;
|
// 设置当前方案
|
||||||
//修改配置当前方案
|
SchemeHelper.SetCurrentScheme(selectedScheme);
|
||||||
SchemeHelper.SetCurrentScheme(SystemModel.CurrentScheme);
|
SystemModel.CurrentScheme = selectedScheme;
|
||||||
//将配置文件替换为当前方案
|
|
||||||
|
// 加载配置
|
||||||
ConfigHelper.LoadConfig();
|
ConfigHelper.LoadConfig();
|
||||||
AntdUI.Message.success(this, $"载入方案{SystemModel.CurrentScheme}成功!", autoClose: 3);
|
|
||||||
|
AntdUI.Message.success(this, $"载入方案{selectedScheme}成功!", autoClose: 3);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -1049,31 +1033,27 @@ namespace DHSoftware
|
|||||||
{
|
{
|
||||||
BtnHeight = 0,
|
BtnHeight = 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (form.submit)
|
if (form.submit)
|
||||||
{
|
{
|
||||||
string SchemeName = form.SchemeName;
|
string schemeName = form.SchemeName;
|
||||||
//保存到方案配置
|
|
||||||
SchemeHelper.AddScheme(SchemeName);
|
// 保存到方案配置
|
||||||
|
SchemeHelper.AddScheme(schemeName);
|
||||||
|
|
||||||
|
// 根据选择初始化配置
|
||||||
if (form.NullScheme)
|
if (form.NullScheme)
|
||||||
{
|
{
|
||||||
//新构建配置文件
|
ConfigHelper.InitializeScheme(schemeName);
|
||||||
ConfigHelper.InitializeScheme(SchemeName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//派生当前方案
|
ConfigHelper.DeriveScheme(schemeName);
|
||||||
ConfigHelper.DeriveScheme(SchemeName);
|
|
||||||
}
|
}
|
||||||
//刷新方案列表
|
|
||||||
sltProjects.Items.Clear();
|
// 刷新UI
|
||||||
List<string> list = SchemeHelper.GetAllSchemes();
|
LoadScheme();
|
||||||
foreach (string s in list)
|
AntdUI.Message.success(this, $"新增方案{schemeName}成功!", autoClose: 3);
|
||||||
{
|
|
||||||
sltProjects.Items.Add(s);
|
|
||||||
}
|
|
||||||
string CurrentScheme = SchemeHelper.GetCurrentScheme();
|
|
||||||
sltProjects.SelectedValue = CurrentScheme;
|
|
||||||
AntdUI.Message.success(this, $"新增方案{SchemeName}成功!", autoClose: 3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -1087,11 +1067,84 @@ namespace DHSoftware
|
|||||||
public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>();
|
public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>();
|
||||||
public XinJEPLCTcpNet PLC { get; } = XinJEPLCTcpNet.Instance;
|
public XinJEPLCTcpNet PLC { get; } = XinJEPLCTcpNet.Instance;
|
||||||
private SLDMotion sLDMotion = new SLDMotion();
|
private SLDMotion sLDMotion = new SLDMotion();
|
||||||
|
// 线程控制标志
|
||||||
|
private volatile bool _isRunning = false;
|
||||||
|
private Thread _monitorThread;
|
||||||
private void MainWindow_Load(object sender, EventArgs e)
|
private void MainWindow_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
//开启按钮监听
|
||||||
|
// 启动所有监控线程
|
||||||
|
StartAllMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void StartAllMonitors()
|
||||||
|
{
|
||||||
|
if (PLC.Connected)
|
||||||
|
{
|
||||||
|
if (_monitorThread == null || !_monitorThread.IsAlive)
|
||||||
|
{
|
||||||
|
_isRunning = true;
|
||||||
|
_monitorThread = new Thread(MonitorPlcButtons);
|
||||||
|
_monitorThread.IsBackground = true; // 后台线程
|
||||||
|
_monitorThread.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MonitorPlcButtons(object? obj)
|
||||||
|
{
|
||||||
|
while (_isRunning)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 读取 PLC 输入点状态
|
||||||
|
bool startPressed = PLC.ReadBool("X3");
|
||||||
|
bool resetPressed = PLC.ReadBool("X4");
|
||||||
|
bool stopPressed = PLC.ReadBool("X5");
|
||||||
|
bool eStopPressed = PLC.ReadBool("X6");
|
||||||
|
|
||||||
|
// 处理按钮状态变化
|
||||||
|
if (startPressed)
|
||||||
|
{
|
||||||
|
PLC.TurnSpeed(0);
|
||||||
|
PLC.TurnStart(false);
|
||||||
|
HandleStartButton();
|
||||||
|
}
|
||||||
|
if (resetPressed)
|
||||||
|
{
|
||||||
|
//ResetProcess();
|
||||||
|
}
|
||||||
|
if (stopPressed)
|
||||||
|
{
|
||||||
|
HandleStopButton();
|
||||||
|
}
|
||||||
|
if (eStopPressed)
|
||||||
|
{
|
||||||
|
//EmergencyStop(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(50); // 降低 CPU 占用,根据实际调整轮询间隔
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
// 记录错误并停止线程
|
||||||
|
// throw new ProcessException($"按钮监听线程:{ex.Message}");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止监听线程
|
||||||
|
private void StopMonitoring()
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
if (_monitorThread != null && _monitorThread.IsAlive)
|
||||||
|
{
|
||||||
|
_monitorThread.Join(1000); // 等待线程退出
|
||||||
|
}
|
||||||
|
}
|
||||||
private bool _isClosing = false; // 状态标志
|
private bool _isClosing = false; // 状态标志
|
||||||
|
|
||||||
private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
|
private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
@ -1122,6 +1175,7 @@ namespace DHSoftware
|
|||||||
{
|
{
|
||||||
PLC.CloseProcess();
|
PLC.CloseProcess();
|
||||||
}
|
}
|
||||||
|
StopMonitoring();
|
||||||
_visionEngine.Stop();//释放模型
|
_visionEngine.Stop();//释放模型
|
||||||
CloseWindow.Instance.Close();// 关闭提示窗口
|
CloseWindow.Instance.Close();// 关闭提示窗口
|
||||||
//Application.Exit();
|
//Application.Exit();
|
||||||
@ -1221,11 +1275,14 @@ namespace DHSoftware
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void StartProcess()
|
private async void StartProcess()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (CurrentMachine)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BatchNO = textBoxBatchNO.Text;
|
BatchNO = textBoxBatchNO.Text;
|
||||||
textBoxBatchNO.ReadOnly = true;
|
textBoxBatchNO.ReadOnly = true;
|
||||||
@ -1314,20 +1371,41 @@ namespace DHSoftware
|
|||||||
//mOfflineImageTimer.Start();
|
//mOfflineImageTimer.Start();
|
||||||
|
|
||||||
#endregion 虚拟相机
|
#endregion 虚拟相机
|
||||||
|
//流程执行时PLC
|
||||||
|
PLC.StartProcess();
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Action, "流程启动11111111111完成!");
|
||||||
|
///这里会执行完成后,会造成后台线程断断续续,会造成界面UI卡顿
|
||||||
|
//var settings = ConfigModel.DetectionList.Where(u => u.IsEnabled && u.IsAddStation).ToList();
|
||||||
|
//if (settings != null)
|
||||||
|
//{
|
||||||
|
// settings = settings.Where(s => s.IsEnabled).ToList();
|
||||||
|
// ProductBaseCount = settings.Count;
|
||||||
|
|
||||||
var settings = _visionEngine.DetectionConfigs.Where(u => u.IsEnabled && u.IsAddStation).ToList();
|
// for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
|
||||||
if (settings != null)
|
// {
|
||||||
|
// ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
|
||||||
|
// _productLists.Add(products);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
settings = settings.Where(s => s.IsEnabled).ToList();
|
var settings = ConfigModel.DetectionList.Where(u => u.IsEnabled && u.IsAddStation).ToList();
|
||||||
ProductBaseCount = settings.Count;
|
if (settings != null)
|
||||||
|
|
||||||
for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
|
|
||||||
{
|
{
|
||||||
ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
|
ProductBaseCount = settings.Count;
|
||||||
_productLists.Add(products);
|
_productLists.Clear(); // 清空旧数据
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 预分配列表容量(减少动态扩容开销)
|
||||||
|
_productLists.Capacity = ProductBaseCount * ProductListMulti;
|
||||||
|
|
||||||
|
for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
|
||||||
|
{
|
||||||
|
_productLists.Add(new ConcurrentDictionary<uint, ProductData>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
// _MGSCameraList = DeviceCollection
|
// _MGSCameraList = DeviceCollection
|
||||||
//.OfType<MGSCameraDriver>() // 直接筛选出 MGSCameraDriver 类型的元素
|
//.OfType<MGSCameraDriver>() // 直接筛选出 MGSCameraDriver 类型的元素
|
||||||
//.Where(camera => camera.IConfig != null && camera.IConfig.IsEnabled) // 进一步筛选 IConfig 不为 null 且 IsEnabled 为 true
|
//.Where(camera => camera.IConfig != null && camera.IConfig.IsEnabled) // 进一步筛选 IConfig 不为 null 且 IsEnabled 为 true
|
||||||
@ -1337,9 +1415,10 @@ namespace DHSoftware
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//流程执行时PLC
|
|
||||||
PLC.StartProcess();
|
|
||||||
InitialOEEStatistic();
|
InitialOEEStatistic();
|
||||||
|
|
||||||
|
CurrentMachine = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -1771,14 +1850,19 @@ namespace DHSoftware
|
|||||||
|
|
||||||
private void HandleStopButton()
|
private void HandleStopButton()
|
||||||
{
|
{
|
||||||
|
if (!CurrentMachine)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
textBoxBatchNO.ReadOnly = false;
|
textBoxBatchNO.ReadOnly = false;
|
||||||
btnCreateBatchNO.Enabled = true;
|
btnCreateBatchNO.Enabled = true;
|
||||||
|
|
||||||
// Cameras.Clear();
|
// Cameras.Clear();
|
||||||
// Dectection.Clear();
|
// Dectection.Clear();
|
||||||
// Add the code for the "停止" button click here
|
// Add the code for the "停止" button click here
|
||||||
PLC.TurnStart(false);
|
PLC.StopProcess();
|
||||||
CurrentMachine = true;
|
CurrentMachine = false;
|
||||||
//sLDMotion.Stop();
|
//sLDMotion.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user