Exiting "while" loop

I have a while loop that can be entered by serial data, in this case pressing a bluetooth button. If the button is pressed a second time during the while loop the serial information is stored and it goes into the second while state immediately after the first becomes false. I want to exit the while loop if the button is pressed a second time. My && Serial.available() == 0 doesn't work, tried -1 also because that is what I think is no data. Tried many things, can't get it to work.

Ideas?

void UpBlue() {
  while (digitalRead(limitUp) == LOW && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (up, LOW);
  }
  while (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (up, HIGH);
    digitalWrite (stow, LOW);
  }
  while (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == HIGH && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (stow, HIGH);
    digitalWrite (Close, LOW);
  }
  for (int i = 8; i <= 13; i++) {
    // all outputs (8-13) off (relay board is active low)
    digitalWrite(i, HIGH);
  }
}

Complete code

int button1 = 14;
int button2 = 15;
int limitOpen = 2;
int limitDeploy = 3;
int limitDown = 4;
int limitUp = 5;
int limitStow = 6;
int limitClose = 7;
int Open = 8;
int Close = 9;
int deploy = 10;
int stow = 11;
int down = 12;
int up = 13;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode (button1, INPUT_PULLUP);
  pinMode (button2, INPUT_PULLUP);
  pinMode (limitOpen, INPUT_PULLUP);
  pinMode (limitDeploy, INPUT_PULLUP);
  pinMode (limitDown, INPUT_PULLUP);
  pinMode (limitUp, INPUT_PULLUP);
  pinMode (limitStow, INPUT_PULLUP);
  pinMode (limitClose, INPUT_PULLUP);
  pinMode (Open, OUTPUT);
  pinMode (Close, OUTPUT);
  pinMode (deploy, OUTPUT);
  pinMode (stow, OUTPUT);
  pinMode (down, OUTPUT);
  pinMode (up, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  char data = 2;

  if (Serial.available() > 0)
  {
    data = Serial.read();

    if (data == '0')
    {
      DownBlue();
    }
    else if (data == '1')
    {
      UpBlue();
    }
  }

  else if (digitalRead(button1) == HIGH)
  {
    Down();
  }
  else if (digitalRead(button2) == HIGH)
  {
    Up();
  }
  else
  {
    for (int i = 8; i <= 13; i++) {
      // all outputs (8-13) off (relay board is active low)
      digitalWrite(i, HIGH);
    }
  }
}

void Down()  {
  if (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == LOW && digitalRead(limitDown) == LOW)
  {
    digitalWrite (Open, LOW);
  }
  else if (digitalRead(limitOpen) == HIGH && digitalRead(limitDeploy) == LOW && digitalRead(limitDown) == LOW)
  {
    digitalWrite (Open, HIGH);
    digitalWrite (deploy, LOW);
  }
  else if (digitalRead(limitOpen) == HIGH && digitalRead(limitDeploy) == HIGH && digitalRead(limitDown) == LOW)
  {
    digitalWrite (deploy, HIGH);
    digitalWrite (down, LOW);
  }
}

void Up() {
  if (digitalRead(limitUp) == LOW && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW)
  {
    digitalWrite (up, LOW);
  }
  else if (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW)
  {
    digitalWrite (up, HIGH);
    digitalWrite (stow, LOW);
  }
  else if (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == HIGH && digitalRead(limitClose) == LOW)
  {
    digitalWrite (stow, HIGH);
    digitalWrite (Close, LOW);
  }
}

void UpBlue() {
  while (digitalRead(limitUp) == LOW && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (up, LOW);
  }
  while (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (up, HIGH);
    digitalWrite (stow, LOW);
  }
  while (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == HIGH && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (stow, HIGH);
    digitalWrite (Close, LOW);
  }
  for (int i = 8; i <= 13; i++) {
    // all outputs (8-13) off (relay board is active low)
    digitalWrite(i, HIGH);
  }
}

void DownBlue()  {
  while (digitalRead(limitOpen) == LOW && digitalRead(limitDeploy) == LOW && digitalRead(limitDown) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (Open, LOW);
  }
  while (digitalRead(limitOpen) == HIGH && digitalRead(limitDeploy) == LOW && digitalRead(limitDown) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (Open, HIGH);
    digitalWrite (deploy, LOW);
  }
  while (digitalRead(limitOpen) == HIGH && digitalRead(limitDeploy) == HIGH && digitalRead(limitDown) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW && Serial.available() == 0)
  {
    digitalWrite (deploy, HIGH);
    digitalWrite (down, LOW);
  }
  for (int i = 8; i <= 13; i++) {
    // all outputs (8-13) off (relay board is active low)
    digitalWrite(i, HIGH);
  }
}

Bri6462 wrote (in part):

My && Serial.available() == 0 doesn't work, tried -1 also because that is what I think is no data. Tried many things, can't get it to work.

I don't know what you actually tried or how you tried it because I do not get to see that code.

break will let you exit a while loop, but it seems that you should be using if and not while. I do not understand the point of using a looping construct in the first place.

By the way, a while loop is NOT a state.

Maybe the wrong question is being asked and answered.

You're right, I should not have stated I tried a bunch of things without stating what they were. The problem with an if loop like I have on my momentary switches is that the Bluetooth app just sends the info on one press, no ability to use it like a momentary switch you can hold down. The while loop let's it complete the cycle to the next stage and then stop. The problem is that if the Bluetooth button is pressed again during the cycle, the press is held in the buffer. This will start the second cycle immediately after the first. I can't have this and would like the second press, during a while cycle, to stop all output.

I found an example of how to clear the buffer on my UpBlue function upon exit by just reading the buffer over and over until it's gone. This will solve half of my problem and stop the cycle, but I'd like to find a way to stop all output if the button is pressed in the middle of a cycle. I'll look into the break function and see if it can be used.

After you have detected the button transition you are looking for (LOW->HIGH?) and initiated some action like opening or closing a door, then stop detecting the button. Just let it run to completion. Unless you need a second press of the button to act as an emergency stop or a reverse? Then you probably need a state machine.

You have done well in the UpBlue() function to give all your pins names. But then you have that for() loop at the end that totally ignores the names. This is definitely one place NOT to use a for() loop. Just write out 4 digitalWrite() statements to set the outputs how you want. If you rearrange pins or change to a Mega with different pins or you decide that the 'middle' one needs to stay LOW, then you will have a difficult bug to find because there's this for() loop buried in your code tuning pins on and off in a way that's unrelated to the functions named for those pins.

There is no such thing as an if loop. if does not loop.
break is a statement, not a function.

Sorry to be pedantic, but clarity is important.

My && Serial.available() == 0 doesn't work, tried -1 also because that is what I think is no data

Zero is no data.

If you have no dogs, you have zero dogs, right? You don't have -1 dogs.

Serial.read() returns -1 if you have no data. That is different from Serial.available() which returns how many bytes are available.

Thanks everyone! I love this forum! I'm two weeks into my arduino learning experience and everytime I get stuck I come here to get a nudge in the right direction.

I do need to be able to stop all motion as a safety factor in this case. With your help and some searching I was able to get this figured out. The code below works as I planned. One button press starts motion, a second press stops motion. Once motion reaches the limit sensor the next press starts the following motion.

void UpBlue() {
  while (digitalRead(limitUp) == LOW && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW)
  {
    if (Serial.available() > 0)
    {
      break;
      }   
    digitalWrite (up, LOW);
  }
  while (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == LOW && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW)
  {
    if (Serial.available() > 0)
    {
      break;
      }
    digitalWrite (up, HIGH);
    digitalWrite (stow, LOW);
  }
  while (digitalRead(limitUp) == HIGH && digitalRead(limitStow) == HIGH && digitalRead(limitClose) == LOW && digitalRead(button1) == LOW && digitalRead(button2) == LOW)
  {
    if (Serial.available() > 0)
    {
      break;
      }
    digitalWrite (stow, HIGH);
    digitalWrite (Close, LOW);
  }
   for (; Serial.available() > 0;) {
    // deplete serial buffer
    Serial.read();
  }
  for (int i = 8; i <= 13; i++) {
    // all outputs (8-13) off (relay board is active low)
    digitalWrite(i, HIGH);
  }
  }

This particular project shouldn't (famous last words) get much bigger than this. I will go back and list out the resets instead of using the for loop if it does grow, that is a great idea. I bought some switches last night to box it all up nice and pretty for an easier time of simulated real world, every scenario testing. Then I'll have to actually try it in the real world. Thanks again!