using System.Diagnostics;
using System.IO.Ports;
namespace UHFHelper
{
public class UHF_RS485_Helper
{
private SerialPort? _serialPort;
private SerialParam? _serialParam;
public Action OpenOk { get; set; }
public Action DisConnect { get; set; }
///
/// 单例模式
///
private static UHF_RS485_Helper? Instance { get; set; }
public static UHF_RS485_Helper GetInstance()
{
if (Instance == null)
{
Instance = new UHF_RS485_Helper();
}
return Instance;
}
///
/// 打开串口
///
///
public void Open(SerialParam param)
{
if (SerialPort.GetPortNames().Contains(param.PortName))
{
_serialParam = param;
_serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits);
try
{
_serialPort.Open();
if (_serialPort.IsOpen) OpenOk?.Invoke();
}
catch (Exception)
{
}
}
}
///
/// 获取串口状态
///
///
public bool GetSerialPortState()
{
if (_serialPort != null)
{
return _serialPort.IsOpen;
}
else
{
DisConnect?.Invoke();
return false;
}
}
///
/// 关闭串口
///
public void Close()
{
if (_serialPort == null) return;
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
private object async = new object();
///
/// 读卡方法,返回读卡器数据
///
/// 设备读取地址
///
public DKoutput? ReadCard(int adr)
{
lock (async)
{
try
{
if (_serialPort == null) return null;
DKoutput dKoutput = new();
var readByte = ReadByte(adr);
_serialPort.Write(readByte, 0, readByte.Length);
var result = SendMessage(readByte, 150, 18);
if (result == null)
{
return null;
}
else
{
//获取校验码
var crc = result.Skip(16).Take(2).ToArray();
//获取卡号
var cardNo = result.Skip(6).Take(10).ToArray();
//获取读卡器数据
var readData = result.Skip(0).Take(16).ToArray();
//获取读卡器地址
var address = result.Skip(1).Take(1).ToArray();
//判断数据是否合法
var temcrc = CRC16.ToCRC16(readData);
if (crc.ByteArrayToHexString() == temcrc.ByteArrayToHexString())
{
dKoutput.Address = address.ByteArrayToHexString();
dKoutput.ResData = cardNo.ByteArrayToHexString();
return dKoutput;
}
else
{
return null;
}
}
}
catch (Exception ex) {
return null;
}
}
}
///
/// 生成读取命令
///
///
private byte[] ReadByte(int adr)
{
//根据读取地址生成读取命令
byte[] data1 = new byte[3] { 04, (byte)adr, 01 };
//生成crc校验码
byte[] data2 = CRC16.ToCRC16(data1);
byte[] data3 = new byte[data1.Length + data2.Length];
data1.CopyTo(data3, 0);
data2.CopyTo(data3, data1.Length);
return data3;
}
///
/// 获取本机可用串口
///
///
public string[] GetLocalSerialPortNames()
{
return SerialPort.GetPortNames();
}
///
/// 发送数据
///
/// 数据
/// 超时时间
/// 串口回复字节数
///
public byte[]? SendMessage(byte[] msg, long timeout, int count)
{
if (_serialPort == null) return null;
var stopwatch = Stopwatch.StartNew();
try
{
_serialPort.DiscardInBuffer();
_serialPort.Write(msg, 0, msg.Length);
var tmpCount = count;
byte[] buffer = new byte[tmpCount];
int offset = 0;
while (tmpCount > 0)
{
if (stopwatch.ElapsedMilliseconds >= timeout)
{
return null;
}
int res = _serialPort.BytesToRead;
if (res > 0)
{
var readCount = _serialPort.Read(buffer, offset, tmpCount);
if (buffer.Skip(0).Take(1).ToArray().ByteArrayToHexString() == "05")
{
return null;
}
offset += readCount;
tmpCount -= readCount;
}
}
return buffer;
}
catch (Exception ex)
{
return null;
}
}
///
/// 发送数据
///
public void SendMessage(int adr)
{
var readByte = ReadByte(adr);
if (_serialPort == null) return;
_serialPort.Write(readByte, 0, readByte.Length);
}
///
/// 读取数据
///
///
public byte[]? GetMessage(int count, long timeout)
{
if (_serialPort == null) return null;
var stopwatch = Stopwatch.StartNew();
try
{
_serialPort.DiscardInBuffer();
var tmpCount = count;
byte[] buffer = new byte[tmpCount];
int offset = 0;
while (tmpCount > 0)
{
var readCount = _serialPort.Read(buffer, offset, tmpCount);
if (readCount == 6)
{
tmpCount = 0;
continue;
}
offset += readCount;
tmpCount -= readCount;
if (stopwatch.ElapsedMilliseconds >= timeout)
{
return null;
}
}
return buffer;
}
catch (Exception ex)
{
return null;
}
}
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
throw new NotImplementedException();
}
/////
///// 发送数据
/////
///// 数据
///// 超时时间
///// 串口回复字节数
/////
//public async Task SendMessageAsync(byte[] msg, TimeSpan timeout, int count)
//{
// var sendTask = Task.Run(() => SendMessage(msg, timeout, count));
// //try
// //{
// // await Task.WhenAny(sendTask, Task.Delay(timeout));
// //}
// //catch (TaskCanceledException)
// //{
// // return null;
// //}
// return await sendTask;
//}
///
/// 发出蜂鸣声音3次,代表扣款成功!
///
public void OpenBeep(int addr)
{
//byte[] sendData = new byte[] { 0x07, (byte)addr, 0x33, 0x08, 0x02, 0x03, 0x33, 0xB1 };
byte[] data1 = new byte[6] { 0x07, (byte)addr, 0x33, 0x08, 0x02, 0x03 };
//生成crc校验码
byte[] data2 = CRC16.ToCRC16(data1);
byte[] data3 = new byte[data1.Length + data2.Length];
data1.CopyTo(data3, 0);
data2.CopyTo(data3, data1.Length);
if (_serialPort != null)
{
_serialPort.DiscardInBuffer();
_serialPort.Write(data3, 0, data3.Length);
}
}
}
public class SerialParam
{
public string PortName { get; set; } = "COM3";
public int BaudRate { get; set; } = 57600;
public int DataBits { get; set; } = 8;
public Parity PortParity { get; set; } = Parity.None;
public StopBits PortStopBits { get; set; } = StopBits.One;
}
}