Skip to content

Commit

Permalink
Merge pull request #481 from obbardc/wip/obbardc/fix-pwm-contactor-co…
Browse files Browse the repository at this point in the history
…ntrol

Fix: PWM_CONTACTOR_CONTROL now actually engages contactors
  • Loading branch information
dalathegreat authored Sep 24, 2024
2 parents c53ebf1 + ca98c12 commit d759946
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 17 deletions.
45 changes: 30 additions & 15 deletions Software/Software.ino
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
#endif // MQTT
#endif // WIFI

#ifndef CONTACTOR_CONTROL
#ifdef PWM_CONTACTOR_CONTROL
#error CONTACTOR_CONTROL needs to be enabled for PWM_CONTACTOR_CONTROL
#endif
#endif

Preferences settings; // Store user settings
// The current software version, shown on webserver
const char* version_number = "7.4.dev";
Expand Down Expand Up @@ -119,6 +125,8 @@ State contactorStatus = DISCONNECTED;
#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
#define PWM_On_Duty 1023
#define POSITIVE_PWM_Ch 0
#define NEGATIVE_PWM_Ch 1
#endif
Expand Down Expand Up @@ -448,17 +456,18 @@ void init_CAN() {
void init_contactors() {
// Init contactor pins
#ifdef CONTACTOR_CONTROL
#ifndef PWM_CONTACTOR_CONTROL
pinMode(POSITIVE_CONTACTOR_PIN, OUTPUT);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
pinMode(NEGATIVE_CONTACTOR_PIN, OUTPUT);
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
#ifdef PWM_CONTACTOR_CONTROL
#else
ledcAttachChannel(POSITIVE_CONTACTOR_PIN, PWM_Freq, PWM_Res,
POSITIVE_PWM_Ch); // Setup PWM Channel Frequency and Resolution
ledcAttachChannel(NEGATIVE_CONTACTOR_PIN, PWM_Freq, PWM_Res,
NEGATIVE_PWM_Ch); // Setup PWM Channel Frequency and Resolution
ledcWrite(POSITIVE_PWM_Ch, 0); // Set Positive PWM to 0%
ledcWrite(NEGATIVE_PWM_Ch, 0); // Set Negative PWM to 0%
NEGATIVE_PWM_Ch); // Setup PWM Channel Frequency and Resolution
ledcWrite(POSITIVE_CONTACTOR_PIN, PWM_Off_Duty); // Set Positive PWM to 0%
ledcWrite(NEGATIVE_CONTACTOR_PIN, PWM_Off_Duty); // Set Negative PWM to 0%
#endif
pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW);
Expand Down Expand Up @@ -633,13 +642,11 @@ void check_interconnect_available() {
#endif //DOUBLE_BATTERY

void handle_contactors() {

#ifdef BYD_SMA
datalayer.system.status.inverter_allows_contactor_closing = digitalRead(INVERTER_CONTACTOR_ENABLE_PIN);
#endif

#ifdef CONTACTOR_CONTROL

// First check if we have any active errors, incase we do, turn off the battery
if (datalayer.battery.status.bms_status == FAULT) {
timeSpentInFaultedMode++;
Expand All @@ -652,8 +659,13 @@ void handle_contactors() {
}
if (contactorStatus == SHUTDOWN_REQUESTED) {
digitalWrite(PRECHARGE_PIN, LOW);
#ifndef PWM_CONTACTOR_CONTROL
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
#else
ledcWrite(NEGATIVE_CONTACTOR_PIN, PWM_Off_Duty);
ledcWrite(POSITIVE_CONTACTOR_PIN, PWM_Off_Duty);
#endif
set_event(EVENT_ERROR_OPEN_CONTACTOR, 0);
datalayer.system.status.contactor_control_closed = false;
return; // A fault scenario latches the contactor control. It is not possible to recover without a powercycle (and investigation why fault occured)
Expand All @@ -662,11 +674,12 @@ void handle_contactors() {
// After that, check if we are OK to start turning on the battery
if (contactorStatus == DISCONNECTED) {
digitalWrite(PRECHARGE_PIN, LOW);
#ifndef PWM_CONTACTOR_CONTROL
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
#ifdef PWM_CONTACTOR_CONTROL
ledcWrite(POSITIVE_PWM_Ch, 0);
ledcWrite(NEGATIVE_PWM_Ch, 0);
#else
ledcWrite(NEGATIVE_CONTACTOR_PIN, PWM_Off_Duty);
ledcWrite(POSITIVE_CONTACTOR_PIN, PWM_Off_Duty);
#endif

if (datalayer.system.status.battery_allows_contactor_closing &&
Expand Down Expand Up @@ -694,9 +707,10 @@ void handle_contactors() {

case NEGATIVE:
if (currentTime - prechargeStartTime >= PRECHARGE_TIME_MS) {
#ifndef PWM_CONTACTOR_CONTROL
digitalWrite(NEGATIVE_CONTACTOR_PIN, HIGH);
#ifdef PWM_CONTACTOR_CONTROL
ledcWrite(NEGATIVE_PWM_Ch, 1023);
#else
ledcWrite(NEGATIVE_CONTACTOR_PIN, PWM_On_Duty);
#endif
negativeStartTime = currentTime;
contactorStatus = POSITIVE;
Expand All @@ -705,9 +719,10 @@ void handle_contactors() {

case POSITIVE:
if (currentTime - negativeStartTime >= NEGATIVE_CONTACTOR_TIME_MS) {
#ifndef PWM_CONTACTOR_CONTROL
digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH);
#ifdef PWM_CONTACTOR_CONTROL
ledcWrite(POSITIVE_PWM_Ch, 1023);
#else
ledcWrite(POSITIVE_CONTACTOR_PIN, PWM_On_Duty);
#endif
contactorStatus = PRECHARGE_OFF;
}
Expand All @@ -717,8 +732,8 @@ void handle_contactors() {
if (currentTime - negativeStartTime >= POSITIVE_CONTACTOR_TIME_MS) {
digitalWrite(PRECHARGE_PIN, LOW);
#ifdef PWM_CONTACTOR_CONTROL
ledcWrite(NEGATIVE_PWM_Ch, PWM_Hold_Duty);
ledcWrite(POSITIVE_PWM_Ch, PWM_Hold_Duty);
ledcWrite(NEGATIVE_CONTACTOR_PIN, PWM_Hold_Duty);
ledcWrite(POSITIVE_CONTACTOR_PIN, PWM_Hold_Duty);
#endif
contactorStatus = COMPLETED;
datalayer.system.status.contactor_control_closed = true;
Expand Down
2 changes: 1 addition & 1 deletion Software/USER_SETTINGS.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
//#define DEBUG_CANFD_DATA //Enable this line to have the USB port output CAN-FD data while program runs (WARNING, raises CPU load, do not use for production)
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
//#define CONTACTOR_CONTROL //Enable this line to have pins 25,32,33 handle automatic precharge/contactor+/contactor- closing sequence
//#define PWM_CONTACTOR_CONTROL //Enable this line to use PWM logic for contactors, which lower power consumption and heat generation
//#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 DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)
//#define CAN_FD //Enable this line to activate an isolated secondary CAN-FD bus using add-on MCP2518FD chip / Native CANFD on Stark board
//#define USE_CANFD_INTERFACE_AS_CLASSIC_CAN // Enable this line if you intend to use the CANFD as normal CAN
Expand Down
2 changes: 2 additions & 0 deletions Software/src/battery/JAGUAR-IPACE-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ void setup_battery(void) { // Performs one time setup at startup
datalayer.battery.info.number_of_cells = 108;
datalayer.battery.info.max_design_voltage_dV = 4546;
datalayer.battery.info.min_design_voltage_dV = 3370;

datalayer.system.status.battery_allows_contactor_closing = true;
}

#endif
4 changes: 3 additions & 1 deletion Software/src/battery/TEST-FAKE-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void send_can_battery() {
if (currentMillis - previousMillis100 >= INTERVAL_100_MS) {
previousMillis100 = currentMillis;
// Put fake messages here incase you want to test sending CAN
transmit_can(&TEST, can_config.battery);
//transmit_can(&TEST, can_config.battery);
}
}

Expand All @@ -104,6 +104,8 @@ void setup_battery(void) { // Performs one time setup at startup
datalayer.battery.info.max_design_voltage_dV =
4040; // 404.4V, over this, charging is not possible (goes into forced discharge)
datalayer.battery.info.min_design_voltage_dV = 2450; // 245.0V under this, discharging further is disabled

datalayer.system.status.battery_allows_contactor_closing = true;
}

#endif

0 comments on commit d759946

Please sign in to comment.