| | |
| | | using log4net.Config; |
| | | using Newtonsoft.Json; |
| | | using Newtonsoft.Json.Serialization; |
| | | using OpenCvSharp; |
| | | using Serilog; |
| | | using Serilog.Events; |
| | | using Sunny.UI; |
| | |
| | | using System.Text.RegularExpressions; |
| | | using System.Threading.Tasks; |
| | | using System.Windows.Forms; |
| | | using System.Windows.Media.Media3D; |
| | | |
| | | namespace LB_SmartVision |
| | | { |
| | |
| | | |
| | | // 窗体类的全局变量:标记是否允许切换Tab(默认允许) |
| | | private bool _isTabSwitchAllowed = true; |
| | | |
| | | PausableHeartbeatAsync heartbeat = new PausableHeartbeatAsync( |
| | | sendHeartbeatAsync: async () => |
| | | { |
| | | // 模拟异步心跳发送(如 HttpClient 请求) |
| | | await Task.Delay(100); // 模拟 I/O 延迟 |
| | | Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 心跳已发送"); |
| | | }, |
| | | interval: TimeSpan.FromSeconds(0.5) |
| | | ); |
| | | |
| | | |
| | | #endregion |
| | | |
| | |
| | | materialTabControl.ControlRemoved += (s, e) => UpdateOverflowComboBox(); |
| | | |
| | | //HOperatorSet.SetSystem("max_mem_cache", 2048); |
| | | startPLCThread(); |
| | | } |
| | | |
| | | string removeName = string.Empty; |
| | |
| | | catch { return false; } |
| | | } |
| | | |
| | | public bool LoadAllPLCSettings(string allPLCSettingStringPath) |
| | | { |
| | | try |
| | | { |
| | | GlobalVar.allPlcSettings = ConfigManager<Dictionary<string, PlcConfig>>.LoadConfig<Dictionary<string, PlcConfig>>(allPLCSettingStringPath); |
| | | } |
| | | catch |
| | | { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public bool SaveAllPLCSettings() |
| | | { |
| | | try |
| | | { |
| | | ConfigManager<Dictionary<string, PlcConfig>>.SaveConfig<Dictionary<string, PlcConfig>>(GlobalVar.allPlcSettings, GlobalVar.allPlcSettingsPath); |
| | | } |
| | | catch |
| | | { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public static bool SaveAllProcessSetting() |
| | | { |
| | | try |
| | |
| | | else |
| | | { |
| | | LogInfo("通讯加载失败", LogInfoType.ERROR); |
| | | } |
| | | if (LoadAllPLCSettings(GlobalVar.allPlcSettingsPath)) |
| | | { |
| | | LogInfo("PLC通讯加载成功", LogInfoType.PASS); |
| | | } |
| | | else |
| | | { |
| | | LogInfo("PLC通讯加载失败", LogInfoType.ERROR); |
| | | } |
| | | //加载相机 |
| | | foreach (BaseCamera camera in GlobalVar.dicCameras.Values) |
| | |
| | | if (GlobalVar.dicCommunicators.Keys.Contains("通讯0")) |
| | | { |
| | | SiemensLBS7 siemensLBS7 = GlobalVar.dicCommunicators["通讯0"] as SiemensLBS7; |
| | | siemensLBS7.Write(GlobalVar.dicMotionControlData[GlobalVar.strProductName][item].XAxisAddress, GlobalVar.dicMotionControlData[GlobalVar.strProductName][item].XAxisAddress); |
| | | //siemensLBS7.Write(GlobalVar.dicMotionControlData[GlobalVar.strProductName][item].XAxisAddress, GlobalVar.dicMotionControlData[GlobalVar.strProductName][item].XAxisAddress); |
| | | } |
| | | } |
| | | } |
| | |
| | | SaveMotionControlDatas(); |
| | | SaveSerialPorts(); |
| | | SaveAllBarcodeReaders(); |
| | | SaveAllPLCSettings(); |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | try |
| | | { |
| | | GlobalVar.dicMotionControlData = ConfigManager<Dictionary<string, Dictionary<string, RecordMotionControlData>>>.LoadConfig<Dictionary<string, Dictionary<string, RecordMotionControlData>>>(alMotionControlDataPath); |
| | | GlobalVar.dicMotionControlData = ConfigManager<Dictionary<string, Dictionary<string, PlcConfig>>>.LoadConfig<Dictionary<string, Dictionary<string, PlcConfig>>>(alMotionControlDataPath); |
| | | } |
| | | catch |
| | | { |
| | |
| | | GlobalVar.dicMotionControlData[item].Remove(itemSN); |
| | | } |
| | | } |
| | | ConfigManager<Dictionary<string, Dictionary<string, RecordMotionControlData>>>.SaveConfig<Dictionary<string, Dictionary<string, RecordMotionControlData>>>(GlobalVar.dicMotionControlData, GlobalVar.allMotionControlDataPath); |
| | | ConfigManager<Dictionary<string, Dictionary<string, PlcConfig>>>.SaveConfig<Dictionary<string, Dictionary<string, PlcConfig>>>(GlobalVar.dicMotionControlData, GlobalVar.allMotionControlDataPath); |
| | | } |
| | | catch |
| | | { |
| | |
| | | Debug.WriteLine("No match found."); |
| | | } |
| | | } |
| | | |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0) |
| | | { |
| | | GlobalVar.currentCommunicators = GlobalVar.dicCommunicators.Keys.ToList()[0]; |
| | | } |
| | | return true; |
| | | } |
| | | catch { return false; } |
| | |
| | | { |
| | | camera.Dispose(); |
| | | } |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | foreach (var item in GlobalVar.allPlcSettings[GlobalVar.currentCommunicators].Signals) |
| | | { |
| | | if (item.SignalName.Equals("视觉Ready信号")) |
| | | { |
| | | if (!string.IsNullOrEmpty("0")) |
| | | { |
| | | object convertedValue = ConvertValue(item.DataType, "0"); |
| | | ((SiemensLBS7)GlobalVar.dicCommunicators[GlobalVar.currentCommunicators]).WriteSignal(item, convertedValue); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | StopPLC(); |
| | | |
| | | foreach (BaseCommunicator communicator in GlobalVar.dicCommunicators.Values) |
| | | { |
| | | communicator.Disconnect(); |
| | | } |
| | | |
| | | FormClosing -= VisionForm_FormClosing; |
| | | |
| | | //try |
| | | //{ |
| | | // Process[] processes = System.Diagnostics.Process.GetProcesses(); //获得所有进程 |
| | | // foreach (Process p in processes) |
| | | // { |
| | | // if (p.ProcessName == "LB_SmartVision" && p.StartTime < DateTime.Now.AddMilliseconds(-300)) |
| | | // { |
| | | // p.Kill(); |
| | | // } |
| | | // } |
| | | //} |
| | | //catch { } |
| | | |
| | | KillAllTargetProcesses(); |
| | | } |
| | |
| | | { |
| | | _isTabSwitchAllowed = false; |
| | | btn_RunContinuously.Text = "暂停运行"; |
| | | |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | foreach (var item in GlobalVar.allPlcSettings[GlobalVar.currentCommunicators].Signals) |
| | | { |
| | | if (item.SignalName.Equals("视觉Ready信号")) |
| | | { |
| | | if (!string.IsNullOrEmpty("1")) |
| | | { |
| | | object convertedValue = ConvertValue(item.DataType, "1"); |
| | | ((SiemensLBS7)GlobalVar.dicCommunicators[GlobalVar.currentCommunicators]).WriteSignal(item, convertedValue); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | StartPLC(); |
| | | // 关闭使能 |
| | | SelectMainPage(); |
| | | btn_GlobalVar.Enabled = false; |
| | |
| | | ckbAllowRun.Enabled = true; |
| | | Thread.Sleep(100); |
| | | _isTabSwitchAllowed = true; |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | foreach (var item in GlobalVar.allPlcSettings[GlobalVar.currentCommunicators].Signals) |
| | | { |
| | | if (item.SignalName.Equals("视觉Ready信号")) |
| | | { |
| | | if (!string.IsNullOrEmpty("0")) |
| | | { |
| | | object convertedValue = ConvertValue(item.DataType, "0"); |
| | | ((SiemensLBS7)GlobalVar.dicCommunicators[GlobalVar.currentCommunicators]).WriteSignal(item, convertedValue); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | StopPLC(); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | materialCombobox1.SelectedItem = materialTabControl.SelectedTab.Text; |
| | | } |
| | | |
| | | |
| | | #region PLC心跳线程 |
| | | private bool threadStart = false; |
| | | private AutoResetEvent mAutoResetEventWorking = new AutoResetEvent(false); |
| | | |
| | | private void startPLCThread() |
| | | { |
| | | var taskworking = Task.Factory.StartNew(() => |
| | | { |
| | | PLCHeartBeatWorkThread(); |
| | | }); |
| | | } |
| | | private void StartPLC() |
| | | { |
| | | threadStart = true; |
| | | mAutoResetEventWorking.Set(); |
| | | AsyncLogHelper.Info("开启心跳通讯线程!"); |
| | | } |
| | | private void StopPLC() |
| | | { |
| | | threadStart = false; |
| | | Thread.Sleep(10); |
| | | } |
| | | bool isStart = true; |
| | | object plcHeartBeatWorkThread = new object(); |
| | | private bool plcHeartBeat = false; |
| | | private void PLCHeartBeatWorkThread() |
| | | { |
| | | while (isStart) |
| | | { |
| | | try |
| | | { |
| | | lock (plcHeartBeatWorkThread) |
| | | { |
| | | if (threadStart == false) |
| | | { |
| | | mAutoResetEventWorking.WaitOne();//阻塞等待 |
| | | } |
| | | else |
| | | { |
| | | if (threadStart) |
| | | { |
| | | try |
| | | { |
| | | Thread.Sleep(500); |
| | | } |
| | | catch { } |
| | | try |
| | | { |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | var TaskHeartBeat = Task.Factory.StartNew(() => |
| | | { |
| | | try |
| | | { |
| | | if (!plcHeartBeat) |
| | | { |
| | | plcHeartBeat = true; |
| | | foreach (var item in GlobalVar.allPlcSettings[GlobalVar.currentCommunicators].Signals) |
| | | { |
| | | if (item.SignalName.Equals("心跳信号")) |
| | | { |
| | | if (!string.IsNullOrEmpty(plcHeartBeat.ToString())) |
| | | { |
| | | object convertedValue = ConvertValue(item.DataType, plcHeartBeat.ToString()); |
| | | ((SiemensLBS7)GlobalVar.dicCommunicators[GlobalVar.currentCommunicators]).WriteSignal(item, convertedValue); |
| | | } |
| | | } |
| | | } |
| | | this.textBox_CommunicationSetting.BackColor = Color.SpringGreen; |
| | | } |
| | | else |
| | | { |
| | | plcHeartBeat = false; |
| | | foreach (var item in GlobalVar.allPlcSettings[GlobalVar.currentCommunicators].Signals) |
| | | { |
| | | if (item.SignalName.Equals("心跳信号")) |
| | | { |
| | | if (!string.IsNullOrEmpty(plcHeartBeat.ToString())) |
| | | { |
| | | object convertedValue = ConvertValue(item.DataType, plcHeartBeat.ToString()); |
| | | ((SiemensLBS7)GlobalVar.dicCommunicators[GlobalVar.currentCommunicators]).WriteSignal(item, convertedValue); |
| | | } |
| | | } |
| | | } |
| | | this.textBox_CommunicationSetting.BackColor = Color.Red; |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //Thread.Sleep(1000); |
| | | } |
| | | catch { } |
| | | } |
| | | } |
| | | public void stopPLC() |
| | | { |
| | | if (btn_RunContinuously.Text.Equals("连续运行")) |
| | | { |
| | | var taskstopPLC = Task.Factory.StartNew(() => |
| | | { |
| | | try |
| | | { |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | //S7NETplusStaticClass.plc.Write(VVar.softWareParams.StopNG, true); |
| | | AsyncLogHelper.Error("[" + DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss:fff") + "]" + "连续NG次数为:" + ", 已发出停线信号!请人为排查并复位异常。"); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | AsyncLogHelper.Error("[" + DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss:fff") + "]" + "连续NG停线异常!请检查工控机到PLC的网线连接!"); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | private void abortHeartB() |
| | | { |
| | | try |
| | | { |
| | | threadStart = false; |
| | | } |
| | | catch { } |
| | | } |
| | | private void stopPLCHB() |
| | | { |
| | | //发送给PLC的IsRead为false; |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | foreach (var item in GlobalVar.allPlcSettings[GlobalVar.currentCommunicators].Signals) |
| | | { |
| | | if (item.SignalName.Equals("视觉Ready信号")) |
| | | { |
| | | ((SiemensLBS7)GlobalVar.dicCommunicators[GlobalVar.currentCommunicators]).WriteSignal(item, "0"); |
| | | } |
| | | } |
| | | threadStart = false; |
| | | AsyncLogHelper.Info("暂停心跳通讯线程!"); |
| | | if (GlobalVar.dicCommunicators != null && GlobalVar.dicCommunicators.Count > 0 && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators] != null && |
| | | GlobalVar.dicCommunicators[GlobalVar.currentCommunicators].bConnected) |
| | | { |
| | | this.textBox_CommunicationSetting.BackColor = Color.SpringGreen; |
| | | } |
| | | else |
| | | { |
| | | textBox_CommunicationSetting.BackColor = Color.Red; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | AsyncLogHelper.Error("停止通讯异常!PLC连接异常,请检查工控机到PLC的网线连接!"); |
| | | } |
| | | Thread.Sleep(100); |
| | | } |
| | | #endregion |
| | | // 数据类型转换辅助方法 |
| | | private object ConvertValue(string dataType, string valueStr) |
| | | { |
| | | switch (dataType) |
| | | { |
| | | case "Bool": |
| | | { |
| | | if (bool.TryParse(valueStr, out bool b)) return b; |
| | | if (valueStr == "1") return true; |
| | | if (valueStr == "0") return false; |
| | | throw new Exception("无效的布尔值"); |
| | | } |
| | | case "Byte": |
| | | { |
| | | return byte.Parse(valueStr); |
| | | } |
| | | case "Int": |
| | | { |
| | | return short.Parse(valueStr); |
| | | } |
| | | case "DInt": |
| | | { |
| | | return int.Parse(valueStr); |
| | | } |
| | | case "Real": |
| | | { |
| | | return float.Parse(valueStr); |
| | | } |
| | | case "String": |
| | | { |
| | | return valueStr; |
| | | } |
| | | default: |
| | | { |
| | | throw new NotSupportedException($"不支持的类型: {dataType}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |