Skip to content

Commit e575208

Browse files
committed
Refactor BLE services into dedicated modules
Moved BLE service and characteristic definitions from extra-data.ino into separate header and source files under inc/sp140/ble and src/sp140/ble. This modularizes BLE functionality for BMS, ESC, and configuration services, improving code organization and maintainability. Updated sp140.ino to include new BLE headers and removed legacy BLE code from extra-data.ino.
1 parent 67a2f3a commit e575208

File tree

11 files changed

+646
-573
lines changed

11 files changed

+646
-573
lines changed

inc/sp140/ble/ble_core.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef INC_SP140_BLE_BLE_CORE_H_
2+
#define INC_SP140_BLE_BLE_CORE_H_
3+
4+
// Core BLE helpers for initializing and maintaining the server.
5+
6+
void setupBLE();
7+
8+
// Allow modules to trigger advertising after disconnects.
9+
void restartBLEAdvertising();
10+
11+
#endif // INC_SP140_BLE_BLE_CORE_H_

inc/sp140/ble/ble_ids.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef INC_SP140_BLE_BLE_IDS_H_
2+
#define INC_SP140_BLE_BLE_IDS_H_
3+
4+
// Shared BLE UUID definitions. Keeping macros to match existing style.
5+
6+
// Configuration service
7+
#define CONFIG_SERVICE_UUID "1779A55B-DEB8-4482-A5D1-A12E62146138"
8+
#define METRIC_ALT_UUID "DF63F19E-7295-4A44-A0DC-184D1AFEDDF7"
9+
#define ARMED_TIME_UUID "58B29259-43EF-4593-B700-250EC839A2B2"
10+
#define SCREEN_ROTATION_UUID "9CBAB736-3705-4ECF-8086-FB7C5FB86282"
11+
#define SEA_PRESSURE_UUID "DB47E20E-D8C1-405A-971A-DA0A2DF7E0F6"
12+
#define METRIC_TEMP_UUID "D4962473-A3FB-4754-AD6A-90B079C3FB38"
13+
#define PERFORMANCE_MODE_UUID "D76C2E92-3547-4F5F-AFB4-515C5C08B06B"
14+
#define THEME_UUID "AD0E4309-1EB2-461A-B36C-697B2E1604D2"
15+
#define HW_REVISION_UUID "2A27"
16+
#define FW_VERSION_UUID "2A26"
17+
#define UNIX_TIME_UUID "E09FF0B7-5D02-4FD5-889E-C4251A58D9E7"
18+
#define TIMEZONE_UUID "CAE49D1A-7C21-4B0C-8520-416F3EF69DB1"
19+
#define THROTTLE_VALUE_UUID "50AB3859-9FBF-4D30-BF97-2516EE632FAD"
20+
#define DEVICE_STATE_UUID "8F80BCF5-B58F-4908-B079-E8AD6F5EE257"
21+
22+
// Device info service
23+
#define DEVICE_INFO_SERVICE_UUID "180A"
24+
#define MANUFACTURER_NAME_UUID "2A29"
25+
26+
// BMS service
27+
#define BMS_TELEMETRY_SERVICE_UUID "9E0F2FA3-3F2B-49C0-A6A3-3D8923062133"
28+
#define BMS_SOC_UUID "ACDEB138-3BD0-4BB3-B159-19F6F70871ED"
29+
#define BMS_VOLTAGE_UUID "AC0768DF-2F49-43D4-B23D-1DC82C90A9E9"
30+
#define BMS_CURRENT_UUID "6FEEC926-BA3C-4E65-BC71-5DB481811186"
31+
#define BMS_POWER_UUID "9DEA1343-434F-4555-A0A1-BB43FCBC68A6"
32+
#define BMS_HIGH_CELL_UUID "49267B41-560F-4CFF-ADC8-90EF85D2BE20"
33+
#define BMS_LOW_CELL_UUID "B9D01E5C-3751-4092-8B06-6D1FFF479E77"
34+
#define BMS_HIGH_TEMP_UUID "0EA08B6D-C905-4D9D-93F8-51E35DA096FC"
35+
#define BMS_LOW_TEMP_UUID "26CD6E8A-175D-4C8E-B487-DEFF0B034F2A"
36+
#define BMS_FAILURE_LEVEL_UUID "396C768B-F348-44CC-9D46-92388F25A557"
37+
#define BMS_VOLTAGE_DIFF_UUID "1C45825B-7C81-430B-8D5F-B644FFFC71BB"
38+
#define BMS_CHARGE_MOS_UUID "4D0C3E4D-E7E2-41EF-8DDD-38C4B0948F9E"
39+
#define BMS_DISCHARGE_MOS_UUID "175A2989-3442-4B69-9C84-0CE4F1BD4F4F"
40+
#define BMS_CELL_VOLTAGES_UUID "4337e58b-8462-49b2-b061-c3bf379ef4af"
41+
42+
// ESC service
43+
#define ESC_TELEMETRY_SERVICE_UUID "C154DAE9-1984-40EA-B20F-5B23F9CBA0A9"
44+
#define ESC_VOLTAGE_UUID "0528ecd8-9337-4249-95e4-9aba69f6c1f4"
45+
#define ESC_CURRENT_UUID "3889e01e-7d2d-4478-b5cc-a06b803e2788"
46+
#define ESC_RPM_UUID "24dc4a84-0be3-4eba-a8c3-ed9748daa599"
47+
#define ESC_TEMPS_UUID "d087f190-5450-4fea-b9ff-17133a0b6f64"
48+
49+
#endif // INC_SP140_BLE_BLE_IDS_H_

inc/sp140/ble/bms_service.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef INC_SP140_BLE_BMS_SERVICE_H_
2+
#define INC_SP140_BLE_BMS_SERVICE_H_
3+
4+
#include "sp140/structs.h"
5+
6+
class BLEServer;
7+
8+
void initBmsBleService(BLEServer* server);
9+
void updateBMSTelemetry(const STR_BMS_TELEMETRY_140& telemetry);
10+
11+
#endif // INC_SP140_BLE_BMS_SERVICE_H_

inc/sp140/ble/config_service.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef INC_SP140_BLE_CONFIG_SERVICE_H_
2+
#define INC_SP140_BLE_CONFIG_SERVICE_H_
3+
4+
class BLEServer;
5+
6+
void initConfigBleService(BLEServer* server);
7+
void updateThrottleBLE(int value);
8+
9+
#endif // INC_SP140_BLE_CONFIG_SERVICE_H_

inc/sp140/ble/esc_service.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef INC_SP140_BLE_ESC_SERVICE_H_
2+
#define INC_SP140_BLE_ESC_SERVICE_H_
3+
4+
#include "sp140/structs.h"
5+
6+
class BLEServer;
7+
8+
void initEscBleService(BLEServer* server);
9+
void updateESCTelemetryBLE(const STR_ESC_TELEMETRY_140& telemetry);
10+
11+
#endif // INC_SP140_BLE_ESC_SERVICE_H_

src/sp140/ble/ble_core.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "sp140/ble/ble_core.h"
2+
3+
#include <Arduino.h>
4+
5+
#include "sp140/ble.h"
6+
#include "sp140/ble/ble_ids.h"
7+
#include "sp140/ble/bms_service.h"
8+
#include "sp140/ble/config_service.h"
9+
#include "sp140/ble/esc_service.h"
10+
11+
namespace {
12+
13+
class MyServerCallbacks : public BLEServerCallbacks {
14+
void onConnect(BLEServer* server) override {
15+
deviceConnected = true;
16+
USBSerial.println("Device connected");
17+
}
18+
19+
void onDisconnect(BLEServer* server) override {
20+
deviceConnected = false;
21+
USBSerial.println("Device disconnected");
22+
BLEAdvertising* advertising = server->getAdvertising();
23+
advertising->start();
24+
USBSerial.println("Started advertising");
25+
}
26+
};
27+
28+
} // namespace
29+
30+
void setupBLE() {
31+
BLEDevice::init("OpenPPG Controller");
32+
pServer = BLEDevice::createServer();
33+
pServer->setCallbacks(new MyServerCallbacks());
34+
35+
initConfigBleService(pServer);
36+
initBmsBleService(pServer);
37+
initEscBleService(pServer);
38+
39+
BLEAdvertising* advertising = pServer->getAdvertising();
40+
advertising->addServiceUUID(BLEUUID(CONFIG_SERVICE_UUID));
41+
advertising->addServiceUUID(BLEUUID(BMS_TELEMETRY_SERVICE_UUID));
42+
advertising->setScanResponse(false);
43+
advertising->setMinPreferred(0x0);
44+
advertising->start();
45+
46+
USBSerial.println("BLE device ready");
47+
USBSerial.println("Waiting for a client connection...");
48+
}
49+
50+
void restartBLEAdvertising() {
51+
if (pServer == nullptr) {
52+
return;
53+
}
54+
55+
BLEAdvertising* advertising = pServer->getAdvertising();
56+
advertising->start();
57+
}

src/sp140/ble/bms_service.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#include <Arduino.h>
2+
3+
#include "sp140/ble/bms_service.h"
4+
5+
#include "sp140/ble.h"
6+
#include "sp140/ble/ble_ids.h"
7+
8+
namespace {
9+
10+
BLEService* pBmsService = nullptr;
11+
BLECharacteristic* pBMSSOC = nullptr;
12+
BLECharacteristic* pBMSVoltage = nullptr;
13+
BLECharacteristic* pBMSCurrent = nullptr;
14+
BLECharacteristic* pBMSPower = nullptr;
15+
BLECharacteristic* pBMSHighCell = nullptr;
16+
BLECharacteristic* pBMSLowCell = nullptr;
17+
BLECharacteristic* pBMSHighTemp = nullptr;
18+
BLECharacteristic* pBMSLowTemp = nullptr;
19+
BLECharacteristic* pBMSFailureLevel = nullptr;
20+
BLECharacteristic* pBMSVoltageDiff = nullptr;
21+
BLECharacteristic* pBMSCellVoltages = nullptr;
22+
BLECharacteristic* pBMSChargeMos = nullptr;
23+
BLECharacteristic* pBMSDischargeMos = nullptr;
24+
25+
} // namespace
26+
27+
void initBmsBleService(BLEServer* server) {
28+
// Lazily guard against repeated init calls.
29+
if (pBmsService != nullptr) {
30+
return;
31+
}
32+
33+
pBmsService = server->createService(BLEUUID(BMS_TELEMETRY_SERVICE_UUID), 30);
34+
35+
pBMSSOC = pBmsService->createCharacteristic(
36+
BLEUUID(BMS_SOC_UUID), BLECharacteristic::PROPERTY_READ);
37+
38+
pBMSVoltage = pBmsService->createCharacteristic(
39+
BLEUUID(BMS_VOLTAGE_UUID), BLECharacteristic::PROPERTY_READ);
40+
41+
pBMSCurrent = pBmsService->createCharacteristic(
42+
BLEUUID(BMS_CURRENT_UUID), BLECharacteristic::PROPERTY_READ);
43+
44+
pBMSPower = pBmsService->createCharacteristic(
45+
BLEUUID(BMS_POWER_UUID), BLECharacteristic::PROPERTY_READ);
46+
47+
pBMSHighCell = pBmsService->createCharacteristic(
48+
BLEUUID(BMS_HIGH_CELL_UUID), BLECharacteristic::PROPERTY_READ);
49+
50+
pBMSLowCell = pBmsService->createCharacteristic(
51+
BLEUUID(BMS_LOW_CELL_UUID), BLECharacteristic::PROPERTY_READ);
52+
53+
pBMSHighTemp = pBmsService->createCharacteristic(
54+
BLEUUID(BMS_HIGH_TEMP_UUID), BLECharacteristic::PROPERTY_READ);
55+
56+
pBMSLowTemp = pBmsService->createCharacteristic(
57+
BLEUUID(BMS_LOW_TEMP_UUID), BLECharacteristic::PROPERTY_READ);
58+
59+
pBMSFailureLevel = pBmsService->createCharacteristic(
60+
BLEUUID(BMS_FAILURE_LEVEL_UUID), BLECharacteristic::PROPERTY_READ);
61+
62+
pBMSVoltageDiff = pBmsService->createCharacteristic(
63+
BLEUUID(BMS_VOLTAGE_DIFF_UUID), BLECharacteristic::PROPERTY_READ);
64+
65+
pBMSCellVoltages = pBmsService->createCharacteristic(
66+
BLEUUID(BMS_CELL_VOLTAGES_UUID), BLECharacteristic::PROPERTY_READ);
67+
68+
pBMSChargeMos = pBmsService->createCharacteristic(
69+
BLEUUID(BMS_CHARGE_MOS_UUID), BLECharacteristic::PROPERTY_READ);
70+
71+
pBMSDischargeMos = pBmsService->createCharacteristic(
72+
BLEUUID(BMS_DISCHARGE_MOS_UUID), BLECharacteristic::PROPERTY_READ);
73+
74+
// Ensure characteristics have deterministic startup values.
75+
uint16_t initial_cell_values[BMS_CELLS_NUM] = {0};
76+
pBMSCellVoltages->setValue(
77+
reinterpret_cast<uint8_t*>(initial_cell_values),
78+
BMS_CELLS_NUM * sizeof(uint16_t));
79+
80+
uint8_t initial_flag = 0;
81+
pBMSChargeMos->setValue(&initial_flag, sizeof(initial_flag));
82+
pBMSDischargeMos->setValue(&initial_flag, sizeof(initial_flag));
83+
84+
pBmsService->start();
85+
}
86+
87+
void updateBMSTelemetry(const STR_BMS_TELEMETRY_140& telemetry) {
88+
if (pBmsService == nullptr) {
89+
return; // Not initialized yet.
90+
}
91+
92+
float soc = telemetry.soc;
93+
float voltage = telemetry.battery_voltage;
94+
float current = telemetry.battery_current;
95+
float power = telemetry.power;
96+
float highCell = telemetry.highest_cell_voltage;
97+
float lowCell = telemetry.lowest_cell_voltage;
98+
float highTemp = telemetry.highest_temperature;
99+
float lowTemp = telemetry.lowest_temperature;
100+
float voltageDiff = telemetry.voltage_differential;
101+
102+
if (pBMSSOC) pBMSSOC->setValue(soc);
103+
if (pBMSVoltage) pBMSVoltage->setValue(voltage);
104+
if (pBMSCurrent) pBMSCurrent->setValue(current);
105+
if (pBMSPower) pBMSPower->setValue(power);
106+
if (pBMSHighCell) pBMSHighCell->setValue(highCell);
107+
if (pBMSLowCell) pBMSLowCell->setValue(lowCell);
108+
if (pBMSHighTemp) pBMSHighTemp->setValue(highTemp);
109+
if (pBMSLowTemp) pBMSLowTemp->setValue(lowTemp);
110+
if (pBMSFailureLevel) {
111+
uint8_t failureLevel = telemetry.battery_failure_level;
112+
pBMSFailureLevel->setValue(&failureLevel, sizeof(failureLevel));
113+
}
114+
if (pBMSVoltageDiff) pBMSVoltageDiff->setValue(voltageDiff);
115+
116+
if (pBMSChargeMos) {
117+
uint8_t chargeMos = telemetry.is_charge_mos ? 1 : 0;
118+
pBMSChargeMos->setValue(&chargeMos, sizeof(chargeMos));
119+
}
120+
121+
if (pBMSDischargeMos) {
122+
uint8_t dischargeMos = telemetry.is_discharge_mos ? 1 : 0;
123+
pBMSDischargeMos->setValue(&dischargeMos, sizeof(dischargeMos));
124+
}
125+
126+
if (pBMSCellVoltages) {
127+
uint16_t cell_millivolts[BMS_CELLS_NUM];
128+
for (uint8_t i = 0; i < BMS_CELLS_NUM; i++) {
129+
cell_millivolts[i] = static_cast<uint16_t>(telemetry.cell_voltages[i] * 1000.0f);
130+
}
131+
pBMSCellVoltages->setValue(
132+
reinterpret_cast<uint8_t*>(cell_millivolts),
133+
BMS_CELLS_NUM * sizeof(uint16_t));
134+
}
135+
136+
if (!deviceConnected) {
137+
return; // No notifications needed without a subscriber.
138+
}
139+
140+
if (pBMSSOC) pBMSSOC->notify();
141+
if (pBMSVoltage) pBMSVoltage->notify();
142+
if (pBMSCurrent) pBMSCurrent->notify();
143+
if (pBMSPower) pBMSPower->notify();
144+
if (pBMSHighCell) pBMSHighCell->notify();
145+
if (pBMSLowCell) pBMSLowCell->notify();
146+
if (pBMSHighTemp) pBMSHighTemp->notify();
147+
if (pBMSLowTemp) pBMSLowTemp->notify();
148+
if (pBMSFailureLevel) pBMSFailureLevel->notify();
149+
if (pBMSVoltageDiff) pBMSVoltageDiff->notify();
150+
if (pBMSChargeMos) pBMSChargeMos->notify();
151+
if (pBMSDischargeMos) pBMSDischargeMos->notify();
152+
}

0 commit comments

Comments
 (0)