Add tempe ANT sensor support (#4595)

Fixes #4234
This commit is contained in:
Ivor Hewitt
2025-01-20 13:51:48 +00:00
committed by GitHub
parent d18f24c03f
commit aee21447a0
11 changed files with 64 additions and 2 deletions

View File

@@ -72,6 +72,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_TEMPE, ANT_SPORT_TEMPE_PERIOD, ANT_SPORT_TEMPE_TYPE,
ANT_SPORT_FREQUENCY, ANT_SPORT_NETWORK_NUMBER, "Tempe", 't', ":images/IconTemp.png" },
{ false, ANTChannel::CHANNEL_TYPE_GUARD, 0, 0, 0, 0, "", '\0', "" }
};
@@ -231,6 +233,11 @@ void ANT::setHb(double smo2, double thb)
telemetry.setHb(smo2, thb);
}
void ANT::setTemp(double temp)
{
telemetry.setTemp(temp);
}
/*======================================================================
* Main thread functions; start, stop etc
*====================================================================*/

View File

@@ -251,6 +251,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_TEMPE_PERIOD 8192
#define ANT_SPORT_HR_TYPE 0x78
#define ANT_SPORT_POWER_TYPE 11
@@ -265,6 +266,7 @@ struct setChannelAtom {
#define ANT_FAST_QUARQ_TYPE_WAS 11 // before release 1.8
#define ANT_FAST_QUARQ_TYPE 0x60
#define ANT_QUARQ_TYPE 0x60
#define ANT_SPORT_TEMPE_TYPE 0x19
#define ANT_SPORT_FREQUENCY 57
#define ANT_FOOTPOD_FREQUENCY 57
@@ -722,6 +724,8 @@ public:
void setTrainerReady(bool status) { telemetry.setTrainerReady(status); }
void setTrainerRunning(bool status) { telemetry.setTrainerRunning(status); }
void setTemp(double temp);
qint64 getElapsedTime();
private:

View File

@@ -1242,6 +1242,13 @@ void ANTChannel::broadcastEvent(unsigned char *ant_message)
}
break;
case CHANNEL_TYPE_TEMPE:
{
if (antMessage.tempValid)
parent->setTemp(antMessage.temp/100.0);
}
break;
default:
break; // unknown?
}

View File

@@ -147,6 +147,7 @@ class ANTChannel : public QObject {
CHANNEL_TYPE_CONTROL,
CHANNEL_TYPE_TACX_VORTEX,
CHANNEL_TYPE_FITNESS_EQUIPMENT,
CHANNEL_TYPE_TEMPE,
CHANNEL_TYPE_GUARD
};
typedef enum channeltype ChannelType;

View File

@@ -809,6 +809,17 @@ ANTMessage::ANTMessage(ANT *parent, const unsigned char *message) {
}
break;
case ANTChannel::CHANNEL_TYPE_TEMPE:
{
if (data_page == 1){
uint16_t val = message[10] | (message[11]<<8);
if (val != 0x8000)
tempValid = true;
temp = val;
}
}
break;
default:
break;
}
@@ -934,6 +945,8 @@ void ANTMessage::init()
fpodInstant = false;
fpodSpeed=fpodCadence=0;
fpodStrides=0;
tempValid = false;
temp=0;
}
ANTMessage ANTMessage::resetSystem()

View File

@@ -207,6 +207,10 @@ class ANTMessage {
uint8_t fpodStrides;
double fpodSpeed, fpodCadence;
// tempe
bool tempValid;
uint16_t temp;
private:
void init();
};

View File

@@ -540,6 +540,10 @@ DialWindow::telemetryUpdate(const RealtimeData &rtData)
valueLabel->setText(QString("%1").arg(value, 0, 'f', 2));
break;
case RealtimeData::Temp:
valueLabel->setText(QString("%1").arg(value, 0, 'f', 2));
break;
default:
valueLabel->setText(QString("%1").arg(round(displayValue)));
break;

View File

@@ -521,6 +521,9 @@ double RealtimeData::value(DataSeries series) const
case FeO2: return feo2;
break;
case Temp: return temp;
break;
case None:
default:
return 0;
@@ -593,6 +596,7 @@ const QList<RealtimeData::DataSeries> &RealtimeData::listDataSeries()
seriesList << Altitude;
seriesList << RouteDistance;
seriesList << DistanceRemaining;
seriesList << Temp;
}
return seriesList;
}
@@ -781,6 +785,9 @@ QString RealtimeData::seriesName(DataSeries series)
case FeO2: return tr("Fraction O2 Expired");
break;
case Temp: return tr("Temperature");
break;
}
}
@@ -868,3 +875,7 @@ double RealtimeData::getVCO2() const { return vco2; }
double RealtimeData::getRER() const { return rer; }
double RealtimeData::getTv() const { return tv; }
double RealtimeData::getFeO2() const { return feo2; }
void RealtimeData::setTemp(double temp) { this->temp = temp; }
double RealtimeData::getTemp() const { return temp; }

View File

@@ -54,7 +54,8 @@ public:
DistanceRemaining,
RightPowerPhaseBegin, RightPowerPhaseEnd,
RightPowerPhasePeakBegin, RightPowerPhasePeakEnd,
Position, RightPCO, LeftPCO };
Position, RightPCO, LeftPCO,
Temp };
typedef enum dataseries DataSeries;
@@ -197,6 +198,9 @@ public:
bool getTrainerConfigRequired() const;
bool getTrainerBrakeFault() const;
void setTemp(double temp);
double getTemp() const;
uint8_t spinScan[24];
private:
@@ -215,6 +219,7 @@ private:
double latitude, longitude, altitude;
double vo2, vco2, rf, rmv, tv, feo2;
RealtimeData::riderPosition position;
double temp;
std::chrono::high_resolution_clock::time_point wheelRpmSampleTime;

View File

@@ -395,6 +395,7 @@ TrainSidebar::TrainSidebar(Context *context) : GcWindow(context), context(contex
mode = ErgFileFormat::erg;
pendingConfigChange = false;
displayTemp = 0;
displayWorkoutLap = 0;
pwrcount = 0;
cadcount = 0;
@@ -1674,6 +1675,7 @@ void TrainSidebar::Stop(int deviceStatus) // when stop button is pressed
hrcount = 0;
spdcount = 0;
lodcount = 0;
displayTemp = 0;
displayWorkoutLap = 0;
wbalr = 0;
wbal = WPRIME;
@@ -1724,6 +1726,7 @@ void TrainSidebar::updateData(RealtimeData &rtData)
displayLpppb = rtData.getLpppb();
displayLpppe = rtData.getLpppe();
displayPosition = rtData.getPosition();
displayTemp = rtData.getTemp();
// Gradient not supported
return;
}
@@ -1913,6 +1916,7 @@ void TrainSidebar::guiUpdate() // refreshes the telemetry
if (Devices[dev].type == DEV_ANTLOCAL || Devices[dev].type == DEV_NULL) {
rtData.setHb(local.getSmO2(), local.gettHb()); //only moxy data from ant and robot devices right now
rtData.setTemp(local.getTemp());
}
if (Devices[dev].type == DEV_NULL || Devices[dev].type == DEV_BT40) {
@@ -2163,6 +2167,7 @@ void TrainSidebar::guiUpdate() // refreshes the telemetry
displayLpppb = rtData.getLpppb();
displayLpppe = rtData.getLpppe();
displayPosition = rtData.getPosition();
displayTemp = rtData.getTemp();
double weightKG = bicycle.MassKG();
double vs = computeInstantSpeed(weightKG, rtData.getSlope(), rtData.getAltitude(), rtData.getWatts());
@@ -2309,7 +2314,7 @@ void TrainSidebar::diskUpdate()
recordFileStream << "," // headwind
<< "," << slopeStr
<< "," // temp
<< "," << displayTemp
<< "," << displayWorkoutLap
<< "," << displayLRBalance
<< "," << displayLTE

View File

@@ -277,6 +277,7 @@ class TrainSidebar : public GcWindow
double displayRppb, displayRppe, displayRpppb, displayRpppe;
double displayLppb, displayLppe, displayLpppb, displayLpppe;
RealtimeData::riderPosition displayPosition; // rider position (seated = 0, transistionToSeated = 1, standing = 2, transitionToStanding=3, aero = 10, off = 11)
double displayTemp;
void maintainLapDistanceState();