mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Safety tweaks for double battery
This commit is contained in:
parent
8b952b805c
commit
12ec967e5d
7 changed files with 47 additions and 24 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -643,7 +643,7 @@ String processor(const String& var) {
|
|||
|
||||
#ifdef DOUBLE_BATTERY
|
||||
content += "<div style='flex: 1; background-color: ";
|
||||
switch (datalayer.battery2.status.bms_status) {
|
||||
switch (datalayer.battery.status.bms_status) {
|
||||
case ACTIVE:
|
||||
content += "#2D3F2F;";
|
||||
break;
|
||||
|
@ -660,8 +660,7 @@ String processor(const String& var) {
|
|||
// Display battery statistics within this block
|
||||
socRealFloat =
|
||||
static_cast<float>(datalayer.battery2.status.real_soc) / 100.0; // Convert to float and divide by 100
|
||||
socScaledFloat =
|
||||
static_cast<float>(datalayer.battery.status.reported_soc) / 100.0; // Convert to float and divide by 100
|
||||
//socScaledFloat; // Same value used for bat2
|
||||
sohFloat = static_cast<float>(datalayer.battery2.status.soh_pptt) / 100.0; // Convert to float and divide by 100
|
||||
voltageFloat =
|
||||
static_cast<float>(datalayer.battery2.status.voltage_dV) / 10.0; // Convert to float and divide by 10
|
||||
|
@ -685,12 +684,12 @@ String processor(const String& var) {
|
|||
content += "<h4>Cell min: " + String(datalayer.battery2.status.cell_min_voltage_mV) + " mV</h4>";
|
||||
content += "<h4>Temperature max: " + String(tempMaxFloat, 1) + " C</h4>";
|
||||
content += "<h4>Temperature min: " + String(tempMinFloat, 1) + " C</h4>";
|
||||
if (datalayer.battery2.status.bms_status == ACTIVE) {
|
||||
content += "<h4>BMS Status: OK </h4>";
|
||||
} else if (datalayer.battery2.status.bms_status == UPDATING) {
|
||||
content += "<h4>BMS Status: UPDATING </h4>";
|
||||
if (datalayer.battery.status.bms_status == ACTIVE) {
|
||||
content += "<h4>System status: OK </h4>";
|
||||
} else if (datalayer.battery.status.bms_status == UPDATING) {
|
||||
content += "<h4>System status: UPDATING </h4>";
|
||||
} else {
|
||||
content += "<h4>BMS Status: FAULT </h4>";
|
||||
content += "<h4>System status: FAULT </h4>";
|
||||
}
|
||||
if (datalayer.battery2.status.current_dA == 0) {
|
||||
content += "<h4>Battery idle</h4>";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue