Created
February 16, 2016 20:51
-
-
Save ihewitt/6f89405bf3e0d8a216f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/ANT.cpp b/src/ANT.cpp | |
index e23f0bf..39316d2 100644 | |
--- a/src/ANT.cpp | |
+++ b/src/ANT.cpp | |
@@ -69,6 +69,8 @@ const ant_sensor_type_t ANT::ant_sensor_types[] = { | |
ANT_TACX_VORTEX_FREQUENCY, DEFAULT_NETWORK_NUMBER, "Tacx Vortex Smart", 'v', ":images/IconPower.png" }, | |
{ true, ANTChannel::CHANNEL_TYPE_FITNESS_EQUIPMENT, ANT_SPORT_FITNESS_EQUIPMENT_PERIOD, ANT_SPORT_FITNESS_EQUIPMENT_TYPE, | |
ANT_FITNESS_EQUIPMENT_FREQUENCY, ANT_SPORT_NETWORK_NUMBER, "Fitness Equipment Control (FE-C)", 'f', ":images/IconPower.png" }, | |
+ { true, ANTChannel::CHANNEL_TYPE_QUBO_DIGITAL, ANT_SPORT_QUBO_PERIOD, ANT_SPORT_SandC_TYPE, | |
+ ANT_SPORT_FREQUENCY, ANT_SPORT_NETWORK_NUMBER, "Elite QUBO Digital", 'q', ":images/IconPower.png" }, | |
{ false, ANTChannel::CHANNEL_TYPE_GUARD, 0, 0, 0, 0, "", '\0', "" } | |
}; | |
@@ -108,6 +110,8 @@ ANT::ANT(QObject *parent, DeviceConfiguration *devConf, QString athlete) : QThre | |
fecChannel = -1; | |
+ quboChannel = -1; | |
+ | |
// current and desired modes/load/gradients | |
// set so first time through current != desired | |
currentMode = 0; | |
@@ -297,6 +301,12 @@ ANT::setLoad(double load) | |
{ | |
sendMessage(ANTMessage::fecSetTargetPower(fecChannel, (int)load)); | |
} | |
+ | |
+ // if we have a qubo digital trainer set the target power | |
+ if (quboChannel != -1) | |
+ { | |
+ sendMessage(ANTMessage::quboSetTargetPower(quboChannel, (int)load)); | |
+ } | |
} | |
void ANT::refreshFecLoad() | |
@@ -333,6 +343,13 @@ void ANT::refreshVortexLoad() | |
sendMessage(ANTMessage::tacxVortexSetPower(vortexChannel, vortexID, (int)load)); | |
} | |
+void ANT::refreshQuboLoad() | |
+{ | |
+ if (quboChannel == -1) | |
+ return; | |
+ | |
+ sendMessage(ANTMessage::quboSetTargetPower(quboChannel, (int)load)); | |
+} | |
void | |
ANT::setGradient(double gradient) | |
{ | |
@@ -482,6 +499,7 @@ ANT::setup() | |
addDevice(0, ANTChannel::CHANNEL_TYPE_SandC, 4); | |
addDevice(0, ANTChannel::CHANNEL_TYPE_MOXY, 5); | |
addDevice(0, ANTChannel::CHANNEL_TYPE_FITNESS_EQUIPMENT, 6); | |
+ addDevice(0, ANTChannel::CHANNEL_TYPE_QUBO_DIGITAL, 7); | |
} | |
} | |
} | |
@@ -1290,6 +1308,11 @@ void ANT::setFecChannel(int channel) | |
fecChannel = channel; | |
} | |
+void ANT::setQuboChannel(int channel) | |
+{ | |
+ quboChannel = channel; | |
+} | |
+ | |
void ANT::setControlChannel(int channel) | |
{ | |
controlChannel = channel; | |
diff --git a/src/ANT.h b/src/ANT.h | |
index 880fcba..65cfcb1 100644 | |
--- a/src/ANT.h | |
+++ b/src/ANT.h | |
@@ -242,6 +242,7 @@ struct setChannelAtom { | |
#define ANT_SPORT_FITNESS_EQUIPMENT_PERIOD 8192 | |
#define ANT_FAST_QUARQ_PERIOD (8182/16) | |
#define ANT_QUARQ_PERIOD (8182*4) | |
+#define ANT_SPORT_QUBO_PERIOD 16172 | |
#define ANT_SPORT_HR_TYPE 0x78 | |
#define ANT_SPORT_POWER_TYPE 11 | |
@@ -541,6 +542,9 @@ public: | |
void refreshFecGradient(); | |
void requestFecCapabilities(); | |
+ void setQuboChannel(int channel); | |
+ void refreshQuboLoad(); | |
+ | |
void setVortexData(int channel, int id); | |
void refreshVortexLoad(); | |
@@ -618,6 +622,9 @@ private: | |
int vortexID; | |
int vortexChannel; | |
+ // Qubo digital data | |
+ int quboChannel; | |
+ | |
// remote control data | |
int controlChannel; | |
diff --git a/src/ANTChannel.cpp b/src/ANTChannel.cpp | |
index 356a2bd..37ab066 100644 | |
--- a/src/ANTChannel.cpp | |
+++ b/src/ANTChannel.cpp | |
@@ -709,6 +709,30 @@ void ANTChannel::broadcastEvent(unsigned char *ant_message) | |
} | |
break; | |
+ //QUBO Digital | |
+ case CHANNEL_TYPE_QUBO_DIGITAL: | |
+ { | |
+ static int quboRefreshCounter = 1; | |
+ | |
+ parent->setQuboChannel(number); | |
+ | |
+ if ((quboRefreshCounter++ % 10) == 0) | |
+ { | |
+ parent->refreshQuboLoad(); | |
+ } | |
+ if (antMessage.quboSpeed > 0) | |
+ { | |
+ parent->setSpeed(antMessage.quboSpeed); | |
+ value = antMessage.quboSpeed; | |
+ } | |
+ if (antMessage.quboCadence) | |
+ { | |
+ parent->setSecondaryCadence(antMessage.quboCadence); | |
+ value2 = antMessage.quboCadence; | |
+ } | |
+ } | |
+ break; | |
+ | |
//moxy | |
case CHANNEL_TYPE_MOXY: | |
{ | |
diff --git a/src/ANTChannel.h b/src/ANTChannel.h | |
index 8b48b33..8dd89bc 100644 | |
--- a/src/ANTChannel.h | |
+++ b/src/ANTChannel.h | |
@@ -133,6 +133,7 @@ class ANTChannel : public QObject { | |
CHANNEL_TYPE_CONTROL, | |
CHANNEL_TYPE_TACX_VORTEX, | |
CHANNEL_TYPE_FITNESS_EQUIPMENT, | |
+ CHANNEL_TYPE_QUBO_DIGITAL, | |
CHANNEL_TYPE_GUARD | |
}; | |
typedef enum channeltype ChannelType; | |
diff --git a/src/ANTMessage.cpp b/src/ANTMessage.cpp | |
index 7a4f989..8d7a4a8 100644 | |
--- a/src/ANTMessage.cpp | |
+++ b/src/ANTMessage.cpp | |
@@ -509,6 +509,21 @@ ANTMessage::ANTMessage(ANT *parent, const unsigned char *message) { | |
wheelRevolutions = message[10] + (message[11]<<8); | |
break; | |
+ case ANTChannel::CHANNEL_TYPE_QUBO_DIGITAL: | |
+ channel=message[3]; | |
+ | |
+ quboSpeed = 0.1f * (message[4] & 0xf)+ | |
+ 1 * (message[4] >> 4)+ | |
+ 10 * (message[5] >> 4)+ | |
+ 100 * (message[5] & 0xf); | |
+ | |
+ quboCadence = 1 * (message[8] >> 4)+ | |
+ 10 * (message[9] >> 4)+ | |
+ 100 * (message[9] & 0xf); | |
+ | |
+// dist = (message[6]<<1) + (message[4]<<7); //distance? | |
+ break; | |
+ | |
case ANTChannel::CHANNEL_TYPE_MOXY: | |
channel = message[3]; | |
utcTimeRequired = message[6] & 0x01; | |
@@ -759,6 +774,8 @@ void ANTMessage::init() | |
fecPowerOverLimits = fecState = fecHRSource = 0; | |
fecDistanceCapability = fecSpeedIsVirtual = false; | |
fecEqtType = 0; | |
+ quboSpeed = 0; | |
+ quboCadence = 0.0; | |
} | |
ANTMessage ANTMessage::resetSystem() | |
@@ -1010,6 +1027,14 @@ ANTMessage ANTMessage::fecSetResistance(const uint8_t channel, const uint8_t res | |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, resistance); | |
} | |
+ANTMessage ANTMessage::quboSetResistance(const uint8_t channel, const uint8_t resistance) // 0-200% -> 0-16 | |
+{ | |
+ uint8_t levelValue = resistance * 16 / 200; | |
+ | |
+ return ANTMessage(9, ANT_ACK_DATA, channel, | |
+ 0xFF, 0xFF, levelValue, 0, 0, 0, 0, 1 ); | |
+} | |
+ | |
ANTMessage ANTMessage::fecSetTargetPower(const uint8_t channel, const uint16_t targetPower) | |
{ | |
// unit is 0.25W, but targetPower are full watts and theres no trainer with that precision anyway | |
@@ -1019,6 +1044,13 @@ ANTMessage ANTMessage::fecSetTargetPower(const uint8_t channel, const uint16_t t | |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, (uint8_t)(powerValue & 0xFF), (uint8_t)(powerValue >> 8)); | |
} | |
+ANTMessage ANTMessage::quboSetTargetPower(const uint8_t channel, const uint16_t targetPower) // power in 1W | |
+{ | |
+ return ANTMessage(9, ANT_ACK_DATA, channel, | |
+ (uint8_t)(targetPower & 0xFF), (uint8_t)(targetPower >> 8), | |
+ 0, 0, 0, 0, 0, 1 ); | |
+} | |
+ | |
ANTMessage ANTMessage::fecSetWindResistance(const uint8_t channel, const double windResistance, const uint8_t windSpeed, const uint8_t draftingFactor) | |
// 0.00 < kg/m < 1.86 -127 < kph < + 127 0 < % < 100% | |
{ | |
diff --git a/src/ANTMessage.h b/src/ANTMessage.h | |
index c81c5bb..f80a963 100644 | |
--- a/src/ANTMessage.h | |
+++ b/src/ANTMessage.h | |
@@ -77,6 +77,10 @@ class ANTMessage { | |
static ANTMessage tacxVortexSetCalibrationValue(const uint8_t channel, const uint16_t vortexId, const uint8_t calibrationValue); | |
static ANTMessage tacxVortexSetPower(const uint8_t channel, const uint16_t vortexId, const uint16_t power); | |
+ // QUBO digital control messages | |
+ static ANTMessage quboSetResistance(const uint8_t channel, const uint8_t resistance); | |
+ static ANTMessage quboSetTargetPower(const uint8_t channel, const uint16_t targetPower); | |
+ | |
// fitness equipment control messages | |
static ANTMessage fecSetResistance(const uint8_t channel, const uint8_t resistance); | |
static ANTMessage fecSetTargetPower(const uint8_t channel, const uint16_t targetPower); | |
@@ -175,6 +179,10 @@ class ANTMessage { | |
int8_t fecSetWindSpeedAck; // -127 / +127 km/h | |
uint8_t fecSetDraftingFactorAck; // 0 / 100 % | |
+ // qubo digital | |
+ uint16_t quboCadence; | |
+ double quboSpeed; | |
+ | |
// remote control | |
uint8_t controlSeq; | |
uint16_t controlSerial, controlVendor, controlCmd; | |
diff --git a/src/AddDeviceWizard.cpp b/src/AddDeviceWizard.cpp | |
index ae99e21..dd52400 100644 | |
--- a/src/AddDeviceWizard.cpp | |
+++ b/src/AddDeviceWizard.cpp | |
@@ -686,7 +686,7 @@ AddPair::initializePage() | |
// defaults | |
static const int index4[4] = { 1,2,3,5 }; | |
- static const int index8[8] = { 1,2,3,4,5,6,9,0 }; | |
+ static const int index8[8] = { 1,2,3,4,5,6,9,10 }; | |
const int *index = channels == 4 ? index4 : index8; | |
// how many devices we got then? | |
@@ -815,6 +815,11 @@ AddPair::getChannelValues() | |
.arg(dynamic_cast<ANTlocalController*>(wizard->controller)->myANTlocal->channelValue(i), 0, 'f', 1) // tHb | |
.arg(dynamic_cast<ANTlocalController*>(wizard->controller)->myANTlocal->channelValue2(i), 0, 'f', 1)); // SmO2 | |
+ } else if (p->itemData(p->currentIndex()) == ANTChannel::CHANNEL_TYPE_QUBO_DIGITAL) { | |
+ | |
+ dynamic_cast<QLabel *>(channelWidget->itemWidget(item,2))->setText(QString("%1 %2") | |
+ .arg(dynamic_cast<ANTlocalController*>(wizard->controller)->myANTlocal->channelValue(i),0,'f',1) //speed | |
+ .arg((int)dynamic_cast<ANTlocalController*>(wizard->controller)->myANTlocal->channelValue2(i))); // cad | |
} else { | |
dynamic_cast<QLabel *>(channelWidget->itemWidget(item,2))->setText(QString("%1") | |
.arg((int)dynamic_cast<ANTlocalController*>(wizard->controller)->myANTlocal->channelValue(i))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment