diff --git a/Software/Software.ino b/Software/Software.ino index c038af2f..a7439f8b 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -349,6 +349,12 @@ void inform_user_on_battery() { // Inform user what battery is used #ifdef BMW_I3_BATTERY Serial.println("BMW i3 battery selected"); + pinMode(WUP_PIN, OUTPUT); //This pin used for WUP relay + digitalWrite(WUP_PIN, LOW); +#ifdef CONTACTOR_CONTROL +// Contactor control cannot be used when WUP signal is sent on GPIO pins +#error CONTACTOR CONTROL CANNOT BE USED ON BMW i3 +#endif #endif #ifdef CHADEMO_BATTERY Serial.println("Chademo battery selected"); diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 4ba402a6..e024dfd5 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -8,7 +8,7 @@ /* To edit battery specific limits, see also the USER_SETTINGS.cpp file*/ /* Select battery used */ -//#define BMW_I3_BATTERY +#define BMW_I3_BATTERY //#define CHADEMO_BATTERY //#define IMIEV_CZERO_ION_BATTERY //#define KIA_HYUNDAI_64_BATTERY diff --git a/Software/src/battery/BMW-I3-BATTERY.cpp b/Software/src/battery/BMW-I3-BATTERY.cpp index 730c2c57..af54c2cd 100644 --- a/Software/src/battery/BMW-I3-BATTERY.cpp +++ b/Software/src/battery/BMW-I3-BATTERY.cpp @@ -33,10 +33,16 @@ static const int interval5000 = 5000; // interval (ms) at which send CA static const int interval10000 = 10000; // interval (ms) at which send CAN Messages static uint8_t CANstillAlive = 12; //counter for checking if CAN is still alive +static const uint16_t WUPonDuration = 477; // in milliseconds how long WUP should be ON after poweron +static const uint16_t WUPoffDuration = 105; // in milliseconds how long WUP should be OFF after on pulse +unsigned long lastChangeTime; // Variables to store timestamps +unsigned long turnOnTime; // Variables to store timestamps +enum State { POWERON, STATE_ON, STATE_OFF, STATE_STAY_ON }; +static State WUPState = POWERON; + #define LB_MAX_SOC 1000 //BMS never goes over this value. We use this info to rescale SOC% sent to Inverter #define LB_MIN_SOC 0 //BMS never goes below this value. We use this info to rescale SOC% sent to Inverter - CAN_frame_t BMW_000 = {.FIR = {.B = { .DLC = 4, @@ -755,11 +761,32 @@ void receive_can_i3_battery(CAN_frame_t rx_frame) { } void send_can_i3_battery() { unsigned long currentMillis = millis(); + + //Handle WUP signal + if (WUPState == POWERON) { + digitalWrite(WUP_PIN, HIGH); + turnOnTime = currentMillis; + WUPState = STATE_ON; + } + + // Check if it's time to change state + if (WUPState == STATE_ON && currentMillis - turnOnTime >= WUPonDuration) { + WUPState = STATE_OFF; + digitalWrite(WUP_PIN, LOW); // Turn off + lastChangeTime = currentMillis; + } else if (WUPState == STATE_OFF && currentMillis - lastChangeTime >= WUPoffDuration) { + WUPState = STATE_STAY_ON; + digitalWrite(WUP_PIN, HIGH); // Turn on and stay on + lastChangeTime = currentMillis; + } else if (WUPState == STATE_STAY_ON) { + // Do nothing, stay in this state forever + } + //Send 10ms message - if (currentMillis - previousMillis10 >= interval10) { + if (currentMillis - previousMillis10 >= interval10) { previousMillis10 = currentMillis; - if(!sent_100){ + if (!sent_100) { BMW_000_counter++; if (BMW_000_counter > 6) { ESP32Can.CANWriteFrame(&BMW_000); diff --git a/Software/src/devboard/config.h b/Software/src/devboard/config.h index 04f12822..c7e5c79c 100644 --- a/Software/src/devboard/config.h +++ b/Software/src/devboard/config.h @@ -26,6 +26,10 @@ #define PRECHARGE_PIN 25 #endif +#ifdef BMW_I3_BATTERY +#define WUP_PIN 25 +#endif + #define SD_MISO_PIN 2 #define SD_MOSI_PIN 15 #define SD_SCLK_PIN 14