diff --git a/Software/Software.ino b/Software/Software.ino index 438be072..b0e12606 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -606,7 +606,7 @@ void handle_CAN_contactors() { if (abs(datalayer.battery.status.voltage_dV - datalayer.battery2.status.voltage_dV) < 30) { // If we are within 3.0V clear_event(EVENT_VOLTAGE_DIFFERENCE); - if (datalayer.battery2.status.bms_status != FAULT) { // Only proceed if BMS on battery2 is not faulted + if (datalayer.battery.status.bms_status != FAULT) { // Only proceed if we are not in faulted state datalayer.system.status.battery2_allows_contactor_closing = true; } } else { //We are over 3.0V diff diff --git a/Software/src/battery/BMW-I3-BATTERY.cpp b/Software/src/battery/BMW-I3-BATTERY.cpp index fde63b8f..5c8e93dc 100644 --- a/Software/src/battery/BMW-I3-BATTERY.cpp +++ b/Software/src/battery/BMW-I3-BATTERY.cpp @@ -457,7 +457,7 @@ static uint8_t battery2_status_diagnosis_powertrain_maximum_multiplexer = 0; static uint8_t battery2_status_diagnosis_powertrain_immediate_multiplexer = 0; static uint8_t battery2_ID2 = 0; static uint8_t battery2_cellvoltage_mux = 0; -static uint8_t battery2_soh = 0; +static uint8_t battery2_soh = 99; static uint8_t message_data[50]; static uint8_t next_data = 0; diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index 12c18df4..99c13777 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -811,7 +811,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { battery_TEMP = (rx_frame.data.u8[4] >> 1); if (battery_TEMP != 0) { - battery_StateOfHealth = battery_TEMP; //Collect state of health from battery + battery_StateOfHealth = (uint8_t)battery_TEMP; //Collect state of health from battery } break; case 0x5C0: diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index 172645d9..65617a83 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -7,6 +7,8 @@ static uint8_t discharge_limit_failures = 0; static bool battery_full_event_fired = false; static bool battery_empty_event_fired = false; +#define MAX_SOH_DEVIATION_PPTT 2500 + void update_machineryprotection() { // Start checking that the battery is within reason. Incase we see any funny business, raise an event! @@ -67,9 +69,9 @@ void update_machineryprotection() { // Battery is extremely degraded, not fit for secondlifestorage! if (datalayer.battery.status.soh_pptt < 2500) { - set_event(EVENT_LOW_SOH, datalayer.battery.status.soh_pptt); + set_event(EVENT_SOH_LOW, datalayer.battery.status.soh_pptt); } else { - clear_event(EVENT_LOW_SOH); + clear_event(EVENT_SOH_LOW); } // Check if SOC% is plausible @@ -129,25 +131,43 @@ void update_machineryprotection() { // Too many malformed CAN messages recieved! if (datalayer.battery.status.CAN_error_counter > MAX_CAN_FAILURES) { - set_event(EVENT_CAN_RX_WARNING, 0); + set_event(EVENT_CAN_RX_WARNING, 1); } else { clear_event(EVENT_CAN_RX_WARNING); } -#ifdef DOUBLE_BATTERY - // Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error +#ifdef DOUBLE_BATTERY // Additional Double-Battery safeties are checked here + // Check if the Battery 2 BMS is still sending CAN messages. If we go 60s without messages we raise an error if (!datalayer.battery2.status.CAN_battery_still_alive) { - set_event(EVENT_CAN_RX_FAILURE, 0); + set_event(EVENT_CAN2_RX_FAILURE, 0); } else { datalayer.battery2.status.CAN_battery_still_alive--; - clear_event(EVENT_CAN_RX_FAILURE); + clear_event(EVENT_CAN2_RX_FAILURE); } // Too many malformed CAN messages recieved! if (datalayer.battery2.status.CAN_error_counter > MAX_CAN_FAILURES) { - set_event(EVENT_CAN_RX_WARNING, 0); + set_event(EVENT_CAN_RX_WARNING, 2); } else { clear_event(EVENT_CAN_RX_WARNING); } -#endif + + // Check if SOH% between the packs is too large + if((datalayer.battery.status.soh_pptt != 9900) && (datalayer.battery2.status.soh_pptt != 9900)){ + // Both values available, check diff + uint16_t soh_diff_pptt; + if(datalayer.battery.status.soh_pptt > datalayer.battery2.status.soh_pptt) { + soh_diff_pptt = datalayer.battery.status.soh_pptt - datalayer.battery2.status.soh_pptt; + } else { + soh_diff_pptt = datalayer.battery2.status.soh_pptt - datalayer.battery.status.soh_pptt; + } + + if(soh_diff_pptt > MAX_SOH_DEVIATION_PPTT){ + set_event(EVENT_SOH_DIFFERENCE, MAX_SOH_DEVIATION_PPTT); + } else { + clear_event(EVENT_SOH_DIFFERENCE); + } + } + +#endif // DOUBLE_BATTERY } diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index eca9c20b..14dc1ea8 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -157,7 +157,8 @@ void init_events(void) { events.entries[EVENT_BATTERY_UNDERVOLTAGE].level = EVENT_LEVEL_WARNING; events.entries[EVENT_BATTERY_ISOLATION].level = EVENT_LEVEL_WARNING; events.entries[EVENT_VOLTAGE_DIFFERENCE].level = EVENT_LEVEL_INFO; - events.entries[EVENT_LOW_SOH].level = EVENT_LEVEL_ERROR; + events.entries[EVENT_SOH_DIFFERENCE].level = EVENT_LEVEL_WARNING; + events.entries[EVENT_SOH_LOW].level = EVENT_LEVEL_ERROR; events.entries[EVENT_HVIL_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_PRECHARGE_FAILURE].level = EVENT_LEVEL_INFO; events.entries[EVENT_INTERNAL_OPEN_FAULT].level = EVENT_LEVEL_ERROR; @@ -276,7 +277,9 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { return "Warning: Battery reports isolation error. High voltage might be leaking to ground. Check battery!"; case EVENT_VOLTAGE_DIFFERENCE: return "Info: Too large voltage diff between the batteries. Second battery cannot join the DC-link"; - case EVENT_LOW_SOH: + case EVENT_SOH_DIFFERENCE: + return "Warning: Large deviation in State of health between packs. Inspect battery."; + case EVENT_SOH_LOW: return "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle " "battery."; case EVENT_HVIL_FAILURE: diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index afda0f1e..850d5d17 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -6,7 +6,7 @@ // #define INCLUDE_EVENTS_TEST // Enable to run an event test loop, see events_test_on_target.cpp -#define EE_MAGIC_HEADER_VALUE 0x0009 // 0x0000 to 0xFFFF +#define EE_MAGIC_HEADER_VALUE 0x0010 // 0x0000 to 0xFFFF #define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_STRING(STRING) #STRING, @@ -53,7 +53,8 @@ XX(EVENT_BATTERY_REQUESTS_HEAT) \ XX(EVENT_BATTERY_WARMED_UP) \ XX(EVENT_VOLTAGE_DIFFERENCE) \ - XX(EVENT_LOW_SOH) \ + XX(EVENT_SOH_DIFFERENCE) \ + XX(EVENT_SOH_LOW) \ XX(EVENT_HVIL_FAILURE) \ XX(EVENT_PRECHARGE_FAILURE) \ XX(EVENT_INTERNAL_OPEN_FAULT) \ diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index c1f4fdb9..f3fe9e53 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -643,7 +643,7 @@ String processor(const String& var) { #ifdef DOUBLE_BATTERY content += "