Skip to content

Commit 2e344bc

Browse files
authored
Merge pull request #632 from matthewshirley/correct-characteristic-size-for-cycling-services
Correct Cycling Power And CSC Feature Characteristics
2 parents 35850e6 + 0276a8a commit 2e344bc

File tree

6 files changed

+60
-7
lines changed

6 files changed

+60
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
### Changed
13+
- Fixed flags in CPS and CSC which were causing issues in GTA Bike. Thanks @matthewsshirley !
1314

1415
### Hardware
1516

include/BLE_Cycling_Power_Service.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ class BLE_Cycling_Power_Service {
2121
BLECharacteristic *cyclingPowerMeasurementCharacteristic;
2222
BLECharacteristic *cyclingPowerFeatureCharacteristic;
2323
BLECharacteristic *sensorLocationCharacteristic;
24-
};
24+
byte cpFeature[4] = {0, 0, 0, 0};
25+
};

include/BLE_Cycling_Speed_Cadence.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ class BLE_Cycling_Speed_Cadence {
2121
BLECharacteristic *cscMeasurement;
2222
BLECharacteristic *cscFeature;
2323
BLECharacteristic *cscControlPoint;
24+
byte cscFeatureBytes[2] = {0, 0};
2425
};

include/BLE_Definitions.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct FitnessMachineIndoorBikeDataFlags {
1212
enum Types : uint16_t {
1313
MoreDataBit = 1U << 0,
1414
AverageSpeedPresent = 1U << 1,
15-
InstantaneousCadencePresent = 1U << 2,
15+
InstantaneousCadencePresent = 1U << 2,
1616
AverageCadencePresent = 1U << 3,
1717
TotalDistancePresent = 1U << 4,
1818
ResistanceLevelPresent = 1U << 5,
@@ -191,6 +191,27 @@ struct FtmsStatus {
191191
int length;
192192
};
193193

194+
// https://www.bluetooth.com/specifications/specs/cpp-1-1-html/
195+
// See "4.4. Cycling Power Feature"
196+
struct CyclingPowerFeatureFlags {
197+
enum Types : uint32_t {
198+
PedalPowerBalanceSupported = 1U << 0,
199+
AccumulatedTorqueSupported = 1U << 1,
200+
WheelRevolutionDataSupported = 1U << 2,
201+
CrankRevolutionDataSupported = 1U << 3,
202+
ExtremeMagnitudesSupported = 1U << 4,
203+
ExtremesAnglesSupported = 1U << 5,
204+
TopBottomDeadSpotAnglesSupported = 1U << 6,
205+
AccumulatedEnergySupported = 1U << 7,
206+
ExtremeTorquesSupported = 1U << 8,
207+
OffsetCompensationIndicatorSupported = 1U << 9,
208+
};
209+
};
210+
211+
inline CyclingPowerFeatureFlags::Types operator|(CyclingPowerFeatureFlags::Types a, CyclingPowerFeatureFlags::Types b) {
212+
return static_cast<CyclingPowerFeatureFlags::Types>(static_cast<int>(a) | static_cast<int>(b));
213+
}
214+
194215
class CyclingPowerMeasurement {
195216
public:
196217
// Flags definition as per specification
@@ -256,6 +277,21 @@ class CyclingPowerMeasurement {
256277
}
257278
};
258279

280+
// https://www.bluetooth.com/specifications/specs/cscs-1-0/
281+
// See "3.2. CSC Feature"
282+
struct CyclingSpeedCadenceFeatureFlags {
283+
enum Types : uint16_t {
284+
WheelRevolutionDataSupported = 1U << 0,
285+
CrankRevolutionDataSupported = 1U << 1,
286+
MultipleSensorLocationsSupported = 1U << 2
287+
// 3-15: Reserved for Future Use
288+
};
289+
};
290+
291+
inline CyclingSpeedCadenceFeatureFlags::Types operator|(CyclingSpeedCadenceFeatureFlags::Types a, CyclingSpeedCadenceFeatureFlags::Types b) {
292+
return static_cast<CyclingSpeedCadenceFeatureFlags::Types>(static_cast<int>(a) | static_cast<int>(b));
293+
}
294+
259295
class CscMeasurement {
260296
public:
261297
// Flags definition as per specification
@@ -305,4 +341,4 @@ class CscMeasurement {
305341

306342
return data;
307343
}
308-
};
344+
};

src/BLE_Cycling_Power_Service.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,15 @@ void BLE_Cycling_Power_Service::setupService(NimBLEServer *pServer, MyCallbacks
1616
cyclingPowerFeatureCharacteristic = pPowerMonitor->createCharacteristic(CYCLINGPOWERFEATURE_UUID, NIMBLE_PROPERTY::READ);
1717
sensorLocationCharacteristic = pPowerMonitor->createCharacteristic(SENSORLOCATION_UUID, NIMBLE_PROPERTY::READ);
1818
byte cpsLocation[1] = {0b0101}; // sensor location 5 == left crank
19-
byte cpFeature[1] = {0b001100}; // crank information & wheel revolution data present
19+
20+
CyclingPowerFeatureFlags::Types cpFeatureFlags = CyclingPowerFeatureFlags::WheelRevolutionDataSupported |
21+
CyclingPowerFeatureFlags::CrankRevolutionDataSupported;
22+
23+
cpFeature[0] = static_cast<uint8_t>(cpFeatureFlags & 0xFF);
24+
cpFeature[1] = static_cast<uint8_t>((cpFeatureFlags >> 8) & 0xFF);
25+
cpFeature[2] = static_cast<uint8_t>((cpFeatureFlags >> 16) & 0xFF);
26+
cpFeature[3] = static_cast<uint8_t>((cpFeatureFlags >> 24) & 0xFF);
27+
2028
cyclingPowerFeatureCharacteristic->setValue(cpFeature, sizeof(cpFeature));
2129
sensorLocationCharacteristic->setValue(cpsLocation, sizeof(cpsLocation));
2230
cyclingPowerMeasurementCharacteristic->setCallbacks(chrCallbacks);
@@ -57,4 +65,4 @@ void BLE_Cycling_Power_Service::update() {
5765

5866
logCharacteristic(logBuf, kLogBufCapacity, &byteArray[0], byteArrayLength, CYCLINGPOWERSERVICE_UUID, cyclingPowerMeasurementCharacteristic->getUUID(),
5967
"CPS(CPM)[ CD(%.2f) PW(%d) ]", cadence > 0 ? fmodf(cadence, 1000.0) : 0, power % 10000);
60-
}
68+
}

src/BLE_Cycling_Speed_Cadence.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ void BLE_Cycling_Speed_Cadence::setupService(NimBLEServer *pServer, MyCallbacks
1414
pCyclingSpeedCadenceService = pServer->createService(CSCSERVICE_UUID);
1515
cscMeasurement = pCyclingSpeedCadenceService->createCharacteristic(CSCMEASUREMENT_UUID, NIMBLE_PROPERTY::NOTIFY);
1616
cscFeature = pCyclingSpeedCadenceService->createCharacteristic(CSCFEATURE_UUID, NIMBLE_PROPERTY::READ);
17-
byte cscFeatureFlags[1] = {0b11};
18-
cscFeature->setValue(cscFeatureFlags, sizeof(cscFeatureFlags));
17+
18+
CyclingSpeedCadenceFeatureFlags::Types cscFeatureFlags = CyclingSpeedCadenceFeatureFlags::WheelRevolutionDataSupported |
19+
CyclingSpeedCadenceFeatureFlags::CrankRevolutionDataSupported;
20+
21+
cscFeatureBytes[0] = static_cast<uint8_t>(cscFeatureFlags & 0xFF);
22+
cscFeatureBytes[1] = static_cast<uint8_t>((cscFeatureFlags >> 8) & 0xFF);
23+
24+
cscFeature->setValue(cscFeatureBytes, sizeof(cscFeatureBytes));
1925
cscMeasurement->setCallbacks(chrCallbacks);
2026
pCyclingSpeedCadenceService->start();
2127
}

0 commit comments

Comments
 (0)