Move more settings to common-image

This commit is contained in:
Daniel Öster 2025-09-01 13:25:59 +03:00
parent 6253cd678b
commit 9031d3e5cf
7 changed files with 76 additions and 68 deletions

View file

@ -14,15 +14,6 @@
//#define HW_3LB //#define HW_3LB
//#define HW_DEVKIT //#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) */ /* Shunt/Contactor settings (Optional) */
//#define BMW_SBOX // SBOX relay control & battery current/voltage measurement //#define BMW_SBOX // SBOX relay control & battery current/voltage measurement

View file

@ -9,9 +9,6 @@
#ifdef CHADEMO_BATTERY #ifdef CHADEMO_BATTERY
#define SELECTED_BATTERY_CLASS ChademoBattery #define SELECTED_BATTERY_CLASS ChademoBattery
//Contactor control is required for CHADEMO support
#define CONTACTOR_CONTROL
#endif #endif
class ChademoBattery : public CanBattery { class ChademoBattery : public CanBattery {

View file

@ -3,45 +3,16 @@
#include "../../devboard/safety/safety.h" #include "../../devboard/safety/safety.h"
#include "../../inverter/INVERTERS.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 // 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 // Parameters
enum State { DISCONNECTED, START_PRECHARGE, PRECHARGE, POSITIVE, PRECHARGE_OFF, COMPLETED, SHUTDOWN_REQUESTED }; enum State { DISCONNECTED, START_PRECHARGE, PRECHARGE, POSITIVE, PRECHARGE_OFF, COMPLETED, SHUTDOWN_REQUESTED };
State contactorStatus = DISCONNECTED; 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!) 500 // Time after negative contactor is turned on, to start precharge (not actual precharge time!)
#define PRECHARGE_COMPLETED_TIME_MS \ #define PRECHARGE_COMPLETED_TIME_MS \
1000 // After successful precharge, resistor is turned off after this delay (and contactors are economized if PWM enabled) 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 uint16_t pwm_frequency = 20000;
#define PWM_Res 10 // 10 Bit resolution 0 to 1023, maps 'nicely' to 0% 100% uint16_t pwm_hold_duty = 250;
#define PWM_HOLD_DUTY 250
#define PWM_OFF_DUTY 0
#define PWM_ON_DUTY 1023 #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_Positive_Channel 0
#define PWM_Negative_Channel 1 #define PWM_Negative_Channel 1
static unsigned long prechargeStartTime = 0; static unsigned long prechargeStartTime = 0;
@ -108,8 +79,8 @@ bool init_contactors() {
if (pwm_contactor_control) { if (pwm_contactor_control) {
// Setup PWM Channel Frequency and Resolution // Setup PWM Channel Frequency and Resolution
ledcAttachChannel(posPin, PWM_Freq, PWM_Res, PWM_Positive_Channel); ledcAttachChannel(posPin, pwm_frequency, PWM_RESOLUTION, PWM_Positive_Channel);
ledcAttachChannel(negPin, PWM_Freq, PWM_Res, PWM_Negative_Channel); ledcAttachChannel(negPin, pwm_frequency, PWM_RESOLUTION, PWM_Negative_Channel);
// Set all pins OFF (0% PWM) // Set all pins OFF (0% PWM)
ledcWrite(posPin, PWM_OFF_DUTY); ledcWrite(posPin, PWM_OFF_DUTY);
ledcWrite(negPin, PWM_OFF_DUTY); ledcWrite(negPin, PWM_OFF_DUTY);
@ -245,7 +216,7 @@ void handle_contactors() {
break; break;
case POSITIVE: case POSITIVE:
if (currentTime - negativeStartTime >= PRECHARGE_TIME_MS) { if (currentTime - negativeStartTime >= precharge_time_ms) {
set(posPin, ON, PWM_ON_DUTY); set(posPin, ON, PWM_ON_DUTY);
dbg_contactors("POSITIVE"); dbg_contactors("POSITIVE");
prechargeCompletedTime = currentTime; prechargeCompletedTime = currentTime;
@ -256,8 +227,8 @@ void handle_contactors() {
case PRECHARGE_OFF: case PRECHARGE_OFF:
if (currentTime - prechargeCompletedTime >= PRECHARGE_COMPLETED_TIME_MS) { if (currentTime - prechargeCompletedTime >= PRECHARGE_COMPLETED_TIME_MS) {
set(prechargePin, OFF); set(prechargePin, OFF);
set(negPin, ON, PWM_HOLD_DUTY); set(negPin, ON, pwm_hold_duty);
set(posPin, ON, PWM_HOLD_DUTY); set(posPin, ON, pwm_hold_duty);
dbg_contactors("PRECHARGE_OFF"); dbg_contactors("PRECHARGE_OFF");
contactorStatus = COMPLETED; contactorStatus = COMPLETED;
datalayer.system.status.contactors_engaged = 1; datalayer.system.status.contactors_engaged = 1;

View file

@ -10,6 +10,9 @@ extern bool contactor_control_enabled_double_battery;
extern bool pwm_contactor_control; extern bool pwm_contactor_control;
extern bool periodic_bms_reset; extern bool periodic_bms_reset;
extern bool remote_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 * @brief Handle BMS power output

View file

@ -138,8 +138,11 @@ void init_stored_settings() {
equipment_stop_behavior = (STOP_BUTTON_BEHAVIOR)settings.getUInt("EQSTOP", (int)STOP_BUTTON_BEHAVIOR::NOT_CONNECTED); equipment_stop_behavior = (STOP_BUTTON_BEHAVIOR)settings.getUInt("EQSTOP", (int)STOP_BUTTON_BEHAVIOR::NOT_CONNECTED);
user_selected_second_battery = settings.getBool("DBLBTR", false); user_selected_second_battery = settings.getBool("DBLBTR", false);
contactor_control_enabled = settings.getBool("CNTCTRL", false); contactor_control_enabled = settings.getBool("CNTCTRL", false);
precharge_time_ms = settings.getUInt("PRECHGMS", 100);
contactor_control_enabled_double_battery = settings.getBool("CNTCTRLDBL", false); contactor_control_enabled_double_battery = settings.getBool("CNTCTRLDBL", false);
pwm_contactor_control = settings.getBool("PWMCNTCTRL", 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); periodic_bms_reset = settings.getBool("PERBMSRESET", false);
remote_bms_reset = settings.getBool("REMBMSRESET", false); remote_bms_reset = settings.getBool("REMBMSRESET", false);
use_canfd_as_can = settings.getBool("CANFDASCAN", false); use_canfd_as_can = settings.getBool("CANFDASCAN", false);

View file

@ -557,6 +557,18 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti
return String(settings.getUInt("CANFREQ", 8)); 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") { if (var == "DIGITALHVIL") {
return settings.getBool("DIGITALHVIL") ? "checked" : ""; return settings.getBool("DIGITALHVIL") ? "checked" : "";
} }
@ -781,6 +793,16 @@ const char* getCANInterfaceName(CAN_Interface interface) {
display: contents; 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 .if-sofar { display: none; }
form[data-inverter="17"] .if-sofar { form[data-inverter="17"] .if-sofar {
display: contents; display: contents;
@ -932,7 +954,7 @@ const char* getCANInterfaceName(CAN_Interface interface) {
</select> </select>
</div> </div>
<label>Can Addon Frequency: </label> <label>Can-addon frequency Mhz: </label>
<input name='CANFREQ' type='text' value="%CANFREQ%" pattern="^[0-9]+$" /> <input name='CANFREQ' type='text' value="%CANFREQ%" pattern="^[0-9]+$" />
<label>Equipment stop button: </label><select name='EQSTOP'> <label>Equipment stop button: </label><select name='EQSTOP'>
@ -943,21 +965,33 @@ const char* getCANInterfaceName(CAN_Interface interface) {
<input type='checkbox' name='DBLBTR' value='on' style='margin-left: 0;' %DBLBTR% /> <input type='checkbox' name='DBLBTR' value='on' style='margin-left: 0;' %DBLBTR% />
<div class="if-dblbtr"> <div class="if-dblbtr">
<label>Battery 2 comm I/F: </label><select name='BATT2COMM'> <label>Battery 2 comm I/F: </label>
%BATT2COMM% <select name='BATT2COMM'>
</select> %BATT2COMM%
</select>
<label>Contactor control via GPIO double battery: </label>
<input type='checkbox' name='CNTCTRLDBL' value='on' style='margin-left: 0;' %CNTCTRLDBL% />
</div> </div>
<label>Contactor control: </label> <label>Contactor control via GPIO: </label>
<input type='checkbox' name='CNTCTRL' value='on' style='margin-left: 0;' %CNTCTRL% /> <input type='checkbox' name='CNTCTRL' value='on' style='margin-left: 0;' %CNTCTRL% />
<div class="if-dblbtr"> <div class="if-cntctrl">
<label>Contactor control double battery: </label> <label>Precharge time ms: </label>
<input type='checkbox' name='CNTCTRLDBL' value='on' style='margin-left: 0;' %CNTCTRLDBL% /> <input name='PRECHGMS' type='text' value="%PRECHGMS%" pattern="^[0-9]+$" />
</div>
<label>PWM contactor control: </label> <label>PWM contactor control: </label>
<input type='checkbox' name='PWMCNTCTRL' value='on' style='margin-left: 0;' %PWMCNTCTRL% /> <input type='checkbox' name='PWMCNTCTRL' value='on' style='margin-left: 0;' %PWMCNTCTRL% />
<div class="if-pwmcntctrl">
<label>PWM Frequency Hz: </label>
<input name='PWMFREQ' type='text' value="%PWMFREQ%" pattern="^[0-9]+$" />
<label>PWM Hold 0-1023: </label>
<input name='PWMHOLD' type='text' value="%PWMHOLD%" pattern="^[0-9]+$" />
</div>
</div>
<label>Periodic BMS reset: </label> <label>Periodic BMS reset: </label>
<input type='checkbox' name='PERBMSRESET' value='on' style='margin-left: 0;' %PERBMSRESET% /> <input type='checkbox' name='PERBMSRESET' value='on' style='margin-left: 0;' %PERBMSRESET% />

View file

@ -515,6 +515,15 @@ void init_webserver() {
} else if (p->name() == "CANFREQ") { } else if (p->name() == "CANFREQ") {
auto type = atoi(p->value().c_str()); auto type = atoi(p->value().c_str());
settings.saveUInt("CANFREQ", type); 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") { } else if (p->name() == "GTWCOUNTRY") {
auto type = atoi(p->value().c_str()); auto type = atoi(p->value().c_str());
settings.saveUInt("GTWCOUNTRY", type); settings.saveUInt("GTWCOUNTRY", type);