AntManager.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using System;
  4. using System.Collections;
  5. using ANT_Managed_Library;
  6. using System.Text;
  7. using System.Collections.Generic;
  8. /*
  9. * AntManager
  10. *
  11. * Call the Init method from your script and then open a channel.
  12. * Ant responses and received DATA are queued when received
  13. * and dequeued in the update loop by triggering events you can register on your script
  14. */
  15. public class SerialError {
  16. public ANT_Device sender;
  17. public ANT_Device.serialErrorCode error;
  18. public bool isCritical;
  19. public SerialError(ANT_Device sender, ANT_Device.serialErrorCode error, bool isCritical) {
  20. this.sender = sender;
  21. this.error = error;
  22. this.isCritical = isCritical;
  23. }
  24. }
  25. public class AntManager : MonoBehaviour {
  26. static AntManager _instance;
  27. public static int lastChannel = 0;
  28. public static AntManager Instance {
  29. get {
  30. if (_instance == null)
  31. return _instance = (new GameObject("AntManager")).AddComponent<AntManager>();
  32. else
  33. return _instance;
  34. }
  35. }
  36. readonly byte[] NETWORK_KEY = { 0xB9, 0xA5, 0x21, 0xFB, 0xBD, 0x72, 0xC3, 0x45 }; // <- key is set
  37. //readonly byte[] NETWORK_KEY = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // COPY THE CORRECT NETWORK KEY HERE
  38. /*
  39. * To obtain the network key:
  40. * register on https://www.thisisant.com/register/
  41. * Once your basic user account is activated, login and go to your MyANT+ page https://www.thisisant.com/my-ant to add ANT+ Adopter,
  42. * search "Network Keys" on thisisant.com, we want the first key on the txt
  43. */
  44. public ANT_Device device {
  45. get {
  46. return devices[0];
  47. }
  48. }
  49. public ANT_Device[] devices = new ANT_Device[8]; //if you need more than 8 usb devices, change this
  50. Queue<ANT_Response> messageQueue;
  51. public delegate void OnDeviceResponse(ANT_Response response);
  52. public event OnDeviceResponse onDeviceResponse; //ant response event
  53. public delegate void OnSerialError(SerialError error);
  54. public event OnSerialError onSerialError;
  55. Queue<SerialError> errorQueue;
  56. public List<AntChannel> channelList;
  57. public bool[,] channelIDUsed = new bool[8, 8];
  58. private AntChannel backgroundScanChannel;
  59. private int nScanRequest = 0;
  60. void Awake() {
  61. // Sets this to not be destroyed when reloading scene
  62. if (NETWORK_KEY[0] == 0x00) {
  63. Debug.LogWarning("NETWORK_KEY NOT SET IN ANTMANAGER.CS ! INSTRUCTIONS IN PC_MAC_readme.txt");
  64. }
  65. DontDestroyOnLoad(gameObject);
  66. }
  67. void Update() {
  68. if (messageQueue != null && messageQueue.Count > 0) {
  69. if (onDeviceResponse != null)
  70. onDeviceResponse(messageQueue.Dequeue());
  71. }
  72. if (onSerialError != null && errorQueue.Count > 0)
  73. onSerialError(errorQueue.Dequeue());
  74. }
  75. public void Init(byte USBDeviceNum = 0) {
  76. if (ANT_Common.getNumDetectedUSBDevices() < USBDeviceNum) {
  77. Debug.Log("ANT+ cannot detect USB device #" + USBDeviceNum);
  78. return;
  79. }
  80. // if (deviceList == null)
  81. // deviceList = new List<ANT_Device>();
  82. if (messageQueue == null)
  83. messageQueue = new Queue<ANT_Response>(16);
  84. if (errorQueue == null)
  85. errorQueue = new Queue<SerialError>(16);
  86. if (channelList == null)
  87. channelList = new List<AntChannel>();
  88. //init the device
  89. if (devices[USBDeviceNum] == null) {
  90. devices[USBDeviceNum] = new ANT_Device(USBDeviceNum, 57000);
  91. devices[USBDeviceNum].deviceResponse += new ANT_Device.dDeviceResponseHandler(DeviceResponse);
  92. devices[USBDeviceNum].serialError += new ANT_Device.dSerialErrorHandler(SerialErrorHandler);
  93. devices[USBDeviceNum].ResetSystem();
  94. devices[USBDeviceNum].setNetworkKey(0, NETWORK_KEY, 500);
  95. }
  96. }
  97. public void Reconnect(ANT_Device previousDevice) {
  98. int usbNum = previousDevice.getOpenedUSBDeviceNum();
  99. devices[usbNum] = previousDevice;
  100. previousDevice.deviceResponse += new ANT_Device.dDeviceResponseHandler(DeviceResponse);
  101. previousDevice.serialError += new ANT_Device.dSerialErrorHandler(SerialErrorHandler);
  102. previousDevice.ResetSystem();
  103. previousDevice.setNetworkKey(0, NETWORK_KEY, 500);
  104. }
  105. public AntChannel OpenChannel(ANT_ReferenceLibrary.ChannelType channelType, byte userChannel, ushort deviceNum, byte deviceType, byte transType, byte radioFreq, ushort channelPeriod, bool pairing, int USBNum = 0) {
  106. AntChannel channel = this.gameObject.AddComponent<AntChannel>();
  107. channelList.Add(channel);
  108. channelIDUsed[USBNum, userChannel] = true;
  109. channel.ConfigureAnt(channelType, userChannel, deviceNum, deviceType, transType, radioFreq, channelPeriod, pairing, USBNum);
  110. return channel;
  111. }
  112. public AntChannel OpenBackgroundScanChannel(byte userChannel, byte USBDeviceNum = 0) {
  113. nScanRequest++;
  114. if (backgroundScanChannel) //if a background Scan channel already exist
  115. return backgroundScanChannel;
  116. channelIDUsed[USBDeviceNum, userChannel] = true;
  117. backgroundScanChannel = this.gameObject.AddComponent<AntChannel>();
  118. channelList.Add(backgroundScanChannel);
  119. backgroundScanChannel.ConfigureScan(userChannel, USBDeviceNum);
  120. return backgroundScanChannel;
  121. }
  122. public AntChannel OpenContinuousScanChannel(byte radioFreq, byte USBDeviceNum = 0) {
  123. AntChannel channel = this.gameObject.AddComponent<AntChannel>();
  124. channel.ConfigureContinuousScan(0x00, radioFreq, USBDeviceNum);
  125. return channel;
  126. }
  127. public void CloseBackgroundScanChannel() {
  128. Invoke("CloseBackgroundScan", 1);
  129. }
  130. void CloseBackgroundScan() {
  131. nScanRequest--;
  132. if (nScanRequest == 0) {
  133. backgroundScanChannel.Close();
  134. backgroundScanChannel = null;
  135. Debug.Log("all devices connected, closing background scan channel");
  136. }
  137. }
  138. public byte GetFreeChannelID(int USBNum = 0) {
  139. for (int id = 1; id <= 8; id++) {
  140. if (channelIDUsed[USBNum, id] == false)
  141. return (byte)id;
  142. }
  143. Debug.LogWarning("no free ANT + channel available!");
  144. return 0;
  145. }
  146. /*
  147. * DeviceResponse
  148. * Called whenever a message is received from ANT unless that message is a
  149. * channel event message.
  150. * response: ANT message
  151. */
  152. void DeviceResponse(ANT_Response response) {
  153. if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
  154. messageQueue.Enqueue(response);
  155. }
  156. void SerialErrorHandler(ANT_Device sender, ANT_Device.serialErrorCode error, bool isCritical) {
  157. if (onSerialError != null) {
  158. SerialError serialError = new SerialError(sender, error, isCritical);
  159. errorQueue.Enqueue(serialError);
  160. }
  161. }
  162. void OnApplicationQuit() {
  163. //dispose the device on app quit or the application will freeze
  164. foreach (ANT_Device device in devices) {
  165. if (device != null)
  166. device.Dispose();
  167. }
  168. }
  169. }