From 9031d3e5cf4ea591ae8db9f9673d5c79cf413e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 1 Sep 2025 13:25:59 +0300 Subject: [PATCH] Move more settings to common-image --- Software/USER_SETTINGS.h | 9 --- Software/src/battery/CHADEMO-BATTERY.h | 3 - .../comm_contactorcontrol.cpp | 61 +++++-------------- .../contactorcontrol/comm_contactorcontrol.h | 3 + Software/src/communication/nvm/comm_nvm.cpp | 3 + .../src/devboard/webserver/settings_html.cpp | 56 +++++++++++++---- Software/src/devboard/webserver/webserver.cpp | 9 +++ 7 files changed, 76 insertions(+), 68 deletions(-) diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 8c450453..08cb36b6 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -14,15 +14,6 @@ //#define HW_3LB //#define HW_DEVKIT -/* Contactor settings. If you have a battery that does not activate contactors via CAN, configure this section */ -#define PRECHARGE_TIME_MS 500 //Precharge time in milliseconds. Modify to suit your inverter (See wiki for more info) -//#define CONTACTOR_CONTROL //Enable this line to have the emulator handle automatic precharge/contactor+/contactor- closing sequence (See wiki for pins) -//#define CONTACTOR_CONTROL_DOUBLE_BATTERY //Enable this line to have the emulator hardware control secondary set of contactors for double battery setups (See wiki for pins) -//#define PWM_CONTACTOR_CONTROL //Enable this line to use PWM for CONTACTOR_CONTROL, which lowers power consumption and heat generation. CONTACTOR_CONTROL must be enabled. -//#define NC_CONTACTORS //Enable this line to control normally closed contactors. CONTACTOR_CONTROL must be enabled for this option. Extremely rare setting! -//#define PERIODIC_BMS_RESET //Enable to have the emulator powercycle the connected battery every 24hours via GPIO. Useful for some batteries like Nissan LEAF -//#define REMOTE_BMS_RESET //Enable to allow the emulator to remotely trigger a powercycle of the battery via MQTT. Useful for some batteries like Nissan LEAF - /* Shunt/Contactor settings (Optional) */ //#define BMW_SBOX // SBOX relay control & battery current/voltage measurement diff --git a/Software/src/battery/CHADEMO-BATTERY.h b/Software/src/battery/CHADEMO-BATTERY.h index 8e603f4e..613a8057 100644 --- a/Software/src/battery/CHADEMO-BATTERY.h +++ b/Software/src/battery/CHADEMO-BATTERY.h @@ -9,9 +9,6 @@ #ifdef CHADEMO_BATTERY #define SELECTED_BATTERY_CLASS ChademoBattery - -//Contactor control is required for CHADEMO support -#define CONTACTOR_CONTROL #endif class ChademoBattery : public CanBattery { diff --git a/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp b/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp index c7a0e877..a88ff9d0 100644 --- a/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp +++ b/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp @@ -3,45 +3,16 @@ #include "../../devboard/safety/safety.h" #include "../../inverter/INVERTERS.h" -#ifdef CONTACTOR_CONTROL -const bool contactor_control_enabled_default = true; -#else -const bool contactor_control_enabled_default = false; -#endif -bool contactor_control_enabled = contactor_control_enabled_default; - -#ifdef PWM_CONTACTOR_CONTROL -const bool pwn_contactor_control_default = true; -#else -const bool pwn_contactor_control_default = false; -#endif -bool pwm_contactor_control = pwn_contactor_control_default; - -#ifdef PERIODIC_BMS_RESET -const bool periodic_bms_reset_default = true; -#else -const bool periodic_bms_reset_default = false; -#endif -bool periodic_bms_reset = periodic_bms_reset_default; - -#ifdef REMOTE_BMS_RESET -const bool remote_bms_reset_default = true; -#else -const bool remote_bms_reset_default = false; -#endif -bool remote_bms_reset = remote_bms_reset_default; - -#ifdef CONTACTOR_CONTROL_DOUBLE_BATTERY -const bool contactor_control_enabled_double_battery_default = true; -#else -const bool contactor_control_enabled_double_battery_default = false; -#endif -bool contactor_control_enabled_double_battery = contactor_control_enabled_double_battery_default; - // TODO: Ensure valid values at run-time +// User can update all these values via Settings page +bool contactor_control_enabled = false; //Should GPIO contactor control be performed? +uint16_t precharge_time_ms = 100; //Precharge time in ms. Adjust depending on capacitance in inverter +bool pwm_contactor_control = false; //Should the contactors be economized via PWM after they are engaged? +bool contactor_control_enabled_double_battery = false; //Should a contactor for the secondary battery be operated? +bool remote_bms_reset = false; //Is it possible to actuate BMS reset via MQTT? +bool periodic_bms_reset = false; //Should periodic BMS reset be performed each 24h? // Parameters - enum State { DISCONNECTED, START_PRECHARGE, PRECHARGE, POSITIVE, PRECHARGE_OFF, COMPLETED, SHUTDOWN_REQUESTED }; State contactorStatus = DISCONNECTED; @@ -60,11 +31,11 @@ const int OFF = 0; 500 // Time after negative contactor is turned on, to start precharge (not actual precharge time!) #define PRECHARGE_COMPLETED_TIME_MS \ 1000 // After successful precharge, resistor is turned off after this delay (and contactors are economized if PWM enabled) -#define PWM_Freq 20000 // 20 kHz frequency, beyond audible range -#define PWM_Res 10 // 10 Bit resolution 0 to 1023, maps 'nicely' to 0% 100% -#define PWM_HOLD_DUTY 250 -#define PWM_OFF_DUTY 0 +uint16_t pwm_frequency = 20000; +uint16_t pwm_hold_duty = 250; #define PWM_ON_DUTY 1023 +#define PWM_RESOLUTION 10 +#define PWM_OFF_DUTY 0 //No need to have this userconfigurable #define PWM_Positive_Channel 0 #define PWM_Negative_Channel 1 static unsigned long prechargeStartTime = 0; @@ -108,8 +79,8 @@ bool init_contactors() { if (pwm_contactor_control) { // Setup PWM Channel Frequency and Resolution - ledcAttachChannel(posPin, PWM_Freq, PWM_Res, PWM_Positive_Channel); - ledcAttachChannel(negPin, PWM_Freq, PWM_Res, PWM_Negative_Channel); + ledcAttachChannel(posPin, pwm_frequency, PWM_RESOLUTION, PWM_Positive_Channel); + ledcAttachChannel(negPin, pwm_frequency, PWM_RESOLUTION, PWM_Negative_Channel); // Set all pins OFF (0% PWM) ledcWrite(posPin, PWM_OFF_DUTY); ledcWrite(negPin, PWM_OFF_DUTY); @@ -245,7 +216,7 @@ void handle_contactors() { break; case POSITIVE: - if (currentTime - negativeStartTime >= PRECHARGE_TIME_MS) { + if (currentTime - negativeStartTime >= precharge_time_ms) { set(posPin, ON, PWM_ON_DUTY); dbg_contactors("POSITIVE"); prechargeCompletedTime = currentTime; @@ -256,8 +227,8 @@ void handle_contactors() { case PRECHARGE_OFF: if (currentTime - prechargeCompletedTime >= PRECHARGE_COMPLETED_TIME_MS) { set(prechargePin, OFF); - set(negPin, ON, PWM_HOLD_DUTY); - set(posPin, ON, PWM_HOLD_DUTY); + set(negPin, ON, pwm_hold_duty); + set(posPin, ON, pwm_hold_duty); dbg_contactors("PRECHARGE_OFF"); contactorStatus = COMPLETED; datalayer.system.status.contactors_engaged = 1; diff --git a/Software/src/communication/contactorcontrol/comm_contactorcontrol.h b/Software/src/communication/contactorcontrol/comm_contactorcontrol.h index 45551610..9441c121 100644 --- a/Software/src/communication/contactorcontrol/comm_contactorcontrol.h +++ b/Software/src/communication/contactorcontrol/comm_contactorcontrol.h @@ -10,6 +10,9 @@ extern bool contactor_control_enabled_double_battery; extern bool pwm_contactor_control; extern bool periodic_bms_reset; extern bool remote_bms_reset; +extern uint16_t precharge_time_ms; +extern uint16_t pwm_frequency; +extern uint16_t pwm_hold_duty; /** * @brief Handle BMS power output diff --git a/Software/src/communication/nvm/comm_nvm.cpp b/Software/src/communication/nvm/comm_nvm.cpp index bd8a8802..83d2b6c1 100644 --- a/Software/src/communication/nvm/comm_nvm.cpp +++ b/Software/src/communication/nvm/comm_nvm.cpp @@ -138,8 +138,11 @@ void init_stored_settings() { equipment_stop_behavior = (STOP_BUTTON_BEHAVIOR)settings.getUInt("EQSTOP", (int)STOP_BUTTON_BEHAVIOR::NOT_CONNECTED); user_selected_second_battery = settings.getBool("DBLBTR", false); contactor_control_enabled = settings.getBool("CNTCTRL", false); + precharge_time_ms = settings.getUInt("PRECHGMS", 100); contactor_control_enabled_double_battery = settings.getBool("CNTCTRLDBL", false); pwm_contactor_control = settings.getBool("PWMCNTCTRL", false); + pwm_frequency = settings.getUInt("PWMFREQ", 20000); + pwm_hold_duty = settings.getUInt("PWMHOLD", 250); periodic_bms_reset = settings.getBool("PERBMSRESET", false); remote_bms_reset = settings.getBool("REMBMSRESET", false); use_canfd_as_can = settings.getBool("CANFDASCAN", false); diff --git a/Software/src/devboard/webserver/settings_html.cpp b/Software/src/devboard/webserver/settings_html.cpp index 62060cfb..cc4ffc14 100644 --- a/Software/src/devboard/webserver/settings_html.cpp +++ b/Software/src/devboard/webserver/settings_html.cpp @@ -557,6 +557,18 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti return String(settings.getUInt("CANFREQ", 8)); } + if (var == "PRECHGMS") { + return String(settings.getUInt("PRECHGMS", 100)); + } + + if (var == "PWMFREQ") { + return String(settings.getUInt("PWMFREQ", 20000)); + } + + if (var == "PWMHOLD") { + return String(settings.getUInt("PWMHOLD", 250)); + } + if (var == "DIGITALHVIL") { return settings.getBool("DIGITALHVIL") ? "checked" : ""; } @@ -781,6 +793,16 @@ const char* getCANInterfaceName(CAN_Interface interface) { display: contents; } + form .if-pwmcntctrl { display: none; } + form[data-pwmcntctrl="true"] .if-pwmcntctrl { + display: contents; + } + + form .if-cntctrl { display: none; } + form[data-cntctrl="true"] .if-cntctrl { + display: contents; + } + form .if-sofar { display: none; } form[data-inverter="17"] .if-sofar { display: contents; @@ -932,7 +954,7 @@ const char* getCANInterfaceName(CAN_Interface interface) { - +
- + + + +
- + -
- - -
+
+ + - - + + + +
+ + + + + +
+ +
diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index f0b5c633..6b6102e4 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -515,6 +515,15 @@ void init_webserver() { } else if (p->name() == "CANFREQ") { auto type = atoi(p->value().c_str()); settings.saveUInt("CANFREQ", type); + } else if (p->name() == "PRECHGMS") { + auto type = atoi(p->value().c_str()); + settings.saveUInt("PRECHGMS", type); + } else if (p->name() == "PWMFREQ") { + auto type = atoi(p->value().c_str()); + settings.saveUInt("PWMFREQ", type); + } else if (p->name() == "PWMHOLD") { + auto type = atoi(p->value().c_str()); + settings.saveUInt("PWMHOLD", type); } else if (p->name() == "GTWCOUNTRY") { auto type = atoi(p->value().c_str()); settings.saveUInt("GTWCOUNTRY", type);