From 2cecc3d55a2ccdb335d0f93613689e241eb9ef88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 23 Sep 2024 23:22:15 +0300 Subject: [PATCH 01/26] Add inverter missing from CAN event, Solax --- Software/src/devboard/utils/events.cpp | 3 +++ Software/src/devboard/utils/events.h | 1 + Software/src/inverter/SOLAX-CAN.cpp | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index ed41da11..3457bd07 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -148,6 +148,7 @@ void init_events(void) { events.entries[EVENT_CANFD_RX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CAN_RX_WARNING].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_TX_FAILURE].level = EVENT_LEVEL_ERROR; + events.entries[EVENT_CAN_INVERTER_MISSING].level = EVENT_LEVEL_WARNING; 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; @@ -258,6 +259,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { return "ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!"; case EVENT_CAN_TX_FAILURE: return "ERROR: CAN messages failed to transmit, or no one on the bus to ACK the message!"; + case EVENT_CAN_INVERTER_MISSING: + return "Warning: Inverter not sending messages on CAN bus. Check wiring!"; case EVENT_CHARGE_LIMIT_EXCEEDED: return "Info: Inverter is charging faster than battery is allowing."; case EVENT_DISCHARGE_LIMIT_EXCEEDED: diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 570aa302..24f7b282 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -34,6 +34,7 @@ XX(EVENT_CANFD_RX_FAILURE) \ XX(EVENT_CAN_RX_WARNING) \ XX(EVENT_CAN_TX_FAILURE) \ + XX(EVENT_CAN_INVERTER_MISSING) \ XX(EVENT_CHARGE_LIMIT_EXCEEDED) \ XX(EVENT_DISCHARGE_LIMIT_EXCEEDED) \ XX(EVENT_WATER_INGRESS) \ diff --git a/Software/src/inverter/SOLAX-CAN.cpp b/Software/src/inverter/SOLAX-CAN.cpp index 45a5dde8..7aee920c 100644 --- a/Software/src/inverter/SOLAX-CAN.cpp +++ b/Software/src/inverter/SOLAX-CAN.cpp @@ -18,6 +18,7 @@ static unsigned long LastFrameTime = 0; static uint8_t number_of_batteries = 1; static uint16_t capped_capacity_Wh; static uint16_t capped_remaining_capacity_Wh; +static uint16_t inverter_missing_on_can = 0; //CAN message translations from this amazing repository: https://github.com/rand12345/solax_can_bus @@ -88,6 +89,12 @@ void update_values_can_inverter() { //This function maps all the values fetched if (millis() - LastFrameTime >= SolaxTimeout) { datalayer.system.status.inverter_allows_contactor_closing = false; STATE = BATTERY_ANNOUNCE; + inverter_missing_on_can++; + if (inverter_missing_on_can > CAN_STILL_ALIVE) { + set_event(EVENT_CAN_INVERTER_MISSING, 0); + } else { + clear_event(EVENT_CAN_INVERTER_MISSING); + } } //Calculate the required values temperature_average = From 3f4ffb8055adf8d94a7bdce1f322a3a3f2f56df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 1 Oct 2024 11:00:14 +0300 Subject: [PATCH 02/26] Update version number to signal dev --- Software/Software.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/Software.ino b/Software/Software.ino index a1819c2c..888549b7 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -50,7 +50,7 @@ Preferences settings; // Store user settings // The current software version, shown on webserver -const char* version_number = "7.4.0"; +const char* version_number = "7.5.dev"; // Interval settings uint16_t intervalUpdateValues = INTERVAL_5_S; // Interval at which to update inverter values / Modbus registers From 81cd6780a345b21746aa033828b7a1ca7970f462 Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:12:22 +0100 Subject: [PATCH 03/26] Initial Implementation of Core Emergency Stop Feature on Battery Emulator --- Software/Software.ino | 28 ++++++++++++- Software/src/datalayer/datalayer.h | 1 + Software/src/devboard/safety/safety.cpp | 13 ++++++- Software/src/devboard/safety/safety.h | 4 +- Software/src/devboard/utils/events.cpp | 3 ++ Software/src/devboard/utils/events.h | 1 + Software/src/devboard/webserver/webserver.cpp | 39 ++++++++++++++++++- 7 files changed, 84 insertions(+), 5 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index a1819c2c..90bb5900 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -334,10 +334,24 @@ void init_serial() { } void init_stored_settings() { + static uint32_t temp = 0; settings.begin("batterySettings", false); + //allways get the emergency stop status + temp = settings.getBool("EMERGENGY_STOP", false); + datalayer.system.settings.equipment_stop_active = temp; + if (datalayer.system.settings.equipment_stop_active) { + set_event(EVENT_EMERGENCY_STOP, 1); + } + #ifndef LOAD_SAVED_SETTINGS_ON_BOOT settings.clear(); // If this clear function is executed, no settings will be read from storage + + //always save the emergency stop status + if (datalayer.system.settings.equipment_stop_active) { + settings.putBool("EMERGENGY_STOP", datalayer.system.settings.equipment_stop_active); + } + #endif #ifdef WIFI @@ -356,7 +370,6 @@ void init_stored_settings() { } #endif - static uint32_t temp = 0; temp = settings.getUInt("BATTERY_WH_MAX", false); if (temp != 0) { datalayer.battery.info.total_capacity_Wh = temp; @@ -658,9 +671,14 @@ void handle_contactors() { timeSpentInFaultedMode = 0; } - if (timeSpentInFaultedMode > MAX_ALLOWED_FAULT_TICKS) { + //handle contactor control SHUTDOWN_REQUESTED vs DISCONNECTED + if (timeSpentInFaultedMode > MAX_ALLOWED_FAULT_TICKS || + (datalayer.system.settings.equipment_stop_active && contactorStatus != SHUTDOWN_REQUESTED)) { contactorStatus = SHUTDOWN_REQUESTED; } + if (contactorStatus == SHUTDOWN_REQUESTED && !datalayer.system.settings.equipment_stop_active) { + contactorStatus = DISCONNECTED; + } if (contactorStatus == SHUTDOWN_REQUESTED) { digitalWrite(PRECHARGE_PIN, LOW); #ifndef PWM_CONTACTOR_CONTROL @@ -832,6 +850,12 @@ void init_serialDataLink() { #endif } +void store_settings_emergency_stop() { + settings.begin("batterySettings", false); + settings.putBool("EMERGENGY_STOP", datalayer.system.settings.equipment_stop_active); + settings.end(); +} + void storeSettings() { settings.begin("batterySettings", false); #ifdef WIFI diff --git a/Software/src/datalayer/datalayer.h b/Software/src/datalayer/datalayer.h index eebcf3a6..8efc6fbd 100644 --- a/Software/src/datalayer/datalayer.h +++ b/Software/src/datalayer/datalayer.h @@ -172,6 +172,7 @@ typedef struct { } DATALAYER_SYSTEM_STATUS_TYPE; typedef struct { + bool equipment_stop_active = false; } DATALAYER_SYSTEM_SETTINGS_TYPE; typedef struct { diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index e9a592a2..acb91540 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -196,7 +196,18 @@ void update_machineryprotection() { } //battery pause status begin -void setBatteryPause(bool pause_battery, bool pause_CAN) { +void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop) { + + //fist handle emergency stop / resume + if (emergency_stop && !datalayer.system.settings.equipment_stop_active) { + datalayer.system.settings.equipment_stop_active = true; + store_settings_emergency_stop(); + set_event(EVENT_EMERGENCY_STOP, 1); + } else if (!emergency_stop && datalayer.system.settings.equipment_stop_active) { + datalayer.system.settings.equipment_stop_active = false; + store_settings_emergency_stop(); + clear_event(EVENT_EMERGENCY_STOP); + } emulator_pause_CAN_send_ON = pause_CAN; diff --git a/Software/src/devboard/safety/safety.h b/Software/src/devboard/safety/safety.h index 4710696f..4823f006 100644 --- a/Software/src/devboard/safety/safety.h +++ b/Software/src/devboard/safety/safety.h @@ -15,10 +15,12 @@ extern battery_pause_status emulator_pause_status; extern bool allowed_to_send_CAN; //battery pause status end +extern void store_settings_emergency_stop(); + void update_machineryprotection(); //battery pause status begin -void setBatteryPause(bool pause_battery, bool pause_CAN); +void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop = false); void emulator_pause_state_send_CAN_battery(); std::string get_emulator_pause_status(); //battery pause status end diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index f7c25160..6cc5aaed 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -213,6 +213,7 @@ void init_events(void) { events.entries[EVENT_WIFI_DISCONNECT].level = EVENT_LEVEL_INFO; events.entries[EVENT_MQTT_CONNECT].level = EVENT_LEVEL_INFO; events.entries[EVENT_MQTT_DISCONNECT].level = EVENT_LEVEL_INFO; + events.entries[EVENT_EMERGENCY_STOP].level = EVENT_LEVEL_ERROR; events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger... @@ -411,6 +412,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { return "Info: MQTT connected."; case EVENT_MQTT_DISCONNECT: return "Info: MQTT disconnected."; + case EVENT_EMERGENCY_STOP: + return "ERROR: EMERGENCY STOP ACTIVATED!!!"; default: return ""; } diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 396788ef..cd036bb4 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -101,6 +101,7 @@ XX(EVENT_WIFI_DISCONNECT) \ XX(EVENT_MQTT_CONNECT) \ XX(EVENT_MQTT_DISCONNECT) \ + XX(EVENT_EMERGENCY_STOP) \ XX(EVENT_NOF_EVENTS) typedef enum { EVENTS_ENUM_TYPE(GENERATE_ENUM) } EVENTS_ENUM_TYPE; diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index c37520b7..7852b3d1 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -166,6 +166,23 @@ void init_webserver() { } }); + // Route for emergency stop/resume + server.on("/estop", HTTP_GET, [](AsyncWebServerRequest* request) { + if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) + return request->requestAuthentication(); + if (request->hasParam("stop")) { + String valueStr = request->getParam("stop")->value(); + if (valueStr == "true" || valueStr == "1") { + setBatteryPause(true, true, true); + } else { + setBatteryPause(false, false, false); + } + request->send(200, "text/plain", "Updated successfully"); + } else { + request->send(400, "text/plain", "Bad Request"); + } + }); + // Route for editing SOCMin server.on("/updateSocMin", HTTP_GET, [](AsyncWebServerRequest* request) { if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) @@ -844,6 +861,21 @@ String processor(const String& var) { content += ""; if (WEBSERVER_AUTH_REQUIRED) content += ""; + if (!datalayer.system.settings.equipment_stop_active) + content += + "


"; + else + content += + "


"; + content += ""; //Script for refreshing page From c1a262421b7901cb756e4ba6ccd9bccdbdb5558a Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Wed, 2 Oct 2024 02:50:32 +0100 Subject: [PATCH 04/26] Implement Support for External Equipment / Emergency Button on Battery Emulator --- Software/Software.ino | 47 +++++++++++++++++++ Software/USER_SETTINGS.h | 1 + Software/src/devboard/hal/hw_lilygo.h | 15 ++++++ Software/src/devboard/hal/hw_stark.h | 3 ++ Software/src/devboard/safety/safety.cpp | 9 ++++ Software/src/devboard/safety/safety.h | 1 + Software/src/devboard/webserver/webserver.cpp | 5 -- 7 files changed, 76 insertions(+), 5 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 90bb5900..be74b27c 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -135,6 +135,14 @@ unsigned long negativeStartTime = 0; unsigned long timeSpentInFaultedMode = 0; #endif +#ifdef EQUIPMENT_STOP_BUTTON +volatile unsigned long equipment_button_press_time = 0; // Time when button is pressed +const unsigned long equipment_button_long_press_duration = 5000; // 5 seconds for long press +int equipment_button_lastState = LOW; // the previous state from the input pin +int equipment_button_currentState; // the current reading from the input pin +unsigned long equipment_button_pressedTime = 0; +unsigned long equipment_button_releasedTime = 0; +#endif TaskHandle_t main_loop_task; TaskHandle_t connectivity_loop_task; @@ -163,6 +171,9 @@ void setup() { init_battery(); +#ifdef EQUIPMENT_STOP_BUTTON + init_equipment_stop_button(); +#endif // BOOT button at runtime is used as an input for various things pinMode(0, INPUT_PULLUP); @@ -235,6 +246,8 @@ void core_loop(void* task_time_us) { while (true) { START_TIME_MEASUREMENT(all); START_TIME_MEASUREMENT(comm); + monitor_equipment_stop_button(); + // Input, Runs as fast as possible receive_can_native(); // Receive CAN messages from native CAN port #ifdef CAN_FD @@ -546,6 +559,40 @@ void init_battery() { #endif } +#ifdef EQUIPMENT_STOP_BUTTON + +void monitor_equipment_stop_button() { + // read the state of the switch/button: + equipment_button_currentState = digitalRead(EQUIPMENT_STOP_PIN); + + if (equipment_button_lastState == LOW && equipment_button_currentState == HIGH) // button is pressed + equipment_button_pressedTime = millis(); + else if (equipment_button_lastState == HIGH && equipment_button_currentState == LOW) { // button is released + equipment_button_releasedTime = millis(); + + long pressDuration = equipment_button_releasedTime - equipment_button_pressedTime; + + if (pressDuration < equipment_button_long_press_duration) { + // Short press detected, trigger emergency stop + setBatteryPause(true, true, true); + } else { + // Long press detected, reset equipment stop state + setBatteryPause(false, false, false); + } + } + + // save the the last state + equipment_button_lastState = equipment_button_currentState; +} + +void init_equipment_stop_button() { + + //using external pulldown resistors + pinMode(EQUIPMENT_STOP_PIN, INPUT); +} + +#endif + #ifdef CAN_FD // Functions #ifdef DEBUG_CANFD_DATA diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index a05ae685..9325957c 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -65,6 +65,7 @@ #define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled. #define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below) //#define FUNCTION_TIME_MEASUREMENT // Enable this to record execution times and present them in the web UI (WARNING, raises CPU load, do not use for production) +//#define EQUIPMENT_STOP_BUTTON // Enable this to have a emergengy/equipment stop button connected to board /* MQTT options */ // #define MQTT // Enable this line to enable MQTT diff --git a/Software/src/devboard/hal/hw_lilygo.h b/Software/src/devboard/hal/hw_lilygo.h index 65ee569f..d4d7ce2c 100644 --- a/Software/src/devboard/hal/hw_lilygo.h +++ b/Software/src/devboard/hal/hw_lilygo.h @@ -65,6 +65,9 @@ #define LED_PIN 4 #define LED_MAX_BRIGHTNESS 40 +// Equipment stop pin +#define EQUIPMENT_STOP_PIN 35 + /* ----- Error checks below, don't change (can't be moved to separate file) ----- */ #ifndef HW_CONFIGURED #define HW_CONFIGURED @@ -78,6 +81,18 @@ #endif #endif +#ifdef EQUIPMENT_STOP_BUTTON +#ifdef DUAL_CAN +#error EQUIPMENT_STOP_BUTTON and DUAL_CAN cannot coexist due to overlapping GPIO pin usage +#endif +#ifdef CAN_FD +#error EQUIPMENT_STOP_BUTTON and CAN_FD cannot coexist due to overlapping GPIO pin usage +#endif +#ifdef CHADEMO_BATTERY +#error EQUIPMENT_STOP_BUTTON and CHADEMO_BATTERY cannot coexist due to overlapping GPIO pin usage +#endif +#endif + #ifdef BMW_I3_BATTERY #ifdef CONTACTOR_CONTROL #error GPIO PIN 25 cannot be used for both BMWi3 Wakeup and contactor control. Disable CONTACTOR_CONTROL diff --git a/Software/src/devboard/hal/hw_stark.h b/Software/src/devboard/hal/hw_stark.h index 7bc45a54..5e26f559 100644 --- a/Software/src/devboard/hal/hw_stark.h +++ b/Software/src/devboard/hal/hw_stark.h @@ -58,6 +58,9 @@ GPIOs on extra header #define LED_PIN 4 #define LED_MAX_BRIGHTNESS 40 +// Equipment stop pin +#define EQUIPMENT_STOP_PIN 2 + /* ----- Error checks below, don't change (can't be moved to separate file) ----- */ #ifndef HW_CONFIGURED #define HW_CONFIGURED diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index acb91540..32788e2b 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -239,6 +239,7 @@ void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop) { /// @brief handle emulator pause status /// @return true if CAN messages should be sent to battery, false if not void emulator_pause_state_send_CAN_battery() { + bool previous_allowed_to_send_CAN = allowed_to_send_CAN; if (emulator_pause_status == NORMAL) { allowed_to_send_CAN = true; @@ -256,6 +257,14 @@ void emulator_pause_state_send_CAN_battery() { } allowed_to_send_CAN = (!emulator_pause_CAN_send_ON || emulator_pause_status == NORMAL); + + if (previous_allowed_to_send_CAN && !allowed_to_send_CAN) { + //completely force stop the CAN communication + ESP32Can.CANStop(); + } else if (!previous_allowed_to_send_CAN && allowed_to_send_CAN) { + //resume CAN communication + ESP32Can.CANInit(); + } } std::string get_emulator_pause_status() { diff --git a/Software/src/devboard/safety/safety.h b/Software/src/devboard/safety/safety.h index 4823f006..0020cd81 100644 --- a/Software/src/devboard/safety/safety.h +++ b/Software/src/devboard/safety/safety.h @@ -2,6 +2,7 @@ #define SAFETY_H #include #include +#include "../../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #define MAX_CAN_FAILURES 50 diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 7852b3d1..7a04feb3 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -933,9 +933,6 @@ void onOTAStart() { clear_event(EVENT_OTA_UPDATE_TIMEOUT); ota_active = true; - //completely force stop the CAN communication - ESP32Can.CANStop(); - ota_timeout_timer.reset(); } @@ -968,8 +965,6 @@ void onOTAEnd(bool success) { #endif // DEBUG_VIA_USB //try to Resume the battery pause and CAN communication setBatteryPause(false, false); - //resume CAN communication - ESP32Can.CANInit(); } } From 8344bf51792767f4a8338eab3d15ad44ab9947a6 Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Wed, 2 Oct 2024 03:10:51 +0100 Subject: [PATCH 05/26] #ifdef missing --- Software/Software.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Software/Software.ino b/Software/Software.ino index be74b27c..806d7024 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -246,7 +246,9 @@ void core_loop(void* task_time_us) { while (true) { START_TIME_MEASUREMENT(all); START_TIME_MEASUREMENT(comm); +#ifdef EQUIPMENT_STOP_BUTTON monitor_equipment_stop_button(); +#endif // Input, Runs as fast as possible receive_can_native(); // Receive CAN messages from native CAN port From 36b1f320c3c3eb2f5ea906286d97a4e72c6365f5 Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:27:27 +0100 Subject: [PATCH 06/26] Update Software/Software.ino Co-authored-by: Christopher Obbard --- Software/Software.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/Software.ino b/Software/Software.ino index 806d7024..8a1ebc9b 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -352,7 +352,7 @@ void init_stored_settings() { static uint32_t temp = 0; settings.begin("batterySettings", false); - //allways get the emergency stop status + // Always get the emergency stop status temp = settings.getBool("EMERGENGY_STOP", false); datalayer.system.settings.equipment_stop_active = temp; if (datalayer.system.settings.equipment_stop_active) { From d2de79e64a0bfd8a51253532575d1773fa7dee1d Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:39:16 +0100 Subject: [PATCH 07/26] Update Software/USER_SETTINGS.h Co-authored-by: Christopher Obbard --- Software/USER_SETTINGS.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 9325957c..a97e4883 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -65,7 +65,7 @@ #define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled. #define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below) //#define FUNCTION_TIME_MEASUREMENT // Enable this to record execution times and present them in the web UI (WARNING, raises CPU load, do not use for production) -//#define EQUIPMENT_STOP_BUTTON // Enable this to have a emergengy/equipment stop button connected to board +//#define EQUIPMENT_STOP_BUTTON // Enable this to allow an emergency/equipment stop button connected to the Battery-Emulator to disengage the battery /* MQTT options */ // #define MQTT // Enable this line to enable MQTT From 173acab23ae0505aecffc22f8529872f72229003 Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:20:10 +0100 Subject: [PATCH 08/26] NC logic for button. 2 button behaviors. some suggestions implemented --- Software/Software.ino | 56 ++++++++++++------- Software/USER_SETTINGS.cpp | 7 +++ Software/USER_SETTINGS.h | 7 ++- Software/src/devboard/safety/safety.cpp | 2 +- Software/src/devboard/webserver/webserver.cpp | 4 +- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 806d7024..48bc3183 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -138,10 +138,11 @@ unsigned long timeSpentInFaultedMode = 0; #ifdef EQUIPMENT_STOP_BUTTON volatile unsigned long equipment_button_press_time = 0; // Time when button is pressed const unsigned long equipment_button_long_press_duration = 5000; // 5 seconds for long press -int equipment_button_lastState = LOW; // the previous state from the input pin +int equipment_button_lastState = HIGH; // the previous state from the input pin NC int equipment_button_currentState; // the current reading from the input pin unsigned long equipment_button_pressedTime = 0; unsigned long equipment_button_releasedTime = 0; +bool first_run_after_boot = true; #endif TaskHandle_t main_loop_task; TaskHandle_t connectivity_loop_task; @@ -352,9 +353,8 @@ void init_stored_settings() { static uint32_t temp = 0; settings.begin("batterySettings", false); - //allways get the emergency stop status - temp = settings.getBool("EMERGENGY_STOP", false); - datalayer.system.settings.equipment_stop_active = temp; + // Always get the emergency stop status + datalayer.system.settings.equipment_stop_active = settings.getBool("EMERGENCY_STOP", false); if (datalayer.system.settings.equipment_stop_active) { set_event(EVENT_EMERGENCY_STOP, 1); } @@ -363,9 +363,7 @@ void init_stored_settings() { settings.clear(); // If this clear function is executed, no settings will be read from storage //always save the emergency stop status - if (datalayer.system.settings.equipment_stop_active) { - settings.putBool("EMERGENGY_STOP", datalayer.system.settings.equipment_stop_active); - } + settings.putBool("EMERGENCY_STOP", datalayer.system.settings.equipment_stop_active); #endif @@ -564,32 +562,48 @@ void init_battery() { #ifdef EQUIPMENT_STOP_BUTTON void monitor_equipment_stop_button() { + //NC Logic // read the state of the switch/button: equipment_button_currentState = digitalRead(EQUIPMENT_STOP_PIN); - if (equipment_button_lastState == LOW && equipment_button_currentState == HIGH) // button is pressed - equipment_button_pressedTime = millis(); - else if (equipment_button_lastState == HIGH && equipment_button_currentState == LOW) { // button is released - equipment_button_releasedTime = millis(); + if (equipment_stop_behavior == TOGGLE_SWITCH) { + if (equipment_button_lastState != equipment_button_currentState || first_run_after_boot) { + if (!equipment_button_currentState) { + // Changed to ON – initiating equipment stop. + setBatteryPause(true, true, true); + } else { + // Changed to OFF – ending equipment stop. + setBatteryPause(false, false, false); + } + } + } else if (equipment_stop_behavior == PERSISTENT_ACTIVATION_SWITCH) { + if (equipment_button_lastState == HIGH && equipment_button_currentState == LOW) { // button is pressed + equipment_button_pressedTime = millis(); + } else if (equipment_button_lastState == LOW && equipment_button_currentState == HIGH) { // button is released + equipment_button_releasedTime = millis(); - long pressDuration = equipment_button_releasedTime - equipment_button_pressedTime; + long pressDuration = equipment_button_releasedTime - equipment_button_pressedTime; - if (pressDuration < equipment_button_long_press_duration) { - // Short press detected, trigger emergency stop - setBatteryPause(true, true, true); - } else { - // Long press detected, reset equipment stop state - setBatteryPause(false, false, false); + if (pressDuration < equipment_button_long_press_duration) { + // Short press detected, trigger emergency stop + setBatteryPause(true, true, true); + } else { + // Long press detected, reset equipment stop state + setBatteryPause(false, false, false); + } } } // save the the last state equipment_button_lastState = equipment_button_currentState; + + if (first_run_after_boot) { + first_run_after_boot = false; + } } void init_equipment_stop_button() { - - //using external pulldown resistors + //using external pullup resistors NC pinMode(EQUIPMENT_STOP_PIN, INPUT); } @@ -901,7 +915,7 @@ void init_serialDataLink() { void store_settings_emergency_stop() { settings.begin("batterySettings", false); - settings.putBool("EMERGENGY_STOP", datalayer.system.settings.equipment_stop_active); + settings.putBool("EMERGENCY_STOP", datalayer.system.settings.equipment_stop_active); settings.end(); } diff --git a/Software/USER_SETTINGS.cpp b/Software/USER_SETTINGS.cpp index 8310355e..a4c0b56f 100644 --- a/Software/USER_SETTINGS.cpp +++ b/Software/USER_SETTINGS.cpp @@ -48,6 +48,13 @@ const char* mqtt_password = "REDACTED"; // Set NULL for no password #endif // USE_MQTT #endif // WIFI +#ifdef EQUIPMENT_STOP_BUTTON +// Equipment stop button behavior. Use NC button for safety reasons. +//TOGGLE_SWITCH - activated while pressed, deactivated when released, button state is reflected in the emulator state +//PERSISTENT_ACTIVATION_SWITCH - short press to activate, long press to deactivate, state is persisted between reboots +volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior = TOGGLE_SWITCH; +#endif + /* Charger settings (Optional, when using generator charging) */ volatile float CHARGER_SET_HV = 384; // Reasonably appropriate 4.0v per cell charging of a 96s pack volatile float CHARGER_MAX_HV = 420; // Max permissible output (VDC) of charger diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 9325957c..08b9b5fa 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -65,7 +65,7 @@ #define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled. #define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below) //#define FUNCTION_TIME_MEASUREMENT // Enable this to record execution times and present them in the web UI (WARNING, raises CPU load, do not use for production) -//#define EQUIPMENT_STOP_BUTTON // Enable this to have a emergengy/equipment stop button connected to board +//#define EQUIPMENT_STOP_BUTTON // Enable this to allow an emergency/equipment stop button connected to the Battery-Emulator to disengage the battery /* MQTT options */ // #define MQTT // Enable this line to enable MQTT @@ -120,6 +120,11 @@ extern volatile float CHARGER_END_A; extern bool charger_HV_enabled; extern bool charger_aux12V_enabled; +#ifdef EQUIPMENT_STOP_BUTTON +typedef enum { TOGGLE_SWITCH = 0, PERSISTENT_ACTIVATION_SWITCH = 1 } STOP_BUTTON_BEHAVIOR; +extern volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior; +#endif + #ifdef WIFICONFIG extern IPAddress local_IP; // Set your Gateway IP address diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index 32788e2b..ade03995 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -198,7 +198,7 @@ void update_machineryprotection() { //battery pause status begin void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop) { - //fist handle emergency stop / resume + // First handle emergency stop / resume if (emergency_stop && !datalayer.system.settings.equipment_stop_active) { datalayer.system.settings.equipment_stop_active = true; store_settings_emergency_stop(); diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 7a04feb3..1f1317b3 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -167,7 +167,7 @@ void init_webserver() { }); // Route for emergency stop/resume - server.on("/estop", HTTP_GET, [](AsyncWebServerRequest* request) { + server.on("/emergencyStop", HTTP_GET, [](AsyncWebServerRequest* request) { if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) return request->requestAuthentication(); if (request->hasParam("stop")) { @@ -908,7 +908,7 @@ String processor(const String& var) { content += "var xhr=new " "XMLHttpRequest();xhr.onload=function() { " - "window.location.reload();};xhr.open('GET','/estop?stop='+stop,true);xhr.send();"; + "window.location.reload();};xhr.open('GET','/emergencyStop?stop='+stop,true);xhr.send();"; content += "}"; content += ""; From 7b3594c24840f6a104856c3d3bb4edf1d362413a Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:49:01 +0100 Subject: [PATCH 09/26] stop equipment before reboot --- Software/src/devboard/safety/safety.cpp | 11 ++++++++--- Software/src/devboard/safety/safety.h | 2 +- Software/src/devboard/webserver/webserver.cpp | 5 ++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index ade03995..c3b79ede 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -196,16 +196,21 @@ void update_machineryprotection() { } //battery pause status begin -void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop) { +void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop, bool store_settings) { // First handle emergency stop / resume if (emergency_stop && !datalayer.system.settings.equipment_stop_active) { datalayer.system.settings.equipment_stop_active = true; - store_settings_emergency_stop(); + if (store_settings) { + store_settings_emergency_stop(); + } + set_event(EVENT_EMERGENCY_STOP, 1); } else if (!emergency_stop && datalayer.system.settings.equipment_stop_active) { datalayer.system.settings.equipment_stop_active = false; - store_settings_emergency_stop(); + if (store_settings) { + store_settings_emergency_stop(); + } clear_event(EVENT_EMERGENCY_STOP); } diff --git a/Software/src/devboard/safety/safety.h b/Software/src/devboard/safety/safety.h index 0020cd81..9dd71851 100644 --- a/Software/src/devboard/safety/safety.h +++ b/Software/src/devboard/safety/safety.h @@ -21,7 +21,7 @@ extern void store_settings_emergency_stop(); void update_machineryprotection(); //battery pause status begin -void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop = false); +void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop = false, bool store_settings = true); void emulator_pause_state_send_CAN_battery(); std::string get_emulator_pause_status(); //battery pause status end diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 1f1317b3..800c23b1 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -344,7 +344,10 @@ void init_webserver() { if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) return request->requestAuthentication(); request->send(200, "text/plain", "Rebooting server..."); - //TODO: Should we handle contactors gracefully? Ifdef CONTACTOR_CONTROL then what? + + //Equipment STOP without persisting the emergency state before restart + // Max Charge/Discharge = 0; CAN = stop; contactors = open + setBatteryPause(true, true, true, false); delay(1000); ESP.restart(); }); From ce542033822257766030c98fd90088affda416a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Thu, 3 Oct 2024 11:36:47 +0300 Subject: [PATCH 10/26] Refactor cellvoltage safeties --- Software/src/battery/BMW-I3-BATTERY.cpp | 60 +++++--- Software/src/battery/BYD-ATTO-3-BATTERY.cpp | 18 ++- Software/src/battery/BYD-ATTO-3-BATTERY.h | 4 + Software/src/battery/CHADEMO-BATTERY.h | 1 - .../src/battery/IMIEV-CZERO-ION-BATTERY.cpp | 18 +-- .../src/battery/IMIEV-CZERO-ION-BATTERY.h | 4 + Software/src/battery/JAGUAR-IPACE-BATTERY.cpp | 7 +- Software/src/battery/JAGUAR-IPACE-BATTERY.h | 6 +- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 20 +-- Software/src/battery/KIA-E-GMP-BATTERY.h | 4 + .../src/battery/KIA-HYUNDAI-64-BATTERY.cpp | 18 +-- Software/src/battery/KIA-HYUNDAI-64-BATTERY.h | 2 + .../battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 8 +- .../src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h | 4 + Software/src/battery/MG-5-BATTERY.cpp | 6 +- Software/src/battery/MG-5-BATTERY.h | 4 + Software/src/battery/NISSAN-LEAF-BATTERY.cpp | 26 ++-- Software/src/battery/NISSAN-LEAF-BATTERY.h | 4 + Software/src/battery/PYLON-BATTERY.cpp | 10 +- Software/src/battery/PYLON-BATTERY.h | 6 + .../src/battery/RENAULT-KANGOO-BATTERY.cpp | 15 +- Software/src/battery/RENAULT-KANGOO-BATTERY.h | 11 +- .../src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp | 17 +-- .../src/battery/RENAULT-ZOE-GEN1-BATTERY.h | 8 +- .../src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp | 17 +-- .../src/battery/RENAULT-ZOE-GEN2-BATTERY.h | 7 +- Software/src/battery/RJXZS-BMS.cpp | 6 +- Software/src/battery/RJXZS-BMS.h | 4 + .../src/battery/SANTA-FE-PHEV-BATTERY.cpp | 6 +- Software/src/battery/SANTA-FE-PHEV-BATTERY.h | 4 + .../SERIAL-LINK-RECEIVER-FROM-BATTERY.h | 3 - Software/src/battery/TESLA-BATTERY.cpp | 130 +++++------------- Software/src/battery/TESLA-BATTERY.h | 19 ++- Software/src/battery/VOLVO-SPA-BATTERY.cpp | 21 +-- Software/src/battery/VOLVO-SPA-BATTERY.h | 4 + Software/src/datalayer/datalayer.h | 6 + Software/src/devboard/safety/safety.cpp | 28 +++- 37 files changed, 266 insertions(+), 270 deletions(-) diff --git a/Software/src/battery/BMW-I3-BATTERY.cpp b/Software/src/battery/BMW-I3-BATTERY.cpp index f0e67617..1fc75264 100644 --- a/Software/src/battery/BMW-I3-BATTERY.cpp +++ b/Software/src/battery/BMW-I3-BATTERY.cpp @@ -395,8 +395,37 @@ void update_values_battery2() { //This function maps all the values fetched via datalayer.battery2.status.temperature_max_dC = battery2_temperature_max * 10; // Add a decimal - datalayer.battery2.status.cell_min_voltage_mV = datalayer.battery2.status.cell_voltages_mV[0]; - datalayer.battery2.status.cell_max_voltage_mV = datalayer.battery2.status.cell_voltages_mV[1]; + if (battery2_info_available) { + // Start checking safeties. First up, cellvoltages! + if (detectedBattery == BATTERY_60AH) { + datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_60AH; + datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_60AH; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_60AH; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_60AH; + } else if (detectedBattery == BATTERY_94AH) { + datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_94AH; + datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_94AH; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_94AH; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_94AH; + } else { // BATTERY_120AH + datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_120AH; + datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_120AH; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_120AH; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_120AH; + } + } + + // Perform other safety checks + if (battery2_status_error_locking == 2) { // HVIL seated? + set_event(EVENT_HVIL_FAILURE, 2); + } else { + clear_event(EVENT_HVIL_FAILURE); + } + if (battery2_status_precharge_locked == 2) { // Capacitor seated? + set_event(EVENT_PRECHARGE_FAILURE, 2); + } else { + clear_event(EVENT_PRECHARGE_FAILURE); + } } void update_values_battery() { //This function maps all the values fetched via CAN to the battery datalayer @@ -433,30 +462,18 @@ void update_values_battery() { //This function maps all the values fetched via if (detectedBattery == BATTERY_60AH) { datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_60AH; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_60AH; - if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_60AH) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_60AH) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_60AH; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_60AH; } else if (detectedBattery == BATTERY_94AH) { datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_94AH; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_94AH; - if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_94AH) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_94AH) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_94AH; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_94AH; } else { // BATTERY_120AH datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_120AH; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_120AH; - if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_120AH) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_120AH) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_120AH; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_120AH; } } @@ -1124,13 +1141,14 @@ void setup_battery(void) { // Performs one time setup at startup //Before we have started up and detected which battery is in use, use 60AH values datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_60AH; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_60AH; - + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; datalayer.system.status.battery_allows_contactor_closing = true; #ifdef DOUBLE_BATTERY Serial.println("Another BMW i3 battery also selected!"); datalayer.battery2.info.max_design_voltage_dV = datalayer.battery.info.max_design_voltage_dV; datalayer.battery2.info.min_design_voltage_dV = datalayer.battery.info.min_design_voltage_dV; + datalayer.battery2.info.max_cell_voltage_deviation_mV = datalayer.battery.info.max_cell_voltage_deviation_mV; datalayer.battery2.status.voltage_dV = 0; //Init voltage to 0 to allow contactor check to operate without fear of default values colliding #endif diff --git a/Software/src/battery/BYD-ATTO-3-BATTERY.cpp b/Software/src/battery/BYD-ATTO-3-BATTERY.cpp index d36e4166..f6adb248 100644 --- a/Software/src/battery/BYD-ATTO-3-BATTERY.cpp +++ b/Software/src/battery/BYD-ATTO-3-BATTERY.cpp @@ -135,14 +135,14 @@ void update_values_battery() { //This function maps all the values fetched via } void receive_can_battery(CAN_frame rx_frame) { - datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; switch (rx_frame.ID) { //Log values taken with 422V from battery case 0x244: //00,00,00,04,41,0F,20,8B - Static, values never changes between logs break; case 0x245: //01,00,02,19,3A,25,90,F4 Seems to have a mux in frame0 - //02,00,90,01,79,79,90,EA // Point of interest, went from 7E,75 to 7B,7C when discharging - //03,C6,88,12,FD,48,90,5C - //04,00,FF,FF,00,00,90,6D + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + //02,00,90,01,79,79,90,EA // Point of interest, went from 7E,75 to 7B,7C when discharging + //03,C6,88,12,FD,48,90,5C + //04,00,FF,FF,00,00,90,6D if (rx_frame.data.u8[0] == 0x01) { temperature_ambient = (rx_frame.data.u8[4] - 40); // TODO, check if this is actually temperature_ambient } @@ -371,9 +371,13 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("BYD Atto 3 battery selected"); #endif - - datalayer.battery.info.max_design_voltage_dV = 4410; // Over this charging is not possible - datalayer.battery.info.min_design_voltage_dV = 3800; // Under this discharging is disabled + datalayer.battery.info.number_of_cells = 126; + datalayer.battery.info.chemistry = battery_chemistry_enum::LFP; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; } #endif diff --git a/Software/src/battery/BYD-ATTO-3-BATTERY.h b/Software/src/battery/BYD-ATTO-3-BATTERY.h index 550975d5..3917425e 100644 --- a/Software/src/battery/BYD-ATTO-3-BATTERY.h +++ b/Software/src/battery/BYD-ATTO-3-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 4410 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 3800 #define MAX_CELL_DEVIATION_MV 150 +#define MAX_CELL_VOLTAGE_MV 3800 //Battery is put into emergency stop if one cell goes over this value +#define MIN_CELL_VOLTAGE_MV 2800 //Battery is put into emergency stop if one cell goes below this value void setup_battery(void); void transmit_can(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/CHADEMO-BATTERY.h b/Software/src/battery/CHADEMO-BATTERY.h index 0e00a76d..fa6545a9 100644 --- a/Software/src/battery/CHADEMO-BATTERY.h +++ b/Software/src/battery/CHADEMO-BATTERY.h @@ -4,7 +4,6 @@ #include "../include.h" #define BATTERY_SELECTED -#define MAX_CELL_DEVIATION_MV 9999 //Contactor control is required for CHADEMO support #define CONTACTOR_CONTROL diff --git a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp index b9a706f4..c4094e3f 100644 --- a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp +++ b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp @@ -8,8 +8,6 @@ //Figure out if CAN messages need to be sent to keep the system happy? /* Do not change code below unless you are sure what you are doing */ -#define MAX_CELL_VOLTAGE 4150 -#define MIN_CELL_VOLTAGE 2750 static uint8_t errorCode = 0; //stores if we have an error code active from battery control logic static uint8_t BMU_Detected = 0; static uint8_t CMU_Detected = 0; @@ -106,14 +104,6 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.temperature_max_dC = (int16_t)(max_temp_cel * 10); } - //Check safeties - if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, datalayer.battery.status.cell_max_voltage_mV); - } - if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, datalayer.battery.status.cell_min_voltage_mV); - } - if (!BMU_Detected) { #ifdef DEBUG_VIA_USB Serial.println("BMU not detected, check wiring!"); @@ -239,9 +229,11 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("Mitsubishi i-MiEV / Citroen C-Zero / Peugeot Ion battery selected"); #endif - - datalayer.battery.info.max_design_voltage_dV = 3696; // 369.6V - datalayer.battery.info.min_design_voltage_dV = 3160; // 316.0V + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; } #endif diff --git a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h index 3eb56955..70bbf9fb 100644 --- a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h +++ b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 3696 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 3160 #define MAX_CELL_DEVIATION_MV 500 +#define MAX_CELL_VOLTAGE_MV 4150 //Battery is put into emergency stop if one cell goes over this value +#define MIN_CELL_VOLTAGE_MV 2750 //Battery is put into emergency stop if one cell goes below this value void setup_battery(void); void transmit_can(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp b/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp index 88a47d02..e5f3fe9b 100644 --- a/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp +++ b/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp @@ -263,8 +263,11 @@ void setup_battery(void) { // Performs one time setup at startup #endif datalayer.battery.info.number_of_cells = 108; - datalayer.battery.info.max_design_voltage_dV = 4546; - datalayer.battery.info.min_design_voltage_dV = 3370; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; datalayer.system.status.battery_allows_contactor_closing = true; } diff --git a/Software/src/battery/JAGUAR-IPACE-BATTERY.h b/Software/src/battery/JAGUAR-IPACE-BATTERY.h index d4d0338d..6ff7827f 100644 --- a/Software/src/battery/JAGUAR-IPACE-BATTERY.h +++ b/Software/src/battery/JAGUAR-IPACE-BATTERY.h @@ -3,7 +3,11 @@ #include "../include.h" #define BATTERY_SELECTED -#define MAX_CELL_DEVIATION_MV 9999 // TODO is this ok ? +#define MAX_PACK_VOLTAGE_DV 4546 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 3370 +#define MAX_CELL_DEVIATION_MV 500 +#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(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index 2c4204f2..8a036ea0 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -15,9 +15,6 @@ static unsigned long previousMillis500ms = 0; // will store last time a 500ms C static unsigned long previousMillis1s = 0; // will store last time a 1s CAN Message was send static unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send -#define MAX_CELL_VOLTAGE 4250 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE 2950 //Battery is put into emergency stop if one cell goes below this value - const unsigned char crc8_table[256] = { // CRC8_SAE_J1850_ZER0 formula,0x1D Poly,initial value 0x3F,Final XOR value varies 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, @@ -864,14 +861,6 @@ void update_values_battery() { //This function maps all the values fetched via set_event(EVENT_12V_LOW, leadAcidBatteryVoltage); } - // Check if cell voltages are within allowed range - if (CellVoltMax_mV >= MAX_CELL_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (CellVoltMin_mV <= MIN_CELL_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } - /* Safeties verified. Perform USB serial printout if configured to do so */ #ifdef DEBUG_VIA_USB @@ -1239,11 +1228,10 @@ void setup_battery(void) { // Performs one time setup at startup datalayer.system.status.battery_allows_contactor_closing = true; datalayer.battery.info.number_of_cells = 192; // TODO: will vary depending on battery - - datalayer.battery.info.max_design_voltage_dV = - 8064; // TODO: define when battery is known, charging is not possible (goes into forced discharge) - datalayer.battery.info.min_design_voltage_dV = - 4320; // TODO: define when battery is known. discharging further is disabled + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.h b/Software/src/battery/KIA-E-GMP-BATTERY.h index 4de98330..8000b05b 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.h +++ b/Software/src/battery/KIA-E-GMP-BATTERY.h @@ -7,7 +7,11 @@ extern ACAN2517FD canfd; #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 8064 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 4320 #define MAX_CELL_DEVIATION_MV 150 +#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value +#define MIN_CELL_VOLTAGE_MV 2950 //Battery is put into emergency stop if one cell goes below this value #define MAXCHARGEPOWERALLOWED 10000 #define MAXDISCHARGEPOWERALLOWED 10000 diff --git a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp index d27e60eb..3e75293e 100644 --- a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp @@ -8,9 +8,6 @@ static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send static unsigned long previousMillis10 = 0; // will store last time a 10s CAN Message was send -#define MAX_CELL_VOLTAGE 4250 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE 2950 //Battery is put into emergency stop if one cell goes below this value - static uint16_t soc_calculated = 0; static uint16_t SOC_BMS = 0; static uint16_t SOC_Display = 0; @@ -147,14 +144,6 @@ void update_values_battery() { //This function maps all the values fetched via set_event(EVENT_12V_LOW, leadAcidBatteryVoltage); } - // Check if cell voltages are within allowed range - if (CellVoltMax_mV >= MAX_CELL_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (CellVoltMin_mV <= MIN_CELL_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } - /* Safeties verified. Perform USB serial printout if configured to do so */ #ifdef DEBUG_VIA_USB @@ -550,9 +539,10 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("Kia Niro / Hyundai Kona 64kWh battery selected"); #endif - - datalayer.battery.info.max_design_voltage_dV = 4040; // 404.0V - datalayer.battery.info.min_design_voltage_dV = 3100; // 310.0V + datalayer.battery.info.max_design_voltage_dV = 4040; //startup with 98S max value. Precised later + datalayer.battery.info.min_design_voltage_dV = 2250; //startup with 90S min value. Precised later + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif diff --git a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h index aaee9221..880da01a 100644 --- a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h +++ b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h @@ -5,6 +5,8 @@ #define BATTERY_SELECTED #define MAX_CELL_DEVIATION_MV 150 +#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value +#define MIN_CELL_VOLTAGE_MV 2950 //Battery is put into emergency stop if one cell goes below this value void setup_battery(void); void update_number_of_cells(); diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 5ef5996e..f2597d3d 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -264,9 +264,11 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("Kia/Hyundai Hybrid battery selected"); #endif - datalayer.battery.info.number_of_cells = 56; // HEV , TODO: Make dynamic according to HEV/PHEV - datalayer.battery.info.max_design_voltage_dV = 2550; //TODO: Values OK? - datalayer.battery.info.min_design_voltage_dV = 1700; + datalayer.battery.info.number_of_cells = 56; // HEV , TODO: Make dynamic according to HEV/PHEV + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h index 8747404d..26b06d6f 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 2550 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 1700 #define MAX_CELL_DEVIATION_MV 100 +#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(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/MG-5-BATTERY.cpp b/Software/src/battery/MG-5-BATTERY.cpp index 3a4f8a82..b181edaf 100644 --- a/Software/src/battery/MG-5-BATTERY.cpp +++ b/Software/src/battery/MG-5-BATTERY.cpp @@ -141,8 +141,10 @@ void setup_battery(void) { // Performs one time setup at startup Serial.println("MG 5 battery selected"); #endif - datalayer.battery.info.max_design_voltage_dV = 4040; // Over this charging is not possible - datalayer.battery.info.min_design_voltage_dV = 3100; // Under this discharging is disabled + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif diff --git a/Software/src/battery/MG-5-BATTERY.h b/Software/src/battery/MG-5-BATTERY.h index 4919219e..4efd3735 100644 --- a/Software/src/battery/MG-5-BATTERY.h +++ b/Software/src/battery/MG-5-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 4040 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 3100 #define MAX_CELL_DEVIATION_MV 150 +#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(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index 32cafddf..48de2fa6 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -75,9 +75,7 @@ static uint8_t crctable[256] = { #define ZE1_BATTERY 2 static uint8_t LEAF_battery_Type = ZE0_BATTERY; static bool battery_can_alive = false; -#define MAX_CELL_VOLTAGE 4250 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE 2700 //Battery is put into emergency stop if one cell goes below this value -#define WH_PER_GID 77 //One GID is this amount of Watt hours +#define WH_PER_GID 77 //One GID is this amount of Watt hours static uint16_t battery_Discharge_Power_Limit = 0; //Limit in kW static uint16_t battery_Charge_Power_Limit = 0; //Limit in kW static int16_t battery_MAX_POWER_FOR_CHARGER = 0; //Limit in kW @@ -634,12 +632,6 @@ void receive_can_battery2(CAN_frame rx_frame) { datalayer.battery2.status.cell_max_voltage_mV = battery2_min_max_voltage[1]; datalayer.battery2.status.cell_min_voltage_mV = battery2_min_max_voltage[0]; - if (battery2_min_max_voltage[1] >= MAX_CELL_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (battery2_min_max_voltage[0] <= MIN_CELL_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } break; } @@ -884,12 +876,6 @@ void receive_can_battery(CAN_frame rx_frame) { datalayer.battery.status.cell_max_voltage_mV = battery_min_max_voltage[1]; datalayer.battery.status.cell_min_voltage_mV = battery_min_max_voltage[0]; - if (battery_min_max_voltage[1] >= MAX_CELL_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (battery_min_max_voltage[0] <= MIN_CELL_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } break; } @@ -1221,13 +1207,19 @@ void setup_battery(void) { // Performs one time setup at startup #endif datalayer.battery.info.number_of_cells = 96; - datalayer.battery.info.max_design_voltage_dV = 4040; // 404.4V - datalayer.battery.info.min_design_voltage_dV = 2600; // 260.0V + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; #ifdef DOUBLE_BATTERY datalayer.battery2.info.number_of_cells = datalayer.battery.info.number_of_cells; datalayer.battery2.info.max_design_voltage_dV = datalayer.battery.info.max_design_voltage_dV; datalayer.battery2.info.min_design_voltage_dV = datalayer.battery.info.min_design_voltage_dV; + datalayer.battery2.info.max_cell_voltage_mV = datalayer.battery.info.max_cell_voltage_mV; + datalayer.battery2.info.min_cell_voltage_mV = datalayer.battery.info.min_cell_voltage_mV; + datalayer.battery2.info.max_cell_voltage_deviation_mV = datalayer.battery.info.max_cell_voltage_deviation_mV; #endif //DOUBLE_BATTERY } diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.h b/Software/src/battery/NISSAN-LEAF-BATTERY.h index 41de044f..89ff4443 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.h +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 4040 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 2600 #define MAX_CELL_DEVIATION_MV 500 +#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 uint16_t Temp_fromRAW_to_F(uint16_t temperature); bool is_message_corrupt(CAN_frame rx_frame); diff --git a/Software/src/battery/PYLON-BATTERY.cpp b/Software/src/battery/PYLON-BATTERY.cpp index a71d58f4..0df16c77 100644 --- a/Software/src/battery/PYLON-BATTERY.cpp +++ b/Software/src/battery/PYLON-BATTERY.cpp @@ -4,10 +4,6 @@ #include "../devboard/utils/events.h" #include "PYLON-BATTERY.h" -/* Change the following to suit your battery */ -#define MAX_PACK_VOLTAGE 5000 //5000 = 500.0V -#define MIN_PACK_VOLTAGE 1500 - /* Do not change code below unless you are sure what you are doing */ static unsigned long previousMillis1000 = 0; // will store last time a 1s CAN Message was sent @@ -183,8 +179,10 @@ void setup_battery(void) { // Performs one time setup at startup Serial.println("Pylon battery selected"); #endif - datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE; - datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif diff --git a/Software/src/battery/PYLON-BATTERY.h b/Software/src/battery/PYLON-BATTERY.h index b266d8fc..3ec005e0 100644 --- a/Software/src/battery/PYLON-BATTERY.h +++ b/Software/src/battery/PYLON-BATTERY.h @@ -4,6 +4,12 @@ #include "../include.h" #define BATTERY_SELECTED + +/* Change the following to suit your battery */ +#define MAX_PACK_VOLTAGE_DV 5000 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 1500 +#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 #define MAX_CELL_DEVIATION_MV 9999 void setup_battery(void); diff --git a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp index 34a37032..bd8b1665 100644 --- a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp +++ b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp @@ -106,13 +106,6 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_max_voltage_mV = LB_Cell_Max_Voltage; - if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, (LB_Cell_Max_Voltage / 20)); - } - if (LB_Cell_Min_Voltage <= ABSOLUTE_CELL_MIN_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, (LB_Cell_Min_Voltage / 20)); - } - #ifdef DEBUG_VIA_USB Serial.println("Values going to inverter:"); Serial.print("SOH%: "); @@ -248,9 +241,11 @@ void setup_battery(void) { // Performs one time setup at startup Serial.println("Renault Kangoo battery selected"); #endif - datalayer.battery.info.max_design_voltage_dV = - 4040; // 404.0V, over this, charging is not possible (goes into forced discharge) - datalayer.battery.info.min_design_voltage_dV = 3100; // 310.0V under this, discharging further is disabled + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; } #endif diff --git a/Software/src/battery/RENAULT-KANGOO-BATTERY.h b/Software/src/battery/RENAULT-KANGOO-BATTERY.h index f73c1e85..6afb2335 100644 --- a/Software/src/battery/RENAULT-KANGOO-BATTERY.h +++ b/Software/src/battery/RENAULT-KANGOO-BATTERY.h @@ -4,11 +4,12 @@ #include "../include.h" #define BATTERY_SELECTED - -#define ABSOLUTE_CELL_MAX_VOLTAGE 4150 // If cellvoltage goes over this mV, we go into FAULT mode -#define ABSOLUTE_CELL_MIN_VOLTAGE 2500 // If cellvoltage goes under this mV, we go into FAULT mode -#define MAX_CELL_DEVIATION_MV 500 // If cell mV delta exceeds this, we go into WARNING mode -#define MAX_CHARGE_POWER_W 5000 // Battery can be charged with this amount of power +#define MAX_PACK_VOLTAGE_DV 4150 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 2500 +#define MAX_CELL_DEVIATION_MV 500 +#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 +#define MAX_CHARGE_POWER_W 5000 // Battery can be charged with this amount of power void setup_battery(void); void transmit_can(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp index 5486b086..917e7892 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp @@ -148,15 +148,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_min_voltage_mV = min_cell_mv_value; datalayer.battery.status.cell_max_voltage_mV = max_cell_mv_value; - datalayer.battery.status.voltage_dV = - static_cast((calculated_total_pack_voltage_mV / 100)); // Convert from mV to dV - - if (datalayer.battery.status.cell_max_voltage_mV >= ABSOLUTE_CELL_MAX_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (datalayer.battery.status.cell_min_voltage_mV <= ABSOLUTE_CELL_MIN_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } + datalayer.battery.status.voltage_dV = static_cast((calculated_total_pack_voltage_mV / 100)); // mV to dV #ifdef DEBUG_VIA_USB @@ -535,8 +527,11 @@ void setup_battery(void) { // Performs one time setup at startup #endif datalayer.system.status.battery_allows_contactor_closing = true; datalayer.battery.info.number_of_cells = 96; - datalayer.battery.info.max_design_voltage_dV = 4040; - datalayer.battery.info.min_design_voltage_dV = 2700; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; } #endif diff --git a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h index f3e98b57..81c7c2cc 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h +++ b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.h @@ -3,10 +3,12 @@ #include "../include.h" #define BATTERY_SELECTED - -#define ABSOLUTE_CELL_MAX_VOLTAGE 4200 -#define ABSOLUTE_CELL_MIN_VOLTAGE 3000 #define MAX_CELL_DEVIATION_MV 500 +#define MAX_PACK_VOLTAGE_DV 4200 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 3000 +#define MAX_CELL_DEVIATION_MV 500 +#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(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp index d90fb3e4..e6d7a249 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp @@ -59,13 +59,6 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_max_voltage_mV; - if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (LB_Cell_Min_Voltage <= ABSOLUTE_CELL_MIN_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } - #ifdef DEBUG_VIA_USB #endif @@ -99,9 +92,13 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("Renault Zoe 50kWh battery selected"); #endif - - datalayer.battery.info.max_design_voltage_dV = 4040; - datalayer.battery.info.min_design_voltage_dV = 3100; + datalayer.system.status.battery_allows_contactor_closing = true; + datalayer.battery.info.number_of_cells = 96; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; } #endif diff --git a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.h b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.h index e9910e89..03981d72 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.h +++ b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.h @@ -3,10 +3,11 @@ #include "../include.h" #define BATTERY_SELECTED - -#define ABSOLUTE_CELL_MAX_VOLTAGE 4100 -#define ABSOLUTE_CELL_MIN_VOLTAGE 3000 +#define MAX_PACK_VOLTAGE_DV 4100 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 3000 #define MAX_CELL_DEVIATION_MV 500 +#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(CAN_frame* tx_frame, int interface); diff --git a/Software/src/battery/RJXZS-BMS.cpp b/Software/src/battery/RJXZS-BMS.cpp index b9070ae4..ad04ac2e 100644 --- a/Software/src/battery/RJXZS-BMS.cpp +++ b/Software/src/battery/RJXZS-BMS.cpp @@ -545,8 +545,10 @@ void setup_battery(void) { // Performs one time setup at startup Serial.println("RJXZS BMS selected"); #endif - datalayer.battery.info.max_design_voltage_dV = 5000; - datalayer.battery.info.min_design_voltage_dV = 1000; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif // RJXZS_BMS diff --git a/Software/src/battery/RJXZS-BMS.h b/Software/src/battery/RJXZS-BMS.h index 136fd53f..f42af734 100644 --- a/Software/src/battery/RJXZS-BMS.h +++ b/Software/src/battery/RJXZS-BMS.h @@ -4,6 +4,10 @@ #include "../include.h" /* Tweak these according to your battery build */ +#define MAX_PACK_VOLTAGE_DV 5000 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 1500 +#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 #define MAX_CELL_DEVIATION_MV 250 #define MAX_DISCHARGE_POWER_ALLOWED_W 5000 #define MAX_CHARGE_POWER_ALLOWED_W 5000 diff --git a/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp b/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp index 4b4c53aa..dbe69b55 100644 --- a/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp +++ b/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp @@ -410,8 +410,10 @@ void setup_battery(void) { // Performs one time setup at startup Serial.println("Hyundai Santa Fe PHEV battery selected"); #endif datalayer.battery.info.number_of_cells = 96; - datalayer.battery.info.max_design_voltage_dV = 4040; - datalayer.battery.info.min_design_voltage_dV = 2880; + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; } #endif diff --git a/Software/src/battery/SANTA-FE-PHEV-BATTERY.h b/Software/src/battery/SANTA-FE-PHEV-BATTERY.h index 09be79e5..fb4774a5 100644 --- a/Software/src/battery/SANTA-FE-PHEV-BATTERY.h +++ b/Software/src/battery/SANTA-FE-PHEV-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 4040 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 2880 #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 uint8_t CalculateCRC8(CAN_frame rx_frame); void setup_battery(void); diff --git a/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.h b/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.h index b438e4af..6be72424 100644 --- a/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.h +++ b/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.h @@ -4,9 +4,6 @@ #define SERIAL_LINK_RECEIVER_FROM_BATTERY_H #define BATTERY_SELECTED -#ifndef MAX_CELL_DEVIATION_MV -#define MAX_CELL_DEVIATION_MV 9999 -#endif #include "../include.h" #include "../lib/mackelec-SerialDataLink/SerialDataLink.h" diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 5bcc4fb8..3e493d0b 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -253,16 +253,6 @@ static const char* hvilStatusState[] = {"NOT OK", "UNKNOWN(14)", "UNKNOWN(15)"}; -#define MAX_CELL_VOLTAGE_NCA_NCM 4250 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE_NCA_NCM 2950 //Battery is put into emergency stop if one cell goes below this value -#define MAX_CELL_DEVIATION_NCA_NCM 500 //LED turns yellow on the board if mv delta exceeds this value - -#define MAX_CELL_VOLTAGE_LFP 3550 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE_LFP 2800 //Battery is put into emergency stop if one cell goes below this value -#define MAX_CELL_DEVIATION_LFP 200 //LED turns yellow on the board if mv delta exceeds this value - -#define REASONABLE_ENERGYAMOUNT 20 //When the BMS stops making sense on some values, they are always <20 - void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus //After values are mapped, we perform some safety checks, and do some serial printouts @@ -316,6 +306,8 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_min_voltage_mV = battery_cell_min_v; + battery_cell_deviation_mV = (battery_cell_max_v - battery_cell_min_v); + /* Value mapping is completed. Start to check all safeties */ if (battery_hvil_status == @@ -325,8 +317,6 @@ void update_values_battery() { //This function maps all the values fetched via clear_event(EVENT_INTERNAL_OPEN_FAULT); } - battery_cell_deviation_mV = (battery_cell_max_v - battery_cell_min_v); - #ifdef TESLA_MODEL_3Y_BATTERY // Autodetect algoritm for chemistry on 3/Y packs. // NCM/A batteries have 96s, LFP has 102-106s @@ -339,49 +329,18 @@ void update_values_battery() { //This function maps all the values fetched via if (datalayer.battery.info.chemistry == battery_chemistry_enum::LFP) { datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_LFP; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_LFP; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_LFP; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_LFP; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_LFP; } else { // NCM/A chemistry datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_NCMA; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_NCMA; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_NCA_NCM; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_NCA_NCM; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_NCA_NCM; } #endif // TESLA_MODEL_3Y_BATTERY - //Check if SOC% is plausible - if (datalayer.battery.status.voltage_dV > - (datalayer.battery.info.max_design_voltage_dV - - 20)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT - if (datalayer.battery.status.real_soc < 5000) { //When SOC is less than 50.00% when approaching max voltage - set_event(EVENT_SOC_PLAUSIBILITY_ERROR, datalayer.battery.status.real_soc / 100); - } - } - - if (datalayer.battery.info.chemistry == battery_chemistry_enum::LFP) { //LFP limits used for voltage safeties - if (battery_cell_max_v >= MAX_CELL_VOLTAGE_LFP) { - set_event(EVENT_CELL_OVER_VOLTAGE, (battery_cell_max_v - MAX_CELL_VOLTAGE_LFP)); - } - if (battery_cell_min_v <= MIN_CELL_VOLTAGE_LFP) { - set_event(EVENT_CELL_UNDER_VOLTAGE, (MIN_CELL_VOLTAGE_LFP - battery_cell_min_v)); - } - if (battery_cell_deviation_mV > MAX_CELL_DEVIATION_LFP) { - set_event(EVENT_CELL_DEVIATION_HIGH, battery_cell_deviation_mV); - } else { - clear_event(EVENT_CELL_DEVIATION_HIGH); - } - } else { //NCA/NCM limits used - if (battery_cell_max_v >= MAX_CELL_VOLTAGE_NCA_NCM) { - set_event(EVENT_CELL_OVER_VOLTAGE, (battery_cell_max_v - MAX_CELL_VOLTAGE_NCA_NCM)); - } - if (battery_cell_min_v <= MIN_CELL_VOLTAGE_NCA_NCM) { - set_event(EVENT_CELL_UNDER_VOLTAGE, (MIN_CELL_VOLTAGE_NCA_NCM - battery_cell_min_v)); - } - if (battery_cell_deviation_mV > MAX_CELL_DEVIATION_NCA_NCM) { - set_event(EVENT_CELL_DEVIATION_HIGH, battery_cell_deviation_mV); - } else { - clear_event(EVENT_CELL_DEVIATION_HIGH); - } - } - - /* Safeties verified. Perform USB serial printout if configured to do so */ - #ifdef DEBUG_VIA_USB printFaultCodesIfActive(); @@ -898,6 +857,8 @@ void update_values_battery2() { //This function maps all the values fetched via datalayer.battery2.status.cell_min_voltage_mV = battery2_cell_min_v; + battery2_cell_deviation_mV = (battery2_cell_max_v - battery2_cell_min_v); + /* Value mapping is completed. Start to check all safeties */ if (battery2_hvil_status == @@ -907,8 +868,6 @@ void update_values_battery2() { //This function maps all the values fetched via clear_event(EVENT_INTERNAL_OPEN_FAULT); } - battery2_cell_deviation_mV = (battery2_cell_max_v - battery2_cell_min_v); - #ifdef TESLA_MODEL_3Y_BATTERY // Autodetect algoritm for chemistry on 3/Y packs. // NCM/A batteries have 96s, LFP has 102-106s @@ -921,57 +880,18 @@ void update_values_battery2() { //This function maps all the values fetched via if (datalayer.battery2.info.chemistry == battery_chemistry_enum::LFP) { datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_LFP; datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_LFP; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_LFP; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_LFP; + datalayer.battery2.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_LFP; } else { // NCM/A chemistry datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_NCMA; datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_NCMA; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_NCA_NCM; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_NCA_NCM; + datalayer.battery2.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_NCA_NCM; } - #endif // TESLA_MODEL_3Y_BATTERY - //Check if SOC% is plausible - if (datalayer.battery2.status.voltage_dV > - (datalayer.battery2.info.max_design_voltage_dV - - 20)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT - if (datalayer.battery2.status.real_soc < 5000) { //When SOC is less than 50.00% when approaching max voltage - set_event(EVENT_SOC_PLAUSIBILITY_ERROR, datalayer.battery2.status.real_soc / 100); - } - } - - //Check if BMS is in need of recalibration - if (battery2_nominal_full_pack_energy > 1 && battery2_nominal_full_pack_energy < REASONABLE_ENERGYAMOUNT) { - set_event(EVENT_KWH_PLAUSIBILITY_ERROR, battery2_nominal_full_pack_energy); - } else if (battery2_nominal_full_pack_energy <= 1) { - set_event(EVENT_KWH_PLAUSIBILITY_ERROR, battery2_nominal_full_pack_energy); - } - - if (datalayer.battery2.info.chemistry == battery_chemistry_enum::LFP) { //LFP limits used for voltage safeties - if (battery2_cell_max_v >= MAX_CELL_VOLTAGE_LFP) { - set_event(EVENT_CELL_OVER_VOLTAGE, (battery2_cell_max_v - MAX_CELL_VOLTAGE_LFP)); - } - if (battery2_cell_min_v <= MIN_CELL_VOLTAGE_LFP) { - set_event(EVENT_CELL_UNDER_VOLTAGE, (MIN_CELL_VOLTAGE_LFP - battery2_cell_min_v)); - } - if (battery2_cell_deviation_mV > MAX_CELL_DEVIATION_LFP) { - set_event(EVENT_CELL_DEVIATION_HIGH, battery2_cell_deviation_mV); - } else { - clear_event(EVENT_CELL_DEVIATION_HIGH); - } - } else { //NCA/NCM limits used - if (battery2_cell_max_v >= MAX_CELL_VOLTAGE_NCA_NCM) { - set_event(EVENT_CELL_OVER_VOLTAGE, (battery2_cell_max_v - MAX_CELL_VOLTAGE_NCA_NCM)); - } - if (battery2_cell_min_v <= MIN_CELL_VOLTAGE_NCA_NCM) { - set_event(EVENT_CELL_UNDER_VOLTAGE, (MIN_CELL_VOLTAGE_NCA_NCM - battery2_cell_min_v)); - } - if (battery2_cell_deviation_mV > MAX_CELL_DEVIATION_NCA_NCM) { - set_event(EVENT_CELL_DEVIATION_HIGH, battery2_cell_deviation_mV); - } else { - clear_event(EVENT_CELL_DEVIATION_HIGH); - } - } - - /* Safeties verified. Perform USB serial printout if configured to do so */ - #ifdef DEBUG_VIA_USB printFaultCodesIfActive_battery2(); @@ -1254,9 +1174,15 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef TESLA_MODEL_SX_BATTERY // Always use NCM/A mode on S/X packs datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_SX_NCMA; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_SX_NCMA; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_NCA_NCM; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_NCA_NCM; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_NCA_NCM; #ifdef DOUBLE_BATTERY datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_SX_NCMA; datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_SX_NCMA; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_NCA_NCM; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_NCA_NCM; + datalayer.battery2.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_NCA_NCM; #endif // DOUBLE_BATTERY #endif // TESLA_MODEL_SX_BATTERY @@ -1265,17 +1191,29 @@ void setup_battery(void) { // Performs one time setup at startup datalayer.battery.info.chemistry = battery_chemistry_enum::LFP; datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_LFP; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_LFP; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_LFP; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_LFP; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_LFP; #ifdef DOUBLE_BATTERY datalayer.battery2.info.chemistry = battery_chemistry_enum::LFP; datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_LFP; datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_LFP; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_LFP; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_LFP; + datalayer.battery2.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_LFP; #endif // DOUBLE_BATTERY #else // Startup in NCM/A mode datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_NCMA; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_NCMA; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_NCA_NCM; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_NCA_NCM; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_NCA_NCM; #ifdef DOUBLE_BATTERY datalayer.battery2.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_3Y_NCMA; datalayer.battery2.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_3Y_NCMA; + datalayer.battery2.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_NCA_NCM; + datalayer.battery2.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_NCA_NCM; + datalayer.battery2.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_NCA_NCM; #endif // DOUBLE_BATTERY #endif // !LFP_CHEMISTRY #endif // TESLA_MODEL_3Y_BATTERY diff --git a/Software/src/battery/TESLA-BATTERY.h b/Software/src/battery/TESLA-BATTERY.h index a9a28f6e..22806132 100644 --- a/Software/src/battery/TESLA-BATTERY.h +++ b/Software/src/battery/TESLA-BATTERY.h @@ -15,13 +15,18 @@ #define FLOAT_MAX_POWER_W 200 // W, what power to allow for top balancing battery #define FLOAT_START_MV 20 // mV, how many mV under overvoltage to start float charging -#define MAX_PACK_VOLTAGE_SX_NCMA 4600 // V+1, if pack voltage goes over this, charge stops -#define MIN_PACK_VOLTAGE_SX_NCMA 3100 // V+1, if pack voltage goes over this, charge stops -#define MAX_PACK_VOLTAGE_3Y_NCMA 4030 // V+1, if pack voltage goes over this, charge stops -#define MIN_PACK_VOLTAGE_3Y_NCMA 3100 // V+1, if pack voltage goes below this, discharge stops -#define MAX_PACK_VOLTAGE_3Y_LFP 3880 // V+1, if pack voltage goes over this, charge stops -#define MIN_PACK_VOLTAGE_3Y_LFP 2968 // V+1, if pack voltage goes below this, discharge stops -#define MAX_CELL_DEVIATION_MV 9999 // Handled inside the Tesla.cpp file, just for compilation +#define MAX_PACK_VOLTAGE_SX_NCMA 4600 // V+1, if pack voltage goes over this, charge stops +#define MIN_PACK_VOLTAGE_SX_NCMA 3100 // V+1, if pack voltage goes over this, charge stops +#define MAX_PACK_VOLTAGE_3Y_NCMA 4030 // V+1, if pack voltage goes over this, charge stops +#define MIN_PACK_VOLTAGE_3Y_NCMA 3100 // V+1, if pack voltage goes below this, discharge stops +#define MAX_PACK_VOLTAGE_3Y_LFP 3880 // V+1, if pack voltage goes over this, charge stops +#define MIN_PACK_VOLTAGE_3Y_LFP 2968 // V+1, if pack voltage goes below this, discharge stops +#define MAX_CELL_DEVIATION_NCA_NCM 500 //LED turns yellow on the board if mv delta exceeds this value +#define MAX_CELL_DEVIATION_LFP 200 //LED turns yellow on the board if mv delta exceeds this value +#define MAX_CELL_VOLTAGE_NCA_NCM 4250 //Battery is put into emergency stop if one cell goes over this value +#define MIN_CELL_VOLTAGE_NCA_NCM 2950 //Battery is put into emergency stop if one cell goes below this value +#define MAX_CELL_VOLTAGE_LFP 3550 //Battery is put into emergency stop if one cell goes over this value +#define MIN_CELL_VOLTAGE_LFP 2800 //Battery is put into emergency stop if one cell goes below this value void printFaultCodesIfActive(); void printDebugIfActive(uint8_t symbol, const char* message); diff --git a/Software/src/battery/VOLVO-SPA-BATTERY.cpp b/Software/src/battery/VOLVO-SPA-BATTERY.cpp index 5d392906..d321ad38 100644 --- a/Software/src/battery/VOLVO-SPA-BATTERY.cpp +++ b/Software/src/battery/VOLVO-SPA-BATTERY.cpp @@ -8,9 +8,6 @@ static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send static unsigned long previousMillis60s = 0; // will store last time a 60s CAN Message was send -#define MAX_CELL_VOLTAGE 4210 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE 2700 //Battery is put into emergency stop if one cell goes below this value - static float BATT_U = 0; //0x3A static float MAX_U = 0; //0x3A static float MIN_U = 0; //0x3A @@ -22,8 +19,8 @@ static float BATT_T_MIN = 0; //0x413 static float BATT_T_AVG = 0; //0x413 static uint16_t SOC_BMS = 0; //0X37D static uint16_t SOC_CALC = 0; -static uint16_t CELL_U_MAX = 0; //0x37D -static uint16_t CELL_U_MIN = 0; //0x37D +static uint16_t CELL_U_MAX = 3700; //0x37D +static uint16_t CELL_U_MIN = 3700; //0x37D static uint8_t CELL_ID_U_MAX = 0; //0x37D static uint16_t HvBattPwrLimDchaSoft = 0; //0x369 static uint8_t batteryModuleNumber = 0x10; // First battery module @@ -288,12 +285,6 @@ void receive_can_battery(CAN_frame rx_frame) { min_max_voltage[1] = cell_voltages[cellcounter]; } - if (min_max_voltage[1] >= MAX_CELL_VOLTAGE) { - set_event(EVENT_CELL_OVER_VOLTAGE, 0); - } - if (min_max_voltage[0] <= MIN_CELL_VOLTAGE) { - set_event(EVENT_CELL_UNDER_VOLTAGE, 0); - } transmit_can(&VOLVO_SOH_Req, can_config.battery); //Send SOH read request } rxConsecutiveFrames = 0; @@ -347,8 +338,10 @@ void setup_battery(void) { // Performs one time setup at startup #endif datalayer.battery.info.number_of_cells = 108; - datalayer.battery.info.max_design_voltage_dV = - 4540; // 454.0V, over this, charging is not possible (goes into forced discharge) - datalayer.battery.info.min_design_voltage_dV = 2938; // 293.8V under this, discharging further is disabled + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; } #endif diff --git a/Software/src/battery/VOLVO-SPA-BATTERY.h b/Software/src/battery/VOLVO-SPA-BATTERY.h index de98d084..76c28074 100644 --- a/Software/src/battery/VOLVO-SPA-BATTERY.h +++ b/Software/src/battery/VOLVO-SPA-BATTERY.h @@ -4,7 +4,11 @@ #include "../include.h" #define BATTERY_SELECTED +#define MAX_PACK_VOLTAGE_DV 4540 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 2938 #define MAX_CELL_DEVIATION_MV 250 +#define MAX_CELL_VOLTAGE_MV 4210 //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(CAN_frame* tx_frame, int interface); diff --git a/Software/src/datalayer/datalayer.h b/Software/src/datalayer/datalayer.h index eebcf3a6..d8389a6c 100644 --- a/Software/src/datalayer/datalayer.h +++ b/Software/src/datalayer/datalayer.h @@ -13,6 +13,12 @@ typedef struct { uint16_t max_design_voltage_dV = 5000; /** The minimum intended packvoltage, in deciVolt. 3300 = 330.0 V */ uint16_t min_design_voltage_dV = 2500; + /** The maximum cellvoltage before shutting down, in milliVolt. 4300 = 4.250 V */ + uint16_t max_cell_voltage_mV = 4300; + /** The minimum cellvoltage before shutting down, in milliVolt. 2700 = 2.700 V */ + uint16_t min_cell_voltage_mV = 2700; + /** The maxumum allowed deviation between cells, in milliVolt. 500 = 0.500 V */ + uint16_t max_cell_voltage_deviation_mV = 500; /** BYD CAN specific setting, max charge in deciAmpere. 300 = 30.0 A */ uint16_t max_charge_amp_dA = BATTERY_MAX_CHARGE_AMP; /** BYD CAN specific setting, max discharge in deciAmpere. 300 = 30.0 A */ diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index e9a592a2..2b57b618 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -54,6 +54,15 @@ void update_machineryprotection() { clear_event(EVENT_BATTERY_UNDERVOLTAGE); } + // Cell overvoltage, critical latching error without automatic reset. Requires user action. + if (datalayer.battery.status.cell_max_voltage_mV >= datalayer.battery.info.max_cell_voltage_mV) { + set_event(EVENT_CELL_OVER_VOLTAGE, 0); + } + // Cell undervoltage, critical latching error without automatic reset. Requires user action. + if (datalayer.battery.status.cell_min_voltage_mV <= datalayer.battery.info.min_cell_voltage_mV) { + set_event(EVENT_CELL_UNDER_VOLTAGE, 0); + } + // Battery is fully charged. Dont allow any more power into it // Normally the BMS will send 0W allowed, but this acts as an additional layer of safety if (datalayer.battery.status.reported_soc == 10000) //Scaled SOC% value is 100.00% @@ -103,7 +112,7 @@ void update_machineryprotection() { // Check diff between highest and lowest cell cell_deviation_mV = (datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV); - if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) { + if (cell_deviation_mV > datalayer.battery.info.max_cell_voltage_deviation_mV) { set_event(EVENT_CELL_DEVIATION_HIGH, (cell_deviation_mV / 20)); } else { clear_event(EVENT_CELL_DEVIATION_HIGH); @@ -175,6 +184,23 @@ void update_machineryprotection() { clear_event(EVENT_CAN_RX_WARNING); } + // Cell overvoltage, critical latching error without automatic reset. Requires user action. + if (datalayer.battery2.status.cell_max_voltage_mV >= datalayer.battery2.info.max_cell_voltage_mV) { + set_event(EVENT_CELL_OVER_VOLTAGE, 0); + } + // Cell undervoltage, critical latching error without automatic reset. Requires user action. + if (datalayer.battery2.status.cell_min_voltage_mV <= datalayer.battery2.info.min_cell_voltage_mV) { + set_event(EVENT_CELL_UNDER_VOLTAGE, 0); + } + + // Check diff between highest and lowest cell + cell_deviation_mV = (datalayer.battery2.status.cell_max_voltage_mV - datalayer.battery2.status.cell_min_voltage_mV); + if (cell_deviation_mV > datalayer.battery2.info.max_cell_voltage_deviation_mV) { + set_event(EVENT_CELL_DEVIATION_HIGH, (cell_deviation_mV / 20)); + } else { + clear_event(EVENT_CELL_DEVIATION_HIGH); + } + // 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 From adf8185d3394fddfa8f8ff4c20b910beabd4f325 Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Thu, 3 Oct 2024 09:43:41 +0100 Subject: [PATCH 11/26] Replaced all instances of "emergency" with "equipment" in the code for improved clarity and alignment with the feature's purpose. --- Software/Software.ino | 16 ++++++++-------- Software/USER_SETTINGS.h | 2 +- Software/src/devboard/safety/safety.cpp | 16 ++++++++-------- Software/src/devboard/safety/safety.h | 4 ++-- Software/src/devboard/utils/events.cpp | 6 +++--- Software/src/devboard/utils/events.h | 2 +- Software/src/devboard/webserver/webserver.cpp | 11 +++++++---- 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 48bc3183..94f3d9d7 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -353,17 +353,17 @@ void init_stored_settings() { static uint32_t temp = 0; settings.begin("batterySettings", false); - // Always get the emergency stop status - datalayer.system.settings.equipment_stop_active = settings.getBool("EMERGENCY_STOP", false); + // Always get the equipment stop status + datalayer.system.settings.equipment_stop_active = settings.getBool("EQUIPMENT_STOP", false); if (datalayer.system.settings.equipment_stop_active) { - set_event(EVENT_EMERGENCY_STOP, 1); + set_event(EVENT_EQUIPMENT_STOP, 1); } #ifndef LOAD_SAVED_SETTINGS_ON_BOOT settings.clear(); // If this clear function is executed, no settings will be read from storage - //always save the emergency stop status - settings.putBool("EMERGENCY_STOP", datalayer.system.settings.equipment_stop_active); + //always save the equipment stop status + settings.putBool("EQUIPMENT_STOP", datalayer.system.settings.equipment_stop_active); #endif @@ -585,7 +585,7 @@ void monitor_equipment_stop_button() { long pressDuration = equipment_button_releasedTime - equipment_button_pressedTime; if (pressDuration < equipment_button_long_press_duration) { - // Short press detected, trigger emergency stop + // Short press detected, trigger equipment stop setBatteryPause(true, true, true); } else { // Long press detected, reset equipment stop state @@ -913,9 +913,9 @@ void init_serialDataLink() { #endif } -void store_settings_emergency_stop() { +void store_settings_equipment_stop() { settings.begin("batterySettings", false); - settings.putBool("EMERGENCY_STOP", datalayer.system.settings.equipment_stop_active); + settings.putBool("EQUIPMENT_STOP", datalayer.system.settings.equipment_stop_active); settings.end(); } diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 08b9b5fa..e72a51c0 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -65,7 +65,7 @@ #define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled. #define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below) //#define FUNCTION_TIME_MEASUREMENT // Enable this to record execution times and present them in the web UI (WARNING, raises CPU load, do not use for production) -//#define EQUIPMENT_STOP_BUTTON // Enable this to allow an emergency/equipment stop button connected to the Battery-Emulator to disengage the battery +//#define EQUIPMENT_STOP_BUTTON // Enable this to allow an equipment stop button connected to the Battery-Emulator to disengage the battery /* MQTT options */ // #define MQTT // Enable this line to enable MQTT diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index c3b79ede..adab2e7f 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -196,22 +196,22 @@ void update_machineryprotection() { } //battery pause status begin -void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop, bool store_settings) { +void setBatteryPause(bool pause_battery, bool pause_CAN, bool equipment_stop, bool store_settings) { - // First handle emergency stop / resume - if (emergency_stop && !datalayer.system.settings.equipment_stop_active) { + // First handle equipment stop / resume + if (equipment_stop && !datalayer.system.settings.equipment_stop_active) { datalayer.system.settings.equipment_stop_active = true; if (store_settings) { - store_settings_emergency_stop(); + store_settings_equipment_stop(); } - set_event(EVENT_EMERGENCY_STOP, 1); - } else if (!emergency_stop && datalayer.system.settings.equipment_stop_active) { + set_event(EVENT_EQUIPMENT_STOP, 1); + } else if (!equipment_stop && datalayer.system.settings.equipment_stop_active) { datalayer.system.settings.equipment_stop_active = false; if (store_settings) { - store_settings_emergency_stop(); + store_settings_equipment_stop(); } - clear_event(EVENT_EMERGENCY_STOP); + clear_event(EVENT_EQUIPMENT_STOP); } emulator_pause_CAN_send_ON = pause_CAN; diff --git a/Software/src/devboard/safety/safety.h b/Software/src/devboard/safety/safety.h index 9dd71851..82a6298f 100644 --- a/Software/src/devboard/safety/safety.h +++ b/Software/src/devboard/safety/safety.h @@ -16,12 +16,12 @@ extern battery_pause_status emulator_pause_status; extern bool allowed_to_send_CAN; //battery pause status end -extern void store_settings_emergency_stop(); +extern void store_settings_equipment_stop(); void update_machineryprotection(); //battery pause status begin -void setBatteryPause(bool pause_battery, bool pause_CAN, bool emergency_stop = false, bool store_settings = true); +void setBatteryPause(bool pause_battery, bool pause_CAN, bool equipment_stop = false, bool store_settings = true); void emulator_pause_state_send_CAN_battery(); std::string get_emulator_pause_status(); //battery pause status end diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 6cc5aaed..faefc6e2 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -213,7 +213,7 @@ void init_events(void) { events.entries[EVENT_WIFI_DISCONNECT].level = EVENT_LEVEL_INFO; events.entries[EVENT_MQTT_CONNECT].level = EVENT_LEVEL_INFO; events.entries[EVENT_MQTT_DISCONNECT].level = EVENT_LEVEL_INFO; - events.entries[EVENT_EMERGENCY_STOP].level = EVENT_LEVEL_ERROR; + events.entries[EVENT_EQUIPMENT_STOP].level = EVENT_LEVEL_ERROR; events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger... @@ -412,8 +412,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) { return "Info: MQTT connected."; case EVENT_MQTT_DISCONNECT: return "Info: MQTT disconnected."; - case EVENT_EMERGENCY_STOP: - return "ERROR: EMERGENCY STOP ACTIVATED!!!"; + case EVENT_EQUIPMENT_STOP: + return "ERROR: EQUIPMENT STOP ACTIVATED!!!"; default: return ""; } diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index cd036bb4..7734e82b 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -101,7 +101,7 @@ XX(EVENT_WIFI_DISCONNECT) \ XX(EVENT_MQTT_CONNECT) \ XX(EVENT_MQTT_DISCONNECT) \ - XX(EVENT_EMERGENCY_STOP) \ + XX(EVENT_EQUIPMENT_STOP) \ XX(EVENT_NOF_EVENTS) typedef enum { EVENTS_ENUM_TYPE(GENERATE_ENUM) } EVENTS_ENUM_TYPE; diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 800c23b1..2c6cbf5d 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -166,8 +166,8 @@ void init_webserver() { } }); - // Route for emergency stop/resume - server.on("/emergencyStop", HTTP_GET, [](AsyncWebServerRequest* request) { + // Route for equipment stop/resume + server.on("/equipmentStop", HTTP_GET, [](AsyncWebServerRequest* request) { if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) return request->requestAuthentication(); if (request->hasParam("stop")) { @@ -345,7 +345,7 @@ void init_webserver() { return request->requestAuthentication(); request->send(200, "text/plain", "Rebooting server..."); - //Equipment STOP without persisting the emergency state before restart + //Equipment STOP without persisting the equipment state before restart // Max Charge/Discharge = 0; CAN = stop; contactors = open setBatteryPause(true, true, true, false); delay(1000); @@ -911,7 +911,7 @@ String processor(const String& var) { content += "var xhr=new " "XMLHttpRequest();xhr.onload=function() { " - "window.location.reload();};xhr.open('GET','/emergencyStop?stop='+stop,true);xhr.send();"; + "window.location.reload();};xhr.open('GET','/equipmentStop?stop='+stop,true);xhr.send();"; content += "}"; content += ""; @@ -958,6 +958,9 @@ void onOTAEnd(bool success) { // Log when OTA has finished if (success) { + //Equipment STOP without persisting the equipment state before restart + // Max Charge/Discharge = 0; CAN = stop; contactors = open + setBatteryPause(true, true, true, false); // a reboot will be done by the OTA library. no need to do anything here #ifdef DEBUG_VIA_USB Serial.println("OTA update finished successfully!"); From c161e95e7e5d8390b72e6f4cb084a42824330e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Thu, 3 Oct 2024 11:46:54 +0300 Subject: [PATCH 12/26] Make tighter mv celldiff for pylon --- Software/src/battery/PYLON-BATTERY.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/PYLON-BATTERY.h b/Software/src/battery/PYLON-BATTERY.h index 3ec005e0..98588c69 100644 --- a/Software/src/battery/PYLON-BATTERY.h +++ b/Software/src/battery/PYLON-BATTERY.h @@ -10,7 +10,7 @@ #define MIN_PACK_VOLTAGE_DV 1500 #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 -#define MAX_CELL_DEVIATION_MV 9999 +#define MAX_CELL_DEVIATION_MV 500 void setup_battery(void); void transmit_can(CAN_frame* tx_frame, int interface); From 8fed9f237a7e1d5de91ffa59ba7b988c7a4c8f7e Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:26:03 +0100 Subject: [PATCH 13/26] change terms --- Software/Software.ino | 4 ++-- Software/USER_SETTINGS.cpp | 6 +++--- Software/USER_SETTINGS.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 94f3d9d7..9db0bc83 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -566,7 +566,7 @@ void monitor_equipment_stop_button() { // read the state of the switch/button: equipment_button_currentState = digitalRead(EQUIPMENT_STOP_PIN); - if (equipment_stop_behavior == TOGGLE_SWITCH) { + if (equipment_stop_behavior == LATCHING_SWITCH) { if (equipment_button_lastState != equipment_button_currentState || first_run_after_boot) { if (!equipment_button_currentState) { // Changed to ON – initiating equipment stop. @@ -576,7 +576,7 @@ void monitor_equipment_stop_button() { setBatteryPause(false, false, false); } } - } else if (equipment_stop_behavior == PERSISTENT_ACTIVATION_SWITCH) { + } else if (equipment_stop_behavior == MOMENTARY_SWITCH) { if (equipment_button_lastState == HIGH && equipment_button_currentState == LOW) { // button is pressed equipment_button_pressedTime = millis(); } else if (equipment_button_lastState == LOW && equipment_button_currentState == HIGH) { // button is released diff --git a/Software/USER_SETTINGS.cpp b/Software/USER_SETTINGS.cpp index a4c0b56f..9c203e0a 100644 --- a/Software/USER_SETTINGS.cpp +++ b/Software/USER_SETTINGS.cpp @@ -50,9 +50,9 @@ const char* mqtt_password = "REDACTED"; // Set NULL for no password #ifdef EQUIPMENT_STOP_BUTTON // Equipment stop button behavior. Use NC button for safety reasons. -//TOGGLE_SWITCH - activated while pressed, deactivated when released, button state is reflected in the emulator state -//PERSISTENT_ACTIVATION_SWITCH - short press to activate, long press to deactivate, state is persisted between reboots -volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior = TOGGLE_SWITCH; +//LATCHING_SWITCH - Normally closed (NC), latching switch. When pressed it activates e-stop +//MOMENTARY_SWITCH - Short press to activate e-stop, long 5s press to deactivate. E-stop is persistent between reboots +volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior = LATCHING_SWITCH; #endif /* Charger settings (Optional, when using generator charging) */ diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index e72a51c0..86e603b4 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -121,7 +121,7 @@ extern bool charger_HV_enabled; extern bool charger_aux12V_enabled; #ifdef EQUIPMENT_STOP_BUTTON -typedef enum { TOGGLE_SWITCH = 0, PERSISTENT_ACTIVATION_SWITCH = 1 } STOP_BUTTON_BEHAVIOR; +typedef enum { LATCHING_SWITCH = 0, MOMENTARY_SWITCH = 1 } STOP_BUTTON_BEHAVIOR; extern volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior; #endif From f7f1427aefac8fd4c5be15f29c5049c0287c535f Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:36:20 +0100 Subject: [PATCH 14/26] long press increased to 15s --- Software/Software.ino | 8 ++++---- Software/USER_SETTINGS.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 9db0bc83..9f8b5991 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -136,10 +136,10 @@ unsigned long timeSpentInFaultedMode = 0; #endif #ifdef EQUIPMENT_STOP_BUTTON -volatile unsigned long equipment_button_press_time = 0; // Time when button is pressed -const unsigned long equipment_button_long_press_duration = 5000; // 5 seconds for long press -int equipment_button_lastState = HIGH; // the previous state from the input pin NC -int equipment_button_currentState; // the current reading from the input pin +volatile unsigned long equipment_button_press_time = 0; // Time when button is pressed +const unsigned long equipment_button_long_press_duration = 15000; // 15 seconds for long press +int equipment_button_lastState = HIGH; // the previous state from the input pin NC +int equipment_button_currentState; // the current reading from the input pin unsigned long equipment_button_pressedTime = 0; unsigned long equipment_button_releasedTime = 0; bool first_run_after_boot = true; diff --git a/Software/USER_SETTINGS.cpp b/Software/USER_SETTINGS.cpp index 9c203e0a..3f50223a 100644 --- a/Software/USER_SETTINGS.cpp +++ b/Software/USER_SETTINGS.cpp @@ -51,7 +51,7 @@ const char* mqtt_password = "REDACTED"; // Set NULL for no password #ifdef EQUIPMENT_STOP_BUTTON // Equipment stop button behavior. Use NC button for safety reasons. //LATCHING_SWITCH - Normally closed (NC), latching switch. When pressed it activates e-stop -//MOMENTARY_SWITCH - Short press to activate e-stop, long 5s press to deactivate. E-stop is persistent between reboots +//MOMENTARY_SWITCH - Short press to activate e-stop, long 15s press to deactivate. E-stop is persistent between reboots volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior = LATCHING_SWITCH; #endif From 917f76fd47f82cc5f99a2df71a7c5e66bf13500f Mon Sep 17 00:00:00 2001 From: amarofarinha <151563493+amarofarinha@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:59:43 +0100 Subject: [PATCH 15/26] button name on web site --- Software/src/devboard/webserver/webserver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 2c6cbf5d..9e055d2b 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -870,14 +870,14 @@ String processor(const String& var) { " onclick=\"" "if(confirm('This action will open contactors on the battery and stop all CAN communications. Are you " "sure?')) { estop(true); }\"" - ">EQUIPMENT STOP
"; + ">Open Contactors
"; else content += "


"; + ">Close Contactors
"; content += "