using SerialPortUtility; using System.Collections.Generic; using UnityEngine; public class ArrowSerialPort : MonoBehaviour { private SerialPortUtilityPro serialPortUtility; private SerialPortUtilityPro.OpenSystem openMode = SerialPortUtilityPro.OpenSystem.PCI; private int baudrate = 115200; private string PortName = "/dev/ttyS1"; private static Dictionary _isInit = new(); public bool testMode = false; private void Awake() { if (!_isInit.TryGetValue(gameObject.name, out int instanceID) && instanceID == 0) { DontDestroyOnLoad(gameObject); Init(); } } private void LOG(string msg) { Debug.Log($"{msg}"); } private void Init() { _isInit[gameObject.name] = GetInstanceID(); serialPortUtility = gameObject.GetComponent(); serialPortUtility.OpenMethod = openMode; serialPortUtility.DeviceName = PortName; serialPortUtility.BaudRate = baudrate; serialPortUtility.StopBit = SerialPortUtilityPro.StopBitEnum.OneBit; serialPortUtility.DataBit = SerialPortUtilityPro.DataBitEnum.EightBit; serialPortUtility.Open(); LOG($"{PortName} 串口打开"); #if UNITY_EDITOR if (testMode) { var testBoard = Resources.Load("SerialPortTest"); GameObject.Instantiate(testBoard); } #endif } private void OnDestroy() { if (_isInit.TryGetValue(gameObject.name, out var instanceID) && instanceID == GetInstanceID()) { LOG($"{PortName} 串口关闭"); serialPortUtility.Close(); _isInit.Remove(gameObject.name); } } /// /// 串口读取二进制流数据(界面挂载调用) /// /// public void ReadStreamingBinary(object data) { PhraseData(data as byte[]); } public void TestRead(byte[] bytes) { PhraseData(bytes); } /// /// 解析串口数据 /// /// private void PhraseData(byte[] bytes) { LOG($"{PortName} 收到串口信息!"); if (bytes[0] == 0xAA) { var cmdID = bytes[1]; switch (cmdID) { case 0x80://设备信息响应 OnDeviceInfoBack(bytes); break; case 0x81://射击消息 OnDeviceShoot(bytes); break; case 0x82://按键消息 OnDeviceButton(bytes); break; } } } #region APP请求 // 异或校验内容:命令+长度+数据内容 /// /// app请求设备信息 /// public void RequestDeviceIno() { List data = new List(); data[0] = 0xAA;//起始码 data[1] = 0x80;//命令号 data[2] = 0x05;//长度 data[3] = 0x85;//异或校验 data[4] = 0x55;//结束码 serialPortUtility.Write(data.ToArray()); } #endregion #region 返回消息处理 /// /// 设备信息响应 /// private void OnDeviceInfoBack(byte[] bytes) { Debug.Log($"{PortName} 收到设备信息响应!"); var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容 if(check != bytes[5]) { LOG("OnDeviceInfoBack 数据校验错误!"); } //0x01 HOUYI Pro //0x02 ARTEMIS Pro //0x03 Pistol 1 var deviceType = bytes[3];//设备类型 //0x01 移动手机 //0x02 PC电脑 //0x03 VR设备 var systemType = bytes[4];//系统类型 } /// /// 射击消息 /// private void OnDeviceShoot(byte[] bytes) { Debug.Log($"{PortName} 收到设备射击消息!"); var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容 if (check != bytes[5]) { LOG("OnDeviceShoot 数据校验错误!"); } var time1 = bytes[3]; var time2 = bytes[4]; } /// /// 按键消息 /// /// private void OnDeviceButton(byte[] bytes) { Debug.Log($"{PortName} 收到设备按键消息!"); var check = bytes[1] + bytes[2] + bytes[3];//校验:命令+长度+数据内容 if (check != bytes[4]) { LOG("OnDeviceButton 数据校验错误!"); } var clickType = bytes[3];//按键类型 // 0x01 开机键 - 短按 // 0x02 开机键 - 长按(1.5 秒) // 0x03 开机键 - 双击 // 0x04 标定键 - 短按 // 0x05 标定键 - 长按(1.5 秒) // 0x06 标定键 - 双击 } #endregion }