This page can be quickly reached from the link: http://www.gammon.com.au/serial
Something that seems to "throw" beginners to programming on a microprocessor is how to receive incoming serial data without "blocking". That is, being able to do other things while the text is arriving.
For a general discussion about the async serial protocol see:
http://www.gammon.com.au/forum/?id=10894
Serial data comes in fairly slowly (depending on the baud rate). For example at 9600 baud you get 960 characters per second, which means each one takes 1/960 of a second, that is 1.041 mS each. Whilst a millisecond might not sound like much, once you are expecting 80 characters it starts to add up.
Buffering input
The code below illustrates how, inside the main "loop" function, if any incoming data is received it is placed inside a buffer. Once a terminating character (typically a newline) is received the buffer is sent off to another function for processing, and the buffer reset to be empty.
/*
Example of processing incoming serial data without blocking.
Author: Nick Gammon
Date: 13 November 2011.
Modified: 31 August 2013.
Released for public use.
*/
// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 50;
void setup ()
{
Serial.begin (115200);
} // end of setup
// here to process incoming serial data after a terminator received
void process_data (const char * data)
{
// for now just display it
// (but you could compare it to some value, convert to an integer, etc.)
Serial.println (data);
} // end of process_data
void processIncomingByte (const byte inByte)
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
switch (inByte)
{
case '\n': // end of text
input_line [input_pos] = 0; // terminating null byte
// terminator reached! process input_line here ...
process_data (input_line);
// reset buffer for next time
input_pos = 0;
break;
case '\r': // discard carriage return
break;
default:
// keep adding if not full ... allow for terminating null byte
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // end of switch
} // end of processIncomingByte
void loop()
{
// if serial data available, process it
while (Serial.available () > 0)
processIncomingByte (Serial.read ());
// do other stuff here like testing digital input (button presses) ...
} // end of loop
[EDIT] Modified 31 August 2013 to move the processing of each byte into a separate function for clarity.
[EDIT] Modified 15 November 2014 to change "if (Serial.available () > 0)" to "while (Serial.available () > 0)" which allows for lengthier processing inside the "other stuff" in the main loop.

