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();
|
}
|
|
/// <summary>
|
/// 加载运行参数
|
/// </summary>
|
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();
|
}));
|
}
|
|
/// <summary>
|
/// 更新运行参数
|
/// </summary>
|
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<string>((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();
|
}
|
}
|
|
/// <summary>
|
/// 更新输出结果
|
/// </summary>
|
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;
|
}
|
}
|
}));
|
}
|
}
|
}
|