diff --git a/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp b/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp index b189eedb..9d286324 100644 --- a/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp +++ b/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp @@ -49,27 +49,62 @@ void updateData() { */ void manageSerialLinkReceiver() { + static bool lasterror = false; + static unsigned long lastGood; + static uint16_t lastGoodMaxCharge; + static uint16_t lastGoodMaxDischarge; + static bool initLink = false; + + unsigned long currentTime = millis(); + + if (!initLink) { + initLink = true; + // sends variables every 5000mS even if no change + dataLinkReceive.setUpdateInterval(5000); +#ifdef SERIALDATALINK_MUTEACK + dataLinkReceive.muteACK(true); +#endif + } dataLinkReceive.run(); bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag LEDcolor = GREEN; if (readError) { LEDcolor = RED; - Serial.println("ERROR: Serial Data Link - Read Error"); + bms_status = 4; //FAULT + Serial.print(currentTime); + Serial.println(" - ERROR: Serial Data Link - Read Error"); + lasterror = true; + } else { + if (lasterror) { + lasterror = false; + Serial.print(currentTime); + Serial.println(" - RECOVERY: Serial Data Link - Read GOOD"); + } + lastGood = currentTime; } if (dataLinkReceive.checkNewData(true)) // true = clear Flag { __getData(); + lastGoodMaxCharge = max_target_charge_power; + lastGoodMaxDischarge = max_target_discharge_power; } -#ifdef INVERTER_SEND_NUM_VARIABLES - static bool initLink = false; - static unsigned long updateTime = 0; - if (!initLink) { - initLink = true; - // sends variables every 5000mS even if no change - dataLinkReceive.setUpdateInterval(5000); + unsigned long minutesLost = (currentTime - lastGood) / 60000UL; + ; + if (minutesLost > 0 && lastGood > 0) { + // lose 25% each minute of data loss + if (minutesLost < 4) { + max_target_charge_power = (lastGoodMaxCharge * (4 - minutesLost)) / 4; + max_target_discharge_power = (lastGoodMaxDischarge * (4 - minutesLost)) / 4; + } else { + max_target_charge_power = 0; + max_target_discharge_power = 0; + } } - unsigned long currentTime = millis(); + + static unsigned long updateTime = 0; + +#ifdef INVERTER_SEND_NUM_VARIABLES if (currentTime - updateTime > 100) { updateTime = currentTime; dataLinkReceive.run(); diff --git a/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp b/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp index e0f62c62..229d0bd5 100644 --- a/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp +++ b/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp @@ -31,6 +31,7 @@ void _getData() { void manageSerialLinkTransmitter() { static bool initLink = false; static unsigned long updateTime = 0; + static bool lasterror = false; dataLinkTransmit.run(); @@ -53,9 +54,16 @@ void manageSerialLinkTransmitter() { LEDcolor = GREEN; if (sendError) { LEDcolor = RED; - Serial.println("ERROR: Serial Data Link - SEND Error"); + Serial.print(millis()); + Serial.println(" - ERROR: Serial Data Link - SEND Error"); + lasterror = true; + } else { + if (lasterror) { + lasterror = false; + Serial.print(millis()); + Serial.println(" - RECOVERY: Serial Data Link - Send GOOD"); + } } - // todo some error management - LEDS etc dataLinkTransmit.updateData(0, SOC); dataLinkTransmit.updateData(1, StateOfHealth); diff --git a/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.cpp b/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.cpp index 522b8811..31a6902c 100644 --- a/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.cpp +++ b/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.cpp @@ -124,8 +124,31 @@ bool SerialDataLink::checkNewData(bool resetFlag) { return currentStatus; } +void SerialDataLink::muteACK(bool mute) +{ + muteAcknowledgement = mute; +} + void SerialDataLink::run() { + unsigned long currentTime = millis(); + static DataLinkState oldstate; + + + // Check if state has not changed for a prolonged period + if (oldstate != currentState) + { + lastStateChangeTime = currentTime; + oldstate = currentState; + } + if ((currentTime - lastStateChangeTime) > stateChangeTimeout) { + // Reset the state to Idle and perform necessary cleanup + currentState = DataLinkState::Idle; + // Perform any additional cleanup or reinitialization here + // ... + + lastStateChangeTime = currentTime; // Reset the last state change time + } switch (currentState) { case DataLinkState::Idle: @@ -146,7 +169,12 @@ void SerialDataLink::run() { constructPacket(); // Construct a new packet if not currently transmitting - + + if (muteAcknowledgement) + { + needToACK = false; + needToNACK = false; + } uint8_t ack; // now it is known which acknoledge need sending since last Reception if (needToACK) @@ -215,6 +243,15 @@ void SerialDataLink::run() } } +void SerialDataLink::updateState(DataLinkState newState) +{ + if (currentState != newState) + { + currentState = newState; + lastStateChangeTime = millis(); + } +} + bool SerialDataLink::shouldTransmit() { // Priority condition: Device with transmitID = 1 and receiveID = 0 has the highest priority diff --git a/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.h b/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.h index 163d9441..258939c4 100644 --- a/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.h +++ b/Software/src/lib/mackelec-SerialDataLink/SerialDataLink.h @@ -76,6 +76,7 @@ class SerialDataLink { void setHeaderChar(char header); void setEOTChar(char eot); + void muteACK(bool mute); private: enum class DataLinkState @@ -115,6 +116,7 @@ class SerialDataLink { bool retransmitEnabled; bool transmissionError = false; bool readError = false; + bool muteAcknowledgement = false; // Data arrays and update management @@ -130,6 +132,9 @@ class SerialDataLink { unsigned long ACK_TIMEOUT = 100; unsigned long PACKET_TIMEOUT = 100; // Timeout in milliseconds + unsigned long lastStateChangeTime = 0; + unsigned long stateChangeTimeout = 200; + // Special characters for packet framing char headerChar = '<'; char eotChar = '>'; @@ -147,7 +152,8 @@ class SerialDataLink { void addToTxBuffer(uint8_t byte); bool sendNextByte(); bool ackReceived(); - bool ackTimeout(); + bool ackTimeout(); + void updateState(DataLinkState newState); // Internal methods for reception void read();