using System; using System.Collections.Generic; using System.Configuration; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using ZJ_BYD.ViewModel; namespace ZJ_BYD.Untils { public class CAN2DeviceHelper : Singleton { public DeviceInfo DeviceInfo { get; set; } = new DeviceInfo(); List> _dataList = new List>(); List _data = new List(); SerialPort _serialPort; /// /// CAN通讯 /// /// 软件编码 /// 是否写入序列号 /// 零部件号 /// 打印条码组成字符(例如:D) /// 流水号 /// 序列号 public void Run(string softCode, bool isSerialNum, string partCode, string printBarcode, string num,out string _serialNum) { _serialNum=string.Empty; try { string PortName = ConfigurationManager.AppSettings["PortName"]; int BaudRate = int.Parse(ConfigurationManager.AppSettings["BaudRate"]); int Parity = int.Parse(ConfigurationManager.AppSettings["Parity"]); int DataBits = int.Parse(ConfigurationManager.AppSettings["DataBits"]); int StopBits = int.Parse(ConfigurationManager.AppSettings["StopBits"]); if (_serialPort != null && _serialPort.IsOpen) { _serialPort.Close(); } _serialPort = null; _dataList = new List>(); bufferQueue = new Queue(); _data = new List(); _serialPort = new SerialPort { PortName = PortName, BaudRate = BaudRate, Parity = (Parity)Parity, DataBits = DataBits, StopBits = (StopBits)StopBits }; _serialPort.DataReceived += _serialPort_DataReceived; _serialPort.Open(); string sendString = null; //如果掩码表中配置了软件编码,则需要请求 if (!string.IsNullOrWhiteSpace(softCode)) { //1.发送软件编码 sendString = "68 07 00 04 00 20 A1 07 00 00 3B 16 68 13 00 02 00 01 00 00 08 00 B3 07 00 00 03 22 F1 94 55 55 55 55 3E 16 68 13 00 02 00 01 00 00 08 00 B3 07 00 00 30 00 00 00 00 00 00 00 70 16"; Info($"1.发送-->软件编码:{sendString}"); var writeResult1 = writeData(sendString); if (!writeResult1.isok) { Info($"1.发送-->软件编码异常:{writeResult1.msg}"); } getSoftwareCode();//解析软件编码 Info($"1.解析软件编码结果:{DeviceInfo.SoftwareCode}"); } //2.发送引导报文 sendString = "68 13 00 02 00 01 00 00 08 00 22 07 00 00 03 22 F1 80 55 55 55 55 99 16 68 13 00 02 00 01 00 00 08 00 22 07 00 00 30 00 00 00 00 00 00 00 DF 16"; Info($"2.发送-->引导报文:{sendString}"); var writeResult2 = writeData(sendString); if (!writeResult2.isok) { Info($"2.发送-->引导报文异常:{writeResult2.msg}"); } getGuideVersion();//解析引导报文 Info($"2.解析引导报文结果:{DeviceInfo.GuideVersion}"); //3.清除故障 sendString = "68 13 00 02 00 01 00 00 08 00 B3 07 00 00 04 14 FF FF FF AA AA AA 53 16"; Info($"3.1发送-->清除故障:{sendString}"); byte[] sendBytes = HexStrToByteArray(sendString); if (sendBytes == null) { return; } _serialPort.Write(sendBytes, 0, sendBytes.Length); Thread.Sleep(500); sendString = "68 13 00 02 00 01 00 00 08 00 B3 07 00 00 03 19 01 09 55 55 55 55 BA 16 68 13 00 02 00 01 00 00 08 00 B3 07 00 00 30 00 00 00 00 00 00 00 70 16"; Info($"3.2发送-->清除故障:{sendString}"); var writeResult3 = writeData(sendString); if (!writeResult3.isok) { Info($"3.2发送-->清除故障异常:{writeResult3.msg}"); } getClearFault();//解析清除故障 Info($"3.2解析清除故障结果:{DeviceInfo.ClearFault}"); //4.软件版本号 sendString = "68 13 00 02 00 01 00 00 08 00 22 07 00 00 03 22 F1 95 55 55 55 55 AE 16 68 13 00 02 00 01 00 00 08 00 22 07 00 00 30 00 00 00 00 00 00 00 DF 16"; Info($"4.发送-->软件版本号:{sendString}"); var writeResult4 = writeData(sendString); if (!writeResult4.isok) { Info($"4.发送-->软件版本号异常:{writeResult4.msg}"); } getSoftwareVersion();//解析软件版本号 Info($"4.解析软件版本号结果:{DeviceInfo.SoftwareVersion}"); //5.电压 getVoltage(); Info($"5.接收--电压:{DeviceInfo.Voltage}"); if (isSerialNum) { //6.写入零部件号 var sendHexList = GetParCodeHexMsg(partCode); if (sendHexList.Count > 0) { var writeResult6 = writeData(sendString); if (!writeResult6.isok) { Info($"6.写入-->零部件号异常:{writeResult6.msg}"); } } //7.获取零部件号 sendString = "68 13 00 02 00 01 00 00 08 00 22 07 00 00 03 22 01 05 55 55 55 55 2E 16 68 13 00 02 00 01 00 00 08 00 22 07 00 00 30 00 00 55 55 55 55 55 88 16"; var writeResult7 = writeData(sendString); if (!writeResult7.isok) { Info($"7.获取-->零部件号异常:{writeResult7.msg}"); } getPartCode();//解析零部件号 Info($"7.接收--零部件号:{DeviceInfo.PartCode}"); //8.写入序列号 if (!string.IsNullOrWhiteSpace(DeviceInfo.PartCode)) { var mySerialNum = $"{DateTime.Now.ToString("yyMMdd")}{printBarcode}{num}"; var sendSerialNunHexList = GetSerialNumHexMsg(mySerialNum); if (sendSerialNunHexList.Count > 0) { var writeResult8 = writeData(sendString); if (!writeResult8.isok) { Info($"8.写入-->序列号异常:{writeResult8.msg}"); } } } //9.读取序列号 sendString = "68 13 00 02 00 01 00 00 08 00 22 07 00 00 03 22 F1 8C 55 55 55 55 A5 16 68 13 00 02 00 01 00 00 08 00 22 07 00 00 30 00 00 55 55 55 55 55 88 16"; var writeResult9 = writeData(sendString); if (!writeResult9.isok) { Info($"9.获取-->序列号异常:{writeResult9.msg}"); } getSerialNum(); _serialNum=DeviceInfo.SerialNum; Info($"9.接收--序列号:{DeviceInfo.SerialNum}"); } } catch (Exception ex) { var msg = ex == null ? "与232模块通讯异常" : ex.Message; ErrorInfo($"DeviceHelper类中Run方法异常:{msg}"); } } /// /// 获取写入零部件号的报文 /// /// 番号 /// private List GetParCodeHexMsg(string partCode) { List hexList = new List(); var hex = ExtendMethod.StringToHexString(partCode, Encoding.ASCII).TrimEnd(' ');//番号转十六进制 var arr = hex.Split(' '); //必须发5条指令 for (var i = 1; i <= 5; i++) { int data4 = i; var data = arr.Skip((i - 1) * 4).Take(4).ToList(); for (int h = 0; h < 5; h++) { if (data.Count < 4) { data.Add("00"); } else { break; } } var dataArr = data.ToArray(); var newData = string.Empty; for (int j = 0; j < dataArr.Length; j++) { newData += dataArr[j] + " "; } var sendString = $"68 13 00 02 00 01 00 00 08 00 72 06 00 00 80 00 30 0{data4} {newData.TrimEnd(' ')}"; sendString = ExtendMethod.ProtocolCRC(sendString) + "16"; hexList.Add(sendString); } return hexList; } /// /// 获取写入序列号的报文 /// /// 序列号 /// private List GetSerialNumHexMsg(string serialNum) { List hexList = new List(); var hex = ExtendMethod.StringToHexString(serialNum, Encoding.ASCII).TrimEnd(' ');//序列号转十六进制 var arr = hex.Split(' '); //必须发3条指令 for (var i = 1; i <= 3; i++) { int data4 = i; var data = arr.Skip((i - 1) * 4).Take(4).ToList(); for (int h = 0; h < 5; h++) { if (data.Count < 4) { data.Add("00"); } else { break; } } var dataArr = data.ToArray(); var newData = string.Empty; for (int j = 0; j < dataArr.Length; j++) { newData += dataArr[j] + " "; } var sendString = $"68 13 00 02 00 01 00 00 08 00 72 06 00 00 80 00 2D 0{data4} {newData.TrimEnd(' ')}"; sendString = ExtendMethod.ProtocolCRC(sendString) + "16"; hexList.Add(sendString); } return hexList; } /// /// 解析序列号 /// /// private void getSerialNum() { DeviceInfo.SerialNum = string.Empty; if (_dataList.Count > 0) { for (int i = 0; i < _dataList.Count; i++) { var item = _dataList[i]; if (item[14] == 0x2A && item[15] == 0x07) { var arr1 = new byte[3]; var arr2 = new byte[7]; if (item[18] == 0x10) { arr1 = item.Skip(22).Take(3).ToArray(); } if (item[18] == 0x21) { arr2 = item.Skip(18).Take(7).ToArray(); } DeviceInfo.SerialNum = Encoding.ASCII.GetString(arr1.Concat(arr2).ToArray()); } } } } private (bool isok, string msg) writeData(string sendString) { try { _dataList.Clear(); byte[] sendBytes = HexStrToByteArray(sendString); if (sendBytes == null) { return (false, $"将{sendString}字符串转成字节数组时异常"); } _serialPort.Write(sendBytes, 0, sendBytes.Length); //Thread.Sleep(500); //if (_dataList.Count > 0) //{ // Info("writeData方法已获取到_dataList"); //} return (true, ""); } catch (Exception ex) { var msg = ex == null ? "writeData异常" : $"writeData异常,{ex.Message}"; ErrorInfo(msg); return (false, msg); } } /// /// 软件编码 /// private void getSoftwareCode() { try { DeviceInfo.SoftwareCode = string.Empty; if (_dataList.Count > 0) { for (int i = 0; i < _dataList.Count; i++) { var item = _dataList[i]; if (item[14] == 0xBB && item[15] == 0x07) { if (item[18] == 0x10) { DeviceInfo.SoftwareCode += item[23].ToString("X2"); DeviceInfo.SoftwareCode += item[24].ToString("X2"); DeviceInfo.SoftwareCode += item[25].ToString("X2"); } else if (item[18] == 0x21) { DeviceInfo.SoftwareCode += item[19].ToString("X2"); DeviceInfo.SoftwareCode += item[20].ToString("X2"); DeviceInfo.SoftwareCode += item[21].ToString("X2"); DeviceInfo.SoftwareCode += item[22].ToString("X2"); DeviceInfo.SoftwareCode += item[23].ToString("X2"); DeviceInfo.SoftwareCode += item[24].ToString("X2"); } } } } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"getSoftwareCode方法异常:{msg}"); } } /// /// 引导版本 /// private void getGuideVersion() { try { DeviceInfo.GuideVersion = string.Empty; if (_dataList.Count > 0) { for (int i = 0; i < _dataList.Count; i++) { var item = _dataList[i]; if (item[14] == 0x2A && item[15] == 0x07) { if (item[18] == 0x10) { DeviceInfo.GuideVersion += item[23].ToString() + "."; DeviceInfo.GuideVersion += item[24].ToString() + "."; DeviceInfo.GuideVersion += item[25].ToString() + "."; } else if (item[18] == 0x21) { DeviceInfo.GuideVersion += item[19].ToString() + "."; DeviceInfo.GuideVersion += item[20].ToString() + "."; DeviceInfo.GuideVersion += item[21].ToString() + "."; DeviceInfo.GuideVersion += item[22].ToString() + "."; DeviceInfo.GuideVersion += item[23].ToString() + "."; DeviceInfo.GuideVersion += item[24].ToString(); } } } } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"getGuideVersion方法异常:{msg}"); } } /// /// 清除故障 /// private void getClearFault() { try { DeviceInfo.ClearFault = string.Empty; if (_dataList.Count > 0) { for (int i = 0; i < _dataList.Count; i++) { var item = _dataList[i]; if (item[14] == 0xBB && item[15] == 0x07 && item[18] == 0x06 && item[19] == 0x59) { DeviceInfo.ClearFault += item[23].ToString(); DeviceInfo.ClearFault += item[24].ToString(); break; } } } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"getClearFault方法异常:{msg}"); } } /// /// 软件版本 /// private void getSoftwareVersion() { try { DeviceInfo.SoftwareVersion = string.Empty; if (_dataList.Count > 1) { string year = string.Empty, month = string.Empty, day = string.Empty, times = string.Empty, version = string.Empty, version1 = string.Empty, version2 = string.Empty, version3 = string.Empty; for (int i = 0; i < _dataList.Count; i++) { var item = _dataList[i]; if (item[18] == 0x10) { var yearVal = ByteArrayToInt(new byte[] { item[25] }); if (yearVal.HasValue) { year = yearVal.Value.ToString(); } var versionVal = ByteArrayToInt(new byte[] { item[23], item[24] }); if (versionVal.HasValue) { version = versionVal.Value.ToString().PadLeft(5, '0'); version1 = version.Substring(0, 1); version2 = version.Substring(1, 2); version3 = version.Substring(3, 2); } } if (item[18] == 0x21) { var monthVal = ByteArrayToInt(new byte[] { item[19] }); if (monthVal.HasValue) { month = monthVal.Value.ToString(); } var dayVal = ByteArrayToInt(new byte[] { item[20] }); if (dayVal.HasValue) { day = dayVal.Value.ToString(); } var timsVal = ByteArrayToInt(new byte[] { item[21] }); if (timsVal.HasValue) { times = timsVal.Value.ToString(); } } DeviceInfo.SoftwareVersion = $"{version1}.{version2}.{version3}.{year}.{month}.{day}.{times}"; } } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"getSoftwareVersion方法异常:{msg}"); } } /// /// 电压 /// private void getVoltage() { try { DeviceInfo.Voltage = string.Empty; if (_dataList.Count > 0) { String voltage1 = String.Empty, voltage2 = String.Empty; for (int i = 0; i < _dataList.Count; i++) { if (_dataList[i].Count == 28 && _dataList[i][14] == 0xDB && _dataList[i][15] == 0x02) { voltage1 = ((double)_dataList[i][22] / 10).ToString() + "V"; voltage2 = ((double)_dataList[i][23] / 10).ToString() + "V"; DeviceInfo.Voltage = $"{voltage1},{voltage2}"; } } } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"getVoltage方法异常:{msg}"); } } /// /// 解析零部件号 /// private void getPartCode() { DeviceInfo.PartCode = string.Empty; if (_dataList.Count > 0) { for (int i = 0; i < _dataList.Count; i++) { var item = _dataList[i]; if (item[14] == 0x2A && item[15] == 0x07) { var arr1 = new byte[3]; var arr2 = new byte[7]; if (item[18] == 0x10) { arr1 = item.Skip(22).Take(3).ToArray(); } if (item[18] == 0x21) { arr2 = item.Skip(18).Take(7).ToArray(); } DeviceInfo.PartCode = Encoding.ASCII.GetString(arr1.Concat(arr2).ToArray()); } } } } private void _serialPort_DataReceived2(object sender, SerialDataReceivedEventArgs e) { try { byte[] read = new byte[_serialPort.BytesToRead]; _serialPort.Read(read, 0, read.Length); foreach (byte b in read) { if (b == 0x68) { if (_data.Count == 28) { if (_data[14] == 0x2A && _data[15] == 0x07) { _dataList.Add(new List(_data)); } if (_data[14] == 0xBB && _data[15] == 0x07) { _dataList.Add(new List(_data)); } else if (_data[14] == 0x73 && _data[15] == 0x06 && _data[16] == 0x00 && _data[17] == 0x00 && (_data[18] == 0x51 || _data[18] == 0x52)) { _dataList.Add(new List(_data)); } else if (_data[14] == 0xDB && _data[15] == 0x02) { _dataList.Add(new List(_data)); } } _data.Clear(); } _data.Add(b); } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"_serialPort_DataReceived方法异常:{msg}"); } } private Queue bufferQueue = null; private bool isHeadRecive = false; private int frameLenth = 0; private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { byte[] read = new byte[_serialPort.BytesToRead]; _serialPort.Read(read, 0, read.Length); foreach (byte item in read) { // 入列 bufferQueue.Enqueue(item); } // 解析获取帧头 if (isHeadRecive == false) { foreach (byte item in bufferQueue.ToArray()) { if (item != 0x68) { // 出列 bufferQueue.Dequeue(); } else { isHeadRecive = true; break; } } } if (isHeadRecive == true) { // 判断有数据帧长度 if (bufferQueue.Count >= 2) { //数据区的长度 frameLenth = bufferQueue.ToArray()[1]; // 一帧完整的数据长度判断,不代表数据是正确的 if (bufferQueue.Count >= 1 + 2 + frameLenth + 2) { byte[] frameBuffer = new byte[1 + 2 + frameLenth + 2]; Array.Copy(bufferQueue.ToArray(), 0, frameBuffer, 0, frameBuffer.Length); if (frameBuffer[14] == 0x2A && frameBuffer[15] == 0x07) { _dataList.Add(new List(frameBuffer)); } if (frameBuffer[14] == 0xBB && frameBuffer[15] == 0x07) { _dataList.Add(new List(frameBuffer)); } else if (frameBuffer[14] == 0x73 && frameBuffer[15] == 0x06 && frameBuffer[16] == 0x00 && frameBuffer[17] == 0x00 && (frameBuffer[18] == 0x51 || frameBuffer[18] == 0x52)) { _dataList.Add(new List(frameBuffer)); } else if (frameBuffer[14] == 0xDB && frameBuffer[15] == 0x02) { _dataList.Add(new List(frameBuffer)); } for (int i = 0; i < 1 + 2 + frameLenth + 2; i++) { bufferQueue.Dequeue(); } isHeadRecive = false; } } } } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"_serialPort_DataReceived方法异常:{msg}"); } } private static void Info(string info = "") { LogHelper.WriteLog(info); } private static void ErrorInfo(string info = "") { LogHelper.WriteErrorLog(info); } /// /// 字符串转16进制字节数组 /// /// /// public byte[] HexStrToByteArray(string hexString) { try { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"HexStrToByteArray方法将({hexString})字符串转成16进制时,异常:{msg}"); return null; } } /// /// 字节数组转Int32 /// /// /// public static int? ByteArrayToInt(byte[] bytes) { try { int mask = 0xff; int temp = 0; int n = 0; for (int i = 0; i < bytes.Length; i++) { n <<= 8; temp = bytes[i] & mask; n |= temp; } return n; } catch (Exception ex) { var msg = ex == null ? "操作异常" : ex.Message; ErrorInfo($"ByteArrayToInt方法异常:{msg}"); return null; } } } }