protected void onChannelResponse(ANT_Response response) { try { if (response.isExtended()) // Check if we are dealing with an extended message { ANT_ChannelID chID = response.getDeviceIDfromExt(); // Channel ID of the device we just received a message from DeviceNumber = (ushort)chID.deviceNumber; } Parse(response.getDataPayload()); } catch { } }
protected override void handleNonRxFailChannelResponse(ANT_Managed_Library.ANT_Response response) { if (response.responseID == (byte)ANT_Managed_Library.ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E) { switch (response.messageContents[1]) { case 16: //Page 16 - General Page { //Get new values byte curElapsedTimeAcc = response.messageContents[3]; byte curDistAcc = response.messageContents[4]; ushort curInstSpeed = (ushort)(response.messageContents[5] + ((ushort)response.messageContents[6] << 8)); //heartRate = response.messageContents[7], //If we aren't initialized we can't do the calculations yet and we just save the values below if (isInitialized) { //Get the distance increase out of the accumulated field int distIncrease = curDistAcc - lastDistAcc; if (distIncrease < 0) { distIncrease = 255 + distIncrease; } if (distIncrease == 0) //Some devices like the rower don't reset the speed value when the rowing stops { if (++idleCount >= MAX_NO_EVENT_STOP_COUNT) //depending on page setup of machine, this is at least 1.5s, max 3s { curInstSpeed = 0; idleCount = MAX_NO_EVENT_STOP_COUNT; //Always set, so we don't rollover } } else { idleCount = 0; } //System.Console.Out.WriteLine(feDataSource.type + ", " + curData.distAcc + ", " + distIncrease); //TODO: qc Keep checking if this is the same device as original connection? //if((FitEquipType)(response.messageContents[2] & 0x1F) != feDataSource.type) if (curInstSpeed == 0xFFFF) //If instantaneous speed is invalid, we have to manually calculate it { //Average speed over last 16 msgs //System.Console.Write(String.Format("Pre Speed = {0}, ", calcSpeed)); double calcTimeDiff = curElapsedTimeAcc - lastElapsedTimeAcc; if (calcTimeDiff > 0) //If there is no time diff, it is probably because the broadcast data wasn't updated, so don't try and predict speed from it { calcSpeed = (calcSpeed * 7 / 8); calcSpeed += (((double)distIncrease * 4) / calcTimeDiff) / 8; //Add the fractional contributed by this msg. Time is in 0.25s units, so multiply dist by 4 } incrementDistanceAndUpdate(distIncrease, calcSpeed, lastInstCadence, powerW: lastInstPower); } else { incrementDistanceAndUpdate(distIncrease, ((double)curInstSpeed) / 1000, lastInstCadence, powerW: lastInstPower); } } else //When we are initializing we determine the sport type { switch (response.messageContents[2] & 0x1F) { case 19: //Treadmill sportType = racerSportType.Running; break; case 22: //Rower sportType = racerSportType.Rowing; break; case 21: //Biking sportType = racerSportType.Biking; break; case 20: //Elliptical sportType = racerSportType.Running; break; case 23: //Climber sportType = racerSportType.Running; break; case 24: //Nordic Ski machine sportType = racerSportType.Skiing; break; default: sportType = racerSportType.Unknown; break; } isInitialized = true; } //Save for next time lastElapsedTimeAcc = curElapsedTimeAcc; lastDistAcc = curDistAcc; } break; //case 17: //general settings Page, not on bike, shows on rower, but not very useful // { // System.Console.Out.WriteLine("Cycle Length:" + response.messageContents[4] + ",Incline:" + (response.messageContents[5] + (response.messageContents[5] << 8)) + ",Resist:" + response.messageContents[7]); // } // break; //case 18: //metabolic data, doesn't show on rower or bike // { // System.Console.Out.WriteLine("BurnRate:" + (response.messageContents[5] + (response.messageContents[6] << 8)) + ",Cal:" + response.messageContents[7]); // } // break; case 19: //treadmill data { lastInstCadence = response.messageContents[5]; } break; case 21: //bike data case 22: //Row data, same format as bike for cad and power case 20: //Elliptical, same format as bike for cad and power case 24: //Nordic Skier, same format as bike for cad and power { lastInstCadence = response.messageContents[5]; lastInstPower = (ushort)(response.messageContents[6] + (response.messageContents[7] << 8)); //System.Console.Out.WriteLine("Cadence:" + response.messageContents[5] + ",Power:" + (response.messageContents[6] + (response.messageContents[7] << 8))); //System.Console.Out.WriteLine("SPM:"+response.messageContents[5]+"Power:"+(response.messageContents[6] + (response.messageContents[7] << 8))); } break; } } }
//////////////////////////////////////////////////////////////////////////////// // DeviceResponse // // Called whenever a message is received from ANT unless that message is a // channel event message. // // response: ANT message //////////////////////////////////////////////////////////////////////////////// protected void DeviceResponse(ANT_Response response) { switch ((ANT_ReferenceLibrary.ANTMessageID) response.responseID) { case ANT_ReferenceLibrary.ANTMessageID.STARTUP_MESG_0x6F: { Console.Write("RESET Complete, reason: "); byte ucReason = response.messageContents[0]; if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_POR_0x00) Console.WriteLine("RESET_POR"); if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_RST_0x01) Console.WriteLine("RESET_RST"); if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_WDT_0x02) Console.WriteLine("RESET_WDT"); if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_CMD_0x20) Console.WriteLine("RESET_CMD"); if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_SYNC_0x40) Console.WriteLine("RESET_SYNC"); if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_SUSPEND_0x80) Console.WriteLine("RESET_SUSPEND"); break; } case ANT_ReferenceLibrary.ANTMessageID.VERSION_0x3E: { Console.WriteLine("VERSION: " + new ASCIIEncoding().GetString(response.messageContents)); break; } case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40: { switch (response.getMessageID()) { case ANT_ReferenceLibrary.ANTMessageID.CLOSE_CHANNEL_0x4C: { if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.CHANNEL_IN_WRONG_STATE_0x15) { foreach (SensorProcessor s in _SensorProcessors) { s.UnassignChannel(); } } break; } case ANT_ReferenceLibrary.ANTMessageID.NETWORK_KEY_0x46: case ANT_ReferenceLibrary.ANTMessageID.ASSIGN_CHANNEL_0x42: case ANT_ReferenceLibrary.ANTMessageID.CHANNEL_ID_0x51: case ANT_ReferenceLibrary.ANTMessageID.CHANNEL_RADIO_FREQ_0x45: case ANT_ReferenceLibrary.ANTMessageID.OPEN_CHANNEL_0x4B: case ANT_ReferenceLibrary.ANTMessageID.UNASSIGN_CHANNEL_0x41: { if (response.getChannelEventCode() != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00) { Console.WriteLine(String.Format("Error {0} configuring {1}", response.getChannelEventCode(), response.getMessageID())); } break; } case ANT_ReferenceLibrary.ANTMessageID.RX_EXT_MESGS_ENABLE_0x66: { if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.INVALID_MESSAGE_0x28) { Console.WriteLine("Extended messages not supported in this ANT product"); break; } else if(response.getChannelEventCode() != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00) { Console.WriteLine(String.Format("Error {0} configuring {1}", response.getChannelEventCode(), response.getMessageID())); break; } Console.WriteLine("Extended messages enabled"); break; } case ANT_ReferenceLibrary.ANTMessageID.REQUEST_0x4D: { if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.INVALID_MESSAGE_0x28) { Console.WriteLine("Requested message not supported in this ANT product"); break; } break; } default: { Console.WriteLine("Unhandled response " + response.getChannelEventCode() + " to message " + response.getMessageID()); break; } } break; } } }
/// <overloads>Requests a message from the device and returns the response</overloads> /// <summary> /// Request a message from device and returns the response. /// Throws exception on timeout. /// </summary> /// <param name="channelNum">Channel to send request on</param> /// <param name="messageID">Request to send</param> /// <param name="responseWaitTime">Time to wait for device success response</param> public ANT_Response requestMessageAndResponse(byte channelNum, ANT_ReferenceLibrary.RequestMessageID messageID, UInt32 responseWaitTime) { if (!initializedUSB) throw new ObjectDisposedException("ANTDevice object has been disposed"); ANTMessageItem response = new ANTMessageItem(); if (ANT_RequestMessage(unmanagedANTFramerPtr, channelNum, (byte)messageID, ref response, responseWaitTime) == 0) throw new ANT_Exception("Timed out waiting for requested message"); ANT_Response retVal = new ANT_Response(this, channelNum, DateTime.Now, response.antMsgData.msgID, response.antMsgData.ucharBuf.Take(response.dataSize).ToArray()); return retVal; }
private void responsePollFunc() { ushort messageSize = 0; byte channelNum; bool isMsgForChannel; pollingOn = true; //Set to false on shutdown to terminate the thread #if (ANTFS_DEBUGGING) ANT_Common.initDebugLogThread("Device" + USBDeviceNum + "_ANTReceive"); // We still need this for ANT-FS! Will not be created if debug disabled #endif while (initializedUSB && pollingOn) //check continuously; this thread is terminated on destruction of the class { // We only wait in the unmanged code for 100 ms because we want this thread to be responsive on our side. // It does mean that we are running through a lot more cycles than we need to messageSize = ANT_WaitForMessage(unmanagedANTFramerPtr, 100); if (messageSize == (ushort)0xFFFE) //DSI_FRAMER_TIMEDOUT continue; //Expected, just keep looping ANTMessage newMessage = new ANTMessage(); messageSize = ANT_GetMessage(unmanagedANTFramerPtr, ref newMessage); if (messageSize == (ushort)0xFFFF) // DSI_FRAMER_ERROR - in current library could be from CRC error, Write error, Read error, or DeviceGone { serialErrorCode error; bool isCritical = false; switch(newMessage.msgID) { case 0x02: //DSI_FRAMER_ANT_ESERIAL switch(newMessage.ucharBuf[0]) { case 0x04: //ESERIAL -> DSI_FRAMER_ANT_CRC_ERROR error = serialErrorCode.MessageLost_CrcError; break; case 0x02: //ESERIAL -> DSI_SERIAL_EWRITE error = serialErrorCode.SerialWriteError; break; case 0x03: //ESERIAL -> DSI_SERIAL_EREAD error = serialErrorCode.SerialReadError; isCritical = true; break; case 0x01: //ESERIAL -> DSI_SERIAL_DEVICE_GONE error = serialErrorCode.DeviceConnectionLost; isCritical = true; break; default: error = serialErrorCode.Unknown; System.Diagnostics.Debug.Fail("Unknown serial failure, why isn't this known?"); break; } break; case 0x01: //DSI_FRAMER_ANT_EQUEUE_OVERFLOW error = serialErrorCode.MessageLost_QueueOverflow; break; case 0x03: //DSI_FRAMER_ANT_EINVALID_SIZE error = serialErrorCode.MessageLost_TooLarge; break; default: error = serialErrorCode.Unknown; System.Diagnostics.Debug.Fail("Unknown serial failure, why isn't this known?"); break; } if(isCritical) { //System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(x => shutdown())); //Clean up all resources on another thread to allow this one to close cleanly pollingOn = false; //Just stop polling, since we will never get new messages now. Allow the user to dispose of the device. } //If application has subscribed to the event we can inform them if (serialError != null) serialError(this, error, isCritical); else //Debug.Fail is a no-op in release mode, so we will only see this in debugging, in release mode we don't want to do anything intrusive (ie:message box, exception) System.Diagnostics.Debug.Fail("Device Serial Communication Failure, HandleSerialError not handled by application"); if (isCritical) break; //If the device is dead, exit the polling loop else continue; } isMsgForChannel = false; channelNum = Byte.MaxValue; switch (newMessage.msgID) //Check if we send to channel or protocol response func { // Send on Channel event case (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40: if (newMessage.ucharBuf[1] == (byte)ANT_ReferenceLibrary.ANTMessageID.EVENT_0x01) isMsgForChannel = true; break; // or any of the transmission events case (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E: case (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F: case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D: case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E: case (byte)ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50: case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F: #if (!REFERENCE_DESIGN) case (byte)ANT_ReferenceLibrary.ANTMessageID.ADV_BURST_DATA_0x72: #endif case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_BROADCAST_DATA_0xC1: case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_ACKNOWLEDGED_DATA_0xC2: case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_BURST_DATA_0xC3: isMsgForChannel = true; break; } ANT_Response newResponse; //Now dispatch to appropriate event //The messages are buffered in the ant library so we just dispatch with current thread //then no matter how long the event call takes we still won't miss messages if (isMsgForChannel) { channelNum = (byte)(newMessage.ucharBuf[0] & 0x1F); //Mask out what channel this is for. [We can eventually switch to use the c++ code to determine the channel, but we should do it all together with getMessage to avoid extra marshalling and copying and remove the processing in C# above] if (antChannels != null && channelNum < antChannels.Length) { if (antChannels[channelNum] != null) antChannels[channelNum].MessageReceived(newMessage, messageSize); } else { if (serialError != null) serialError(this, serialErrorCode.MessageLost_InvalidChannel, false); } } else { newResponse = new ANT_Response(this, newMessage.ucharBuf[0], DateTime.Now, newMessage.msgID, newMessage.ucharBuf.Take(messageSize).ToArray()); if (deviceResponse != null) //Ensure events are assigned before we call the event deviceResponse(newResponse); } } }
//////////////////////////////////////////////////////////////////////////////// // ChannelResponse // // Called whenever a channel event is recieved. // // response: ANT message //////////////////////////////////////////////////////////////////////////////// private void ChannelResponse(ANT_Response response) { try { switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID) { case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40: { switch (response.getChannelEventCode()) { // This event indicates that a message has just been // sent over the air. case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03: { break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01: { Console.WriteLine("Search timeout"); Status = SensorStatus.Disconnected; break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02: { Console.WriteLine("Rx Fail"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04: { Console.WriteLine("Burst receive has failed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05: { Console.WriteLine("Transfer Completed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06: { Console.WriteLine("Transfer Failed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07: { // This event should be used to determine that the channel is closed. Console.WriteLine("Channel Closed"); Console.WriteLine("Unassigning Channel..."); if (_Channel.unassignChannel(500)) { Console.WriteLine("Unassigned Channel"); Status = SensorStatus.Disconnected; } break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08: { Console.WriteLine("Go to Search"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09: { Console.WriteLine("Channel Collision"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A: { Console.WriteLine("Burst Started"); break; } default: { Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode()); break; } } break; } case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E: case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F: case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50: case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D: case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E: case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F: { Status = SensorStatus.Connected; if (DeviceNumber == 0) { ANT_ChannelID chId = _Channel.requestID(500); if (chId.deviceNumber > 0) { Console.WriteLine("Setting device number and transmission type..."); DeviceNumber = chId.deviceNumber; TransmissionType = chId.transmissionTypeID; } } Console.WriteLine("decoding payload...."); _Sensor.Decode(response.getDataPayload()); break; } default: { Console.WriteLine("Unknown Message " + response.responseID); break; } } } catch (Exception ex) { Console.WriteLine("Channel response processing failed with exception: " + ex.Message); } }
/// <summary> /// Callback used by the .NET DLL for the Garmin device (USB1/2) /// </summary> /// <param name="response"></param> void DeviceResponse(ANT_Response response) { byte[] message_bytes = new byte[response.messageContents.Length + 3]; //Add header bytes as expected by the ProcessMessage function message_bytes[2] = response.responseID; response.messageContents.CopyTo(message_bytes, 3); BeginInvoke(new EventHandler(delegate { ProcessMessage(message_bytes); })); }
private void DeviceResponse(ANT_Response response) { // Debug.Log("[AntStick] " + decodeDeviceFeedback(response)); }
/// <summary> /// This function decodes the message code into human readable form and shows the error /// value on failures for device response events. /// </summary> /// <param name="response">The ANT Response received from the device.</param> /// <returns>A nicely formatted string</returns> private string decodeDeviceFeedback(ANT_Response response) { string toDisplay = "Device: "; // The ANTReferenceLibrary contains all the message and event codes in user-friendly // enums. This allows for more readable code and easy conversion to human readable // strings for display. // So, for the device response we first check if it is an event, then we check if it // failed, and display the failure if that is the case. "Events" use message code 0x40. if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40) { // We cast the byte to its messageID string and add the channel number byte. // associated with the message toDisplay += (ANT_ReferenceLibrary.ANTMessageID)response.messageContents[1] + ", Ch:" + response.messageContents[0]; // Check if the eventID shows an error, if it does, show the error message. if ((ANT_ReferenceLibrary.ANTEventID)response.messageContents[2] != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00) toDisplay += Environment.NewLine + ((ANT_ReferenceLibrary.ANTEventID)response.messageContents[2]).ToString(); } else // If the message is not an event, we just show the messageID. toDisplay += ((ANT_ReferenceLibrary.ANTMessageID)response.responseID).ToString(); // Finally we display the raw byte contents of the response, converting it to hex. toDisplay += Environment.NewLine + "::" + Convert.ToString(response.responseID, 16) + ", " + BitConverter.ToString(response.messageContents) + Environment.NewLine; return toDisplay; }
/// <summary> /// This function decodes the message code into human readable form and shows the error /// value on failures for channel response events. /// </summary> /// <param name="response">The ANT Response received from the channel.</param> /// <returns>A nicely formatted string.</returns> String decodeChannelFeedback(ANT_Response response) { // We use a stringbuilder for speed and better memory usage. StringBuilder stringToPrint; stringToPrint = new StringBuilder("Channel: ", 100); // In the channel feedback we will get either RESPONSE_EVENTs or receive events. If it // is a response event we display what the event was and the error code if it failed. // Mostly, these response_events will all be broadcast events from a Master channel. if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40) stringToPrint.AppendLine(((ANT_ReferenceLibrary.ANTEventID)response.messageContents[2]).ToString()); else // This is a receive event, so display the ID stringToPrint.AppendLine("Received " + ((ANT_ReferenceLibrary.ANTMessageID)response.responseID).ToString()); // Always print the raw contents in hex, with leading '::' for easy visibility/parsing. // If this is a receive event it will contain the payload of the message. stringToPrint.Append(" :: "); stringToPrint.Append(Convert.ToString(response.responseID, 16)); stringToPrint.Append(", "); stringToPrint.Append(BitConverter.ToString(response.messageContents) + Environment.NewLine); return stringToPrint.ToString(); }
private void ChannelResponse(ANT_Response response) { // Debug.Log("[AntStick] " + decodeChannelFeedback(response)); if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40) { if (response.messageContents[2] == (byte)ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01) { Debug.LogWarning("[AntStick] Failed to connect to any device."); Debug.LogWarning("[AntStick] <b>WARNING --- UNITY MAY CRASH!</b> Try lowering AntStick.CONNECT_TIMEOUT value."); UpdateState(AntState.ConnectFail); Stop(); } if (response.messageContents[2] == (byte)ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02) { Stats.IncrementRxFailCount(); } if (response.messageContents[2] == (byte)ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08) { UpdateState(AntState.ReConnecting); StartConnectTimeout(); } } else { if (state == AntState.Starting || state == AntState.ReConnecting) { Debug.Log("[AntStick] Successfully began receiving data."); UpdateState(AntState.Connected); } DataPage dataPage = DataPage.BuildDataPageFromReceivedData(response.messageContents); Stats.IncrementPageCount(dataPage.DataPageNumber); dataPage.FireReceived(); } }
void OnChannelResponseRecieved(ANT_Response response) { lock (locker) { messageSubject.OnNext(new AntMessage(response.responseID, response.messageContents)); } }
//////////////////////////////////////////////////////////////////////////////// // ChannelResponse // // Called whenever a channel event is recieved. // // response: ANT message //////////////////////////////////////////////////////////////////////////////// public void ChannelResponse(ANT_Response response) { try { switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID) { case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40: { switch (response.getChannelEventCode()) { // This event indicates that a message has just been // sent over the air. We take advantage of this event to set // up the data for the next message period. case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03: { txBuffer[0]++; // Increment the first byte of the buffer // Broadcast data will be sent over the air on // the next message period if (bBroadcasting) { channel0.sendBroadcastData(txBuffer); if (bDisplay) { // Echo what the data will be over the air on the next message period Console.WriteLine("Tx: (" + response.antChannel.ToString() + ")" + BitConverter.ToString(txBuffer)); } } else { string[] ac = { "|", "/", "_", "\\" }; Console.Write("Tx: " + ac[iIndex++] + "\r"); iIndex &= 3; } break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01: { Console.WriteLine("Search Timeout"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02: { Console.WriteLine("Rx Fail"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04: { Console.WriteLine("Burst receive has failed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05: { Console.WriteLine("Transfer Completed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06: { Console.WriteLine("Transfer Failed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07: { // This event should be used to determine that the channel is closed. Console.WriteLine("Channel Closed"); Console.WriteLine("Unassigning Channel..."); if (channel0.unassignChannel(500)) { Console.WriteLine("Unassigned Channel"); Console.WriteLine("Press enter to exit"); bDone = true; } break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08: { Console.WriteLine("Go to Search"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09: { Console.WriteLine("Channel Collision"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A: { Console.WriteLine("Burst Started"); break; } default: { Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode()); break; } } break; } case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E: case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F: case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50: case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D: case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E: case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F: { if (bDisplay) { if (response.isExtended()) // Check if we are dealing with an extended message { ANT_ChannelID chID = response.getDeviceIDfromExt(); // Channel ID of the device we just received a message from if (chID.deviceTypeID == 120) this.Heartrate = System.Convert.ToString(response.getDataPayload()[7]); // Device type for HR monitor is 120 else if (chID.deviceTypeID == 11) { if (response.getDataPayload()[0] == 10) { this.pwr = response.getDataPayload()[7]; this.cadence = response.getDataPayload()[4]; } } if (chID.deviceTypeID == 120) this.Heartrate = System.Convert.ToString(response.getDataPayload()[7]); Console.Write("Chan ID(" + chID.deviceNumber.ToString() + "," + chID.deviceTypeID.ToString() + "," + chID.transmissionTypeID.ToString() + ") - "); } if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E || response.responseID == (byte) ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D) Console.Write("Rx:(" + response.antChannel.ToString() + "): "); else if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F || response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E) Console.Write("Acked Rx:(" + response.antChannel.ToString() + "): "); else Console.Write("Burst(" + response.getBurstSequenceNumber().ToString("X2") + ") Rx:(" + response.antChannel.ToString() + "): "); //Console.Write(BitConverter.ToString(response.getDataPayload()) + Environment.NewLine); // Display data payload Console.Write(" Heart Rate is: " + this.Heartrate + Environment.NewLine); } else { string[] ac = { "|", "/", "_", "\\" }; Console.Write("Rx: " + ac[iIndex++] + "\r"); iIndex &= 3; } break; } default: { Console.WriteLine("Unknown Message " + response.responseID); break; } } } catch (Exception ex) { Console.WriteLine("Channel response processing failed with exception: " + ex.Message); } }
//////////////////////////////////////////////////////////////////////////////// // ChannelResponse // // Called whenever a channel event is recieved. // // response: ANT message //////////////////////////////////////////////////////////////////////////////// private void ChannelResponse(ANT_Response response) { bool bDisplay = true; bool bDone = false; try { switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID) { case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40: { switch (response.getChannelEventCode()) { // This event indicates that a message has just been // sent over the air. We take advantage of this event to set // up the data for the next message period. case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03: { //txBuffer[0]++; // Increment the first byte of the buffer //// Broadcast data will be sent over the air on //// the next message period //if (bBroadcasting) //{ // channel0.sendBroadcastData(txBuffer); // if (bDisplay) // { // // Echo what the data will be over the air on the next message period // Console.WriteLine("Tx: (" + response.antChannel.ToString() + ")" + BitConverter.ToString(txBuffer)); // } //} //else //{ // string[] ac = { "|", "/", "_", "\\" }; // Console.Write("Tx: " + ac[iIndex++] + "\r"); // iIndex &= 3; //} break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01: { break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02: { Console.WriteLine("Rx Fail"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04: { Console.WriteLine("Burst receive has failed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05: { Console.WriteLine("Transfer Completed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06: { Console.WriteLine("Transfer Failed"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07: { // This event should be used to determine that the channel is closed. Console.WriteLine("Channel Closed"); Console.WriteLine("Unassigning Channel..."); if (_Channel.unassignChannel(500)) { Console.WriteLine("Unassigned Channel"); Console.WriteLine("Press enter to exit"); bDone = true; } break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08: { Console.WriteLine("Go to Search"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09: { Console.WriteLine("Channel Collision"); break; } case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A: { Console.WriteLine("Burst Started"); break; } default: { Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode()); break; } } break; } case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E: case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F: case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50: case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D: case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E: case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F: { Console.WriteLine("decoding payload...."); _Sensor.Decode(response.getDataPayload()); break; } default: { Console.WriteLine("Unknown Message " + response.responseID); break; } } } catch (Exception ex) { Console.WriteLine("Channel response processing failed with exception: " + ex.Message); } }
/// <overloads>Requests a message from the device and returns the response</overloads> /// <summary> /// Read User Nvm by sending Request Mesg capturing the response. /// Throws exception on timeout. /// </summary> /// <param name="address">NVM Address to read from</param> /// <param name="size">Number of bytes to read</param> /// <param name="responseWaitTime">Time to wait for device success response</param> public ANT_Response readUserNvm(UInt16 address, byte size, UInt32 responseWaitTime) { if (!initializedUSB) throw new ObjectDisposedException("ANTDevice object has been disposed"); ANTMessageItem response = new ANTMessageItem(); if (ANT_RequestUserNvmMessage(unmanagedANTFramerPtr, 0, (byte)ANT_ReferenceLibrary.RequestMessageID.USER_NVM_0x7C, ref response, address, size, responseWaitTime) == 0) throw new ANT_Exception("Timed out waiting for requested message"); ANT_Response retVal = new ANT_Response(this, 0, DateTime.Now, response.antMsgData.msgID, response.antMsgData.ucharBuf.Take(response.dataSize).ToArray()); return retVal; }