Lag/Dropped bytes from serial input TO arduino?

Hello all, looking for a little advice here, as I'm not sure what's going on. I have my Arduino accepting serial inputs in order to flash an led. A little project of mine will actually be outputting rather fast flashes, as a small game implementation.

The problem is, and this is just from my tests, is that when I output to the Arduino, some of my inputs are being dropped? Or ignored? I'm not sure how to explain it.

So atm, I have a CMD window that just sets the MODE settings, then goes to a loop that sends 5 different characters to the Arduino, 1 at a time. And I came down to 1 at a time instead of all 5 at once as a test, because I noticed this issue immediately:

Then, on the Arduino side, it takes input from the serial, stores the character, checks what character it is, turns on the led for a few miliseconds, as a blink, checks to see if X time has passed, and shuts it off.

Sometimes though, the Arduino either barely, a very tiny flash, turns on the led, doesn't turn it on at all, or "freezes / lags".

Below is my code, and hopefully someone can point to me what I'm doing wrong.

And before anyone says anything, system("Echo" etc was the ONLY way I was able to put out from CMD to the Arduino, without first starting Arduino's built in Serial Monitor. If there's a more elegant solution, PLEASE tell me what it is, as it took me almost three damn days of trying different things, and nothing but system(Echo) working for me!

CMD Serial Loop

#include <windows.h>
#include <stdio.h>

int main(){
	system("MODE COM4: Baud=9600 Parity=N Data=8 Stop=1");
	loop:
	system("echo 2 > COM4");
	Sleep(200);
	system("echo 3 > COM4");
	Sleep(200);
	system("echo 4 > COM4");
	Sleep(200);
	system("echo 5 > COM4");
	Sleep(200);
	system("echo 6 > COM4");
	Sleep(200);
	goto loop;
	
}

Arduino Side

const int startTime = 0;    //just to make sure the time is started at 0. Shouldn't be needed though?
const int ledInterval = 50; //how long we want our led to be on exactly. 50 miliseconds, or (0050).
unsigned long currentTime;       //tracks the current time.
unsigned long setTime2;          //sets the current time in storage, for checking later.
unsigned long setTime3;
unsigned long setTime4;
unsigned long setTime5;
unsigned long setTime6;
char serialState;            //byte storage for serial intake.

void setup(){
  pinMode(2, OUTPUT);       //sets up pin2 for useage
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  Serial.begin(9600);       //turns on serial set baud rate default 9600
  while(!Serial);
}

void loop(){

    currentTime = millis();             //ensures that that time is being tracked.
 
    if(Serial.available()){
          serialState = Serial.read();  //takes the byte from serial usb and stores it into
    
    switch(serialState){                //checks serialState to see if it contains "XYZ"case.
          case '2':                     //if serialState contained 2, do the following.
          digitalWrite(2, HIGH);        //2 turns on pin2
          setTime2 = millis();          //Then sets the setTime1 as the current internal millis timer
         // Serial.print("2 Received.\n");  //prints BACK to the serial that it was received. Can be commented out, merely for debugging.
          break;                          //Ends the current switch case.

          case '3':
          digitalWrite(3, HIGH);
          setTime3 = millis();
         // Serial.print("3 received.\n");
          break;
          
          case '4':
          digitalWrite(4, HIGH);
          setTime4 = millis();
         // Serial.print("4 received.\n");
          break;

          case '5':
          digitalWrite(5, HIGH);
          setTime5 = millis();
         // Serial.print("5 received.\n");
          break;

          case '6':
          digitalWrite(6, HIGH);
          setTime6 = millis();
         // Serial.print("6 received.\n");
          break;
          }
      }
  
    if(currentTime - setTime2 >= ledInterval){ //Checks if the current time, minur the time that we set in XYZ switch case, is equal to or larger than ledInterval (50 milieconds!).
          digitalWrite(2, LOW);                  //And if the result IS larger than or equal to 50 miliseconds, it turns off pin2.
          }
    if(currentTime - setTime3 >= ledInterval){
          digitalWrite(3, LOW);
          }
    if(currentTime - setTime4 >= ledInterval){
          digitalWrite(4, LOW);
          }
    if(currentTime - setTime5 >= ledInterval){
          digitalWrite(5, LOW);
          }
    if(currentTime - setTime6 >= ledInterval){
          digitalWrite(6, LOW);
          }
}

I don't know enough to understand your PC program. There could be (probably will be) a problem if each call to system("echo 2 > COM4"); opens the serial port, sends the data and then closes the serial port. When the PC program opens the serial port it will cause an Uno or Mega to reset and the reset process takes time.

Your PC program should open the serial port, allow time for the reset to happen before sending the first message and then keep it open until it is completely finished with the Arduino.

If this was my project I would use a short Python program to send the data to the Arduino. This Python - Arduino demo may be of interest. But you can do the same thing using any PC programming language.

You are also using a strange baud rate. It is not listed in the table in the Atmega 328 datasheet so I have no idea how accurately the Arduino works at that rate. There is no error when using 250,000 baud or 500,000 baud.

...R

On the baud rate, it happens all the same with 9600, I was just trying different baud rates and somehow ended up that high. Likely through just random testing.

On the Opening and closing the serial port, well, as I said, that was literally the only way I could get to work without opening the Arduino SM first. Though I would be fully willing to accept it could be the issue, if someone with higher knowledge wants to tell to tell me so.

Edit: Fixed the baud rate to be normal, it still does the same thing anyways.

BlackLightComet:
On the Opening and closing the serial port, well, as I said, that was literally the only way I could get to work without opening the Arduino SM first. Though I would be fully willing to accept it could be the issue, if someone with higher knowledge wants to tell to tell me so.

I did not say that your program is opening and closing the serial port - I don't know. You need to figure out if it is. I just explained how there would be a problem if it is happening.

Have you looked at my Python code? It should work with Windows if you change the references to the Serial port to the Windows' style.

A common reason why something won't work without opening the Serial Monitor first is the failure to set the DTR and RTS settings for the serial port.

...R

Then, on the Arduino side, it takes input from the serial, stores the character, checks what character it is, turns on the led for a few miliseconds, as a blink, checks to see if X time has passed, and shuts it off.

You say that like the LED will be turned on, and then off, in a single pass through loop(). That is NOT what will happen.

Sometimes though, the Arduino either barely, a very tiny flash, turns on the led, doesn't turn it on at all, or "freezes / lags".

Sometimes, barely, very tiny, etc. are all weasel words that mean that you don't have any real data.

50 milliseconds IS a very tiny interval. Are you really expecting to see that?

I suggest that you try again to explain what the problem is. Try to stick to facts, without so many weasel words.

You could use an array of pin numbers and an array of times, and have approximately a 50% reduction in code, and a much cleaner presentation.