|
- 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; }
-
- /// <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)
- {
- 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)
- {
- }
-
- }
- }
- /// <summary>
- /// 获取串口状态
- /// </summary>
- /// <returns></returns>
- public bool GetSerialPortState()
- {
- if (_serialPort != null)
- {
- return _serialPort.IsOpen;
- }
- else
- {
- DisConnect?.Invoke();
- 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 DKoutput? ReadCard(int adr)
- {
- 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;
- }
- }
- }
- /// <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, 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;
- }
- }
- /// <summary>
- /// 发送数据
- /// </summary>
- public void SendMessage(int adr)
- {
- var readByte = ReadByte(adr);
- if (_serialPort == null) return;
- _serialPort.Write(readByte, 0, readByte.Length);
- }
- /// <summary>
- /// 读取数据
- /// </summary>
- /// <returns></returns>
- 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();
- }
-
- ///// <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)
- // //{
- // // return null;
- // //}
- // return await sendTask;
- //}
-
- /// <summary>
- /// 发出蜂鸣声音3次,代表扣款成功!
- /// </summary>
- 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;
- }
- }
|