diff --git a/Software/BYD-CAN.cpp b/Software/BYD-CAN.cpp index a6569087..aeb099d8 100644 --- a/Software/BYD-CAN.cpp +++ b/Software/BYD-CAN.cpp @@ -113,31 +113,35 @@ void send_can_byd() send_intial_data(); initialDataSent = 1; } - // Send 2s CAN Message - if (currentMillis - previousMillis2s >= interval2s) - { - previousMillis2s = currentMillis; - ESP32Can.CANWriteFrame(&BYD_110); - } - // Send 10s CAN Message - if (currentMillis - previousMillis10s >= interval10s) - { - previousMillis10s = currentMillis; + if(bms_status != FAULT) + { // Send CAN messages towards inverter if battery is OK + // Send 2s CAN Message + if (currentMillis - previousMillis2s >= interval2s) + { + previousMillis2s = currentMillis; - ESP32Can.CANWriteFrame(&BYD_150); - 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_110); + } + // Send 10s CAN Message + if (currentMillis - previousMillis10s >= interval10s) + { + previousMillis10s = currentMillis; - ESP32Can.CANWriteFrame(&BYD_190); - //Serial.println("CAN 60s done"); - } + ESP32Can.CANWriteFrame(&BYD_150); + 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() diff --git a/Software/NISSAN-LEAF-BATTERY.cpp b/Software/NISSAN-LEAF-BATTERY.cpp index 32dcb3b5..547312b3 100644 --- a/Software/NISSAN-LEAF-BATTERY.cpp +++ b/Software/NISSAN-LEAF-BATTERY.cpp @@ -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_Failsafe_Status = (rx_frame.data.u8[1] & 0x07); 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_Interlock = (byte) ((rx_frame.data.u8[3] & 0x08) >> 3); break; diff --git a/Software/NISSAN-LEAF-BATTERY.h b/Software/NISSAN-LEAF-BATTERY.h index eac5d81e..bd552286 100644 --- a/Software/NISSAN-LEAF-BATTERY.h +++ b/Software/NISSAN-LEAF-BATTERY.h @@ -26,6 +26,7 @@ extern uint16_t stat_batt_power; extern uint16_t temperature_min; extern uint16_t temperature_max; extern uint16_t CANerror; +extern uint8_t batteryAllowsContactorClosing; // Definitions for BMS status #define STANDBY 0 #define INACTIVE 1 diff --git a/Software/Software.ino b/Software/Software.ino index 3a063f4e..136f1b26 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -82,16 +82,22 @@ const int maxBrightness = 255; //Contactor parameters enum State { + WAITING_FOR_BATTERY, PRECHARGE, NEGATIVE, POSITIVE, PRECHARGE_OFF, 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 negativeStartTime = 0; +unsigned long timeSpentInFaultedMode = 0; +uint8_t batteryAllowsContactorClosing = 0; // Setup() - initialization happens here void setup() @@ -272,7 +278,16 @@ void handle_inverter() 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(NEGATIVE_CONTACTOR_PIN, LOW); @@ -280,13 +295,22 @@ void handle_contactors() 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; } unsigned long currentTime = millis(); - + //Handle actual state machine. This first turns on Precharge, then Negative, then Positive, and finally turns OFF precharge switch (contactorStatus) { case PRECHARGE: digitalWrite(PRECHARGE_PIN, HIGH); @@ -295,7 +319,7 @@ void handle_contactors() break; case NEGATIVE: - if (currentTime - prechargeStartTime >= 60) { + if (currentTime - prechargeStartTime >= PRECHARGE_TIME_MS) { digitalWrite(NEGATIVE_CONTACTOR_PIN, HIGH); negativeStartTime = currentTime; contactorStatus = POSITIVE; @@ -303,14 +327,14 @@ void handle_contactors() break; case POSITIVE: - if (currentTime - negativeStartTime >= 100) { + if (currentTime - negativeStartTime >= NEGATIVE_CONTACTOR_TIME_MS) { digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH); contactorStatus = PRECHARGE_OFF; } break; case PRECHARGE_OFF: - if (currentTime - negativeStartTime >= 300) { + if (currentTime - negativeStartTime >= POSITIVE_CONTACTOR_TIME_MS) { digitalWrite(PRECHARGE_PIN, LOW); contactorStatus = COMPLETED; }