using DefaultEdit.Enums; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.SerialPorts; using TouchSocket.Sockets; namespace DefaultEdit.Communication { public class SerialCommunication : IDisposable { /// /// 串口名称 /// public string PortName { get; private set; } /// /// 波特率 /// public int BaudRate { get; private set; } /// /// 奇偶校验位 /// public Parity Parity { get; private set; } /// /// 停止位 /// public StopBits StopBits { get; private set; } /// /// 数据位 /// public int DataBits { get; private set; } public Encoding Encoding { get; set; } = Encoding.ASCII; /// /// 当前连接状态 /// public bool IsConnected { get { if ( client != null ) { return client.Online; } else { return false; } } } private SerialPortClient client; private IWaitingClient WaitClient; /// /// 接收到的数据 /// public string Data { get; private set; } /// /// 连接状态变化事件 /// public event Action ConnectionChanged; /// /// 数据接收事件 /// public event Action DataReceived; /// /// 发送数据事件 /// public event Action SendData; public Terminator terminator; public SerialCommunication(Terminator terminator, string portName, int baudRate = 9600, Parity parity = Parity.None, StopBits stopBits = StopBits.One, int dataBits = 8) { PortName = portName; BaudRate = baudRate; Parity = parity; StopBits = stopBits; DataBits = dataBits; client = new SerialPortClient(); client.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到端口 client.Connected = (client, e) => { ConnectionChanged?.Invoke(this, IsConnected); return EasyTask.CompletedTask; };//成功连接到端口 client.Closing = (client, e) => { return EasyTask.CompletedTask; };//即将从端口断开连接。此处仅主动断开才有效。 client.Closed = (client, e) => { ConnectionChanged?.Invoke(this, IsConnected); return EasyTask.CompletedTask; };//从端口断开连接,当连接不成功时不会触发。 client.Received = async (c, e) => { Data = e.ByteBlock.Span.ToString(Encoding); //接收到数据 DataReceived?.Invoke(this, Data); }; TouchSocketConfig touchSocket = new TouchSocketConfig(); touchSocket.SetSerialPortOption(new SerialPortOption() { BaudRate = BaudRate,//波特率 DataBits = DataBits,//数据位 Parity = Parity,//校验位 PortName = PortName,//COM StopBits = StopBits//停止位 }); if ( terminator == Terminator.None ) { touchSocket.SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromSeconds(0.8) }); } if ( terminator == Terminator.CRLF ) { touchSocket.SetSerialDataHandlingAdapter(() => new TerminatorPackageAdapter("\r\n")); } client.Setup(touchSocket); } /// /// 异步连接到串口扫描枪 /// /// public async Task ConnectAsync() { if ( ( await client.TryConnectAsync() ).IsSuccess ) { ConnectionChanged?.Invoke(this, IsConnected); //调用CreateWaitingClient获取到IWaitingClient的对象。 WaitClient = client.CreateWaitingClient(new WaitingOptions() { FilterFunc = response => //设置用于筛选的fun委托,当返回为true时,才会响应返回 { return true; } }); return true; } return false; } /// /// 连接到串口扫描枪 /// /// public bool Connect() { if ( client.TryConnect().IsSuccess )//尝试连接到端口 { //调用CreateWaitingClient获取到IWaitingClient的对象。 WaitClient = client.CreateWaitingClient(new WaitingOptions() { FilterFunc = response => //设置用于筛选的fun委托,当返回为true时,才会响应返回 { return true; } }); return true; } return false; } /// /// 断开连接到串口扫描枪 /// public void Disconnect() { if ( IsConnected ) { client.Close(); ConnectionChanged?.Invoke(this, IsConnected); } } /// /// 发送数据到串口扫描枪,并等待返回数据。 /// /// /// /// public string SendThenReturn(string msg, int millisecondsTimeout = 5000) { //然后使用SendThenReturn。 SendData?.Invoke(this, msg); byte[] returnData = WaitClient.SendThenReturn(Encoding.GetBytes(msg), millisecondsTimeout); DataReceived?.Invoke(this, Encoding.GetString(returnData)); return Encoding.GetString(returnData); } /// /// 异步发送数据到串口扫描枪,并等待返回数据。 /// /// /// /// public async Task SendThenReturnAsync(string msg, int millisecondsTimeout = 5000) { SendData?.Invoke(this, msg); byte[] returnData = await WaitClient.SendThenReturnAsync(Encoding.GetBytes(msg), millisecondsTimeout); DataReceived?.Invoke(this, Encoding.GetString(returnData)); return Encoding.GetString(returnData); } /// /// 发送数据到串口扫描枪 /// /// public void Send(string msg) { if ( IsConnected ) { SendData?.Invoke(this, msg); client.Send(Encoding.GetBytes(msg)); //发送数据到串口扫描枪 } } public void Dispose() { if ( WaitClient != null ) { WaitClient = null; } if ( client != null ) { client.Dispose(); client = null; } } } }