Unity3d使用SerialPortUtilityPro读取串口数据

Unity3d2021.3.35f1,Serial Port Utility Pro v2.6

一、测试串口接收基本功能

1.新建工程,导入Serial Port Utility Pro v2.6.unitypackage

提示 error CS0619: 'AndroidSdkVersions.AndroidApiLevel21' is obsolete: 'Minimum supported Android API level is 22 (Android 5.1 Lollipop). Please use AndroidApiLevel22 or higher'

解决方法将21改为22

2.打开ExampleDeviceList场景

3.修改DeviceListProgram波特率为115200,编辑代码SPUPDeviceList.cs

(1)将按钮名改为串口名

(2)接收0x00时不要丢弃,处理16进制时有用,

4.切换到SerialPortUtilityPro.cs,去掉ReadUpdate函数中的调试输出代码

5.添加byte数组以16进制字符串显示函数

复制代码
        /// <summary>
        /// byte[]转16进制格式string
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToHexString(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                { 
                    returnStr += bytes[i].ToString("X2") + " ";
                }
            }
            return returnStr;
        }

6.输入16进制字符串

cs 复制代码
                string debugString = ToHexString(dataBuffer.ToArray());
                Debug.Log(debugString);
                SerialDebugAddString(debugString, false);

注意:程序UI字符串太长的话会被截断,输出到Unity控制台不会被截断。

二、在下拉列表中打开串口

1.修改SPUPDeviceList.cs

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Linq;

public class SPUPDeviceList : MonoBehaviour
{
	//SPUP
    List<SerialPortUtility.SerialPortUtilityPro> spList = new List<SerialPortUtility.SerialPortUtilityPro>();
    public int baudrate = 115200;
    public SerialPortUtility.SerialPortUtilityPro.OpenSystem openMode = SerialPortUtility.SerialPortUtilityPro.OpenSystem.USB;

    public PositioningManager positioningManager;
    public Dropdown dropdownDevices;
    public Button btnOpen;
    public Text textPrompt;

    private Dictionary<string, SerialPortUtility.SerialPortUtilityPro.DeviceInfo> dictIndex2Dev = new Dictionary<string, SerialPortUtility.SerialPortUtilityPro.DeviceInfo>();

    void Awake()
	{
        SerialPortUtility.SerialPortUtilityPro.DeviceInfo[] devicelist = 
            SerialPortUtility.SerialPortUtilityPro.GetConnectedDeviceList(openMode);

        if (devicelist == null)
            return;

        foreach (SerialPortUtility.SerialPortUtilityPro.DeviceInfo d in devicelist)
        {
            //serialPort = new SerialPortUtility.SerialPortUtilityPro(); //do not use
            String GameObjectName = "NONE";
            if (openMode == SerialPortUtility.SerialPortUtilityPro.OpenSystem.USB)
                GameObjectName = d.PortName;
            else if (openMode == SerialPortUtility.SerialPortUtilityPro.OpenSystem.BluetoothSSP)
                GameObjectName = d.SerialNumber;
            else if (openMode == SerialPortUtility.SerialPortUtilityPro.OpenSystem.PCI)
                GameObjectName = d.Vendor;

            dictIndex2Dev.Add(GameObjectName, d);
        }
        dropdownDevices.AddOptions(dictIndex2Dev.Keys.ToList());
    }

    private void Start()
    {
        btnOpen.onClick.AddListener(Open);
    }

    void Open()
    {
        string key = dropdownDevices.options[dropdownDevices.value].text;
        if(dictIndex2Dev.ContainsKey(key))
        {
            SerialPortUtility.SerialPortUtilityPro.DeviceInfo d = dictIndex2Dev[key];
            OpenSerialPort(d, key);
        }
    }

    private void OpenSerialPort(SerialPortUtility.SerialPortUtilityPro.DeviceInfo d, string GameObjectName)
    {
        GameObject obj = new GameObject(GameObjectName);
        SerialPortUtility.SerialPortUtilityPro serialPort = obj.AddComponent<SerialPortUtility.SerialPortUtilityPro>();
   
        //config
        serialPort.SetDebugConsoleMonitorView(false);
        serialPort.OpenMethod = openMode;
        serialPort.VendorID = d.Vendor;
        serialPort.ProductID = d.Product;
        serialPort.SerialNumber = d.SerialNumber;
        serialPort.BaudRate = baudrate;   //115200kbps

        serialPort.ReadProtocol = SerialPortUtility.SerialPortUtilityPro.MethodSystem.Streaming;
        serialPort.RecvDiscardNull = false;
        serialPort.IsAutoOpen = true;
        serialPort.OnReceveDistanceMsgHand += OnReceveDistanceMsg;
        spList.Add(serialPort);

        StartCoroutine(delayGetOpenResult(serialPort));
    }

    IEnumerator delayGetOpenResult(SerialPortUtility.SerialPortUtilityPro serialPort)
    {
        yield return new WaitForSeconds(0.2f);
        bool suc = serialPort.IsOpened();
        textPrompt.text = suc ? "打开成功" : "打开失败";
    }

    void OnReceveDistanceMsg(uint dis1, uint dis2, uint dis3)
    {
        positioningManager.UpdateDistance(dis1, dis2, dis3);
    }

    void OnDestory()
	{
        foreach (SerialPortUtility.SerialPortUtilityPro item in spList)
        {
            item.Close();
        }
	}
	
	// Update is called once per frame
	void Update ()
	{
        if (Input.GetKey(KeyCode.Home) || Input.GetKey(KeyCode.Escape) || Input.GetKey(KeyCode.Menu))
        {
            Application.runInBackground = false;
            Application.Quit();
            return;
        }
    }

	//for 
	public void ReadComprateString(object data)
	{
		var text = data as string;
		Debug.Log(text);
	}
}