Arduino Freezes after a while of Serial.

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

//Message sample <2X245> Which means motor 2, speed 245.
boolean ParseSerial(int &MotorNum, int &Speed){
  char SerialData[6]; //Reference paramter to modify. Read Pointers
  char Temp[4]; // X is an integer.
  
   //Strings must be null terminated
  if (Serial.read() == '<') {//If first Char = <
    int StartTime = millis();    // Wait for Serial Buffer
    while (millis() - StartTime < 200 && Serial.available() < 5){};
    if (Serial.available() < 5) return false; // Timeout 
    for (int i = 0; i < 5; i++) {
      SerialData[i] = Serial.read();
      if (((int(SerialData[i]) - 48) > 9 || (int(SerialData[i]) - 48) < 0 )) return false;
    }

    MotorNum = int(SerialData[0]) - 48; //ASCII to Int
    
    strncpy(Temp, SerialData + 2, 3);
    Speed = atoi(Temp);
    Serial.flush();
    return true;   
  }
  return false;
}
    

void loop() { 
  int LEDPin;
  int TEMP;
  int Speed;
  LEDPin = 13;
  TEMP = 11;
  //Serial.println(millis());
  if (ParseSerial(TEMP, Speed)) {
    analogWrite(TEMP, Speed);
  }
}

//PORTB = (PORTB & B11100111) | (bit3_value << 3) | (bit4_value << 4);

There's my arduino code.

There's data incoming from the serial RX pin every 20ms, in the form of , where M is the pin number for a PWM output, and SSS is the duty cycle.

It works perfectly fine for around 3 minutes, then the waveform freezes, whatever I do. Tx also stops, if the led on the board is correct.
According to my oscilloscope, the serial data coming in from Rx is still changing fine, but Tx stops, and the waveform stops changing. I've tried pins 5,6 and 9.

Is there some sort of memory leak in the above stuff?

Oh, yes. It works fine if Serial.println(millis()); isn't commented out, and it will work for another 3 minutes if the arduino is restarted.

    Serial.flush();

Throw away random amounts of data. Now, does that really seem like a good idea?

You are sending, you said, "". But, you are reading the '<' and the next 5 characters. You assume that the 5 characters are valid. Bad assumption. You should read and store all the data after the '<', until the '>' arrives, and check that you have stored exactly 5 characters. Only then should you use the data.

    MotorNum = int(SerialData[0]) - 48; //ASCII to Int

This would be much more readable as:

    MotorNum = int(SerialData[0]) - '0'; //ASCII to Int

There's data incoming from the serial RX pin every 20ms

And yet your timeout is 200 milliseconds...

Search the forum for "started && ended" for an example I posted on how to read delimited serial data, as it becomes available. There is no need to have any timeout in the read function, because the function can simply read any unread data, doing something with the data only when a complete packet has arrived.

The timeout is 200 ms, which is why I have Serial.flush. And its the timeout. In particular, this line of code

while (millis() - StartTime < 200 && Serial.available() < 5){};

means that once Serial.available is above 5, it quits the while loop.

This data is sent in a continuous stream, so it is no big deal if a few packets are lost here and there - the next one is incoming, as I said, in 20 ms.

Basiclaly, I have a program which reads a joystick and sends serial data continuously. Would it matter that a few packets are lost?

And wouldn't the program waiting until ">" comes along wait a while if > doesn't come?

EDIT: Took your suggestion about the '>'. Changed code to

while (millis() - StartTime < 200 && Serial.available() < 6){};

and added

if (Serial.read() != '>') return false;

So if the sixth character isn't a '<', it'll return false.

Still have no idea why the arduino would freeze if it doesn't transmit Tx continuously, but it's fine if it does.

In your code, where does the 4th byte of Temp get set to zero? That is, Temp [3].

It starts off undefined, then you copy 3 bytes in with strncpy. Then you do atoi on it. So the results could be undefined, or wrong (no terminating 0x0 byte).

I'm inclined to agree with Paul. The Serial.flush isn't going to help, and you are doing Serial.read() without checking first if anything is there.

This data is sent in a continuous stream, so it is no big deal if a few packets are lost here and there - the next one is incoming, as I said, in 20 ms.

Well ... the data comes every 20 ms but you are waiting 200 ms? Plus, the UART chip buffers stuff (4 bytes from memory). So the available test isn't really guaranteed to be "recently received". I think I would rework it.