12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739 |
- /*
- This software is subject to the license described in the License.txt file
- included with this software distribution. You may not use this file except in compliance
- with this license.
- Copyright (c) Dynastream Innovations Inc. 2012
- All rights reserved.
- */
- #include "StdAfx.h"
- #include "SDMSensor.h"
- /**************************************************************************
- * SDMSensor::ANT_eventNotification
- *
- * Process ANT channel event
- *
- * ucEventCode_: code of ANT channel event
- * pucEventBuffer_: pointer to buffer containing data received from ANT,
- * or a pointer to the transmit buffer in the case of an EVENT_TX
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::ANT_eventNotification(UCHAR ucEventCode_, UCHAR* pucEventBuffer_)
- {
- switch(ucEventCode_)
- {
- case EVENT_TX:
- HandleTransmit((UCHAR*) pucEventBuffer_);
- UpdateDisplay();
- break;
- case EVENT_RX_ACKNOWLEDGED: // added for receiving request pages
- HandleReceive((UCHAR*) pucEventBuffer_);
- break;
- case EVENT_TRANSFER_TX_COMPLETED: // For sending ACK request replies
- ucAckRetryCount = 0; // Reset retransmission counter
- ucMsgExpectingAck = 0; // Clear pending msg code
- break;
- case EVENT_TRANSFER_TX_FAILED:
- case EVENT_ACK_TIMEOUT: // Intentional fall thru
- if(ucMsgExpectingAck)
- HandleRetransmit(); // resend if it failed
- break;
- default:
- break;
- }
- }
- /**************************************************************************
- * SDMSensor::InitializeSim
- *
- * Initializes simulator variables
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::InitializeSim()
- {
- // Time info
- ulTimerInterval = 667; //cadence of 90
- ulRunTime = 0;
- dwTimeLastEvent = GetTickCount(); // Initialize timers for latency calculation
- dwTimeLastTx = dwTimeLastEvent;
- // Common pages (data initialized on UI)
- commonPages->ulSerialNum = System::Convert::ToUInt32(this->textBox_SerialNum->Text);
- commonPages->usModelNum = System::Convert::ToUInt16(this->textBox_ModelNum->Text);
- commonPages->usMfgID = System::Convert::ToUInt16(this->textBox_MfgID->Text);
- commonPages->ucHwVersion = System::Convert::ToByte(this->textBox_HwVersion->Text);
- commonPages->ucSwVersion = System::Convert::ToByte(this->textBox_SwVersion->Text);
- // Options
- ucSimDataType = SIM_FIXED;
- bSweepAscending = TRUE;
- bTxCommon = TRUE; // Enable common pages (required on new designs)
- bTxPage2 = TRUE; // Enable page 2 and all fields by default
- bTxPage3 = FALSE; // Disable Page 3 by default
- bTxPage16 = TRUE; // Enable Request Pages by default
- bTxPage22 = TRUE; // Enable Request Pages by default
- bTxPage16Flag = FALSE; // This flag is raised when a request to send Page 16 data is received
- bTxPage22Flag = FALSE; // This flag is raised when a request to send Page 22 data is received
- ucRequestCount = 0;
- bP22Ignore = FALSE;
- ucMsgExpectingAck = 0;
- ucMaxAckRetries = 127; // 127 is the default max number of times to attempt to resend an ack message
- bUseTime = TRUE;
- bUseDistance = TRUE;
- bUseLatency = TRUE;
- bUseSpeed = TRUE;
- bUseCadence = TRUE;
- eUnit = SDM_SPM; // user input is cadence (rpm)
- // Simulator data
- ucStrideLength = System::Convert::ToByte(this->numericUpDown_Sim_StrideLength->Value);
- ucCalorieRate = System::Convert::ToByte(this->numericUpDown_Sim_BurnRate->Value);
- this->listBox_SimUnits->SelectedIndex = 3; // Use rpm by default
- this->listBox_SimUnits->SelectedIndexChanged += gcnew System::EventHandler(this, &SDMSensor::listBox_SimUnitsChanged);
- usMaxCadence16 = ConvertFromInput(this->numericUpDown_Sim_MaxOutput->Value); // Initial cadence value set on UI
- usMinCadence16 = ConvertFromInput(this->numericUpDown_Sim_MinOutput->Value); // Initial cadence value set on UI
- usCurCadence16 = ConvertFromInput(this->numericUpDown_Sim_CurOutput->Value); // Initial cadence value set on UI
- usMaxSpeed256 = CadenceToSpeed(usMaxCadence16);
- usMinSpeed256 = CadenceToSpeed(usMinCadence16);
- usCurSpeed256 = CadenceToSpeed(usCurCadence16);
- usCadence16 = usCurCadence16;
- usSpeed256 = usCurSpeed256;
- ucStrideCount = 0;
- ucCalorieCount = 0;
- ulTempCalories = 0;
- ulStridesAccum = 0;
- ulDistanceAccum = 0;
- usDistance16 = 0;
- usTime200 = 0;
- ucLatency32 = 0;
- // Initialize status flags
- sStatusFlags.ucLocation = (UCHAR) 0;
- sStatusFlags.ucBatteryStatus = (UCHAR) 0;
- sStatusFlags.ucHealth = (UCHAR) 0;
- sStatusFlags.ucUseState = (UCHAR) 1;
- this->listBox_P2Location->SelectedIndex = 0;
- this->listBox_P2Battery->SelectedIndex = 0;
- this->listBox_P2Health->SelectedIndex = 0;
- this->listBox_P2Use->SelectedIndex = 1;
- // Initialize capabilities flags
- sCapabFlags.ucCadence = (UCHAR) 1;
- sCapabFlags.ucCalories = (UCHAR) 0;
- sCapabFlags.ucDistance = (UCHAR) 1;
- sCapabFlags.ucLatency = (UCHAR) 1;
- sCapabFlags.ucSpeed = (UCHAR) 1;
- sCapabFlags.ucTime = (UCHAR) 1;
- ucCapabFlags = SDM_CAPAB_INITIAL; // initialize flags based on the values above, very important to do this
- this->label_P22Cadence->ForeColor = System::Drawing::Color::Green;
- this->label_P22Calories->ForeColor = System::Drawing::Color::Red;
- this->label_P22Distance->ForeColor = System::Drawing::Color::Green;
- this->label_P22Latency->ForeColor = System::Drawing::Color::Green;
- this->label_P22Speed->ForeColor = System::Drawing::Color::Green;
- this->label_P22Time->ForeColor = System::Drawing::Color::Green;
- }
- /**************************************************************************
- * SDMSensor::HandleTransmit
- *
- * Encode data generated by simulator for transmission
- *
- * pucTxBuffer_: pointer to the transmit buffer
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::HandleTransmit(UCHAR* pucTxBuffer_)
- {
- static UCHAR ucMessageCount = 0;
- static UCHAR ucExtMesgType = 0;
- UCHAR ucPageNum;
- // Update latency
- // Latency calculation is platform specific
- dwTimeLastTx = GetTickCount(); // Get current time for latency calculation
- ucLatency32 = (UCHAR) (((dwTimeLastTx - dwTimeLastEvent) << 2)/25); // Convert from ms to 1/32 seconds
- // Figure out what page to send
- ucPageNum = SDM_PAGE1;
- if(bTxPage2 || bTxPage3)
- {
- // Page 1 and 2 (or 3) alternate every 2 messages
- if(ucMessageCount & 0x02)
- if (bTxPage2)
- ucPageNum = SDM_PAGE2;
- else
- ucPageNum = SDM_PAGE3;
- }
- // Send common pages every 65th message,
- // Skip if we are sending request pages as this takes priority
- if(ucMessageCount++ >= (SDM_COMMON_INTERVAL - 1) && bTxCommon
- && (bTxPage16Flag == FALSE) && (bTxPage22Flag == FALSE))
- {
- // Always send two in a row
- if(ucExtMesgType++ & 0x02)
- ucPageNum = CommonData::PAGE81;
- else
- ucPageNum = CommonData::PAGE80;
- ucMessageCount = 0;
- }
- // Request pages only on request. This takes priority over all other messages.
- if (bTxPage16Flag == TRUE)
- {
- ucPageNum = SDM_PAGE16;
- ucRequestCount--; // subtract one from the resend count
- if (ucRequestCount == 0) // if count is zero, then reset
- bTxPage16Flag = FALSE;
- }
- if (bTxPage22Flag == TRUE)
- {
- ucPageNum = SDM_PAGE22;
- ucRequestCount--; // subtract one from the resend count
- if (ucRequestCount == 0) // if count is zero, then reset
- bTxPage22Flag = FALSE;
- }
- // Set page number
- pucTxBuffer_[0] = ucPageNum;
- // Encode each page
- switch(ucPageNum)
- {
- case SDM_PAGE1:
- pucTxBuffer_[1] = (usTime200 % 200) * bUseTime; // fractional time (1/200 seconds)
- pucTxBuffer_[2] = (UCHAR) (usTime200/200 * bUseTime); // time of last event (seconds)
- pucTxBuffer_[3] = (usDistance16 * bUseDistance >> 4) & 0xFF; // cumulative distance (meters)
- pucTxBuffer_[4] = (usDistance16 * bUseDistance << 4) & 0xF0; // fractional distance (1/16 meters)
- pucTxBuffer_[4] |= ((usSpeed256 * bUseSpeed >> 8) & 0x0F); // current speed (m/s) - if enabled
- pucTxBuffer_[5] = usSpeed256 * bUseSpeed & 0xFF; // fractional speed (1/256 m/s) - if enabled
- pucTxBuffer_[6] = ucStrideCount & 0xFF; // cumulative stride count (number of strides)
- pucTxBuffer_[7] = ucLatency32 * bUseLatency; // latency (1/32 seconds) - if enabled
- break;
- case SDM_PAGE2:
- pucTxBuffer_[1] = SDM_RESERVED;
- pucTxBuffer_[2] = SDM_RESERVED;
- pucTxBuffer_[3] = (usCadence16 * bUseCadence >> 4) & 0xFF; // current cadence (strides/min)
- pucTxBuffer_[4] = (usCadence16 * bUseCadence << 4) & 0xF0; // fractional cadence (1/16 strides/min)
- pucTxBuffer_[4] |= (usSpeed256 * bUseSpeed >> 8) & 0x0F; // current speed (m/s)
- pucTxBuffer_[5] = usSpeed256 * bUseSpeed & 0xFF; // fractional speed (1/256 m/s)
- pucTxBuffer_[6] = SDM_RESERVED;
- pucTxBuffer_[7] = ucStatusFlags; // SDM status flags
- break;
- case SDM_PAGE3:
- pucTxBuffer_[1] = SDM_RESERVED;
- pucTxBuffer_[2] = SDM_RESERVED;
- pucTxBuffer_[3] = (usCadence16 * bUseCadence >> 4) & 0xFF; // current cadence (strides/min)
- pucTxBuffer_[4] = (usCadence16 * bUseCadence << 4) & 0xF0; // fractional cadence (1/16 strides/min)
- pucTxBuffer_[4] |= (usSpeed256 * bUseSpeed >> 8) & 0x0F; // current speed (m/s)
- pucTxBuffer_[5] = usSpeed256 * bUseSpeed & 0xFF; // fractional speed (1/256 m/s)
- pucTxBuffer_[6] = ucCalorieCount & 0xFF; // cumulative calorie count
- pucTxBuffer_[7] = ucStatusFlags; // SDM status flags
- break;
- case SDM_PAGE16: // on request only
- pucTxBuffer_[1] = ulStridesAccum & 0xFF; // Bytes 1-3 = Stride Count
- pucTxBuffer_[2] = (ulStridesAccum >> 8) & 0xFF;
- pucTxBuffer_[3] = (ulStridesAccum >> 16) & 0xFF;
- pucTxBuffer_[4] = ulDistanceAccum & 0xFF; // Bytes 4-7 = Distance
- pucTxBuffer_[5] = (ulDistanceAccum >> 8) & 0xFF;
- pucTxBuffer_[6] = (ulDistanceAccum >> 16) & 0xFF;
- pucTxBuffer_[7] = (ulDistanceAccum >> 24) & 0xFF;
- break;
- case SDM_PAGE22: // on request only
- pucTxBuffer_[1] = ucCapabFlags; // Capabilities Byte
- pucTxBuffer_[2] = SDM_RESERVED; // Bytes 2-7 are reserved
- pucTxBuffer_[3] = SDM_RESERVED;
- pucTxBuffer_[4] = SDM_RESERVED;
- pucTxBuffer_[5] = SDM_RESERVED;
- pucTxBuffer_[6] = SDM_RESERVED;
- pucTxBuffer_[7] = SDM_RESERVED;
- break;
- case CommonData::PAGE80:
- case CommonData::PAGE81:
- try
- {
- commonPages->Encode(ucPageNum, pucTxBuffer_);
- }
- catch(CommonData::Error^ errorCommon)
- {
- }
- break;
- default:
- break;
- }
- }
- /**************************************************************************
- * SDMSensor::HandleReceive
- *
- * Decode incoming transmissions, specifically data requests
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::HandleReceive(UCHAR* pucRxBuffer_)
- {
- UCHAR ucPageNum = pucRxBuffer_[0];
- UCHAR ucRequestNum = pucRxBuffer_[6];
- BOOL bP22Skip = FALSE;
- // if all the flags are on AND we are chosing to ignore the request if this happens, set the flag
- if ((bP22Ignore == TRUE) && (ucCapabFlags == SDM_CAPAB_ALL))
- bP22Skip = TRUE;
- if(ucPageNum == SDM_PAGE70) // Only decode request pages
- {
- if ((ucRequestNum == SDM_PAGE16) && (bTxPage16 == TRUE)) // only process request if page is enabled
- {
- ucRequestCount = pucRxBuffer_[5]; // save the number of times to re-transmit
- if (ucRequestCount == 0x80) // 0x80 is a special case where we want to resend ack messages until a response is recieved
- {
- ucMaxAckRetries = 127; // reset to default in case this was changed
- SendAckRequestMsg(SDM_PAGE16); // will automatically attempt to re-send until ack
- }
- else if ((ucRequestCount & 0x80) == 0x80) // if MSB is set we want to use ACK response, the number in bits 0-6 becomes the maximum number of retries
- {
- ucMaxAckRetries = ucRequestCount &= ~0x80; // clear the MSB, save the remaining number as max retries
- SendAckRequestMsg(SDM_PAGE16);
- }
- else // must be a regular broadcast request
- {
- // set a flag that will insert the page into the regular broadcast stream
- bTxPage16Flag = TRUE;
- bTxPage22Flag = FALSE; // new requests will overwrite the last request
- }
- }
- if ((ucRequestNum == SDM_PAGE22) && (bTxPage22 == TRUE) && (bP22Skip == FALSE)) // only process request if page is enabled and we are not skipping
- {
- ucRequestCount = pucRxBuffer_[5]; // save the number of times to re-transmit
- if (ucRequestCount == 0x80) // 0x80 is a special case where we want to resend ack messages until a response is recieved
- {
- ucMaxAckRetries = 127; // reset to default in case this was changed
- SendAckRequestMsg(SDM_PAGE22); // will automatically attempt to re-send until ack
- }
- else if ((ucRequestCount & 0x80) == 0x80) // if MSB is set we want to use ACK response, the number in bits 0-6 becomes the maximum number of retries
- {
- ucMaxAckRetries = ucRequestCount &= ~0x80; // clear the MSB, save the remaining number as max retries
- SendAckRequestMsg(SDM_PAGE22);
- }
- else // must be a regular broadcast request
- {
- // set a flag that will insert the page into the regular broadcast stream
- bTxPage22Flag = TRUE;
- bTxPage16Flag = FALSE; // new requests will overwrite the last request
- }
- }
- }
- }
- /**************************************************************************
- * SDMSensor::HandleRetransmit
- *
- * Retransmits request message, up to the maximum retransmission number,
- * ucMaxAckRetries, which defaults to 127, but is modified on request
- *
- * returns: TRUE if message was retransmitted
- * FALSE if maximum number of retransmissions was reached
- *
- **************************************************************************/
- BOOL SDMSensor::HandleRetransmit()
- {
- BOOL bSuccess = TRUE;
- if(ucMsgExpectingAck) // Message still expecting an ack
- {
- if(ucAckRetryCount++ < ucMaxAckRetries)
- SendAckRequestMsg(ucMsgExpectingAck);
- else
- bSuccess = FALSE;
- }
-
- return bSuccess;
- }
- /**************************************************************************
- * SDMSensor::SendAckRequestMsg
- *
- * Reply to the request message using an acknoledged message
- *
- * ucMsgCode_: message ID of the calibration message to send
- * Supported messages:
- * - Page 16 Request (Distance and Strides)
- * - Page 22 Request (Capabilities)
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::SendAckRequestMsg(UCHAR ucMsgCode_)
- {
- UCHAR aucAckBuffer[8] = {0,0,0,0,0,0,0,0};
- switch(ucMsgCode_)
- {
- case SDM_PAGE16: // Page 16 Request (Distance and Strides)
- aucAckBuffer[0] = SDM_PAGE16;
- aucAckBuffer[1] = ulStridesAccum & 0xFF; // Bytes 1-3 = Stride Count
- aucAckBuffer[2] = (ulStridesAccum >> 8) & 0xFF;
- aucAckBuffer[3] = (ulStridesAccum >> 16) & 0xFF;
- aucAckBuffer[4] = ulDistanceAccum & 0xFF; // Bytes 4-7 = Distance
- aucAckBuffer[5] = (ulDistanceAccum >> 8) & 0xFF;
- aucAckBuffer[6] = (ulDistanceAccum >> 16) & 0xFF;
- aucAckBuffer[7] = (ulDistanceAccum >> 24) & 0xFF;
- break;
- case SDM_PAGE22: // Page 22 Request (Capabilities)
- aucAckBuffer[0] = SDM_PAGE22;
- aucAckBuffer[1] = ucCapabFlags; // Capabilities Byte
- aucAckBuffer[2] = SDM_RESERVED; // Bytes 2-7 are reserved
- aucAckBuffer[3] = SDM_RESERVED;
- aucAckBuffer[4] = SDM_RESERVED;
- aucAckBuffer[5] = SDM_RESERVED;
- aucAckBuffer[6] = SDM_RESERVED;
- aucAckBuffer[7] = SDM_RESERVED;
- break;
- default:
- return; // Do not transmit if unsupported message code
- }
- // Send acknowledged message
- if(!ucMsgExpectingAck) // If this message is not a retransmission
- {
- ucAckRetryCount = 0; // Reset retransmission counter
- ucMsgExpectingAck = ucMsgCode_; // Set code to message for which an ACK wil be expected
- }
- requestAckMsg(aucAckBuffer); // Send message
- }
- /**************************************************************************
- * SDMSensor::onTimerTock
- *
- * Simulates a device event, updating simulator data based on this event
- * Modifications to the timer interval are applied immediately after this
- * at ANTChannel
- *
- * usEventTime_: current time (ms)
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::onTimerTock(USHORT eventTime)
- {
- USHORT tempOffset = 0; // Temporary variable to calculate sweeping intervals
- dwTimeLastEvent = GetTickCount(); // Get current time in ms (since system started)
-
- // Update stride count (required)
- ucStrideCount++;
-
- // Update Accumulative stride count once every two steps
- ulStridesAccum++;
- if (ulStridesAccum == 16777216) // 16777215 = 0xFFFFFF
- ulStridesAccum = 0;
- // Update event time
- ulRunTime += ulTimerInterval;
- usTime200 = (USHORT) ((ulRunTime%256000)/5); // ms -> 1/200s, rollover at 256 seconds
- // Update speed
- switch(ucSimDataType)
- {
- case SIM_FIXED:
- // Speed and cadence values do not change
- break;
- case SIM_SWEEP:
- // Value sweeps between max and min
- // The jump offset is calculated versus position against the max so it won't get stuck on low values for a long time and won't speed through high values too fast
- // Calculate next speed value
- tempOffset = usMaxSpeed256-usCurSpeed256;
- tempOffset = ((tempOffset & 0x600) >> 6) + ((tempOffset & 0x100) >>5) + ((tempOffset & 0x80) >>4)+0xF;
- if(bSweepAscending)
- usCurSpeed256 += tempOffset;
- else
- usCurSpeed256 -= tempOffset;
- // Ensure value is more than min and less than max
- if(usCurSpeed256 >= usMaxSpeed256)
- {
- usCurSpeed256 = usMaxSpeed256;
- bSweepAscending = FALSE;
- }
- if(usCurSpeed256 <= usMinSpeed256)
- {
- usCurSpeed256 = usMinSpeed256;
- bSweepAscending = TRUE;
- }
- // Update cadence according to new speed
- usCurCadence16 = SpeedToCadence(usCurSpeed256);
- break;
- default:
- break;
- }
- usSpeed256 = usCurSpeed256;
- usCadence16 = usCurCadence16;
- // Calculate distance
- usDistance16 += ((USHORT) ucStrideLength * 16)/100; // Stride length cm -> 1/16m
- // Update Accumulative distance
- ulDistanceAccum += ((ULONG) ucStrideLength * 256)/100; // Stride length cm -> 1/256m
- // Update the Calorie count (burn rate (K-kcal/m) * distance (1/16m))
- ulTempCalories += (ULONG)(ucCalorieRate*((ucStrideLength * 16)/100)); // K-kcal
- ucCalorieCount = (UCHAR)((ulTempCalories/1000)/16); // convert to UCHAR and kcal
- // Update timer interval (in ms)
- if(usCadence16)
- ulTimerInterval = (ULONG) 960000/usCadence16; // 60 seconds/revolutions per minute (60 * 1000 * 16)
- else
- ulTimerInterval = 600000; // Cadence & speed = 0, so timer interval is set to a very large value
-
- }
- /***************************************************************************
- * SDMSensor::UpdateDisplay
- *
- * Updates displayed simulator data on GUI
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::UpdateDisplay()
- {
- this->label_TransStrideCountDisplay->Text = ucStrideCount.ToString(); // Display stride count (required)
- this->label_P1StrideCountDisplay->Text = ucStrideCount.ToString();
- if(bUseTime)
- this->label_Trn_TimeDisplay->Text = ((double)usTime200/200).ToString(); // Display time in seconds
- else
- this->label_Trn_TimeDisplay->Text = "--"; // Unused
- if(bUseSpeed)
- this->label_TransInstSpeedDisplay->Text = ((double)(usSpeed256 & 0xFFF)/256).ToString(); // Display speed in m/s
- else
- this->label_TransInstSpeedDisplay->Text = "--"; // Unused
- if(bUseCadence && (bTxPage2 || bTxPage3))
- this->label_TransCadenceDisplay->Text = ((double)usCadence16/16).ToString(); // Display cadence in rpm
- else
- this->label_TransCadenceDisplay->Text = "--"; // Unused
- if(bUseDistance)
- {
- this->label_TransDistDisplay->Text = ((double)(usDistance16 & 0xFFF)/16).ToString(); // Display distance in m
- this->label_P1TotDistDisplay->Text = ((double)(usDistance16 & 0xFFF)/16).ToString();
- }
- else
- {
- this->label_TransDistDisplay->Text = "--"; // Unused
- this->label_P1TotDistDisplay->Text = "--";
- }
- if(bUseLatency)
- this->label_TransLatencyDisplay->Text = System::Convert::ToString((double)ucLatency32*1000/32); // Display latency in ms
- else
- this->label_TransLatencyDisplay->Text = "--";
- if(ucSimDataType == SIM_SWEEP)
- {
- if(eUnit == SDM_SPM) // Show sweeping values
- this->numericUpDown_Sim_CurOutput->Value = ConvertToInput(usCurCadence16); // Cadence
- else
- this->numericUpDown_Sim_CurOutput->Value = ConvertToInput(usCurSpeed256 & 0xFFF); // Speed
- }
- if(bTxPage3) // calories
- {
- this->label_P3CalDisplay->Text = ucCalorieCount.ToString();
- this->label_TransCalDisplay->Text = ucCalorieCount.ToString();
- }
- else
- {
- this->label_P3CalDisplay->Text = "--";
- this->label_TransCalDisplay->Text = "--";
- }
- if(bTxPage16)
- {
- this->label_P16StridesDisplay->Text = ulStridesAccum.ToString(); //mask off the top byte
- this->label_P16DistanceDisplay->Text = ulDistanceAccum.ToString();
- }
- else
- {
- this->label_P16StridesDisplay->Text = "--";
- this->label_P16DistanceDisplay->Text = "--";
- }
- }
- /**************************************************************************
- * SDMSensor::button_UpdateCommon_Click
- *
- * Validates and updates product information, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::button_UpdateCommon_Click(System::Object^ sender, System::EventArgs^ e)
- {
- label_ErrorCommon->Visible = false;
- label_ErrorCommon->Text = "Error: ";
- // Convert and catch failed conversions
- try{
- commonPages->usMfgID = System::Convert::ToUInt16(this->textBox_MfgID->Text);
- }
- catch(...){
- label_ErrorCommon->Text = System::String::Concat(label_ErrorCommon->Text, " MFID");
- label_ErrorCommon->Visible = true;
- }
- try{
- if(!this->checkBox_InvalidSerial->Checked)
- commonPages->ulSerialNum = System::Convert::ToUInt32(this->textBox_SerialNum->Text);
- else
- commonPages->ulSerialNum = 0xFFFFFFFF;
- }
- catch(...){
- label_ErrorCommon->Text = System::String::Concat(label_ErrorCommon->Text, " Ser#");
- label_ErrorCommon->Visible = true;
- }
- try{
- commonPages->ucHwVersion = System::Convert::ToByte(this->textBox_HwVersion->Text);
- }
- catch(...){
- label_ErrorCommon->Text = System::String::Concat(label_ErrorCommon->Text, " HWVr");
- label_ErrorCommon->Visible = true;
- }
- try{
- commonPages->ucSwVersion = System::Convert::ToByte(this->textBox_SwVersion->Text);
- }
- catch(...){
- label_ErrorCommon->Text = System::String::Concat(label_ErrorCommon->Text, " SWVr");
- label_ErrorCommon->Visible = true;
- }
- try{
- commonPages->usModelNum = System::Convert::ToUInt16(this->textBox_ModelNum->Text);
- }
- catch(...){
- label_ErrorCommon->Text = System::String::Concat(label_ErrorCommon->Text, " Mdl#");
- label_ErrorCommon->Visible = true;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_EnableCommon_CheckedChanged
- *
- * Enable/disable transmission of common pages
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_EnableCommon_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Enable disabling common data pages for testing backward compatibility of receivers
- // Do NOT use as a reference for new designs
- if(!checkBox_EnableCommon->Checked)
- {
- System::Windows::Forms::DialogResult result = MessageBox::Show(L"This option is available for backward compatibility testing.\nIt should not be used as a reference in the development of new sensors.", L"Warning", MessageBoxButtons::OKCancel);
- if( result == ::DialogResult::OK )
- {
- bTxCommon = FALSE;
- }
- else
- {
- bTxCommon = TRUE;
- checkBox_EnableCommon->Checked = TRUE;
- }
- }
- else
- {
- // Reenable common pages
- bTxCommon = TRUE;
- }
- }
- /**************************************************************************
- * SDMSensor::listBox_SimUnitsChanged
- *
- * Select simulation units
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_SimUnitsChanged(System::Object^ sender, System::EventArgs^ e)
- {
- System::Decimal decMaxValue;
- eUnit = (SDMUnit) this->listBox_SimUnits->SelectedIndex;
- // Remove limit, so that conversion can take place successfully (changed from 1000 to 2000)
- this->numericUpDown_Sim_MaxOutput->Maximum = 2000;
- this->numericUpDown_Sim_MinOutput->Maximum = 2000;
- this->numericUpDown_Sim_CurOutput->Maximum = 2000;
- // Disable boxes momentarily, to keep values from being checked and modified again as they change
- this->numericUpDown_Sim_CurOutput->Enabled = FALSE;
- this->numericUpDown_Sim_MaxOutput->Enabled = FALSE;
- this->numericUpDown_Sim_MinOutput->Enabled = FALSE;
- // Update input data
- if(eUnit == SDM_SPM)
- {
- // Selected cadence (switching from speed to cadence)
- // Latest speed and cadence values are maintained, just displayed in proper unit
- // Display values
- this->numericUpDown_Sim_MinOutput->Value = ConvertToInput(usMinCadence16);
- this->numericUpDown_Sim_CurOutput->Value = ConvertToInput(usCurCadence16);
- this->numericUpDown_Sim_MaxOutput->Value = ConvertToInput(usMaxCadence16);
- decMaxValue = ConvertToInput(SDM_MAX_CADENCE16);
- //MessageBox::Show("Current Cadence = " + usCurCadence16.ToString() + " Current dexMaxValue = " + decMaxValue.ToString(), "Speed to Cadence", MessageBoxButtons::OK,MessageBoxIcon::Error, MessageBoxDefaultButton::Button1);
- }
- else
- {
- // Selected a speed unit (switching between speed units or from cadence)
- // Latest speed value is maintained, just displayed in the selected unit
- this->numericUpDown_Sim_MinOutput->Value = ConvertToInput(usMinSpeed256);
- this->numericUpDown_Sim_CurOutput->Value = ConvertToInput(usCurSpeed256);
- this->numericUpDown_Sim_MaxOutput->Value = ConvertToInput(usMaxSpeed256);
- decMaxValue = ConvertToInput(SDM_MAX_SPEED256);
- //MessageBox::Show("Current Cadence = " + usCurCadence16.ToString() + " Current dexMaxValue = " + decMaxValue.ToString(), "Cadence to Speed", MessageBoxButtons::OK,MessageBoxIcon::Error, MessageBoxDefaultButton::Button1);
- }
- // Adjust maximum value of input boxes to prevent overflow of the speed/cadence fields
- this->numericUpDown_Sim_MaxOutput->Maximum = decMaxValue + (System::Decimal) 0.001;
- this->numericUpDown_Sim_MinOutput->Maximum = decMaxValue + (System::Decimal) 0.001;
- this->numericUpDown_Sim_CurOutput->Maximum = decMaxValue + (System::Decimal) 0.001;
- // Enable input boxes again so that they can be modified
- if(ucSimDataType == SIM_SWEEP)
- {
- this->numericUpDown_Sim_MaxOutput->Enabled = TRUE;
- this->numericUpDown_Sim_MinOutput->Enabled = TRUE;
- }
- else
- {
- this->numericUpDown_Sim_CurOutput->Enabled = TRUE;
- }
- }
- /**************************************************************************
- * SDMSensor::numericUpDown_Sim_CurOutput_ValueChanged
- *
- * Updates and converts units of the current speed or cadence value, when it changes
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::numericUpDown_Sim_CurOutput_ValueChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Ignore changes when sweeping
- if(this->numericUpDown_Sim_CurOutput->Enabled)
- {
- if(eUnit == SDM_SPM)
- {
- // User input is cadence
- // Update cadence value
- usCurCadence16 = ConvertFromInput(this->numericUpDown_Sim_CurOutput->Value);
- // Update speed from cadence
- usCurSpeed256 = CadenceToSpeed(usCurCadence16);
- }
- else
- {
- // User input is speed
- // Update speed value
- usCurSpeed256 = ConvertFromInput(this->numericUpDown_Sim_CurOutput->Value);
- // Update cadence from speed
- usCurCadence16 = SpeedToCadence(usCurSpeed256);
- }
- ForceUpdate();
- }
- }
- /**************************************************************************
- * SDMSensor::numericUpDown_Sim_MinMaxOutput_ValueChanged
- *
- * If the user has changed the min or max speed, validate that
- * minimum < current < maximum
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::numericUpDown_Sim_MinMaxOutput_ValueChanged(System::Object^ sender, System::EventArgs^ e)
- {
- USHORT usPrevCadence16 = usCurCadence16;
- USHORT usPrevSpeed256 = usCurSpeed256;
- // Check only if user changes values
- if(this->numericUpDown_Sim_MinOutput->Enabled && this->numericUpDown_Sim_MaxOutput->Enabled)
- {
- // Check min<max if in min/max mode, and force min<cur<max
- if(this->numericUpDown_Sim_MinOutput->Value < this->numericUpDown_Sim_MaxOutput->Value)
- {
- if(eUnit == SDM_SPM)
- {
- // User input is cadence
- usMinCadence16 = ConvertFromInput(this->numericUpDown_Sim_MinOutput->Value);
- usMaxCadence16 = ConvertFromInput(this->numericUpDown_Sim_MaxOutput->Value);
- if(usCurCadence16 > usMaxCadence16)
- usCurCadence16 = usMaxCadence16;
- else if(usCurCadence16 < usMinCadence16)
- usCurCadence16= usMinCadence16;
- // Update speed
- usMinSpeed256 = CadenceToSpeed(usMinCadence16);
- usMaxSpeed256 = CadenceToSpeed(usMaxCadence16);
- if(usCurCadence16 != usPrevCadence16)
- {
- this->numericUpDown_Sim_CurOutput->Value = ConvertToInput(usCurCadence16);
- usCurSpeed256 = CadenceToSpeed(usCurCadence16);
- ForceUpdate();
- }
- }
- else
- {
- // User input is speed
- usMinSpeed256 = ConvertFromInput(this->numericUpDown_Sim_MinOutput->Value);
- usMaxSpeed256 = ConvertFromInput(this->numericUpDown_Sim_MaxOutput->Value);
- if(usCurSpeed256 > usMaxSpeed256)
- usCurSpeed256 = usMaxSpeed256;
- else if(usCurSpeed256 < usMinSpeed256)
- usCurSpeed256 = usMinSpeed256;
- // Update cadence
- usMinCadence16 = SpeedToCadence(usMinSpeed256);
- usMaxCadence16 = SpeedToCadence(usMaxSpeed256);
- if(usCurSpeed256 != usPrevSpeed256)
- {
- this->numericUpDown_Sim_CurOutput->Value = ConvertToInput(usCurSpeed256);
- usCurCadence16 = SpeedToCadence(usCurSpeed256);
- ForceUpdate();
- }
- }
- }
- else
- {
- // If the values were invalid, set numeric values to last valid values
- if(eUnit == SDM_SPM)
- {
- // Cadence
- this->numericUpDown_Sim_MinOutput->Value = ConvertToInput(usMinCadence16);
- this->numericUpDown_Sim_MaxOutput->Value = ConvertToInput(usMaxCadence16);
- }
- else
- {
- // Speed
- this->numericUpDown_Sim_MinOutput->Value = ConvertToInput(usMinSpeed256);
- this->numericUpDown_Sim_MaxOutput->Value = ConvertToInput(usMaxSpeed256);
- }
- }
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_Sweeping_CheckedChanged
- *
- * Select method to generate simulator data, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_Sweeping_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- this->numericUpDown_Sim_CurOutput->Enabled = !this->numericUpDown_Sim_CurOutput->Enabled;
- this->numericUpDown_Sim_MinOutput->Enabled = !this->numericUpDown_Sim_MinOutput->Enabled;
- this->numericUpDown_Sim_MaxOutput->Enabled = !this->numericUpDown_Sim_MaxOutput->Enabled;
- // If we allow the units to be changed while the transmission is sweeping it gets really messy
- this->listBox_SimUnits->Enabled = !this->listBox_SimUnits->Enabled;
- if(this->checkBox_Sweeping->Checked)
- {
- ucSimDataType = SIM_SWEEP;
- bSweepAscending = TRUE;
- }
- else
- {
- ucSimDataType = SIM_FIXED;
- }
- }
- /**************************************************************************
- * SDMSensor::button_UpdateDistance_Click
- *
- * Validates and updates cumulative distance, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::button_UpdateDistance_Click(System::Object^ sender, System::EventArgs^ e)
- {
- this->label_P1UpdateError->Visible = false;
- //convert and catch failed conversions
- try{
- usDistance16 = 16 * (USHORT) System::Convert::ToByte(this->textBox_P1TotDistChange->Text);
- this->label_P1TotDistDisplay->Text = this->textBox_P1TotDistChange->Text;
- }
- catch(...){
- this->label_P1UpdateError->Text = "Error: Dist";
- this->label_P1UpdateError->Visible = true;
- }
- }
- /**************************************************************************
- * SDMSensor::button_UpdateStrides_Click
- *
- * Validates and updates cumulative distance, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::button_UpdateStrides_Click(System::Object^ sender, System::EventArgs^ e)
- {
- this->label_P1UpdateError->Visible = false;
- //convert and catch failed conversions
- try{
- ucStrideCount = System::Convert::ToByte(this->textBox_P1StrideCountChange->Text);
- this->label_P1StrideCountDisplay->Text = this->textBox_P1StrideCountChange->Text;
- }
- catch(...){
- this->label_P1UpdateError->Text = "Error: Stride";
- this->label_P1UpdateError->Visible = true;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P1InstSpeed_CheckedChanged
- *
- * Enable/disable transmission of speed (optional field), and synchronizes
- * option in Page 1, 2, and 3
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P1InstSpeed_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Synchronize the three pages' inst speed options to avoid confusion
- this->checkBox_P2InstSpeed->Checked = this->checkBox_P1InstSpeed->Checked;
- this->checkBox_P3InstSpeed->Checked = this->checkBox_P1InstSpeed->Checked;
- bUseSpeed = this->checkBox_P1InstSpeed->Checked;
- sCapabFlags.ucSpeed = (UCHAR) this->checkBox_P1InstSpeed->Checked;
- if (sCapabFlags.ucSpeed == 1) // if latency is selected
- {
- ucCapabFlags |= SDM_SPEED_MASK; // set the bit to 1
- this->label_P22Speed->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_SPEED_MASK; // set the bit to 0
- this->label_P22Speed->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P2InstSpeed_CheckedChanged
- *
- * Enable/disable transmission of speed (optional field), and synchronizes
- * option in Page 1, 2, and 3
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P2InstSpeed_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Synchronize the three pages' inst speed options to avoid confusion
- this->checkBox_P1InstSpeed->Checked = this->checkBox_P2InstSpeed->Checked;
- this->checkBox_P3InstSpeed->Checked = this->checkBox_P2InstSpeed->Checked;
- bUseSpeed = this->checkBox_P2InstSpeed->Checked;
- sCapabFlags.ucSpeed = (UCHAR) this->checkBox_P2InstSpeed->Checked;
- if (sCapabFlags.ucSpeed == 1) // if latency is selected
- {
- ucCapabFlags |= SDM_SPEED_MASK; // set the bit to 1
- this->label_P22Speed->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_SPEED_MASK; // set the bit to 0
- this->label_P22Speed->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P3InstSpeed_CheckedChanged
- *
- * Enable/disable transmission of speed (optional field), and synchronizes
- * option in Page 1, 2, and 3
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P3InstSpeed_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Synchronize the three pages' inst speed options to avoid confusion
- this->checkBox_P1InstSpeed->Checked = this->checkBox_P3InstSpeed->Checked;
- this->checkBox_P2InstSpeed->Checked = this->checkBox_P3InstSpeed->Checked;
- bUseSpeed = this->checkBox_P3InstSpeed->Checked;
- sCapabFlags.ucSpeed = (UCHAR) this->checkBox_P3InstSpeed->Checked;
- if (sCapabFlags.ucSpeed == 1) // if latency is selected
- {
- ucCapabFlags |= SDM_SPEED_MASK; // set the bit to 1
- this->label_P22Speed->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_SPEED_MASK; // set the bit to 0
- this->label_P22Speed->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P1Time_CheckedChanged
- *
- * Enable/disable transmission of time in Page 1 (optional field)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P1Time_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- bUseTime = !bUseTime;
- sCapabFlags.ucTime = (UCHAR) this->checkBox_P1Time->Checked;
- if (sCapabFlags.ucTime == 1) // if time is selected
- {
- ucCapabFlags |= SDM_TIME_MASK; // set the bit to 1
- this->label_P22Time->ForeColor = System::Drawing::Color::Green;
- }
- else // time not selected
- {
- ucCapabFlags &= ~SDM_TIME_MASK; // set the bit to 0
- this->label_P22Time->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P1Latency_CheckedChanged
- *
- * Enable/disable transmission of latency in Page 1 (optional field)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P1Latency_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- bUseLatency = !bUseLatency;
- sCapabFlags.ucLatency = (UCHAR) this->checkBox_P1Latency->Checked;
- if (sCapabFlags.ucLatency == 1) // if latency is selected
- {
- ucCapabFlags |= SDM_LATENCY_MASK; // set the bit to 1
- this->label_P22Latency->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_LATENCY_MASK; // set the bit to 0
- this->label_P22Latency->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P1Distance_CheckedChanged
- *
- * Enable/disable transmission of distance in Page 1 (optional field)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P1Distance_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- bUseDistance = !bUseDistance;
- sCapabFlags.ucDistance = (UCHAR) this->checkBox_P1Distance->Checked;
- if (sCapabFlags.ucDistance == 1) // if distance is selected
- {
- ucCapabFlags |= SDM_DISTANCE_MASK; // set the bit to 1
- this->label_P22Distance->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_DISTANCE_MASK; // set the bit to 0
- this->label_P22Distance->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P2Cadence_CheckedChanged
- *
- * Enable/disable transmission of cadence in Page 2 (optional field)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P2Cadence_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- this->checkBox_P3Cadence->Checked = this->checkBox_P2Cadence->Checked;
- bUseCadence = this->checkBox_P2Cadence->Checked;
- //bUseCadence = !bUseCadence;
- sCapabFlags.ucCadence = (UCHAR) this->checkBox_P2Cadence->Checked;
- if (sCapabFlags.ucCadence == 1) // if latency is selected
- {
- ucCapabFlags |= SDM_CADENCE_MASK; // set the bit to 1
- this->label_P22Cadence->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_CADENCE_MASK; // set the bit to 0
- this->label_P22Cadence->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P3Cadence_CheckedChanged
- *
- * Enable/disable transmission of cadence in Page 3 (optional field)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P3Cadence_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- this->checkBox_P2Cadence->Checked = this->checkBox_P3Cadence->Checked;
- bUseCadence = this->checkBox_P3Cadence->Checked;
- //bUseCadence = !bUseCadence;
- sCapabFlags.ucCadence = (UCHAR) this->checkBox_P3Cadence->Checked;
- if (sCapabFlags.ucCadence == 1) // if latency is selected
- {
- ucCapabFlags |= SDM_CADENCE_MASK; // set the bit to 1
- this->label_P22Cadence->ForeColor = System::Drawing::Color::Green;
- }
- else // distance not selected
- {
- ucCapabFlags &= ~SDM_CADENCE_MASK; // set the bit to 0
- this->label_P22Cadence->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::numericUpDown_Sim_StrideLength_ValueChanged
- *
- * Updates stride length when modified in UI
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::numericUpDown_Sim_StrideLength_ValueChanged(System::Object^ sender, System::EventArgs^ e)
- {
- ucStrideLength = System::Convert::ToByte(this->numericUpDown_Sim_StrideLength->Value);
- usMaxSpeed256 = CadenceToSpeed(usMaxCadence16); // update the speed since it is based on stride length
- usMinSpeed256 = CadenceToSpeed(usMinCadence16);
- usCurSpeed256 = CadenceToSpeed(usCurCadence16);
- }
- /**************************************************************************
- * SDMSensor::numericUpDown_Sim_BurnRate_ValueChanged
- *
- * Updates Calories Burn Rate when modified in UI
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::numericUpDown_Sim_BurnRate_ValueChanged(System::Object^ sender, System::EventArgs^ e)
- {
- ucCalorieRate = System::Convert::ToByte(this->numericUpDown_Sim_BurnRate->Value);
- }
- /**************************************************************************
- * SDMSensor::listBox_P2Location_SelectedIndexChanged
- *
- * Updates location field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P2Location_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucLocation = (UCHAR) this->listBox_P2Location->SelectedIndex;
- ucStatusFlags &= ~SDM_LOCATION_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucLocation << SDM_LOCATION_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P2Battery_SelectedIndexChanged
- *
- * Updates battery status field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P2Battery_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucBatteryStatus = (UCHAR) this->listBox_P2Battery->SelectedIndex;
- ucStatusFlags &= ~SDM_BAT_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucBatteryStatus << SDM_BAT_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P2Health_SelectedIndexChanged
- *
- * Updates health field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P2Health_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucHealth = (UCHAR) this->listBox_P2Health->SelectedIndex;
- ucStatusFlags &= ~SDM_HEALTH_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucHealth << SDM_HEALTH_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P2Use_SelectedIndexChanged
- *
- * Updates use state field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P2Use_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucUseState = (UCHAR) this->listBox_P2Use->SelectedIndex;
- ucStatusFlags &= ~SDM_STATE_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucUseState << SDM_STATE_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P3Location_SelectedIndexChanged
- *
- * Updates location field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P3Location_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucLocation = (UCHAR) this->listBox_P3Location->SelectedIndex;
- ucStatusFlags &= ~SDM_LOCATION_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucLocation << SDM_LOCATION_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P3Battery_SelectedIndexChanged
- *
- * Updates battery status field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P3Battery_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucBatteryStatus = (UCHAR) this->listBox_P3Battery->SelectedIndex;
- ucStatusFlags &= ~SDM_BAT_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucBatteryStatus << SDM_BAT_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P3Health_SelectedIndexChanged
- *
- * Updates health field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P3Health_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucHealth = (UCHAR) this->listBox_P3Health->SelectedIndex;
- ucStatusFlags &= ~SDM_HEALTH_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucHealth << SDM_HEALTH_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::listBox_P3Use_SelectedIndexChanged
- *
- * Updates use state field in status flags
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::listBox_P3Use_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
- {
- sStatusFlags.ucUseState = (UCHAR) this->listBox_P3Use->SelectedIndex;
- ucStatusFlags &= ~SDM_STATE_MASK; // Clear previous status
- ucStatusFlags |= (sStatusFlags.ucUseState << SDM_STATE_SHIFT); // Set updated status
- }
- /**************************************************************************
- * SDMSensor::ConvertFromInput
- *
- * Converts from user selected units for speed and cadence to units
- * defined in the device profile
- *
- * decValue_: Value to convert
- *
- * returns: speed (1/256 s) or cadence (strides/min)
- *
- **************************************************************************/
- USHORT SDMSensor::ConvertFromInput(System::Decimal decValue_)
- {
- USHORT usOutput;
- switch(eUnit)
- {
- case SDM_MS:
- usOutput = (USHORT) (256 * decValue_); // Convert speed from m/s to 1/256 m/s
- break;
- case SDM_KPH:
- usOutput = (USHORT) (2560 * decValue_/36); // Convert speed from km/h to 1/256 m/s
- break;
- case SDM_MPH:
- usOutput = (USHORT) (411991 * decValue_/3600); // Convert speed from mi/h to 1/256 m/s
- break;
- case SDM_SPM:
- usOutput = (USHORT) (16 * decValue_); // Convert cadence from spm to 1/16 spm
- break;
- default:
- usOutput = SDM_UNUSED;
- break;
- }
- return usOutput;
- }
- /**************************************************************************
- * SDMSensor::ConvertToInput
- *
- * Converts from units defined in device profile for speed and cadence
- * to the user selected units for display purposes (on text box)
- *
- * usValue_: Value to convert
- *
- * returns: speed or cadence, in selected unit
- *
- **************************************************************************/
- System::Decimal SDMSensor::ConvertToInput(USHORT usValue_)
- {
- System::Decimal decInput;
- switch(eUnit)
- {
- case SDM_MS:
- decInput = System::Convert::ToDecimal(usValue_ /256.0); // Convert speed from 1/256 m/s to m/s
- break;
- case SDM_KPH:
- decInput = System::Convert::ToDecimal(usValue_ * 36/2560.0); // Convert speed from 1/256 m/s to km/h
- break;
- case SDM_MPH:
- decInput = System::Convert::ToDecimal(usValue_ * 3600/411991.0); // Convert speed from 1/256 m/s to mi/h
- break;
- case SDM_SPM:
- decInput = System::Convert::ToDecimal(usValue_/16.0); // Convert cadence from 1/16 spm to spm
- break;
- default:
- decInput = System::Convert::ToDecimal(SDM_UNUSED);
- break;
- }
- return decInput;
- }
- /**************************************************************************
- * SDMSensor::CadenceToSpeed
- *
- * Converts from cadence to speed
- *
- * usCadence16_: Cadence (1/16 rpm)
- *
- * returns: Speed (1/256 m/s)
- *
- **************************************************************************/
- USHORT SDMSensor::CadenceToSpeed(USHORT usCadence16_)
- {
- return (USHORT) (16 * (ULONG) ucStrideLength * (ULONG) usCadence16_ / (ULONG) 6000); // 1/16 spm -> 1/256 m/s (stride length is in cm)
- }
- /**************************************************************************
- * SDMSensor::SpeedToCadence
- *
- * Converts from cadence to speed
- *
- * usCadence16_: Cadence (1/16 rpm)
- *
- * returns: Speed (1/256 m/s)
- *
- **************************************************************************/
- USHORT SDMSensor::SpeedToCadence(USHORT usSpeed256_)
- {
- return (USHORT) ((ULONG) 6000 * usSpeed256_ / (16 * (ULONG) ucStrideLength)); // 1/256 m/s -> 1/16 spm (stride length is in cm)
- }
- /**************************************************************************
- * SDMSensor::ForceUpdate
- *
- * Causes a timer event, to force the simulator to update all calculations
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::ForceUpdate()
- {
- timerHandle->Interval = 250;
- }
- /**************************************************************************
- * SDMSensor::checkBox_Page2_CheckedChanged
- *
- * Select whether to include Page 2 in transmission (Page 1 is always on)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_Page2_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_Page2->Checked) // If checked, Enable Page 2, Disable Page 3
- {
- Page2_Enable();
- Page3_Disable();
- this->checkBox_Page3->Checked = FALSE;
- }
- else // If not checked, Disable Page 2
- {
- Page2_Disable();
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_Page3_CheckedChanged
- *
- * Select whether to include Page 3 in transmission
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_Page3_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- // Calories capability dependent on whether Page 3 is on, so store that capability
- sCapabFlags.ucCalories = (UCHAR) this->checkBox_Page3->Checked;
- if(this->checkBox_Page3->Checked) // If checked, Enable Page 3, Disable Page 2
- {
- Page3_Enable();
- Page2_Disable();
- this->checkBox_Page2->Checked = FALSE;
-
- ucCapabFlags |= SDM_CALORIES_MASK; // set the bit to 1
- this->label_P22Calories->ForeColor = System::Drawing::Color::Green;
- }
- else // If not checked, Disable Page 3
- {
- Page3_Disable();
- ucCapabFlags &= ~SDM_CALORIES_MASK; // set the bit to 0
- this->label_P22Calories->ForeColor = System::Drawing::Color::Red;
- }
- }
- /**************************************************************************
- * SDMSensor::Page2_Enable
- *
- * Enables Page 2 GUI
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::Page2_Enable()
- {
- this->listBox_P2Battery->Enabled = TRUE;
- this->listBox_P2Health->Enabled = TRUE;
- this->listBox_P2Location->Enabled = TRUE;
- this->listBox_P2Use->Enabled = TRUE;
- this->checkBox_P2Cadence->Enabled = TRUE;
- this->checkBox_P2InstSpeed->Enabled = TRUE;
- // synchronize Instant Speed and Flags in case anything was changed while the page was disabled
- this->checkBox_P2InstSpeed->Checked = this->checkBox_P1InstSpeed->Checked;
- this->listBox_P2Location->SelectedIndex = (int) sStatusFlags.ucLocation;
- this->listBox_P2Battery->SelectedIndex = (int) sStatusFlags.ucBatteryStatus;
- this->listBox_P2Health->SelectedIndex = (int) sStatusFlags.ucHealth;
- this->listBox_P2Use->SelectedIndex = (int) sStatusFlags.ucUseState;
- bTxPage2 = TRUE;
- }
- /**************************************************************************
- * SDMSensor::Page2_Disable
- *
- * Disables Page 2 GUI
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::Page2_Disable()
- {
- //this->label_TransCadence->ForeColor = System::Drawing::SystemColors::GrayText;
- //this->label_TransCadenceDisplay->ForeColor = System::Drawing::SystemColors::GrayText;
- this->listBox_P2Battery->Enabled = FALSE;
- this->listBox_P2Health->Enabled = FALSE;
- this->listBox_P2Location->Enabled = FALSE;
- this->listBox_P2Use->Enabled = FALSE;
- this->checkBox_P2Cadence->Enabled = FALSE;
- this->checkBox_P2InstSpeed->Enabled = FALSE;
- bTxPage2 = FALSE;
- }
- /**************************************************************************
- * SDMSensor::Page3_Enable
- *
- * Enables Page 3 GUI
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::Page3_Enable()
- {
- this->listBox_P3Battery->Enabled = TRUE;
- this->listBox_P3Health->Enabled = TRUE;
- this->listBox_P3Location->Enabled = TRUE;
- this->listBox_P3Use->Enabled = TRUE;
- this->checkBox_P3Cadence->Enabled = TRUE;
- this->checkBox_P3InstSpeed->Enabled = TRUE;
- this->textBox_P3Calories->Enabled = TRUE;
- this->button_P3UpdateCalories->Enabled = TRUE;
- this->label_P3CalDisplay->Enabled = TRUE;
- // synchronize Instant Speed and Flags in case anything was changed while the page was disabled
- this->checkBox_P3InstSpeed->Checked = this->checkBox_P1InstSpeed->Checked;
- this->listBox_P3Location->SelectedIndex = (int) sStatusFlags.ucLocation;
- this->listBox_P3Battery->SelectedIndex = (int) sStatusFlags.ucBatteryStatus;
- this->listBox_P3Health->SelectedIndex = (int) sStatusFlags.ucHealth;
- this->listBox_P3Use->SelectedIndex = (int) sStatusFlags.ucUseState;
- bTxPage3 = TRUE;
- }
- /**************************************************************************
- * SDMSensor::Page3_Disable
- *
- * Disables Page 3 GUI
- *
- * returns: N/A
- *
- **************************************************************************/
- void SDMSensor::Page3_Disable()
- {
- this->listBox_P3Battery->Enabled = FALSE;
- this->listBox_P3Health->Enabled = FALSE;
- this->listBox_P3Location->Enabled = FALSE;
- this->listBox_P3Use->Enabled = FALSE;
- this->checkBox_P3Cadence->Enabled = FALSE;
- this->checkBox_P3InstSpeed->Enabled = FALSE;
- this->textBox_P3Calories->Enabled = FALSE;
- this->button_P3UpdateCalories->Enabled = FALSE;
- this->label_P3CalDisplay->Enabled = FALSE;
- bTxPage3 = FALSE;
- }
- /**************************************************************************
- * SDMSensor::checkBox_P22Enabled_CheckedChanged
- *
- * Select whether to allow Pagge 22 to be requestable
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P22Enabled_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_P22Enabled->Checked) // If checked, Enable
- {
- bTxPage22 = TRUE;
- // disable UI
- this->checkBox_P22Ignore->Enabled = TRUE;
- this->groupBox_P22Supported->Enabled = TRUE;
- }
- else // If not checked, Disable
- {
- bTxPage22 = FALSE;
- // enable UI
- this->checkBox_P22Ignore->Enabled = FALSE;
- this->groupBox_P22Supported->Enabled = FALSE;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P22Ignore_CheckedChanged
- *
- * The device profile allows for sensors to ignore a Page 22 (Capabilities) Request
- * if the device supports all fields. This allows the user to either use this feature or not.
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P22Ignore_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_P22Ignore->Checked) // If checked, Enable
- {
- bP22Ignore = TRUE;
- }
- else // If not checked, Disable
- {
- bP22Ignore = FALSE;
- }
- }
- /**************************************************************************
- * SDMSensor::checkBox_P16Enabled_CheckedChanged
- *
- * Select whether to allow Pagge 16 to be requestable
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::checkBox_P16Enabled_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_P16Enabled->Checked) // If checked, Enable
- {
- bTxPage16 = TRUE;
- // disable UI
- this->label_P16Strides->Enabled = TRUE;
- this->label_P16Distance->Enabled = TRUE;
- this->label_P16StridesDisplay->Enabled = TRUE;
- this->label_P16DistanceDisplay->Enabled = TRUE;
- this->label_P16_UnitsDist->Enabled = TRUE;
- this->button_P16UpdateStrides->Enabled = TRUE;
- this->button_P16UpdateDistance->Enabled = TRUE;
- this->textBox_P16StridesDisplayChange->Enabled = TRUE;
- this->textBox_P16DistDisplayChange->Enabled = TRUE;
- }
- else // If not checked, Disable
- {
- bTxPage16 = FALSE;
- // enable UI
- this->label_P16Strides->Enabled = FALSE;
- this->label_P16Distance->Enabled = FALSE;
- this->label_P16StridesDisplay->Enabled = FALSE;
- this->label_P16DistanceDisplay->Enabled = FALSE;
- this->label_P16_UnitsDist->Enabled = FALSE;
- this->button_P16UpdateStrides->Enabled = FALSE;
- this->button_P16UpdateDistance->Enabled = FALSE;
- this->textBox_P16StridesDisplayChange->Enabled = FALSE;
- this->textBox_P16DistDisplayChange->Enabled = FALSE;
- }
- }
- /**************************************************************************
- * SDMSensor::button_P3UpdateCalories_Click
- *
- * Validates and updates cumulative Calories on Page 3, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::button_P3UpdateCalories_Click(System::Object^ sender, System::EventArgs^ e)
- {
- //convert and catch failed conversions
- try{
- ucCalorieCount = System::Convert::ToByte(this->textBox_P3Calories->Text);
- this->label_P3CalDisplay->Text = this->textBox_P3Calories->Text;
- ulTempCalories = ucCalorieCount * 1000 * 16;
- }
- catch(...){
- MessageBox::Show("Invalid Input. Please enter a value from 0 to 255.", "Error", MessageBoxButtons::OK,MessageBoxIcon::Error, MessageBoxDefaultButton::Button1);
- }
- }
- /**************************************************************************
- * SDMSensor::button_P16UpdateStrides_Click
- *
- * Validates and updates accumulated strides, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::button_P16UpdateStrides_Click(System::Object^ sender, System::EventArgs^ e)
- {
- this->label_P16UpdateError->Visible = false;
- //convert and catch failed conversions
- try{
- ulStridesAccum = System::Convert::ToUInt32(this->textBox_P16StridesDisplayChange->Text);
- if (ulStridesAccum >= 16777216)
- {
- ulStridesAccum = 16777215;
- this->label_P16StridesDisplay->Text = "16777215";
- }
- else
- this->label_P16StridesDisplay->Text = this->textBox_P16StridesDisplayChange->Text;
- }
- catch(...){
- this->label_P16UpdateError->Text = "Error: Stride";
- this->label_P16UpdateError->Visible = true;
- }
- }
- /**************************************************************************
- * SDMSensor::button_P16UpdateDistance_Click
- *
- * Validates and updates accumlated distance, from user input (GUI)
- *
- * returns: N/A
- *
- **************************************************************************/
- System::Void SDMSensor::button_P16UpdateDistance_Click(System::Object^ sender, System::EventArgs^ e)
- {
- this->label_P16UpdateError->Visible = false;
- //convert and catch failed conversions
- try{
- ulDistanceAccum = System::Convert::ToUInt32(this->textBox_P16DistDisplayChange->Text);
- this->label_P16DistanceDisplay->Text = this->textBox_P16DistDisplayChange->Text;
- }
- catch(...){
- this->label_P16UpdateError->Text = "Error: Dist";
- this->label_P16UpdateError->Visible = true;
- }
- }
- System::Void SDMSensor::checkBox_InvalidSerial_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
- {
- if(this->checkBox_InvalidSerial->Checked)
- this->textBox_SerialNum->Enabled = false;
- else
- this->textBox_SerialNum->Enabled = true;
- }
|