AntDemo.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.UI;
  4. using ANT_Managed_Library;
  5. using System.Collections.Generic;
  6. using System;
  7. public class AntDemo : MonoBehaviour
  8. {
  9. //output ant responses and data to unity UI text
  10. public Text dataDisplay;
  11. List<string> logDisplay;
  12. AntChannel hrChannel;
  13. AntChannel speedChannel;
  14. AntChannel backgroundScanChannel;
  15. //variable use for speed display
  16. int prevRev;
  17. int prevMeasTime = 0;
  18. //fake HRM beat
  19. byte hbCount = 0;
  20. void Start()
  21. {
  22. logDisplay = new List<string>();
  23. dataDisplay.text = "";
  24. //EncodeFitFile(); //the FIT library is included to encode and decode FIT files
  25. }
  26. void init_Device()
  27. {
  28. if (AntManager.Instance.device == null)
  29. {
  30. AntManager.Instance.Init();
  31. AntManager.Instance.onDeviceResponse += OnDeviceResponse;
  32. AntManager.Instance.onSerialError += OnSerialError; //if usb dongle is unplugged for example
  33. }
  34. }
  35. public void Onclick_Init_HRSensor()
  36. {
  37. init_Device();
  38. //call the ConfigureAnt method for a master channel with the correct ANT speed display settings
  39. //found in ANT_Device_Profile_Heart_Rate_Monitor.pdf on thisisant.com
  40. //using channel 1
  41. hrChannel = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Master_Transmit_0x10, 1, 255, 120, 0, 57, 8070, false); //hr sensor
  42. hrChannel.onChannelResponse += OnChannelResponse;
  43. InvokeRepeating("HRMTransmit", 1, 1 / 4f); // let's fake a HRM by updating a HR beat every 1/4 second
  44. }
  45. public void Onclick_Init_SpeedDisplay()
  46. {
  47. init_Device();
  48. //call the ConfigureAnt method for a slave channel with the correct ANT speed display settings
  49. //found in ANT+_Device_Profile_-_Bicycle_Speed_and_Cadence_2.0.pdf on thisisant.com
  50. //using channel 2
  51. //note: collision is a normal behaviour searching for a master.
  52. speedChannel = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 2, 0, 123, 0, 57, 8118, false); //bike speed Display
  53. speedChannel.onChannelResponse += OnChannelResponse;
  54. speedChannel.onReceiveData += ReceivedSpeedAntData;
  55. }
  56. public void Onclick_Start_BackgroundScan()
  57. {
  58. init_Device();
  59. backgroundScanChannel = AntManager.Instance.OpenBackgroundScanChannel(0);
  60. backgroundScanChannel.onReceiveData += ReceivedBackgroundScanData;
  61. backgroundScanChannel.onChannelResponse += OnChannelResponse;
  62. }
  63. public void Onclick_Close()
  64. {
  65. if (hrChannel)
  66. {
  67. hrChannel.onChannelResponse -= OnChannelResponse;
  68. hrChannel.Close();
  69. CancelInvoke("HRMTransmit");
  70. hrChannel = null;
  71. }
  72. if (speedChannel)
  73. {
  74. speedChannel.onReceiveData -= ReceivedSpeedAntData;
  75. speedChannel.Close();
  76. speedChannel = null;
  77. }
  78. if (backgroundScanChannel)
  79. {
  80. backgroundScanChannel.onReceiveData -= ReceivedBackgroundScanData;
  81. backgroundScanChannel.onChannelResponse -= OnChannelResponse;
  82. backgroundScanChannel.Close();
  83. backgroundScanChannel = null;
  84. }
  85. StopCoroutine("Reconnect");
  86. }
  87. void OnDeviceResponse(ANT_Response response)
  88. {
  89. DisplayText("device:" + response.getMessageID().ToString());
  90. }
  91. void OnSerialError(SerialError serialError)
  92. {
  93. DisplayText("Error:" + serialError.error.ToString());
  94. //attempt to auto reconnect if the USB was unplugged
  95. if (serialError.error == ANT_Device.serialErrorCode.DeviceConnectionLost)
  96. {
  97. foreach (AntChannel channel in AntManager.Instance.channelList)
  98. channel.PauseChannel();
  99. StartCoroutine("Reconnect", serialError.sender.getSerialNumber());
  100. }
  101. }
  102. IEnumerator Reconnect(uint serial)
  103. {
  104. Debug.Log("looking for usb device " + serial.ToString());
  105. // polling to try and find the USB device
  106. while (true)
  107. {
  108. if (ANT_Common.getNumDetectedUSBDevices() > 0)
  109. {
  110. ANT_Device device = new ANT_Device();
  111. if (device.getSerialNumber() == serial)
  112. {
  113. Debug.Log("usb found!");
  114. AntManager.Instance.Reconnect(device);
  115. foreach (AntChannel channel in AntManager.Instance.channelList)
  116. channel.ReOpen();
  117. yield break;
  118. }
  119. else
  120. device.Dispose();
  121. }
  122. yield return new WaitForSeconds(0.1f);
  123. }
  124. }
  125. void OnChannelResponse(ANT_Response response)
  126. {
  127. if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02)
  128. DisplayText("channel " + response.antChannel.ToString() + " " + "RX fail");
  129. else if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08)
  130. DisplayText("channel " + response.antChannel.ToString() + " " + "Go to search");
  131. else if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03)
  132. DisplayText("channel " + response.antChannel.ToString() + " " + "Tx: (" + response.antChannel.ToString() + ")" + BitConverter.ToString(hrChannel.txBuffer));
  133. else
  134. DisplayText("channel " + response.antChannel.ToString() + " " + response.getChannelEventCode());
  135. }
  136. void HRMTransmit()
  137. {
  138. hbCount++;
  139. //super simple HRM
  140. hrChannel.txBuffer[0] = 0;
  141. hrChannel.txBuffer[1] = 0;
  142. hrChannel.txBuffer[2] = 0;
  143. hrChannel.txBuffer[3] = 0;
  144. hrChannel.txBuffer[4] = 0;
  145. hrChannel.txBuffer[5] = 0;
  146. hrChannel.txBuffer[6] = hbCount;
  147. hrChannel.txBuffer[7] = (byte)UnityEngine.Random.Range(90, 100);
  148. }
  149. void ReceivedSpeedAntData(Byte[] data)
  150. {
  151. //output the data to our log window
  152. string dataString = "RX: ";
  153. foreach (byte b in data)
  154. dataString += b.ToString("X") + " ";
  155. DisplayText(dataString);
  156. //speed formula as described in the ant+ device profile doc
  157. int currentRevCount = (data[6]) | data[7] << 8;
  158. if (currentRevCount != prevRev && prevRev > 0)
  159. {
  160. int currentMeasTime = (data[4]) | data[5] << 8;
  161. float speed = (2.070f * (currentRevCount - prevRev) * 1024) / (currentMeasTime - prevMeasTime);
  162. speed *= 3.6f;
  163. prevMeasTime = currentMeasTime;
  164. DisplayText("speed: " + speed.ToString("F2") + "km/h");
  165. }
  166. prevRev = currentRevCount;
  167. }
  168. void ReceivedBackgroundScanData(Byte[] data)
  169. {
  170. byte deviceType = (data[12]); // extended info Device Type byte
  171. //use the Extended Message Formats to identify nodes
  172. Debug.Log("scan found ID : "+ ((data[10]) | data[11] << 8)+ "of TYPE: "+ deviceType);
  173. switch (deviceType)
  174. {
  175. case AntplusDeviceType.Antfs:
  176. {
  177. DisplayText("Scan Found Antfs");
  178. break;
  179. }
  180. case AntplusDeviceType.BikePower:
  181. {
  182. DisplayText("Scan Found BikePower");
  183. break;
  184. }
  185. case AntplusDeviceType.EnvironmentSensorLegacy:
  186. {
  187. DisplayText("Scan Found EnvironmentSensorLegacy");
  188. break;
  189. }
  190. case AntplusDeviceType.MultiSportSpeedDistance:
  191. {
  192. DisplayText("Scan Found MultiSportSpeedDistance");
  193. break;
  194. }
  195. case AntplusDeviceType.Control:
  196. {
  197. DisplayText("Scan Found Control");
  198. break;
  199. }
  200. case AntplusDeviceType.FitnessEquipment:
  201. {
  202. DisplayText("Scan Found FitnessEquipment");
  203. break;
  204. }
  205. case AntplusDeviceType.BloodPressure:
  206. {
  207. DisplayText("Scan Found BloodPressure");
  208. break;
  209. }
  210. case AntplusDeviceType.GeocacheNode:
  211. {
  212. DisplayText("Scan Found GeocacheNode");
  213. break;
  214. }
  215. case AntplusDeviceType.LightElectricVehicle:
  216. {
  217. DisplayText("Scan Found LightElectricVehicle");
  218. break;
  219. }
  220. case AntplusDeviceType.EnvSensor:
  221. {
  222. DisplayText("Scan Found EnvSensor");
  223. break;
  224. }
  225. case AntplusDeviceType.Racquet:
  226. {
  227. DisplayText("Scan Found Racquet");
  228. break;
  229. }
  230. case AntplusDeviceType.ControlHub:
  231. {
  232. DisplayText("Scan Found ControlHub");
  233. break;
  234. }
  235. case AntplusDeviceType.MuscleOxygen:
  236. {
  237. DisplayText("Scan Found MuscleOxygen");
  238. break;
  239. }
  240. case AntplusDeviceType.BikeLightMain:
  241. {
  242. DisplayText("Scan Found BikeLightMain");
  243. break;
  244. }
  245. case AntplusDeviceType.BikeLightShared:
  246. {
  247. DisplayText("Scan Found BikeLightShared");
  248. break;
  249. }
  250. case AntplusDeviceType.BikeRadar:
  251. {
  252. DisplayText("Scan Found BikeRadar");
  253. break;
  254. }
  255. case AntplusDeviceType.WeightScale:
  256. {
  257. DisplayText("Scan Found WeightScale");
  258. break;
  259. }
  260. case AntplusDeviceType.HeartRate:
  261. {
  262. DisplayText("Scan Found HeartRate");
  263. break;
  264. }
  265. case AntplusDeviceType.BikeSpeedCadence:
  266. {
  267. DisplayText("Scan Found BikeSpeedCadence");
  268. break;
  269. }
  270. case AntplusDeviceType.BikeCadence:
  271. {
  272. DisplayText("Scan Found BikeCadence");
  273. break;
  274. }
  275. case AntplusDeviceType.BikeSpeed:
  276. {
  277. DisplayText("Scan Found BikeSpeed");
  278. break;
  279. }
  280. case AntplusDeviceType.StrideSpeedDistance:
  281. {
  282. DisplayText("Scan Found StrideSpeedDistance");
  283. break;
  284. }
  285. default:
  286. {
  287. DisplayText("Scan Found Found Unknown device");
  288. break;
  289. }
  290. }
  291. }
  292. //Display content of the string list to the UI text
  293. void DisplayText(string s)
  294. {
  295. dataDisplay.text = "";
  296. logDisplay.Add(s + "\n");
  297. if (logDisplay.Count > 13)
  298. logDisplay.RemoveAt(0);
  299. foreach (string log in logDisplay)
  300. dataDisplay.text += log;
  301. }
  302. }