Unity 读取Arduino串口消息

垃圾文章 没写好 别看!!!

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

/// <summary>
/// 串口通信
/// </summary>
public class SerialKit:MonoBehaviour
{
    public static SerialKit Instance;

    // 在设备管理器中查看端口名称
    public string m_rduinoBoardName = "ArduinoBoardNano";

    /// <summary>
    /// 开启串口参数
    /// </summary>
    public class SerialPortParam
    {
        public string portName;
        public int BaudRate;
        public Parity Parity;
        public StopBits StopBits;
        public int DataBits;
        public Handshake Handshake;
        public bool RtsEnable;
    }

    public   SerialPort serialPort;
    private bool isClose;
    private Thread serialPortThread;//收发串口线程

    //读取数据缓存
    private byte[] readDataBuffer = new byte[1024];
    private int readDataLen;//读取到数据长度

    //写数据缓存
    private List<byte> writeDataBuffer = new List<byte>();

    private bool isOpen;

    /// <summary>
    /// 是否开启串口
    /// </summary>
    public bool IsOpen
    {
        get { return isOpen; }
    }

    #region 事件

    /// <summary>
    /// 接到数据(子线程)
    /// </summary>
    public Action<byte[]> OnReceiveData;

    /// <summary>
    /// 错误(子线程)
    /// </summary>
    public Action<string> OnError;

    #endregion

    private void Awake()
    {
        Instance = this;
    }

    private void Start()
    {
        // 可以用于多个单片机用于数据的接收和写入
        // 第一个端口初始化
        SerialPortParam param = new SerialPortParam()
        {
            portName = "COM3",
            BaudRate = 9600,
            Parity = Parity.None,
            DataBits = 8,
            StopBits = StopBits.One
        };
        // 第一个端口实例化
        serialPort = new SerialPort(param.portName); //串口名
        // 第一个端口打开串口
        Open(serialPort,param);
}

    private void OnDestroy()
    {
        Close();
    }

    /// <summary>
    /// 根据Arduino单片机在设备管理器端口名字,获取它连接的端口
    /// </summary>
    /// <returns></returns>
    private string GetArduinoBoardPort(string sArduinoBoardName = "ArduinoBoardNano")
    {
        string sArduinoBoardPort = "";

        // 遍历所有端口
        foreach (string item in SerialPort.GetPortNames())
        {
            if (item.Equals(sArduinoBoardName))
            {
                sArduinoBoardPort = item;
                Debug.Log("找到当前单片机连接的端口: " + item);
            }
        }
        return sArduinoBoardPort;
    }

    /// <summary>
    /// 开启串口
    /// </summary>
    /// <param name="param"></param>
    public void Open(SerialPort serialPort,SerialPortParam param)
    {
        serialPort.BaudRate = param.BaudRate; //波特率
        serialPort.Parity = param.Parity; //效验位
        serialPort.StopBits = param.StopBits; //停止位
        serialPort.DataBits = param.DataBits; //数据位
        serialPort.ReadTimeout = 1; // 读取超时
        serialPort.WriteTimeout = 1; // 写入超时

        try
        {
            serialPort.Open();
        }
        catch (Exception ex)
        {
            if (OnError != null)
                OnError(ex.ToString());

            Close();
        }

        isOpen = true;
        isClose = false;

        serialPortThread = new Thread(new ParameterizedThreadStart(work));
        serialPortThread.Start(serialPort);
    }


    /// <summary>
    /// 只使用了一个端口 发送数据
    /// </summary>
    /// <param name="bytes"></param>
    public void Send(byte[] bytes)
    {
        if (serialPort != null
            && serialPort.IsOpen)
        {
            lock (writeDataBuffer)
            {
                writeDataBuffer.AddRange(bytes);
            }
        }
    }

    /// <summary>
    /// 使用多个端口 发送数据
    /// </summary>
    /// <param name="bytes"></param>
    public void Send(SerialPort serialPort, byte[] bytes)
    {
        if (serialPort != null
            && serialPort.IsOpen)
        {
            lock (writeDataBuffer)
            {
                writeDataBuffer.AddRange(bytes);
            }
        }
    }

    /// <summary>
    ///  接收消息
    /// </summary>
    /// <param name="obj"></param>
    private void work(object obj)
    {
        SerialPort sp = (SerialPort)obj;

        while (true)
        {
            if (isClose)
                break;

            if (!sp.IsOpen)
            {
                break;
            }

            //读取
            try
            {
                readDataLen = sp.Read(readDataBuffer, 0, readDataBuffer.Length);
                if (readDataLen > 0)
                {
                    byte[] receiveBytes = new byte[readDataLen];
                    Array.Copy(readDataBuffer, 0, receiveBytes, 0, receiveBytes.Length);
                    if (OnReceiveData != null)
                        OnReceiveData(receiveBytes);
                }
            }
            catch (TimeoutException)
            {//正常结束

            }
            catch (Exception ex)
            {
                sp.Close();

                if (OnError != null)
                    OnError(ex.ToString());
            }

            //写入
            if (writeDataBuffer.Count > 0)
            {
                byte[] writeBytes = null;
                lock (writeDataBuffer)
                {
                    writeBytes = writeDataBuffer.ToArray();
                    writeDataBuffer.Clear();
                }

                try
                {
                    sp.Write(writeBytes, 0, writeBytes.Length);
                }
                catch (TimeoutException)
                {//正常结束

                }
                catch (Exception ex)
                {
                    sp.Close();

                    if (OnError != null)
                        OnError(ex.ToString());
                }
            }
        }

        sp.Close();
    }


    /// <summary>
    /// 关闭端口
    /// </summary>
    public void Close()
    {
        isOpen = false;
        isClose = true;
        serialPort = null;
    }
}

参考链接: https://gameinstitute.qq.com/community/detail/116079  我也不知道这个是不是原创,这个啥TXYX学院好多都是直接Copy的

猜你喜欢

转载自blog.csdn.net/qq_39097425/article/details/110411495