Using Serial.available() to break while loop

Hello friends, I'm trying to exit an infinite while loop when Arduino receives a new command from Python via Serial. My code is essentially:

while(!Serial.available()) {
    //do stuff
}

but even though I'm sending things from Python, this condition is never met and the loop never breaks. I've tried using a non-infinite loop in order to make sure that I really am sending something from Python, and it works as I expect, but once the infinite loop is implemented, it's as if nothing is being sent. I've also tried:

while(1) {

    //do stuff

    if(Serial.available() > 0) {
        break;    }
}

Perhaps I can't constantly be checking for new Serial input inside a while loop? Any suggestions would be much appreciated!

Hi janizer, what I usually do when reading from serial is this (pseudocode to follow);

some_type result;
while (result is not what I expect to be){
    while(Serial.available()){
         result = read from serial
         do stuff with result if it's the case
     }
}

Hope it helps : )

Simple. Don’t use an infinite loop. Allow the loop() function to do your iteration. Only use WHILE or FOR in situations where they will complete in a few microseconds.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. Notice how it receives data while allowing other things to happen.

And also have a look at the demo Several Things at a Time

…R

Robin2: Don't use an infinite loop. Allow the loop() function to do your iteration. Only use WHILE or FOR in situations where they will complete in a few microseconds.

The only trouble is that in my infinite loop, I'm repeatedly updating and using a local variable, so if I were to instead repeatedly call my function, I (think I) would have to reference that variable using a pointer in order to preserve its value from iteration to iteration. I just tried that out and it seems to take a lot more clock cycles, and speed is really important for my program :( Is there really no way to just break out of the loop when Serial data arrives?

Goet: Hi janizer, what I usually do when reading from serial is this (pseudocode to follow);

some_type result;
while (result is not what I expect to be){
    while(Serial.available()){
         result = read from serial
         do stuff with result if it's the case
     }
}

Hope it helps : )

Thanks, but isn't this basically what I'm doing already? Where the "result is not what I expect" is "!Serial.available()". I still can't seem to exit the loop.

janizer: I (think I) would have to reference that variable using a pointer in order to preserve its value from iteration to iteration.

No, you would make it a 'static' local variable.

gfvalvo: No, you would make it a 'static' local variable.

Whoops, you're right, thank you.

So I suppose that means that the drop in speed (~4 times slower than the infinite loop) is most likely due to repeatedly calling the function from the loop() method. Is this possible?

The only trouble is that in my infinite loop, I'm repeatedly updating and using a local variable,

Is there really no way to just break out of the loop when Serial data arrives?

Your going to have to post some code as to what you have going in inside the infinite loop. I'm not familiar with Python, but this piece of code with the serial monitor operates as expected

void setup() {
  Serial.begin(9600);
}

void loop() {
  while (!Serial.available())
  {
    static byte val = 0;
    val++;
    Serial.println(val);
    if (val == 50)
      val = 0;
    delay(100);
  }
  Serial.println((char)Serial.read());
}

cattledog: Your going to have to post some code as to what you have going in inside the infinite loop. I'm not familiar with Python, but this piece of code with the serial monitor operates as expected

Thanks cattledog, your code does work perfectly and so it made me realize the problem had to be elsewhere. After a lot of googling, I realized that I was using a Serial.read() inside an interrupt routine, and that was causing problems. Now I've worked around the issue and it seems to be running much more smoothly. (knock on wood that I won't be back here again in an hour!)

Thanks for all the help, everyone!