diff --git a/Software/Software.ino b/Software/Software.ino index c8f4186d..06c3a5ae 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -52,6 +52,7 @@ volatile unsigned long long bmsResetTimeOffset = 0; const char* version_number = "8.12.dev"; // Interval timers +volatile unsigned long currentMillis = 0; unsigned long previousMillis10ms = 0; unsigned long previousMillisUpdateVal = 0; unsigned long lastMillisOverflowCheck = 0; @@ -100,12 +101,13 @@ void setup() { init_precharge_control(); #endif // PRECHARGE_CONTROL - init_rs485(); - #if defined(CAN_INVERTER_SELECTED) || defined(MODBUS_INVERTER_SELECTED) || defined(RS485_INVERTER_SELECTED) setup_inverter(); #endif setup_battery(); + + init_rs485(); + #ifdef EQUIPMENT_STOP_BUTTON init_equipment_stop_button(); #endif @@ -208,6 +210,7 @@ void core_loop(void*) { led_init(); while (true) { + START_TIME_MEASUREMENT(all); START_TIME_MEASUREMENT(comm); #ifdef EQUIPMENT_STOP_BUTTON @@ -227,8 +230,12 @@ void core_loop(void*) { #endif // WEBSERVER // Process - if (millis() - previousMillis10ms >= INTERVAL_10_MS) { - previousMillis10ms = millis(); + currentMillis = millis(); + if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) { + if ((currentMillis - previousMillis10ms >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_TASK_OVERRUN, (currentMillis - previousMillis10ms)); + } + previousMillis10ms = currentMillis; #ifdef FUNCTION_TIME_MEASUREMENT START_TIME_MEASUREMENT(time_10ms); #endif @@ -242,8 +249,8 @@ void core_loop(void*) { #endif } - if (millis() - previousMillisUpdateVal >= INTERVAL_1_S) { - previousMillisUpdateVal = millis(); // Order matters on the update_loop! + if (currentMillis - previousMillisUpdateVal >= INTERVAL_1_S) { + previousMillisUpdateVal = currentMillis; // Order matters on the update_loop! #ifdef FUNCTION_TIME_MEASUREMENT START_TIME_MEASUREMENT(time_values); #endif @@ -264,7 +271,7 @@ void core_loop(void*) { START_TIME_MEASUREMENT(cantx); #endif // Output - transmit_can(); // Send CAN messages to all components + transmit_can(currentMillis); // Send CAN messages to all components #ifdef RS485_BATTERY_SELECTED transmit_rs485(); diff --git a/Software/src/battery/BATTERIES.cpp b/Software/src/battery/BATTERIES.cpp index 2d88dd6a..e9bc2f92 100644 --- a/Software/src/battery/BATTERIES.cpp +++ b/Software/src/battery/BATTERIES.cpp @@ -3,14 +3,17 @@ // These functions adapt the old C-style global functions battery-API to the // object-oriented battery API. -#ifdef OO_BATTERY_SELECTED +// The instantiated class is defined by the pre-compiler define +// to support battery class selection at compile-time +#ifdef SELECTED_BATTERY_CLASS -static CanBattery* battery; +static CanBattery* battery = nullptr; void setup_battery() { - // Currently only one battery is implemented as a class. - // TODO: Extend based on build-time or run-time selected battery. - battery = new RenaultZoeGen1Battery(); + // Instantiate the battery only once just in case this function gets called multiple times. + if (battery == nullptr) { + battery = new SELECTED_BATTERY_CLASS(); + } battery->setup(); } @@ -18,8 +21,8 @@ void update_values_battery() { battery->update_values(); } -void transmit_can_battery() { - battery->transmit_can(); +void transmit_can_battery(unsigned long currentMillis) { + battery->transmit_can(currentMillis); } void handle_incoming_can_frame_battery(CAN_frame rx_frame) { diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index 5c92696d..80afe51f 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -2,23 +2,10 @@ #define BATTERIES_H #include "../../USER_SETTINGS.h" -#include "src/devboard/utils/types.h" - -// Abstract base class for next-generation battery implementations. -// Defines the interface to call battery specific functionality. -// No support for double battery yet. -class CanBattery { - public: - virtual void setup(void) = 0; - virtual void handle_incoming_can_frame(CAN_frame rx_frame) = 0; - virtual void update_values() = 0; - virtual void transmit_can() = 0; -}; - #ifdef BMW_SBOX #include "BMW-SBOX.h" void handle_incoming_can_frame_shunt(CAN_frame rx_frame); -void transmit_can_shunt(); +void transmit_can_shunt(unsigned long currentMillis); void setup_can_shunt(); #endif @@ -168,7 +155,7 @@ void transmit_rs485(); void receive_RS485(); #else void handle_incoming_can_frame_battery(CAN_frame rx_frame); -void transmit_can_battery(); +void transmit_can_battery(unsigned long currentMillis); #endif #ifdef DOUBLE_BATTERY diff --git a/Software/src/battery/BMW-I3-BATTERY.cpp b/Software/src/battery/BMW-I3-BATTERY.cpp index 7188eda6..281ce895 100644 --- a/Software/src/battery/BMW-I3-BATTERY.cpp +++ b/Software/src/battery/BMW-I3-BATTERY.cpp @@ -880,18 +880,11 @@ void handle_incoming_can_frame_battery2(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { if (battery_awake) { //Send 20ms message if (currentMillis - previousMillis20 >= INTERVAL_20_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis20 >= INTERVAL_20_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis20)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis20 = currentMillis; if (startup_counter_contactor < 160) { diff --git a/Software/src/battery/BMW-IX-BATTERY.cpp b/Software/src/battery/BMW-IX-BATTERY.cpp index 11872e22..71e1c959 100644 --- a/Software/src/battery/BMW-IX-BATTERY.cpp +++ b/Software/src/battery/BMW-IX-BATTERY.cpp @@ -11,8 +11,6 @@ static unsigned long previousMillis100 = 0; // will store last time a 100ms C static unsigned long previousMillis200 = 0; // will store last time a 200ms CAN Message was send static unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was send static unsigned long previousMillis640 = 0; // will store last time a 600ms CAN Message was send -static unsigned long previousMillis1000 = 0; // will store last time a 1000ms 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 #define ALIVE_MAX_VALUE 14 // BMW CAN messages contain alive counter, goes from 0...14 @@ -839,8 +837,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { //if (battery_awake) { //We can always send CAN as the iX BMS will wake up on vehicle comms // Send 100ms CAN Message @@ -862,14 +859,6 @@ void transmit_can_battery() { BMWiX_C0.data.u8[0] = increment_C0_counter(BMWiX_C0.data.u8[0]); //Keep Alive 1 transmit_can_frame(&BMWiX_C0, can_config.battery); } - // Send 1000ms CAN Message - if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { - previousMillis1000 = currentMillis; - } - // Send 5000ms CAN Message - if (currentMillis - previousMillis5000 >= INTERVAL_5_S) { - previousMillis5000 = currentMillis; - } // Send 10000ms CAN Message if (currentMillis - previousMillis10000 >= INTERVAL_10_S) { previousMillis10000 = currentMillis; @@ -877,18 +866,6 @@ void transmit_can_battery() { transmit_can_frame(&BMWiX_6F4_REQUEST_BALANCING_START, can_config.battery); } } -//We can always send CAN as the iX BMS will wake up on vehicle comms -// else { -// previousMillis20 = currentMillis; -// previousMillis100 = currentMillis; -// previousMillis200 = currentMillis; -// previousMillis500 = currentMillis; -// previousMillis640 = currentMillis; -// previousMillis1000 = currentMillis; -// previousMillis5000 = currentMillis; -// previousMillis10000 = currentMillis; -// } -//} //We can always send CAN as the iX BMS will wake up on vehicle comms void setup_battery(void) { // Performs one time setup at startup strncpy(datalayer.system.info.battery_protocol, "BMW iX and i4-7 platform", 63); diff --git a/Software/src/battery/BMW-PHEV-BATTERY.cpp b/Software/src/battery/BMW-PHEV-BATTERY.cpp index 53b87eb9..ad62b3aa 100644 --- a/Software/src/battery/BMW-PHEV-BATTERY.cpp +++ b/Software/src/battery/BMW-PHEV-BATTERY.cpp @@ -1005,8 +1005,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { //if (battery_awake) { //We can always send CAN as the PHEV BMS will wake up on vehicle comms diff --git a/Software/src/battery/BMW-SBOX.cpp b/Software/src/battery/BMW-SBOX.cpp index ff0139b4..dcd9807d 100644 --- a/Software/src/battery/BMW-SBOX.cpp +++ b/Software/src/battery/BMW-SBOX.cpp @@ -100,18 +100,17 @@ void handle_incoming_can_frame_shunt(CAN_frame rx_frame) { } } -void transmit_can_shunt() { - unsigned long currentTime = millis(); +void transmit_can_shunt(unsigned long currentMillis) { /** Shunt can frames seen? **/ - if (ShuntLastSeen + 1000 < currentTime) { + if (ShuntLastSeen + 1000 < currentMillis) { datalayer.shunt.available = false; } else { datalayer.shunt.available = true; } // Send 20ms CAN Message - if (currentTime - LastMsgTime >= INTERVAL_20_MS) { - LastMsgTime = currentTime; + if (currentMillis - LastMsgTime >= INTERVAL_20_MS) { + LastMsgTime = currentMillis; // First check if we have any active errors, incase we do, turn off the battery if (datalayer.battery.status.bms_status == FAULT) { timeSpentInFaultedMode++; @@ -154,16 +153,16 @@ void transmit_can_shunt() { switch (contactorStatus) { case PRECHARGE: SBOX_100.data.u8[0] = 0x86; // Precharge relay only - prechargeStartTime = currentTime; + prechargeStartTime = currentMillis; contactorStatus = NEGATIVE; #ifdef DEBUG_VIA_USB Serial.println("S-BOX Precharge relay engaged"); #endif break; case NEGATIVE: - if (currentTime - prechargeStartTime >= CONTACTOR_CONTROL_T1) { + if (currentMillis - prechargeStartTime >= CONTACTOR_CONTROL_T1) { SBOX_100.data.u8[0] = 0xA6; // Precharge + Negative - negativeStartTime = currentTime; + negativeStartTime = currentMillis; contactorStatus = POSITIVE; datalayer.shunt.precharging = true; #ifdef DEBUG_VIA_USB @@ -172,11 +171,11 @@ void transmit_can_shunt() { } break; case POSITIVE: - if (currentTime - negativeStartTime >= CONTACTOR_CONTROL_T2 && + if (currentMillis - negativeStartTime >= CONTACTOR_CONTROL_T2 && (datalayer.shunt.measured_voltage_mV * MAX_PRECHARGE_RESISTOR_VOLTAGE_PERCENT < datalayer.shunt.measured_outvoltage_mV)) { SBOX_100.data.u8[0] = 0xAA; // Precharge + Negative + Positive - positiveStartTime = currentTime; + positiveStartTime = currentMillis; contactorStatus = PRECHARGE_OFF; datalayer.shunt.precharging = false; #ifdef DEBUG_VIA_USB @@ -185,7 +184,7 @@ void transmit_can_shunt() { } break; case PRECHARGE_OFF: - if (currentTime - positiveStartTime >= CONTACTOR_CONTROL_T3) { + if (currentMillis - positiveStartTime >= CONTACTOR_CONTROL_T3) { SBOX_100.data.u8[0] = 0x6A; // Negative + Positive contactorStatus = COMPLETED; #ifdef DEBUG_VIA_USB diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index 26169f06..43f8b412 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -769,17 +769,10 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { //Send 20ms message if (currentMillis - previousMillis20ms >= INTERVAL_20_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis20ms >= INTERVAL_20_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis20ms)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis20ms = currentMillis; transmit_can_frame(&BOLT_778, can_config.battery); } diff --git a/Software/src/battery/BYD-ATTO-3-BATTERY.cpp b/Software/src/battery/BYD-ATTO-3-BATTERY.cpp index d785ec28..afdec7f9 100644 --- a/Software/src/battery/BYD-ATTO-3-BATTERY.cpp +++ b/Software/src/battery/BYD-ATTO-3-BATTERY.cpp @@ -6,16 +6,21 @@ #include "BYD-ATTO-3-BATTERY.h" /* Notes - - SOC% by default is now ESTIMATED. - - If you have a non-crashed pack, enable using real SOC. See Wiki for info. - - TODO: In the future, we might be able to unlock crashed batteries and get SOC going always +SOC% by default is now ESTIMATED. +If you have a crash-locked pack, See the Wiki for more info on how to attempt an unlock +After battery has been unlocked, you can remove the "USE_ESTIMATED_SOC" from the BYD-ATTO-3-BATTERY.h file */ /* Do not change code below unless you are sure what you are doing */ #define NOT_DETERMINED_YET 0 #define STANDARD_RANGE 1 #define EXTENDED_RANGE 2 +#define NOT_RUNNING 0xFF +#define STARTED 0 +#define RUNNING_STEP_1 1 +#define RUNNING_STEP_2 2 static uint8_t battery_type = NOT_DETERMINED_YET; +static uint8_t stateMachineClearCrash = NOT_RUNNING; static unsigned long previousMillis50 = 0; // will store last time a 50ms CAN Message was send static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send static unsigned long previousMillis200 = 0; // will store last time a 200ms CAN Message was send @@ -178,6 +183,16 @@ CAN_frame ATTO_3_7E7_POLL = {.FD = false, .DLC = 8, .ID = 0x7E7, //Poll PID 03 22 00 05 (POLL_FOR_BATTERY_SOC) .data = {0x03, 0x22, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame ATTO_3_7E7_ACK = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x7E7, //ACK frame for long PIDs + .data = {0x30, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame ATTO_3_7E7_CLEAR_CRASH = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x7E7, + .data = {0x02, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}}; // Define the data points for %SOC depending on pack voltage const uint8_t numPoints = 28; @@ -366,6 +381,12 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.bydAtto3.unknown11 = BMS_unknown11; datalayer_extended.bydAtto3.unknown12 = BMS_unknown12; datalayer_extended.bydAtto3.unknown13 = BMS_unknown13; + + // Update requests from webserver datalayer + if (datalayer_extended.bydAtto3.UserRequestCrashReset && stateMachineClearCrash == NOT_RUNNING) { + stateMachineClearCrash = STARTED; + datalayer_extended.bydAtto3.UserRequestCrashReset = false; + } } void handle_incoming_can_frame_battery(CAN_frame rx_frame) { @@ -470,6 +491,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; case 0x7EF: //OBD2 PID reply from battery + if (rx_frame.data.u8[0] == 0x10) { + transmit_can_frame(&ATTO_3_7E7_ACK, can_config.battery); //Send next line request + } pid_reply = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]); switch (pid_reply) { case POLL_FOR_BATTERY_SOC: @@ -548,16 +572,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { //Send 50ms message if (currentMillis - previousMillis50 >= INTERVAL_50_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis50 >= INTERVAL_50_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis50)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis50 = currentMillis; // Set close contactors to allowed (Useful for crashed packs, started via contactor control thru GPIO) @@ -603,7 +620,6 @@ void transmit_can_battery() { } if (counter_100ms > 3) { - ATTO_3_441.data.u8[4] = 0x9D; ATTO_3_441.data.u8[5] = 0x01; ATTO_3_441.data.u8[6] = 0xFF; @@ -614,6 +630,27 @@ void transmit_can_battery() { #ifdef DOUBLE_BATTERY transmit_can_frame(&ATTO_3_441, can_config.battery_double); #endif //DOUBLE_BATTERY + switch (stateMachineClearCrash) { + case STARTED: + ATTO_3_7E7_CLEAR_CRASH.data = {0x02, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}; + transmit_can_frame(&ATTO_3_7E7_CLEAR_CRASH, can_config.battery); + stateMachineClearCrash = RUNNING_STEP_1; + break; + case RUNNING_STEP_1: + ATTO_3_7E7_CLEAR_CRASH.data = {0x04, 0x14, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}; + transmit_can_frame(&ATTO_3_7E7_CLEAR_CRASH, can_config.battery); + stateMachineClearCrash = RUNNING_STEP_2; + break; + case RUNNING_STEP_2: + ATTO_3_7E7_CLEAR_CRASH.data = {0x03, 0x19, 0x02, 0x09, 0x00, 0x00, 0x00, 0x00}; + transmit_can_frame(&ATTO_3_7E7_CLEAR_CRASH, can_config.battery); + stateMachineClearCrash = NOT_RUNNING; + break; + case NOT_RUNNING: + break; + default: + break; + } } // Send 200ms CAN Message if (currentMillis - previousMillis200 >= INTERVAL_200_MS) { @@ -735,10 +772,12 @@ void transmit_can_battery() { break; } - transmit_can_frame(&ATTO_3_7E7_POLL, can_config.battery); + if (stateMachineClearCrash == NOT_RUNNING) { //Don't poll battery for data if clear crash running + transmit_can_frame(&ATTO_3_7E7_POLL, can_config.battery); #ifdef DOUBLE_BATTERY - transmit_can_frame(&ATTO_3_7E7_POLL, can_config.battery_double); + transmit_can_frame(&ATTO_3_7E7_POLL, can_config.battery_double); #endif //DOUBLE_BATTERY + } } } diff --git a/Software/src/battery/CELLPOWER-BMS.cpp b/Software/src/battery/CELLPOWER-BMS.cpp index 9a73ed40..e0a480c8 100644 --- a/Software/src/battery/CELLPOWER-BMS.cpp +++ b/Software/src/battery/CELLPOWER-BMS.cpp @@ -316,11 +316,10 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { + // Send 1s CAN Message if (currentMillis - previousMillis1s >= INTERVAL_1_S) { - previousMillis1s = currentMillis; /* diff --git a/Software/src/battery/CHADEMO-BATTERY.cpp b/Software/src/battery/CHADEMO-BATTERY.cpp index e864b285..e2ba0095 100644 --- a/Software/src/battery/CHADEMO-BATTERY.cpp +++ b/Software/src/battery/CHADEMO-BATTERY.cpp @@ -655,9 +655,7 @@ void update_evse_discharge_capabilities(CAN_frame& f) { CHADEMO_208.data.u8[7] = highByte(x208_evse_dischg_cap.lower_threshold_voltage); } -void transmit_can_battery() { - - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { handlerBeforeMillis = currentMillis; handle_chademo_sequence(); @@ -665,12 +663,6 @@ void transmit_can_battery() { // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis100 >= INTERVAL_100_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis100)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis100 = currentMillis; /* no EVSE messages should be sent until the vehicle has diff --git a/Software/src/battery/CMFA-EV-BATTERY.cpp b/Software/src/battery/CMFA-EV-BATTERY.cpp index 2e6282ae..322fa140 100644 --- a/Software/src/battery/CMFA-EV-BATTERY.cpp +++ b/Software/src/battery/CMFA-EV-BATTERY.cpp @@ -513,14 +513,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 10ms CAN Message if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10ms >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10ms)); - } previousMillis10ms = currentMillis; transmit_can_frame(&CMFA_1EA, can_config.battery); transmit_can_frame(&CMFA_135, can_config.battery); diff --git a/Software/src/battery/CanBattery.h b/Software/src/battery/CanBattery.h new file mode 100644 index 00000000..efb55cbe --- /dev/null +++ b/Software/src/battery/CanBattery.h @@ -0,0 +1,17 @@ +#ifndef CAN_BATTERY_H +#define CAN_BATTERY_H + +#include "src/devboard/utils/types.h" + +// Abstract base class for next-generation battery implementations. +// Defines the interface to call battery specific functionality. +// No support for double battery yet. +class CanBattery { + public: + virtual void setup(void) = 0; + virtual void handle_incoming_can_frame(CAN_frame rx_frame) = 0; + virtual void update_values() = 0; + virtual void transmit_can(unsigned long currentMillis) = 0; +}; + +#endif diff --git a/Software/src/battery/ECMP-BATTERY.cpp b/Software/src/battery/ECMP-BATTERY.cpp index 9bea886a..ce349179 100644 --- a/Software/src/battery/ECMP-BATTERY.cpp +++ b/Software/src/battery/ECMP-BATTERY.cpp @@ -288,8 +288,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 1s CAN Message if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { previousMillis1000 = currentMillis; diff --git a/Software/src/battery/FOXESS-BATTERY.cpp b/Software/src/battery/FOXESS-BATTERY.cpp index 465ad8ec..cb256d9e 100644 --- a/Software/src/battery/FOXESS-BATTERY.cpp +++ b/Software/src/battery/FOXESS-BATTERY.cpp @@ -474,9 +474,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); - +void transmit_can_battery(unsigned long currentMillis) { // Send 500ms CAN Message if (currentMillis - previousMillis500 >= INTERVAL_500_MS) { previousMillis500 = currentMillis; diff --git a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp index ddc63814..b9767694 100644 --- a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp +++ b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp @@ -207,16 +207,10 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { + // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis100 >= INTERVAL_100_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis100)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis100 = currentMillis; // Send CAN goes here... diff --git a/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp b/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp index 618b32c8..22b2295d 100644 --- a/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp +++ b/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp @@ -1,5 +1,6 @@ #include "../include.h" #ifdef JAGUAR_IPACE_BATTERY +#include "../communication/can/comm_can.h" #include "../datalayer/datalayer.h" #include "../devboard/utils/events.h" #include "JAGUAR-IPACE-BATTERY.h" @@ -62,7 +63,7 @@ void print_units(char* header, int value, char* units) { logging.print(units); } -void update_values_battery() { +void JaguarIpaceBattery::update_values() { datalayer.battery.status.real_soc = HVBattAvgSOC * 100; //Add two decimals @@ -119,14 +120,7 @@ void update_values_battery() { #endif } -void handle_incoming_can_frame_battery(CAN_frame rx_frame) { - - // Do not log noisy startup messages - there are many ! - if (rx_frame.ID == 0 && rx_frame.DLC == 8 && rx_frame.data.u8[0] == 0 && rx_frame.data.u8[1] == 0 && - rx_frame.data.u8[2] == 0 && rx_frame.data.u8[3] == 0 && rx_frame.data.u8[4] == 0 && rx_frame.data.u8[5] == 0 && - rx_frame.data.u8[6] == 0x80 && rx_frame.data.u8[7] == 0) { - return; - } +void JaguarIpaceBattery::handle_incoming_can_frame(CAN_frame rx_frame) { switch (rx_frame.ID) { // These messages are periodically transmitted by the battery case 0x080: @@ -222,38 +216,17 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { default: break; } - - // Discard non-interesting can messages so they do not get logged via serial - if (rx_frame.ID < 0x500) { - return; - } - - // All CAN messages recieved will be logged via serial - logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D - logging.print(" "); - logging.print(rx_frame.ID, HEX); - logging.print(" "); - logging.print(rx_frame.DLC); - logging.print(" "); - for (int i = 0; i < rx_frame.DLC; ++i) { - logging.print(rx_frame.data.u8[i], HEX); - logging.print(" "); - } - logging.println(""); } -void transmit_can_battery() { - unsigned long currentMillis = millis(); - +void JaguarIpaceBattery::transmit_can(unsigned long currentMillis) { /* Send keep-alive every 200ms */ if (currentMillis - previousMillisKeepAlive >= INTERVAL_200_MS) { previousMillisKeepAlive = currentMillis; transmit_can_frame(&ipace_keep_alive, can_config.battery); - return; } } -void setup_battery(void) { // Performs one time setup at startup +void JaguarIpaceBattery::setup(void) { // Performs one time setup at startup strncpy(datalayer.system.info.battery_protocol, "Jaguar I-PACE", 63); datalayer.system.info.battery_protocol[63] = '\0'; datalayer.battery.info.number_of_cells = 108; diff --git a/Software/src/battery/JAGUAR-IPACE-BATTERY.h b/Software/src/battery/JAGUAR-IPACE-BATTERY.h index d89e4770..f91444a0 100644 --- a/Software/src/battery/JAGUAR-IPACE-BATTERY.h +++ b/Software/src/battery/JAGUAR-IPACE-BATTERY.h @@ -1,15 +1,23 @@ #ifndef JAGUAR_IPACE_BATTERY_H #define JAGUAR_IPACE_BATTERY_H -#include "../include.h" + +#include "CanBattery.h" #define BATTERY_SELECTED +#define SELECTED_BATTERY_CLASS JaguarIpaceBattery + #define MAX_PACK_VOLTAGE_DV 4546 //5000 = 500.0V #define MIN_PACK_VOLTAGE_DV 3370 #define MAX_CELL_DEVIATION_MV 250 #define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value #define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value -void setup_battery(void); -void transmit_can_frame(CAN_frame* tx_frame, int interface); +class JaguarIpaceBattery : public CanBattery { + public: + virtual void setup(void); + virtual void handle_incoming_can_frame(CAN_frame rx_frame); + virtual void update_values(); + virtual void transmit_can(unsigned long currentMillis); +}; #endif diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index ce70cd2c..9bac65bc 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -1082,8 +1082,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { if (startedUp) { //Send Contactor closing message loop // Check if we still have messages to send @@ -1108,13 +1107,6 @@ void transmit_can_battery() { //Send 200ms CANFD message if (currentMillis - previousMillis200ms >= INTERVAL_200_MS) { previousMillis200ms = currentMillis; - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis200ms >= INTERVAL_200_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis200ms)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } - previousMillis200ms = currentMillis; EGMP_7E4.data.u8[3] = KIA_7E4_COUNTER; diff --git a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp index a8d85114..53d52329 100644 --- a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp @@ -924,8 +924,7 @@ void handle_incoming_can_frame_battery2(CAN_frame rx_frame) { } #endif //DOUBLE_BATTERY -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { if (!startedUp) { return; // Don't send any CAN messages towards battery until it has started up @@ -948,12 +947,6 @@ void transmit_can_battery() { } // Send 10ms CAN Message if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10 >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis10 = currentMillis; switch (counter_200) { diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 71c4c88f..37d36b08 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -230,8 +230,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 1000ms CAN Message if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { diff --git a/Software/src/battery/MEB-BATTERY.cpp b/Software/src/battery/MEB-BATTERY.cpp index 8c9f84ad..8d9e4f8c 100644 --- a/Software/src/battery/MEB-BATTERY.cpp +++ b/Software/src/battery/MEB-BATTERY.cpp @@ -1627,9 +1627,8 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); - // Send 10ms CAN Message +void transmit_can_battery(unsigned long currentMillis) { + if (currentMillis > last_can_msg_timestamp + 500) { #ifdef DEBUG_LOG if (first_can_msg) @@ -1642,15 +1641,8 @@ void transmit_can_battery() { datalayer.system.status.battery_allows_contactor_closing = false; } } - + // Send 10ms CAN Message if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10ms >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME) && - previousMillis10ms > 0) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10ms)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis10ms = currentMillis; MEB_0FC.data.u8[1] = ((MEB_0FC.data.u8[1] & 0xF0) | counter_10ms); diff --git a/Software/src/battery/MG-5-BATTERY.cpp b/Software/src/battery/MG-5-BATTERY.cpp index 07c54a7d..ab12c6e8 100644 --- a/Software/src/battery/MG-5-BATTERY.cpp +++ b/Software/src/battery/MG-5-BATTERY.cpp @@ -108,16 +108,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { //Send 10ms message if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10 >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis10 = currentMillis; transmit_can_frame(&MG_5_100, can_config.battery); diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index bea67ddd..8e45919f 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -1071,13 +1071,10 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { if (datalayer.system.status.BMS_reset_in_progress || datalayer.system.status.BMS_startup_in_progress) { // Transmitting towards battery is halted while BMS is being reset - // Reset sending counters to avoid overrun messages when reset is over previousMillis10 = currentMillis; previousMillis100 = currentMillis; previousMillis10s = currentMillis; @@ -1088,12 +1085,6 @@ void transmit_can_battery() { //Send 10ms message if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10 >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis10 = currentMillis; switch (mprun10) { diff --git a/Software/src/battery/ORION-BMS.cpp b/Software/src/battery/ORION-BMS.cpp index f0ba33a8..54ad5f25 100644 --- a/Software/src/battery/ORION-BMS.cpp +++ b/Software/src/battery/ORION-BMS.cpp @@ -132,8 +132,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // No transmission needed for this integration } diff --git a/Software/src/battery/PYLON-BATTERY.cpp b/Software/src/battery/PYLON-BATTERY.cpp index e41eb48c..847c935d 100644 --- a/Software/src/battery/PYLON-BATTERY.cpp +++ b/Software/src/battery/PYLON-BATTERY.cpp @@ -158,11 +158,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 1s CAN Message if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { - previousMillis1000 = currentMillis; transmit_can_frame(&PYLON_3010, can_config.battery); // Heartbeat diff --git a/Software/src/battery/RANGE-ROVER-PHEV-BATTERY.cpp b/Software/src/battery/RANGE-ROVER-PHEV-BATTERY.cpp index 3ff1325e..b87bd709 100644 --- a/Software/src/battery/RANGE-ROVER-PHEV-BATTERY.cpp +++ b/Software/src/battery/RANGE-ROVER-PHEV-BATTERY.cpp @@ -301,11 +301,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 50ms CAN Message if (currentMillis - previousMillis50ms >= INTERVAL_50_MS) { - previousMillis50ms = currentMillis; transmit_can_frame(&RANGE_ROVER_18B, can_config.battery); diff --git a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp index 4fa4a6e4..e8a8ccaa 100644 --- a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp +++ b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp @@ -210,8 +210,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 100ms CAN Message (for 2.4s, then pause 10s) if ((currentMillis - previousMillis100) >= (INTERVAL_100_MS + GVL_pause)) { previousMillis100 = currentMillis; diff --git a/Software/src/battery/RENAULT-TWIZY.cpp b/Software/src/battery/RENAULT-TWIZY.cpp index b6c746f2..6965d514 100644 --- a/Software/src/battery/RENAULT-TWIZY.cpp +++ b/Software/src/battery/RENAULT-TWIZY.cpp @@ -127,7 +127,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { +void transmit_can_battery(unsigned long currentMillis) { // we do not need to send anything to the battery for now } diff --git a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp index 5501782b..35e9d084 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp @@ -493,14 +493,10 @@ void RenaultZoeGen1Battery::handle_incoming_can_frame(CAN_frame rx_frame) { } } -void RenaultZoeGen1Battery::transmit_can() { - unsigned long currentMillis = millis(); +void RenaultZoeGen1Battery::transmit_can(unsigned long currentMillis) { + // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis100 >= INTERVAL_100_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis100)); - } previousMillis100 = currentMillis; transmit_can_frame(&ZOE_423, can_config.battery); diff --git a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h index c5f6b48f..dee94a35 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h +++ b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h @@ -1,11 +1,10 @@ #ifndef RENAULT_ZOE_GEN1_BATTERY_H #define RENAULT_ZOE_GEN1_BATTERY_H -#include "../include.h" + +#include "CanBattery.h" #define BATTERY_SELECTED - -// Indicates that the object-oriented battery interface is to be activated. -#define OO_BATTERY_SELECTED +#define SELECTED_BATTERY_CLASS RenaultZoeGen1Battery #define MAX_PACK_VOLTAGE_DV 4200 //5000 = 500.0V #define MIN_PACK_VOLTAGE_DV 3000 @@ -18,7 +17,7 @@ class RenaultZoeGen1Battery : public CanBattery { virtual void setup(void); virtual void handle_incoming_can_frame(CAN_frame rx_frame); virtual void update_values(); - virtual void transmit_can(); + virtual void transmit_can(unsigned long currentMillis); }; #endif diff --git a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp index a34203ae..ebc3453b 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp @@ -371,8 +371,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { previousMillis100 = currentMillis; @@ -391,10 +390,6 @@ void transmit_can_battery() { // Send 200ms CAN Message if (currentMillis - previousMillis200 >= INTERVAL_200_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis200 >= INTERVAL_200_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis200)); - } previousMillis200 = currentMillis; // Update current poll from the array diff --git a/Software/src/battery/RJXZS-BMS.cpp b/Software/src/battery/RJXZS-BMS.cpp index f08e9659..dd0c59eb 100644 --- a/Software/src/battery/RJXZS-BMS.cpp +++ b/Software/src/battery/RJXZS-BMS.cpp @@ -571,11 +571,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 10s CAN Message if (currentMillis - previousMillis10s >= INTERVAL_10_S) { - previousMillis10s = currentMillis; if (datalayer.battery.status.bms_status == FAULT) { diff --git a/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp b/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp index db1e4377..a48bf1d8 100644 --- a/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp +++ b/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp @@ -333,17 +333,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); - +void transmit_can_battery(unsigned long currentMillis) { //Send 10ms message if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10 >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis10 = currentMillis; SANTAFE_200.data.u8[6] = (counter_200 << 1); diff --git a/Software/src/battery/SIMPBMS-BATTERY.cpp b/Software/src/battery/SIMPBMS-BATTERY.cpp index 5feedb3d..c13e32a9 100644 --- a/Software/src/battery/SIMPBMS-BATTERY.cpp +++ b/Software/src/battery/SIMPBMS-BATTERY.cpp @@ -115,7 +115,9 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery() {} +void transmit_can_battery(unsigned long currentMillis) { + // No periodic transmitting for this battery type +} void setup_battery(void) { // Performs one time setup at startup strncpy(datalayer.system.info.battery_protocol, "SIMPBMS battery", 63); diff --git a/Software/src/battery/SONO-BATTERY.cpp b/Software/src/battery/SONO-BATTERY.cpp index d9de102f..24592e0b 100644 --- a/Software/src/battery/SONO-BATTERY.cpp +++ b/Software/src/battery/SONO-BATTERY.cpp @@ -137,9 +137,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery() { - unsigned long currentMillis = millis(); - +void transmit_can_battery(unsigned long currentMillis) { // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { previousMillis100 = currentMillis; diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index d0cc62e1..e88f5fea 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -1864,14 +1864,12 @@ int index_1CF = 0; int index_118 = 0; #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) -void transmit_can_battery() { +void transmit_can_battery(unsigned long currentMillis) { /*From bielec: My fist 221 message, to close the contactors is 0x41, 0x11, 0x01, 0x00, 0x00, 0x00, 0x20, 0x96 and then, to cause "hv_up_for_drive" I send an additional 221 message 0x61, 0x15, 0x01, 0x00, 0x00, 0x00, 0x20, 0xBA so two 221 messages are being continuously transmitted. When I want to shut down, I stop the second message and only send the first, for a few cycles, then stop all messages which causes the contactor to open. */ - unsigned long currentMillis = millis(); - if (!cellvoltagesRead) { return; //All cellvoltages not read yet, do not proceed with contactor closing } @@ -1906,12 +1904,6 @@ the first, for a few cycles, then stop all messages which causes the contactor //Send 50ms message if (currentMillis - previousMillis50 >= INTERVAL_50_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis50 >= INTERVAL_50_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis50)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis50 = currentMillis; if ((datalayer.system.status.inverter_allows_contactor_closing == true) && diff --git a/Software/src/battery/TEST-FAKE-BATTERY.cpp b/Software/src/battery/TEST-FAKE-BATTERY.cpp index fb1cf729..6c701200 100644 --- a/Software/src/battery/TEST-FAKE-BATTERY.cpp +++ b/Software/src/battery/TEST-FAKE-BATTERY.cpp @@ -130,8 +130,7 @@ void handle_incoming_can_frame_battery2(CAN_frame rx_frame) { void handle_incoming_can_frame_battery(CAN_frame rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { previousMillis100 = currentMillis; diff --git a/Software/src/battery/VOLVO-SPA-BATTERY.cpp b/Software/src/battery/VOLVO-SPA-BATTERY.cpp index aaf33b63..97b3891b 100644 --- a/Software/src/battery/VOLVO-SPA-BATTERY.cpp +++ b/Software/src/battery/VOLVO-SPA-BATTERY.cpp @@ -435,16 +435,9 @@ void readCellVoltages() { transmit_can_frame(&VOLVO_CELL_U_Req, can_config.battery); //Send cell voltage read request for first module } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis100 >= INTERVAL_100_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis100)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis100 = currentMillis; transmit_can_frame(&VOLVO_536, can_config.battery); //Send 0x536 Network managing frame to keep BMS alive diff --git a/Software/src/battery/VOLVO-SPA-HYBRID-BATTERY.cpp b/Software/src/battery/VOLVO-SPA-HYBRID-BATTERY.cpp index c0d1ead7..556fdf84 100644 --- a/Software/src/battery/VOLVO-SPA-HYBRID-BATTERY.cpp +++ b/Software/src/battery/VOLVO-SPA-HYBRID-BATTERY.cpp @@ -610,16 +610,9 @@ void readCellVoltages() { transmit_can_frame(&VOLVO_CELL_U_Req, can_config.battery); //Send cell voltage read request for first module } -void transmit_can_battery() { - unsigned long currentMillis = millis(); +void transmit_can_battery(unsigned long currentMillis) { // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis100 >= INTERVAL_100_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis100)); - } else { - clear_event(EVENT_CAN_OVERRUN); - } previousMillis100 = currentMillis; transmit_can_frame(&VOLVO_536, can_config.battery); //Send 0x536 Network managing frame to keep BMS alive diff --git a/Software/src/charger/CHARGERS.h b/Software/src/charger/CHARGERS.h index a41b5bc9..e09cd633 100644 --- a/Software/src/charger/CHARGERS.h +++ b/Software/src/charger/CHARGERS.h @@ -11,6 +11,6 @@ #endif void map_can_frame_to_variable_charger(CAN_frame rx_frame); -void transmit_can_charger(); +void transmit_can_charger(unsigned long currentMillis); #endif diff --git a/Software/src/charger/CHEVY-VOLT-CHARGER.cpp b/Software/src/charger/CHEVY-VOLT-CHARGER.cpp index 80377676..fe85d446 100644 --- a/Software/src/charger/CHEVY-VOLT-CHARGER.cpp +++ b/Software/src/charger/CHEVY-VOLT-CHARGER.cpp @@ -98,8 +98,7 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) { } } -void transmit_can_charger() { - unsigned long currentMillis = millis(); +void transmit_can_charger(unsigned long currentMillis) { uint16_t Vol_temp = 0; uint16_t setpoint_HV_VDC = floor(datalayer.charger.charger_setpoint_HV_VDC); diff --git a/Software/src/charger/NISSAN-LEAF-CHARGER.cpp b/Software/src/charger/NISSAN-LEAF-CHARGER.cpp index 194fad95..52e4b5cd 100644 --- a/Software/src/charger/NISSAN-LEAF-CHARGER.cpp +++ b/Software/src/charger/NISSAN-LEAF-CHARGER.cpp @@ -156,8 +156,7 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) { } } -void transmit_can_charger() { - unsigned long currentMillis = millis(); +void transmit_can_charger(unsigned long currentMillis) { /* Send keepalive with mode every 10ms */ if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) { diff --git a/Software/src/communication/can/comm_can.cpp b/Software/src/communication/can/comm_can.cpp index 61d00970..71b11db6 100644 --- a/Software/src/communication/can/comm_can.cpp +++ b/Software/src/communication/can/comm_can.cpp @@ -3,12 +3,12 @@ #include "src/devboard/sdcard/sdcard.h" // Parameters - -CAN_device_t CAN_cfg; // CAN Config -const int rx_queue_size = 10; // Receive Queue size +CAN_device_t CAN_cfg; // CAN Config +const uint8_t rx_queue_size = 10; // Receive Queue size volatile bool send_ok_native = 0; volatile bool send_ok_2515 = 0; volatile bool send_ok_2518 = 0; +static unsigned long previousMillis10 = 0; #ifdef CAN_ADDON static const uint32_t QUARTZ_FREQUENCY = CRYSTAL_FREQUENCY_MHZ * 1000000UL; //MHZ configured in USER_SETTINGS.h @@ -105,25 +105,26 @@ void init_CAN() { } // Transmit functions -void transmit_can() { +void transmit_can(unsigned long currentMillis) { + if (!allowed_to_send_CAN) { return; //Global block of CAN messages } #ifndef RS485_BATTERY_SELECTED - transmit_can_battery(); + transmit_can_battery(currentMillis); #endif #ifdef CAN_INVERTER_SELECTED - transmit_can_inverter(); + transmit_can_inverter(currentMillis); #endif // CAN_INVERTER_SELECTED #ifdef CHARGER_SELECTED - transmit_can_charger(); + transmit_can_charger(currentMillis); #endif // CHARGER_SELECTED #ifdef CAN_SHUNT_SELECTED - transmit_can_shunt(); + transmit_can_shunt(currentMillis); #endif // CAN_SHUNT_SELECTED } diff --git a/Software/src/communication/can/comm_can.h b/Software/src/communication/can/comm_can.h index ea047878..1ebdcc6b 100644 --- a/Software/src/communication/can/comm_can.h +++ b/Software/src/communication/can/comm_can.h @@ -16,6 +16,7 @@ #endif //CANFD_ADDON void dump_can_frame(CAN_frame& frame, frameDirection msgDir); +void transmit_can_frame(CAN_frame* tx_frame, int interface); /** * @brief Initialization function for CAN. @@ -40,10 +41,11 @@ void transmit_can_frame(); * @brief Send CAN messages to all components * * @param[in] void + * @param[in] unsigned long currentMillis * * @return void */ -void transmit_can(); +void transmit_can(unsigned long currentMillis); /** * @brief Receive CAN messages from all interfaces diff --git a/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp b/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp index 815abe22..0e5d4d58 100644 --- a/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp +++ b/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp @@ -94,7 +94,7 @@ void init_contactors() { #ifdef BMS_2_POWER //Hardware supports 2x BMS pinMode(BMS_2_POWER, OUTPUT); digitalWrite(BMS_2_POWER, HIGH); -#endif BMS_2_POWER +#endif //BMS_2_POWER #endif // HW with dedicated BMS pins #if defined(PERIODIC_BMS_RESET) || defined(REMOTE_BMS_RESET) // User has enabled BMS reset, turn on output on start pinMode(BMS_POWER, OUTPUT); diff --git a/Software/src/datalayer/datalayer_extended.h b/Software/src/datalayer/datalayer_extended.h index 5f5ddc45..dcba9e2c 100644 --- a/Software/src/datalayer/datalayer_extended.h +++ b/Software/src/datalayer/datalayer_extended.h @@ -163,6 +163,9 @@ typedef struct { } DATALAYER_INFO_BMWI3; typedef struct { + /** bool */ + /** User requesting crash reset via WebUI*/ + bool UserRequestCrashReset = false; /** bool */ /** Which SOC method currently used. 0 = Estimated, 1 = Measured */ bool SOC_method = 0; diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index dc135c6a..7ec7a2d7 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -19,11 +19,19 @@ battery_pause_status emulator_pause_status = NORMAL; //battery pause status end void update_machineryprotection() { - // Check if the CPU is too hot + /* Check if the ESP32 CPU running the Battery-Emulator is too hot. + We start with a warning, you can start to see Wifi issues if it becomes too hot + If the chip starts to approach the design limit, we perform a graceful shutdown */ if (datalayer.system.info.CPU_temperature > 80.0f) { - set_event(EVENT_CPU_OVERHEAT, 0); + set_event(EVENT_CPU_OVERHEATING, 0); } else { - clear_event(EVENT_CPU_OVERHEAT); + clear_event(EVENT_CPU_OVERHEATING); + } + if (datalayer.system.info.CPU_temperature > 110.0f) { + set_event(EVENT_CPU_OVERHEATED, 0); + } + if (datalayer.system.info.CPU_temperature < 105.0f) { + clear_event(EVENT_CPU_OVERHEATED); //Hysteresis on the clearing } // Check health status of CAN interfaces diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 7849e997..0f3c68e7 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -39,7 +39,7 @@ void init_events(void) { events.entries[EVENT_CANMCP2515_INIT_FAILURE].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CANFD_BUFFER_FULL].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_BUFFER_FULL].level = EVENT_LEVEL_WARNING; - events.entries[EVENT_CAN_OVERRUN].level = EVENT_LEVEL_INFO; + events.entries[EVENT_TASK_OVERRUN].level = EVENT_LEVEL_INFO; events.entries[EVENT_CAN_CORRUPTED_WARNING].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_NATIVE_TX_FAILURE].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_BATTERY_MISSING].level = EVENT_LEVEL_ERROR; @@ -47,7 +47,8 @@ void init_events(void) { events.entries[EVENT_CAN_CHARGER_MISSING].level = EVENT_LEVEL_INFO; events.entries[EVENT_CAN_INVERTER_MISSING].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CONTACTOR_WELDED].level = EVENT_LEVEL_WARNING; - events.entries[EVENT_CPU_OVERHEAT].level = EVENT_LEVEL_WARNING; + events.entries[EVENT_CPU_OVERHEATING].level = EVENT_LEVEL_WARNING; + events.entries[EVENT_CPU_OVERHEATED].level = EVENT_LEVEL_ERROR; events.entries[EVENT_WATER_INGRESS].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CHARGE_LIMIT_EXCEEDED].level = EVENT_LEVEL_INFO; events.entries[EVENT_DISCHARGE_LIMIT_EXCEEDED].level = EVENT_LEVEL_INFO; @@ -81,6 +82,7 @@ void init_events(void) { events.entries[EVENT_INVERTER_OPEN_CONTACTOR].level = EVENT_LEVEL_INFO; events.entries[EVENT_INTERFACE_MISSING].level = EVENT_LEVEL_INFO; events.entries[EVENT_MODBUS_INVERTER_MISSING].level = EVENT_LEVEL_INFO; + events.entries[EVENT_NO_ENABLE_DETECTED].level = EVENT_LEVEL_INFO; events.entries[EVENT_ERROR_OPEN_CONTACTOR].level = EVENT_LEVEL_INFO; events.entries[EVENT_CELL_CRITICAL_UNDER_VOLTAGE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CELL_CRITICAL_OVER_VOLTAGE].level = EVENT_LEVEL_ERROR; @@ -176,8 +178,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { return "MCP2518FD message failed to send. Buffer full or no one on the bus to ACK the message!"; case EVENT_CAN_BUFFER_FULL: return "MCP2515 message failed to send. Buffer full or no one on the bus to ACK the message!"; - case EVENT_CAN_OVERRUN: - return "CAN message failed to send within defined time. Contact developers, CPU load might be too high."; + case EVENT_TASK_OVERRUN: + return "Task took too long to complete. CPU load might be too high. Info message, no action required."; case EVENT_CAN_CORRUPTED_WARNING: return "High amount of corrupted CAN messages detected. Check CAN wire shielding!"; case EVENT_CAN_NATIVE_TX_FAILURE: @@ -192,8 +194,10 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { return "Inverter not sending messages via CAN for the last 60 seconds. Check wiring!"; case EVENT_CONTACTOR_WELDED: return "Contactors sticking/welded. Inspect battery with caution!"; - case EVENT_CPU_OVERHEAT: + case EVENT_CPU_OVERHEATING: return "Battery-Emulator CPU overheating! Increase airflow/cooling to increase hardware lifespan!"; + case EVENT_CPU_OVERHEATED: + return "Battery-Emulator CPU melting! Performing controlled shutdown until temperature drops!"; case EVENT_CHARGE_LIMIT_EXCEEDED: return "Inverter is charging faster than battery is allowing."; case EVENT_DISCHARGE_LIMIT_EXCEEDED: @@ -269,6 +273,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { "Check other error code for reason!"; case EVENT_MODBUS_INVERTER_MISSING: return "Modbus inverter has not sent any data. Inspect communication wiring!"; + case EVENT_NO_ENABLE_DETECTED: + return "Inverter Enable line has not been active for a long time. Check Wiring!"; case EVENT_CELL_CRITICAL_UNDER_VOLTAGE: return "CELL VOLTAGE CRITICALLY LOW! Not possible to continue. Inspect battery!"; case EVENT_CELL_UNDER_VOLTAGE: diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index c651d80b..ecff3118 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -12,7 +12,6 @@ XX(EVENT_CANMCP2515_INIT_FAILURE) \ XX(EVENT_CANFD_BUFFER_FULL) \ XX(EVENT_CAN_BUFFER_FULL) \ - XX(EVENT_CAN_OVERRUN) \ XX(EVENT_CAN_CORRUPTED_WARNING) \ XX(EVENT_CAN_BATTERY_MISSING) \ XX(EVENT_CAN_BATTERY2_MISSING) \ @@ -21,7 +20,8 @@ XX(EVENT_CAN_NATIVE_TX_FAILURE) \ XX(EVENT_CHARGE_LIMIT_EXCEEDED) \ XX(EVENT_CONTACTOR_WELDED) \ - XX(EVENT_CPU_OVERHEAT) \ + XX(EVENT_CPU_OVERHEATING) \ + XX(EVENT_CPU_OVERHEATED) \ XX(EVENT_DISCHARGE_LIMIT_EXCEEDED) \ XX(EVENT_WATER_INGRESS) \ XX(EVENT_12V_LOW) \ @@ -55,6 +55,7 @@ XX(EVENT_INVERTER_OPEN_CONTACTOR) \ XX(EVENT_INTERFACE_MISSING) \ XX(EVENT_MODBUS_INVERTER_MISSING) \ + XX(EVENT_NO_ENABLE_DETECTED) \ XX(EVENT_ERROR_OPEN_CONTACTOR) \ XX(EVENT_CELL_CRITICAL_UNDER_VOLTAGE) \ XX(EVENT_CELL_CRITICAL_OVER_VOLTAGE) \ @@ -73,6 +74,7 @@ XX(EVENT_SERIAL_RX_FAILURE) \ XX(EVENT_SERIAL_TX_FAILURE) \ XX(EVENT_SERIAL_TRANSMITTER_FAILURE) \ + XX(EVENT_TASK_OVERRUN) \ XX(EVENT_RESET_UNKNOWN) \ XX(EVENT_RESET_POWERON) \ XX(EVENT_RESET_EXT) \ diff --git a/Software/src/devboard/utils/types.h b/Software/src/devboard/utils/types.h index 0d1195a2..28941f8f 100644 --- a/Software/src/devboard/utils/types.h +++ b/Software/src/devboard/utils/types.h @@ -37,12 +37,6 @@ enum PrechargeState { #define INTERVAL_60_S 60000 #define INTERVAL_10_MS_DELAYED 15 -#define INTERVAL_20_MS_DELAYED 30 -#define INTERVAL_30_MS_DELAYED 40 -#define INTERVAL_50_MS_DELAYED 65 -#define INTERVAL_100_MS_DELAYED 120 -#define INTERVAL_200_MS_DELAYED 240 -#define INTERVAL_500_MS_DELAYED 550 #define CAN_STILL_ALIVE 60 // Set by battery each time we get a CAN message. Decrements every second. When reaching 0, sets event diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 1dc7d4d7..d9d42971 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -487,6 +487,7 @@ String advanced_battery_processor(const String& var) { #ifdef BYD_ATTO_3_BATTERY static const char* SOCmethod[2] = {"Estimated from voltage", "Measured by BMS"}; + content += ""; content += "

SOC method used: " + String(SOCmethod[datalayer_extended.bydAtto3.SOC_method]) + "

"; content += "

SOC estimated: " + String(datalayer_extended.bydAtto3.SOC_estimated) + "

"; content += "

SOC highprec: " + String(datalayer_extended.bydAtto3.SOC_highprec) + "

"; @@ -1516,6 +1517,18 @@ String advanced_battery_processor(const String& var) { content += "function goToMainPage() { window.location.href = '/'; }"; content += ""; content += ""; + content += "