ArrowSerialPort.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. }
  43. private void OnDestroy()
  44. {
  45. if (_isInit.TryGetValue(gameObject.name, out var instanceID) && instanceID == GetInstanceID())
  46. {
  47. LOG($"{PortName} 串口关闭");
  48. serialPortUtility.Close();
  49. _isInit.Remove(gameObject.name);
  50. }
  51. }
  52. /// <summary>
  53. /// 串口读取二进制流数据(界面挂载调用)
  54. /// </summary>
  55. /// <param name="data"></param>
  56. public void ReadStreamingBinary(object data)
  57. {
  58. PhraseData(data as byte[]);
  59. }
  60. public void TestRead(byte[] bytes)
  61. {
  62. PhraseData(bytes);
  63. }
  64. /// <summary>
  65. /// 解析串口数据
  66. /// </summary>
  67. /// <param name="bytes"></param>
  68. private void PhraseData(byte[] bytes)
  69. {
  70. LOG($"{PortName} 收到串口信息!");
  71. if (bytes[0] == 0xAA)
  72. {
  73. var cmdID = bytes[1];
  74. switch (cmdID)
  75. {
  76. case 0x80://设备信息响应
  77. OnDeviceInfoBack(bytes);
  78. break;
  79. case 0x81://射击消息
  80. OnDeviceShoot(bytes);
  81. break;
  82. case 0x82://按键消息
  83. OnDeviceButton(bytes);
  84. break;
  85. }
  86. }
  87. }
  88. #region APP请求
  89. // 异或校验内容:命令+长度+数据内容
  90. /// <summary>
  91. /// app请求设备信息
  92. /// </summary>
  93. public void RequestDeviceIno()
  94. {
  95. List<byte> data = new List<byte>();
  96. data[0] = 0xAA;//起始码
  97. data[1] = 0x80;//命令号
  98. data[2] = 0x05;//长度
  99. data[3] = 0x85;//异或校验
  100. data[4] = 0x55;//结束码
  101. serialPortUtility.Write(data.ToArray());
  102. }
  103. #endregion
  104. #region 返回消息处理
  105. /// <summary>
  106. /// 设备信息响应
  107. /// </summary>
  108. private void OnDeviceInfoBack(byte[] bytes)
  109. {
  110. Debug.Log($"{PortName} 收到设备信息响应!");
  111. var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容
  112. if(check != bytes[5])
  113. {
  114. LOG("OnDeviceInfoBack 数据校验错误!");
  115. }
  116. //0x01 HOUYI Pro
  117. //0x02 ARTEMIS Pro
  118. //0x03 Pistol 1
  119. var deviceType = bytes[3];//设备类型
  120. //0x01 移动手机
  121. //0x02 PC电脑
  122. //0x03 VR设备
  123. var systemType = bytes[4];//系统类型
  124. }
  125. /// <summary>
  126. /// 射击消息
  127. /// </summary>
  128. private void OnDeviceShoot(byte[] bytes)
  129. {
  130. Debug.Log($"{PortName} 收到设备射击消息!");
  131. var check = bytes[1] + bytes[2] + bytes[3] + bytes[4];//校验:命令+长度+数据内容
  132. if (check != bytes[5])
  133. {
  134. LOG("OnDeviceShoot 数据校验错误!");
  135. }
  136. var time1 = bytes[3];
  137. var time2 = bytes[4];
  138. }
  139. /// <summary>
  140. /// 按键消息
  141. /// </summary>
  142. /// <param name="bytes"></param>
  143. private void OnDeviceButton(byte[] bytes)
  144. {
  145. Debug.Log($"{PortName} 收到设备按键消息!");
  146. var check = bytes[1] + bytes[2] + bytes[3];//校验:命令+长度+数据内容
  147. if (check != bytes[4])
  148. {
  149. LOG("OnDeviceButton 数据校验错误!");
  150. }
  151. var clickType = bytes[3];//按键类型
  152. // 0x01 开机键 - 短按
  153. // 0x02 开机键 - 长按(1.5 秒)
  154. // 0x03 开机键 - 双击
  155. // 0x04 标定键 - 短按
  156. // 0x05 标定键 - 长按(1.5 秒)
  157. // 0x06 标定键 - 双击
  158. }
  159. #endregion
  160. }