Programar fácil con Arduino

Programar fácil con Arduino, entiende cómo funciona el mundo.

  • Inicio
  • Cursos
  • Blog
  • Podcast
  • ¿Quién soy?
  • Contactar
  • Acceder
Usted está aquí: Inicio / Blog / Arduino / Interrupciones con Arduino a través de un ejemplo práctico

Interrupciones con Arduino a través de un ejemplo práctico

Comentarios(6)
Luis del Valle Hernández

Los microcontroladores Atmel incorporan un mecanismo que en muchas ocasiones es desconocido por todos nosotros. Las interrupciones con Arduino nos permitirán reaccionar a eventos externos a la placa de una forma rápida. Cuando se detecta una señal, una interrupción, interrumpe el proceso que se está ejecutando. Esto nos va a permitir dos cosas. Por un lado, ejecutar rápidamente un trozo de código, y por otro lado parar la ejecución del código que se estaba ejecutando.

Por ejemplo, imagínate que quieres cocinar una pizza en el horno. Lo típico es que calientes el horno a una determinada temperatura, metas la pizza y programes el reloj durante 25 minutos. Mientras, te vas a ver la televisión. Cuando el reloj termina la cuenta atrás, suena un timbre e interrumpes de ver la televisión para atender al horno. Sacas la pizza del horno, te la llevas al salón y sigues viendo la televisión. Esto sería un ejemplo de la vida real de cómo funcionan las interrupciones.

Las interrupciones no son simplemente para cambiar y hacer algo diferente. Por ejemplo, estamos montando en bicicleta llegamos a casa y guardamos la bici en el garaje o un botón es pulsado por el usuario y permite parar el DFRobot. En estos dos casos no interrumpimos una acción, pasamos a hacer algo diferente. Terminamos de hacer una cosa y hacemos otra. En el caso del botón, lo máximo que podemos hacer es recordar el estado de botón pulsado. Debemos utilizar las interrupciones para lo que son, interrumpir lo que se está ejecutando y realizar otra tarea, para luego volver al mismo sitio donde lo habíamos dejado.

Dentro de la gama de interrupciones con Arduino están las interrupciones programadas y las interrupciones externas. La filosofía es la misma, poder ejecutar un código cuando sucede un evento concreto. En el caso de las interrupciones programadas, el evento se disparará cada cierto intervalo de tiempo que debemos de configurar. Este tipo de interrupciones no es el objeto de este artículo. Si quieres saber más puedes ver la referencia de la librería TimerOne que se encarga de configurar y gestionar este tipo de interrupciones.

El otro tipo de interrupciones, las externas, nos permite reaccionar a eventos externos. Un evento puede ser que se pulsa un botón, o que un sensor capta cierta información.

Indice de contenidos

  • 1 Por qué utilizar interrupciones con Arduino
  • 2 Cómo utilizar interrupciones con Arduino
  • 3 Ejemplo práctico: controlando la velocidad de las luces del coche fantástico

Por qué utilizar interrupciones con Arduino

Utilizar interrupciones nos permitirá olvidarnos de controlar ciertos pines. Esto muy importante ya que dentro de una aplicación o programa, no vamos a hacer una única cosa. Por ejemplo, queremos que un LED se encienda o se apague cuando pulsamos un botón. Esto es realativamente sencillo pero cuando además queremos que otro LED parpadee, la cosa se complica.

La probabilidad de capturar el evento cuando se pulsa el botón disminuye con el aumento de tiempo de parpadeo. En estos casos, y en muchos otros, nos interesa liberar el procesador de Arduino para que solo cuando se pulse el botón, haga una acción determinada. Así no tendremos que estar constantemente comprobando el pin X si ha pulsado el botón.

Precisamente este es el sentido de las interrupciones, poder hacer otras cosas mientras no suceda el evento, pero cuando ese evento externo esté presente, que ejecute rápidamente el código asociado.

Internamente, Arduino (mejor dicho el microcontrolador AtMega) tiene ciertas interrupciones configuradas que lanza según la situación. Para la transmisión de datos a través del puerto serie, para resetear la placa antes de cargar un programa, comunicación I2C, etc…

En este caso, nosotros mismos crearemos nuestras propias interrupciones asociadas a ciertos pines según el tipo de placa.

Cómo utilizar interrupciones con Arduino

Dentro de la placa de Arduino encontramos diferentes pines que nos permiten tener interrupciones. Dependerá del tipo de placa.

PlacaPines interrupciones
Uno, Nano, Mini2, 3
Mega, Mega2560, MegaADK2, 3, 18, 19, 20, 21
Micro, Leonardo0, 1, 2, 3, 7
ZeroTodos los pines digitales excepto el 4
MKR10000, 1, 4, 5, 6, 7, 8, 9, A1, A2
Due, 101Todos los pines digitales

Para poder utilizar interrupciones con Arduino no necesitamos incorporar ningún tipo de librería a nuestro programa. Únicamente necesitamos hacer referencias a ciertas funciones o métodos. Ahora veremos cuales son.

attachInterrupt(pin, ISR, modo)

Esta función nos va a permitir definir o configurar uno de los pines como un puerto de interrupción. Los tres parámetros que admite son:

  • pin: debemos llevar especial cuidado con este parámetro. Indica que pin vamos a utilizar como interrupción. No debemos pasar el número de pin, debemos pasar el ordinal es decir, si trabajamos con Arduino UNO tenemos dos pines para interrupciones el 2 y el 3. Si queremos utilizar el 2 debemos poner un 0 y si queremos utilizar el 3 debemos poner un 1. Esto se resuelve muy fácilmente utilizando otra función, digitalPinToInterrupt(pin), que devuelve el ordinal del pin que queremos utilizar. En este caso si que debemos pasar su número. Por ejemplo, en el caso anterior, si queremos utilizar el pin 2 llamaríamos a la función digitalPinToInterrupt(2). Esto nos devolverá un 0 y es el método recomendado por Arduino para pasar este parámetro.
  • ISR: es una abreviatura de Interrupt Service Routine y no es más que la función o método que se llama cuando se produce la interrupción. Es de un tipo particular ya que no admite parámetros y tampoco devuelve ningún valor.
  • modo: define cuando debe ser disparada la interrupción. Puede tomar cuatro valores constantes dependiendo de lo que queramos hacer:
    • LOW: se lanzará la interrupción cuando el pin esté en estado bajo.
    • CHANGE: se lanzará la interrupción cuando el pin cambie de valor de alto a bajo, o de bajo a alto.
    • RISING: se lanzará la interrupción cuando el pin cambie de estado de bajo a alto.
    • FALLING: se lanzará la interrupción cuando el pin cambie de estado de alto a bajo.
    Existe un quinto estado que solo los Arduino Due, Zero y MKR1000 permiten:
    • HIGH: se lanzará la interrupción cuando el pin esté en estado alto.
Modos interrupciones

detachInterrupt(pin)

Si attachInterrupt() nos permite configurar un pin como interrupción, el método detachInterrupt() anula esa configuración. Como parámetro le pasamos el pin y lo podemos hacer con la función digitalPinToInterrupt(número de pin) que nos devolverá el ordinal del pin del que queremos anular la configuración.

Ejemplo práctico: controlando la velocidad de las luces del coche fantástico

La mejor manera de aprender es poniendo en práctica lo aprendido en la teoría. Para ello lo que vamos a hacer es el típico sketch con las luces del coche fantástico. En este caso vamos a controlar la velocidad con la que se mueve a través de dos pulsadores.

Circuito eléctrico

Vamos a necesitar el siguiente material:

  • 2 LEDs verdes
  • 3 LEDs rojos
  • 5 resistencias de 470 Ω
  • 2 pulsadores
  • 1 resistencia de 1 kΩ
  • Arduino UNO
  • Protoboard
  • Cables macho/macho

Cada pulsador irá conectado a un pin y tendrán una resistencia pull-down. Esto hará que en estado normal, sin pulsar, el pin tengamos un estado bajo. Cuando el pulsador se active tendremos un estado alto. Por lo tanto debemos de detectar un cambio de estado de bajo a alto (RISING).

Por otro lado, los LEDs van a hacer una secuencia de encenderse y apagarse de izquierda a derecha y de derecha a izquierda. Simula las luces del coche fantástico. Empezaremos con una velocidad y según vayamos pulsando los pulsadores se irá aumentando o disminuyendo la velocidad.

El esquema eléctrico es el siguiente.

Luces del coche fantástico con Arduino

Programación del sketch de interrupciones con Arduino

La primera parte es la declaración de contantes y variables. En este punto hay que hacer una aclaración. Cuando trabajamos con interrupciones con Arduino, hay que llevar especial cuidado con los métodos ISR que se van a ejecutar cuando se produce el evento.

En general, debemos hacer métodos o funciones ISR lo más cortas y rápidas posibles. Se puede producir un bloqueo entre los diferentes ISR. Lo que sucede en estos casos es que solo se ejecuta una a la vez quedando en cola el resto de interrupciones.

Dentro de las interrupciones no funciona el delay() (retardo) por lo tanto no lo utilices. Recuerda que se trata de ejecutar un código lo más rápido posible. Si quieres hacer que el proceso se pare dentro de un ISR utiliza la función delayMicrosends(), ya que funciona con normalidad.

Las variables que vayamos a utilizar tanto dentro de los métodos ISR como fuera, ya sea en el loop() o en cualquier otra función, debemos declararlas como volatile. Esta palabra reservada le dice al compilador que estas variables pueden cambiar de valor en cualquier momento y, por lo tanto, el compilador debe volver a cargar la variable cada vez que se hace referencia en algún sitio a ella. Al contrario que ocurre con otras variables donde el compilador confía en alguna copia que pueda tener en algún registro del procesador.

Sketch luces del coche fantástico con interrupciones

Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
  Creado: Luis del Valle ([email protected])
  https://programarfacil.com
 
  Compártelo a todo el mundo :)
*/
 
// Variable global de velocidad
volatile int velocidad = 20;
// Constantes de velocidad máxima, mínima y cuanto aumenta
const int maxima = 1000;
const int minima = 20;
const int aumenta = 20;
 
// Array con los números de los pines donde están conectados
// los LEDs de las luces del coche fantástico
int leds[5] = {8, 9, 10, 11, 12};
 
void setup() {
  // Inicializamos los pines de los LEDs como salida y a estado bajo
  for (int i = 0; i < 5; i++)
  {
    pinMode(leds[i], OUTPUT);
    digitalWrite(leds[i], LOW);
  }
 
  // Asignamos la velocidad mínima
  velocidad = minima;
 
  // Configuramos los pines de interrupciones para que
  // detecten un cambio de bajo a alto
  attachInterrupt(digitalPinToInterrupt(2), velocidadMenos, RISING);
  attachInterrupt(digitalPinToInterrupt(3), velocidadMas, RISING);
 
}
 
void loop() {
  // Este primer bucle recorre el array de izquierda a derecha
  for (int i = 0; i < 5; i++)
  {
    // Solo para el segundo pin y consecutivos apagamos el pin anterior
    // En el caso de 0 no hace falta ya que por defecto está apagado
    // Cuidado que nos salimos del rango del array 0-1=-1 no existe este elemento
    if (i > 0)
    {
      // Apagamos el LED a la izquierda
      digitalWrite(leds[i - 1], LOW);
    }
 
    // Encendemos en el LED en el que estamos
    digitalWrite(leds[i], HIGH);
 
    // Esperamos el tiempo marcado por velocidad
    delay(velocidad);
  }
 
  // Apagamos el último LED encendido, el elemento 5 del array
  digitalWrite(leds[4], LOW);
 
  // Recorremos el array en sentido inverso de derecha a izquierda
  for (int i = 4; i >= 0; i--)
  {
    // En el primer caso como ya está apagado el LED no hacemos nada
    // Cuidado que nos salimos del rango del array 4+1=5 no existe este elemento
    if (i < 4)
    {
      // Apagamos el LED a la derecha
      digitalWrite(leds[i + 1], LOW);
    }
    // Encendemos en el LED en el que estamos
    digitalWrite(leds[i], HIGH);
 
    // Esperamos el tiempo marcado por velocidad
    delay(velocidad);
  }
 
  // Apagamos el último LED encendido, el elemento 0 del array
  digitalWrite(leds[0], LOW);
 
}
 
// ISR pin 2, disminuye la velocidad
void velocidadMenos()
{
  // Disminuimos el valor establecido
  velocidad = velocidad - aumenta;
 
  // Si hemos llegado a la velocidad mínima no disminuímos más
  if (velocidad < minima)
  {
    velocidad = minima;
  }
}
 
// ISR pin 3, aumenta la velocidad
void velocidadMas()
{
  // Aumentamos el valor establecido
  velocidad = velocidad + aumenta;
 
  // Si hemos llegado a la velocidad máxima no aumentamos más
  if (velocidad > maxima)
  {
    velocidad = maxima;
  }
}


Y hasta aquí el artículo donde hemos visto las interrupciones con Arduino. Es muy importante conocer muy bien esta técnica ya que nos ahorrará mucho trabajo en ciertas ocasiones.

curso programacion de arduino desde cero

Tutoriales de Arduino


Curso de Arduino
Proyectos con Arduino
Arduino UNO R3
Arduino MEGA 2560
Servomotor con Arduino
Sensor de temperatura DHT11
Sensor temperatura Arduino
Tutorial pulsadores
Tutorial RTC reloj Arduino
Tutorial potenciómetro Arduino
Tutorial display 7 Arduino
Tutorial motor paso a paso Arduino
Tutorial librerías Arduino
Tutorial ultrasonidos Arduino
Tutorial I2C Arduino
Tutorial consumo Arduino
Tutorial weareable Arduino
Tutorial interrupciones Arduino
Tutorial ADS1115 ADC Arduino
Tutorial pilas Arduino
Tutorial riego Arduino
Arduino Shield EchidnaShield
Tutorial if else Arduino

Tutoriales ESP8266


Introducción ESP8266
Tutorial NodeMCU
IDE Arduino NodeMCU
Tutorial ESP-01
Relé WiFi Sonoff

Tutoriales IoT


Proyectos IoT con Arduino
MQTT ESP8266 Raspberry Pi
Redes LPWAN Arduino
IFTTT Arduino
Geolocalización Arduino
Arduino MKRFOX1200 Sigfox
Tutorial Node-RED

Tutoriales Visión Artificial


Instalación OpenCV y Python
Introducción Vision Artificial
Detección movimiento OpenCV
Introducción OpenCV
Qué es Machine Learning
Sensor Kinect
Realidad Aumentada
Detector Canny OpenCV
Big Data Visión Artificial
Kinect y Processing
Deep Learning

Tutoriales Raspberry Pi


Tutorial Raspberry Pi
Proyectos Raspberry Pi
Vídeo Raspberry Pi
Servidor web Raspberry Pi
Servidor Raspberry Pi
Flask Raspberry Pi
Monitor bebé Raspberry Pi

Podcast


Entrevista Obijuan
Entrevista BricoGeek
Entrevista David Cuartielles
Entrevista Rinconingenieril
Entrevista Staticboards
Entrevista La Hora Maker
Entrevista OSHWDem
Entrevista Colepower
Entrevista Aprendiendoarduino
Entrevista BitFab
Protocolo i2c imagen destacada

Comunicación I2C con Arduino lo mejor de dos mundos

El protocolo de comunicación I2C con Arduino es ampliamente utilizado en multitud de sensores y actuadores. Esto se debe principalmente a dos … [+ info...]

Introducion-a-git-y-git-hub-github tutorial paso a paso

Git y GitHub tutorial paso a paso

¿Qué es Git y GitHub? En este artículo vas a entender cómo utilizar Git y GitHub, la famosa red social del código basada en Git, orientada a … [+ info...]

Arduino IDE entorno de desarrollo oficial

El entorno de desarrollo integrado Arduino IDE representa el software básico ideal para principiantes y expertos. Cuando decides implementar un … [+ info...]

Copyright © 2021 · Programar Fácil · Aviso legal

Utilizamos cookies propios y de terceros para mejorar nuestros servicios y experiencia de usuario. Si continua navegando, consideramos que acepta su uso.Aceptar Política de privacidad y cookies
Política de cookies

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necesarias
Siempre activado

Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.

No necesarias

Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.

close

Te ayudo a dar los primeros pasos con Arduino

Si quieres aprender programación de electrónica con Arduino utilizando un método serio, prueba el curso que te ofrezco.


Es muy sencillo, te apuntas en este formulario y accedes a los 3 primeros módulos.


Que te gusta, sigues con el curso completo.


Que no te gusta, sin problema, te das de baja y tan amigos.


Solo para gente seria que esté cansada de copiar y pegar código sin saber lo que hace.

x