|
- using System.Diagnostics;
- using System.IO.Ports;
-
- namespace UHFHelper
- {
- public class UHF_RS485_Helper
- {
- private SerialPort? _serialPort;
- private SerialParam? _serialParam;
-
- /// <summary>
- /// 单例模式
- /// </summary>
- private static UHF_RS485_Helper? Instance { get; set; }
- public static UHF_RS485_Helper GetInstance()
- {
- if (Instance == null)
- {
- Instance = new UHF_RS485_Helper();
- }
- return Instance;
- }
- /// <summary>
- /// 打开串口
- /// </summary>
- /// <param name="param"></param>
- public void Open(SerialParam param)
- {
- _serialParam = param;
- _serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits);
- _serialPort.Open();
-
- }
- /// <summary>
- /// 获取串口状态
- /// </summary>
- /// <returns></returns>
- public bool GetSerialPortState()
- {
- if (_serialPort!=null)
- {
- return _serialPort.IsOpen;
- }
- else
- {
- return false;
- }
- }
- /// <summary>
- /// 关闭串口
- /// </summary>
- public void Close()
- {
- if (_serialPort == null) return;
- _serialPort.Close();
- _serialPort.Dispose();
- _serialPort = null;
- }
- /// <summary>
- /// 读卡方法,返回读卡器数据
- /// </summary>
- /// <param name="adr">设备读取地址</param>
- /// <returns></returns>
- public async Task<DKoutput?> ReadCard(int adr)
- {
- DKoutput dKoutput = new();
- var readByte = ReadByte(adr);
- var result = await SendMessageAsync(readByte, TimeSpan.FromSeconds(1), 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;
- }
- }
- }
- /// <summary>
- /// 生成读取命令
- /// </summary>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 获取本机可用串口
- /// </summary>
- /// <returns></returns>
- public string[] GetLocalSerialPortNames()
- {
- return SerialPort.GetPortNames();
- }
- /// <summary>
- /// 发送数据
- /// </summary>
- /// <param name="msg">数据</param>
- /// <param name="timeout">超时时间</param>
- /// <param name="count">串口回复字节数</param>
- /// <returns></returns>
- public byte[]? SendMessage(byte[] msg, TimeSpan timeout, int count)
- {
- if (_serialPort == null) return null;
- var stopwatch = Stopwatch.StartNew();
- var originalWriteTimeout = _serialPort.WriteTimeout;
- var originalReadTimeout = _serialPort.ReadTimeout;
- try
- {
-
- _serialPort.WriteTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
- _serialPort.Write(msg, 0, msg.Length);
-
- var tmpCount = count;
- byte[] buffer = new byte[tmpCount];
- int offset = 0;
- while (tmpCount > 0)
- {
- _serialPort.ReadTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
- var readCount = _serialPort.Read(buffer, offset, tmpCount);
- if (readCount==6)
- {
- tmpCount = 0;
- continue;
- }
- offset += readCount;
- tmpCount -= readCount;
- }
- _serialPort.DiscardInBuffer();
- return buffer;
- }catch(Exception ex)
- {
- return null;
- }
- finally
- {
- _serialPort.ReadTimeout = originalReadTimeout;
- _serialPort.WriteTimeout = originalWriteTimeout;
- }
- }
-
- /// <summary>
- /// 发送数据
- /// </summary>
- /// <param name="msg">数据</param>
- /// <param name="timeout">超时时间</param>
- /// <param name="count">串口回复字节数</param>
- /// <returns></returns>
- public async Task<byte[]?> 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)
- {
- throw new TimeoutException();
- }
- return await sendTask;
- }
-
- /// <summary>
- /// 发出蜂鸣声音3次,代表扣款成功!
- /// </summary>
- public async void OpenBeep(int addr)
- {
- byte[] sendData = new byte[]{ 0x07, (byte)addr, 0x33, 0x08, 0x02, 0x03, 0x33,0xB1 };
- await SendMessageAsync(sendData, TimeSpan.FromSeconds(1), 6);
- }
- }
-
- 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;
- }
- }
|