SOLVED Blink an LED until specific serial input is given

I'm trying to set up my code for an Arduino UNO so that if 'a' is given in the serial input, the LED will blink until 'b' and ONLY 'b' is input. I've attached my code.
My problem is that anything can turn off the LED because of the while loop that I have setup, but I wasn't sure of any other way that I could make the LED blink indefinitely.
I tried replacing the while condition with (serial.readString().compareTo("b\n") == !0), but then the LED doesn't blink even when 'a' is pressed.
I also have to use strings because I don't want an input like "abc" to trigger anything in the code.

My code:

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  Serial.println("Press 'a' to blink the LEDs. Press 'b' to turn them off."); // prompt user input
}

void loop() {
  if (Serial.available() > 0) { // check if serial input is given
    String input = Serial.readString(); // read and store the input as a string
    // check if the string is a
    if (input.compareTo("a\n") == 0) {
      Serial.print("\tInput was 'a'.\n");
      Serial.print("\tTurning LEDs on.\n");
      while (Serial.available() == 0) {
        digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(2000);                       // wait for a second
        digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
        delay(1000);
      }      
    }
    // check if the string is b
    else if (input.compareTo("b\n") == 0) {
      Serial.print("\tInput was 'b'.\n");
        Serial.print("\tTurning LEDs off.\n");
        digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    }
    // check if the string is not a or b
    else {
      Serial.print("\tInput not recognized.\n\tPlease try again.\n");
    }
    Serial.print("\nPress 'a' to blink the LEDs. Press 'b' to turn them off.\n"); // restate the user prompt
  }
}

blinkLED_specificSerialInput.ino (1.32 KB)

What you need to do is multiple things at once. When LEDs are not blinking you need to check for an 'a' and when they are you need to check for a 'b'. The easiest way to do that is to not use delays but the millis() function. See the following tutorial: Walk Away from Delay. It is actually has a blinking LED example. Get that working first then add code to check the serial port.

Is there a way to make the LED stay on for a different amount than it is off? i.e. 2 s on and 1 s off

Modified from the example that ToddL1962 linked to have different on and off times.

const int ledPin =  LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
long interval = 1000;     // ************ removed const

void setup()
{
   pinMode(ledPin, OUTPUT);   
}

void loop()
{
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval)
   {
      previousMillis = currentMillis;
      if (ledState == LOW)
      {
         ledState = HIGH;
         interval = 500;   // ********** sets on time
      }
      else
      {
         ledState = LOW;
         interval = 2000; // ********** sets off time
      }
      digitalWrite(ledPin, ledState);
   } //end if
}

How can I make it so that it only enters that loops if the 'a' input is given? I don't want to start out blinking the LED

If the source of the input 'a' is the serial monitor the serial input basics tutorial shows how to receive a character. Then us if to see if the serial input is 'a' and set a flag to run the blinking.

Here is the previous example modified to get input from serial monitor to control whether the LED will blink or not. Uses code from the serial input basics tutorial.

const int ledPin =  LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
long interval = 500;     // ************ removed const

char receivedChar;
boolean newData = false;
boolean runLed = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("Arduino ready");
   pinMode(ledPin, OUTPUT);
}

void loop()
{
   recvOneChar();
   if (newData == true)
   {
      if (receivedChar == 'a') //run blink
      {
         runLed = true;
         newData = false;
      }
      else if (receivedChar == 's') // turn off blink
      { 
         runLed = false;
         ledState = LOW;  // turn led off
         newData = false;
      }
   }
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval && runLed == true)
   {
      previousMillis = currentMillis;
      if (ledState == LOW)
      {
         ledState = HIGH;
         interval = 500;   // ********** sets on time
      }
      else
      {
         ledState = LOW;
         interval = 100; // ********** sets off time
      }
   } //end if
   digitalWrite(ledPin, ledState);
}

void recvOneChar()
{
   if (Serial.available() > 0)
   {
      receivedChar = Serial.read();
      newData = true;
   }
}

Thanks ToddL1962 and groundFungus for your responses and the examples you provided. I'm pretty new to coding so seeing that approach really helped me learn.

I changed the code to Serial.readString() instead of just Serial.read() so that if multiple characters were input, it wouldn't be recognized as just 'a' or 'b'. So in the end the code runs the way I want it to and I learned a little bit about coding.

Thanks again!

And if you keep using the String class you will, eventually, learn about chasing weird bugs. Read the evils of String page to see why.

The second example in Robin2's serial input basics tutorial (linked in reply #5) shows how to read multiple characters into a null terminated character array (string) without blocking (readString blocks).