Merge pull request #29 from dalathegreat/contactor-improvements

Contactor improvements
This commit is contained in:
Daniel Öster 2023-07-26 15:26:19 +03:00 committed by GitHub
commit 43be1ff8ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 30 deletions

View file

@ -113,31 +113,35 @@ void send_can_byd()
send_intial_data(); send_intial_data();
initialDataSent = 1; initialDataSent = 1;
} }
// Send 2s CAN Message
if (currentMillis - previousMillis2s >= interval2s)
{
previousMillis2s = currentMillis;
ESP32Can.CANWriteFrame(&BYD_110); if(bms_status != FAULT)
} { // Send CAN messages towards inverter if battery is OK
// Send 10s CAN Message // Send 2s CAN Message
if (currentMillis - previousMillis10s >= interval10s) if (currentMillis - previousMillis2s >= interval2s)
{ {
previousMillis10s = currentMillis; previousMillis2s = currentMillis;
ESP32Can.CANWriteFrame(&BYD_150); ESP32Can.CANWriteFrame(&BYD_110);
ESP32Can.CANWriteFrame(&BYD_1D0); }
ESP32Can.CANWriteFrame(&BYD_210); // Send 10s CAN Message
//Serial.println("CAN 10s done"); if (currentMillis - previousMillis10s >= interval10s)
} {
//Send 60s message previousMillis10s = currentMillis;
if (currentMillis - previousMillis60s >= interval60s)
{
previousMillis60s = currentMillis;
ESP32Can.CANWriteFrame(&BYD_190); ESP32Can.CANWriteFrame(&BYD_150);
//Serial.println("CAN 60s done"); ESP32Can.CANWriteFrame(&BYD_1D0);
} ESP32Can.CANWriteFrame(&BYD_210);
//Serial.println("CAN 10s done");
}
//Send 60s message
if (currentMillis - previousMillis60s >= interval60s)
{
previousMillis60s = currentMillis;
ESP32Can.CANWriteFrame(&BYD_190);
//Serial.println("CAN 60s done");
}
}
} }
void send_intial_data() void send_intial_data()

View file

@ -327,6 +327,14 @@ void receive_can_leaf_battery(CAN_frame_t rx_frame)
LB_Relay_Cut_Request = ((rx_frame.data.u8[1] & 0x18) >> 3); LB_Relay_Cut_Request = ((rx_frame.data.u8[1] & 0x18) >> 3);
LB_Failsafe_Status = (rx_frame.data.u8[1] & 0x07); LB_Failsafe_Status = (rx_frame.data.u8[1] & 0x07);
LB_MainRelayOn_flag = (byte) ((rx_frame.data.u8[3] & 0x20) >> 5); LB_MainRelayOn_flag = (byte) ((rx_frame.data.u8[3] & 0x20) >> 5);
if(LB_MainRelayOn_flag)
{
batteryAllowsContactorClosing = 1;
}
else
{
batteryAllowsContactorClosing = 0;
}
LB_Full_CHARGE_flag = (byte) ((rx_frame.data.u8[3] & 0x10) >> 4); LB_Full_CHARGE_flag = (byte) ((rx_frame.data.u8[3] & 0x10) >> 4);
LB_Interlock = (byte) ((rx_frame.data.u8[3] & 0x08) >> 3); LB_Interlock = (byte) ((rx_frame.data.u8[3] & 0x08) >> 3);
break; break;

View file

@ -26,6 +26,7 @@ extern uint16_t stat_batt_power;
extern uint16_t temperature_min; extern uint16_t temperature_min;
extern uint16_t temperature_max; extern uint16_t temperature_max;
extern uint16_t CANerror; extern uint16_t CANerror;
extern uint8_t batteryAllowsContactorClosing;
// Definitions for BMS status // Definitions for BMS status
#define STANDBY 0 #define STANDBY 0
#define INACTIVE 1 #define INACTIVE 1

View file

@ -82,16 +82,22 @@ const int maxBrightness = 255;
//Contactor parameters //Contactor parameters
enum State { enum State {
WAITING_FOR_BATTERY,
PRECHARGE, PRECHARGE,
NEGATIVE, NEGATIVE,
POSITIVE, POSITIVE,
PRECHARGE_OFF, PRECHARGE_OFF,
COMPLETED, COMPLETED,
SHUTDOWN SHUTDOWN_REQUESTED
}; };
State contactorStatus = PRECHARGE; State contactorStatus = WAITING_FOR_BATTERY;
#define PRECHARGE_TIME_MS 160
#define NEGATIVE_CONTACTOR_TIME_MS 1000
#define POSITIVE_CONTACTOR_TIME_MS 2000
unsigned long prechargeStartTime = 0; unsigned long prechargeStartTime = 0;
unsigned long negativeStartTime = 0; unsigned long negativeStartTime = 0;
unsigned long timeSpentInFaultedMode = 0;
uint8_t batteryAllowsContactorClosing = 0;
// Setup() - initialization happens here // Setup() - initialization happens here
void setup() void setup()
@ -272,7 +278,16 @@ void handle_inverter()
void handle_contactors() void handle_contactors()
{ {
if(contactorStatus == SHUTDOWN) //First check if we have any active errors, incase we do, turn off the battery after 15 seconds
if(bms_status == FAULT)
{
timeSpentInFaultedMode++;
}
if(timeSpentInFaultedMode > 1500)
{
contactorStatus = SHUTDOWN_REQUESTED;
}
if(contactorStatus == SHUTDOWN_REQUESTED)
{ {
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW); digitalWrite(NEGATIVE_CONTACTOR_PIN, LOW);
@ -280,13 +295,22 @@ void handle_contactors()
return; return;
} }
if(contactorStatus == COMPLETED) //After that, check if we are OK to start turning on the battery
if(contactorStatus == WAITING_FOR_BATTERY)
{ {
if(batteryAllowsContactorClosing)
{
contactorStatus = PRECHARGE;
}
}
if(contactorStatus == COMPLETED)
{ //Skip running the state machine below if it has already completed
return; return;
} }
unsigned long currentTime = millis(); unsigned long currentTime = millis();
//Handle actual state machine. This first turns on Precharge, then Negative, then Positive, and finally turns OFF precharge
switch (contactorStatus) { switch (contactorStatus) {
case PRECHARGE: case PRECHARGE:
digitalWrite(PRECHARGE_PIN, HIGH); digitalWrite(PRECHARGE_PIN, HIGH);
@ -295,7 +319,7 @@ void handle_contactors()
break; break;
case NEGATIVE: case NEGATIVE:
if (currentTime - prechargeStartTime >= 60) { if (currentTime - prechargeStartTime >= PRECHARGE_TIME_MS) {
digitalWrite(NEGATIVE_CONTACTOR_PIN, HIGH); digitalWrite(NEGATIVE_CONTACTOR_PIN, HIGH);
negativeStartTime = currentTime; negativeStartTime = currentTime;
contactorStatus = POSITIVE; contactorStatus = POSITIVE;
@ -303,14 +327,14 @@ void handle_contactors()
break; break;
case POSITIVE: case POSITIVE:
if (currentTime - negativeStartTime >= 100) { if (currentTime - negativeStartTime >= NEGATIVE_CONTACTOR_TIME_MS) {
digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH); digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH);
contactorStatus = PRECHARGE_OFF; contactorStatus = PRECHARGE_OFF;
} }
break; break;
case PRECHARGE_OFF: case PRECHARGE_OFF:
if (currentTime - negativeStartTime >= 300) { if (currentTime - negativeStartTime >= POSITIVE_CONTACTOR_TIME_MS) {
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
contactorStatus = COMPLETED; contactorStatus = COMPLETED;
} }