From 76d74124f6011a25ee1cdbc322ab22e2c36d7beb Mon Sep 17 00:00:00 2001
From: C3204 <zhengyabo@lanpucloud.cn>
Date: 星期五, 16 一月 2026 12:23:27 +0800
Subject: [PATCH] 添加运动控制菜单底层逻辑

---
 LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorsEditPage.cs     |   28 +
 LB_SmartVision/VisionForm.cs                                             |   16 
 LB_VisionProcesses/Communicators/CommunicatorForm.resx                   |    2 
 LB_VisionProcesses/Communicators/CommunicatorForm.Designer.cs            |  198 +++++++++-----
 LB_VisionProcesses/Communicators/SiemensS7/SiemensLBS7.cs                |  358 ++++++++++++++++++++++---
 LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs |   75 +++-
 LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs          |   74 ++++-
 LB_VisionProcesses/Communicators/CommunicatorForm.cs                     |   84 +++++
 8 files changed, 657 insertions(+), 178 deletions(-)

diff --git a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs
index 6f861c8..a4c2066 100644
--- a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs
+++ b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.Designer.cs
@@ -46,6 +46,8 @@
             lblType = new Label();
             lblAddress = new Label();
             lblIP = new Label();
+            cmbDataType = new ComboBox();
+            lblDataType = new Label();
             tableLayoutPanel2 = new TableLayoutPanel();
             btnRuleSend = new Button();
             btnSend = new Button();
@@ -84,7 +86,7 @@
             tableLayoutPanel1.Controls.Add(label3, 0, 1);
             tableLayoutPanel1.Dock = DockStyle.Fill;
             tableLayoutPanel1.Location = new Point(0, 0);
-            tableLayoutPanel1.Margin = new Padding(4);
+            tableLayoutPanel1.Margin = new Padding(4, 4, 4, 4);
             tableLayoutPanel1.Name = "tableLayoutPanel1";
             tableLayoutPanel1.RowCount = 5;
             tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 125F));
@@ -101,9 +103,9 @@
             grpReceive.Dock = DockStyle.Fill;
             grpReceive.ForeColor = Color.CornflowerBlue;
             grpReceive.Location = new Point(4, 242);
-            grpReceive.Margin = new Padding(4);
+            grpReceive.Margin = new Padding(4, 4, 4, 4);
             grpReceive.Name = "grpReceive";
-            grpReceive.Padding = new Padding(4);
+            grpReceive.Padding = new Padding(4, 4, 4, 4);
             grpReceive.Size = new Size(819, 156);
             grpReceive.TabIndex = 30;
             grpReceive.TabStop = false;
@@ -113,7 +115,7 @@
             // 
             txtReceiveMsg.Dock = DockStyle.Fill;
             txtReceiveMsg.Location = new Point(4, 21);
-            txtReceiveMsg.Margin = new Padding(4);
+            txtReceiveMsg.Margin = new Padding(4, 4, 4, 4);
             txtReceiveMsg.Multiline = true;
             txtReceiveMsg.Name = "txtReceiveMsg";
             txtReceiveMsg.ReadOnly = true;
@@ -125,7 +127,7 @@
             // 
             txtSendMsg.Dock = DockStyle.Fill;
             txtSendMsg.Location = new Point(4, 154);
-            txtSendMsg.Margin = new Padding(4);
+            txtSendMsg.Margin = new Padding(4, 4, 4, 4);
             txtSendMsg.Name = "txtSendMsg";
             txtSendMsg.Size = new Size(819, 24);
             txtSendMsg.TabIndex = 29;
@@ -144,13 +146,15 @@
             grpSetting.Controls.Add(lblType);
             grpSetting.Controls.Add(lblAddress);
             grpSetting.Controls.Add(lblIP);
+            grpSetting.Controls.Add(cmbDataType);
+            grpSetting.Controls.Add(lblDataType);
             grpSetting.Dock = DockStyle.Fill;
             grpSetting.ForeColor = Color.CornflowerBlue;
             grpSetting.Location = new Point(4, 4);
-            grpSetting.Margin = new Padding(4);
+            grpSetting.Margin = new Padding(4, 4, 4, 4);
             grpSetting.MinimumSize = new Size(326, 76);
             grpSetting.Name = "grpSetting";
-            grpSetting.Padding = new Padding(4);
+            grpSetting.Padding = new Padding(4, 4, 4, 4);
             grpSetting.Size = new Size(819, 117);
             grpSetting.TabIndex = 28;
             grpSetting.TabStop = false;
@@ -159,7 +163,7 @@
             // txtAddress
             // 
             txtAddress.Location = new Point(314, 75);
-            txtAddress.Margin = new Padding(4);
+            txtAddress.Margin = new Padding(4, 4, 4, 4);
             txtAddress.Name = "txtAddress";
             txtAddress.Size = new Size(124, 24);
             txtAddress.TabIndex = 9;
@@ -181,7 +185,7 @@
             cmbType.DropDownStyle = ComboBoxStyle.DropDownList;
             cmbType.FormattingEnabled = true;
             cmbType.Location = new Point(314, 29);
-            cmbType.Margin = new Padding(4);
+            cmbType.Margin = new Padding(4, 4, 4, 4);
             cmbType.Name = "cmbType";
             cmbType.Size = new Size(124, 26);
             cmbType.TabIndex = 8;
@@ -189,7 +193,7 @@
             // txtIP
             // 
             txtIP.Location = new Point(99, 28);
-            txtIP.Margin = new Padding(4);
+            txtIP.Margin = new Padding(4, 4, 4, 4);
             txtIP.Name = "txtIP";
             txtIP.Size = new Size(124, 24);
             txtIP.TabIndex = 7;
@@ -197,7 +201,7 @@
             // txtPort
             // 
             txtPort.Location = new Point(99, 75);
-            txtPort.Margin = new Padding(4);
+            txtPort.Margin = new Padding(4, 4, 4, 4);
             txtPort.Name = "txtPort";
             txtPort.Size = new Size(124, 24);
             txtPort.TabIndex = 6;
@@ -226,7 +230,7 @@
             // 
             cmbIP.FormattingEnabled = true;
             cmbIP.Location = new Point(99, 26);
-            cmbIP.Margin = new Padding(4);
+            cmbIP.Margin = new Padding(4, 4, 4, 4);
             cmbIP.Name = "cmbIP";
             cmbIP.Size = new Size(124, 26);
             cmbIP.TabIndex = 1;
@@ -234,7 +238,7 @@
             // lblType
             // 
             lblType.AutoSize = true;
-            lblType.Location = new Point(246, 32);
+            lblType.Location = new Point(256, 32);
             lblType.Margin = new Padding(4, 0, 4, 0);
             lblType.Name = "lblType";
             lblType.Size = new Size(38, 18);
@@ -244,10 +248,10 @@
             // lblAddress
             // 
             lblAddress.AutoSize = true;
-            lblAddress.Location = new Point(242, 79);
+            lblAddress.Location = new Point(256, 79);
             lblAddress.Margin = new Padding(4, 0, 4, 0);
             lblAddress.Name = "lblAddress";
-            lblAddress.Size = new Size(68, 18);
+            lblAddress.Size = new Size(38, 18);
             lblAddress.TabIndex = 0;
             lblAddress.Text = "鍙橀噺鍦板潃";
             // 
@@ -261,6 +265,27 @@
             lblIP.TabIndex = 0;
             lblIP.Text = "鍦板潃";
             // 
+            // cmbDataType
+            // 
+            cmbDataType.DropDownStyle = ComboBoxStyle.DropDownList;
+            cmbDataType.FormattingEnabled = true;
+            cmbDataType.Location = new Point(525, 75);
+            cmbDataType.Margin = new Padding(4, 4, 4, 4);
+            cmbDataType.Name = "cmbDataType";
+            cmbDataType.Size = new Size(124, 26);
+            cmbDataType.TabIndex = 11;
+            cmbDataType.SelectedIndexChanged += cmbDataType_SelectedIndexChanged;
+            // 
+            // lblDataType
+            // 
+            lblDataType.AutoSize = true;
+            lblDataType.Location = new Point(462, 79);
+            lblDataType.Margin = new Padding(4, 0, 4, 0);
+            lblDataType.Name = "lblDataType";
+            lblDataType.Size = new Size(38, 18);
+            lblDataType.TabIndex = 10;
+            lblDataType.Text = "绫诲瀷";
+            // 
             // tableLayoutPanel2
             // 
             tableLayoutPanel2.ColumnCount = 3;
@@ -271,7 +296,7 @@
             tableLayoutPanel2.Controls.Add(btnSend, 0, 0);
             tableLayoutPanel2.Dock = DockStyle.Fill;
             tableLayoutPanel2.Location = new Point(4, 192);
-            tableLayoutPanel2.Margin = new Padding(4);
+            tableLayoutPanel2.Margin = new Padding(4, 4, 4, 4);
             tableLayoutPanel2.Name = "tableLayoutPanel2";
             tableLayoutPanel2.RowCount = 1;
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
@@ -283,7 +308,7 @@
             btnRuleSend.Dock = DockStyle.Fill;
             btnRuleSend.ForeColor = Color.CornflowerBlue;
             btnRuleSend.Location = new Point(104, 4);
-            btnRuleSend.Margin = new Padding(4);
+            btnRuleSend.Margin = new Padding(4, 4, 4, 4);
             btnRuleSend.Name = "btnRuleSend";
             btnRuleSend.Size = new Size(92, 34);
             btnRuleSend.TabIndex = 14;
@@ -296,7 +321,7 @@
             btnSend.Dock = DockStyle.Fill;
             btnSend.ForeColor = Color.CornflowerBlue;
             btnSend.Location = new Point(4, 4);
-            btnSend.Margin = new Padding(4);
+            btnSend.Margin = new Padding(4, 4, 4, 4);
             btnSend.Name = "btnSend";
             btnSend.Size = new Size(92, 34);
             btnSend.TabIndex = 12;
@@ -313,7 +338,7 @@
             themeForm_Communicator.Font = new Font("Microsoft Sans Serif", 9F);
             themeForm_Communicator.Image = (Image)resources.GetObject("themeForm_Communicator.Image");
             themeForm_Communicator.Location = new Point(0, 0);
-            themeForm_Communicator.Margin = new Padding(4);
+            themeForm_Communicator.Margin = new Padding(4, 4, 4, 4);
             themeForm_Communicator.Name = "themeForm_Communicator";
             themeForm_Communicator.Padding = new Padding(12, 88, 12, 11);
             themeForm_Communicator.RoundCorners = true;
@@ -334,8 +359,8 @@
             controlBox1.EnableMaximizeButton = true;
             controlBox1.EnableMinimizeButton = true;
             controlBox1.ForeColor = Color.FromArgb(155, 155, 155);
-            controlBox1.Location = new Point(726, 18);
-            controlBox1.Margin = new Padding(4);
+            controlBox1.Location = new Point(726, 22);
+            controlBox1.Margin = new Padding(4, 4, 4, 4);
             controlBox1.MaximizeHoverColor = Color.FromArgb(74, 74, 74);
             controlBox1.MinimizeHoverColor = Color.FromArgb(63, 63, 65);
             controlBox1.Name = "controlBox1";
@@ -348,7 +373,7 @@
             panel_CommunicatorForm.Controls.Add(tableLayoutPanel1);
             panel_CommunicatorForm.Dock = DockStyle.Fill;
             panel_CommunicatorForm.Location = new Point(12, 88);
-            panel_CommunicatorForm.Margin = new Padding(4);
+            panel_CommunicatorForm.Margin = new Padding(4, 4, 4, 4);
             panel_CommunicatorForm.Name = "panel_CommunicatorForm";
             panel_CommunicatorForm.Size = new Size(827, 402);
             panel_CommunicatorForm.TabIndex = 27;
@@ -360,7 +385,7 @@
             ClientSize = new Size(851, 501);
             Controls.Add(themeForm_Communicator);
             FormBorderStyle = FormBorderStyle.None;
-            Margin = new Padding(4);
+            Margin = new Padding(4, 4, 4, 4);
             MinimumSize = new Size(326, 76);
             Name = "CommunicatorForm";
             Text = "閫氳璁剧疆";
@@ -400,7 +425,7 @@
         private ComboBox cmbType;
         private Label lblAddress;
         private TextBox txtAddress;
-        private ComboBox cmbVarType;
-        private Label lbVarType;
+        private Label lblDataType;
+        private ComboBox cmbDataType;
     }
 }
\ No newline at end of file
diff --git a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs
index ab9629a..ac1936d 100644
--- a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs
+++ b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorForm.cs
@@ -49,12 +49,17 @@
             cmbIP.Enabled = false;
             txtIP.Enabled = false;
             txtPort.Enabled = false;
+            cmbDataType.Enabled = false;
+
+
             lblType.Visible = false;
             lblAddress.Visible = false;
             cmbType.Visible = false;
             txtAddress.Visible = false;
-            lbVarType.Visible = false;
-            cmbVarType.Visible = false;
+            lblDataType.Visible = false;
+            cmbDataType.Visible = false;
+
+
             this.Text = name;
             if (communicator is UARTPort)
             {
@@ -74,13 +79,16 @@
                 lblAddress.Visible = false;
                 cmbType.Visible = false;
                 txtAddress.Visible = false;
+                lblDataType.Visible = false;
+                cmbDataType.Visible = false;
+
                 lblIP.Text = "COM鍙�";
                 lblPort.Text = "娉㈢壒鐜�";
             }
             else if (communicator is TCPClient || communicator is TCPServer)
             {
                 txtIP.Text = communicator.CommunicatorConnections["鍦板潃"]?.ToString();
-                txtPort.SelectedText = communicator.CommunicatorConnections["绔彛"]?.ToString();
+                txtPort.Text = communicator.CommunicatorConnections["绔彛"]?.ToString();
                 txtIP.Visible = true;
                 cmbIP.Visible = false;
                 this.btnRuleSend.Visible = false;
@@ -88,6 +96,9 @@
                 lblAddress.Visible = false;
                 cmbType.Visible = false;
                 txtAddress.Visible = false;
+                lblDataType.Visible = false;
+                cmbDataType.Visible = false;
+
                 lblIP.Text = "鍦板潃";
                 lblPort.Text = "绔彛";
             }
@@ -105,13 +116,15 @@
                 {
                     txtAddress.Text = communicator.CommunicatorConnections["鍙橀噺鍦板潃"]?.ToString();
                 }
-                if (!string.IsNullOrEmpty(communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString()))
-                {
-                    cmbVarType.Items.Add(communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString());
-                    cmbVarType.Text = communicator.CommunicatorConnections["鍙橀噺绫诲瀷"]?.ToString();
-                }
-                lbVarType.Visible = true;
-                cmbVarType.Visible = true;
+
+                // 鍒濆鍖栨暟鎹被鍨�
+                cmbDataType.Items.Clear();
+                cmbDataType.Items.AddRange(new string[] { "String", "Bool", "Byte", "Int", "DInt", "Real", "Double", "Word", "DWord" });
+                if (communicator.CommunicatorConnections.Contains("鏁版嵁绫诲瀷"))
+                    cmbDataType.Text = communicator.CommunicatorConnections["鏁版嵁绫诲瀷"].ToString();
+                else
+                    cmbDataType.Text = "String";
+
                 txtIP.Visible = true;
                 cmbIP.Visible = false;
                 this.btnRuleSend.Visible = false;
@@ -119,6 +132,10 @@
                 lblAddress.Visible = true;
                 cmbType.Visible = true;
                 txtAddress.Visible = true;
+                lblDataType.Visible = true;
+                cmbDataType.Visible = true;
+                cmbDataType.Enabled = true; // 鍚敤鏁版嵁绫诲瀷閫夋嫨
+
                 lblIP.Text = "IP";
                 lblPort.Text = "妲�";
             }
@@ -126,6 +143,15 @@
             this.communicator = communicator;
             //鍔犺浇鍥炶皟鍑芥暟
             Subscribe();
+        }
+
+        private void cmbDataType_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            if (communicator != null)
+            {
+                communicator.CommunicatorConnections.Add("鏁版嵁绫诲瀷", cmbDataType.Text);
+                communicatorChanged(communicator);
+            }
         }
 
         private void CommunicatorForm_FormClosing(object sender, FormClosingEventArgs e) => Unsubscribe();
@@ -227,6 +253,24 @@
             }
         }
 
+        private void ShowLogMsg(string msg)
+        {
+            // 濡傛灉褰撳墠涓嶆槸 UI 绾跨▼锛屽垯閫氳繃 Invoke 灏嗘搷浣滆皟搴﹀埌 UI 绾跨▼
+            if (this.InvokeRequired)
+            {
+                this.Invoke(new Action<string>((message) =>
+                {
+                    this.txtReceiveMsg.AppendText("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + message + "\r\n");
+                    this.txtReceiveMsg.ScrollToCaret();
+                }), msg);
+            }
+            else
+            {
+                this.txtReceiveMsg.AppendText("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + msg + "\r\n");
+                this.txtReceiveMsg.ScrollToCaret();
+            }
+        }
+
         private void btnSend_Click(object sender, EventArgs e)
         {
             if (communicator == null)
@@ -234,6 +278,8 @@
 
             if (communicator.SendMessage(txtSendMsg.Text))
                 ShowSendMsg(txtSendMsg.Text);
+            else
+                ShowLogMsg(communicator.Msg);
         }
 
         private void btnRuleSend_Click(object sender, EventArgs e)
@@ -252,17 +298,15 @@
 
             if (communicator.SendMessage(SendMsg))
                 ShowSendMsg(SendMsg);
+            else
+                ShowLogMsg(communicator.Msg);
         }
 
         private void txtAddress_TextChanged(object sender, EventArgs e)
         {
-            if (communicator != null && !communicator.CommunicatorConnections.Contains("鍙橀噺鍦板潃"))
+            if (communicator != null)
             {
                 communicator.CommunicatorConnections.Add("鍙橀噺鍦板潃", txtAddress.Text);
-            }
-            else if (communicator != null)
-            {
-                communicator.CommunicatorConnections["鍙橀噺鍦板潃"] = txtAddress.Text;
                 communicatorChanged(communicator);
             }
         }
diff --git a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorsEditPage.cs b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorsEditPage.cs
index 0a561a3..ad09050 100644
--- a/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorsEditPage.cs
+++ b/LB_SmartVision/Forms/Pages/CommunicatorPage/CommunicatorsEditPage.cs
@@ -34,7 +34,9 @@
                 if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
                     return;
 
-                string CommunicatorConnectionString = $"({ClassName}){IP}:{PORT}";
+                string DataType = item.Value.CommunicatorConnections.Contains("鏁版嵁绫诲瀷") ?
+                    item.Value.CommunicatorConnections["鏁版嵁绫诲瀷"].ToString() : "String";
+                string CommunicatorConnectionString = $"({ClassName}){IP}:{PORT} [{DataType}]";
 
                 UserItem flow = new UserItem(new string[] { "娴嬭瘯", "鍒锋柊", "绉婚櫎", "閲嶅懡鍚�" });
                 //flow.SetDPIScale();
@@ -69,7 +71,9 @@
                 if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
                     return;
 
-                string CommunicatorConnectionString = $"({ClassName}){IP}:{PORT}";
+                string DataType = communicator.CommunicatorConnections.Contains("鏁版嵁绫诲瀷") ?
+                    communicator.CommunicatorConnections["鏁版嵁绫诲瀷"].ToString() : "String";
+                string CommunicatorConnectionString = $"({ClassName}){IP}:{PORT} [{DataType}]";
 
                 GlobalVar.dicCommunicators.TryAdd(Name, communicator);
                 communicator.CommunicatorName = Name;
@@ -135,7 +139,27 @@
 
         private void CommunicatorFForm_CommunicatorChanged(BaseCommunicator communicator)
         {
+            if (this.InvokeRequired)
+            {
+                this.Invoke(new Action<BaseCommunicator>(CommunicatorFForm_CommunicatorChanged), communicator);
+                return;
+            }
 
+            for (int i = 0; i < uiFlowLayoutPanel1.Controls.Count; i++)
+            {
+                if (uiFlowLayoutPanel1.Controls[i] is UserItem flow && flow.Name == communicator.CommunicatorName)
+                {
+                    string ClassName = communicator.GetType().Name;
+                    string IP = communicator.CommunicatorConnections["鍦板潃"].ToString();
+                    string PORT = communicator.CommunicatorConnections["绔彛"].ToString();
+                    string DataType = communicator.CommunicatorConnections.Contains("鏁版嵁绫诲瀷") ?
+                        communicator.CommunicatorConnections["鏁版嵁绫诲瀷"].ToString() : "String";
+
+                    flow.Text = $"({ClassName}){IP}:{PORT} [{DataType}]";
+                    flow.Refresh();
+                    break;
+                }
+            }
         }
 
         // 绉婚櫎閫氳鍙�
diff --git a/LB_SmartVision/VisionForm.cs b/LB_SmartVision/VisionForm.cs
index a8fdfcf..f4ed8c8 100644
--- a/LB_SmartVision/VisionForm.cs
+++ b/LB_SmartVision/VisionForm.cs
@@ -841,12 +841,8 @@
                     if (!string.IsNullOrEmpty(CommunicatorAddress) && CommunicatorAddress.Contains("SiemensLBS7"))
                     {
                         // 瀹氫箟姝e垯琛ㄨ揪寮忎互鎻愬彇鍗忚銆両P 鍦板潃鍜岀鍙�
-                        //1.    \((.*?)\)锛歕(鍜� \) 鏄敤浜庡尮閰嶆嫭鍙风殑杞箟瀛楃銆�
-                        //      (.*?) 鏄竴涓潪璐┆鐨勫尮閰嶏紝鐢ㄦ潵鍖归厤绫诲悕锛圡yProcesses.Communicators.TCPServer 鎴� MyProcesses.Communicators.UARTPort锛夈��
-                        //2.    ([^:] +)锛氬尮閰嶅啋鍙蜂箣鍓嶇殑閮ㄥ垎锛屽嵆鍦板潃锛�127.0.0.1 鎴� COM5锛夈�傝繖閲屼娇鐢ㄤ簡[^:] 鏉ュ尮閰嶉櫎浜嗗啋鍙蜂箣澶栫殑浠绘剰瀛楃銆�
-                        //3.    (\d +) 锛氬尮閰嶇鍙e彿锛岀‘淇濆畠鍖归厤涓�涓垨澶氫釜鏁板瓧銆�
-
-                        string pattern = @"^\((?<ClassName>[^)]+)\)\[(?<IP>[^]]+)\]\[(?<Slot>[^]]+)\]\[(?<CpuType>[^]]+)\]\[(?<PlcAddress>[^]]+)\]$";
+                        // 鏇存柊姝e垯浠ユ敮鎸佸彲閫夌殑鏁版嵁绫诲瀷瀛楁
+                        string pattern = @"^\((?<ClassName>[^)]+)\)\[(?<IP>[^]]+)\]\[(?<Slot>[^]]+)\]\[(?<CpuType>[^]]+)\]\[(?<PlcAddress>[^]]+)\](?:\[(?<DataType>[^]]+)\])?$";
                         Match match = Regex.Match(CommunicatorAddress, pattern);
 
                         if (match.Success)
@@ -856,6 +852,8 @@
                             string Slot = match.Groups["Slot"].Value;        // "1111"
                             string CpuType= match.Groups["CpuType"].Value;
                             string PlcAddress = match.Groups["PlcAddress"].Value;
+                            string DataType = match.Groups["DataType"].Success ? match.Groups["DataType"].Value : "String";
+
                             if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(Slot) || string.IsNullOrEmpty(CpuType) || string.IsNullOrEmpty(PlcAddress))
                                 break;
 
@@ -878,6 +876,7 @@
                             Communicator.CommunicatorConnections.Add("绔彛", Slot);
                             Communicator.CommunicatorConnections.Add("鍨嬪彿", CpuType);
                             Communicator.CommunicatorConnections.Add("鍙橀噺鍦板潃", PlcAddress);
+                            Communicator.CommunicatorConnections.Add("鏁版嵁绫诲瀷", DataType);
                             Communicator.CommunicatorName = CommunicatorName;
                             if (!Communicator.Connect())
                             {
@@ -1038,11 +1037,14 @@
                     {
                         string CpuType = item.Value.CommunicatorConnections["鍨嬪彿"].ToString();
                         string PlcAddress = item.Value.CommunicatorConnections["鍙橀噺鍦板潃"].ToString();
+                        string DataType = item.Value.CommunicatorConnections.Contains("鏁版嵁绫诲瀷") ?
+                                          item.Value.CommunicatorConnections["鏁版嵁绫诲瀷"].ToString() : "String";
+
                         if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT) || string.IsNullOrEmpty(CpuType) || string.IsNullOrEmpty(PlcAddress))
                         {
                             break;
                         }
-                        string CommunicatorConnectionString = $"({ClassName})[{IP}][{PORT}][{CpuType}][{PlcAddress}]";
+                        string CommunicatorConnectionString = $"({ClassName})[{IP}][{PORT}][{CpuType}][{PlcAddress}][{DataType}]";
                         GlobalVar.allCommunicatorsConnectionString.TryAdd(item.Key, CommunicatorConnectionString);
                     }
                     else
diff --git a/LB_VisionProcesses/Communicators/CommunicatorForm.Designer.cs b/LB_VisionProcesses/Communicators/CommunicatorForm.Designer.cs
index d9998c9..f70e61d 100644
--- a/LB_VisionProcesses/Communicators/CommunicatorForm.Designer.cs
+++ b/LB_VisionProcesses/Communicators/CommunicatorForm.Designer.cs
@@ -37,25 +37,27 @@
             btnConnect = new Button();
             cmbIP = new ComboBox();
             lblIP = new Label();
+            lblDataType = new Label();
+            cmbDataType = new ComboBox();
             grpReceive = new GroupBox();
             txtReceiveMsg = new TextBox();
             txtSendMsg = new TextBox();
             btnSend = new Button();
             grpTest = new GroupBox();
             lblCom = new Label();
+            txtAddress = new TextBox();
             ckbRuleCheck = new CheckBox();
             cmbCom = new ComboBox();
             cmbType = new ComboBox();
             lblType = new Label();
             btnRun = new Button();
+            lblAddress = new Label();
             lblMsg = new Label();
             txtMsg = new TextBox();
             btnRuleSend = new Button();
             label6 = new Label();
             themeForm1 = new ReaLTaiizor.Forms.ThemeForm();
             controlBox1 = new ReaLTaiizor.Controls.ControlBox();
-            lblAddress = new Label();
-            txtAddress = new TextBox();
             grpSetting.SuspendLayout();
             grpReceive.SuspendLayout();
             grpTest.SuspendLayout();
@@ -72,42 +74,48 @@
             grpSetting.Controls.Add(cmbIP);
             grpSetting.Controls.Add(lblIP);
             grpSetting.ForeColor = SystemColors.Control;
-            grpSetting.Location = new Point(18, 74);
+            grpSetting.Location = new Point(22, 92);
+            grpSetting.Margin = new Padding(4);
             grpSetting.Name = "grpSetting";
-            grpSetting.Size = new Size(200, 146);
+            grpSetting.Padding = new Padding(4);
+            grpSetting.Size = new Size(250, 262);
             grpSetting.TabIndex = 0;
             grpSetting.TabStop = false;
             grpSetting.Text = "閫氳閰嶇疆";
             // 
             // txtIP
             // 
-            txtIP.Location = new Point(83, 32);
+            txtIP.Location = new Point(104, 40);
+            txtIP.Margin = new Padding(4);
             txtIP.Name = "txtIP";
-            txtIP.Size = new Size(100, 23);
+            txtIP.Size = new Size(124, 27);
             txtIP.TabIndex = 7;
             // 
             // txtPort
             // 
-            txtPort.Location = new Point(83, 70);
+            txtPort.Location = new Point(104, 88);
+            txtPort.Margin = new Padding(4);
             txtPort.Name = "txtPort";
-            txtPort.Size = new Size(100, 23);
+            txtPort.Size = new Size(124, 27);
             txtPort.TabIndex = 6;
             // 
             // lblPort
             // 
             lblPort.AutoSize = true;
-            lblPort.Location = new Point(17, 73);
+            lblPort.Location = new Point(21, 91);
+            lblPort.Margin = new Padding(4, 0, 4, 0);
             lblPort.Name = "lblPort";
-            lblPort.Size = new Size(32, 17);
+            lblPort.Size = new Size(39, 20);
             lblPort.TabIndex = 4;
             lblPort.Text = "绔彛";
             // 
             // btnDisconnect
             // 
             btnDisconnect.ForeColor = SystemColors.Control;
-            btnDisconnect.Location = new Point(118, 109);
+            btnDisconnect.Location = new Point(148, 136);
+            btnDisconnect.Margin = new Padding(4);
             btnDisconnect.Name = "btnDisconnect";
-            btnDisconnect.Size = new Size(75, 23);
+            btnDisconnect.Size = new Size(94, 29);
             btnDisconnect.TabIndex = 3;
             btnDisconnect.Text = "鏂紑";
             btnDisconnect.UseVisualStyleBackColor = true;
@@ -116,9 +124,10 @@
             // btnConnect
             // 
             btnConnect.ForeColor = SystemColors.Control;
-            btnConnect.Location = new Point(14, 109);
+            btnConnect.Location = new Point(18, 136);
+            btnConnect.Margin = new Padding(4);
             btnConnect.Name = "btnConnect";
-            btnConnect.Size = new Size(75, 23);
+            btnConnect.Size = new Size(94, 29);
             btnConnect.TabIndex = 2;
             btnConnect.Text = "杩炴帴";
             btnConnect.UseVisualStyleBackColor = true;
@@ -127,9 +136,10 @@
             // cmbIP
             // 
             cmbIP.FormattingEnabled = true;
-            cmbIP.Location = new Point(83, 31);
+            cmbIP.Location = new Point(104, 39);
+            cmbIP.Margin = new Padding(4);
             cmbIP.Name = "cmbIP";
-            cmbIP.Size = new Size(100, 25);
+            cmbIP.Size = new Size(124, 28);
             cmbIP.TabIndex = 1;
             cmbIP.Click += cmbIP_Click;
             cmbIP.MouseClick += cmbIP_MouseClick;
@@ -137,19 +147,41 @@
             // lblIP
             // 
             lblIP.AutoSize = true;
-            lblIP.Location = new Point(17, 36);
+            lblIP.Location = new Point(21, 45);
+            lblIP.Margin = new Padding(4, 0, 4, 0);
             lblIP.Name = "lblIP";
-            lblIP.Size = new Size(32, 17);
+            lblIP.Size = new Size(39, 20);
             lblIP.TabIndex = 0;
             lblIP.Text = "鍦板潃";
+            // 
+            // lblDataType
+            // 
+            lblDataType.AutoSize = true;
+            lblDataType.Location = new Point(206, 145);
+            lblDataType.Margin = new Padding(4, 0, 4, 0);
+            lblDataType.Name = "lblDataType";
+            lblDataType.Size = new Size(39, 20);
+            lblDataType.TabIndex = 8;
+            lblDataType.Text = "绫诲瀷";
+            // 
+            // cmbDataType
+            // 
+            cmbDataType.FormattingEnabled = true;
+            cmbDataType.Location = new Point(255, 140);
+            cmbDataType.Margin = new Padding(4);
+            cmbDataType.Name = "cmbDataType";
+            cmbDataType.Size = new Size(94, 28);
+            cmbDataType.TabIndex = 9;
             // 
             // grpReceive
             // 
             grpReceive.Controls.Add(txtReceiveMsg);
             grpReceive.ForeColor = SystemColors.Control;
-            grpReceive.Location = new Point(18, 311);
+            grpReceive.Location = new Point(22, 389);
+            grpReceive.Margin = new Padding(4);
             grpReceive.Name = "grpReceive";
-            grpReceive.Size = new Size(543, 174);
+            grpReceive.Padding = new Padding(4);
+            grpReceive.Size = new Size(679, 218);
             grpReceive.TabIndex = 5;
             grpReceive.TabStop = false;
             grpReceive.Text = "閫氳璁板綍";
@@ -157,28 +189,31 @@
             // txtReceiveMsg
             // 
             txtReceiveMsg.Dock = DockStyle.Fill;
-            txtReceiveMsg.Location = new Point(3, 19);
+            txtReceiveMsg.Location = new Point(4, 24);
+            txtReceiveMsg.Margin = new Padding(4);
             txtReceiveMsg.Multiline = true;
             txtReceiveMsg.Name = "txtReceiveMsg";
             txtReceiveMsg.ReadOnly = true;
             txtReceiveMsg.ScrollBars = ScrollBars.Both;
-            txtReceiveMsg.Size = new Size(537, 152);
+            txtReceiveMsg.Size = new Size(671, 190);
             txtReceiveMsg.TabIndex = 0;
             // 
             // txtSendMsg
             // 
             txtSendMsg.ForeColor = SystemColors.WindowText;
-            txtSendMsg.Location = new Point(18, 249);
+            txtSendMsg.Location = new Point(26, 311);
+            txtSendMsg.Margin = new Padding(4);
             txtSendMsg.Name = "txtSendMsg";
-            txtSendMsg.Size = new Size(543, 23);
+            txtSendMsg.Size = new Size(238, 27);
             txtSendMsg.TabIndex = 10;
             // 
             // btnSend
             // 
             btnSend.ForeColor = SystemColors.WindowText;
-            btnSend.Location = new Point(18, 282);
+            btnSend.Location = new Point(22, 352);
+            btnSend.Margin = new Padding(4);
             btnSend.Name = "btnSend";
-            btnSend.Size = new Size(75, 23);
+            btnSend.Size = new Size(94, 29);
             btnSend.TabIndex = 11;
             btnSend.Text = "鍙戦��";
             btnSend.UseVisualStyleBackColor = true;
@@ -196,10 +231,14 @@
             grpTest.Controls.Add(lblAddress);
             grpTest.Controls.Add(lblMsg);
             grpTest.Controls.Add(txtMsg);
+            grpTest.Controls.Add(lblDataType);
+            grpTest.Controls.Add(cmbDataType);
             grpTest.ForeColor = SystemColors.Control;
-            grpTest.Location = new Point(241, 74);
+            grpTest.Location = new Point(301, 92);
+            grpTest.Margin = new Padding(4);
             grpTest.Name = "grpTest";
-            grpTest.Size = new Size(320, 146);
+            grpTest.Padding = new Padding(4);
+            grpTest.Size = new Size(400, 262);
             grpTest.TabIndex = 12;
             grpTest.TabStop = false;
             grpTest.Text = "閫氳娴嬭瘯";
@@ -207,18 +246,29 @@
             // lblCom
             // 
             lblCom.AutoSize = true;
-            lblCom.Location = new Point(165, 40);
+            lblCom.Location = new Point(206, 50);
+            lblCom.Margin = new Padding(4, 0, 4, 0);
             lblCom.Name = "lblCom";
-            lblCom.Size = new Size(32, 17);
+            lblCom.Size = new Size(39, 20);
             lblCom.TabIndex = 9;
             lblCom.Text = "閫氳";
+            // 
+            // txtAddress
+            // 
+            txtAddress.Location = new Point(74, 140);
+            txtAddress.Margin = new Padding(4);
+            txtAddress.Name = "txtAddress";
+            txtAddress.ReadOnly = true;
+            txtAddress.Size = new Size(116, 27);
+            txtAddress.TabIndex = 6;
             // 
             // ckbRuleCheck
             // 
             ckbRuleCheck.AutoSize = true;
-            ckbRuleCheck.Location = new Point(55, 173);
+            ckbRuleCheck.Location = new Point(69, 216);
+            ckbRuleCheck.Margin = new Padding(4);
             ckbRuleCheck.Name = "ckbRuleCheck";
-            ckbRuleCheck.Size = new Size(99, 21);
+            ckbRuleCheck.Size = new Size(121, 24);
             ckbRuleCheck.TabIndex = 6;
             ckbRuleCheck.Text = "鏄惁瑙勫垯鏍¢獙";
             ckbRuleCheck.UseVisualStyleBackColor = true;
@@ -226,63 +276,80 @@
             // cmbCom
             // 
             cmbCom.FormattingEnabled = true;
-            cmbCom.Location = new Point(204, 35);
+            cmbCom.Location = new Point(255, 44);
+            cmbCom.Margin = new Padding(4);
             cmbCom.Name = "cmbCom";
-            cmbCom.Size = new Size(100, 25);
+            cmbCom.Size = new Size(124, 28);
             cmbCom.TabIndex = 8;
             cmbCom.SelectedIndexChanged += cmbCom_SelectedIndexChanged;
             // 
             // cmbType
             // 
             cmbType.FormattingEnabled = true;
-            cmbType.Location = new Point(59, 36);
+            cmbType.Location = new Point(74, 45);
+            cmbType.Margin = new Padding(4);
             cmbType.Name = "cmbType";
-            cmbType.Size = new Size(94, 25);
+            cmbType.Size = new Size(116, 28);
             cmbType.TabIndex = 5;
             // 
             // lblType
             // 
             lblType.AutoSize = true;
-            lblType.Location = new Point(21, 39);
+            lblType.Location = new Point(26, 49);
+            lblType.Margin = new Padding(4, 0, 4, 0);
             lblType.Name = "lblType";
-            lblType.Size = new Size(32, 17);
+            lblType.Size = new Size(39, 20);
             lblType.TabIndex = 4;
             lblType.Text = "绫诲瀷";
             // 
             // btnRun
             // 
             btnRun.ForeColor = SystemColors.WindowText;
-            btnRun.Location = new Point(215, 109);
+            btnRun.Location = new Point(269, 210);
+            btnRun.Margin = new Padding(4);
             btnRun.Name = "btnRun";
-            btnRun.Size = new Size(75, 23);
+            btnRun.Size = new Size(94, 29);
             btnRun.TabIndex = 3;
             btnRun.Text = "杩愯娴嬭瘯";
             btnRun.UseVisualStyleBackColor = true;
             btnRun.Click += btnRun_Click;
             // 
+            // lblAddress
+            // 
+            lblAddress.AutoSize = true;
+            lblAddress.Location = new Point(25, 144);
+            lblAddress.Margin = new Padding(4, 0, 4, 0);
+            lblAddress.Name = "lblAddress";
+            lblAddress.Size = new Size(39, 20);
+            lblAddress.TabIndex = 0;
+            lblAddress.Text = "鍦板潃";
+            // 
             // lblMsg
             // 
             lblMsg.AutoSize = true;
-            lblMsg.Location = new Point(20, 78);
+            lblMsg.Location = new Point(25, 98);
+            lblMsg.Margin = new Padding(4, 0, 4, 0);
             lblMsg.Name = "lblMsg";
-            lblMsg.Size = new Size(32, 17);
+            lblMsg.Size = new Size(39, 20);
             lblMsg.TabIndex = 1;
             lblMsg.Text = "娑堟伅";
             // 
             // txtMsg
             // 
-            txtMsg.Location = new Point(59, 76);
+            txtMsg.Location = new Point(74, 95);
+            txtMsg.Margin = new Padding(4);
             txtMsg.Name = "txtMsg";
             txtMsg.ReadOnly = true;
-            txtMsg.Size = new Size(245, 23);
+            txtMsg.Size = new Size(305, 27);
             txtMsg.TabIndex = 0;
             // 
             // btnRuleSend
             // 
             btnRuleSend.ForeColor = SystemColors.WindowText;
-            btnRuleSend.Location = new Point(118, 282);
+            btnRuleSend.Location = new Point(148, 352);
+            btnRuleSend.Margin = new Padding(4);
             btnRuleSend.Name = "btnRuleSend";
-            btnRuleSend.Size = new Size(75, 23);
+            btnRuleSend.Size = new Size(94, 29);
             btnRuleSend.TabIndex = 13;
             btnRuleSend.Text = "鏍¢獙鍙戦��";
             btnRuleSend.UseVisualStyleBackColor = true;
@@ -292,9 +359,10 @@
             // 
             label6.AutoSize = true;
             label6.ForeColor = SystemColors.Control;
-            label6.Location = new Point(18, 223);
+            label6.Location = new Point(22, 279);
+            label6.Margin = new Padding(4, 0, 4, 0);
             label6.Name = "label6";
-            label6.Size = new Size(56, 17);
+            label6.Size = new Size(69, 20);
             label6.TabIndex = 9;
             label6.Text = "鍙戦�佷俊鎭�";
             // 
@@ -306,11 +374,12 @@
             themeForm1.Font = new Font("Microsoft Sans Serif", 9F);
             themeForm1.Image = (Image)resources.GetObject("themeForm1.Image");
             themeForm1.Location = new Point(0, 0);
+            themeForm1.Margin = new Padding(4);
             themeForm1.Name = "themeForm1";
-            themeForm1.Padding = new Padding(10, 70, 10, 9);
+            themeForm1.Padding = new Padding(12, 88, 12, 11);
             themeForm1.RoundCorners = true;
             themeForm1.Sizable = true;
-            themeForm1.Size = new Size(581, 496);
+            themeForm1.Size = new Size(726, 620);
             themeForm1.SmartBounds = true;
             themeForm1.StartPosition = FormStartPosition.WindowsDefaultLocation;
             themeForm1.TabIndex = 14;
@@ -326,7 +395,8 @@
             controlBox1.EnableMaximizeButton = false;
             controlBox1.EnableMinimizeButton = false;
             controlBox1.ForeColor = Color.FromArgb(155, 155, 155);
-            controlBox1.Location = new Point(481, 18);
+            controlBox1.Location = new Point(601, 18);
+            controlBox1.Margin = new Padding(4);
             controlBox1.MaximizeHoverColor = Color.FromArgb(74, 74, 74);
             controlBox1.MinimizeHoverColor = Color.FromArgb(63, 63, 65);
             controlBox1.Name = "controlBox1";
@@ -334,28 +404,11 @@
             controlBox1.TabIndex = 0;
             controlBox1.Text = "controlBox1";
             // 
-            // lblAddress
-            // 
-            lblAddress.AutoSize = true;
-            lblAddress.Location = new Point(20, 115);
-            lblAddress.Name = "lblAddress";
-            lblAddress.Size = new Size(32, 17);
-            lblAddress.TabIndex = 0;
-            lblAddress.Text = "鍦板潃";
-            // 
-            // txtAddress
-            // 
-            txtAddress.Location = new Point(59, 112);
-            txtAddress.Name = "txtAddress";
-            txtAddress.ReadOnly = true;
-            txtAddress.Size = new Size(94, 23);
-            txtAddress.TabIndex = 6;
-            // 
             // CommunicatorForm
             // 
-            AutoScaleDimensions = new SizeF(96F, 96F);
+            AutoScaleDimensions = new SizeF(120F, 120F);
             AutoScaleMode = AutoScaleMode.Dpi;
-            ClientSize = new Size(581, 496);
+            ClientSize = new Size(726, 620);
             Controls.Add(btnRuleSend);
             Controls.Add(grpTest);
             Controls.Add(btnSend);
@@ -365,7 +418,8 @@
             Controls.Add(grpSetting);
             Controls.Add(themeForm1);
             FormBorderStyle = FormBorderStyle.None;
-            MinimumSize = new Size(261, 61);
+            Margin = new Padding(4);
+            MinimumSize = new Size(326, 76);
             Name = "CommunicatorForm";
             Text = "閫氳娴嬭瘯";
             TransparencyKey = Color.Fuchsia;
@@ -412,5 +466,7 @@
         private ReaLTaiizor.Controls.ControlBox controlBox1;
         private TextBox txtAddress;
         private Label lblAddress;
+        private Label lblDataType;
+        private ComboBox cmbDataType;
     }
 }
\ No newline at end of file
diff --git a/LB_VisionProcesses/Communicators/CommunicatorForm.cs b/LB_VisionProcesses/Communicators/CommunicatorForm.cs
index 0de5c45..37d6ac5 100644
--- a/LB_VisionProcesses/Communicators/CommunicatorForm.cs
+++ b/LB_VisionProcesses/Communicators/CommunicatorForm.cs
@@ -56,11 +56,26 @@
 
         private void CommunicatorForm_Load(object sender, EventArgs e)
         {
+            // 鍒濆鍖栨暟鎹被鍨�
+            cmbDataType.Items.Clear();
+            cmbDataType.Items.AddRange(new string[] { "String", "Bool", "Byte", "Int", "DInt", "Real", "Double", "Word", "DWord" });
+            
+            // 缁戝畾绱㈠紩鏀瑰彉浜嬩欢
+            cmbDataType.SelectedIndexChanged += (s, ev) =>
+            {
+                if (communicator != null)
+                {
+                    communicator.CommunicatorConnections.Add("鏁版嵁绫诲瀷", cmbDataType.Text);
+                }
+            };
+
             // 浣跨敤 Enum.GetValues 鑾峰彇 enum 绫诲瀷鐨勬墍鏈夊��
             foreach (CommunicatorType type in Enum.GetValues(typeof(CommunicatorType)))
             {
                 cmbType.Items.Add(type.ToString());
             }
+
+            // ... (淇濇寔涓嶅彉)
 
             //閫夋嫨Com浼氳Е鍙慥alueChanged浜嬩欢锛屾病鏈夎緭鍏ラ�氳鍙g殑鎯呭喌涓嬮�夋嫨鍒�-1
             if (comConfig != null)
@@ -118,10 +133,13 @@
                 txtIP.Visible = false;
                 this.lblAddress.Visible = false;
                 this.txtAddress.Visible = false;
+                this.lblDataType.Visible = false;
+                this.cmbDataType.Visible = false;
 
 
                 lblIP.Text = "涓插彛鍙�";
-                lblIP.Text = "娉㈢壒鐜�";
+                lblIP.Text = "娉㈢壒鐜�"; // Bug: 杩欓噷 lblPort 搴旇琚缃负 "娉㈢壒鐜�"锛屼絾鍘熶唬鐮佸鐢ㄤ簡 lblIP? 涓嶏紝lblIP.Text琚浜嗕袱娆°��
+                lblPort.Text = "娉㈢壒鐜�"; // 淇鍘熶唬鐮佺殑娼滃湪Bug
 
                 cmbIP.Text = communicator.CommunicatorConnections["鍦板潃"].ToString();
                 txtPort.Text = communicator.CommunicatorConnections["绔彛"].ToString();
@@ -136,10 +154,12 @@
                 txtIP.Visible = true;
                 this.lblAddress.Visible = false;
                 this.txtAddress.Visible = false;
+                this.lblDataType.Visible = false;
+                this.cmbDataType.Visible = false;
 
 
                 lblIP.Text = "鐩戞帶鏂囦欢";
-                lblIP.Text = "鍐欏叆鏂囦欢";
+                lblPort.Text = "鍐欏叆鏂囦欢"; // 淇鍘熶唬鐮佸彲鑳界殑閿欒
 
                 txtIP.Text = communicator.CommunicatorConnections["鍦板潃"].ToString();
                 txtPort.Text = communicator.CommunicatorConnections["绔彛"].ToString();
@@ -153,12 +173,21 @@
                 txtIP.Visible = true;
                 this.lblAddress.Visible = true;
                 this.txtAddress.Visible = true;
+                this.lblDataType.Visible = true;
+                this.cmbDataType.Visible = true;
+                
                 lblIP.Text = "IP";
-                lblIP.Text = "妲�";
+                lblPort.Text = "妲�"; // 鍘熶唬鐮佽繖閲屾槸 lblIP.Text="妲�" 瑕嗙洊浜� "IP"
 
                 txtIP.Text = communicator.CommunicatorConnections["鍦板潃"].ToString();
                 txtPort.Text = communicator.CommunicatorConnections["绔彛"].ToString();
                 this.txtAddress.Text = communicator.CommunicatorConnections["鍙橀噺鍦板潃"]?.ToString();
+                
+                if (communicator.CommunicatorConnections.Contains("鏁版嵁绫诲瀷"))
+                    this.cmbDataType.Text = communicator.CommunicatorConnections["鏁版嵁绫诲瀷"].ToString();
+                else
+                    this.cmbDataType.Text = "String";
+
                 this.grpSetting.ForeColor = SystemColors.Control;
                 btnRuleSend.Visible = false;
             }
@@ -168,12 +197,14 @@
                 btnRuleSend.Enabled = false;
                 this.lblAddress.Visible = false;
                 this.txtAddress.Visible = false;
+                this.lblDataType.Visible = false;
+                this.cmbDataType.Visible = false;
 
                 cmbIP.Visible = false;
                 txtIP.Visible = true;
 
                 lblIP.Text = " IP";
-                lblIP.Text = "绔彛";
+                lblPort.Text = "绔彛";
 
                 txtIP.Text = communicator.CommunicatorConnections["鍦板潃"].ToString();
                 txtPort.Text = communicator.CommunicatorConnections["绔彛"].ToString();
@@ -198,6 +229,13 @@
             {
                 communicator.CommunicatorConnections.Add("鍦板潃", cmbIP.SelectedItem.ToString());
                 communicator.CommunicatorConnections.Add("绔彛", txtPort.Text);
+            }
+            else if (communicator is SiemensLBS7)
+            {
+                communicator.CommunicatorConnections.Add("鍦板潃", txtIP.Text);
+                communicator.CommunicatorConnections.Add("绔彛", txtPort.Text);
+                communicator.CommunicatorConnections.Add("鍙橀噺鍦板潃", txtAddress.Text);
+                communicator.CommunicatorConnections.Add("鏁版嵁绫诲瀷", cmbDataType.Text);
             }
             else
             {
@@ -263,14 +301,37 @@
             MessageBox.Show(result ? "鏂紑鎴愬姛" : "鏂紑澶辫触,鍘熷洜鏄�:" + communicator.Msg);
         }
 
+        private void ShowLogMsg(string msg)
+        {
+            // 濡傛灉褰撳墠涓嶆槸 UI 绾跨▼锛屽垯閫氳繃 Invoke 灏嗘搷浣滆皟搴﹀埌 UI 绾跨▼
+            if (this.InvokeRequired)
+            {
+                this.Invoke(new Action<string>((message) =>
+                {
+                    this.txtReceiveMsg.AppendText("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + message + "\r\n");
+                    this.txtReceiveMsg.ScrollToCaret();
+                }), msg);
+            }
+            else
+            {
+                this.txtReceiveMsg.AppendText("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "] " + msg + "\r\n");
+                this.txtReceiveMsg.ScrollToCaret();
+            }
+        }
+
         private void btnSend_Click(object sender, EventArgs e)
         {
             if (communicator == null)
                 return;
 
-            communicator.SendMessage(txtSendMsg.Text);
-
-            ShowSendMsg(txtSendMsg.Text);
+            if (communicator.SendMessage(txtSendMsg.Text))
+            {
+                ShowSendMsg(txtSendMsg.Text);
+            }
+            else
+            {
+                ShowLogMsg(communicator.Msg);
+            }
         }
 
         private void btnRuleSend_Click(object sender, EventArgs e)
@@ -287,7 +348,14 @@
             //HexByte = strToHexByte(strSendMsg + crcString);
             SendMsg = SendMsg + crcString;
 
-            communicator.SendMessage(SendMsg);
+            if (communicator.SendMessage(SendMsg))
+            {
+                ShowSendMsg(SendMsg);
+            }
+            else
+            {
+                ShowLogMsg(communicator.Msg);
+            }
         }
 
         private void btnRun_Click(object sender, EventArgs e)
diff --git a/LB_VisionProcesses/Communicators/CommunicatorForm.resx b/LB_VisionProcesses/Communicators/CommunicatorForm.resx
index 83adc1a..922b5eb 100644
--- a/LB_VisionProcesses/Communicators/CommunicatorForm.resx
+++ b/LB_VisionProcesses/Communicators/CommunicatorForm.resx
@@ -121,7 +121,7 @@
   <data name="themeForm1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
-        wQAADsEBuJFr7QAAA+JJREFUWEftVkuIHGUQbt34iMEoq2S2q3p3yTJsuqpnJ+L6WBRdwaigohfFgEou
+        vgAADr4B6kKxwAAAA+JJREFUWEftVkuIHGUQbt34iMEoq2S2q3p3yTJsuqpnJ+L6WBRdwaigohfFgEou
         BkVBUPCBCEG8BXNQ48GLeImCehIJxMsqhsSZruod46K4HtSIGjU+4iOr0c1I9fSsM3/PLNtCPO0H36m/
         evz/X11VnreKVRTAHPOZumkY6lFwqURws3BwZ8ywTQnuiCP/+iTCzY1qaUPzdm/Atf3PaHre6XPsjyQM
         2xLGV4XwIyX4QRj+UMK/lPFvJTyhBMeV8IgQvmRJuH4Ko+l5p9UjGBbCJ5RxTgj+VMZmXxKcSAjekHE/
diff --git a/LB_VisionProcesses/Communicators/SiemensS7/SiemensLBS7.cs b/LB_VisionProcesses/Communicators/SiemensS7/SiemensLBS7.cs
index 006d3c6..84e8566 100644
--- a/LB_VisionProcesses/Communicators/SiemensS7/SiemensLBS7.cs
+++ b/LB_VisionProcesses/Communicators/SiemensS7/SiemensLBS7.cs
@@ -1,45 +1,103 @@
-锘縰sing LB_SmartVisionCommon;
+using LB_SmartVisionCommon;
 using S7.Net;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
-using System.Threading.Tasks;
+using System.Text.RegularExpressions;
+using System.Threading;
 
 namespace LB_VisionProcesses.Communicators.SiemensS7
 {
     public class SiemensLBS7 : BaseCommunicator
     {
         private Plc plc;
-        public string variable = string.Empty;
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="name"></param>
-        public SiemensLBS7(string name = "瑗块棬瀛怱7")
+        // 榛樿鍙橀噺鍦板潃
+        public string variable = "DB1.DBD0"; 
+        // 鏁版嵁绫诲瀷
+        private string dataType = "String";
+        
+        // 缂撳瓨杩炴帴鍙傛暟
+        private string ip = "127.0.0.1";
+        private short rack = 0;
+        private short slot = 1;
+        private CpuType cpuType = CpuType.S71500;
+
+        public SiemensLBS7(string name = "瑗块棬瀛怱7") : base(name)
         {
-            CommunicatorConnections.Add("鍦板潃", "127.0.0.1");
-            CommunicatorConnections.Add("绔彛", "1");
-            CommunicatorConnections.Add("鍨嬪彿", S7.Net.CpuType.S71500);
-            CommunicatorBrand = CommunicatorBrand.SiemensS7;
             CommunicatorName = name;
+            CommunicatorBrand = CommunicatorBrand.SiemensS7;
+            
+            // 鍒濆鍖栭粯璁ゅ弬鏁�
+            if (!CommunicatorConnections.Contains("鍦板潃")) CommunicatorConnections.Add("鍦板潃", "192.168.0.1");
+            if (!CommunicatorConnections.Contains("鏈烘灦鍙�")) CommunicatorConnections.Add("鏈烘灦鍙�", "0");
+            if (!CommunicatorConnections.Contains("鎻掓Ы鍙�")) CommunicatorConnections.Add("鎻掓Ы鍙�", "1");
+            if (!CommunicatorConnections.Contains("鍨嬪彿")) CommunicatorConnections.Add("鍨嬪彿", CpuType.S71500);
+            if (!CommunicatorConnections.Contains("鍙橀噺鍦板潃")) CommunicatorConnections.Add("鍙橀噺鍦板潃", "DB1.DBD0");
+            if (!CommunicatorConnections.Contains("鏁版嵁绫诲瀷")) CommunicatorConnections.Add("鏁版嵁绫诲瀷", "String");
+            
+            // 鍏煎鏃ч厤缃� "绔彛"
+            if (CommunicatorConnections.Contains("绔彛"))
+            {
+                CommunicatorConnections["鎻掓Ы鍙�"] = CommunicatorConnections["绔彛"];
+            }
+
+            // 璁剧疆榛樿蹇冭烦娑堟伅
+            strHeartbeat = "HEARTBEAT"; 
         }
+
         public override bool Connect()
         {
             try
             {
-                string IP = CommunicatorConnections["鍦板潃"].ToString();
-                short slot;
-                short.TryParse(CommunicatorConnections["绔彛"].ToString(), out slot);
-                S7.Net.CpuType cpuType = (CpuType)CommunicatorConnections["鍨嬪彿"];
-                variable = CommunicatorConnections["鍙橀噺鍦板潃"].ToString();
-                plc = new Plc(cpuType, IP, 0, slot);
-                plc.Open();
-                return true;
+                // 鏇存柊鍙傛暟
+                if (CommunicatorConnections.Contains("鍦板潃")) ip = CommunicatorConnections["鍦板潃"].ToString();
+                
+                if (CommunicatorConnections.Contains("鏈烘灦鍙�")) 
+                    short.TryParse(CommunicatorConnections["鏈烘灦鍙�"].ToString(), out rack);
+                
+                if (CommunicatorConnections.Contains("鎻掓Ы鍙�")) 
+                    short.TryParse(CommunicatorConnections["鎻掓Ы鍙�"].ToString(), out slot);
+                else if (CommunicatorConnections.Contains("绔彛"))
+                    short.TryParse(CommunicatorConnections["绔彛"].ToString(), out slot);
 
+                if (CommunicatorConnections.Contains("鍨嬪彿"))
+                {
+                    if (CommunicatorConnections["鍨嬪彿"] is CpuType type)
+                        cpuType = type;
+                    else
+                        Enum.TryParse(CommunicatorConnections["鍨嬪彿"].ToString(), out cpuType);
+                }
+                
+                if (CommunicatorConnections.Contains("鍙橀噺鍦板潃"))
+                    variable = CommunicatorConnections["鍙橀噺鍦板潃"].ToString();
+
+                if (CommunicatorConnections.Contains("鏁版嵁绫诲瀷"))
+                    dataType = CommunicatorConnections["鏁版嵁绫诲瀷"].ToString();
+
+                // 鍏抽棴鏃ц繛鎺�
+                plc?.Close();
+                
+                plc = new Plc(cpuType, ip, rack, slot);
+                plc.Open();
+                
+                if (plc.IsConnected)
+                {
+                    bConnected = true;
+                    AsyncLogHelper.Info($"Device:[{CommunicatorName}] 宸茶繛鎺ュ埌 {ip} 鏈烘灦:{rack} 鎻掓Ы:{slot}");
+                    return true;
+                }
+                else
+                {
+                    bConnected = false;
+                    AsyncLogHelper.Error($"Device:[{CommunicatorName}] 杩炴帴澶辫触: IsConnected 涓� false");
+                    return false;
+                }
             }
-            catch
+            catch (Exception ex)
             {
+                bConnected = false;
+                AsyncLogHelper.Error($"Device:[{CommunicatorName}] 杩炴帴閿欒: {ex.Message}");
                 return false;
             }
         }
@@ -48,7 +106,223 @@
         {
             try
             {
-                plc?.Close();
+                if (plc != null)
+                {
+                    plc.Close();
+                    bConnected = false;
+                    AsyncLogHelper.Info($"Device:[{CommunicatorName}] 宸叉柇寮�杩炴帴");
+                }
+                return true;
+            }
+            catch (Exception ex)
+            {
+                AsyncLogHelper.Error($"Device:[{CommunicatorName}] 鏂紑杩炴帴閿欒: {ex.Message}");
+                return false;
+            }
+        }
+
+        public override bool SendMessage(string message)
+        {
+            if (plc == null || !plc.IsConnected)
+            {
+                Msg = "杩炴帴鏈紑鍚�";
+                return false;
+            }
+
+            if (message == strHeartbeat) return plc.IsConnected;
+
+            try
+            {
+                string targetVar = variable;
+                string strValue = message;
+
+                // 绠�鍗曠殑鍗忚瑙f瀽锛氬湴鍧�:鍊�
+                if (message.Contains(":"))
+                {
+                    var parts = message.Split(new char[] { ':' }, 2);
+                    if (parts.Length == 2 && !string.IsNullOrWhiteSpace(parts[0]))
+                    {
+                        targetVar = parts[0];
+                        strValue = parts[1];
+                    }
+                }
+
+                object valueToWrite = strValue;
+                // 鑾峰彇褰撳墠鏁版嵁绫诲瀷閰嶇疆
+                string currentDataType = CommunicatorConnections.Contains("鏁版嵁绫诲瀷") ? CommunicatorConnections["鏁版嵁绫诲瀷"].ToString() : "String";
+
+                // 鏍规嵁閰嶇疆鐨勬暟鎹被鍨嬭繘琛岃浆鎹�
+                try 
+                {
+                    switch (currentDataType)
+                    {
+                        case "Bool":
+                            if (strValue == "1") valueToWrite = true;
+                            else if (strValue == "0") valueToWrite = false;
+                            else valueToWrite = bool.Parse(strValue);
+                            break;
+                        case "Byte":
+                            valueToWrite = byte.Parse(strValue);
+                            break;
+                        case "Int": // 16-bit
+                            valueToWrite = short.Parse(strValue);
+                            break;
+                        case "DInt": // 32-bit
+                            valueToWrite = int.Parse(strValue);
+                            break;
+                        case "Word": // 16-bit unsigned
+                            valueToWrite = ushort.Parse(strValue);
+                            break;
+                        case "DWord": // 32-bit unsigned
+                            valueToWrite = uint.Parse(strValue);
+                            break;
+                        case "Real": // Float
+                            valueToWrite = float.Parse(strValue);
+                            break;
+                        case "Double": // LReal
+                            valueToWrite = double.Parse(strValue);
+                            break;
+                        case "String":
+                        default:
+                            valueToWrite = strValue;
+                            break;
+                    }
+                }
+                catch (FormatException)
+                {
+                    Msg = $"鏃犳晥鐨剓currentDataType}鍊硷紝璇疯緭鍏ユ纭牸寮忋��";
+                    if (currentDataType == "Bool") Msg += " (true/false 鎴� 1/0)";
+                    AsyncLogHelper.Error($"Device:[{CommunicatorName}] {Msg}");
+                    return false;
+                }
+                catch (Exception castEx)
+                {
+                    Msg = $"鏁版嵁杞崲閿欒({currentDataType}): {castEx.Message}";
+                    AsyncLogHelper.Error($"Device:[{CommunicatorName}] {Msg}");
+                    return false;
+                }
+
+                // 灏濊瘯鍐欏叆
+                plc.Write(targetVar, valueToWrite);
+                AsyncLogHelper.Info($"Device:[{CommunicatorName}] 鍐欏叆({currentDataType}) {targetVar} = {valueToWrite}");
+                return true;
+            }
+            catch (Exception ex)
+            {
+                Msg = $"鍙戦�佹秷鎭敊璇�: {ex.Message}";
+                AsyncLogHelper.Error($"Device:[{CommunicatorName}] {Msg}");
+                return false;
+            }
+        }
+
+        public override string ReceiveMsg()
+        {
+            if (plc == null || !plc.IsConnected) return string.Empty;
+
+            try
+            {
+                // 鑾峰彇褰撳墠鏁版嵁绫诲瀷閰嶇疆
+                string currentDataType = CommunicatorConnections.Contains("鏁版嵁绫诲瀷") ? CommunicatorConnections["鏁版嵁绫诲瀷"].ToString() : "String";
+
+                if (currentDataType == "String")
+                {
+                    var match = Regex.Match(variable, @"DB(\d+)\.DB[B|W|D|X]?(\d+)", RegexOptions.IgnoreCase);
+                    if (match.Success)
+                    {
+                        try
+                        {
+                            int db = int.Parse(match.Groups[1].Value);
+                            int startByte = int.Parse(match.Groups[2].Value);
+
+                            // 璇诲彇澶撮儴 (MaxLen, ActLen)
+                            byte[] header = plc.ReadBytes(DataType.DataBlock, db, startByte, 2);
+                            if (header != null && header.Length >= 2)
+                            {
+                                int actLen = header[1];
+                                if (actLen > 0)
+                                {
+                                    // 璇诲彇瀹為檯瀛楃鏁版嵁
+                                    byte[] strBytes = plc.ReadBytes(DataType.DataBlock, db, startByte + 2, actLen);
+                                    strReceiveMsg = Encoding.ASCII.GetString(strBytes);
+                                    return strReceiveMsg;
+                                }
+                                else
+                                {
+                                    strReceiveMsg = string.Empty;
+                                    return strReceiveMsg;
+                                }
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            AsyncLogHelper.Error($"Device:[{CommunicatorName}] 璇诲彇S7String澶辫触: {ex.Message}");
+                        }
+                    }
+                    // 濡傛灉姝e垯涓嶅尮閰嶆垨璇诲彇澶辫触锛屽洖閫�鍒伴粯璁よ鍙�
+                }
+
+                var result = plc.Read(variable);
+                if (result != null)
+                {
+                    // 灏濊瘯鏍规嵁 dataType 鏍煎紡鍖栬緭鍑� (S7.Net 璇诲嚭鏉ョ殑绫诲瀷鍙兘涓庨鏈熶笉绗︼紝鐗瑰埆鏄� DWord/Real)
+                    // 渚嬪 DBD0 榛樿璇诲嚭鏉ユ槸 UInt32锛屽鏋� dataType 鏄� Real锛岄渶瑕佽浆鎹�
+                    if (currentDataType == "Real" && (result is uint || result is int))
+                    {
+                        byte[] bytes = BitConverter.GetBytes(Convert.ToUInt32(result));
+                        float f = BitConverter.ToSingle(bytes, 0);
+                        strReceiveMsg = f.ToString();
+                    }
+                    else
+                    {
+                        strReceiveMsg = result.ToString();
+                    }
+                    return strReceiveMsg;
+                }
+            }
+            catch (Exception ex)
+            {
+                AsyncLogHelper.Error($"Device:[{CommunicatorName}] 鎺ユ敹娑堟伅閿欒: {ex.Message}");
+            }
+            return string.Empty;
+        }
+
+        /// <summary>
+        /// 甯﹀~鍏呯殑 S7 瀛楃涓插啓鍏ワ紝闃叉娈嬬暀鏁版嵁
+        /// </summary>
+        private bool WriteS7StringWithPadding(string address, string value)
+        {
+            try
+            {
+                // 瑙f瀽鍦板潃锛屼緥濡� DB1.DBB0, DB1.DBD0
+                var match = Regex.Match(address, @"DB(\d+)\.DB[B|W|D|X]?(\d+)", RegexOptions.IgnoreCase);
+                if (!match.Success) return false;
+
+                int db = int.Parse(match.Groups[1].Value);
+                int startByte = int.Parse(match.Groups[2].Value);
+
+                byte maxLen = 254; // 榛樿鏈�澶у��
+                try
+                {
+                    var header = plc.ReadBytes(DataType.DataBlock, db, startByte, 1);
+                    if (header != null && header.Length > 0 && header[0] > 0)
+                    {
+                        maxLen = header[0];
+                    }
+                }
+                catch { }
+
+                byte[] buffer = new byte[maxLen + 2];
+                buffer[0] = maxLen;
+                int currentLen = Math.Min(value.Length, maxLen);
+                buffer[1] = (byte)currentLen;
+
+                if (currentLen > 0)
+                {
+                    byte[] strBytes = Encoding.ASCII.GetBytes(value);
+                    Array.Copy(strBytes, 0, buffer, 2, Math.Min(strBytes.Length, currentLen));
+                }
+
+                plc.WriteBytes(DataType.DataBlock, db, startByte, buffer);
                 return true;
             }
             catch
@@ -56,45 +330,31 @@
                 return false;
             }
         }
-
-        public override bool SendMessage(string message)
+        
+        public object Read(string address)
         {
-            try
-            {
-                if (plc!=null)
-                {
-                    if (string.IsNullOrEmpty(variable))
-                    {
-                        variable = CommunicatorConnections["鍙橀噺鍦板潃"].ToString();
-                    }
-                    plc.Write(variable, message);
-                    return true;
-                }
-                else
-                {
-                    return false;
-                }
-            }
-            catch
-            {
-                return false;
-            }
+             if (plc == null || !plc.IsConnected) return null;
+             return plc.Read(address);
+        }
+        
+        public void Write(string address, object value)
+        {
+             if (plc != null && plc.IsConnected)
+                plc.Write(address, value);
         }
 
         public override void Dispose()
         {
             try
             {
-                AsyncLogHelper.Info($"Device:[{CommunicatorName}],Dispose()");
-
+                AsyncLogHelper.Info($"Device:[{CommunicatorName}],閲婃斁璧勬簮(Dispose)");
+                plc?.Close();
                 plc = null;
-
-                // Suppress finalization.
                 GC.SuppressFinalize(this);
             }
             catch (Exception ex)
             {
-                AsyncLogHelper.Error($"Device:[{CommunicatorName}],Dispose(),Error" + ex);
+                AsyncLogHelper.Error($"Device:[{CommunicatorName}],閲婃斁璧勬簮(Dispose)閿欒: " + ex.Message);
             }
         }
     }

--
Gitblit v1.9.3