Skip to content

Commit e3052c2

Browse files
committed
Initial Gear UI Commit
1 parent dfd1449 commit e3052c2

File tree

6 files changed

+120
-12
lines changed

6 files changed

+120
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Added CSC Service to BLE server.
1515
- Added Yosuda-007C.
1616
- Updated wiki banner.
17+
- Added support for the Zwift gear display.
1718

1819
### Changed
1920

include/BLE_Common.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77

88
#pragma once
99

10-
// #define CONFIG_SW_COEXIST_ENABLE 1
11-
12-
#include <memory>
1310
#include <NimBLEDevice.h>
11+
#include <memory>
1412
#include <Arduino.h>
1513
#include <queue>
1614
#include <deque>
@@ -44,12 +42,6 @@ class MyServerCallbacks : public NimBLEServerCallbacks {
4442
bool onConnParamsUpdateRequest(NimBLEClient *pClient, const ble_gap_upd_params *params);
4543
};
4644

47-
class MyCallbacks : public NimBLECharacteristicCallbacks {
48-
public:
49-
void onWrite(BLECharacteristic *);
50-
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue);
51-
};
52-
5345
// TODO add the rest of the server to this class
5446
class SpinBLEServer {
5547
private:
@@ -72,6 +64,12 @@ class SpinBLEServer {
7264
SpinBLEServer() { memset(&clientSubscribed, 0, sizeof(clientSubscribed)); }
7365
};
7466

67+
class MyCallbacks : public NimBLECharacteristicCallbacks {
68+
public:
69+
void onWrite(BLECharacteristic *);
70+
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue);
71+
};
72+
7573
extern SpinBLEServer spinBLEServer;
7674

7775
void startBLEServer();
@@ -199,4 +197,4 @@ class MyClientCallback : public NimBLEClientCallbacks {
199197
void onAuthenticationComplete(ble_gap_conn_desc);
200198
};
201199

202-
extern SpinBLEClient spinBLEClient;
200+
extern SpinBLEClient spinBLEClient;

include/BLE_Wattbike_Service.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (C) 2020 Anthony Doud & Joel Baranick
3+
* All rights reserved
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-only
6+
*/
7+
8+
#pragma once
9+
10+
#include <NimBLEDevice.h>
11+
12+
class BLE_Wattbike_Service {
13+
public:
14+
BLE_Wattbike_Service();
15+
void setupService(NimBLEServer *pServer);
16+
void update();
17+
void parseNemit();
18+
19+
private:
20+
NimBLEService *pWattbikeService;
21+
NimBLECharacteristic *wattbikeReadCharacteristic;
22+
NimBLECharacteristic *wattbikeWriteCharacteristic;
23+
};

lib/SS2K/include/Constants.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@
5959
#define FITNESSMACHINEPOWERRANGE_UUID NimBLEUUID((uint16_t)0x2AD8)
6060
#define FITNESSMACHINEINCLINATIONRANGE_UUID NimBLEUUID((uint16_t)0x2AD5)
6161

62+
// Wattbike Service
63+
#define WATTBIKE_SERVICE_UUID NimBLEUUID("b4cc1223-bc02-4cae-adb9-1217ad2860d1")
64+
#define WATTBIKE_READ_UUID NimBLEUUID("b4cc1224-bc02-4cae-adb9-1217ad2860d1")
65+
#define WATTBIKE_WRITE_UUID NimBLEUUID("b4cc1225-bc02-4cae-adb9-1217ad2860d1")
66+
6267
// GATT service/characteristic UUIDs for Flywheel Bike from ptx2/gymnasticon/
6368
#define FLYWHEEL_UART_SERVICE_UUID NimBLEUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e")
6469
#define FLYWHEEL_UART_RX_UUID NimBLEUUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")

src/BLE_Server.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "BLE_Fitness_Machine_Service.h"
1515
#include "BLE_Custom_Characteristic.h"
1616
#include "BLE_Device_Information_Service.h"
17+
#include "BLE_Wattbike_Service.h"
1718

1819
#include <ArduinoJson.h>
1920
#include <Constants.h>
@@ -32,6 +33,7 @@ BLE_Heart_Service heartService;
3233
BLE_Fitness_Machine_Service fitnessMachineService;
3334
BLE_ss2kCustomCharacteristic ss2kCustomCharacteristic;
3435
BLE_Device_Information_Service deviceInformationService;
36+
BLE_Wattbike_Service wattbikeService;
3537

3638
void startBLEServer() {
3739
// Server Setup
@@ -46,7 +48,8 @@ void startBLEServer() {
4648
fitnessMachineService.setupService(spinBLEServer.pServer, &chrCallbacks);
4749
ss2kCustomCharacteristic.setupService(spinBLEServer.pServer);
4850
deviceInformationService.setupService(spinBLEServer.pServer);
49-
51+
wattbikeService.setupService(spinBLEServer.pServer); // No callback needed
52+
5053
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
5154
// const std::string fitnessData = {0b00000001, 0b00100000, 0b00000000};
5255
// pAdvertising->setServiceData(FITNESSMACHINESERVICE_UUID, fitnessData);
@@ -56,6 +59,7 @@ void startBLEServer() {
5659
pAdvertising->addServiceUUID(CSCSERVICE_UUID);
5760
pAdvertising->addServiceUUID(HEARTSERVICE_UUID);
5861
pAdvertising->addServiceUUID(SMARTSPIN2K_SERVICE_UUID);
62+
pAdvertising->addServiceUUID(WATTBIKE_SERVICE_UUID);
5963
pAdvertising->setMaxInterval(250);
6064
pAdvertising->setMinInterval(160);
6165
pAdvertising->setScanResponse(true);
@@ -74,6 +78,7 @@ void SpinBLEServer::update() {
7478
cyclingPowerService.update();
7579
cyclingSpeedCadenceService.update();
7680
fitnessMachineService.update();
81+
wattbikeService.parseNemit(); // Changed from update() to parseNemit()
7782
}
7883

7984
double SpinBLEServer::calculateSpeed() {
@@ -182,7 +187,7 @@ void MyCallbacks::onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_con
182187
SS2K_LOG(BLE_SERVER_LOG_TAG, "%s", str.c_str());
183188
}
184189

185-
//This might be worth depreciating. With multiple clients connected (SS2k App, + Training App), it at least needs to be an int, not a bool.
190+
// This might be worth depreciating. With multiple clients connected (SS2k App, + Training App), it at least needs to be an int, not a bool.
186191
void SpinBLEServer::setClientSubscribed(NimBLEUUID pUUID, bool subscribe) {
187192
if (pUUID == HEARTCHARACTERISTIC_UUID) {
188193
spinBLEServer.clientSubscribed.Heartrate = subscribe;

src/BLE_Wattbike_Service.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (C) 2020 Anthony Doud & Joel Baranick
3+
* All rights reserved
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-only
6+
*/
7+
8+
#include "BLE_Wattbike_Service.h"
9+
#include "BLE_Common.h"
10+
#include <Constants.h>
11+
12+
BLE_Wattbike_Service::BLE_Wattbike_Service() : pWattbikeService(nullptr), wattbikeReadCharacteristic(nullptr), wattbikeWriteCharacteristic(nullptr) {}
13+
14+
void BLE_Wattbike_Service::setupService(NimBLEServer *pServer) {
15+
// Create Wattbike service
16+
pWattbikeService = spinBLEServer.pServer->createService(WATTBIKE_SERVICE_UUID);
17+
18+
// Create characteristic for gear notifications
19+
wattbikeReadCharacteristic = pWattbikeService->createCharacteristic(WATTBIKE_READ_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
20+
21+
// Create characteristic for receiving commands
22+
wattbikeWriteCharacteristic = pWattbikeService->createCharacteristic(WATTBIKE_WRITE_UUID, NIMBLE_PROPERTY::WRITE);
23+
24+
// Start the service
25+
pWattbikeService->start();
26+
}
27+
28+
void BLE_Wattbike_Service::parseNemit() {
29+
static int lastGear = -1; // Track last gear position
30+
static unsigned long lastNotifyTime = 0; // Track last notification time
31+
const unsigned long NOTIFY_INTERVAL = 30000; // 30 seconds in milliseconds
32+
33+
// Get current shifter position
34+
int currentGear = rtConfig->getShifterPosition();
35+
if (currentGear < 1) { // Ensure gear is at least 1
36+
currentGear = 1;
37+
}
38+
39+
unsigned long currentTime = millis();
40+
41+
// Only call update if gear changed or 30 seconds elapsed
42+
if (currentGear != lastGear || (currentTime - lastNotifyTime) >= NOTIFY_INTERVAL) {
43+
update(); // Call existing update function to handle notification
44+
45+
// Update tracking variables
46+
lastGear = currentGear;
47+
lastNotifyTime = currentTime;
48+
}
49+
}
50+
51+
void BLE_Wattbike_Service::update() {
52+
// Get current shifter position
53+
int currentGear = rtConfig->getShifterPosition();
54+
if (currentGear < 1) { // Ensure gear is at least 1
55+
currentGear = 1;
56+
}
57+
58+
// Create gear data packet with sequence number and fixed value
59+
static uint8_t seq = 0;
60+
++seq;
61+
62+
uint8_t gearData[4];
63+
gearData[0] = seq; // Sequence number
64+
gearData[1] = 0x03; // Fixed value
65+
gearData[2] = 0xB6; // Fixed value
66+
gearData[3] = (byte)currentGear; // Gear value
67+
68+
// Update the characteristic
69+
wattbikeReadCharacteristic->setValue(gearData, sizeof(gearData));
70+
wattbikeReadCharacteristic->notify();
71+
72+
// Log the update
73+
const int kLogBufCapacity = 100;
74+
char logBuf[kLogBufCapacity];
75+
logCharacteristic(logBuf, kLogBufCapacity, gearData, sizeof(gearData), WATTBIKE_SERVICE_UUID, wattbikeReadCharacteristic->getUUID(), "Wattbike Gear[ %d ]", currentGear);
76+
}

0 commit comments

Comments
 (0)