Deep Dive: Functions
We can also create functions that encapsulate code into blocks that can easily be called from anywhere in a program, just like in Scratch and Python. The following code does the same thing as our for
loop example above, but this time uses functions:
void loop()
{
blinkOnce();
blinkOnce();
blinkOnce();
delay(400);
}
void blinkOnce()
{
digitalWrite(2, HIGH);
delay(100);
digitalWrite(2, LOW);
delay(100);
}
Functions can also be written so that they have parameters that allow you to customize (or “parameterize”) the behavior of the function when you call it. Consider the following revision of the example, which varies the length of the three blinks between 50 and 150 ms (milliseconds):
void loop()
{
blinkOnce(50);
blinkOnce(100);
blinkOnce(150);
delay(400);
}
void blinkOnce(int delayLength)
{
digitalWrite(2, HIGH);
delay(delayLength);
digitalWrite(2, LOW);
delay(delayLength);
}
Data Types for Functions
The keywords void
and int
are data types. When placed in front of a function declaration, a data type specifies what type of data the function returns. The functions setup()
, loop()
, and blinkOnce()
all have the return type void
, which means they do not return anything. If you wanted to create a function that returns an integer, you could put int
in front of it, like this function that adds two numbers and returns the sum:
int add(int a, int b)
{
return a + b;
}
Data types are also used with function parameters to specify what kind of data the function accepts. The parameters of blinkOnce()
and add()
are all integers, and so they are prefixed with the int
data type.
In addition to int
and void
there are lots of other data types supported by the C compiler used in the Arduino IDE. Here are some common ones, taken from the Arduino website:
Type | Description |
---|---|
bool |
A boolean value that can be either true or false. |
byte |
An 8-bit unsigned integer, from 0 to 255. |
int |
A 16-bit signed integer, from -32,768 to 32,767. |
unsigned int |
A 16-bit unsigned integer, from 0 to 65,535. |
long |
A 32-bit signed integer, from -2,147,483,648 to 2,147,483,647. |
unsigned long |
A 32-bit unsigned integer, from 0 to 4,294,967,295. |
float |
A 32-bit floating point number (also known as a decimal number). |
double |
A 64-bit floating point number (also known as a decimal number). |
Some programming languages, like C, C#, and Java, are statically typed and require you to explicitly state the data type of every function, parameter, and variable like we have done here. Other programming languages, like Python and Javascript, are dynamically typed and instead infer types based on how functions, parameters, and variables are used in your code (e.g., if you try to multiply two variables they presumably contain numbers). There are strengths and weaknesses of each, but for now you are writing C so you do not have much of a choice!