Arduino: Setting Delay Time via Serial Input

12th February 2010

There are plenty of tutorials explaining how to make an LED turn on for a pre-set period of time using the Arduino. However I have come across none which allow us to set the delay time using serial communication. As it turns out, getting an integer value from serial input is a little more complex than one might first think. To understand why, we must first understand how serial communication works.

Serial transfer is where we send each bit of data sequentially, one after another. The Arduino stores each byte (8 bits) it receives into its input buffer array. When we call the Serial.read() function, we grab one byte form the input buffer. So, if we send the number 100 we will read a one followed by a zero followed by another zero. To make things a little more confusing, each number will be ASCII encoded. We must convert each received byte to an integer and then join each individual integer into one value.

After a few attempts to concatenate integers,  I came across this insightful post on the Arduino forums. The following code is adapted from the code suggested by user PaulS.

value = 0;

while (Serial.available() > 0)
{
  value *= 10;
  value += (Serial.read() - '0');
  delay(1); 
}

We start by initializing an integer to zero, this will hold our read value. Within the while loop, the value is multiplied by 10 to shift the place value of the digits to the left. In line 6, we subtract the ASCII value of character zero (48) from the input byte (which we know is ASCII encoded) and hence obtain a numeric value. It should be noted that each number is placed in the units column and then shifted to the left each time another value is added.

I found that at a baud rate of 9600, the Arduino was executing the run loop faster than the serial bytes were being received. As a result if I sent the number 100, the while loop only ran once and so the value was set to 1. The one ms delay gives the Arduino time to receive the next byte.

Full source code is provided below:

/*
*  Serial Delay
*
*  Reads value from serial input and stores it as an integer.
*  Switches an LED on for the number of milliseconds defined
*  by the integer.
*
*  Note: Does not check to see if input is numeric.
*
*  By Leo Kent
*  Created 11 February 2010
*
*  http://leo.me.uk/
*/

// Declare a variable to hold the delay value.
int value;

void setup()
{
  // Begin serial communication at a baud rate of 9600.
  Serial.begin(9600);
  
  // Set pin 13 as an output.
  pinMode(13, OUTPUT);
}

void loop()
{
  // Check to see if serial data is available.
  if (Serial.available() > 0)
  {    
    // (Re)set the value to zero.
    value = 0;
    
    // Append each byte to the delay value integer.
    while(Serial.available() > 0)
    {
      value *= 10;
      value += (Serial.read() - '0');
      delay(1); // Give the AVR time to receive all bytes.
    }
    
    Serial.println(value);
    
    // Turn the LED on.
    digitalWrite(13, HIGH);
    
    // Delay by the requested number of ms.
    delay(value);
    
    // Turn the LED off.
    digitalWrite(13, LOW);
  }
}
Advertisements

6 Responses to “Arduino: Setting Delay Time via Serial Input”

  1. Iyan Says:

    Thanks a lot, I’m using your snippet to get integer data from the serial input

  2. David Says:

    Nice code, but doesn’t work too well with negative numbers though

  3. jackpronin Says:

    hello

  4. chan Says:

    that is right

  5. Thomascig Says:

    Приватный форум по заработку – garsuk.net


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: