using HalconDotNet; using LB_VisionProcesses.Communicators; using LB_VisionControls; using LB_VisionProcesses.Alogrithms; using LB_VisionProcesses.Communicators; using System.Data; using System.Windows.Forms; namespace LB_VisionProcesses.Processes { public partial class ModbusRTUMasterToolEdit : TAlgorithmEdit { public ModbusRTUMasterToolEdit(ModbusRTUMasterTool subject = null) { InitializeComponent(); if (subject == null) subject = new ModbusRTUMasterTool(); this.Subject = subject; // 设置高质量渲染模式 SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SizeChanged += (s, e) => { LoadParas(); }; btnTest.MouseClick += btnRunCode_Click; } private void ModbusRTUMasterToolEdit_Load(object sender, EventArgs e) { foreach (var value in IProcess.lstCommunicators) cmbPortName.Items.Add(value.CommunicatorName); foreach (var value in Enum.GetValues(typeof(ModbusType))) cmbModbusType.Items.Add(value.ToString()); foreach (var value in Enum.GetValues(typeof(ModbusFunctionCode))) cmbModbusFunctionCode.Items.Add(value.ToString()); LoadParas(); } /// /// 加载运行参数 /// public override void LoadParas() { this.Invoke(new Action(() => { // 初始化参数 iReadTimeout.Text = Subject.Params.Inputs["读超时时间"]?.ToString(); iWriteTimeout.Text = Subject.Params.Inputs["写超时时间"]?.ToString(); iRetries.Text = Subject.Params.Inputs["失败重测次数"]?.ToString(); iWaitToRetryMilliseconds.Text = Subject.Params.Inputs["失败重测延时"]?.ToString(); // 连接参数 cmbPortName.Text = Subject.Params.Inputs["通讯口名"]?.ToString(); iConnectAddress.Text = Subject.Params.Inputs["首地址"]?.ToString(); iConnectCount.Text = Subject.Params.Inputs["寄存器个数"]?.ToString(); // 读写参数 cmbModbusType.Text = Subject.Params.Inputs["通讯类型"]?.ToString(); cmbModbusFunctionCode.Text = Subject.Params.Inputs["功能码"]?.ToString(); iSlaveAddress.Text = Subject.Params.Inputs["设备地址"]?.ToString(); iStartAddress.Text = Subject.Params.Inputs["寄存器地址"]?.ToString(); iNumberOfPoints.Text = Subject.Params.Inputs["读写寄存器个数"]?.ToString(); txtWriteMsg.Text = Subject.Params.Inputs["通讯消息"]?.ToString(); })); } private void btnRunCode_Click(object sender, EventArgs e) { DateTime StartTime = DateTime.Now; Run(); //更新日志与结果 this.BeginInvoke(new Action(() => { //if (Subject.Result) //{ // lblResult.BackColor = Color.Green; // lblResult.Text = "True"; // recordImageHSmartWindowControl.SetColor("green"); //} //else //{ // lblResult.BackColor = Color.Red; // lblResult.Text = "False"; // recordImageHSmartWindowControl.SetColor("red"); //} //lblMsg.Text = Msg.Length > 50 ? Msg.Substring(0, 50) : Msg; //lblMsgToolTip.SetToolTip(BtmStatusStrip, Msg); lblRunTime.Text = $"{(DateTime.Now - StartTime).TotalMilliseconds}ms"; UpdataOutputs(); if (Subject.InputImage != null && Subject.InputImage is HObject) { HOperatorSet.GetImageSize((HObject)Subject.InputImage, out HTuple ho_ImageWidth, out HTuple ho_ImageHeight); inputImageHSmartWindowControl.ShowHoImage((HObject)Subject.InputImage); } //先判断子类再判断父类 if (Subject.Record != null && Subject.Record is MsgRecord msgRecord) { inputImageHSmartWindowControl.DispObj(msgRecord.RecordObject_OK, true); inputImageHSmartWindowControl.DispObj(msgRecord.RecordObject_NG, false); for (int i = 0; i < msgRecord.Msg.Length; i++) inputImageHSmartWindowControl.ShowMsg(msgRecord.Msg[i] , 1 == msgRecord.Result[i] ? true : false, msgRecord.Column[i], msgRecord.Row[i]); } else if (Subject.Record != null && Subject.Record is ObjectRecord objRecord) { inputImageHSmartWindowControl.DispObj(objRecord.RecordObject_OK, true); inputImageHSmartWindowControl.DispObj(objRecord.RecordObject_NG, false); } GC.Collect(); })); } /// /// 更新运行参数 /// public override void UpdataInputs() { //设置运行参数 int iResult = 0; // 初始化参数 if (int.TryParse(iReadTimeout.Text, out iResult)) Subject.Params.Inputs.Add("读超时时间", iResult); else Subject.Params.Inputs.Add("读超时时间", 500); if (int.TryParse(iWriteTimeout.Text, out iResult)) Subject.Params.Inputs.Add("写超时时间", iResult); else Subject.Params.Inputs.Add("写超时时间", 500); if (int.TryParse(iRetries.Text, out iResult)) Subject.Params.Inputs.Add("失败重测次数", iResult); else Subject.Params.Inputs.Add("失败重测次数", 500); if (int.TryParse(iWaitToRetryMilliseconds.Text, out iResult)) Subject.Params.Inputs.Add("失败重测延时", iResult); else Subject.Params.Inputs.Add("失败重测延时", 500); // 连接参数 Subject.Params.Inputs.Add("通讯口名", cmbPortName.Text); if (int.TryParse(iConnectAddress.Text, out iResult)) Subject.Params.Inputs.Add("首地址", iResult); else Subject.Params.Inputs.Add("首地址", 100); if (int.TryParse(iConnectCount.Text, out iResult)) Subject.Params.Inputs.Add("寄存器个数", iResult); else Subject.Params.Inputs.Add("寄存器个数", 300); // 读写参数 if (Enum.TryParse(cmbModbusType.Text, out ModbusType ModbusType)) Subject.Params.Inputs.Add("通讯类型", ModbusType.ToString()); else Subject.Params.Inputs.Add("通讯类型", ModbusType.Write.ToString()); if (Enum.TryParse(cmbModbusFunctionCode.Text, out ModbusFunctionCode FunctionCode)) Subject.Params.Inputs.Add("功能码", FunctionCode.ToString()); else Subject.Params.Inputs.Add("功能码", ModbusFunctionCode.HoldingRegisters.ToString()); if (int.TryParse(iSlaveAddress.Text, out iResult)) Subject.Params.Inputs.Add("设备地址", iResult); else Subject.Params.Inputs.Add("设备地址", 1); if (int.TryParse(iStartAddress.Text, out iResult)) Subject.Params.Inputs.Add("寄存器地址", iResult); else Subject.Params.Inputs.Add("寄存器地址", 0); if (int.TryParse(iNumberOfPoints.Text, out iResult)) Subject.Params.Inputs.Add("读写寄存器个数", iResult); else Subject.Params.Inputs.Add("读写寄存器个数", 1); Subject.Params.Inputs.Add("通讯消息", txtWriteMsg.Text); return; } public void LogInfo(string strLog, bool result = true) { if (string.IsNullOrEmpty(strLog)) return; string strInfo = DateTime.Now.ToString("[HH:mm:ss:fff] "); strInfo += strLog; strLog = strInfo; // 如果当前不是 UI 线程,则通过 Invoke 将操作调度到 UI 线程 if (this.InvokeRequired) { this.BeginInvoke(new Action((msg) => { if (this.richLog.Lines.Length > 100) this.richLog.Clear(); if (result) this.richLog.SelectionColor = Color.Green; else this.richLog.SelectionColor = Color.Red; // 更新 UI 控件,比如显示接收到的消息 this.richLog.AppendText(strLog); this.richLog.AppendText("\r\n"); this.richLog.SelectionStart = this.richLog.Text.Length; this.richLog.ScrollToCaret(); }), strInfo); } else { if (this.richLog.Lines.Length > 100) this.richLog.Clear(); if (result) this.richLog.SelectionColor = Color.Green; else this.richLog.SelectionColor = Color.Red; this.richLog.AppendText(strLog); this.richLog.AppendText("\r\n"); this.richLog.SelectionStart = this.richLog.Text.Length; this.richLog.ScrollToCaret(); } } /// /// 更新输出结果 /// public override void UpdataOutputs() { this.BeginInvoke(new Action(() => { // 读写参数 if (Enum.TryParse(cmbModbusType.Text, out ModbusType ModbusType)) { byte slaveAddress = Convert.ToByte(Subject.Params.Inputs["设备地址"].ToString()); ushort startAddress = Convert.ToUInt16(Subject.Params.Inputs["寄存器地址"].ToString()); ushort numberOfPoints = Convert.ToUInt16(Subject.Params.Inputs["读写寄存器个数"].ToString()); switch (ModbusType) { case ModbusType.Read: LogInfo($"读取{cmbModbusFunctionCode.Text} ID = {slaveAddress} Start = {startAddress} \r\n" + $"Value = {Subject.Params.Outputs["收到消息"]}\r\n", Subject.Result); break; case ModbusType.Write: LogInfo($"写入{cmbModbusFunctionCode.Text} ID = {slaveAddress} Start = {startAddress} \r\n" + $"Value = {Subject.Params.Inputs["通讯消息"]}\r\n", Subject.Result); break; } } })); } } }