From 471d42c8bda78f914996475558a183f298bf1f54 Mon Sep 17 00:00:00 2001 From: liuwf Date: Tue, 16 Jul 2024 18:38:51 +0800 Subject: [PATCH] =?UTF-8?q?add-=E6=B7=BB=E5=8A=A0=E5=96=B7=E7=A0=81?= =?UTF-8?q?=E6=9C=BA=E6=9D=A1=E7=A0=81=E8=BD=AC=E6=8D=A2=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SlnMesnac.Business/ProdCompletionBusiness.cs | 2 +- SlnMesnac.Common/GunHelper.cs | 258 +++++++++++-------- SlnMesnac.WPF/ViewModel/ProdMgmtViewModel.cs | 5 + 3 files changed, 150 insertions(+), 115 deletions(-) diff --git a/SlnMesnac.Business/ProdCompletionBusiness.cs b/SlnMesnac.Business/ProdCompletionBusiness.cs index b4c5b87..0fef559 100644 --- a/SlnMesnac.Business/ProdCompletionBusiness.cs +++ b/SlnMesnac.Business/ProdCompletionBusiness.cs @@ -47,7 +47,7 @@ namespace SlnMesnac.Business private readonly IMesProductPlanService _mesProductPlanService; private readonly IRealBarCodeTaskService _barCodeTaskService; - private readonly GunHelper gunHelper = GunHelper.Instance; + private List _barCodeTasks; public ProdCompletionBusiness(ILogger logger, AppConfig appConfig, List plcFactories, List rfidFactories, IMesProductPlanService mesProductPlanService, IRealBarCodeTaskService barCodeTaskService, List barCodeTasks,IServiceProvider serviceProvider) : base(logger, appConfig, plcFactories, rfidFactories, serviceProvider) diff --git a/SlnMesnac.Common/GunHelper.cs b/SlnMesnac.Common/GunHelper.cs index c7f478b..a3ba701 100644 --- a/SlnMesnac.Common/GunHelper.cs +++ b/SlnMesnac.Common/GunHelper.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; +using System.IO; using System.IO.Ports; using System.Linq; using System.Text; @@ -44,7 +45,7 @@ namespace SlnMesnac.Common try { //端口名 注:因为使用的是USB转RS232 所以去设备管理器中查看一下虚拟com口的名字 - serialPort.PortName = "COM3";// portName; + serialPort.PortName = "COM1";// portName; //波特率 霍尼威尔扫码枪115200,普通9600 serialPort.BaudRate = 9600; //奇偶校验 @@ -61,8 +62,9 @@ namespace SlnMesnac.Common //开启串口 serialPort.Open(); - - + //SendData("202 407 16B1"); + + } catch (Exception ex) { @@ -95,159 +97,187 @@ namespace SlnMesnac.Common /// /// 发送数据方法 - /// OK-校验成功关闭灯光,NG-校验失败闪烁红灯 /// /// public void SendData(string data) { - //try - //{ - // if (serialPort.IsOpen) - // { - - // if (data == "NG") - // { - // byte[] buffer = GetBytesByCommand("CloseRed"); - // serialPort.Write(buffer, 0x0, 0x4); - // byte[] buffer1 = GetBytesByCommand("OpenRed"); - // serialPort.Write(buffer1, 0x0, 0x4); - // } - // else if (data == "OK") - // { - // byte[] buffer = GetBytesByCommand("CloseRed"); - // serialPort.Write(buffer, 0x0, 0x4); - // byte[] buffer1 = GetBytesByCommand("OpenGreen"); - // serialPort.Write(buffer1, 0x0, 0x4); - // } - // else if (data == "Exit") - // { - // byte[] buffer = GetBytesByCommand("CloseRed"); - // serialPort.Write(buffer, 0x0, 0x4); - // } - - // } - // else - // { - // Console.WriteLine("串口未打开,请先初始化串口并打开连接。"); - // } - //} - //catch (Exception ex) - //{ - // Console.WriteLine($"发送数据时发生错误:{ex.Message}"); - //} + byte[] buffer = GetBytesByCommand(data); + serialPort.Write(buffer, 0, buffer.Length); } /// - /// 条码根据通信协议转换 + /// 条码转换为待发送字节数组 /// /// /// private byte[] GetBytesByCommand(string barCode) { byte[] buffer = null; - //byte[] SOI = new byte[] { 0x7E }; - //byte[] OrderID = new byte[] { 0x02 }; - //byte[] MemoID = new byte[] { 0x00 }; - - //byte[] Info = EncodeInfoData(barCode); - //byte[] Length = GetLength(Info.Length); - //byte CheckSum = GetCheckSum(OrderID,MemoID,Length,Info); - //byte[] EOI = new byte[] { 0x0D }; - // 起始结束:7E\0D; SOI OrderID MemoID Length Info CheckSum EOI - // buffer = new byte[] { 0x7E, 0x01, 0x00, Length, iNFO, CheckSum, 0x0D }; - - + byte[] SOI = new byte[] { 0x7E }; + byte[] OrderID = new byte[] { 0x30, 0x32 }; + byte[] MemoID = new byte[] { 0x30, 0x31 }; + byte[] Info = GetInfoBytes(barCode); + byte[] Length = GetLengthByte(Info.Length); + byte[] CheckSum = GetCheckSumBytes(OrderID, MemoID, Info, Length); + byte[] EOI = new byte[] { 0x0D }; + + using (MemoryStream stream = new MemoryStream()) + { + // 将所有数组依次写入 MemoryStream + stream.Write(SOI, 0, SOI.Length); + stream.Write(OrderID, 0, OrderID.Length); + stream.Write(MemoID, 0, MemoID.Length); + stream.Write(Length, 0, Length.Length); + stream.Write(Info, 0, Info.Length); + stream.Write(CheckSum, 0, CheckSum.Length); + stream.Write(EOI, 0, EOI.Length); + + // 获取最终的合并后的字节数组 + buffer = stream.ToArray(); + } - return buffer ; + return buffer; } - //private byte[] GetLength(int length) - //{ - //} + #region 计算Info数据 - private byte[] GetCheckSum(byte[] OrderID, byte[] MemoID, byte[] Length, byte[] Info) + public byte[] GetInfoBytes(string input) { - // 合并所有数据部分,除去 SOI 和 EOI - List dataList = new List(); - dataList.AddRange(OrderID); - dataList.AddRange(MemoID); - dataList.AddRange(Length); - dataList.AddRange(Info); - - // 计算数据的总和 - int sum = 0; - foreach (byte b in dataList) + try { - sum += b; + List bytes = new List(); + + // X + bytes.Add(0x30); + bytes.Add(0x30); + bytes.Add(0x35); + bytes.Add(0x38); + //0 + bytes.Add(0x30); + bytes.Add(0x30); + bytes.Add(0x33); + bytes.Add(0x30); + + foreach (char c in input) + { + byte[] charBytes = ConvertCharToBytes(c); + foreach (byte b in charBytes) + { + bytes.Add(b); + } + } + + // 固定尾部分隔符 + bytes.Add(0x30); + bytes.Add(0x30); + bytes.Add(0x31); + bytes.Add(0x46); + + return bytes.ToArray(); } + catch (Exception ex) + { + // 处理异常,这里可以根据实际情况处理异常,例如记录日志等 + Console.WriteLine($"Error in GetInfoBytes: {ex.Message}"); + return null; + } + } - // 取模 65536 - int moduloResult = sum % 65536; - - // 求反并加1 - ushort lCheckSUM = (ushort)((~moduloResult & 0xFFFF) + 1); + // 将字符转换为符合规则的四字节表示 + public byte[] ConvertCharToBytes(char c) + { + byte[] result = new byte[4]; - // 转换为字节数组,传输时用4个字节 - byte[] checkSumBytes = new byte[4]; - checkSumBytes[0] = (byte)((lCheckSUM >> 8) & 0xFF); // 高位 - checkSumBytes[1] = (byte)(lCheckSUM & 0xFF); // 低位 - checkSumBytes[2] = 0; // 额外的两个字节可以填充为0 - checkSumBytes[3] = 0; + // 获取字符的 ASCII 码 + byte ascii = (byte)c; - return checkSumBytes; - } + // 高4位的 ASCII 码表示 + byte high4 = (byte)((ascii >> 4) + 0x30); + // 低4位的 ASCII 码表示 + byte low4 = (byte)((ascii & 0x0F) + 0x30); + // 构建四字节表示,前两位和后两位 + result[0] = 0x30; // 高位补 '0' + result[1] = 0x30; // 高位补 '0' + result[2] = high4; + result[3] = low4; - public byte[] EncodeInfoData(string data) - { - // 分隔符 - byte separator = 0x1F; - - // 将数据和useFileName转换成字节序列 - byte[] dataBytes = EncodeDataForTransmission(data); - - // 组合所有字节序列 - List encodedBytes = new List(); - - encodedBytes.AddRange(dataBytes); - encodedBytes.Add(separator); - return encodedBytes.ToArray(); + return result; } + #endregion - - byte[] EncodeDataForTransmission(string input) + #region 计算Length 将十进制数转换为两个字节的 ASCII 表示 + public byte[] GetLengthByte(int dec) { - byte[] encodedBytes = new byte[input.Length * 2]; // 每个字符转换为两个字节 + byte[] result = new byte[4]; - for (int i = 0; i < input.Length; i++) + // 将十进制数转换为十六进制字符串 + string hexString = dec.ToString("X4"); + + for (int i = 0; i < hexString.Length; i++) { - char c = input[i]; + char c = hexString[i]; + + int asciiValue = (int)c; - // 将字符转换为ASCII码 - byte asciiValue = (byte)c; + + result[i] = Convert.ToByte(asciiValue.ToString("X2"), 16); + } - // 将ASCII码拆分为高4位和低4位 - byte highNibble = (byte)((asciiValue >> 4) & 0xF); // 高4位 - byte lowNibble = (byte)(asciiValue & 0xF); // 低4位 + return result; + } + #endregion - // 转换成ASCII码形式 - byte highNibbleAscii = (byte)(highNibble + 0x30); // 转成ASCII码 - byte lowNibbleAscii = (byte)(lowNibble + 0x30); // 转成ASCII码 + #region 计算校验码 + public byte[] GetCheckSumBytes(byte[] OrderID, byte[] MemoID, byte[] Info, byte[] Length) + { + byte[] result = new byte[4]; // 始终返回四个字节 + // 计算校验和 + ushort checksum = CalculateLCheckSum(OrderID, MemoID, Info, Length); + string checksumHex = checksum.ToString("X4"); + for (int i = 0; i < checksumHex.Length; i++) + { + char c = checksumHex[i]; + // 获取字符 c 的 ASCII 码 + int asciiValue = (int)c; - // 存储到结果数组中 - encodedBytes[2 * i] = highNibbleAscii; - encodedBytes[2 * i + 1] = lowNibbleAscii; + // 将 ASCII 码转换成十六进制表示,并存储到 result 数组中 + result[i] = Convert.ToByte(asciiValue.ToString("X2"), 16); } - - return encodedBytes; + return result; } + private ushort CalculateLCheckSum(byte[] OrderID, byte[] MemoID, byte[] Info, byte[] Length) + { + // 计算除去 SOI、EOI 和 CheckSUM 外的数据的和 + int sum = CalculateSumWithoutCheckSum(OrderID) + + CalculateSumWithoutCheckSum(MemoID) + + CalculateSumWithoutCheckSum(Info) + + CalculateSumWithoutCheckSum(Length); + + // 取模 65536 + ushort modResult = (ushort)(sum % 65536); + + // 求反加1 + ushort checksum = (ushort)(((ushort)~modResult) + 1); + + return checksum; + } + private int CalculateSumWithoutCheckSum(byte[] data) + { + int sum = 0; + foreach (byte b in data) + { + sum += b; + } + return sum; + } + #endregion - } diff --git a/SlnMesnac.WPF/ViewModel/ProdMgmtViewModel.cs b/SlnMesnac.WPF/ViewModel/ProdMgmtViewModel.cs index 55a2908..eb84529 100644 --- a/SlnMesnac.WPF/ViewModel/ProdMgmtViewModel.cs +++ b/SlnMesnac.WPF/ViewModel/ProdMgmtViewModel.cs @@ -17,6 +17,8 @@ using Newtonsoft.Json.Linq; using System.Collections; using Microsoft.IdentityModel.Logging; using System.Windows.Documents; +using SlnMesnac.Common; +using HslCommunication.Profinet.GE; namespace SlnMesnac.WPF.ViewModel { @@ -35,6 +37,8 @@ namespace SlnMesnac.WPF.ViewModel private ObservableCollection listItems = new ObservableCollection(); + private readonly GunHelper gunHelper = GunHelper.Instance; + #region 参数定义 /// /// 工位名称 @@ -164,6 +168,7 @@ namespace SlnMesnac.WPF.ViewModel public ProdMgmtViewModel() { + gunHelper.InstanceSerialPort(); StartProdPlanCommand = new RelayCommand(obj => StartProdPlan(obj)); StopProdPlanCommand = new RelayCommand(obj => StopProdPlan(obj)); _logger = App.ServiceProvider.GetService>();