AOI_V1/MaiMuAOI/AssistClient/Utils/SSerialPort.cs

180 lines
5.1 KiB
C#
Raw Permalink Normal View History

2024-03-07 14:34:59 +08:00
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AssistClient.Utils
{
public class SSerialPort
{
private SerialPort _serialPort;
private readonly ConcurrentQueue<byte[]> _messageQueue;
private readonly EventWaitHandle _messageWaitHandle;
private int _receiveCount, _sendCount;
private readonly object _lock;
private int queueSize;
public int ReceiveCount
{
get => _receiveCount;
}
public int SendCount
{
get => _sendCount;
}
public SSerialPort(string com, int baud,int size=-1)
{
// initialized
_lock = new object();
_receiveCount = 0;
_sendCount = 0;
_messageQueue = new ConcurrentQueue<byte[]>();
_messageWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
queueSize = size;
// Open Com
openCom(com.ToUpper(), baud);
// Receive byte
pushMessage();
}
private void openCom(string com, int baud)
{
// Open Com
_serialPort = new SerialPort(com, baud);
if (_serialPort.IsOpen) _serialPort.Close();
// Set the read / write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
// Set read / write buffer Sizethe default of value is 1MB
_serialPort.ReadBufferSize = 1024 * 1024;
_serialPort.WriteBufferSize = 1024 * 1024;
_serialPort.Open();
// Discard Buffer
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
}
#region Static
/// <summary>
/// 获取当前计算机的串行端口名的数组
/// </summary>
/// <returns></returns>
public static string[] getPortNames()
{
return SerialPort.GetPortNames();
}
#endregion
#region Receive
private void pushMessage()
{
_serialPort.DataReceived += (sender, e) =>
{
lock (_lock)
{
if (_serialPort.IsOpen == false) return;
int length = _serialPort.BytesToRead;
byte[] buffer = new byte[length];
_serialPort.Read(buffer, 0, length);
_receiveCount += length;
_messageQueue.Enqueue(buffer);
byte[] outObj;
while (queueSize>0 && _messageQueue.Count > queueSize)
{
_messageQueue.TryDequeue(out outObj);
}
_messageWaitHandle.Set();
}
};
}
/// <summary>
/// 获取串口接受到的内容
/// </summary>
/// <param name="millisecondsToTimeout">取消息的超时时间</param>
/// <returns>返回byte数组</returns>
public byte[] getMessage(int millisecondsToTimeout = -1)
{
if (_messageQueue.TryDequeue(out var message))
{
return message;
}
if (_messageWaitHandle.WaitOne(millisecondsToTimeout))
{
if (_messageQueue.TryDequeue(out message))
{
return message;
}
}
return default;
}
#endregion
#region Send
/// <summary>
/// 发送消息byte数组
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
public void send(byte[] buffer, int offset, int count)
{
lock (_lock)
{
_serialPort.Write(buffer, offset, count);
//_sendCount += (count - offset);
_sendCount += count;
}
}
/// <summary>
/// 发送消息(字符串)
/// </summary>
/// <param name="encoding">字符串编码方式,具体方式见<see cref="Encoding"/></param>
/// <param name="message"></param>
public void send(Encoding encoding, string message)
{
lock (_lock)
{
var buffer = encoding.GetBytes(message);
_serialPort.Write(buffer, 0, buffer.Length);
_sendCount += buffer.Length;
}
}
#endregion
/// <summary>
/// 清空接受/发送总数统计
/// </summary>
public void clearCount()
{
lock (_lock)
{
_sendCount = 0;
_receiveCount = 0;
}
}
/// <summary>
/// 关闭串口
/// </summary>
public void close()
{
_serialPort.Close();
}
}
}