wpf SerialPortStream 循环串口进行连接仪器

using CommunityToolkit.Mvvm.Messaging;
using RJCP.IO.Ports;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace 项目名称
{
    public class SerialPortHelper
    {
        /// <summary>
        /// 串口连接工具
        /// </summary>
        public static SerialPortStream Serial { get; set; } = null;

        static int ByteCount { get; set; }

        static List<byte> readBuffer = new();

        public static string Port = "COM1";

        static System.Timers.Timer ctimer = new System.Timers.Timer { Interval = 1000 };
        static int tm = 0;

        static int successCount = 0;// 记录成功连接的串口数量
        static int allCount = 0;// 记录串口数量
        static int failCount = 0;// 记录失败连接的串口数量
        private static System.Threading.Timer timeoutTimer;
        static List<string> PnameList { get; set; } = new List<string>();

        /// <summary>
        /// 连接
        /// </summary>
        public static async void Connect()
        {
            try
            {
                // 获取可用的串口列表
                var portNames = SerialPortStream.GetPortNames().ToList();

                    allCount = portNames.Count;
                    successCount = 0;
                    failCount = 0;
                // 输出串口列表
                if (allCount > 0)
                {
                    PnameList?.Clear();
                    foreach (string portName in portNames)
                    {
                        var serialPort = new SerialPortStream(portName, 115200);
                        try
                        {
                            byte[] sendBuffer = new byte[15];
                            sendBuffer[0] = 0X5a;
                            sendBuffer[1] = 0Xa5;
                            sendBuffer[2] = 0X01;
                            sendBuffer[3] = 0;
                            sendBuffer[4] = 0;
                            sendBuffer[5] = 0;
                            sendBuffer[6] = 4;
                            sendBuffer[7] = 0;
                            sendBuffer[8] = 0;
                            sendBuffer[9] = 0;
                            sendBuffer[10] = 0;
                            var checkhumB = CRC16(sendBuffer, 15);
                            sendBuffer[11] = byte.Parse(checkhumB[0].ToString());
                            sendBuffer[12] = byte.Parse(checkhumB[1].ToString());
                            sendBuffer[13] = 0X3e;
                            sendBuffer[14] = 0Xe3;
                            serialPort.Open();
                            serialPort.DataReceived += SearchDateaReceived;
                            serialPort.Write(sendBuffer, 0, sendBuffer.Length);

                            // 设置超时机制
                            timeoutTimer = new Timer(CheckTimeout, serialPort, 1000, Timeout.Infinite);
                            await Task.Delay(1000);
                        }
                        catch (Exception)
                        {
                            failCount++;
                            if (serialPort != null)
                            {
                                serialPort.DataReceived -= SearchDateaReceived;
                                serialPort.Close();
                                if (serialPort != null && serialPort.IsDisposed == false) { serialPort?.Dispose(); }
                            }
                            CheckConnectionCompletion();
                            continue;
                        }
                    }
                }
                else
                {

                    没有串口做的操作
                    //Application.Current.Dispatcher.Invoke(() =>
                    //{
                        //WeakReferenceMessenger.Default.Send("Close");
                        //var m = new MessageWin("Nspf") { Owner = MainWindow._This };
                        //m.ShowDialog();
                        //if (m.DialogResult != null)
                        //{
                            //MainWindow._This.Vm.SelfCollapsed();
                            //new LoginMainWin() { Owner = MainWindow._This }.Show();
                        //}
                    //});
                    return;
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        public static void Disconnect()
        {
            try
            {
                if (Serial == null) { return; }
                Write15ForNo(0x26);
                if (Serial != null)
                {
                    Serial.DataReceived -= SerialDateaReceived;
                    Serial.Close();
                    Serial.Dispose();
                    Serial = null;
                }
                StopTimer(); // 停止计时器
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        public static void SearchDateaReceived(object serder, SerialDataReceivedEventArgs e)
        {
            if (serder is not SerialPortStream serial || serial == null) { return; }
            try
            {
                int count = serial.BytesToRead;
                if (count == 0) { return; }
                byte[] readBuffer = new byte[count];
                serial.Read(readBuffer, 0, count);
                PnameList.Add(serial.PortName);

                MainWindow._This.Dispatcher.Invoke(() =>
                {
                    if (readBuffer[0] == 0X5A && readBuffer[1] == 0XA5 && readBuffer[2] == 0X01)
                    {
                        StopTimer();
                        if (readBuffer[7] == 0X55 && readBuffer[8] == 0X4D && readBuffer[9] == 0X49)
                        {
                            SCount = readBuffer[10];
                            Write15ForNo(0X02);
                        }
                        else
                        {
                            if (Serial != null)
                            {
                                Serial.DataReceived -= SerialDateaReceived;
                                Serial.Close();
                                Serial = null;
                            }
                            var m = new MessageWin("OFailure") { Owner = MainWindow._This };
                            m.ShowDialog();
                            if (m.DialogResult != null)
                            {
                                MainWindow._This.Vm.SelfCollapsed();
                                new LoginMainWin() { Owner = MainWindow._This }.Show();
                            }
                            return;
                        }
                        WeakReferenceMessenger.Default.Send("Close");//关闭弹窗操作
                        string strReceive = Encoding.Default.GetString(readBuffer);
                        serial.DataReceived -= SearchDateaReceived;

                        serial.Close();
                        Serial = new SerialPortStream(serial.PortName, 115200);
                        Serial.DataReceived += new EventHandler<SerialDataReceivedEventArgs>(SerialDateaReceived);
                        Serial.ErrorReceived += (s, e) => { LogHelper.GetSingleObj().WriteLog("串口报错"); };
                        Serial.Open();
                        Write15ForNo(0X01);
                    }
                });
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        /// <summary>
        /// 接收字节
        /// </summary>
        /// <param name="serder"></param>
        /// <param name="e"></param>
        public static void SerialDateaReceived(object serder, SerialDataReceivedEventArgs e)
        {
            try
            {
                if (Serial == null) { return; }
                int count = Serial.BytesToRead;
                if (count <= 0) { return; }
                var bytes = new byte[count];
                Serial.Read(bytes, 0, count);
                if (bytes == null || bytes.Count() == 0) { return; }
                if (bytes.Count() == 1 && bytes[0] == 0) { return; }
                readBuffer.AddRange(bytes);
                MainWindow._This.Dispatcher.Invoke(() =>
                {
                    SerailData();
                });
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void SerailData()
        {
            if (readBuffer.Count <= 0) { return; }
            try
            {
                TempData();

                if (readBuffer[0] == 0X5A && readBuffer[1] == 0XA5)
                {
                    ByteCount = readBuffer[5] * 256 + readBuffer[6] + 11;
                    //LogHelper.GetSingleObj().WriteLog($"长度:{ByteCount}");

                    // 截取集合
                    if (readBuffer.Count >= ByteCount)
                    {
                        List<byte> firstSegment;
                        if (readBuffer.Count == ByteCount)
                        {
                            firstSegment = readBuffer.ToList();
                            readBuffer.Clear();
                        }
                        else
                        {
                            firstSegment = readBuffer.Take(ByteCount).ToList();
                        }
                        if (firstSegment[ByteCount - 1] == 0xe3 && firstSegment[ByteCount - 2] == 0x3e)
                        {
                            if (readBuffer?.Count >= ByteCount)
                            {
                                readBuffer = readBuffer.Skip(ByteCount).ToList();
                            }
                            ByteCount = firstSegment[5] * 256 + firstSegment[6] + 11;
                            var buf = firstSegment.ToArray();
                            ReceivedData(buf);
                        }
                        else
                        {
                            ErrorData();
                        }
                    }
                }
                else
                {
                    ErrorData();
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog($"长度:{ByteCount}");
                LogHelper.GetSingleObj().WriteLog(string.Join(',', readBuffer));
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void ReceivedData(byte[] bytes)
        {
            try
            {
                int count = bytes.Length;
                if (bytes[2] == 0X01)
                {
                    StopTimer();
                    if (bytes[7] == 0X55 && bytes[8] == 0X4D && bytes[9] == 0X49)
                    {
                        SCount = bytes[10];
                        Write15ForNo(0X02);
                    }
                    else
                    {
                        if (Serial != null)
                        {
                            Serial.DataReceived -= SerialDateaReceived;
                            Serial.Close();
                            //Serial.Dispose();
                            Serial = null;
                        }
                        WeakReferenceMessenger.Default.Send("Close");
                        var m = new MessageWin("OFailure") { Owner = MainWindow._This };
                        m.ShowDialog();
                        if (m.DialogResult != null)
                        {
                            MainWindow._This.Vm.SelfCollapsed();
                            new LoginMainWin() { Owner = MainWindow._This }.Show();
                        }
                        return;
                    }
                }
                else if (bytes[2] == 0X02)
                {
                }
                
                bytes = null;
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(string.Join(',', bytes));
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void CheckTimeout(object state)
        {
            if (state is not SerialPortStream serialPort || serialPort == null)
            {
                return;
            }
            if (PnameList.FirstOrDefault(x => x == serialPort.PortName) != null)
            {
                return;
            }
            try
            {
                if (serialPort != null)
                {
                    serialPort.DataReceived -= SearchDateaReceived;
                    serialPort.Close();
                    if (serialPort != null && serialPort.IsDisposed == false) { serialPort?.Dispose(); }
                }
                failCount++;
                CheckConnectionCompletion();
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void CheckConnectionCompletion()
        {
            try
            {
                if (successCount == 0 && allCount > 0 && allCount == successCount + failCount)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        // ...处理数据...
                        timeoutTimer?.Change(Timeout.Infinite, Timeout.Infinite); // 取消定时器
                        timeoutTimer?.Dispose();
                        //所有串口都没连上,做的操作
                        //WeakReferenceMessenger.Default.Send("Close");
                        //var m = new MessageWin("OFailure") { Owner = MainWindow._This };
                        //m.ShowDialog();
                        //if (m.DialogResult != null)
                        //{
                            //MainWindow._This.Vm.SelfCollapsed();
                            //new LoginMainWin() { Owner = MainWindow._This }.Show();
                        //}
                    });
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="SendBuffer"></param>
        public static void Write(byte[] SendBuffer)
        {
            if (Serial == null) { return; }
            try
            {
                readBuffer.Clear();
                Serial.Write(SendBuffer, 0, SendBuffer.Length);
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        /// <summary>
        /// 发送命令 带数据
        /// </summary>
        /// <param name="no">命令号</param>
        /// <param name="data1">数据1</param>
        /// <param name="data2">数据2</param>
        /// <param name="data3">数据3</param>
        public static void Write15ForNo(byte no, byte data1 = 0, byte data2 = 0, byte data3 = 0, byte data4 = 0)
        {
            try
            {
                if (Serial == null) { return; }
                readBuffer.Clear();
                byte[] SendBuffer = new byte[15];
                SendBuffer[0] = 0X5a;
                SendBuffer[1] = 0Xa5;
                SendBuffer[2] = no;
                SendBuffer[3] = 0;
                SendBuffer[4] = 0;
                SendBuffer[5] = 0;
                SendBuffer[6] = 4;
                SendBuffer[7] = data1;
                SendBuffer[8] = data2;
                SendBuffer[9] = data3;
                SendBuffer[10] = data4;
                var checkhumB = CRC16(SendBuffer, 10);
                SendBuffer[11] = byte.Parse(checkhumB[0].ToString());
                SendBuffer[12] = byte.Parse(checkhumB[1].ToString());
                SendBuffer[13] = 0X3e;
                SendBuffer[14] = 0Xe3;
                Serial.Write(SendBuffer, 0, SendBuffer.Length);
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        /// <summary>
        /// 发送命令 带数据
        /// </summary>
        /// <param name="no">命令号</param>
        /// <param name="data1">数据1</param>
        /// <param name="data2">数据2</param>
        /// <param name="data3">数据3</param>
        /// <param name="data4">数据3</param>
        public static void Write16ForNo(byte no, byte data1 = 0, byte data2 = 0, byte data3 = 0, byte data4 = 0, byte data5 = 0)
        {
            try
            {
                if (Serial == null) { return; }
                readBuffer.Clear();
                byte[] SendBuffer = new byte[16];
                SendBuffer[0] = 0X5a;
                SendBuffer[1] = 0Xa5;
                SendBuffer[2] = no;
                SendBuffer[3] = 0;
                SendBuffer[4] = 0;
                SendBuffer[5] = 0;
                SendBuffer[6] = 5;
                SendBuffer[7] = data1;
                SendBuffer[8] = data2;
                SendBuffer[9] = data3;
                SendBuffer[10] = data4;
                SendBuffer[11] = data5;
                var checkhumB = CRC16(SendBuffer, 11);
                SendBuffer[12] = byte.Parse(checkhumB[0].ToString());
                SendBuffer[13] = byte.Parse(checkhumB[1].ToString());
                SendBuffer[14] = 0X3e;
                SendBuffer[15] = 0Xe3;
                Serial.Write(SendBuffer, 0, SendBuffer.Length);
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        
        


       

        private static List<int> CRC16(byte[] data, int ll)
        {
            try
            {
                int checkhumB = 0;
                for (int checknumA = 2; checknumA < ll; checknumA++)
                {
                    checkhumB += data[checknumA];
                }
                return Util.ConvertToByteTwo(checkhumB);
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
                return new List<int>() { 0, 0 };
            }
        }

        private static void ErrorData()
        {
            try
            {
                if (readBuffer == null || readBuffer.Count == 0) { return; }
                //Util.ShowMsg("ComError");
                LogHelper.GetSingleObj().WriteLog($"整段通信:{string.Join(',', readBuffer)}");

                int c = 0;
                for (int i = 0; i < readBuffer.Count; i++)
                {
                    if (i > 1 && readBuffer[i - 1] == 0x5a && readBuffer[i] == 0xa5)
                    {
                        int counts = readBuffer[i + 4] * 256 + readBuffer[i + 5] + 11;
                        if (readBuffer[counts + 2] == 0xe3 && readBuffer[counts + 1] == 0x3e)
                        {
                            c = i - 1; break;
                        }
                    }
                }
                if (c == 0)
                {
                    readBuffer.Clear();
                }
                else
                {
                    readBuffer = readBuffer.Skip(c).ToList();
                }

                SerailData();
                LogHelper.GetSingleObj().WriteLog($"丢包后整段通信:{string.Join(',', readBuffer)}");
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        static void TempData()
        {
            try
            {
                if (readBuffer[0] == 0X5A && readBuffer[1] == 0XA5 && readBuffer[2] == 0X06 && readBuffer.Count > 19)
                {
                    readBuffer = readBuffer.Skip(19).ToList();
                    TempData();
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void StartTimer()
        {
            try
            {
                if (ctimer != null)
                {
                    ctimer.Elapsed -= Ctimer_Elapsed;
                    ctimer.Stop();
                    ctimer.Dispose();
                }

                ctimer = new System.Timers.Timer { Interval = 1000 };
                ctimer.Elapsed += Ctimer_Elapsed;
                ctimer.Start();
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void StopTimer()
        {
            try
            {
                if (ctimer != null)
                {
                    ctimer.Elapsed -= Ctimer_Elapsed;
                    ctimer.Stop();
                    ctimer.Dispose();
                    ctimer = null;
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

        private static void Ctimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                try
                {
                    tm++;
                    if (tm == 6 && MainWindow._This.Vm.SelfVisibility == Visibility.Visible)
                    {
                        var win = new MessageWin("SelfF")
                        {
                            Owner = MainWindow._This
                        };
                        win.Show();
                        win.Closing += (s, d) =>
                        {
                            //我这里是进行登录需求
                            MainWindow._This.Vm.SelfVisibility = Visibility.Collapsed;
                            MainWindow._This.Vm.IsRunning = false;
                            new LoginMainWin().Show();
                            StopTimer();
                        };
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.GetSingleObj().WriteLog(ex);
                }
            });
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值