diff --git a/Software/src/battery/BATTERIES.cpp b/Software/src/battery/BATTERIES.cpp index 247e61e5..3f24b074 100644 --- a/Software/src/battery/BATTERIES.cpp +++ b/Software/src/battery/BATTERIES.cpp @@ -317,6 +317,14 @@ void setup_battery() { } #endif +/* User-selected Tesla settings */ +bool user_selected_tesla_digital_HVIL = false; +uint16_t user_selected_tesla_GTW_country = 17477; +bool user_selected_tesla_GTW_rightHandDrive = true; +uint16_t user_selected_tesla_GTW_mapRegion = 2; +uint16_t user_selected_tesla_GTW_chassisType = 2; +uint16_t user_selected_tesla_GTW_packEnergy = 1; + /* User-selected voltages used for custom-BMS batteries (RJXZS etc.) */ #if defined(MAX_CUSTOM_PACK_VOLTAGE_DV) && defined(MIN_CUSTOM_PACK_VOLTAGE_DV) && \ defined(MAX_CUSTOM_CELL_VOLTAGE_MV) && defined(MIN_CUSTOM_CELL_VOLTAGE_MV) diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index 5c5539a6..f26dcf6e 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -61,4 +61,11 @@ extern uint16_t user_selected_min_pack_voltage_dV; extern uint16_t user_selected_max_cell_voltage_mV; extern uint16_t user_selected_min_cell_voltage_mV; +extern bool user_selected_tesla_digital_HVIL; +extern uint16_t user_selected_tesla_GTW_country; +extern bool user_selected_tesla_GTW_rightHandDrive; +extern uint16_t user_selected_tesla_GTW_mapRegion; +extern uint16_t user_selected_tesla_GTW_chassisType; +extern uint16_t user_selected_tesla_GTW_packEnergy; + #endif diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index f5a3db24..8407eed9 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -676,39 +676,39 @@ void TeslaBattery:: clear_event(EVENT_BATTERY_FUSE); } -#ifdef TESLA_MODEL_3Y_BATTERY - // Autodetect algoritm for chemistry on 3/Y packs. - // NCM/A batteries have 96s, LFP has 102-108s - // Drawback with this check is that it takes 3-5minutes before all cells have been counted! - if (datalayer.battery.info.number_of_cells > 101) { - datalayer.battery.info.chemistry = battery_chemistry_enum::LFP; - } + if (user_selected_tesla_GTW_chassisType > 1) { //{{0, "Model S"}, {1, "Model X"}, {2, "Model 3"}, {3, "Model Y"}}; + // Autodetect algoritm for chemistry on 3/Y packs. + // NCM/A batteries have 96s, LFP has 102-108s + // Drawback with this check is that it takes 3-5minutes before all cells have been counted! + if (datalayer.battery.info.number_of_cells > 101) { + datalayer.battery.info.chemistry = battery_chemistry_enum::LFP; + } - //Once cell chemistry is determined, set maximum and minimum total pack voltage safety limits - 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; - } + //Once cell chemistry is determined, set maximum and minimum total pack voltage safety limits + 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; + } - // During forced balancing request via webserver, we allow the battery to exceed normal safety parameters - if (datalayer.battery.settings.user_requests_balancing) { - datalayer.battery.status.real_soc = 9900; //Force battery to show up as 99% when balancing - datalayer.battery.info.max_design_voltage_dV = datalayer.battery.settings.balancing_max_pack_voltage_dV; - datalayer.battery.info.max_cell_voltage_mV = datalayer.battery.settings.balancing_max_cell_voltage_mV; - datalayer.battery.info.max_cell_voltage_deviation_mV = - datalayer.battery.settings.balancing_max_deviation_cell_voltage_mV; - datalayer.battery.status.max_charge_power_W = datalayer.battery.settings.balancing_float_power_W; + // During forced balancing request via webserver, we allow the battery to exceed normal safety parameters + if (datalayer.battery.settings.user_requests_balancing) { + datalayer.battery.status.real_soc = 9900; //Force battery to show up as 99% when balancing + datalayer.battery.info.max_design_voltage_dV = datalayer.battery.settings.balancing_max_pack_voltage_dV; + datalayer.battery.info.max_cell_voltage_mV = datalayer.battery.settings.balancing_max_cell_voltage_mV; + datalayer.battery.info.max_cell_voltage_deviation_mV = + datalayer.battery.settings.balancing_max_deviation_cell_voltage_mV; + datalayer.battery.status.max_charge_power_W = datalayer.battery.settings.balancing_float_power_W; + } } -#endif // TESLA_MODEL_3Y_BATTERY // Check if user requests some action if (datalayer.battery.settings.user_requests_tesla_isolation_clear) { @@ -1992,7 +1992,7 @@ int index_118 = 0; void TeslaBattery::transmit_can(unsigned long currentMillis) { - if (operate_contactors) { //Special S/X mode + if (user_selected_tesla_digital_HVIL) { //Special S/X? mode for 2024+ batteries if ((datalayer.system.status.inverter_allows_contactor_closing) && (datalayer.battery.status.bms_status != FAULT)) { if (currentMillis - lastSend1CF >= 10) { transmit_can_frame(&can_msg_1CF[index_1CF]); @@ -2599,12 +2599,12 @@ void TeslaModel3YBattery::setup(void) { // Performs one time setup at startup //0x7FF GTW CAN frame values //Mux1 - write_signal_value(&TESLA_7FF_Mux1, 16, 16, GTW_country, false); - write_signal_value(&TESLA_7FF_Mux1, 11, 1, GTW_rightHandDrive, false); + write_signal_value(&TESLA_7FF_Mux1, 16, 16, user_selected_tesla_GTW_country, false); + write_signal_value(&TESLA_7FF_Mux1, 11, 1, user_selected_tesla_GTW_country, false); //Mux3 - write_signal_value(&TESLA_7FF_Mux3, 8, 4, GTW_mapRegion, false); - write_signal_value(&TESLA_7FF_Mux3, 18, 3, GTW_chassisType, false); - write_signal_value(&TESLA_7FF_Mux3, 32, 5, GTW_packEnergy, false); + write_signal_value(&TESLA_7FF_Mux3, 8, 4, user_selected_tesla_GTW_mapRegion, false); + write_signal_value(&TESLA_7FF_Mux3, 18, 3, user_selected_tesla_GTW_chassisType, false); + write_signal_value(&TESLA_7FF_Mux3, 32, 5, user_selected_tesla_GTW_packEnergy, false); strncpy(datalayer.system.info.battery_protocol, Name, 63); datalayer.system.info.battery_protocol[63] = '\0'; diff --git a/Software/src/battery/TESLA-BATTERY.h b/Software/src/battery/TESLA-BATTERY.h index d2116bfb..fca5a83b 100644 --- a/Software/src/battery/TESLA-BATTERY.h +++ b/Software/src/battery/TESLA-BATTERY.h @@ -11,12 +11,14 @@ #define SELECTED_BATTERY_CLASS TeslaModelSXBattery #endif -/*NOTE! IMPORTANT INFORMATION! -Be sure to scroll down in this file and configure all "GTW_" parameters to suit your battery. -Failure to configure these will result in VCFRONT and GTW MIA errors -*/ - -//#define EXP_TESLA_BMS_DIGITAL_HVIL // Experimental parameter. Forces the transmission of additional CAN frames for experimental purposes, to test potential HVIL issues in 3/Y packs with newer firmware. +// 0x7FF gateway config, "Gen3" vehicles only, not applicable to Gen2 "classic" Model S and Model X +// These are user configurable from the Webserver UI +extern bool user_selected_tesla_digital_HVIL; +extern uint16_t user_selected_tesla_GTW_country; +extern bool user_selected_tesla_GTW_rightHandDrive; +extern uint16_t user_selected_tesla_GTW_mapRegion; +extern uint16_t user_selected_tesla_GTW_chassisType; +extern uint16_t user_selected_tesla_GTW_packEnergy; class TeslaBattery : public CanBattery { public: @@ -53,21 +55,6 @@ class TeslaBattery : public CanBattery { // Set this to true to try to close contactors/full startup even with no inverter defined/connected bool batteryTestOverride = false; - // 0x7FF gateway config, "Gen3" vehicles only, not applicable to Gen2 "classic" Model S and Model X - // - // ** MANUALLY SET FOR NOW **, TODO: change based on USER_SETTINGS.h or preset - // - static const uint16_t GTW_country = - 18242; // "US" (USA): 21843, "CA" (Canada): 17217, "GB" (UK & N Ireland): 18242, "DK" (Denmark): 17483, "DE" (Germany): 17477, "AU" (Australia): 16725 [HVP shows errors if EU/US region mismatch for example] - // GTW_country is ISO 3166-1 Alpha-2 code, each letter converted to binary (8-bit chunks), those 8-bit chunks concatenated and then converted to decimal - static const uint8_t GTW_rightHandDrive = - 1; // Left: 0, Right: 1 (not sure this matters but there for consistency in emulating the car - make sure correct for GTW_country, e.g. 0 for USA) - static const uint8_t GTW_mapRegion = - 1; // "ME": 8, "NONE": 2, "CN": 3, "TW": 6, "JP": 5, "US": 0, "KR": 7, "AU": 4, "EU": 1 (not sure this matters but there for consistency) - static const uint8_t GTW_chassisType = - 2; // "MODEL_3_CHASSIS": 2, "MODEL_Y_CHASSIS": 3 ("MODEL_S_CHASSIS": 0, "MODEL_X_CHASSIS": 1) - static const uint8_t GTW_packEnergy = 1; // "PACK_50_KWH": 0, "PACK_74_KWH": 1, "PACK_62_KWH": 2, "PACK_100_KWH": 3 - /* Do not change anything below this line! */ static const int RAMPDOWN_SOC = 900; // 90.0 SOC% to start ramping down from max charge power towards 0 at 100.00% static const int RAMPDOWNPOWERALLOWED = 10000; // What power we ramp down from towards top balancing @@ -926,19 +913,14 @@ class TeslaBattery : public CanBattery { class TeslaModel3YBattery : public TeslaBattery { public: - TeslaModel3YBattery(battery_chemistry_enum chemistry) { - datalayer.battery.info.chemistry = chemistry; -#ifdef EXP_TESLA_BMS_DIGITAL_HVIL - operate_contactors = true; -#endif - } + TeslaModel3YBattery(battery_chemistry_enum chemistry) { datalayer.battery.info.chemistry = chemistry; } static constexpr const char* Name = "Tesla Model 3/Y"; virtual void setup(void); }; class TeslaModelSXBattery : public TeslaBattery { public: - TeslaModelSXBattery() { operate_contactors = true; } + TeslaModelSXBattery() {} static constexpr const char* Name = "Tesla Model S/X"; virtual void setup(void); }; diff --git a/Software/src/communication/nvm/comm_nvm.cpp b/Software/src/communication/nvm/comm_nvm.cpp index 0d6e97b8..9761e82d 100644 --- a/Software/src/communication/nvm/comm_nvm.cpp +++ b/Software/src/communication/nvm/comm_nvm.cpp @@ -103,6 +103,12 @@ void init_stored_settings() { user_selected_inverter_ah_capacity = settings.getUInt("INVAHCAPACITY", 0); user_selected_inverter_battery_type = settings.getUInt("INVBTYPE", 0); user_selected_inverter_ignore_contactors = settings.getBool("INVICNT", false); + user_selected_tesla_digital_HVIL = settings.getBool("DIGITALHVIL", false); + user_selected_tesla_GTW_country = settings.getUInt("GTWCOUNTRY", 0); + user_selected_tesla_GTW_rightHandDrive = settings.getBool("GTWRHD", false); + user_selected_tesla_GTW_mapRegion = settings.getUInt("GTWMAPREG", 0); + user_selected_tesla_GTW_chassisType = settings.getUInt("GTWCHASSIS", 0); + user_selected_tesla_GTW_packEnergy = settings.getUInt("GTWPACK", 0); auto readIf = [](const char* settingName) { auto batt1If = (comm_interface)settings.getUInt(settingName, (int)comm_interface::CanNative); diff --git a/Software/src/devboard/webserver/settings_html.cpp b/Software/src/devboard/webserver/settings_html.cpp index 023a8309..16541f17 100644 --- a/Software/src/devboard/webserver/settings_html.cpp +++ b/Software/src/devboard/webserver/settings_html.cpp @@ -78,6 +78,33 @@ String options_for_enum(TEnum selected, Func name_for_type) { return options; } +template +String options_from_map(int selected, const TMap& value_name_map) { + String options; + for (const auto& [value, name] : value_name_map) { + options += "