Microcontroladores son parte de cualquier equipo electrónico moderno, desde radios, celulares, juguetes, equipos industriales, médicos, navegación, control, etc. Conocer y practicar con ellos es muy útil para el desarrollo de sistemas electrónicos. La plataforma Arduino nos permite de una manera fácil, introducirnos en el mundo de los microcontroladores y sus aplicaciones. En este artículos veremos los códigos mas comunes en el mundo de los microcontroladores y Arduino uno. Pulsadores y LEDs son los componentes electrónicos más comunes en cualquier circuito y es importante conocer como se programa con ellos.
Arduino es una plataforma de desarrollo que usa computadores pequeños ( Microcontroladores ) para la creación de equipos electrónicos. Por ser una plataforma abierta ( Open ), esta popularizándose mucho y ha crecido en los últimos años. La Figura 1 muestra la tarjeta o placa de desarrollo de Arduino Uno.
En este artículo vamos a iniciarnos en el mundo de los Microcontroladores de una manera fácil. Para escribir el código es necesario tener instalado la IDE de desarrollo de Arduino (ver Figura 2), la cual se puede bajar del página web de Arduino. Para comenzar, usaremos los programas ejemplos que la propia IDE de desarrollo de Arduino dispone en el Menú Archivo->Ejemplos. Vea Figura 3.
En las siguientes practicas usaremos componentes electrónicos como LEDs y pulsadores (ver Figura 4). Estos componentes serán conectados en los pines de entrada y salida de la tarjeta de desarrollo. En la Figura 5 podemos observar la ubicación de los pines de entrada y salida de la tarjeta de desarrollo. En total son 14 pines que van numerados de '0' hasta '13'. Todos ellos operan a 5 Volts. Cada pin puede proveer o recibir un máximo de 40 miliampères y tienen resistor pull-up interno (desconectado por defecto) de 20-50 kohms.
Para configurar si un pin es salida o entrada usaremos la función pinMode, la cual recibe 2 parámetros. El primero es el número del pin (de 0 hasta 13) y el segundo parámetro si va a ser salida o entrada. Si va a ser salida, en el segundo parámetro escribiremos OUTPUT y si va a ser entrada en el segundo parámetro escribiremos INPUT. Para escribir un nivel alto o bajo en un pin configurado como salida, usaremos la función digitalWrite y para leer el valor de un pin, configurado como entrada, usaremos la función digitalRead.
ENCENDIENDO Y APAGANDO (ON/OFF) UN LED.
Vaya al Menu Archivo->Ejemplos->01.Basics->Blink. En el IDE aparecerá el siguiente código:
// the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second }
En este ejemplo encendemos y apagaremos un LED. La tarjeta de Arduino Uno tiene un LED (built-in) conectado al pin digital 13 que por defecto se llama LED_BUILTIN. Si desea conectar LEDs a otros pines puedes seguir el esquema eléctrico de la Figura 6. Hay que declarar una constante como por ejemplo:
conts int LED_APP 12
para el caso de que el LED esté conectado al pin 12. Varié este número de acuerdo a el pin donde esté conectado el LED en la tarjeta Arduino Uno.
Todas los caracteres que se encuentren después de '//' son comentarios y sirve para indicarnos y recordarnos que hacen determinados tramos o piezas de código. En el código anterior hay 2 funciones llamadas:
setup()
loop()
La función setup() es donde se configura el microcontrolador y solo se ejecuta una vez, cuando la placa es alimentada por una fuente de voltaje o cuando ejecutamos un reset. Esta función es muy similar al BIOS ( Basic Input Output Setup ) de los computadores personales. En esta función programamos las entradas y salidas del microcontrolador.
La función loop() como su nombre lo indica es un bucle que se repite indefinidamente y es donde se escribe el programa principal. La Figura 7 muestra el diagrama de flujo para las función setup() y loop(). Podemos observar que la función setup() se ejecuta en el inicio y la función loop se repite indefinidamente.
La función setup es:
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
Dentro de la función setup(), se llama la función pinMode(LED_BUILTIN, OUTPUT); Esta función le dice al microcontrolador que el LED va a ser configurado como salida.
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
Dentro de la función loop(), se llama la función digitalWrite(LED_BUILTIN, HIGH); Esta función escribe un '1' lógico o nivel alto en el pin del LED. En electrónica digital los niveles altos se representan por un voltaje de 5V. La función loop(), también llama la función delay(1000); la cual retarda el funcionamiento del microcontrolador por la cantidad de milisegundos que se especifique dentro de los paréntesis de la función. Para el caso del ejemplo anterior, estamos retardando al microcontrolador por 1000 milisegundos o 1 segundo. Después, usamos la función digitalWrite(LED_BUILTIN, LOW); que coloca a '0' lógico o nivel bajo el pin del LED. En electrónica digital un nivel bajo se representa con 0 voltios o tierra (GROUND). Después volvemos a tener un retardo de 1 Segundo.
Así, el programa se repite continuamente y podemos observar como el LED prende y apaga continuamente. Si se alteran los valores del parámetro de la función delay(); se puede ver el cambio de parpadeo en el LED. Este programa aunque básico es importante entenderlo bien, pues todos los programas siguen la misma regla, por complejos que sean. La Figura 8 muestra el diagrama de flujo para el ejemplo anterior.
CONECTANDO UN PULSADOR ( PUSHBUTTON ) AL MICROCONTROLADOR.
En esta práctica conectaremos un pulsador a un pino del microcontrolador configurado como entrada digital. El código ejemplo puede ser encontrado en la IDE, en el Menú: Archivo->Ejemplos->02.Digital->Button.
// constants won't change. They're used here to set pin numbers: const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin // variables will change: int buttonState = 0; // variable for reading the pushbutton status void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); // initialize the pushbutton pin as an input: pinMode(buttonPin, INPUT); } void loop() { // read the state of the pushbutton value: buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn LED on: digitalWrite(ledPin, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); } }
En el inicio del programa definimos 2 constantes enteras, es decir que estos valores no van a cambiar durante la ejecución del programa. Para esto es usada la palabra const, como se muestra en las siguientes líneas de código:
const int buttonPin = 2;
const int ledPin = 13;
Ya en la función setup(), configuramos el pin 13 como salida digital y el pin 2 como entrada digital, como se ve en el código:
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
La función pinMode(ledPin, OUTPUT); le dice al microcontrolador que el pino ledPin (13) será configurado como salida (OUTPUT) y la función pinMode(buttonPin, INPUT); le dice al microcontrolador que el pin buttonPin ( pino 2 ) será configurado como entrada digital (INPUT). El hardware para este ejemplo es mostrado en la Figura 9, donde podemos notar que el pulsador entra en el pino 2. Es necesario conectar una resistencia de 10 kOhms a 5 volts (pull-up), para polarizar a positivo la entrada, cuando el pulsador no está presionado.
También declaramos una valor variable buttonState, es decir que su valor o contenido va a ser modificado por el programa. La siguiente línea de código muestra y declara la variable para el compilador:
int buttonState = 0;
El codigo para la función loop() de este ejemplo es:
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}
En la función loop() usamos la función digitalRead(buttonPin); para leer el pin de entrada digital buttonPin y almacenamos este valor en la variable buttonState. Después, el código verifica si este valor es alto (HIGH) para lo cual usamos la instrucción if (buttonState == HIGH) . Caso el valor sea alto, ejecutaremos la función digitalWrite(ledPin, HIGH); o caso buttonState sea bajo, será ejecutada la función digitalWrite(ledPin, LOW);. Así, leyendo una entrada digital, podemos controlar salidas (actuadores) o ejecutar algún otro código. La Figura 10 muestra el diagrama de flujo para la lectura del pulsador.
PWM PARA SUBIR Y BAJAR LA INTENSIDAD LUMINOSA DE UN LED.
Los pinos 3, 5, 6, 9, 10 y 11 de la tarjeta Arduino Uno pueden ser usados como salidas analógicas PWM. En total hay 6 pinos con PWM en la tarjeta de Arduino Uno. La Figura 11 muestra estos pineo. Note, que en la placa estas salidas son marcadas con el símbolo ~ antes del número, indicando salidas PWM. El microcontrolador ATmega328P usado en la placa Arduino tiene 3 timer. Cada timer tiene 2 módulos comparadores de salida que normalmente son usado para generar señales PWM. En la Figura 12 podemos observar el Timer 0 del microcontrolador.
El código ejemplo para esta práctica puede ser encontrado en Archivo->Ejemplos->01.Basics->Fade. La idea principal es subir y bajar la intensidad luminosa del LED usando PWM ( Pulse Width Modulator ). El código de este ejemplo es:
int led = 9; // the PWM pin the LED is attached to int brightness = 0; // how bright the LED is int fadeAmount = 5; // how many points to fade the LED by // the setup routine runs once when you press reset: void setup() { // declare pin 9 to be an output: pinMode(led, OUTPUT); } // the loop routine runs over and over again forever: void loop() { // set the brightness of pin 9: analogWrite(led, brightness); // change the brightness for next time through the loop: brightness = brightness + fadeAmount; // reverse the direction of the fading at the ends of the fade: if(brightness <= 0 || brightness >= 255) { fadeAmount = -fadeAmount; } // wait for 30 milliseconds to see the dimming effect delay(30); }
PWM es una técnica de modulación de ancho de pulso que puede ser usada para controlar la intensidad de corriente que circula por un circuito muy similar a como lo hacen los potenciómetros en un dimmer. Para hacer esto podemos usar la función analogWrite la cual recibe 2 parámetros. El primer parámetro es el pin a controlar y el segundo parámetro es la cantidad de tiempo que el pin permanecerá en nivel alto (ON). La Figura 13 muestra como el segundo parámetro actúa sobre el pin que está controlando. Como los pulsos son repetidos rápidamente (aproximadamente 500 Hz), el ojo humano no percibe su cambio, pero al ser variado el ancho del pulso, da la sensación óptica de subir y bajar la intensidad del LED. El hardware necesario para esta práctica lo podemos ver en la Figura 14. Note que el LED es conectado al pin 9.
En el comienzo del programa declaramos 3 variables como sigue:
int led = 9;
int brightness = 0;
int fadeAmount = 5;
La variable led es el pin donde vamos a conectar el LED. La variable brightness almacena el valor para el brillo del LED y la variable fadeAmount es usada para alterar el brillo.
En la función setup() configuramos el pin led como salida para lo cual tenemos el siguiente código:
void setup() {
pinMode(led, OUTPUT);
}
En la función loop() usamos la funcion analogWrite(led, brightness); para colocar un valor de ancho de pulso en la salida PWM. Después sumamos un fadeAmount a la variable brightness para incrementar su valor en forma escalar. Después detectamos si la variable brightness es mayor o igual a 255 y reversamos la variable fadeAmount para revertir el efecto de brillo. Finalmente damos un retado de 30 mili segundos. En la Figura 15 podemos ver el diagrama de flujo para esta práctica. El código para función loop() es el siguiente:
void loop() { analogWrite(led, brightness); brightness = brightness + fadeAmount; if (brightness <= 0 || brightness >= 255) { fadeAmount = -fadeAmount; } delay(30); }
Así, por medio de líneas de código podemos interactuar con el mundo exterior, es decir podemos leer señales (entradas, sensores) y podemos evaluar estos valores para tomar decisiones sobre salidas, normalmente llamadas actuadores. La imaginación es la indicadora que puede utilizar estos recursos para crear diseños y equipos electrónicos.