diff --git a/Software/Software.ino b/Software/Software.ino index 33a81c3c..fe9fcefd 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -244,7 +244,7 @@ void core_loop(void*) { led_exe(); handle_contactors(); // Take care of startup precharge/contactor closing #ifdef PRECHARGE_CONTROL - handle_precharge_control(); + handle_precharge_control(currentMillis); #endif // PRECHARGE_CONTROL #ifdef FUNCTION_TIME_MEASUREMENT END_TIME_MEASUREMENT_MAX(time_10ms, datalayer.system.status.time_10ms_us); diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index a194dfab..bf870214 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -92,7 +92,8 @@ //#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging /* Automatic Precharge settings (Optional) If you have a battery that expects an external voltage applied before opening contactors (within the battery), configure this section */ -//#define PRECHARGE_CONTROL //Enable this line to control a modified HIA4V1 (see wiki) by PWM on the PRECHARGE_PIN. +//#define PRECHARGE_CONTROL //Enable this line to control a modified HIA4V1 via PWM on the HIA4V1_PIN (see Wiki and HAL for pin definition) +//#define INVERTER_DISCONNECT_CONTACTOR_IS_NORMALLY_OPEN //Enable this line if you use a normally open contactor instead of normally closed /* Other options */ //#define EQUIPMENT_STOP_BUTTON // Enable this to allow an equipment stop button connected to the Battery-Emulator to disengage the battery diff --git a/Software/src/communication/precharge_control/precharge_control.cpp b/Software/src/communication/precharge_control/precharge_control.cpp index 761b75c1..6b792e04 100644 --- a/Software/src/communication/precharge_control/precharge_control.cpp +++ b/Software/src/communication/precharge_control/precharge_control.cpp @@ -2,20 +2,22 @@ #include "../../datalayer/datalayer.h" #include "../../datalayer/datalayer_extended.h" #include "../../include.h" - -// Parameters - #ifdef PRECHARGE_CONTROL - +// Parameters #define MAX_PRECHARGE_TIME_MS 15000 // Maximum time precharge may be enabled - #define Precharge_default_PWM_Freq 11000 #define Precharge_min_PWM_Freq 5000 #define Precharge_max_PWM_Freq 34000 -#define PWM_Res 8 -#define PWM_OFF_DUTY 0 - +#define Precharge_PWM_Res 8 +#define PWM_Freq 20000 // 20 kHz frequency, beyond audible range #define PWM_Precharge_Channel 0 +#ifndef INVERTER_DISCONNECT_CONTACTOR_IS_NORMALLY_OPEN +#define ON 0 //Normally closed contactors use inverted logic +#define OFF 1 //Normally closed contactors use inverted logic +#else +#define ON 1 +#define OFF 0 +#endif unsigned long prechargeStartTime = 0; static uint32_t freq = Precharge_default_PWM_Freq; uint16_t delta_freq = 1; @@ -28,48 +30,33 @@ void init_precharge_control() { #ifdef DEBUG_LOG logging.printf("Precharge control initialised\n"); #endif - pinMode(PRECHARGE_PIN, OUTPUT); - digitalWrite(PRECHARGE_PIN, LOW); - pinMode(POSITIVE_CONTACTOR_PIN, OUTPUT); - digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); + pinMode(HIA4V1_PIN, OUTPUT); + digitalWrite(HIA4V1_PIN, LOW); + pinMode(INVERTER_DISCONNECT_CONTACTOR_PIN, OUTPUT); + digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, LOW); } // Main functions -void handle_precharge_control() { - unsigned long currentTime = millis(); -#ifdef MEB_BATTERY +void handle_precharge_control(unsigned long currentMillis) { int32_t target_voltage = datalayer.battery.status.voltage_dV; int32_t external_voltage = datalayer_extended.meb.BMS_voltage_intermediate_dV; -#endif - // Handle actual state machine. This first turns on Negative, then Precharge, then Positive, and finally turns OFF precharge switch (datalayer.system.status.precharge_status) { case AUTO_PRECHARGE_IDLE: - -#if 0 - if (datalayer.battery.status.bms_status != FAULT && datalayer.battery.status.real_bms_status == BMS_STANDBY && - /*datalayer.system.status.inverter_allows_contactor_closing &&*/ - !datalayer.system.settings.equipment_stop_active) { - datalayer.system.status.precharge_status = AUTO_PRECHARGE_START; - } -#else if (datalayer.system.settings.start_precharging) { datalayer.system.status.precharge_status = AUTO_PRECHARGE_START; } -#endif break; - case AUTO_PRECHARGE_START: freq = Precharge_default_PWM_Freq; - ledcAttachChannel(PRECHARGE_PIN, freq, PWM_Res, PWM_Precharge_Channel); - ledcWriteTone(PRECHARGE_PIN, freq); // Set frequency and set dutycycle to 50% - prechargeStartTime = currentTime; + ledcAttachChannel(HIA4V1_PIN, freq, Precharge_PWM_Res, PWM_Precharge_Channel); + ledcWriteTone(HIA4V1_PIN, freq); // Set frequency and set dutycycle to 50% + prechargeStartTime = currentMillis; datalayer.system.status.precharge_status = AUTO_PRECHARGE_PRECHARGING; #ifdef DEBUG_LOG logging.printf("Precharge: Starting sequence\n"); #endif - digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH); - + digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, OFF); break; case AUTO_PRECHARGE_PRECHARGING: @@ -97,24 +84,24 @@ void handle_precharge_control() { logging.printf("Precharge: Target: %d V Extern: %d V Frequency: %u\n", target_voltage / 10, external_voltage / 10, freq); #endif - ledcWriteTone(PRECHARGE_PIN, freq); + ledcWriteTone(HIA4V1_PIN, freq); } if ((datalayer.battery.status.real_bms_status != BMS_STANDBY && datalayer.battery.status.real_bms_status != BMS_ACTIVE) || datalayer.battery.status.bms_status != ACTIVE || datalayer.system.settings.equipment_stop_active) { - pinMode(PRECHARGE_PIN, OUTPUT); - digitalWrite(PRECHARGE_PIN, LOW); - digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); + pinMode(HIA4V1_PIN, OUTPUT); + digitalWrite(HIA4V1_PIN, LOW); + digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, ON); datalayer.system.status.precharge_status = AUTO_PRECHARGE_IDLE; #ifdef DEBUG_LOG logging.printf("Precharge: Disabling Precharge bms not standby/active or equipment stop\n"); #endif - } else if (currentTime - prechargeStartTime >= MAX_PRECHARGE_TIME_MS || + } else if (currentMillis - prechargeStartTime >= MAX_PRECHARGE_TIME_MS || datalayer.battery.status.real_bms_status == BMS_FAULT) { - pinMode(PRECHARGE_PIN, OUTPUT); - digitalWrite(PRECHARGE_PIN, LOW); - digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); + pinMode(HIA4V1_PIN, OUTPUT); + digitalWrite(HIA4V1_PIN, LOW); + digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, ON); datalayer.system.status.precharge_status = AUTO_PRECHARGE_OFF; #ifdef DEBUG_LOG logging.printf("Precharge: Disabled (timeout reached / BMS fault) -> AUTO_PRECHARGE_OFF\n"); @@ -123,9 +110,9 @@ void handle_precharge_control() { // Add event } else if (datalayer.system.status.battery_allows_contactor_closing) { - pinMode(PRECHARGE_PIN, OUTPUT); - digitalWrite(PRECHARGE_PIN, LOW); - digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); + pinMode(HIA4V1_PIN, OUTPUT); + digitalWrite(HIA4V1_PIN, LOW); + digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, ON); datalayer.system.status.precharge_status = AUTO_PRECHARGE_COMPLETED; #ifdef DEBUG_LOG logging.printf("Precharge: Disabled (contacts closed) -> COMPLETED\n"); @@ -147,8 +134,8 @@ void handle_precharge_control() { !datalayer.system.status.inverter_allows_contactor_closing || datalayer.system.settings.equipment_stop_active || datalayer.battery.status.bms_status != FAULT) { datalayer.system.status.precharge_status = AUTO_PRECHARGE_IDLE; - pinMode(PRECHARGE_PIN, OUTPUT); - digitalWrite(PRECHARGE_PIN, LOW); + pinMode(HIA4V1_PIN, OUTPUT); + digitalWrite(HIA4V1_PIN, LOW); #ifdef DEBUG_LOG logging.printf("Precharge: equipment stop activated -> IDLE\n"); #endif @@ -159,4 +146,4 @@ void handle_precharge_control() { break; } } -#endif // AUTO_PRECHARGE_CONTROL +#endif // PRECHARGE_CONTROL diff --git a/Software/src/communication/precharge_control/precharge_control.h b/Software/src/communication/precharge_control/precharge_control.h index c29e1992..74883503 100644 --- a/Software/src/communication/precharge_control/precharge_control.h +++ b/Software/src/communication/precharge_control/precharge_control.h @@ -17,19 +17,10 @@ void init_precharge_control(); /** * @brief Handle contactors * - * @param[in] void + * @param[in] unsigned long currentMillis * * @return void */ -void handle_precharge_control(); - -/** - * @brief Handle contactors of battery 2 - * - * @param[in] void - * - * @return void - */ -void handle_contactors_battery2(); +void handle_precharge_control(unsigned long currentMillis); #endif // _PRECHARGE_CONTROL_H_ diff --git a/Software/src/devboard/hal/hw_3LB.h b/Software/src/devboard/hal/hw_3LB.h index ded31420..e5d01c01 100644 --- a/Software/src/devboard/hal/hw_3LB.h +++ b/Software/src/devboard/hal/hw_3LB.h @@ -61,6 +61,10 @@ // SMA CAN contactor pins #define INVERTER_CONTACTOR_ENABLE_PIN 36 +// Automatic precharging +#define HIA4V1_PIN 25 +#define INVERTER_DISCONNECT_CONTACTOR_PIN 32 + // SD card //#define SD_MISO_PIN 2 //#define SD_MOSI_PIN 15 diff --git a/Software/src/devboard/hal/hw_devkit.h b/Software/src/devboard/hal/hw_devkit.h index c16621b5..a9dd49c6 100644 --- a/Software/src/devboard/hal/hw_devkit.h +++ b/Software/src/devboard/hal/hw_devkit.h @@ -62,6 +62,10 @@ The pin layout below supports the following: // Equipment stop pin #define EQUIPMENT_STOP_PIN GPIO_NUM_12 +// Automatic precharging +#define HIA4V1_PIN GPIO_NUM_17 +#define INVERTER_DISCONNECT_CONTACTOR_PIN GPIO_NUM_5 + // BMW_I3_BATTERY wake up pin #ifdef BMW_I3_BATTERY #define WUP_PIN1 GPIO_NUM_25 // Wake up pin for battery 1 diff --git a/Software/src/devboard/hal/hw_lilygo.h b/Software/src/devboard/hal/hw_lilygo.h index 887f925f..8dbf4f74 100644 --- a/Software/src/devboard/hal/hw_lilygo.h +++ b/Software/src/devboard/hal/hw_lilygo.h @@ -53,6 +53,10 @@ #define PRECHARGE_PIN 25 #define BMS_POWER 18 // Note, this pin collides with CAN add-ons and Chademo +// Automatic precharging +#define HIA4V1_PIN 25 +#define INVERTER_DISCONNECT_CONTACTOR_PIN 32 + // SMA CAN contactor pins #define INVERTER_CONTACTOR_ENABLE_PIN 5 diff --git a/Software/src/devboard/hal/hw_stark.h b/Software/src/devboard/hal/hw_stark.h index 152e189f..74f2ce2f 100644 --- a/Software/src/devboard/hal/hw_stark.h +++ b/Software/src/devboard/hal/hw_stark.h @@ -51,6 +51,10 @@ GPIOs on extra header #define PRECHARGE_PIN 25 #define BMS_POWER 23 +// Automatic precharging +#define HIA4V1_PIN 19 //Available as extra GPIO via pin header +#define INVERTER_DISCONNECT_CONTACTOR_PIN 25 + // SMA CAN contactor pins #define INVERTER_CONTACTOR_ENABLE_PIN 2