How do I (1) wait for input, (2) clear input buffer

My sketch contains in loop() the code

    if (!Serial.available())
    {
        if (DEBUG) Serial.println("Enter a number 0..7");
        if (Serial.available() > 0)
        {
            // read in keyboard numeral value
            bitToSet = Serial.read() - 48;
            if (DEBUG)
            {
                Serial.print("Number entered was ");
                Serial.println(bitToSet);
            }

            // write to the shift register with the correct bit set high:
            registerWrite(bitToSet, HIGH);

            // clear Serial input buffer
            bitToSet = Serial.read();
        }
    }

The line if (Serial.available() > 0) does not achieve what I want which is for the program to wait for input. i.e. The text "Enter a number 0..7" will be output and nothing will happen until something is entered. How do I do that?

I see the Language reference for Serial.flush() stipulates "Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.)". I have worked around this by using the line "bitToSet = Serial.read();" at the bottom on my code. Is there a more elegant solution - one that will flush the buffer no matter what is in it?

Thanks

while (!Serial.available());
if (DEBUG) Serial.println("Enter a number 0..7");
if (Serial.available() > 0)
{
  ...
  ...
}

The while will block all your code till data is available. If that's not what you want, you need to give more details (a complete example).

You can clear the input buffer with a while loop that reads a byte and discards it until no more are available.

Thank you both. I have my program pausing, but clearing the buffer is still a problem.

void loop()
{
    // local variable
    byte userInput = 0;

    // get keyboard input
    userInput = receiveInput();
    if (DEBUG)
    {
        Serial.print("userInput is ");
        Serial.println(userInput);
    }


    // debug
    delay(1000);
}

// this function receives and displays keyboard input
byte receiveInput()
{
    // local variable
    byte localInput = 0;

    // ask for input
    Serial.println("Enter a number 0..7");

    // wait for presence of data
    while (Serial.available() == 0) {}

    // get input when it is available
    if (DEBUG) Serial.println("Reading input");
    localInput = Serial.read();

    // show what was received
    Serial.print("Operator entered ");
    Serial.println(localInput, DEC);

    // clear buffer
    while (Serial.available() > 0)
    {
        byte whatever = 0;
        whatever = Serial.read();
        Serial.print(whatever);
        Serial.println(" read from buffer");
    }

    // return the value
    return(localInput);
}

This results in this Serial output

Opening port
Port open
Enter a number 0..7
Reading input
Operator entered 54
userInput is 54
Enter a number 0..7
Reading input
Operator entered 10
userInput is 10
Enter a number 0..7

My clearing loop doesn't seem to want to do anything. What's my goof?

vagulus: My clearing loop doesn't seem to want to do anything.

BTW: I only entered '6' which is ASCII 54. ASCII 10 is 'NL' which should get eaten up by the loop. Problem is, the loop doesn't run.

You should just look at some working examples to see how Serial.available() is normally used. Sitting and doing nothing forever while nothing comes in, in an endless while loop, is not the normal way (hence likely at the root of your problem...).

Your code in reply #3 assumes that all bytes that were entered in serial monitor are already received by the Arduino. That might not be the case. The the newline might still be being transferred after the ‘6’ so the next serial available will indicate that there is nothing to be read. Next you go back to the beginning of loop and now the newline is available and you read it.

You can use the second example in Robin’s Serial Input Basics. It will read till the ‘\n’.

Your loop could look something like

void loop()
{
  static bool promptForUserInput = true;

  if(promptForUserInput == true)
  {
    // clear input buffer
    while(Serial.available() > 0)
    {
      Serial.read();
    }
    // prompt user
    Serial.println("Enter number between 0 and 7");
    promptForUserInput = false;
  }
  else
  {
    // receive data
    recvWithEndMarker();
    // if data is complete
    if(newData == true)
    {
      Serial.println(receivedChars);
      newData = false;
      promptForUserInput = true;
    }
  }
}

Not tested, not compiled

I am using the standard Arduino IDE with Serial input set to finish the line with both CR and NL. I run this code

  if (!Serial.available())
  {
    // invite data entry
    if (DEBUG) Serial.println("Enter a number 0..7");

    // wait for that entry
    while (Serial.available() == 0) {}

    // read in keyboard input as numeral value
    ledToLight = Serial.read() - 48;
    if (DEBUG)
    {
      Serial.print("Number entered was ");
      Serial.println(ledToLight);
    }

    // filter input
    if (ledToLight >= 0 && ledToLight <= 7)
      // write to the shift register with the correct bit set high:
      specifyHighBit(ledToLight);

    // clear Serial input buffer
    while (Serial.available() > 0)
    {
      ledToLight = Serial.read();
      if (DEBUG)
      {
        Serial.print("Character read was ");
        Serial.println(ledToLight);
      }
    }
  }

I enter ‘1’ then I set the input to finish the line with NL only and enter ‘4’.

I get this debug output

Enter a number 0..7
Number entered was 1
Enter a number 0..7
Number entered was -35
Character read was 10
Enter a number 0..7
Number entered was 4
Enter a number 0..7
Number entered was -38
Enter a number 0..7

My head spins when I try to work out what is happening. The line
while (Serial.available() > 0)
seems to work when it feels like it! :roll_eyes:

So, I go back to finishing the line with CR and Nl, re-start the program and enter
“the quick brown fox”. Now I get

Enter a number 0..7
Number entered was 68
Enter a number 0..7
Number entered was 56
Character read was 101
Character read was 32
Character read was 113
Character read was 117
Character read was 105
Character read was 99
Character read was 107
Character read was 32
Character read was 98
Character read was 114
Character read was 111
Character read was 119
Character read was 110
Character read was 32
Character read was 102
Character read was 111
Character read was 120
Character read was 13
Character read was 10
Enter a number 0..7

The line
while (Serial.available() > 0)
was ignored after reading ‘t’ but activated after reading ‘h’. Curiouser and curiouser!

How do I get a consistent buffer flush routine, one which is not so temperamental? I put a delay just before the buffer clearance

    // give Serial Input time to catch up
    delay(10);
    
    // clear Serial input buffer
    while (Serial.available() > 0)

then (with both CR and NL) I get

Enter a number 0..7
Number entered was 7
Character read was 13
Character read was 10
Enter a number 0..7
Number entered was 6
Character read was 13
Character read was 10
Enter a number 0..7
Number entered was 5
Character read was 13
Character read was 10
Enter a number 0..7

Entering “the quick brown fox” gets me

Enter a number 0..7
Number entered was 68
Character read was 104
Character read was 101
Character read was 32
Character read was 113
Character read was 117
Character read was 105
Character read was 99
Character read was 107
Character read was 32
Character read was 98
Character read was 114
Character read was 111
Character read was 119
Character read was 110
Character read was 32
Character read was 102
Character read was 111
Character read was 120
Character read was 13
Character read was 10
Enter a number 0..7

The buffer clearance is behaving itself!

sterretje was right when he wrote "Your code in reply #3 assumes that all bytes that were entered in serial monitor are already received by the Arduino. That might not be the case. The the newline might still be being transferred after the ‘6’ so the next serial available will indicate that there is nothing to be read. "