using LB_VisionProcesses.Communicators;
|
using System.IO.Ports;
|
|
namespace LB_VisionProcesses.Communicators.Tcom
|
{
|
public class UARTSerialPort : BaseCommunicator
|
{
|
private SerialPort SerialPort = new SerialPort();
|
|
// 构造函数
|
public UARTSerialPort(string name = "UART串口")
|
{
|
CommunicatorConnections.Add("地址", "COM1");
|
CommunicatorConnections.Add("端口", "115200");
|
CommunicatorBrand = CommunicatorBrand.UARTPort;
|
CommunicatorName = name;
|
}
|
|
/// <summary>
|
/// 配置串口参数
|
/// </summary>
|
/// <param name="portName"></param>
|
/// <param name="baudRate"></param>
|
/// <param name="parity"></param>
|
/// <param name="dataBits"></param>
|
/// <param name="stopBits"></param>
|
public void SetConfigure(string portName, int baudRate = 115200, Parity parity = Parity.None,
|
int dataBits = 8, StopBits stopBits = StopBits.One)
|
{
|
SerialPort.PortName = portName;
|
SerialPort.BaudRate = baudRate;
|
SerialPort.Parity = parity;
|
SerialPort.DataBits = dataBits;
|
SerialPort.StopBits = stopBits;
|
SerialPort.NewLine = "\r\n"; // 设置行结束符
|
SerialPort.ReadTimeout = 500; // 设置读取超时
|
SerialPort.WriteTimeout = 500; // 设置写入超时
|
}
|
|
public override bool Connect()
|
{
|
try
|
{
|
Disconnect();
|
|
//波特率
|
int PORT = 0;
|
if (!int.TryParse(this.CommunicatorConnections["端口"].ToString(), out PORT))
|
{
|
Msg = string.Format("端口未设置");
|
return false;
|
}
|
if (!CommunicatorConnections.Contains("地址"))
|
{
|
Msg = string.Format("地址未设置");
|
return false;
|
}
|
//串口号
|
string IP = CommunicatorConnections["地址"].ToString();
|
|
if (!SerialPort.IsOpen)
|
{
|
SerialPort = new SerialPort();
|
SetConfigure(IP, PORT);
|
SerialPort.Open();
|
bConnected = true;
|
SerialPort.DataReceived += SerialPort_DataReceived;
|
|
// 启动心跳线程
|
heartbeatThread = new Thread(SendHeartbeat);
|
heartbeatThread.IsBackground = true;
|
heartbeatThread.Start();
|
|
bConnected = true;
|
return true;
|
}
|
else
|
{
|
Msg = $"原串口关闭失败无法重新打开";
|
return false;
|
}
|
}
|
catch (Exception ex)
|
{
|
Msg = $"失败,串口已经启动: {ex.Message}";
|
return false;
|
}
|
}
|
|
public override bool Disconnect()
|
{
|
try
|
{
|
bConnected = false;
|
if (SerialPort == null)
|
{
|
SerialPort = new SerialPort();
|
return true;
|
}
|
|
if (SerialPort.IsOpen)
|
{
|
SerialPort.DataReceived -= SerialPort_DataReceived;
|
SerialPort.Close(); // 关闭串口
|
}
|
|
SerialPort = new SerialPort();
|
return true;
|
}
|
catch (Exception ex)
|
{
|
bConnected = false;
|
Msg = $"断开串口时出错: {ex.Message}";
|
return true;
|
}
|
}
|
|
public override bool SendMessage(byte[] sBytes)
|
{
|
bool bret = false;
|
if (SerialPort == null || !SerialPort.IsOpen) return bret;
|
try
|
{
|
// 清空缓冲区
|
SerialPort.DiscardOutBuffer();
|
//Thread.Sleep(50);
|
SerialPort.Write(sBytes, 0, sBytes.Length);
|
bret = true;
|
}
|
catch { }
|
return bret;
|
}
|
|
public override bool SendMessage(string message)
|
{
|
if (bConnected)
|
{
|
try
|
{
|
//空消息不发送
|
if (string.IsNullOrEmpty(message) || message.Trim() == "")
|
return true;
|
|
//发送前清空接收消息
|
strReceiveMsg = string.Empty;
|
|
// 清空缓冲区
|
SerialPort.DiscardOutBuffer();
|
//Thread.Sleep(50);
|
SerialPort.Write(message); // 发送消息
|
return true;
|
}
|
catch (Exception ex)
|
{
|
Msg = $"发送消息时出错: {ex.Message}";
|
return false;
|
}
|
}
|
else
|
{
|
Msg = "串口未打开";
|
return false;
|
}
|
}
|
|
private void ReadSerialData()
|
{
|
while (bConnected)
|
{
|
try
|
{
|
string message = SerialPort.ReadLine(); // 读取一行数据
|
if (message != null)
|
{
|
strReceiveMsg = message;
|
MessageReceived?.Invoke(message); // 触发回调
|
TriggerRunMessageReceived?.Invoke(CommunicatorName, strReceiveMsg); // 触发运行事件
|
}
|
}
|
//catch (TimeoutException) { /* 读取超时,可以忽略 */ }
|
catch (Exception ex)
|
{
|
Msg = $"读取串口数据时出错: {ex.Message}";
|
}
|
}
|
}
|
|
private System.Threading.Timer _clearTimer; // 用于延时清空的计时器
|
|
private void SerialPort_DataReceived(object? sender, SerialDataReceivedEventArgs e)
|
{
|
try
|
{
|
if (SerialPort == null || !SerialPort.IsOpen)
|
return;
|
|
string message = string.Empty;
|
|
if (SerialPort.BytesToRead > 0)
|
{
|
byte[] buffer = new byte[SerialPort.BytesToRead];
|
int bytesRead = SerialPort.Read(buffer, 0, buffer.Length);
|
|
message = BitConverter.ToString(buffer, 0, bytesRead);
|
message = message.Replace('-', ' '); // 转换为字符串形式
|
|
if (string.IsNullOrEmpty(message))
|
return;
|
|
if (string.IsNullOrEmpty(strReceiveMsg))
|
{
|
// 重置或启动计时器(1秒后清空)
|
_clearTimer?.Dispose(); // 取消之前的计时器
|
_clearTimer = new System.Threading.Timer(
|
_ => ClearMessage(),
|
null,
|
TimeSpan.FromSeconds(1), // 1秒后触发
|
Timeout.InfiniteTimeSpan // 只触发一次
|
);
|
}
|
|
//串口回调用累加的方式
|
lock (strReceiveMsg)
|
{
|
strReceiveMsg += (" " + message);
|
MessageReceived?.Invoke(strReceiveMsg); // 触发回调
|
TriggerRunMessageReceived?.Invoke(CommunicatorName, strReceiveMsg); // 触发运行事件
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Msg = $"读取串口数据时出错: {ex.Message}";
|
}
|
}
|
|
public override string ReceiveMsg()
|
{
|
string msg = string.Empty;
|
for (int i = 0; i <= 3; i++)
|
{
|
if (string.IsNullOrEmpty(strReceiveMsg))
|
Thread.Sleep(50);
|
else
|
{
|
lock (strReceiveMsg)
|
{
|
msg += strReceiveMsg;
|
strReceiveMsg = string.Empty;
|
}
|
//串口数据需要使用累加方式
|
//return msg;
|
}
|
}
|
return msg;
|
}
|
}
|
}
|