PowerMeterReceiver.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using ANT_Managed_Library;
  4. using UnityEngine;
  5. namespace Sensors.ANT
  6. {
  7. /*
  8. Frequencies such as 4.06 Hz (ANT+ Heart
  9. Rate) and 4.005 Hz (ANT+ Bike Power) will
  10. periodically “drift” into each other, or into
  11. other channel periods that may be present
  12. in the vicinity. During this overlap, channel
  13. collisions may occur as the radio can only
  14. service channel at a time.
  15. */
  16. public struct PowermeterSensorData
  17. {
  18. public int InstantaneousPower; // the instantaneous power in watt
  19. public int InstantaneousCadence; // crank cadence in RPM if available ( 255 indicates invalid)
  20. public float CrankTorque;
  21. }
  22. public class PowerMeterReceiver
  23. {
  24. private AntChannel backgroundScanChannel;
  25. private AntChannel deviceChannel;
  26. private byte[] pageToSend;
  27. private PowermeterSensorData sensorData;
  28. public int DeviceID { get; } = 0;
  29. public bool Connected { get; private set; } = false;
  30. public List<AntDevice> ScanResult { get; private set; }
  31. public PowermeterSensorData SensorData => sensorData;
  32. public PowerMeterReceiver()
  33. {
  34. }
  35. public PowerMeterReceiver(int deviceID) => DeviceID = deviceID;
  36. public void StartScan()
  37. {
  38. Debug.Log("Looking for ANT + power meter sensor");
  39. AntManager.Instance.Init();
  40. ScanResult = new List<AntDevice>();
  41. backgroundScanChannel = AntManager.Instance.OpenBackgroundScanChannel(0);
  42. backgroundScanChannel.onReceiveData += ReceivedBackgroundScanData;
  43. }
  44. void ReceivedBackgroundScanData(Byte[] data)
  45. {
  46. byte deviceType = (data[12]); // extended info Device Type byte
  47. switch (deviceType)
  48. {
  49. case AntplusDeviceType.BikePower:
  50. {
  51. int deviceNumber = (data[10]) | data[11] << 8;
  52. byte transType = data[13];
  53. foreach (AntDevice d in ScanResult)
  54. {
  55. if (d.deviceNumber == deviceNumber && d.transType == transType) //device already found
  56. return;
  57. }
  58. AntDevice foundDevice = new AntDevice();
  59. foundDevice.deviceType = deviceType;
  60. foundDevice.deviceNumber = deviceNumber;
  61. foundDevice.transType = transType;
  62. foundDevice.period = 8182;
  63. foundDevice.radiofreq = 57;
  64. foundDevice.name = "Powermeter(" + foundDevice.deviceNumber + ")";
  65. ScanResult.Add(foundDevice);
  66. if (deviceNumber == DeviceID)
  67. {
  68. Debug.Log($"Desired Power Sensor with id {deviceNumber} found!");
  69. ConnectToDevice(foundDevice);
  70. }
  71. else
  72. {
  73. Debug.Log($"Power sensor ({deviceNumber}) found and added to ScanResult");
  74. }
  75. break;
  76. }
  77. }
  78. }
  79. void ConnectToDevice(AntDevice device)
  80. {
  81. AntManager.Instance.CloseBackgroundScanChannel();
  82. byte channelID = AntManager.Instance.GetFreeChannelID();
  83. deviceChannel = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00,
  84. channelID, (ushort) device.deviceNumber, device.deviceType, device.transType, (byte) device.radiofreq,
  85. (ushort) device.period, false);
  86. Connected = true;
  87. deviceChannel.onReceiveData += Data;
  88. deviceChannel.onChannelResponse += ChannelResponse;
  89. deviceChannel.hideRXFAIL = true;
  90. }
  91. private readonly Dictionary<int, int> updateEventCount = new Dictionary<int, int> {{0x10, 0}, {0x12, 0}};
  92. private readonly Dictionary<int, int> sameEventCounter = new Dictionary<int, int> {{0x10, 0}, {0x12, 0}};
  93. private int previousAccumulatedTorqueValue = 0;
  94. private int previousTorqueEventCount = 0;
  95. //Deal with the received Data
  96. private void Data(Byte[] data)
  97. {
  98. if (data[0] == 0x10) // Standard Power-Only Main Data Page
  99. {
  100. if (data[1] == updateEventCount[0x10])
  101. sameEventCounter[0x10]++;
  102. else
  103. sameEventCounter[0x10] = 0;
  104. updateEventCount[0x10] = data[1];
  105. if (sameEventCounter[0x10] > 3)
  106. {
  107. sensorData.InstantaneousPower = 0;
  108. sensorData.InstantaneousCadence = 0;
  109. }
  110. else
  111. {
  112. sensorData.InstantaneousPower = data[6] | data[7] << 8;
  113. sensorData.InstantaneousCadence = data[3];
  114. }
  115. }
  116. if (data[0] == 0x12) // Standard Crank Torque Main Data Page
  117. {
  118. Debug.Log($"Torque Data {data}");
  119. if (data[1] == updateEventCount[0x12])
  120. sameEventCounter[0x12]++;
  121. else
  122. sameEventCounter[0x12] = 0;
  123. updateEventCount[0x12] = data[1];
  124. if (sameEventCounter[0x12] > 3)
  125. {
  126. sensorData.CrankTorque = 0;
  127. }
  128. else
  129. {
  130. int accumulatedTorque = data[6] | data[7] << 8;
  131. float divisor = (32 * (updateEventCount[0x12] - previousTorqueEventCount));
  132. if (divisor > 0)
  133. {
  134. sensorData.CrankTorque = (accumulatedTorque - previousAccumulatedTorqueValue) / divisor;
  135. }
  136. previousAccumulatedTorqueValue = accumulatedTorque;
  137. previousTorqueEventCount = updateEventCount[0x12];
  138. }
  139. }
  140. }
  141. public void Calibrate()
  142. {
  143. Debug.Log("Sending : Manual Zero Calibration request");
  144. pageToSend = new byte[8] {0x01, 0xAA, 0x0FF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  145. deviceChannel.sendAcknowledgedData(pageToSend);
  146. }
  147. void ChannelResponse(ANT_Response response)
  148. {
  149. if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06)
  150. {
  151. deviceChannel.sendAcknowledgedData(pageToSend); //send the page again if the transfer failed
  152. }
  153. }
  154. }
  155. }