Skip to content

Commit 98dc409

Browse files
committed
BMS: surface per-cell balancing state in cell printouts and CSV
Add an "is balancing" indicator to the cell/temperature readouts: - New accessors in FEB_ADBMS6830B: per-cell discharge getter, active-cell count, pack voltage delta (mV), and a balance-complete flag (valid readings AND delta < slippage threshold). - BMS|cells / cell-stats: mark balancing cells with *BAL plus a footer summary; BMS|status: show cell delta + balance-done. - CSV: append <balancing> to voltage rows; append balance_done + delta_mV to the status row; schema comments updated. - Fix FEB_Stop_Balance leaving stale per-cell discharging flags set (cleared lock-free; reachable from the 1ms SM task).
1 parent a100b41 commit 98dc409

5 files changed

Lines changed: 108 additions & 10 deletions

File tree

BMS/Core/User/Inc/FEB_ADBMS6830B.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ float FEB_ADBMS_GET_ACC_Total_Voltage(void);
9999
float FEB_ADBMS_GET_Cell_Voltage(uint8_t bank, uint16_t cell);
100100
float FEB_ADBMS_GET_Cell_Voltage_S(uint8_t bank, uint16_t cell);
101101
uint8_t FEB_ADBMS_GET_Cell_Violations(uint8_t bank, uint16_t cell);
102+
uint8_t FEB_ADBMS_GET_Cell_Discharging(uint8_t bank, uint16_t cell);
102103

103104
// ********************************** Temperature ********************************
104105

@@ -115,6 +116,9 @@ void FEB_Stop_Balance(void);
115116
void FEB_Cell_Balance_Start(void);
116117
void FEB_Cell_Balance_Process(void);
117118
bool FEB_Cell_Balancing_Status(void);
119+
uint16_t FEB_ADBMS_GET_Balancing_Cell_Count(void); // # of cells with discharge active
120+
float FEB_ADBMS_GET_Cell_Voltage_Delta_mV(void); // pack max-min cell delta in mV, -1 if no valid data
121+
bool FEB_Cell_Balance_Complete(void); // true when valid readings AND delta < threshold
118122

119123
// ********************************** Error Type *********************************
120124

BMS/Core/User/Src/FEB_ADBMS6830B.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,19 @@ uint8_t FEB_ADBMS_GET_Cell_Violations(uint8_t bank, uint16_t cell)
823823
return violations;
824824
}
825825

826+
uint8_t FEB_ADBMS_GET_Cell_Discharging(uint8_t bank, uint16_t cell)
827+
{
828+
if (bank >= FEB_NBANKS || cell >= FEB_NUM_CELLS_PER_BANK)
829+
{
830+
return 0;
831+
}
832+
833+
osMutexAcquire(ADBMSMutexHandle, osWaitForever);
834+
uint8_t discharging = FEB_ACC.banks[bank].cells[cell].discharging;
835+
osMutexRelease(ADBMSMutexHandle);
836+
return discharging;
837+
}
838+
826839
bool FEB_ADBMS_Precharge_Complete(void)
827840
{
828841
// float voltage_V = (float)FEB_IVT_V1_Voltage() * 0.001f;
@@ -1045,6 +1058,63 @@ bool FEB_Cell_Balancing_Status(void)
10451058
return false;
10461059
}
10471060

1061+
uint16_t FEB_ADBMS_GET_Balancing_Cell_Count(void)
1062+
{
1063+
uint16_t count = 0;
1064+
osMutexAcquire(ADBMSMutexHandle, osWaitForever);
1065+
for (size_t i = 0; i < FEB_NBANKS; ++i)
1066+
{
1067+
for (size_t j = 0; j < FEB_NUM_CELLS_PER_BANK; ++j)
1068+
{
1069+
if (FEB_ACC.banks[i].cells[j].discharging)
1070+
{
1071+
count++;
1072+
}
1073+
}
1074+
}
1075+
osMutexRelease(ADBMSMutexHandle);
1076+
return count;
1077+
}
1078+
1079+
// Pack-wide max-min cell-voltage spread in mV (single source of truth for the
1080+
// balancing delta). Returns -1.0f when no valid cell readings are available.
1081+
float FEB_ADBMS_GET_Cell_Voltage_Delta_mV(void)
1082+
{
1083+
float min_v = FLT_MAX;
1084+
float max_v = -FLT_MAX;
1085+
1086+
for (size_t i = 0; i < FEB_NBANKS; ++i)
1087+
{
1088+
for (size_t j = 0; j < FEB_NUM_CELLS_PER_BANK; ++j)
1089+
{
1090+
const float voltage = FEB_ADBMS_GET_Cell_Voltage(i, j) * 1000.0f;
1091+
if (voltage < 0)
1092+
{
1093+
continue; // getter returns -1000mV (-1.0V * 1000) for invalid/out-of-range
1094+
}
1095+
if (voltage < min_v)
1096+
min_v = voltage;
1097+
if (voltage > max_v)
1098+
max_v = voltage;
1099+
}
1100+
}
1101+
1102+
if (max_v < 0 || min_v > 1e8f)
1103+
{
1104+
return -1.0f; // no valid readings
1105+
}
1106+
return max_v - min_v;
1107+
}
1108+
1109+
// "Done balancing": valid readings AND pack converged below the slippage
1110+
// threshold. Distinct from !FEB_Cell_Balancing_Status(), which also returns
1111+
// false when balancing is blocked (too hot / no telemetry).
1112+
bool FEB_Cell_Balance_Complete(void)
1113+
{
1114+
const float delta_mV = FEB_ADBMS_GET_Cell_Voltage_Delta_mV();
1115+
return (delta_mV >= 0.0f && delta_mV < FEB_MIN_SLIPPAGE_V * 1000.0f);
1116+
}
1117+
10481118
void FEB_Stop_Balance()
10491119
{
10501120
LOG_D(TAG_BALANCE, "Stopping all cell discharge");
@@ -1053,6 +1123,18 @@ void FEB_Stop_Balance()
10531123
balancing_mask = 0x0000;
10541124
balancing_cycle = 0;
10551125

1126+
// Clear the per-cell discharge flags so the console/CSV readout reflects the
1127+
// hardware (DCC=0 below) once balancing stops. Lock-free: this is reachable
1128+
// from the 1ms SM task (fault entry / balance transitions), which must never
1129+
// block on ADBMSMutexHandle; single-byte stores are atomic on Cortex-M4.
1130+
for (size_t i = 0; i < FEB_NBANKS; ++i)
1131+
{
1132+
for (size_t j = 0; j < FEB_NUM_CELLS_PER_BANK; ++j)
1133+
{
1134+
FEB_ACC.banks[i].cells[j].discharging = 0;
1135+
}
1136+
}
1137+
10561138
for (uint8_t ic = 0; ic < FEB_NUM_IC; ic++)
10571139
{
10581140
ADBMS6830B_set_cfgr(ic, IC_Config, refon, cth_bits, gpio_bits, 0, dcto_bits, uv, ov);

BMS/Core/User/Src/FEB_Commands.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ static void subcmd_status(int argc, char *argv[])
8787
FEB_Console_Printf("Min Temp: %.1fC Max Temp: %.1fC Avg: %.1fC\r\n", FEB_ADBMS_GET_ACC_MIN_Temp(),
8888
FEB_ADBMS_GET_ACC_MAX_Temp(), FEB_ADBMS_GET_ACC_AVG_Temp());
8989
FEB_Console_Printf("Balancing: %s\r\n", FEB_Cell_Balancing_Status() ? "ON" : "OFF");
90+
FEB_Console_Printf("Cell delta: %.0fmV Balance done: %s\r\n", FEB_ADBMS_GET_Cell_Voltage_Delta_mV(),
91+
FEB_Cell_Balance_Complete() ? "YES" : "NO");
9092
FEB_Console_Printf("Error Type: 0x%02X\r\n", FEB_ADBMS_Get_Error_Type());
9193
}
9294

@@ -106,9 +108,13 @@ static void subcmd_cells(int argc, char *argv[])
106108
{
107109
float v_c = FEB_ADBMS_GET_Cell_Voltage(bank, cell);
108110
float v_s = FEB_ADBMS_GET_Cell_Voltage_S(bank, cell);
109-
FEB_Console_Printf(" C%02d: %.3f/%.3f\r\n", cell + 1, v_c, v_s);
111+
uint8_t bal = FEB_ADBMS_GET_Cell_Discharging(bank, cell);
112+
FEB_Console_Printf(" C%02d: %.3f/%.3f%s\r\n", cell + 1, v_c, v_s, bal ? " *BAL" : "");
110113
}
111114
}
115+
FEB_Console_Printf("Balancing: %u cells active | delta %.0fmV | done: %s\r\n",
116+
(unsigned int)FEB_ADBMS_GET_Balancing_Cell_Count(), FEB_ADBMS_GET_Cell_Voltage_Delta_mV(),
117+
FEB_Cell_Balance_Complete() ? "YES" : "NO");
112118
}
113119

114120
/* ============================================================================
@@ -802,9 +808,10 @@ static void cmd_bms(int argc, char *argv[]);
802808
* CSV-Mode Handlers (one per spec command, registered at top level)
803809
* ============================================================================ */
804810

805-
/* Mandatory per spec. Emits voltage,<module>,<cell>,<primary>,<secondary>
811+
/* Mandatory per spec. Emits voltage,<module>,<cell>,<primary>,<secondary>,<balancing>
806812
* for every cell, then temp,<module>,<sensor>,<temp> for every sensor.
807-
* "module" is the 1-indexed bank number. */
813+
* "module" is the 1-indexed bank number; "balancing" is 1 if the cell's discharge
814+
* FET is active this balance cycle, else 0. */
808815
static void cmd_cell_stats_csv(int argc, char *argv[])
809816
{
810817
(void)argc;
@@ -816,7 +823,8 @@ static void cmd_cell_stats_csv(int argc, char *argv[])
816823
{
817824
float v_c = FEB_ADBMS_GET_Cell_Voltage(bank, cell);
818825
float v_s = FEB_ADBMS_GET_Cell_Voltage_S(bank, cell);
819-
FEB_Console_CsvEmit("voltage", "%d,%d,%.3f,%.3f", bank + 1, cell + 1, v_c, v_s);
826+
uint8_t bal = FEB_ADBMS_GET_Cell_Discharging(bank, cell);
827+
FEB_Console_CsvEmit("voltage", "%d,%d,%.3f,%.3f,%d", bank + 1, cell + 1, v_c, v_s, bal);
820828
}
821829
}
822830
for (int bank = 0; bank < FEB_NBANKS; bank++)
@@ -858,13 +866,16 @@ static void cmd_status_csv(int argc, char *argv[])
858866
}
859867
}
860868

861-
/* Body fields: state,pack_v,min_c,max_c,min_s,max_s,min_t,max_t,avg_t,balancing,err_type */
862-
FEB_Console_CsvEmit("status", "%s,%.2f,%.3f,%.3f,%.3f,%.3f,%.1f,%.1f,%.1f,%d,0x%02X",
869+
/* Body fields: state,pack_v,min_c,max_c,min_s,max_s,min_t,max_t,avg_t,balancing,err_type,balance_done,delta_mV */
870+
FEB_Console_CsvEmit("status", "%s,%.2f,%.3f,%.3f,%.3f,%.3f,%.1f,%.1f,%.1f,%d,0x%02X,%d,%.0f",
863871
FEB_CAN_State_GetStateName(FEB_SM_Get_Current_State()), FEB_ADBMS_GET_ACC_Total_Voltage(), min_c,
864872
max_c, min_s, max_s, FEB_ADBMS_GET_ACC_MIN_Temp(), FEB_ADBMS_GET_ACC_MAX_Temp(),
865-
FEB_ADBMS_GET_ACC_AVG_Temp(), FEB_Cell_Balancing_Status() ? 1 : 0, FEB_ADBMS_Get_Error_Type());
873+
FEB_ADBMS_GET_ACC_AVG_Temp(), FEB_Cell_Balancing_Status() ? 1 : 0, FEB_ADBMS_Get_Error_Type(),
874+
FEB_Cell_Balance_Complete() ? 1 : 0, FEB_ADBMS_GET_Cell_Voltage_Delta_mV());
866875
}
867876

877+
/* Emits voltage,<module>,<cell>,<primary>,<secondary>,<balancing> per cell.
878+
* "balancing" is 1 if the cell's discharge FET is active this cycle, else 0. */
868879
static void cmd_cells_csv(int argc, char *argv[])
869880
{
870881
(void)argc;
@@ -875,7 +886,8 @@ static void cmd_cells_csv(int argc, char *argv[])
875886
{
876887
float v_c = FEB_ADBMS_GET_Cell_Voltage(bank, cell);
877888
float v_s = FEB_ADBMS_GET_Cell_Voltage_S(bank, cell);
878-
FEB_Console_CsvEmit("voltage", "%d,%d,%.3f,%.3f", bank + 1, cell + 1, v_c, v_s);
889+
uint8_t bal = FEB_ADBMS_GET_Cell_Discharging(bank, cell);
890+
FEB_Console_CsvEmit("voltage", "%d,%d,%.3f,%.3f,%d", bank + 1, cell + 1, v_c, v_s, bal);
879891
}
880892
}
881893
}

BMS/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.8.3
1+
1.8.4

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.9.7
1+
1.9.8

0 commit comments

Comments
 (0)