Unity串口通信 16进制 SerialPorts 设置COM口

简介: 串口通信,实时传输,设置COM口,打包程序可设置COM口

1. 新建Unity工程,在场景中建立两个GameObject,分别命名:SerialPorts;DataCtl(直接拖拽或查找DataCtl,代码中可自行修改)

2.新建两个C#脚本,分别命名:SerialPortScript;DataCtlScript,并分别挂载到上述两个游戏物体

3.在Assets文件夹中新建文件夹命名:streamingAssets;在streamingAssets文件夹中新建Text文件命名:PortNameConfig;

在PortNameConfig.txt中写入串口名字,例COM7  

4.SerialPortScript:

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

public class PortTestScript : MonoBehaviour
{
    public string portName = " ";
    public int baudrate = 9600;
    public Parity parite = Parity.None;
    public int dataBits = 8;
    public StopBits stopbits = StopBits.One;
    SerialPort port;
    Thread portRev, portDeal;
    Queue <string> dataQueue;
    string outStr = string.Empty;

    void Start ()
    {
        //本地路径  
        string fileAddress = System.IO.Path.Combine (Application.streamingAssetsPath, "PortNameConfig.txt");  
    
    
        FileInfo fInfo0 = new FileInfo (fileAddress);  
        string s = "";  

        if (fInfo0.Exists) {  
            StreamReader r = new StreamReader (fileAddress);  
            s = r.ReadToEnd (); 
            portName = s;
            dataQueue = new Queue<string> (); 
            port = new SerialPort (portName, baudrate, parite, dataBits, stopbits);
            port.ReadTimeout = 400;
            try {
                port.Open ();
                Debug.Log ("串口打开成功!");
                portRev = new Thread (PortReceivedThread);
                portRev.IsBackground = true;
                portRev.Start ();
                portDeal = new Thread (DealData);
                portDeal.Start ();
            } catch (System.Exception ex) {
                Debug.Log (ex.Message);
            }
        }

    }


    //接收数据
    void PortReceivedThread ()
    {
        try {
            byte[] buf = new byte[1];
            string resStr = string.Empty; 
            if (port.IsOpen) {
                port.Read (buf, 0, 1);
            }
            if (buf.Length == 0) {
                return;
            }
            if (buf != null) {
                for (int i = 0; i < buf.Length; i++) {
                    //                    resStr += ASCIIEncoding.UTF8.GetString (buf);
                    resStr += buf [i].ToString ("X2") + " ";

                    //                    resStr += Encoding.UTF8.GetString (buf);
                    dataQueue.Enqueue (resStr); 
                    resStr += resStr;
                    //                    print (resStr); 

                }
            }
        } catch (System.Exception ex) {
//            Debug.Log (ex.Message);
        }
    }

    string message = " ";
    //处理
    void DealData ()
    {
        while (dataQueue.Count != 0) {
            for (int i = 0; i < dataQueue.Count; i++) {
                outStr += dataQueue.Dequeue ();

                if (outStr.Length == 24) {
                    
                    Debug.Log (outStr);
                    message = outStr;
                    outStr = string.Empty;
                }
            }
        }
    }


    public GameObject _shotctl;

    /// <summary>
    /// 传参数
    /// </summary>
    /// <param name="message"></param>
    void GetTheMessage (string message)
    {
        //传参数给 _shotctl这个游戏物体
        _shotctl.SendMessage ("GetShotMessage", message);

    }


    void SendData (byte[]msg)
    {
        //这里要检测一下msg
        if (port.IsOpen) {
            port.Write (msg, 0, msg.Length);
        }
    }

    string Info = " ";
    // Update is called once per frame
    void Update ()
    {
        if (port.IsOpen) {
            
        
            if (!portRev.IsAlive) {
                portRev = new Thread (PortReceivedThread);
                portRev.IsBackground = true;
                portRev.Start ();

            }
            if (!portDeal.IsAlive) {
                portDeal = new Thread (DealData);
                portDeal.Start ();
            } 
        }
        if (Info != message) {
            GetTheMessage (message);
            Info = message = " ";
        }
    }

    void OnApplicationQuit ()
    {
        Debug.Log ("退出!");
        if (port.IsOpen) {
            if (portRev.IsAlive) {
                portRev.Abort ();
            }
            if (portDeal.IsAlive) {
                portDeal.Abort ();
            }
        }

        port.Close ();
    }

}
 

5.DataCtlScript:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ctlScript : MonoBehaviour
{
    // Use this for initialization
    void Start ()
    {
        

    }
    // Update is called once per frame
    void Update ()
    {
            
    }
    public void GetShotMessage (string shotmessage)
    {
        //打印 shotmessage
        print(shotmessage);
        
    }

}
 

可以通过上述进行测试。

不过我也准备了UnityPakage包,可以直接下载Demo使用,地址:https://download.youkuaiyun.com/download/rick__/10764655

Unity 本身不支持直接读取数据,需要使用第三方插件或自己编写插件来实现。 以下是使用自己编写的插件来读取 16 进制数据的示例: 1. 创建一个 C# 脚本,命名为 SerialPortManager.cs。 2. 在脚本中引入 System.IO.Ports 命名空间 Unity 的命名空间。 ```csharp using System.IO.Ports; using UnityEngine; ``` 3. 在脚本中创建一个 SerialPort 类型的变量,用于连接串。 ```csharp private SerialPort serialPort; ``` 4. 在 Awake() 方法中初始化串连接,设置参数。 ```csharp void Awake() { serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One); serialPort.Open(); serialPort.ReadTimeout = 1000; } ``` 5. 在 Update() 方法中读取数据。 ```csharp void Update() { if (serialPort.IsOpen) { try { string hexString = serialPort.ReadExisting(); byte[] bytes = StringToByteArray(hexString); // 处理接收到的数据 } catch (System.Exception e) { Debug.LogWarning(e.Message); } } } ``` 6. 创建一个 StringToByteArray() 方法,用于将 16 进制字符串转换为字节数组。 ```csharp private byte[] StringToByteArray(string hexString) { hexString = hexString.Replace(" ", ""); byte[] bytes = new byte[hexString.Length / 2]; for (int i = 0; i < hexString.Length; i += 2) { bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16); } return bytes; } ``` 使用以上方法,就可以实现在 Unity读取 16 进制数据了。注意需要在项目设置中开启串权限。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rick__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值