Update precharge to handle separate pin definitions

This commit is contained in:
Daniel Öster 2025-05-13 18:52:48 +03:00
parent 2f18bfec74
commit 2d35e08848
8 changed files with 54 additions and 59 deletions

View file

@ -244,7 +244,7 @@ void core_loop(void*) {
led_exe(); led_exe();
handle_contactors(); // Take care of startup precharge/contactor closing handle_contactors(); // Take care of startup precharge/contactor closing
#ifdef PRECHARGE_CONTROL #ifdef PRECHARGE_CONTROL
handle_precharge_control(); handle_precharge_control(currentMillis);
#endif // PRECHARGE_CONTROL #endif // PRECHARGE_CONTROL
#ifdef FUNCTION_TIME_MEASUREMENT #ifdef FUNCTION_TIME_MEASUREMENT
END_TIME_MEASUREMENT_MAX(time_10ms, datalayer.system.status.time_10ms_us); END_TIME_MEASUREMENT_MAX(time_10ms, datalayer.system.status.time_10ms_us);

View file

@ -92,7 +92,8 @@
//#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging //#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 */ /* 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 */ /* Other options */
//#define EQUIPMENT_STOP_BUTTON // Enable this to allow an 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

View file

@ -2,20 +2,22 @@
#include "../../datalayer/datalayer.h" #include "../../datalayer/datalayer.h"
#include "../../datalayer/datalayer_extended.h" #include "../../datalayer/datalayer_extended.h"
#include "../../include.h" #include "../../include.h"
// Parameters
#ifdef PRECHARGE_CONTROL #ifdef PRECHARGE_CONTROL
// Parameters
#define MAX_PRECHARGE_TIME_MS 15000 // Maximum time precharge may be enabled #define MAX_PRECHARGE_TIME_MS 15000 // Maximum time precharge may be enabled
#define Precharge_default_PWM_Freq 11000 #define Precharge_default_PWM_Freq 11000
#define Precharge_min_PWM_Freq 5000 #define Precharge_min_PWM_Freq 5000
#define Precharge_max_PWM_Freq 34000 #define Precharge_max_PWM_Freq 34000
#define PWM_Res 8 #define Precharge_PWM_Res 8
#define PWM_OFF_DUTY 0 #define PWM_Freq 20000 // 20 kHz frequency, beyond audible range
#define PWM_Precharge_Channel 0 #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; unsigned long prechargeStartTime = 0;
static uint32_t freq = Precharge_default_PWM_Freq; static uint32_t freq = Precharge_default_PWM_Freq;
uint16_t delta_freq = 1; uint16_t delta_freq = 1;
@ -28,48 +30,33 @@ void init_precharge_control() {
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
logging.printf("Precharge control initialised\n"); logging.printf("Precharge control initialised\n");
#endif #endif
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(HIA4V1_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(HIA4V1_PIN, LOW);
pinMode(POSITIVE_CONTACTOR_PIN, OUTPUT); pinMode(INVERTER_DISCONNECT_CONTACTOR_PIN, OUTPUT);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, LOW);
} }
// Main functions // Main functions
void handle_precharge_control() { void handle_precharge_control(unsigned long currentMillis) {
unsigned long currentTime = millis();
#ifdef MEB_BATTERY
int32_t target_voltage = datalayer.battery.status.voltage_dV; int32_t target_voltage = datalayer.battery.status.voltage_dV;
int32_t external_voltage = datalayer_extended.meb.BMS_voltage_intermediate_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) { switch (datalayer.system.status.precharge_status) {
case AUTO_PRECHARGE_IDLE: 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) { if (datalayer.system.settings.start_precharging) {
datalayer.system.status.precharge_status = AUTO_PRECHARGE_START; datalayer.system.status.precharge_status = AUTO_PRECHARGE_START;
} }
#endif
break; break;
case AUTO_PRECHARGE_START: case AUTO_PRECHARGE_START:
freq = Precharge_default_PWM_Freq; freq = Precharge_default_PWM_Freq;
ledcAttachChannel(PRECHARGE_PIN, freq, PWM_Res, PWM_Precharge_Channel); ledcAttachChannel(HIA4V1_PIN, freq, Precharge_PWM_Res, PWM_Precharge_Channel);
ledcWriteTone(PRECHARGE_PIN, freq); // Set frequency and set dutycycle to 50% ledcWriteTone(HIA4V1_PIN, freq); // Set frequency and set dutycycle to 50%
prechargeStartTime = currentTime; prechargeStartTime = currentMillis;
datalayer.system.status.precharge_status = AUTO_PRECHARGE_PRECHARGING; datalayer.system.status.precharge_status = AUTO_PRECHARGE_PRECHARGING;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
logging.printf("Precharge: Starting sequence\n"); logging.printf("Precharge: Starting sequence\n");
#endif #endif
digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH); digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, OFF);
break; break;
case AUTO_PRECHARGE_PRECHARGING: 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, logging.printf("Precharge: Target: %d V Extern: %d V Frequency: %u\n", target_voltage / 10,
external_voltage / 10, freq); external_voltage / 10, freq);
#endif #endif
ledcWriteTone(PRECHARGE_PIN, freq); ledcWriteTone(HIA4V1_PIN, freq);
} }
if ((datalayer.battery.status.real_bms_status != BMS_STANDBY && if ((datalayer.battery.status.real_bms_status != BMS_STANDBY &&
datalayer.battery.status.real_bms_status != BMS_ACTIVE) || datalayer.battery.status.real_bms_status != BMS_ACTIVE) ||
datalayer.battery.status.bms_status != ACTIVE || datalayer.system.settings.equipment_stop_active) { datalayer.battery.status.bms_status != ACTIVE || datalayer.system.settings.equipment_stop_active) {
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(HIA4V1_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(HIA4V1_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, ON);
datalayer.system.status.precharge_status = AUTO_PRECHARGE_IDLE; datalayer.system.status.precharge_status = AUTO_PRECHARGE_IDLE;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
logging.printf("Precharge: Disabling Precharge bms not standby/active or equipment stop\n"); logging.printf("Precharge: Disabling Precharge bms not standby/active or equipment stop\n");
#endif #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) { datalayer.battery.status.real_bms_status == BMS_FAULT) {
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(HIA4V1_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(HIA4V1_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, ON);
datalayer.system.status.precharge_status = AUTO_PRECHARGE_OFF; datalayer.system.status.precharge_status = AUTO_PRECHARGE_OFF;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
logging.printf("Precharge: Disabled (timeout reached / BMS fault) -> AUTO_PRECHARGE_OFF\n"); logging.printf("Precharge: Disabled (timeout reached / BMS fault) -> AUTO_PRECHARGE_OFF\n");
@ -123,9 +110,9 @@ void handle_precharge_control() {
// Add event // Add event
} else if (datalayer.system.status.battery_allows_contactor_closing) { } else if (datalayer.system.status.battery_allows_contactor_closing) {
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(HIA4V1_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(HIA4V1_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(INVERTER_DISCONNECT_CONTACTOR_PIN, ON);
datalayer.system.status.precharge_status = AUTO_PRECHARGE_COMPLETED; datalayer.system.status.precharge_status = AUTO_PRECHARGE_COMPLETED;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
logging.printf("Precharge: Disabled (contacts closed) -> COMPLETED\n"); 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.status.inverter_allows_contactor_closing ||
datalayer.system.settings.equipment_stop_active || datalayer.battery.status.bms_status != FAULT) { datalayer.system.settings.equipment_stop_active || datalayer.battery.status.bms_status != FAULT) {
datalayer.system.status.precharge_status = AUTO_PRECHARGE_IDLE; datalayer.system.status.precharge_status = AUTO_PRECHARGE_IDLE;
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(HIA4V1_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(HIA4V1_PIN, LOW);
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
logging.printf("Precharge: equipment stop activated -> IDLE\n"); logging.printf("Precharge: equipment stop activated -> IDLE\n");
#endif #endif
@ -159,4 +146,4 @@ void handle_precharge_control() {
break; break;
} }
} }
#endif // AUTO_PRECHARGE_CONTROL #endif // PRECHARGE_CONTROL

View file

@ -17,19 +17,10 @@ void init_precharge_control();
/** /**
* @brief Handle contactors * @brief Handle contactors
* *
* @param[in] void * @param[in] unsigned long currentMillis
* *
* @return void * @return void
*/ */
void handle_precharge_control(); void handle_precharge_control(unsigned long currentMillis);
/**
* @brief Handle contactors of battery 2
*
* @param[in] void
*
* @return void
*/
void handle_contactors_battery2();
#endif // _PRECHARGE_CONTROL_H_ #endif // _PRECHARGE_CONTROL_H_

View file

@ -61,6 +61,10 @@
// SMA CAN contactor pins // SMA CAN contactor pins
#define INVERTER_CONTACTOR_ENABLE_PIN 36 #define INVERTER_CONTACTOR_ENABLE_PIN 36
// Automatic precharging
#define HIA4V1_PIN 25
#define INVERTER_DISCONNECT_CONTACTOR_PIN 32
// SD card // SD card
//#define SD_MISO_PIN 2 //#define SD_MISO_PIN 2
//#define SD_MOSI_PIN 15 //#define SD_MOSI_PIN 15

View file

@ -62,6 +62,10 @@ The pin layout below supports the following:
// Equipment stop pin // Equipment stop pin
#define EQUIPMENT_STOP_PIN GPIO_NUM_12 #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 // BMW_I3_BATTERY wake up pin
#ifdef BMW_I3_BATTERY #ifdef BMW_I3_BATTERY
#define WUP_PIN1 GPIO_NUM_25 // Wake up pin for battery 1 #define WUP_PIN1 GPIO_NUM_25 // Wake up pin for battery 1

View file

@ -53,6 +53,10 @@
#define PRECHARGE_PIN 25 #define PRECHARGE_PIN 25
#define BMS_POWER 18 // Note, this pin collides with CAN add-ons and Chademo #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 // SMA CAN contactor pins
#define INVERTER_CONTACTOR_ENABLE_PIN 5 #define INVERTER_CONTACTOR_ENABLE_PIN 5

View file

@ -51,6 +51,10 @@ GPIOs on extra header
#define PRECHARGE_PIN 25 #define PRECHARGE_PIN 25
#define BMS_POWER 23 #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 // SMA CAN contactor pins
#define INVERTER_CONTACTOR_ENABLE_PIN 2 #define INVERTER_CONTACTOR_ENABLE_PIN 2