Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions inc/sp140/ble/ble_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,9 @@

// BMS service
#define BMS_TELEMETRY_SERVICE_UUID "9E0F2FA3-3F2B-49C0-A6A3-3D8923062133"
#define BMS_SOC_UUID "ACDEB138-3BD0-4BB3-B159-19F6F70871ED"
#define BMS_VOLTAGE_UUID "AC0768DF-2F49-43D4-B23D-1DC82C90A9E9"
#define BMS_CURRENT_UUID "6FEEC926-BA3C-4E65-BC71-5DB481811186"
#define BMS_POWER_UUID "9DEA1343-434F-4555-A0A1-BB43FCBC68A6"
#define BMS_HIGH_CELL_UUID "49267B41-560F-4CFF-ADC8-90EF85D2BE20"
#define BMS_LOW_CELL_UUID "B9D01E5C-3751-4092-8B06-6D1FFF479E77"
#define BMS_HIGH_TEMP_UUID "0EA08B6D-C905-4D9D-93F8-51E35DA096FC"
#define BMS_LOW_TEMP_UUID "26CD6E8A-175D-4C8E-B487-DEFF0B034F2A"
#define BMS_FAILURE_LEVEL_UUID "396C768B-F348-44CC-9D46-92388F25A557"
#define BMS_VOLTAGE_DIFF_UUID "1C45825B-7C81-430B-8D5F-B644FFFC71BB"
#define BMS_CHARGE_MOS_UUID "4D0C3E4D-E7E2-41EF-8DDD-38C4B0948F9E"
#define BMS_DISCHARGE_MOS_UUID "175A2989-3442-4B69-9C84-0CE4F1BD4F4F"
#define BMS_CELL_VOLTAGES_UUID "4337e58b-8462-49b2-b061-c3bf379ef4af"
#define BMS_TEMPERATURES_UUID "C53898C0-C10D-435B-8B5D-B46A2E06EB53"

// ESC service
#define ESC_TELEMETRY_SERVICE_UUID "C154DAE9-1984-40EA-B20F-5B23F9CBA0A9"
#define ESC_VOLTAGE_UUID "0528ecd8-9337-4249-95e4-9aba69f6c1f4"
#define ESC_CURRENT_UUID "3889e01e-7d2d-4478-b5cc-a06b803e2788"
#define ESC_RPM_UUID "24dc4a84-0be3-4eba-a8c3-ed9748daa599"
#define ESC_TEMPS_UUID "d087f190-5450-4fea-b9ff-17133a0b6f64"

// ============================================================================
// Binary Packed Telemetry Characteristics (V1)
Expand Down
3 changes: 0 additions & 3 deletions inc/sp140/ble/bms_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ class NimBLEServer;

void initBmsBleService(NimBLEServer* server);

// Legacy individual characteristic updates (can be disabled with DISABLE_LEGACY_BLE_TELEMETRY)
void updateBMSTelemetry(const STR_BMS_TELEMETRY_140& telemetry);

// Binary packed telemetry update (V1 protocol)
// bms_id: 0-3 for multi-BMS support
void updateBMSPackedTelemetry(const STR_BMS_TELEMETRY_140& telemetry, uint8_t bms_id = 0);
Expand Down
3 changes: 0 additions & 3 deletions inc/sp140/ble/esc_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ class NimBLEServer;

void initEscBleService(NimBLEServer* server);

// Legacy individual characteristic updates (can be disabled with DISABLE_LEGACY_BLE_TELEMETRY)
void updateESCTelemetryBLE(const STR_ESC_TELEMETRY_140& telemetry);

// Binary packed telemetry update (V1 protocol)
void updateESCPackedTelemetry(const STR_ESC_TELEMETRY_140& telemetry);

Expand Down
2 changes: 0 additions & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ build_flags =
-D LV_CONF_INCLUDE_SIMPLE
-I inc/sp140/lvgl
-D LV_LVGL_H_INCLUDE_SIMPLE
; Disable legacy individual BLE characteristics (use packed binary only)
-D DISABLE_LEGACY_BLE_TELEMETRY

build_type = debug
debug_speed = 12000
Expand Down
173 changes: 0 additions & 173 deletions src/sp140/ble/bms_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "sp140/ble.h"
#include "sp140/ble/ble_ids.h"
#include "sp140/ble/ble_utils.h"

namespace {

Expand All @@ -13,29 +12,6 @@ NimBLEService* pBmsService = nullptr;
// Binary packed telemetry characteristic (V1)
NimBLECharacteristic* pBMSPackedTelemetry = nullptr;

#ifndef DISABLE_LEGACY_BLE_TELEMETRY
// Legacy individual characteristics
NimBLECharacteristic* pBMSSOC = nullptr;
NimBLECharacteristic* pBMSVoltage = nullptr;
NimBLECharacteristic* pBMSCurrent = nullptr;
NimBLECharacteristic* pBMSPower = nullptr;
NimBLECharacteristic* pBMSHighCell = nullptr;
NimBLECharacteristic* pBMSLowCell = nullptr;
NimBLECharacteristic* pBMSHighTemp = nullptr;
NimBLECharacteristic* pBMSLowTemp = nullptr;
NimBLECharacteristic* pBMSFailureLevel = nullptr;
NimBLECharacteristic* pBMSVoltageDiff = nullptr;
NimBLECharacteristic* pBMSCellVoltages = nullptr;
NimBLECharacteristic* pBMSChargeMos = nullptr;
NimBLECharacteristic* pBMSDischargeMos = nullptr;
NimBLECharacteristic* pBMSTemperatures = nullptr;

// Track previous values to only notify on change
uint8_t lastFailureLevel = 0;
uint8_t lastChargeMos = 0;
uint8_t lastDischargeMos = 0;
#endif // DISABLE_LEGACY_BLE_TELEMETRY

} // namespace

void initBmsBleService(NimBLEServer* server) {
Expand All @@ -58,66 +34,6 @@ void initBmsBleService(NimBLEServer* server) {
reinterpret_cast<uint8_t*>(&initialPacket),
sizeof(BLE_BMS_Telemetry_V1));

#ifndef DISABLE_LEGACY_BLE_TELEMETRY
// Legacy individual characteristics
pBMSSOC = pBmsService->createCharacteristic(
NimBLEUUID(BMS_SOC_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSVoltage = pBmsService->createCharacteristic(
NimBLEUUID(BMS_VOLTAGE_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSCurrent = pBmsService->createCharacteristic(
NimBLEUUID(BMS_CURRENT_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSPower = pBmsService->createCharacteristic(
NimBLEUUID(BMS_POWER_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSHighCell = pBmsService->createCharacteristic(
NimBLEUUID(BMS_HIGH_CELL_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSLowCell = pBmsService->createCharacteristic(
NimBLEUUID(BMS_LOW_CELL_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSHighTemp = pBmsService->createCharacteristic(
NimBLEUUID(BMS_HIGH_TEMP_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSLowTemp = pBmsService->createCharacteristic(
NimBLEUUID(BMS_LOW_TEMP_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSFailureLevel = pBmsService->createCharacteristic(
NimBLEUUID(BMS_FAILURE_LEVEL_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSVoltageDiff = pBmsService->createCharacteristic(
NimBLEUUID(BMS_VOLTAGE_DIFF_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSCellVoltages = pBmsService->createCharacteristic(
NimBLEUUID(BMS_CELL_VOLTAGES_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSChargeMos = pBmsService->createCharacteristic(
NimBLEUUID(BMS_CHARGE_MOS_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSDischargeMos = pBmsService->createCharacteristic(
NimBLEUUID(BMS_DISCHARGE_MOS_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pBMSTemperatures = pBmsService->createCharacteristic(
NimBLEUUID(BMS_TEMPERATURES_UUID),
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

// Ensure characteristics have deterministic startup values.
uint16_t initial_cell_values[BMS_CELLS_NUM] = {0};
pBMSCellVoltages->setValue(
reinterpret_cast<uint8_t*>(initial_cell_values),
BMS_CELLS_NUM * sizeof(uint16_t));

uint8_t initial_flag = 0;
pBMSChargeMos->setValue(&initial_flag, sizeof(initial_flag));
pBMSDischargeMos->setValue(&initial_flag, sizeof(initial_flag));

uint8_t initial_temps[17] = {0};
initial_temps[0] = 0x00; // No valid sensors initially (bitmap = 0x00)
pBMSTemperatures->setValue(initial_temps, 17);
#endif // DISABLE_LEGACY_BLE_TELEMETRY

pBmsService->start();
}

Expand Down Expand Up @@ -156,92 +72,3 @@ void updateBMSPackedTelemetry(const STR_BMS_TELEMETRY_140& telemetry, uint8_t bm
pBMSPackedTelemetry->notify();
}
}

#ifndef DISABLE_LEGACY_BLE_TELEMETRY
// Legacy individual characteristic updates
void updateBMSTelemetry(const STR_BMS_TELEMETRY_140& telemetry) {
if (pBmsService == nullptr) {
return; // Not initialized yet.
}

float soc = telemetry.soc;
float voltage = telemetry.battery_voltage;
float current = telemetry.battery_current;
float power = telemetry.power;
float highCell = telemetry.highest_cell_voltage;
float lowCell = telemetry.lowest_cell_voltage;
float highTemp = telemetry.highest_temperature;
float lowTemp = telemetry.lowest_temperature;
float voltageDiff = telemetry.voltage_differential;

if (pBMSSOC) pBMSSOC->setValue(soc);
if (pBMSVoltage) pBMSVoltage->setValue(voltage);
if (pBMSCurrent) pBMSCurrent->setValue(current);
if (pBMSPower) pBMSPower->setValue(power);
if (pBMSHighCell) pBMSHighCell->setValue(highCell);
if (pBMSLowCell) pBMSLowCell->setValue(lowCell);
if (pBMSHighTemp) pBMSHighTemp->setValue(highTemp);
if (pBMSLowTemp) pBMSLowTemp->setValue(lowTemp);
if (pBMSVoltageDiff) pBMSVoltageDiff->setValue(voltageDiff);

if (pBMSCellVoltages) {
uint16_t cell_millivolts[BMS_CELLS_NUM];
for (uint8_t i = 0; i < BMS_CELLS_NUM; i++) {
cell_millivolts[i] = static_cast<uint16_t>(telemetry.cell_voltages[i] * 1000.0f);
}
pBMSCellVoltages->setValue(
reinterpret_cast<uint8_t*>(cell_millivolts),
BMS_CELLS_NUM * sizeof(uint16_t));
}

// Update temperatures characteristic
// Format (17 bytes): bitmap(1) + 8×int16_t temperatures (deci-degrees C)
// Sensor mapping: [0]=MOS, [1]=Balance, [2]=T1, [3]=T2, [4]=T3, [5]=T4, [6-7]=Reserved
if (pBMSTemperatures) {
uint8_t temp_buffer[17];

// Byte 0: Valid sensor bitmap (bit N = sensor N is valid)
// 0b00111111 = sensors 0-5 valid (6 temperature sensors)
temp_buffer[0] = 0b00111111;

// Bytes 1-16: 8×int16_t temperatures in deci-degrees C (0.1°C resolution)
int16_t* temps = reinterpret_cast<int16_t*>(&temp_buffer[1]);
temps[0] = static_cast<int16_t>(telemetry.mos_temperature * 10.0f); // [0] MOS
temps[1] = static_cast<int16_t>(telemetry.balance_temperature * 10.0f); // [1] Balance
temps[2] = static_cast<int16_t>(telemetry.t1_temperature * 10.0f); // [2] T1
temps[3] = static_cast<int16_t>(telemetry.t2_temperature * 10.0f); // [3] T2
temps[4] = static_cast<int16_t>(telemetry.t3_temperature * 10.0f); // [4] T3
temps[5] = static_cast<int16_t>(telemetry.t4_temperature * 10.0f); // [5] T4
temps[6] = 0; // [6] Reserved
temps[7] = 0; // [7] Reserved

pBMSTemperatures->setValue(temp_buffer, 17);
}

// Handle state-change characteristics - only notify on change
setAndNotifyOnChange(pBMSFailureLevel, telemetry.battery_fail_level, lastFailureLevel);
setAndNotifyOnChange(pBMSChargeMos, static_cast<uint8_t>(telemetry.is_charge_mos ? 1 : 0), lastChargeMos);
setAndNotifyOnChange(pBMSDischargeMos, static_cast<uint8_t>(telemetry.is_discharge_mos ? 1 : 0), lastDischargeMos);

if (!deviceConnected) {
return; // No notifications needed without a subscriber.
}

if (pBMSSOC) pBMSSOC->notify();
if (pBMSVoltage) pBMSVoltage->notify();
if (pBMSCurrent) pBMSCurrent->notify();
if (pBMSPower) pBMSPower->notify();
if (pBMSHighCell) pBMSHighCell->notify();
if (pBMSLowCell) pBMSLowCell->notify();
if (pBMSHighTemp) pBMSHighTemp->notify();
if (pBMSLowTemp) pBMSLowTemp->notify();
if (pBMSVoltageDiff) pBMSVoltageDiff->notify();
if (pBMSTemperatures) pBMSTemperatures->notify();
// Note: pBMSFailureLevel, pBMSChargeMos, pBMSDischargeMos notify separately above, only on change
}
#else
// Stub when legacy telemetry is disabled
void updateBMSTelemetry(const STR_BMS_TELEMETRY_140& telemetry) {
(void)telemetry; // Suppress unused parameter warning
}
#endif // DISABLE_LEGACY_BLE_TELEMETRY
81 changes: 0 additions & 81 deletions src/sp140/ble/esc_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@ NimBLEService* pEscService = nullptr;
// Binary packed telemetry characteristic (V1)
NimBLECharacteristic* pESCPackedTelemetry = nullptr;

#ifndef DISABLE_LEGACY_BLE_TELEMETRY
// Legacy individual characteristics
NimBLECharacteristic* pESCVoltage = nullptr;
NimBLECharacteristic* pESCCurrent = nullptr;
NimBLECharacteristic* pESCRPM = nullptr;
NimBLECharacteristic* pESCTemps = nullptr;

struct EscTempsPacket {
float mos_temp;
float cap_temp;
float mcu_temp;
float motor_temp;
};
#endif // DISABLE_LEGACY_BLE_TELEMETRY

} // namespace

void initEscBleService(NimBLEServer* server) {
Expand All @@ -48,33 +33,6 @@ void initEscBleService(NimBLEServer* server) {
reinterpret_cast<uint8_t*>(&initialPacket),
sizeof(BLE_ESC_Telemetry_V1));

#ifndef DISABLE_LEGACY_BLE_TELEMETRY
// Legacy individual characteristics
pESCVoltage = pEscService->createCharacteristic(
NimBLEUUID(ESC_VOLTAGE_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pESCCurrent = pEscService->createCharacteristic(
NimBLEUUID(ESC_CURRENT_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pESCRPM = pEscService->createCharacteristic(
NimBLEUUID(ESC_RPM_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

pESCTemps = pEscService->createCharacteristic(
NimBLEUUID(ESC_TEMPS_UUID), NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);

// Ensure deterministic startup values.
float initialFloat = 0.0f;
int32_t initialRpm = 0;

if (pESCVoltage) pESCVoltage->setValue(initialFloat);
if (pESCCurrent) pESCCurrent->setValue(initialFloat);
if (pESCRPM) pESCRPM->setValue(initialRpm);
if (pESCTemps) {
EscTempsPacket temps = {0.0f, 0.0f, 0.0f, 0.0f};
pESCTemps->setValue(reinterpret_cast<uint8_t*>(&temps), sizeof(temps));
}
#endif // DISABLE_LEGACY_BLE_TELEMETRY

pEscService->start();
}

Expand Down Expand Up @@ -108,42 +66,3 @@ void updateESCPackedTelemetry(const STR_ESC_TELEMETRY_140& telemetry) {
pESCPackedTelemetry->notify();
}
}

#ifndef DISABLE_LEGACY_BLE_TELEMETRY
// Legacy individual characteristic updates
void updateESCTelemetryBLE(const STR_ESC_TELEMETRY_140& telemetry) {
if (pEscService == nullptr) {
return;
}

float voltage = telemetry.volts;
float current = telemetry.amps;
int32_t rpm = static_cast<int32_t>(telemetry.eRPM);
// motor_temp is NaN when sensor is disconnected/invalid.
EscTempsPacket temps = {
telemetry.mos_temp,
telemetry.cap_temp,
telemetry.mcu_temp,
telemetry.motor_temp
};

if (pESCVoltage) pESCVoltage->setValue(voltage);
if (pESCCurrent) pESCCurrent->setValue(current);
if (pESCRPM) pESCRPM->setValue(rpm);
if (pESCTemps) pESCTemps->setValue(reinterpret_cast<uint8_t*>(&temps), sizeof(temps));

if (!deviceConnected) {
return; // No notifications needed without a subscriber.
}

if (pESCVoltage) pESCVoltage->notify();
if (pESCCurrent) pESCCurrent->notify();
if (pESCRPM) pESCRPM->notify();
if (pESCTemps) pESCTemps->notify();
}
#else
// Stub when legacy telemetry is disabled
void updateESCTelemetryBLE(const STR_ESC_TELEMETRY_140& telemetry) {
(void)telemetry; // Suppress unused parameter warning
}
#endif // DISABLE_LEGACY_BLE_TELEMETRY
6 changes: 0 additions & 6 deletions src/sp140/sp140.ino
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,6 @@ void updateBLETask(void *pvParameters) {
// Update packed binary telemetry (always enabled)
updateBMSPackedTelemetry(newBmsTelemetry, 0); // bms_id=0 for primary BMS

// Update legacy BLE characteristics (can be disabled with DISABLE_LEGACY_BLE_TELEMETRY)
updateBMSTelemetry(newBmsTelemetry);

// Update controller telemetry at same 10Hz rate as BMS
// Gather sensor data from barometer and ESP32
float altitude = getAltitude(deviceData);
Expand Down Expand Up @@ -1234,9 +1231,6 @@ void updateESCBLETask(void *pvParameters) {
updateESCPackedTelemetry(newEscTelemetry);
lastPackedUpdateMs = now;
}

// Update legacy BLE characteristics (can be disabled with DISABLE_LEGACY_BLE_TELEMETRY)
updateESCTelemetryBLE(newEscTelemetry);
}

// Add a small delay to prevent task starvation
Expand Down