You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

740 lines
29 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<CAN2DeviceHelper>
{
public DeviceInfo DeviceInfo { get; set; } = new DeviceInfo();
List<List<byte>> _dataList = new List<List<byte>>();
List<byte> _data = new List<byte>();
SerialPort _serialPort;
/// <summary>
/// CAN通讯
/// </summary>
/// <param name="softCode">软件编码</param>
/// <param name="isSerialNum">是否写入序列号</param>
/// <param name="partCode">零部件号</param>
/// <param name="printBarcode">打印条码组成字符例如D</param>
/// <param name="num">流水号</param>
/// <param name="_serialNum">序列号</param>
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<List<byte>>();
bufferQueue = new Queue<byte>();
_data = new List<byte>();
_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}");
}
}
/// <summary>
/// 获取写入零部件号的报文
/// </summary>
/// <param name="partCode">番号</param>
/// <returns></returns>
private List<string> GetParCodeHexMsg(string partCode)
{
List<string> hexList = new List<string>();
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;
}
/// <summary>
/// 获取写入序列号的报文
/// </summary>
/// <param name="serialNum">序列号</param>
/// <returns></returns>
private List<string> GetSerialNumHexMsg(string serialNum)
{
List<string> hexList = new List<string>();
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;
}
/// <summary>
/// 解析序列号
/// </summary>
/// <exception cref="NotImplementedException"></exception>
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);
}
}
/// <summary>
/// 软件编码
/// </summary>
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}");
}
}
/// <summary>
/// 引导版本
/// </summary>
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}");
}
}
/// <summary>
/// 清除故障
/// </summary>
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}");
}
}
/// <summary>
/// 软件版本
/// </summary>
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}");
}
}
/// <summary>
/// 电压
/// </summary>
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}");
}
}
/// <summary>
/// 解析零部件号
/// </summary>
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<byte>(_data));
}
if (_data[14] == 0xBB && _data[15] == 0x07)
{
_dataList.Add(new List<byte>(_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<byte>(_data));
}
else if (_data[14] == 0xDB && _data[15] == 0x02)
{
_dataList.Add(new List<byte>(_data));
}
}
_data.Clear();
}
_data.Add(b);
}
}
catch (Exception ex)
{
var msg = ex == null ? "操作异常" : ex.Message;
ErrorInfo($"_serialPort_DataReceived方法异常{msg}");
}
}
private Queue<byte> 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<byte>(frameBuffer));
}
if (frameBuffer[14] == 0xBB && frameBuffer[15] == 0x07)
{
_dataList.Add(new List<byte>(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<byte>(frameBuffer));
}
else if (frameBuffer[14] == 0xDB && frameBuffer[15] == 0x02)
{
_dataList.Add(new List<byte>(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);
}
/// <summary>
/// 字符串转16进制字节数组
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 字节数组转Int32
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
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;
}
}
}
}