mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 18:29:48 +02:00
Tweak logic for contactor closing
This commit is contained in:
parent
f83bbc35eb
commit
997866ef8c
5 changed files with 55 additions and 25 deletions
|
@ -619,9 +619,19 @@ void send_can2() {
|
||||||
|
|
||||||
#ifdef DOUBLE_BATTERY
|
#ifdef DOUBLE_BATTERY
|
||||||
void handle_CAN_contactors() {
|
void handle_CAN_contactors() {
|
||||||
if (abs(datalayer.battery.status.voltage_dV - datalayer.battery2.status.voltage_dV) < 50) {
|
if (datalayer.battery.status.voltage_dV == 0 || datalayer.battery2.status.voltage_dV == 0) {
|
||||||
|
return; // Both voltage values need to be available to start check
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
datalayer.system.status.battery2_allows_contactor_closing = true;
|
datalayer.system.status.battery2_allows_contactor_closing = true;
|
||||||
} //TODO: Shall we handle opening incase of fault here?
|
}
|
||||||
|
} else { //We are over 3.0V diff
|
||||||
|
set_event(EVENT_VOLTAGE_DIFFERENCE,
|
||||||
|
(uint8_t)(abs(datalayer.battery.status.voltage_dV - datalayer.battery2.status.voltage_dV) / 10));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -744,7 +754,29 @@ void update_SOC() {
|
||||||
datalayer.battery.status.reported_soc = calc_soc;
|
datalayer.battery.status.reported_soc = calc_soc;
|
||||||
} else { // No SOC window wanted. Set scaled to same as real.
|
} else { // No SOC window wanted. Set scaled to same as real.
|
||||||
datalayer.battery.status.reported_soc = datalayer.battery.status.real_soc;
|
datalayer.battery.status.reported_soc = datalayer.battery.status.real_soc;
|
||||||
|
#ifdef DOUBLE_BATTERY
|
||||||
|
datalayer.battery.status.reported_soc =
|
||||||
|
(datalayer.battery.status.real_soc + datalayer.battery2.status.real_soc) / 2;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef DOUBLE_BATTERY
|
||||||
|
datalayer.battery.status.reported_soc = (datalayer.battery.status.real_soc + datalayer.battery2.status.real_soc) / 2;
|
||||||
|
|
||||||
|
if (datalayer.battery.status.real_soc < 100) { //If this battery is under 1.00%, use this as SOC instead of average
|
||||||
|
datalayer.battery.status.reported_soc = datalayer.battery.status.real_soc;
|
||||||
|
}
|
||||||
|
if (datalayer.battery2.status.real_soc < 100) { //If this battery is under 1.00%, use this as SOC instead of average
|
||||||
|
datalayer.battery.status.reported_soc = datalayer.battery2.status.real_soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datalayer.battery.status.real_soc > 9900) { //If this battery is over 99.00%, use this as SOC instead of average
|
||||||
|
datalayer.battery.status.reported_soc = datalayer.battery.status.real_soc;
|
||||||
|
}
|
||||||
|
if (datalayer.battery2.status.real_soc > 9900) { //If this battery is over 99.00%, use this as SOC instead of average
|
||||||
|
datalayer.battery.status.reported_soc = datalayer.battery2.status.real_soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //TODO: Constrain according to the user settings. Help wanted on algoritm to use.
|
||||||
}
|
}
|
||||||
|
|
||||||
void summarize_battery_values() {
|
void summarize_battery_values() {
|
||||||
|
|
|
@ -16,14 +16,6 @@ static unsigned long previousMillis1000 = 0; // will store last time a 1000m
|
||||||
static unsigned long previousMillis5000 = 0; // will store last time a 5000ms CAN Message was send
|
static unsigned long previousMillis5000 = 0; // will store last time a 5000ms CAN Message was send
|
||||||
static unsigned long previousMillis10000 = 0; // will store last time a 10000ms CAN Message was send
|
static unsigned long previousMillis10000 = 0; // will store last time a 10000ms CAN Message was send
|
||||||
static uint8_t CANstillAlive = 12; // counter for checking if CAN is still alive
|
static uint8_t CANstillAlive = 12; // counter for checking if CAN is still alive
|
||||||
static unsigned long previousMillis20_2 = 0; // will store last time a 20ms CAN Message was send
|
|
||||||
static unsigned long previousMillis100_2 = 0; // will store last time a 100ms CAN Message was send
|
|
||||||
static unsigned long previousMillis200_2 = 0; // will store last time a 200ms CAN Message was send
|
|
||||||
static unsigned long previousMillis500_2 = 0; // will store last time a 500ms CAN Message was send
|
|
||||||
static unsigned long previousMillis640_2 = 0; // will store last time a 600ms CAN Message was send
|
|
||||||
static unsigned long previousMillis1000_2 = 0; // will store last time a 1000ms CAN Message was send
|
|
||||||
static unsigned long previousMillis5000_2 = 0; // will store last time a 5000ms CAN Message was send
|
|
||||||
static unsigned long previousMillis10000_2 = 0; // will store last time a 10000ms CAN Message was send
|
|
||||||
static uint8_t CAN2stillAlive = 12; // counter for checking if CAN2 is still alive
|
static uint8_t CAN2stillAlive = 12; // counter for checking if CAN2 is still alive
|
||||||
static uint16_t CANerror = 0; // counter on how many CAN errors encountered
|
static uint16_t CANerror = 0; // counter on how many CAN errors encountered
|
||||||
#define ALIVE_MAX_VALUE 14 // BMW CAN messages contain alive counter, goes from 0...14
|
#define ALIVE_MAX_VALUE 14 // BMW CAN messages contain alive counter, goes from 0...14
|
||||||
|
@ -533,6 +525,7 @@ void update_values_battery2() { //This function maps all the values fetched via
|
||||||
if (!CAN2stillAlive) {
|
if (!CAN2stillAlive) {
|
||||||
set_event(EVENT_CAN2_RX_FAILURE, 2);
|
set_event(EVENT_CAN2_RX_FAILURE, 2);
|
||||||
datalayer.battery2.status.bms_status = FAULT; //TODO: Refactor handling of event for battery2
|
datalayer.battery2.status.bms_status = FAULT; //TODO: Refactor handling of event for battery2
|
||||||
|
datalayer.system.status.battery2_allows_contactor_closing = false;
|
||||||
} else {
|
} else {
|
||||||
CAN2stillAlive--;
|
CAN2stillAlive--;
|
||||||
clear_event(EVENT_CAN2_RX_FAILURE);
|
clear_event(EVENT_CAN2_RX_FAILURE);
|
||||||
|
@ -788,7 +781,8 @@ void receive_can_battery2(CAN_frame_t rx_frame) {
|
||||||
CAN2stillAlive = 12; //This message is only sent if 30C (Wakeup pin on battery) is energized with 12V
|
CAN2stillAlive = 12; //This message is only sent if 30C (Wakeup pin on battery) is energized with 12V
|
||||||
battery2_current = (rx_frame.data.u8[1] << 8 | rx_frame.data.u8[0]) - 8192; //deciAmps (-819.2 to 819.0A)
|
battery2_current = (rx_frame.data.u8[1] << 8 | rx_frame.data.u8[0]) - 8192; //deciAmps (-819.2 to 819.0A)
|
||||||
battery2_volts = (rx_frame.data.u8[3] << 8 | rx_frame.data.u8[2]); //500.0 V
|
battery2_volts = (rx_frame.data.u8[3] << 8 | rx_frame.data.u8[2]); //500.0 V
|
||||||
datalayer.battery2.status.voltage_dV = battery2_volts; // Update the datalayer as soon as possible with this info
|
datalayer.battery2.status.voltage_dV =
|
||||||
|
battery2_volts; // Update the datalayer as soon as possible with this info, needed for contactor control
|
||||||
battery2_HVBatt_SOC = ((rx_frame.data.u8[5] & 0x0F) << 8 | rx_frame.data.u8[4]);
|
battery2_HVBatt_SOC = ((rx_frame.data.u8[5] & 0x0F) << 8 | rx_frame.data.u8[4]);
|
||||||
battery2_request_open_contactors = (rx_frame.data.u8[5] & 0xC0) >> 6;
|
battery2_request_open_contactors = (rx_frame.data.u8[5] & 0xC0) >> 6;
|
||||||
battery2_request_open_contactors_instantly = (rx_frame.data.u8[6] & 0x03);
|
battery2_request_open_contactors_instantly = (rx_frame.data.u8[6] & 0x03);
|
||||||
|
|
|
@ -143,6 +143,7 @@ void init_events(void) {
|
||||||
events.entries[EVENT_BATTERY_CHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
|
events.entries[EVENT_BATTERY_CHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
|
||||||
events.entries[EVENT_BATTERY_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
|
events.entries[EVENT_BATTERY_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
|
||||||
events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
|
events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
|
||||||
|
events.entries[EVENT_VOLTAGE_DIFFERENCE].level = EVENT_LEVEL_INFO;
|
||||||
events.entries[EVENT_LOW_SOH].level = EVENT_LEVEL_ERROR;
|
events.entries[EVENT_LOW_SOH].level = EVENT_LEVEL_ERROR;
|
||||||
events.entries[EVENT_HVIL_FAILURE].level = EVENT_LEVEL_ERROR;
|
events.entries[EVENT_HVIL_FAILURE].level = EVENT_LEVEL_ERROR;
|
||||||
events.entries[EVENT_INTERNAL_OPEN_FAULT].level = EVENT_LEVEL_ERROR;
|
events.entries[EVENT_INTERNAL_OPEN_FAULT].level = EVENT_LEVEL_ERROR;
|
||||||
|
@ -227,6 +228,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
|
||||||
return "Info: COLD BATTERY! Battery requesting heating pads to activate!";
|
return "Info: COLD BATTERY! Battery requesting heating pads to activate!";
|
||||||
case EVENT_BATTERY_WARMED_UP:
|
case EVENT_BATTERY_WARMED_UP:
|
||||||
return "Info: Battery requesting heating pads to stop. The battery is now warm enough.";
|
return "Info: Battery requesting heating pads to stop. The battery is now warm enough.";
|
||||||
|
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_LOW_SOH:
|
||||||
return "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle "
|
return "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle "
|
||||||
"battery.";
|
"battery.";
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
XX(EVENT_BATTERY_CHG_DISCHG_STOP_REQ) \
|
XX(EVENT_BATTERY_CHG_DISCHG_STOP_REQ) \
|
||||||
XX(EVENT_BATTERY_REQUESTS_HEAT) \
|
XX(EVENT_BATTERY_REQUESTS_HEAT) \
|
||||||
XX(EVENT_BATTERY_WARMED_UP) \
|
XX(EVENT_BATTERY_WARMED_UP) \
|
||||||
|
XX(EVENT_VOLTAGE_DIFFERENCE) \
|
||||||
XX(EVENT_LOW_SOH) \
|
XX(EVENT_LOW_SOH) \
|
||||||
XX(EVENT_HVIL_FAILURE) \
|
XX(EVENT_HVIL_FAILURE) \
|
||||||
XX(EVENT_INTERNAL_OPEN_FAULT) \
|
XX(EVENT_INTERNAL_OPEN_FAULT) \
|
||||||
|
|
|
@ -599,7 +599,7 @@ String processor(const String& var) {
|
||||||
socRealFloat =
|
socRealFloat =
|
||||||
static_cast<float>(datalayer.battery2.status.real_soc) / 100.0; // Convert to float and divide by 100
|
static_cast<float>(datalayer.battery2.status.real_soc) / 100.0; // Convert to float and divide by 100
|
||||||
socScaledFloat =
|
socScaledFloat =
|
||||||
static_cast<float>(datalayer.battery2.status.reported_soc) / 100.0; // Convert to float and divide by 100
|
static_cast<float>(datalayer.battery.status.reported_soc) / 100.0; // Convert to float and divide by 100
|
||||||
sohFloat = static_cast<float>(datalayer.battery2.status.soh_pptt) / 100.0; // Convert to float and divide by 100
|
sohFloat = static_cast<float>(datalayer.battery2.status.soh_pptt) / 100.0; // Convert to float and divide by 100
|
||||||
voltageFloat =
|
voltageFloat =
|
||||||
static_cast<float>(datalayer.battery2.status.voltage_dV) / 10.0; // Convert to float and divide by 10
|
static_cast<float>(datalayer.battery2.status.voltage_dV) / 10.0; // Convert to float and divide by 10
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue