Introduction
By now some of your sketches have a loop() forty lines long, with the same five or six lines appearing twice. A function is how you give a piece of code a name and stop repeating it.
void beep() {
tone(8, 880);
delay(100);
noTone(8);
delay(100);
}
Written once. Now beep(); anywhere in the sketch runs those four lines. Three beeps is three words.
void means gives nothing back — it does a job, it does not answer a question. That is the next lesson's subject.
A function can take parameters — values handed to it when it is called:
void beep(int pitch, int length) { ... }
beep(880, 100);
beep(440, 300);
One function, any number of different beeps.
The real gain is not fewer lines. It is that beep() says what it does. A reader who trusts the name never has to look inside, and a loop() made of well-named calls can be read like a sentence.
What you will be able to do
By the end of this lesson you can:
- Write a
voidfunction and call it. - Give a function parameters and pass values in.
- Say why a function's own variables vanish when it finishes.
- Explain why a function must be defined or declared before it is used.
- Name a function for what it does rather than how.
What you need
| Part | Type | Qty |
|---|---|---|
| Arduino UNO R3 | Microcontroller | 1 |
| USB A to B cable | Cable | 1 |
Basic
No wiring. Read everything in the Serial Monitor at 9600 baud.
→ Functions — the same idea with an LED.
Writing one
void sayHello() {
Serial.println("Hello");
}
void setup() {
Serial.begin(9600);
sayHello();
sayHello();
}
void loop() {
}
void— hands nothing back.sayHello— the name. Same rules as a variable name.()— no parameters this time.{ }— the body.
Calling it needs the brackets: sayHello();. Without them, sayHello; compiles and does nothing at all.
You have been writing functions all along. setup() and loop() are both void functions — the Arduino calls them for you.
Parameters
void countTo(int limit) {
for (int i = 1; i <= limit; i++) {
Serial.println(i);
}
}
countTo(5);
countTo(10);
limit is a variable that exists only inside countTo, and it takes whatever value was passed in.
More than one, separated by commas — each with its own type:
void printLabelled(char tag, int value) {
Serial.print(tag);
.();
.(value);
}
printLabelled(, );
Challenges
Challenge 1
Give it a name.
Take this repetitive sketch and rewrite it with one function called three times.
void setup() {
Serial.begin(9600);
Serial.println("----------");
Serial.println(" SECTION");
Serial.println("----------");
Serial.println("----------");
Serial.println(" SECTION");
Serial.println("----------");
Serial.println("----------");
Serial.println(" SECTION");
Serial.println("----------");
}
Then give the function a parameter so each banner can carry a different word.
Log in to ask for the answer.
Challenge 2
A function with two parameters.
Write void printBar(char symbol, int length) that prints a bar:
printBar('*', 5); // *****
printBar('#', 10); // ##########
Use a for loop inside it, and Serial.println() at the end to finish the line.
Then use it to draw a chart of this array, one bar per value, scaled down by dividing by 10:
int data[] = {, , , , };Extra challenge
Refactor the dice game.
Go back to the ARD-PG-09 dice game — roll, categorise, score, print.
Break it into functions:
int rollDice()— you cannot write this one yet, it returns a value. Use a global for now.void describeRoll(int roll)— prints the message for a rollvoid updateScore(int roll)— changes the running totalvoid printScore()— prints the total
Your loop() should end up about four lines long and read almost like English.
Think about it: the sketch is now longer in total lines than it was. What did you gain? And which of the four functions could you drop into a completely different sketch tomorrow without changing a character?
Log in to ask for the answer.