Functions
Functions can be quite daunting for a novice programmer. Perhaps the easiest way to think of a function is as a means to group several lines of code together and give them a common name, making it easy to reuse that code fragment again and again.
If you were to delve into the inner workings of Arduino, you would notice that built-in functions like
digitalWrite() can be, to put it mildly, complex. Below is the code for the
digitalWrite() function (don't attempt to decipher what it does; just be grateful that you don't have to type all of this code every time you want to change a pin from a high state to a low state):
Code: Select all
void digitalWrite(uint8_t pin, uint8_t val) {
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
// If the pin supports PWM output, it must be turned off before performing digital write
if (timer == NOT_ON_TIMER) turnOffPWM(timer);
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}
SREG = oldSREG;
}
By assigning a name to such a large code fragment, we only need to refer to it by name and use it.
In addition to built-in functions (such as
digitalWrite), you can create your own functions to encapsulate operations you frequently use. For example, you can write a function that makes an LED blink a specified number of times, with the target pin also specified as a parameter. This is demonstrated in the following sketch: we define a
blink function and call it in the
setup() stage, causing the LED on the Arduino board to blink 5 times after a reset:
Code: Select all
const int ledPin = 13;
void setup()
{
pinMode(ledPin, OUTPUT);
blink(ledPin, 5);
}
void loop() {}
void blink(int pin, int n)
{
for (int i = 0; i < n; i++)
{
digitalWrite(pin, HIGH);
delay(500);
digitalWrite(pin, LOW);
delay(500);
}
}
In this code, the
setup() function sets
ledPin as an output and then calls the
blink function, providing it with the name of the pin to blink and the number of times it should blink. The
loop() function is empty and does nothing, but the Arduino IDE expects it to be present.
The
blink function itself begins with the word
void, indicating that the function doesn't return anything. In other words, you cannot assign the result of calling this function to a variable, which might be something you'd want to do if the function performed some calculations. Next, we see the name of the function (
blink) and its parameters enclosed in parentheses and separated by commas. When defining a function, you need to specify the type of each parameter (e.g.,
int, float, etc.). In our case, both the pin to blink (
pin) and the number of blinks (
n) are integers (
int).
In the C language, as well as in most other programming languages, there is a distinction between local and global variables.
Global variables (like
ledPin in the previous example) can be used anywhere in the program. On the other hand,
local variables, such as function parameters (in our case,
pin and n), and even the variable
i in the
for loop, are only accessible within the function where they are defined.
So, in the
setup() function, the line
blink(ledPin, 5) passes the global variable
ledPin to the
blink function, where it is assigned to the local variable
pin. It may seem redundant, but by passing
pin to
blink, we make the
blink function versatile, allowing us to blink any specified pin, not just
ledPin.
Inside the
blink function's body, there is a
for loop that will repeatedly call the
digitalWrite() and delay() functions 5 times. However, if you set it to 3, the LED will blink 3 times.