How to Use Subroutine in Arduino

Ammar Ali Feb 02, 2024
  1. Understanding Subroutines (Functions) in Arduino
  2. Implementation and Usage
  3. Advantages of Using Subroutines
  4. Parameter Passing and Return Values
  5. Conclusion
How to Use Subroutine in Arduino

Subroutines in Arduino, also known as functions, play a pivotal role in organizing and structuring code for more efficient and manageable Arduino projects. Let’s delve into an extensive exploration of subroutines, their significance, implementation, and practical applications within Arduino programming.

This tutorial will discuss working with subroutines by declaring functions and calling them in the main code in Arduino.

Understanding Subroutines (Functions) in Arduino

Subroutines (or functions) in Arduino are modular blocks of code designed to perform specific tasks or operations. They allow you to break down complex tasks into smaller, more manageable segments, enhancing code readability, reusability, and maintenance.

The basic structure of a function in Arduino:

returnType functionName(parameters) {
  // Function body (code block)
  // Perform specific tasks here
  return value;  // Optional return statement
}
  • returnType: Specifies the data type of the value returned by the function (e.g., void, int, float, etc.).
  • functionName: Name of the function, which can be chosen to reflect the task it performs.
  • parameters: Input values or variables passed to the function (optional).
  • return value: Optional statement used to return a value from the function (applicable when the returnType is not void).

Implementation and Usage

In Arduino, we can declare functions and call them in the main code to work with subroutines. The code is executed line by line, and if we call a function at a line, Arduino will stop at that line and move to that function’s declaration.

It will execute the code present in the function and then move to the following line in the main code.

Example:

void setup() {}
void loop() {
  // code
  Sub_1();
  // code
}
void Sub_1() {
  // code
}

When the Sub_1() function line is executed in the above code, the compiler will move to the Sub_1() function declaration and run its code.

It will return to the main code and move to the following line. We can declare functions with or without return types.

In the above code, we used the void keyword, which means the function will not return anything, but we can change the values of global variables in the function.

The variables defined at the start and are not enclosed by any function are called global variables.

Let’s define a global variable and change its value using a subroutine. See the code below:

int a = 5;
void setup() {}
void loop() {
  // code
  Sub_1();
  // code
}
void Sub_1() { a = 10; }

In the above code, the value of the global variable a will be changed after the subroutine Sub_1() is executed. We can print the variable’s value before and after the subroutine to check if it’s working or not.

We can also define functions with a return type that will return a value when they are called.

To define a function with a data type, we must first write the data type, the function name, and the parameters we want to pass inside the function.

For example, let’s define a function to find the sum of two integers and return the result as an integer.

void setup() {}
void loop() {
  int a = 5;
  int b = 5;
  int c;
  c = Sub_1(a, b);
  // code
}
int Sub_1(int x, int y) {
  int result = x + y;
  return result;
}

In the above code, when the function Sub_1() is called with the specific inputs, it will return the sum of the two inputs.

Note that the variables we passed inside the Sub_1() function are not the same as those we used inside the Sub_1() declaration. Still, we can use the same variables because they are not global.

The variables defined inside a function can only be used and changed inside that function. We can use the return keyword to return a value or a variable.

We can also use other data types to define a function like string, char, and long. If we don’t want to return any value or variable, we can use the void keyword to define the function.

Subroutines are helpful when we want to write a clean code or repeat a task multiple times in a code.

If we want to perform a task more than once in a code, we have to write the code multiple times, but we can make a function, put the code inside it, and call it anytime in the main code. It will reduce time and space and make the code clean and short.

Let’s consider a simple example to demonstrate the creation and usage of a function in Arduino:

// Function declaration
void greetUser() { Serial.println("Hello! Welcome to Arduino functions."); }

void setup() {
  Serial.begin(9600);  // Initialize serial communication
  greetUser();         // Call the function to greet the user
}

void loop() {
  // Main loop code
}

Output:

Hello! Welcome to Arduino functions.

In this example, greetUser() is a function that prints a welcome message. It’s declared before the setup() function to ensure that setup() can call it.

Inside setup(), greetUser() is invoked, resulting in the printed message when the code runs.

Advantages of Using Subroutines

  1. Code Modularity: Functions enable the division of code into smaller, reusable units, enhancing readability and organization.
  2. Code Reusability: Once defined, functions can be called multiple times from different parts of the program, reducing redundancy.
  3. Simplified Debugging: Smaller functions are easier to test and debug, aiding in identifying and rectifying issues within specific sections of code.
  4. Abstraction and Encapsulation: Functions abstract the underlying implementation details, allowing the main code to focus on higher-level logic, thus encapsulating complexity.

Parameter Passing and Return Values

Functions can accept parameters and return values, enhancing their versatility:

Parameter Passing

void displayNumber(int num) { Serial.println(num); }

void setup() {
  Serial.begin(9600);
  int value = 42;
  displayNumber(value);  // Passing 'value' to the function
}

void loop() {
  // Main loop code
}

Output:

42

When the code runs, it will print the value of 42 to the serial monitor using the Serial.println() statement inside the displayNumber function.

This code demonstrates how a function can accept a parameter, perform a specific task (in this case, printing a number to the serial monitor), and be called from the setup() function with a specific value passed as an argument.

Return Values

int addNumbers(int a, int b) { return a + b; }

void setup() {
  Serial.begin(9600);
  int result = addNumbers(5, 7);  // Function call with arguments
  Serial.println(result);         // Output: 12
}

void loop() {
  // Main loop code
}

Output:

12

This code exemplifies the usage of a function (addNumbers) that takes two integer arguments and returns their sum. By calling this function with specific arguments within the setup() function, it showcases how functions can perform operations and return values, allowing the main code to utilize the result for further processing or output.

Practical Applications

  • Sensor Readings: Functions can process sensor data, making the code more organized and easier to understand.
  • Motor Control: Segregating motor control logic into functions simplifies the code and makes it more maintainable.
  • Communication Protocols: Implementing communication protocols (like I2C or UART) in functions enhances code readability and scalability.

Conclusion

Subroutines (or functions) in Arduino programming are instrumental in organizing, streamlining, and simplifying code structure. Their modularity, reusability, and ability to encapsulate functionality facilitate efficient development, making complex tasks manageable and enhancing the overall readability and maintainability of Arduino projects.

Integrating functions in your Arduino codebase optimizes development and fosters a more structured approach toward programming, leading to more robust and manageable projects.

Author: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook