串口断线重连

串口脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System.Threading;
using System;
using System.Management;

public class Com2App : AutoInstance
{
    SerialPort port;
    public static string comName;
    Thread initThread;
    Thread recThread;
    Thread checkThread;
    public bool isChange;
    public bool isLink;
    int recInt = 0;
    public int RecInt
    {
        get
        {
            return recInt;
        }
        set
        {
            if (recInt != value)
            {
                recInt = value;
                isChange = true;
            }
        }
    }


    private void InitPort()
    {
        ExceptionManagement.AddLogInfo("初始化串口", MyLogType.Log);

        port = new SerialPort(comName, 115200);
        port.StopBits = StopBits.Two;
        port.DataBits = 8;
        port.Parity = Parity.None;
        while (!port.IsOpen)//未插入串口时保持轮询
        {
            try
            {
                port.Open();
            }
            catch
            {
                continue;
            }
            Thread.Sleep(500);
        }
        isLink = true;
        InitThread();
    }
    private void InitThread()
    {
        if (recThread == null)
        {
            recThread = new Thread(port_DataReceived);
            recThread.Start();
        }
        if (checkThread==null)
        {
            checkThread = new Thread(Work);
            checkThread.Start();
        }

    }

    void Work()
    {
        ExceptionManagement.AddLogInfo("work", MyLogType.Log);
        while (checkThread.IsAlive)
        {
            try
            {
                if (isLink) //串口已打开
                {
                    //ExceptionManagement.AddLogInfo("串口已打开", MyLogType.Log);
                }
                else
                {
                    //串口重连逻辑
                    ExceptionManagement.AddLogInfo("串口已拔出", MyLogType.Log);
                    //if (OnComStatus != null) OnComStatus(true);
                    if (port != null)
                    {
                        if (recThread != null)
                        {
                            recThread.Abort();
                            recThread = null; 
                            Thread.Sleep(300);
                        }
                        
                        port.Close();
                        port.Dispose();
                        port = null;
                    }
                    Thread.Sleep(100);
                    if (!string.IsNullOrEmpty(comName))
                    {
                        InitPort();
                        //port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                        ExceptionManagement.AddLogInfo("重新连接串口", MyLogType.Log);
                        //if (OnComStatus != null) OnComStatus(false);
                    }
                }
            }
            catch (Exception e)
            {
                string erroMsg = e.Message;

                ExceptionManagement.AddLogInfo("work有问题: " + erroMsg, MyLogType.Error);
            }
            Thread.Sleep(3000);
        }
    }

    void port_DataReceived()
    {
        ExceptionManagement.AddLogInfo("接收线程准备", MyLogType.Log);
        Thread.Sleep(1000);
        while (isLink)
        {
            try
            {
                int count = port.BytesToRead;
                if (count > 0)
                {
                    byte[] datas = new byte[count];
                    port.Read(datas, 0, count);
                    RecInt = datas[0];
                    //ExceptionManagement.AddLogInfo($"接收的指令: {RecInt}", MyLogType.Log);

                }

            }
            catch (Exception e)
            {
                string erroMsg = e.Message;
                ExceptionManagement.AddLogInfo($"串口收线程有问题{erroMsg}", MyLogType.Error);
                isLink = false;//串口拔出时进入重连逻辑
            }

        }

    }



    private void Awake()
    {
        Initialize();

    }
    // Start is called before the first frame update
    void Start()
    {
        initThread = new Thread(InitPort);
        initThread.Start();
    }
    private void OnDestroy()
    {
        recThread.Abort();
        recThread = null;
        checkThread.Abort();
        checkThread = null;
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public enum MyLogType
{
    Log,
    Error,
}
public class ExceptionManagement : MonoBehaviour
{
    //public ILog log;
    public LogInfo erroLog = new LogInfo();
    public string netLog = "Cannot connect to destination host";
    public bool isDisconnect = false;
    public string devLog = "IOException: The port `COM3' does not exist.";
    public bool isNoCom = false;

    public static Queue infoQueue = new Queue();//日志队列


    public static string numListToString(byte[] list)
    {
        string str = "";
        foreach (int n in list)
            str += n + " ";

        return str;
    }

    public static void AddLogInfo(string message, MyLogType logType)
    {
        LogInfo logInfo = new LogInfo();
        logInfo.message = message;
        logInfo.logType = logType;
        infoQueue.Enqueue(logInfo);
    }

    public static void LogMessage(LogInfo logInfo)
    {
        string type = string.Empty;
        switch (logInfo.logType)
        {
            case MyLogType.Error:
                type = "Erro:";
                break;
            case MyLogType.Log:
                type = "Log:";
                break;
            default:
                break;
        }
        FileStream myStream = new FileStream(FileManager.Instance.logPath, FileMode.Append, FileAccess.Write);
        StreamWriter sWriter = new StreamWriter(myStream);
        sWriter.WriteLine(DateTime.Now.ToString("F") + "  " + type + "   " + logInfo.message + "\n");
        sWriter.Close();
        myStream.Close();
    }

    private void WriteLog()
    {
        //if (infoQueue == null || infoQueue.Count <= 0)
        //    return;
        //print(infoQueue);
        //print(infoQueue.Count);
        if (infoQueue == null || infoQueue.Count <= 0)
            return;
        var info = infoQueue.Dequeue();
        LogMessage(info);
    }

    void OnEnable()
    {
        Application.logMessageReceivedThreaded += HandleLog;
    }

    void OnDisable()
    {
        Application.logMessageReceivedThreaded -= HandleLog;
    }

    void HandleLog(string logString, string stackTrace, LogType type)
    {
        if (type == LogType.Error || type == LogType.Exception)
        {
            AddLogInfo(logString, MyLogType.Error);
        }
    }

    void Awake()
    {
        //Initialize();
        //1.初始化
        //log = LogManager.GetLogger(typeof(MonoBehaviour)); //需要传递调用日志类的类型

    }
    private void Update()
    {
        WriteLog();
    }
}
public struct LogInfo
{
    public string message;
    public MyLogType logType;
}

你可能感兴趣的:(串口断线重连)