AOI_V1/MaiMuAOI/AssistClient/Utils/SSerialPort.cs

180 lines
5.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}
}