[SOLVED] How to loop 'while' function whilst waiting on serial input?

Hello,

I'm currently trying to do my first simple project written & designed by myself from the ground up. It's basically an RGB LED that will change colour to match an input on the serial monitor. I have the bulk of the code working, the only thing stumping me is how to get the LED to cycle through the spectrum whilst waiting on a serial input. I have the code working to constantly cycle the colours on it's own, but when I paste it into a 'while' function that is waiting for serial input (Serial.available() == 0);{LED cycle code here } it runs once and then waits for input but doesn't cycle again.

The code for the 'while' loop waiting in serial input is lines 28 to 70

(I know I could probably code the colours far more efficiently but i'm only just beginning so go easy on me :slight_smile: )

int rPin = 6;
int gPin = 10;
int bPin = 11;
int rColour;
int gColour;
int bColour;
String myName;
String colour;
int redBrightness;
int greenBrightness;
int blueBrightness;

void setup() {
 Serial.begin(9600);
 pinMode(rPin, OUTPUT);
 pinMode(gPin, OUTPUT);
 pinMode(bPin, OUTPUT);
 
}

void loop() {
  redBrightness = 0;
  greenBrightness = 0;
  blueBrightness = 0;

  Serial.println("Hello!! What is your name?");
  Serial.println("");
  while(Serial.available() == 0);{
    while(redBrightness<=255)
  {
  analogWrite(rPin, redBrightness);
  redBrightness = (redBrightness+1);
  delay(5);
  }
  
  while(greenBrightness<=255)
  {
  analogWrite(gPin, greenBrightness);
  greenBrightness = (greenBrightness+1);
  delay(5);
  }

  while(blueBrightness<=255)
  {
  analogWrite(bPin, blueBrightness);
  blueBrightness = (blueBrightness+1);
  delay(5);
  }

  while(redBrightness>=0)
  {
  analogWrite(rPin, redBrightness);
  redBrightness = (redBrightness-1);
  delay(5);
  }

  while(blueBrightness>=0)
  {
  analogWrite(bPin, blueBrightness);
  blueBrightness = (blueBrightness-1);
  delay(5);
  }

 while(greenBrightness>=0)
  {
  analogWrite(gPin, greenBrightness);
  greenBrightness = (greenBrightness-1);
  delay(5);
  }
  }
  myName = Serial.readString();
  Serial.print("Hello ");
  Serial.print(myName);
  Serial.print("! What is your favourite colour?");
  colour = Serial.readString();

  while(Serial.available() == 0);{
  }
  colour = Serial.readString();
  if(colour == "turquoise"){
    analogWrite(rPin, 64);
    analogWrite(gPin, 224);
    analogWrite(bPin, 208);
  }
  else if(colour == "pink"){
    analogWrite(rPin, 255);
    analogWrite(gPin, 50);
    analogWrite(bPin, 50);
  }
  else if(colour == "purple"){
    analogWrite(rPin, 150);
    analogWrite(gPin, 0);
    analogWrite(bPin, 150);
  }  
  else if(colour == "red"){
    analogWrite(rPin, 255);
    analogWrite(gPin, 0);
    analogWrite(bPin, 0);
  } 
  else if(colour == "green"){
    analogWrite(rPin, 0);
    analogWrite(gPin, 255);
    analogWrite(bPin, 0);
  } 
  else if(colour == "blue"){
    analogWrite(rPin, 0);
    analogWrite(gPin, 0);
    analogWrite(bPin, 255);
  }
  else if(colour == "orange"){
    analogWrite(rPin, 255);
    analogWrite(gPin, 128);
    analogWrite(bPin, 0);
  }
  else if(colour == "yellow"){
    analogWrite(rPin, 255);
    analogWrite(gPin, 175);
    analogWrite(bPin, 0);
  }
  else if(colour == "white"){
    analogWrite(rPin, 255);
    analogWrite(gPin, 255);
    analogWrite(bPin, 255);
  }
  else if(colour == "black"){
    analogWrite(rPin, 0);
    analogWrite(gPin, 0);
    analogWrite(bPin, 0);
  }
}

Serial is slow. Really slow. Think about a friend sending you regular letters by post. Your friend sends one letter about once per week. But it is only "about" so you check the mailbox every day to see if there is a new letter. The rest of the time you live in your house and you turn the lights on and off or whatever you need to do.

If you are waiting for your friend to tell you their favorite color, you remember that the last question you asked was "tell me your favorite color." So you know the next letter you get must be part of the answer to that question.

  while(Serial.available() == 0); {

That semicolon terminates the while statement (while is not a function). The code which follows will not be inside this while loop. Get rid of the semicolon. And fix the other one too.

Pete

1 Like

el_supremo:

  while(Serial.available() == 0); {

That semicolon terminates the while statement (while is not a function). The code which follows will not be inside this while loop. Get rid of the semicolon. And fix the other one too.

Pete

Thank you so much, that worked perfectly! I knew it'd be some silly error!

In general if you are using while loops, replace them with if's and everything will be better.
loop() is always looping, so it can be the only loop, you just get it to check everything
that can change and respond appropriately, without delay() or blocking.

For serial input there is the little used serialEventRun mechanism too (declare this function, it
gets called after each call to loop, so you can keep all the serial processing from cluttering
loop().

The basic approach for complex serial comms is to gather a message character by character
in loop() or serialEventRun(), and only if a complete message/packet is gathered call
anything else to handle it.

This means the serial reading code never blocks...