| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- using SerialPortUtility;
- using System;
- 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<string, int> _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, bool warning = false)
- {
- if (!warning)
- Debug.Log($"<color=#00FF00>{msg}</color>");
- else
- Debug.LogWarning($"<color=#00FF00>{msg}</color>");
- }
- private void Init()
- {
- _isInit[gameObject.name] = GetInstanceID();
- #if UNITY_ANDROID && !UNITY_EDITOR
- serialPortUtility = gameObject.GetComponent<SerialPortUtilityPro>();
- serialPortUtility.OpenMethod = openMode;
- serialPortUtility.DeviceName = PortName;
- serialPortUtility.BaudRate = baudrate;
- serialPortUtility.StopBit = SerialPortUtilityPro.StopBitEnum.OneBit;
- serialPortUtility.DataBit = SerialPortUtilityPro.DataBitEnum.EightBit;
- serialPortUtility.SystemEventObject.AddListener(SystemEventObject);
- TrySerialOpenPort();
- #endif
- #if UNITY_EDITOR
- if (testMode)
- {
- var testBoard = Resources.Load<GameObject>("SerialPortTest");
- GameObject.Instantiate(testBoard);
- }
- #endif
- }
- private void TrySerialOpenPort()
- {
- serialPortUtility?.Open();
- }
- private void SystemEventObject(SerialPortUtilityPro arg0, string msg)
- {
- if (msg.Equals("OPEN_ERROR") || msg.Equals("PERMISSION_ERROR"))//串口开启失败 定时重试
- {
- #if UNITY_ANDROID && !UNITY_EDITOR
- Invoke("TrySerialOpenPort", 1f);
- #endif
- LOG($"{PortName} 串口打开失败 重试中", true);
- }
- else if (msg.Equals("OPENED"))
- {
- SerialPortHelper.ins.OnConnect(arg0.DeviceName);
- RequestDeviceIno();//应用启动 请求一次设备信息
- LOG($"{PortName} 串口打开成功!");
- }
- else if (msg.Equals("CLOSED"))//串口断开
- {
- SerialPortHelper.ins.OnDisConnect(arg0.DeviceName);
- LOG($"{PortName} 串口关闭!");
- }
- }
- private void OnDestroy()
- {
- if (_isInit.TryGetValue(gameObject.name, out var instanceID) && instanceID == GetInstanceID())
- {
- LOG($"{PortName} 串口关闭");
- SerialPortHelper.ins.OnDisConnect(serialPortUtility?.DeviceName);
- serialPortUtility?.Close();
- _isInit.Remove(gameObject.name);
- }
- }
-
- /// <summary>
- /// 串口读取二进制流数据(界面挂载调用)
- /// </summary>
- /// <param name="data"></param>
- public void ReadStreamingBinary(object data)
- {
- PhraseData(data as byte[]);
- }
- public void TestRead(byte[] bytes)
- {
- PhraseData(bytes);
- }
- /// <summary>
- /// 解析串口数据
- /// </summary>
- /// <param name="bytes"></param>
- 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请求
- // 异或校验内容:命令+长度+数据内容
-
- /// <summary>
- /// app请求设备信息
- /// </summary>
- public void RequestDeviceIno()
- {
- List<byte> data = new List<byte>();
- data[0] = 0xAA;//起始码
- data[1] = 0x80;//命令号
- data[2] = 0x05;//长度
- data[3] = 0x85;//异或校验
- data[4] = 0x55;//结束码
- serialPortUtility?.Write(data.ToArray());
- }
- #endregion
-
- #region 返回消息处理
- /// <summary>
- /// 设备信息响应
- /// </summary>
- private void OnDeviceInfoBack(byte[] bytes)// 0xAA 0x80 0x07 0x01 0x01 0x89 0x5D
- {
- Debug.Log($"{PortName} 收到设备信息响应!");
- var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容
- if (check != bytes[5])
- LOG("OnDeviceInfoBack 数据校验错误!");
- else
- {
- //0x01 HOUYI Pro
- //0x02 ARTEMIS Pro
- //0x03 Pistol 1
- var deviceType = bytes[3];//设备类型
- switch (deviceType)
- {
- case 0x01:
- UserSettings.ins.selectDevicesName = "HOUYI Pro";
- DevicesHolder.ins.SwitchDeviceByType(AimDeviceType.HOUYIPRO);
- break;
- case 0x02:
- UserSettings.ins.selectDevicesName = "ARTEMIS Pro";
- DevicesHolder.ins.SwitchDeviceByType(AimDeviceType.ARTEMISPRO);
- break;
- case 0x03:
- UserSettings.ins.selectDevicesName = "Pistol M9";
- DevicesHolder.ins.SwitchDeviceByType(AimDeviceType.Gun);
- break;
- }
-
- //刷新界面
- var setting = FindAnyObjectByType<CustomUIView.BoxUserSettings>();
- setting?.FlushDeviceSelect();
- }
- }
-
- /// <summary>
- /// 射击消息
- /// </summary>
- private void OnDeviceShoot(byte[] bytes)
- {
- LOG($"{PortName} 收到设备射击消息!");
- var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容
- if (check != bytes[5])
- {
- LOG("OnDeviceShoot 数据校验错误!");
- }else
- SerialPortHelper.shoot?.Invoke(bytes);
- }
- /// <summary>
- /// 按键消息
- /// </summary>
- /// <param name="bytes"></param>
- private void OnDeviceButton(byte[] bytes)
- {
- Debug.Log($"{PortName} 收到设备按键消息!");
- var check = bytes[1] + bytes[2] + bytes[3];//校验:命令+长度+数据内容
- if (check != bytes[4])
- {
- LOG("OnDeviceButton 数据校验错误!");
- }
- else
- SerialPortHelper.aim?.Invoke(bytes);
- }
-
- #endregion
- }
|