unity3d 串口通信

根据网上查阅的资料测试并修改的,各种资料各种坑,此处经过一天的修改测试

终于完善了串口通信,以下是代码,脚本直接挂在摄像机就可以了

还有一些bug,不过感觉勉强可以用

using UnityEngine;
using System.Collections;
using System.IO;
using System.IO.Ports;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;//16进制转换

public class ChuanK1 : MonoBehaviour
{

    public string portName = "COM1";
    public int baudRate = 9600;
    public Parity parity = Parity.None;
    public int dataBits = 8;
    public StopBits stopBits = StopBits.One;
    SerialPort sp = null;       //串口的通信类
    byte[] data = new byte[128];  //用户存储6位数据    
    Thread dataReceiveThread;

    string message = "BB";//发送
    string msg; //接收到的数据显示在Label
    string tishi;//提示串口是否打开

    string str1 = "";
    string str2 = "";
    List<string> liData = new List<string>();
    string str = "";
    private bool shuJuZJ = false;

    void Start()
    {
        OpenPort();
        dataReceiveThread = new Thread(new ThreadStart(DataReceiveFunction));//开启线程接收数据
        dataReceiveThread.Start();
    }
    void Update()
    {
        if (shuJuZJ)
        {
            CancelInvoke("XieCheng");//如果str还未接收完整DataReceiveFunction()扔在执行,则快速终止调用
            shuJuZJ = false;
            Invoke("XieCheng", 0.1f);//可根据数据大小来定接收完整数据的时间
        }
    }
    public void OpenPort()  //打开串口
    {
        sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
        sp.ReadTimeout = 400;
        try
        {
            sp.Open();
            Debug.Log("串口已经打开");
            tishi = "串口已经打开";
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    public void ClosePort()         //关闭串口
    {
        try
        {
            sp.Close();
            Debug.Log("关闭串口");
            tishi = "关闭串口";
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    public void WriteData(string dataStr)//写入数据
    {
        if (sp.IsOpen)
        {
            sp.Write(dataStr);
        }
    }
    void OnApplicationQuit()
    {
        ClosePort();
    }
    void DataReceiveFunction()
    {
        byte[] buffer = new byte[128];
        //string str = string.Empty;    //此处只执行一次
        //int index = 0;
        int bytes;
        while (true)
        {
            if (sp != null && sp.IsOpen)      //  sp != null &&
            {
                try
                {
                    //这里面会执行多次,以接收byte[]数据
                    bytes = sp.Read(buffer, 0, buffer.Length);
                    for (int i = 0; i < bytes; i++)
                    {
                        data[i] = buffer[i];        //将数据存入data
                        //str += data[i].ToString("X2") + "/";    //X表示16进制,2表示两位数
                        //index++;
                    }
                    //Debug.Log("长度:" + bytes);
                    if (bytes == 1)
                    {
                        liData.Clear();//添加数据前,先清空泛型数组
                        str1 = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                        liData.Add(str1);
                    }
                    else
                    {
                        str2 = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                        liData.Add(str2);
                        str = "";
                        foreach (var i in liData)
                        {
                            str += i;
                            Debug.Log("");//这里非要加一个Debug,不然最终数据接收不完整
                        }
                        Debug.Log("");//这里非要加一个Debug,不然最终数据接收不完整
                        shuJuZJ = true;
                    }
                }
                catch (Exception e)
                {
                    if (e.GetType() != typeof(ThreadAbortException))
                    {
                        //Debug.Log(e.Message);
                    }
                }
            }
            Thread.Sleep(1);
        }
    }
    void XieCheng()
    {
        Debug.Log("最终数据:" + str);
        //这里接收到的数据str,进行处理
    }
    void OnGUI()        //按钮发送数据
    {
        message = GUILayout.TextField(message);
        if (GUI.Button(new Rect(100, 100, 100, 30), "Send Message"))
        {
            WriteData(message);
        }
        string by = "AA";
        if (GUI.Button(new Rect(100, 150, 100, 30), "Send"))
        {
            WriteData(by);
        }
        GUILayout.Label(msg);
        if (GUI.Button(new Rect(100, 200, 100, 30), "Quit"))
        {
            Application.Quit();
        }
        GUILayout.Label(tishi);
    }
}

关于有两处一定要加上Debug,我也不知道为什么会这样,如有更好的修改办法,欢迎联系。

猜你喜欢

转载自blog.csdn.net/q510264505/article/details/71209941