La modularización, es una técnica usada por los programadores para hacer sus códigos más cortos, ya que consiste en reducir un gran problema complejo, en pequeños problemas más sencillos, concentrándose en la solución por separado, de cada uno de ellos.
Una función es un conjunto de instrucciones que realizan una acción determinada.
Esta función tendrá un nombre y podrá ser llamada desde otras partes
del código tantas veces como sea necesario. Las funciones pueden recibir
datos, denominados parámetros, que pueden ser manipulados en su interior. En ocasiones, esta función, además de ejecutar todas estas instrucciones, podrá devolver un valor final que pueda ser utilizado allí donde la función ha sido llamada.
Ayudan al programador a ser mucho más organizado separando por nombres las funciones haciendo que el código sea legible.
Al utilizar funciones podemos hacer más compacto nuestro código organizándolo por bloques y llamando a las funciones con solo utilizar su nombre para correr su código interno esto nos permite que nuestro código sea más ligero y más fácil de entender.
En las funciones juegan un papel muy importe las variables, ya que como se ha dicho estas pueden ser locales o globales.
Variables Globales: Estas se crean durante toda la ejecución del programa, y son globales, ya que pueden ser llamadas, leídas, modificadas, etc; desde cualquier función. Se definen antes del main().
Variables Locales: Estas, pueden ser utilizadas únicamente en la función que hayan sido declaradas.
La sintaxis de una función es la siguiente:
Tipo_de_datos nombre_de_la_funcion(tipo y nombre de argumentos)
{
acciones
}
donde:
- Tipo_de_datos: Es el tipo de dato que devolverá esa función, que puede ser real, entera, o tipo void(es decir que no devolverá ningún valor).
- Nombre_de_la_funcion: Es el identificador que le damos a nuestra función, la cual debe cumplir las reglas que definimos en un principio para los identificadores.
- Tipo y nombre de argumentos: son los parámetros que recibe la función. Los argumentos de una función no son más que variables locales que reciben un valor. Este valor se lo enviamos al hacer la llamada a la función. Pueden existir funciones que no reciban argumentos.
- Acciones: Constituye el conjunto de acciones, de sentencias que cumplirá la función, cuando sea ejecutada.
Una función, termina con la llave de cerrar, pero antes de esta llave, debemos incluir la instrucción return, con la cual devolverá un valor específico. Es necesario recalcar que si la función no devuelve ningún valor, es decir, es tipo void, no tiene que ir la sentencia return, ya que de lo contrario, nos dará un error.
Ejemplo1: Función para realizar una medida de distancia con un sensor de ultrasonidos.
long medirDistancia()
{
long distancia;
long tiempo;
digitalWrite(TriggerPin,LOW);
delayMicroseconds(5);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
tiempo=pulseIn(EchoPin, HIGH);
return(distancia);
}
Explicación:
Función que devuelve el valor obtenido de la distancia de un objeto. Función que devuelve un tipo de dato entero (long). En esta función no se pasa ningún argumento.
Llamada a la función: distanciaObjeto=medirDistancia();
Ejemplo 2: Función para controlar el giro un motor de corriente continua y el controlador L293H
void girarMotorDerecha()
{
digitalWrite(E1, HIGH); //Activar el motor 1
digitalWrite (I1, HIGH); //Iniciar el giro
digitalWrite (I2, LOW);
}
Explicación: Función que no devuelve ningún valor, función usada para hacer girar un motor de corriente continua a través de un circuito integrado L293.
Los subprogramas se comunican con el programa principal, que es el que contiene a las funciones, mediante parámetros, que estos pueden ser: Parámetros Formales y Parámetros Actuales.
Cuando se da la comunicación los parámetros actuales son utilizados en lugar de los parámetros formales.
Paso de Parámetros a la función por valor
Los parámetros se tratan como variables locales y los valores iniciales se proporcionan copiando los valores de correspondientes argumentos.
Los parámetros formales-Locales de una función reciben como iniciales los valores de los parámetros actuales y con ellos se ejecutan las acciones descritas en el subprograma.
Ejemplo:
Función para controlar la velocidad de giro de un motor de corriente continua, mediante el circuito integrado L293.
void girarMotorDerecha(int velocidad)
{
analogWrite(E1, velocidad); //Activar el motor 1
digitalWrite (I1, HIGH); //Iniciar el giro
digitalWrite (I2, LOW);
}
Explicación: La función no devuelve ningún valor y se le pasa el valor de la velocidad.
Funciones definidas por el usuario en Arduino
Una función, como ya se ha dicho, es un bloque de código dentro del programa que se encarga de realizar una tarea determinada. Por lo tanto un programa en Arduino debe constar de dos o más funciones, y por su puesto no puede faltar la función principal setup() y loop().
Un viejo adagio dice: Separa y vencerás, lo cual se acopla perfectamente cuando tenemos un programa que es bastante grande; podemos separarlos en pequeños subprogramas (funciones), y concentrarnos en la solución por separados de cada uno de ellos y así resolver un gran problemas, en unos cuantos problemitas más pequeños.
Si un programa, está constituido por más de una función, las llamadas a la misma, pueden realizarse desde cualquier parte del programa, y la definición de ellas debe ser independiente unas de otras.
Por lo tanto sería un grave error el tratar de definir una función dentro de otra.
Una función puede ser llamada desde cualquier parte del programa no sólo una vez, y cuando es llamada, empieza a ejecutar las acciones que están escritas en código.
Ejemplos:
- Funciones que no devuelven ningún valor
Ejemplos:
void setup(), void loop()
- Funciones que devuelven un valor entero
Ejemplo:
int leerDistancia(int pinSensor)
- Funciones que devuelven un valor Real
Ejemplo:
float leerLuminosidad(int pinLdr)
Ejemplo: Circuito para controlar la velocidad de giro de un motor de corriente continua en función del valor obtenido por un sensor de ultrasonidos.
Circuito
Código del programa
#define E1 13 // Enable Pin para el motor 1
#define I1 12 // Control pin 1 para el motor 1
#define I2 11 // Control pin 2 para el motor 1
int velocidad=255;
const int EchoPin = 2;
const int TriggerPin =3;
long distanciaAlObjeto;
void setup()
{
pinMode (E1, OUTPUT);
pinMode (I1, OUTPUT);
pinMode (I2, OUTPUT);
pinMode (EchoPin,INPUT);
pinMode (TriggerPin,OUTPUT);
Serial.begin(9600);
}
void loop()
{
distanciaAlObjeto=medirDistancia();
if(distanciaAlObjeto>100)
{
girarMotorDerecha(150);
}
else
{
girarMotorIzquierda(255);
}
}
long medirDistancia()
{
long distancia;
long tiempo;
digitalWrite(TriggerPin,LOW);
delayMicroseconds(5);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
tiempo=pulseIn(EchoPin, HIGH);
return(distancia);
}
void girarMotorDerecha(int velocidad)
{
analogWrite(E1, velocidad); //Activar el motor 1
digitalWrite (I1, HIGH); //Iniciar el giro
digitalWrite (I2, LOW);
}
void girarMotorIzquierda(int velocidad)
{
analogWrite(E1, velocidad); //Activar el motor 1
digitalWrite (I1, LOW); //Iniciar el giro
digitalWrite (I2, HIGH);
}
void pararMotor()
{
digitalWrite (E1, LOW); //Parar el motor 1
}