PROGRAMMINGS: FUNCTIONS
Within a program, you often need to do a task over and over again with some small differences. Functions allow us to create “reusable” code. For example, you might have three LEDs and you want to blink the first one twice, the second one once, and the third one four times. We could do it the hard way and write the code out for each case, or we could come up with a clever function that we reuse for each case. Here’s a function we could use:
void blinkLED(int ledPin, int times){
for(int k = 0; k < times; k++){
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin,LOW);
delay(500);
}
}
This code snippet declares a function by giving it a name, blinkLED, and providing a block of code to run when it is called. It looks a lot like our setup() and loop() declarations (setup() and loop() are, indeed, types of functions). Functions must be declared outside of the setup() and loop() blocks. You can put the function declarations before or after the setup() and loop() blocks, but most programmers put them after.
The values in parentheses following the function name are the function’s arguments. We need to provide values of the appropriate type when we call this function. In our example, the function expects two int values when it is called.
Once we have a function declared, we can call it from setup(), loop(), or another function. Here’s how we call the function to blink the LED on pin 13 four times:
blinkLED(13,4);
We could also use variables we declared elsewhere in our function call. Just remember that the function will expect to receive two int variables:
int blueLED = 11;
int times = 4;
blinkLED(blueLED,times);
You might be wondering: what does void mean in the function declaration? We use the label void when the function does not return any value that we need to store in memory; our function just blinks an LED. But we do want to return a value in a lot of cases. Here’s an example:
int lowestCommon(int num1, int num2){
int low = min(num1, num2);
int high = num1*num2;
int LCD = high;
for(int k = high; k >= low; k--){
if(k % num1 == 0 & k % num2 == 0){
LCD = k;
}
}
return LCD;
}
This function returns the lowest common denominator for two numbers (remember middle school algebra?). The odd symbol % is the modulo operator. It returns the remainder of the division of two integers. We know one number is divisible by the other when the remainder is 0.
If we want to return a value from a function, the declaration needs to start with the variable type we want to return. We return an int in our example, but it can be any variable type. The return statement at the end of the function tells the Arno what value to return after the function is run.
We can call the function like this:
int theLCD = lowestCommon(27,18);
One more important point has to do with the scope of variables. Variables declared within functions are local variables. They can only be accessed by the function and they are reset each time the function is called. In our example above, we declare the variables high, low, and LCD. These variables can’t be accessed anywhere else in the code. The same is true for variables declared within the setup() and loop() blocks (after all these are functions, too). In contrast, a global variable can be accessed anywhere. Global variables are declared at the beginning of the program, before the setup(), loop(), or other functions. We mostly use global variables in our projects for the sake of simplicity. An advantage of using local variables is that it frees up memory as the variables only take up space while the function is being processed. This can be important in complex sketches that push the limits of variable memory in the microcontroller.
void blinkLED(int ledPin, int times){
for(int k = 0; k < times; k++){
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin,LOW);
delay(500);
}
}
This code snippet declares a function by giving it a name, blinkLED, and providing a block of code to run when it is called. It looks a lot like our setup() and loop() declarations (setup() and loop() are, indeed, types of functions). Functions must be declared outside of the setup() and loop() blocks. You can put the function declarations before or after the setup() and loop() blocks, but most programmers put them after.
The values in parentheses following the function name are the function’s arguments. We need to provide values of the appropriate type when we call this function. In our example, the function expects two int values when it is called.
Once we have a function declared, we can call it from setup(), loop(), or another function. Here’s how we call the function to blink the LED on pin 13 four times:
blinkLED(13,4);
We could also use variables we declared elsewhere in our function call. Just remember that the function will expect to receive two int variables:
int blueLED = 11;
int times = 4;
blinkLED(blueLED,times);
You might be wondering: what does void mean in the function declaration? We use the label void when the function does not return any value that we need to store in memory; our function just blinks an LED. But we do want to return a value in a lot of cases. Here’s an example:
int lowestCommon(int num1, int num2){
int low = min(num1, num2);
int high = num1*num2;
int LCD = high;
for(int k = high; k >= low; k--){
if(k % num1 == 0 & k % num2 == 0){
LCD = k;
}
}
return LCD;
}
This function returns the lowest common denominator for two numbers (remember middle school algebra?). The odd symbol % is the modulo operator. It returns the remainder of the division of two integers. We know one number is divisible by the other when the remainder is 0.
If we want to return a value from a function, the declaration needs to start with the variable type we want to return. We return an int in our example, but it can be any variable type. The return statement at the end of the function tells the Arno what value to return after the function is run.
We can call the function like this:
int theLCD = lowestCommon(27,18);
One more important point has to do with the scope of variables. Variables declared within functions are local variables. They can only be accessed by the function and they are reset each time the function is called. In our example above, we declare the variables high, low, and LCD. These variables can’t be accessed anywhere else in the code. The same is true for variables declared within the setup() and loop() blocks (after all these are functions, too). In contrast, a global variable can be accessed anywhere. Global variables are declared at the beginning of the program, before the setup(), loop(), or other functions. We mostly use global variables in our projects for the sake of simplicity. An advantage of using local variables is that it frees up memory as the variables only take up space while the function is being processed. This can be important in complex sketches that push the limits of variable memory in the microcontroller.