diff --git a/AMS_Master_Code/Core/Inc/battery.h b/AMS_Master_Code/Core/Inc/battery.h index 0158579..afdd6e5 100644 --- a/AMS_Master_Code/Core/Inc/battery.h +++ b/AMS_Master_Code/Core/Inc/battery.h @@ -12,6 +12,7 @@ extern struct {uint16_t min; uint16_t max;} module_voltages[N_BMS]; extern int16_t max_temp; extern int16_t min_temp; extern struct {int16_t min; int16_t max;} module_temps[N_BMS]; +extern float module_std_deviation[N_BMS]; extern int16_t cellTemps[N_BMS][N_CELLS]; diff --git a/AMS_Master_Code/Core/Inc/print_master_status.h b/AMS_Master_Code/Core/Inc/print_master_status.h deleted file mode 100644 index dda2d9d..0000000 --- a/AMS_Master_Code/Core/Inc/print_master_status.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef INC_UTIL_H -#define INC_UTIL_H - -#include - -void print_status(); - -#endif // INC_UTIL_H diff --git a/AMS_Master_Code/Core/Src/battery.c b/AMS_Master_Code/Core/Src/battery.c index fc6329f..52be721 100644 --- a/AMS_Master_Code/Core/Src/battery.c +++ b/AMS_Master_Code/Core/Src/battery.c @@ -5,6 +5,7 @@ #include "config_ADBMS6830.h" #include "ts_state_machine.h" #include +#include #define SWO_LOG_PREFIX "[BATTERY] " #include "swo_log.h" @@ -20,6 +21,7 @@ typeof(module_voltages) module_voltages = {[0 ... N_BMS - 1] = {0xFFFF, 0}}; int16_t min_temp = INT16_MAX; int16_t max_temp = INT16_MIN; typeof(module_temps) module_temps = {[0 ... N_BMS - 1] = {INT16_MAX, INT16_MIN}}; +float module_std_deviation[N_BMS] = {}; int16_t cellTemps[N_BMS][N_CELLS]; @@ -57,6 +59,7 @@ HAL_StatusTypeDef battery_init(SPI_HandleTypeDef *hspi) { return HAL_OK; } +[[gnu::optimize("no-math-errno")]] HAL_StatusTypeDef battery_update() { auto ret = AMS_Idle_Loop(); if (ret.status != ADBMS_NO_ERROR) { @@ -78,6 +81,29 @@ HAL_StatusTypeDef battery_update() { max_temp = INT16_MIN; for (size_t i = 0; i < N_BMS; i++) { + // Calculate standard deviation for each module + if (DEBUG_CHANNEL_ENABLED(DEBUG_CHANNEL)) { + float sum = 0; + float mean = 0; + float variance = 0; + + // First pass: calculate mean + for (size_t j = 0; j < N_CELLS; j++) { + sum += modules[i].cellVoltages[j]; + } + mean = sum / N_CELLS; + + // Second pass: calculate variance + for (size_t j = 0; j < N_CELLS; j++) { + float diff = modules[i].cellVoltages[j] - mean; + variance += diff * diff; + } + variance /= N_CELLS; + + // Calculate standard deviation + module_std_deviation[i] = sqrtf(variance); + } + for (size_t j = 0; j < N_CELLS; j++) { if (modules[i].cellVoltages[j] > min_voltage) { min_voltage = modules[i].cellVoltages[j]; diff --git a/AMS_Master_Code/Core/Src/print_master_status.c b/AMS_Master_Code/Core/Src/print_master_status.c index 5bf30ee..e7c4b20 100644 --- a/AMS_Master_Code/Core/Src/print_master_status.c +++ b/AMS_Master_Code/Core/Src/print_master_status.c @@ -1,4 +1,3 @@ -#include "print_master_status.h" #include "imd_monitoring.h" #include "main.h" #include "soc_estimation.h" @@ -51,20 +50,28 @@ void print_master_status() { debug_log(LOG_LEVEL_INFO, " Min/Max voltage: %d mV / %d mV", min_voltage, max_voltage); debug_log(LOG_LEVEL_INFO, " Min/Max temp: %d °C / %d °C", min_temp, max_temp); debug_log(LOG_LEVEL_INFO, " SoC: %.2f %%", current_soc); - debug_log(LOG_LEVEL_INFO, " Module data: Min V | Max V | Min T | Max T"); + debug_log(LOG_LEVEL_INFO, " Module data: Min V | Max V | Std Dev | Min T | Max T"); + auto max_std_dev = 0.0f; + for (size_t i = 0; i < N_BMS; i++) { + if (module_std_deviation[i] > max_std_dev) { + max_std_dev = module_std_deviation[i]; + } + } for (size_t i = 0; i < N_BMS; i++) { #if USE_ANSI_ESCAPE_CODES - #define COLOR_MIN "\033[34m" // Blue for min - #define COLOR_MAX "\033[31m" // Red for max + #define COLOR_MIN "\033[38;5;75m" //blue for min + #define COLOR_MAX "\033[38;5;203m" //red for max #define COLOR_RESET "\033[0m" - debug_log(LOG_LEVEL_INFO, " %2zu: %s%5d mV%s | %s%5d mV%s | %s%3d °C%s | %s%3d °C%s", i, - (module_voltages[i].min == min_voltage) ? COLOR_MIN : "", (module_voltages[i].min), COLOR_RESET, - (module_voltages[i].max == max_voltage) ? COLOR_MAX : "", (module_voltages[i].max), COLOR_RESET, - (module_temps[i].min == min_temp) ? COLOR_MIN : "", (module_temps[i].min), COLOR_RESET, - (module_temps[i].max == max_temp) ? COLOR_MAX : "", (module_temps[i].max), COLOR_RESET); + debug_log(LOG_LEVEL_INFO, " %2zu: %s%5d mV%s | %s%5d mV%s | %s%.2f mV%s | %s%3d °C%s | %s%3d °C%s", i, + (module_voltages[i].min == min_voltage) ? COLOR_MIN : "", (module_voltages[i].min), COLOR_RESET, + (module_voltages[i].max == max_voltage) ? COLOR_MAX : "", (module_voltages[i].max), COLOR_RESET, + (module_std_deviation[i] > max_std_dev) ? COLOR_MAX : "", module_std_deviation[i], COLOR_RESET, + (module_temps[i].min == min_temp) ? COLOR_MIN : "", (module_temps[i].min), COLOR_RESET, + (module_temps[i].max == max_temp) ? COLOR_MAX : "", (module_temps[i].max), COLOR_RESET); #else - debug_log(LOG_LEVEL_INFO, " %2zu: %5d mV | %5d mV | %3d °C | %3d °C", i, + debug_log(LOG_LEVEL_INFO, " %2zu: %5d mV | %5d mV | %.2f mV | %3d °C | %3d °C", i, module_voltages[i].min, module_voltages[i].max, + module_std_deviation[i], module_temps[i].min, module_temps[i].max); #endif }