ArrowSerialPort.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using SerialPortUtility;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class ArrowSerialPort : MonoBehaviour
  5. {
  6. private SerialPortUtilityPro serialPortUtility;
  7. private SerialPortUtilityPro.OpenSystem openMode = SerialPortUtilityPro.OpenSystem.PCI;
  8. private int baudrate = 115200;
  9. private string PortName = "/dev/ttyS1";
  10. private static Dictionary<string, int> _isInit = new();
  11. public bool testMode = false;
  12. private void Awake()
  13. {
  14. if (!_isInit.TryGetValue(gameObject.name, out int instanceID) && instanceID == 0)
  15. {
  16. DontDestroyOnLoad(gameObject);
  17. Init();
  18. }
  19. }
  20. private void LOG(string msg)
  21. {
  22. Debug.Log($"<color=#00FF00>{msg}</color>");
  23. }
  24. private void Init()
  25. {
  26. _isInit[gameObject.name] = GetInstanceID();
  27. serialPortUtility = gameObject.GetComponent<SerialPortUtilityPro>();
  28. serialPortUtility.OpenMethod = openMode;
  29. serialPortUtility.DeviceName = PortName;
  30. serialPortUtility.BaudRate = baudrate;
  31. serialPortUtility.StopBit = SerialPortUtilityPro.StopBitEnum.OneBit;
  32. serialPortUtility.DataBit = SerialPortUtilityPro.DataBitEnum.EightBit;
  33. serialPortUtility.Open();
  34. LOG($"{PortName} 串口打开");
  35. #if UNITY_EDITOR
  36. if (testMode)
  37. {
  38. var testBoard = Resources.Load<GameObject>("SerialPortTest");
  39. GameObject.Instantiate(testBoard);
  40. }
  41. #endif
  42. RequestDeviceIno();//应用启动 请求一次设备信息
  43. }
  44. private void OnDestroy()
  45. {
  46. if (_isInit.TryGetValue(gameObject.name, out var instanceID) && instanceID == GetInstanceID())
  47. {
  48. LOG($"{PortName} 串口关闭");
  49. serialPortUtility.Close();
  50. _isInit.Remove(gameObject.name);
  51. }
  52. }
  53. /// <summary>
  54. /// 串口读取二进制流数据(界面挂载调用)
  55. /// </summary>
  56. /// <param name="data"></param>
  57. public void ReadStreamingBinary(object data)
  58. {
  59. PhraseData(data as byte[]);
  60. }
  61. public void TestRead(byte[] bytes)
  62. {
  63. PhraseData(bytes);
  64. }
  65. /// <summary>
  66. /// 解析串口数据
  67. /// </summary>
  68. /// <param name="bytes"></param>
  69. private void PhraseData(byte[] bytes)
  70. {
  71. LOG($"{PortName} 收到串口信息!");
  72. if (bytes[0] == 0xAA)
  73. {
  74. var cmdID = bytes[1];
  75. switch (cmdID)
  76. {
  77. case 0x80://设备信息响应
  78. OnDeviceInfoBack(bytes);
  79. break;
  80. case 0x81://射击消息
  81. OnDeviceShoot(bytes);
  82. break;
  83. case 0x82://按键消息
  84. OnDeviceButton(bytes);
  85. break;
  86. }
  87. }
  88. }
  89. #region APP请求
  90. // 异或校验内容:命令+长度+数据内容
  91. /// <summary>
  92. /// app请求设备信息
  93. /// </summary>
  94. public void RequestDeviceIno()
  95. {
  96. List<byte> data = new List<byte>();
  97. data[0] = 0xAA;//起始码
  98. data[1] = 0x80;//命令号
  99. data[2] = 0x05;//长度
  100. data[3] = 0x85;//异或校验
  101. data[4] = 0x55;//结束码
  102. serialPortUtility.Write(data.ToArray());
  103. }
  104. #endregion
  105. #region 返回消息处理
  106. /// <summary>
  107. /// 设备信息响应
  108. /// </summary>
  109. private void OnDeviceInfoBack(byte[] bytes)// 0xAA 0x80 0x07 0x01 0x01 0x89 0x5D
  110. {
  111. Debug.Log($"{PortName} 收到设备信息响应!");
  112. var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容
  113. if(check != bytes[5])
  114. {
  115. LOG("OnDeviceInfoBack 数据校验错误!");
  116. }
  117. //0x01 HOUYI Pro
  118. //0x02 ARTEMIS Pro
  119. //0x03 Pistol 1
  120. var deviceType = bytes[3];//设备类型
  121. switch (deviceType)
  122. {
  123. case 0x01:
  124. UserSettings.ins.selectDevicesName = "HOUYI Pro";
  125. break;
  126. case 0x02:
  127. UserSettings.ins.selectDevicesName = "ARTEMIS Pro";
  128. break;
  129. case 0x03:
  130. UserSettings.ins.selectDevicesName = "Pistol";
  131. break;
  132. }
  133. //0x01 移动手机
  134. //0x02 PC电脑
  135. //0x03 VR设备
  136. var systemType = bytes[4];//系统类型
  137. //刷新界面
  138. var setting = FindAnyObjectByType<CustomUIView.BoxUserSettings>();
  139. setting?.FlushDeviceSelect();
  140. }
  141. /// <summary>
  142. /// 射击消息
  143. /// </summary>
  144. private void OnDeviceShoot(byte[] bytes)
  145. {
  146. Debug.Log($"{PortName} 收到设备射击消息!");
  147. var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容
  148. if (check != bytes[5])
  149. {
  150. LOG("OnDeviceShoot 数据校验错误!");
  151. }
  152. var time1 = bytes[3];
  153. var time2 = bytes[4];
  154. }
  155. /// <summary>
  156. /// 按键消息
  157. /// </summary>
  158. /// <param name="bytes"></param>
  159. private void OnDeviceButton(byte[] bytes)
  160. {
  161. Debug.Log($"{PortName} 收到设备按键消息!");
  162. var check = bytes[1] + bytes[2] + bytes[3];//校验:命令+长度+数据内容
  163. if (check != bytes[4])
  164. {
  165. LOG("OnDeviceButton 数据校验错误!");
  166. }
  167. var clickType = bytes[3];//按键类型
  168. // 0x01 开机键 - 短按
  169. // 0x02 开机键 - 长按(1.5 秒)
  170. // 0x03 开机键 - 双击
  171. // 0x04 标定键 - 短按
  172. // 0x05 标定键 - 长按(1.5 秒)
  173. // 0x06 标定键 - 双击
  174. }
  175. #endregion
  176. }