From 919a8efe5f75b9d84ed79c91dfbea5263da8ce59 Mon Sep 17 00:00:00 2001
From: C3032 <C3032@BC3032>
Date: 星期五, 16 一月 2026 09:34:39 +0800
Subject: [PATCH] Merge branch 'feature/Camera3D'
---
LB_VisionProcesses/Communicators/SiemensS7/SiemensLBS7.cs | 358 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 309 insertions(+), 49 deletions(-)
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