using Common.Attributes;
//using DeviceCommand.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using static Common.Attributes.ATSCommandAttribute;
namespace DeviceCommand.Base
{
[ATSCommand]
[DeviceCategory("全部驱动")] // 添加分类属性
public class Serial_Port
{
public string PortName { get; set; } = "COM1";
public int BaudRate { get; set; } = 9600;
public int DataBits { get; set; } = 8;
public StopBits StopBits { get; set; } = StopBits.One;
public Parity Parity { get; set; } = Parity.None;
public int ReadTimeout { get; set; } = 3000;
public int WriteTimeout { get; set; } = 3000;
public SerialPort _SerialPort { get; set; } = new SerialPort();
///
/// 创建并配置串口实例
///
/// 串口名称(如"COM1")
/// 波特率
/// 数据位,配置默认值:8
/// 停止位,配置默认值:StopBits.One
/// 校验位(根据设备需求设置),配置默认值:Parity.None
/// 读取超时
/// 写入超时
public Serial_Port CreateDevice(string portName, int baudRate
, int dataBits = 8, StopBits stopBits = StopBits.One, Parity parity = Parity.None
, int readTimeout = 3000, int writeTimeout = 3000)
{
PortName = portName;
BaudRate = baudRate;
DataBits = dataBits;
StopBits = stopBits;
Parity = parity;
ReadTimeout = readTimeout;
WriteTimeout = writeTimeout;
return this;
}
///
/// 修改串口实例参数
///
/// 串口实例
/// 串口名称(如"COM1")
/// 波特率
/// 数据位
/// 停止位
/// 校验位(根据设备需求设置)
/// 读取超时
/// 写入超时
public static void ChangeDeviceConfig(Serial_Port serialPort, string PortName, int BaudRate
, int dataBits = 8, StopBits stopBits = StopBits.One, Parity parity = Parity.None
, int ReadTimeout = 3000, int WriteTimeout = 3000)
{
// 更新配置串口实例参数
serialPort.PortName = PortName; // 串口名称(如"COM1")
serialPort.BaudRate = BaudRate; // 波特率
//serialPort.ReadTimeout = ReadTimeout;
//serialPort.WriteTimeout = WriteTimeout;
serialPort.Parity = parity; // 校验位(根据设备需求设置)
serialPort.DataBits = dataBits; // 数据位
serialPort.StopBits = stopBits; // 停止位
if (ReadTimeout > 0)
serialPort.ReadTimeout = ReadTimeout; // 读取超时
if (WriteTimeout > 0)
serialPort.WriteTimeout = WriteTimeout;// 写入超时
}
///
/// 串口连接
///
/// 串口实例
/// 支持中途取消发送指令
public static async Task ConnectAsync(Serial_Port serialPort, CancellationToken ct = default)
{
if (serialPort._SerialPort.PortName != serialPort.PortName
|| serialPort._SerialPort.BaudRate != serialPort.BaudRate
|| serialPort._SerialPort.Parity != serialPort.Parity
|| serialPort._SerialPort.DataBits != serialPort.DataBits
|| serialPort._SerialPort.StopBits != serialPort.StopBits
|| serialPort._SerialPort.ReadTimeout != serialPort.ReadTimeout
|| serialPort._SerialPort.WriteTimeout != serialPort.WriteTimeout)
{
// 关闭现有连接并重新配置
serialPort._SerialPort.Close();
//更新串口配置
serialPort._SerialPort.PortName = serialPort.PortName;
serialPort._SerialPort.BaudRate = serialPort.BaudRate;
serialPort._SerialPort.Parity = serialPort.Parity;
serialPort._SerialPort.DataBits = serialPort.DataBits;
serialPort._SerialPort.StopBits = serialPort.StopBits;
serialPort._SerialPort.ReadTimeout = serialPort.ReadTimeout;
serialPort._SerialPort.WriteTimeout = serialPort.WriteTimeout;
// 重新打开串口
serialPort._SerialPort.Open();
}
else
{
// 检查串口是否已打开
if (!serialPort._SerialPort.IsOpen)
{
// 打开串口
serialPort._SerialPort.Open();
}
}
return true;
}
///
/// 串口关闭
///
/// 串口实例
public static void Close(Serial_Port serialPort)
{
if (serialPort._SerialPort.IsOpen)
{
// 关闭串口连接
serialPort._SerialPort.Close();
//Console.WriteLine("串口已关闭");
}
}
///
/// 串口发送byte类型数据信息
///
/// 串口实例
/// 发送的数据信息为byte类型
/// 支持中途取消发送指令
public static async Task SendAsync(Serial_Port serialPort, byte[] bytes, CancellationToken ct = default)
{
if (!serialPort._SerialPort.IsOpen) return;
// 获取写入超时时间
var timeoutMs = serialPort.WriteTimeout;
if (timeoutMs <= 0)
{
serialPort._SerialPort.Write(bytes, 0, bytes.Length); // 向串口写入字节数据
return;
}
var sendTask = Task.Run(() =>
{
// 向串口写入字节数据
serialPort._SerialPort.Write(bytes, 0, bytes.Length);
}, ct);
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(sendTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"串口通讯异常:写入操作在 {timeoutMs} ms内未完成");
}
await sendTask;
//if (serialPort._SerialPort.IsOpen)
//{
//try
//{
// // 异步发送数据到串口
// await Task.Run(() =>
// {
// serialPort._SerialPort.Write(bytes, 0, bytes.Length); // 向串口写入字节数据
// }, ct);
//}
//catch (Exception ex)
//{
// // 异常处理
// //Console.WriteLine($"发送数据失败: {ex.Message}");
// MessageBox.Show($"串口发送数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
//}
//}
//else
//{
// //Console.WriteLine("串口未打开");
// MessageBox.Show($"串口未打开", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
//}
}
///
/// 串口发送字符串类型数据信息
///
/// 串口实例
/// 发送的数据信息为字符串类型
/// 支持中途取消发送指令
public static async Task SendAsync(Serial_Port serialPort, string str, CancellationToken ct = default)
{
if (!serialPort._SerialPort.IsOpen) return;
// 将字符串转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(str);
// 获取写入超时时间
var timeoutMs = serialPort.WriteTimeout;
if (timeoutMs <= 0)
{
serialPort._SerialPort.Write(bytes, 0, bytes.Length);
return;
}
var sendTask = Task.Run(() =>
{
// 向串口写入字节数据
serialPort._SerialPort.Write(bytes, 0, bytes.Length);
}, ct);
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(sendTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"串口通讯异常:写入操作在 {timeoutMs} ms内未完成");
}
await sendTask;
}
///
/// 串口读取byte类型数据信息
///
/// 串口实例
/// 读取的数据信息为byte数组类型
/// 支持中途取消发送指令
public static async Task ReadAsync(Serial_Port serialPort, byte[] buffer, CancellationToken ct = default)
{
if (!serialPort._SerialPort.IsOpen) return null;
int bytesRead = 0;
// 获取写入超时时间
var timeoutMs = serialPort.ReadTimeout;
if (timeoutMs <= 0)
{
return await ReadByte(serialPort, buffer, ct);
//while (bytesRead < buffer.Length)
//{
// if (serialPort._SerialPort.BytesToRead > 0)
// {
// bytesRead += serialPort._SerialPort.Read(buffer, bytesRead, buffer.Length - bytesRead);
// }
//}
//return buffer;
}
//var readTask = Task.Run(() =>
//{
// while (bytesRead < buffer.Length)
// {
// if (serialPort._SerialPort.BytesToRead > 0)
// {
// bytesRead += serialPort._SerialPort.Read(buffer, bytesRead, buffer.Length - bytesRead);
// }
// }
//}, ct);
var readTask = ReadByte(serialPort, buffer, ct);
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(readTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"串口通讯异常:读取操作在 {timeoutMs} ms内未完成");
}
return buffer;
//try
//{
// // 异步读取串口数据
// await Task.Run(() =>
// {
// while (bytesRead < buffer.Length)
// {
// if (serialPort._SerialPort.BytesToRead > 0)
// {
// bytesRead += serialPort._SerialPort.Read(buffer, bytesRead, buffer.Length - bytesRead);
// }
// }
// }, ct);
//}
//catch (Exception ex)
//{
// //Console.WriteLine($"读取数据失败: {ex.Message}");
// MessageBox.Show($"读取串口数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
// return null;
//}
//return buffer;
}
public static async Task ReadByte(Serial_Port serialPort, byte[] buffer, CancellationToken ct)
{
int bytesRead = 0;
while (bytesRead < buffer.Length)
{
if (serialPort._SerialPort.BytesToRead > 0)
{
bytesRead += serialPort._SerialPort.Read(buffer, bytesRead, buffer.Length - bytesRead);
}
}
return buffer;
}
///
/// 串口读取字符串类型数据信息
///
/// 串口实例
/// 读取的数据信息为字符串类型,string delimiter = "\n"
/// 支持中途取消发送指令
public static async Task ReadAsync(Serial_Port serialPort, string delimiter = "\n", CancellationToken ct = default)
{
if (!serialPort._SerialPort.IsOpen) return null;
// 获取写入超时时间
var timeoutMs = serialPort.ReadTimeout;
if (timeoutMs <= 0)
{
return await ReadDefaultString(serialPort, delimiter, ct);
}
var readTask = ReadDefaultString(serialPort, delimiter, ct);
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(readTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"串口通讯异常:读取操作在 {timeoutMs} ms内未完成");
}
return await readTask;
//try
//{
// // 异步读取串口数据
// await Task.Run(() =>
// {
// while (true)
// {
// if (ct.IsCancellationRequested)
// return;
// if (serialPort._SerialPort.BytesToRead > 0)
// {
// bytesRead = serialPort._SerialPort.Read(buffer, 0, buffer.Length);
// memoryStream.Write(buffer, 0, bytesRead);
// data = Encoding.UTF8.GetString(memoryStream.ToArray());
// int lineEndIndex = data.IndexOf(delimiter);
// // 找到分隔符,则返回数据
// if (lineEndIndex >= 0)
// {
// data = data.Substring(0, lineEndIndex).Trim();
// return;
// }
// }
// }
// }, ct);
//}
//catch (Exception ex)
//{
// //Console.WriteLine($"读取串口数据失败: {ex.Message}");
// MessageBox.Show($"读取串口数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
// return null;
//}
//return data;
}
private static async Task ReadDefaultString(Serial_Port serialPort, string delimiter, CancellationToken ct)
{
delimiter ??= "\n";
MemoryStream memoryStream = new();
byte[] buffer = new byte[2048];
int bytesRead = 0;
string data = string.Empty;
// 异步读取串口数据
await Task.Run(() =>
{
while (true)
{
if (ct.IsCancellationRequested)
return;
if (serialPort._SerialPort.BytesToRead > 0)
{
bytesRead = serialPort._SerialPort.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, bytesRead);
data = Encoding.UTF8.GetString(memoryStream.ToArray());
int lineEndIndex = data.IndexOf(delimiter);
// 找到分隔符,则返回数据
if (lineEndIndex >= 0)
{
data = data.Substring(0, lineEndIndex).Trim();
return;
}
}
}
}, ct);
return data;
}
///
/// 串口读取字符串类型数据信息
///
/// 串口实例
/// 读取的数据信息为字符串类型,string delimiter
/// 支持中途取消发送指令
public static async Task ReadStrAsync(Serial_Port serialPort, string delimiter, CancellationToken ct = default)
{
if (!serialPort._SerialPort.IsOpen)
{
return null; // 串口未打开,返回 null
}
// 获取写入超时时间
var timeoutMs = serialPort.ReadTimeout;
if (timeoutMs <= 0)
{
return await ReadString(serialPort, delimiter, ct);
}
var readTask = ReadString(serialPort, delimiter, ct);
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(readTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"串口通讯异常:读取操作在 {timeoutMs} ms内未完成");
}
return await readTask;
////delimiter ??= "\n"; // 默认分隔符为换行符
//MemoryStream memoryStream = new();
//byte[] buffer = new byte[2048];
//int bytesRead;
//string data = string.Empty;
//// 异步读取串口数据
//await Task.Run(() =>
//{
// while (true)
// {
// if (ct.IsCancellationRequested)
// return;
// if (serialPort._SerialPort.BytesToRead > 0)
// {
// // 从串口读取数据
// bytesRead = serialPort._SerialPort.Read(buffer, 0, buffer.Length);
// memoryStream.Write(buffer, 0, bytesRead);
// // 获取当前已读取的数据
// data = Encoding.UTF8.GetString(memoryStream.ToArray());
// // 查找分隔符
// int delimiterIndex = data.IndexOf(delimiter);
// if (delimiterIndex >= 0)
// {
// // 如果找到分隔符,则返回读取到的字符串
// data = data.Substring(0, delimiterIndex).Trim();
// return;
// }
// }
// }
//}, ct);
//try
//{
// // 异步读取串口数据
// await Task.Run(() =>
// {
// while (true)
// {
// if (ct.IsCancellationRequested)
// return;
// if (serialPort._SerialPort.BytesToRead > 0)
// {
// // 从串口读取数据
// bytesRead = serialPort._SerialPort.Read(buffer, 0, buffer.Length);
// memoryStream.Write(buffer, 0, bytesRead);
// // 获取当前已读取的数据
// data = Encoding.UTF8.GetString(memoryStream.ToArray());
// // 查找分隔符
// int delimiterIndex = data.IndexOf(delimiter);
// if (delimiterIndex >= 0)
// {
// // 如果找到分隔符,则返回读取到的字符串
// data = data.Substring(0, delimiterIndex).Trim();
// return;
// }
// }
// }
// }, ct);
//}
//catch (Exception ex)
//{
// //Console.WriteLine($"读取串口数据时发生错误: {ex.Message}");
// MessageBox.Show($"读取串口数据时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
// return null;
//}
//return data; // 如果没有数据返回,返回 null
}
private static async Task ReadString(Serial_Port serialPort, string delimiter, CancellationToken ct)
{
//delimiter ??= "\n";
MemoryStream memoryStream = new();
byte[] buffer = new byte[2048];
int bytesRead = 0;
string data = string.Empty;
// 异步读取串口数据
await Task.Run(() =>
{
while (true)
{
if (ct.IsCancellationRequested)
return;
if (serialPort._SerialPort.BytesToRead > 0)
{
bytesRead = serialPort._SerialPort.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, bytesRead);
data = Encoding.UTF8.GetString(memoryStream.ToArray());
int lineEndIndex = data.IndexOf(delimiter);
// 找到分隔符,则返回数据
if (lineEndIndex >= 0)
{
data = data.Substring(0, lineEndIndex).Trim();
return;
}
}
}
}, ct);
return data;
}
///
/// 串口连接
///
/// 取消令牌
/// 连接结果
public async Task ConnectAsync(CancellationToken ct = default)
{
return await ConnectAsync(this, ct);
}
///
/// 断开串口连接
///
public void Disconnect()
{
Close(this);
}
///
/// 发送字符串到串口
///
/// 要发送的字符串
/// 取消令牌
public async Task SendStringAsync(string str, CancellationToken ct = default)
{
await SendAsync(this, str, ct);
}
///
/// 接收字符串直到遇到指定分隔符
///
/// 分隔符
/// 取消令牌
/// 接收到的字符串
public async Task ReceiveStringToAsync(string delimiter, CancellationToken ct = default)
{
return await ReadAsync(this, delimiter, ct);
}
}
}