BluetoothShoot.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using ArduinoBluetoothAPI;
  6. using DG.Tweening;
  7. /* 蓝牙射击模块 */
  8. public class BluetoothShoot : MonoBehaviour
  9. {
  10. BluetoothHelper bluetoothHelper;
  11. BluetoothHelperCharacteristic characteristicWrite;
  12. BluetoothHelperService bluetoothService;
  13. string targetDeviceName = "BArrow_202105";
  14. string deviceName = "";
  15. bool canConnect = true;
  16. [SerializeField] Text textUI;
  17. public BluetoothStatusEnum status = BluetoothStatusEnum.Connect;
  18. public bool hasData = false;
  19. public static bool scanLock = false; //防止同时扫描冲突
  20. public static BluetoothShoot ins;
  21. void Start() {
  22. ins = this;
  23. BluetoothDispatcher.shoot = handleDataBytes;
  24. }
  25. void OnDestroy()
  26. {
  27. if (bluetoothHelper != null)
  28. {
  29. bluetoothHelper.Disconnect();
  30. }
  31. }
  32. private bool userDoConnect = false;
  33. private bool doConnect = false;
  34. public void DoConnect() {
  35. if (status == BluetoothStatusEnum.Connect) {
  36. userDoConnect = true;
  37. doConnect = true;
  38. SetStatus(BluetoothStatusEnum.Connecting);
  39. } else if (status == BluetoothStatusEnum.ConnectSuccess) {
  40. userDoConnect = false;
  41. doConnect = false;
  42. OnDisconnect();
  43. bluetoothHelper.Disconnect();
  44. }
  45. }
  46. void OnDisconnect() {
  47. hasData = false;
  48. canConnect = true;
  49. if (ShootCheck.ins) ShootCheck.ins.canAdjustNormalOrHightMode = false;
  50. SetStatus(BluetoothStatusEnum.ConnectFail);
  51. //清除射箭收集的数据
  52. dataGetting = false;
  53. dataBytes.Clear();
  54. }
  55. void Update()
  56. {
  57. if (userDoConnect && status == BluetoothStatusEnum.Connect) {
  58. DoConnect();
  59. }
  60. if (doConnect) Connect();
  61. }
  62. void SetStatus(BluetoothStatusEnum statusValue)
  63. {
  64. status = statusValue;
  65. if (status == BluetoothStatusEnum.ConnectFail) {
  66. status = BluetoothStatusEnum.ConnectFail;
  67. Sequence sequence = DOTween.Sequence();
  68. sequence.AppendInterval(2f);
  69. sequence.AppendCallback(delegate() {
  70. if (status == BluetoothStatusEnum.ConnectFail) {
  71. status = BluetoothStatusEnum.Connect;
  72. }
  73. });
  74. sequence.SetUpdate(true);
  75. }
  76. }
  77. void Connect()
  78. {
  79. if (BluetoothAim.scanLock)
  80. {
  81. return;
  82. }
  83. if (!canConnect)
  84. {
  85. return;
  86. }
  87. doConnect = false;
  88. scanLock = true;
  89. canConnect = false;
  90. SetStatus(BluetoothStatusEnum.Connecting);
  91. try
  92. {
  93. BluetoothHelper.BLE = true;
  94. bluetoothHelper = BluetoothHelper.GetNewInstance();
  95. bluetoothHelper.OnConnected += (BluetoothHelper helper) =>
  96. {
  97. Log("连接成功\n" + helper.getDeviceName());
  98. SetStatus(BluetoothStatusEnum.ConnectSuccess);
  99. foreach (BluetoothHelperService service in helper.getGattServices())
  100. {
  101. if (service.getName().ToLower().StartsWith("0000fff0"))
  102. {
  103. bluetoothService = service;
  104. foreach (BluetoothHelperCharacteristic characteristic in service.getCharacteristics())
  105. {
  106. if (characteristic.getName().ToLower().StartsWith("0000fff2"))
  107. {
  108. characteristicWrite = characteristic;
  109. }
  110. else if (characteristic.getName().ToLower().StartsWith("0000fff1"))
  111. {
  112. BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristic.getName());
  113. ch.setService(bluetoothService.getName());
  114. bluetoothHelper.Subscribe(ch);
  115. }
  116. }
  117. }
  118. }
  119. CallDelay(1, OpenReceiveData);
  120. };
  121. bluetoothHelper.OnConnectionFailed += (BluetoothHelper helper) =>
  122. {
  123. Log("连接失败\n" + helper.getDeviceName());
  124. OnDisconnect();
  125. };
  126. bluetoothHelper.OnCharacteristicChanged += (helper, value, characteristic) =>
  127. {
  128. hasData = true;
  129. byte[] bytes = value;
  130. // Log(String.Join(",", bytes));
  131. BluetoothClient.UploadData(1, bytes);
  132. handleDataBytes(bytes);
  133. };
  134. bluetoothHelper.OnScanEnded += (BluetoothHelper helper, LinkedList<BluetoothDevice> nearbyDevices) =>
  135. {
  136. scanLock = false;
  137. foreach (BluetoothDevice device in nearbyDevices)
  138. {
  139. if (device.DeviceName == targetDeviceName)
  140. {
  141. deviceName = device.DeviceName;
  142. bluetoothHelper.setDeviceName(deviceName);
  143. bluetoothHelper.Connect();
  144. Log("发现设备\n" + device.DeviceName);
  145. return;
  146. }
  147. }
  148. canConnect = true;
  149. Log("没有发现设备");
  150. SetStatus(BluetoothStatusEnum.ConnectFail);
  151. };
  152. bluetoothHelper.ScanNearbyDevices();
  153. Log("正在扫描设备");
  154. }
  155. catch (Exception e)
  156. {
  157. Debug.Log(e.Message);
  158. canConnect = true;
  159. Log("请打开蓝牙");
  160. }
  161. }
  162. void OpenReceiveData()
  163. {
  164. WriteData("5");
  165. CallDelay(1, delegate() {
  166. if (ShootCheck.ins)
  167. {
  168. ShootCheck.ins.OnBluetoothReady(this);
  169. Log("射击模块准备完成\n" + deviceName);
  170. }
  171. });
  172. CallDelay(2.5f, delegate() {
  173. WriteData("B");
  174. });
  175. }
  176. void CallDelay(float delayTime, TweenCallback callback)
  177. {
  178. Sequence sequence = DOTween.Sequence();
  179. sequence.PrependInterval(delayTime).AppendCallback(callback);
  180. sequence.SetUpdate(true);
  181. }
  182. public void WriteData(string data)
  183. {
  184. BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristicWrite.getName());
  185. ch.setService(bluetoothService.getName());
  186. bluetoothHelper.WriteCharacteristic(ch, data);
  187. }
  188. void Log(string text)
  189. {
  190. if (textUI)
  191. {
  192. textUI.text = text;
  193. }
  194. }
  195. //---收集射箭轴加速度---
  196. bool dataGetting = false;
  197. int dataGetLen = 0;
  198. List<byte> dataBytes = new List<byte>();
  199. int TwoByteToInt(byte b1, byte b2)
  200. {
  201. ushort twoByte = (ushort) (b1 * 256 + b2);
  202. short shortNum = (short) twoByte;
  203. return (int) shortNum;
  204. }
  205. void cacheDataBytes(byte[] bytes, int startIndex) {
  206. for (int i = startIndex; i < bytes.Length; i++) {
  207. byte b = bytes[i];
  208. if (dataBytes.Count < dataGetLen) {
  209. dataBytes.Add(b);
  210. } else {
  211. if (ShootCheck.ins) ShootCheck.ins.OnDataReceived(dataBytes.ToArray());
  212. dataGetting = false;
  213. dataBytes.Clear();
  214. break;
  215. }
  216. }
  217. }
  218. public void handleDataBytes(byte[] bytes) {
  219. if (dataGetting) {
  220. cacheDataBytes(bytes, 0);
  221. } else {
  222. if (bytes.Length >= 5) {
  223. int byte3Value = 0; //轴数据识别,1:x轴,2:y轴,3:z轴
  224. if (ShootCheck.ins) {
  225. CMD cmd = ShootCheck.ins.cmd;
  226. if (cmd.a == "x") byte3Value = 1;
  227. if (cmd.a == "y") byte3Value = 2;
  228. if (cmd.a == "z") byte3Value = 3;
  229. }
  230. if (bytes[0] == 255 || bytes[1] == 255 && bytes[2] == byte3Value) {
  231. dataGetting = true;
  232. dataGetLen = TwoByteToInt(bytes[3], bytes[4]);
  233. cacheDataBytes(bytes, 5);
  234. }
  235. } else if (bytes.Length == 2) {
  236. DeviceBatteryView.ins.RenderBattery(2, bytes[0]);
  237. }
  238. }
  239. }
  240. }