Function for entering data over Serial

Hi,

I'm able to get my code to work. What I want to do is flush the input buffer after each data entry to get hold the serial input until another value is entered. I"m able to do this.

However, when I try to reduce the 3 lines of code for this into 1 line of code (which I made as a function), it skips every other entry.

Here's what works:

  while (Serial.available() > 0) 
  { Serial.read();    // flush input buffer  
  }

Here's what I want to do:

void flush_input(void)
{
  // flush input buffer, do before asking for new input.  Notes: https://forum.arduino.cc/t/serial-input-basics-updated/382007
  while (Serial.available() > 0) 
  { Serial.read();    // flush input buffer  
  }
}

When I try to replace the 3 lines of code with the function call void flush_input(void) is when the serial monitor skips my entry, e.g. race 2 will be entered as 0.00. So will race 4

Full code:

/*
Input runner's time for each race.
Runner ran 4 times per week, and recorded these times.

Runner1
Runner2

Structure:
- Use 1 array to store both runners' data. Thus, 2 rows, 4 columns, so array[2][4]



Sort:
   - run times per runner, low to high.

Display:
    - slowest run times for each runner 
    - fastest run time for each runner


Advanced:
    - edit lowest run times, likely uses pointers or references


*/

#include<Arduino.h>


//global vars
int runner_num = 1;     // defines start num of which runner is running

// Function Prototypes
void which_runner(int runner_num);

//void flush_input(void);

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


void loop() 
{

// arrays holding runners times
const int total_runners = 2;
const int num_of_races = 4;
double run_time[total_runners][num_of_races];   // defines a 2x4 matrix. Row 1 = runner 1 data, Row 2 = runner 2 data

//Enter run times for runners
which_runner(runner_num);

// 1st runner data, enter all
for(int j=0; j < num_of_races; j++)
{
  //Serial.println("Runner 1***");   //debug line
  Serial.print("race ");
  Serial.print(j+1);        //race number
  Serial.print(": ");
  while (Serial.available() == 0) {}  // waits until data is entered into serial monitor
  run_time[runner_num][0] = Serial.parseFloat();    //takes incoming characters and converts it to a number. This is read into the buffer altogether.  Default is data type long.
  Serial.print(run_time[runner_num][0]);
  Serial.println(" minutes");
  
  // void flush_input(void);

  // flush input buffer, do before asking for new input.  Notes: https://forum.arduino.cc/t/serial-input-basics-updated/382007
  while (Serial.available() > 0) 
  { Serial.read();    // flush input buffer  
  }

}

// increase runner number for display and entry of new array for run times
runner_num++;  

//Enter run times for runners
which_runner(runner_num);

// 2nd runner data, enter all
for(int i=0; i<num_of_races; i++)  
{
  //Serial.println("Runner 2***");  // debug line
  Serial.print("race ");
  Serial.print(i+1);        //race number
  Serial.print(": ");
  while (Serial.available() == 0) {}  // waits until data is entered into serial monitor
  run_time[runner_num][0] = Serial.parseFloat();    //takes incoming characters and converts it to a number. This is read into the buffer altogether.  Default is data type long.
  Serial.print(run_time[runner_num][0]);
  Serial.println(" minutes");

   //void flush_input(void);
  
  // flush input buffer, do before asking for new input.  Notes: https://forum.arduino.cc/t/serial-input-basics-updated/382007
  while (Serial.available() > 0) 
  { Serial.read();    // flush input buffer  
  }
  
}

runner_num++;

if(runner_num > total_runners)
{
  Serial.print("\nAll race data has been entered.");
  Serial.flush();
  exit(0);
}


}

// Function Definitions
void which_runner(int runner_num)
{
  Serial.print("***\nEnter times for runner: ");
  Serial.println(runner_num);
  return 0;
}

/*
void flush_input(void)
{
  // flush input buffer, do before asking for new input.  Notes: https://forum.arduino.cc/t/serial-input-basics-updated/382007
  while (Serial.available() > 0) 
  { Serial.read();    // flush input buffer  
  }
  //return 0;
}
*/

To empty the Serial Buffer in order to bring the pointer at the beginning of the buffer, I usually execute the following codes:

  do
  {
    (void)Serial.read();
  }
  while (Serial.available() != 0);

Well, first of all, I can't understand why you need to flush the serial buffer after each input, especially if you're reading some consecutive data input. IMHO this code could work fine even without the flush_input() function.

Anyway, if I quickly type more values separated by Enter key, like 1 Enter 2 Enter 3 Enter, the only thing you'll flush is the line terminator (I've never used parseFloat() but it seems to leave it in the buffer).
Run this example code to know more about that:

//global vars just to kame things similar:
int runner_num = 1;     // defines start num of which runner is running
const int total_runners = 2;
const int num_of_races = 4;
double run_time[total_runners][num_of_races];   // defines a 2x4 matrix. Row 1 = runner 1 data, Row 2 = runner 2 data

void setup()
{
  Serial.begin(9600);
  Serial.println("STARTED");
  
  for(int j=0; j < num_of_races; j++)
  {
    //Serial.println("Runner 1***");   //debug line
    Serial.print("race ");
    Serial.print(j+1);        //race number
    Serial.print(": ");
    while (Serial.available() == 0) {}  // waits until data is entered into serial monitor
    run_time[runner_num][0] = Serial.parseFloat();    //takes incoming characters and converts it to a number. This is read into the buffer altogether.  Default is data type long.
    Serial.print(run_time[runner_num][0]);
    Serial.println(" minutes");
    flush_input();
  }
  
  Serial.println("END");
}

void flush_input(void)
{
  Serial.println("flushing... ");
  while (Serial.available()) 
  { 
    Serial.print("0x");
    Serial.print(Serial.read(), HEX);    // flush input buffer  
    Serial.print(" ");
  }
  Serial.println("flushed.");
}

void loop()
{
  
}

@ GolamMostafa
When I run your code block instead of mine, I get the same correct results. However, when I try to encapsulate it as a function, it incorrectly runs the same as mine would - it skips every other entry, e.g. on the even race numbers, the code will enter "0.00".

@ docdoc
Your code does work. However, it changes the structure of mine, and I was looking for something similar. Good run, though.

The Arduino serial monitor is a quirky beast and everyone seems to get things to work for them creatively, which is great. (This would be much easier in desktop VS code.)

I still can't understand why it won't run as a function, but I decided to just take the 3 lines of code I was using and structure it as one, and copy where I need it. At least it works now as 1 line.

while (Serial.available() > 0) {Serial.read();}

parseFloat() will get confused when you have multiple line endings CR/LF in the monitor... and will treat the incoming data as 2 numbers. Change to just CR OR LF.

image