|     Inicio    |   |         |  |   FOROS      |  |      |      
   Elastix - VoIP B4A (Basic4Android) App inventor 2 PHP - MySQL
  Estación meteorológica B4J (Basic4Java) ADB Shell - Android Arduino
  AutoIt (Programación) Visual Basic Script (VBS) FireBase (BD autoactualizable) NodeMCU como Arduino
  Teleco - Emisora de A.M. Visual Basic Cosas de Windows Webs interesantes
T Búsqueda en este sitio:


.

Arduino en español
Circuitos con Arduino - Juan Antonio Villalpando

-- Tutorial de iniciación a Arduino --

Volver al índice del tutorial

___________________________

18.- Interrupciones.

Una interrupción es una señal que algún dispositivo le envía a cierto terminal del microprocesador, para que deje de realizar la parte del código que está ejecuando y realice otra distinta.

Imaginamos que se está realizando la parte del programa del bucle loop, en cierto momento un elemento externo, un interruptor, un sensor,... envía una señal al microprocesador por un terminal. El microprocesador deja la parte del código que estaba haciendo y va a otra rutina donde está el código que debe hacer cuando esa interrrupción se activa.

La señal de interrupción puedes ser:
poner a LOW el terminal,
o el terminal que estaba en LOW pasa a HIGH,
o estaba en HIGH y pasa a LOW
o que CAMBIE el terminal de LOW a HIGH
o viceversa.
Esto se configura en el programa.

Vamos a realizar este circuito con este código.

Código
/*
  Juan A. Villalpando
  kio4.com
  agosto 2015
 */

#define pin2 2 
#define pin3 3
#define LED13 13
int boton2, boton3;

// En el setup establecemos los parámetros iniciales.
void setup() {
  pinMode(pin2, INPUT);
  pinMode(pin3, INPUT);
  pinMode(LED13, OUTPUT);
}

void loop() {
  boton2 = digitalRead(pin2);
  boton3 = digitalRead(pin3);
  if (boton2 == HIGH) { digitalWrite(LED13, HIGH);} 
  if (boton3 == HIGH) { digitalWrite(LED13, LOW);} 
}

- Fíjate, he puesto cada los códigos de if en una sola línea cada uno.

- Si pulsas el botón2 se enciende el LED13
- Si pulsas el botón3 se apaga el LED13

Pero... ¿cómo funciona?

- Se declaran los valores, se configuran en el inicio y se entra en un bucle loop, de tal manera que el programa está realizando contínuamente el bucle recorriendo las instrucciones que tiene en su interior de arriba abajo y volviendo arriba.

En este caso dentro del bucle se está consultando si está pulsado el botón1 y el botón2. Es una consulta por software, por programa.

Es lo que se llama "bucle infinito". Este bucle continuará hasta que se cierre el programa.

La mayoría de los programas que hemos visto y que veremos funciona de esta manera, un blucle loop y dentro intrucciones que se repiten contínuamente de arriba abajo.

__________________________________

- Interrupciones.

Adapto el ejemplo anterior a las interrupciones.

Arduino UNO tiene dos terminales para realizar interrupciones, el 2 y el 3 (por eso en el ejemplo anterior tomé esos terminales).

A la interrupción provocada por el terminal 2 se denomina interrupción: 0
A la interrupción provocada por el terminal 3 se denomina interrupción: 1

- Pero en vez de utilizar el 0 y el 1 para indicar el terminal correspondiente a la interrupción, es mejor darle un nombre al pin y luego poner digitalPinToInterrupt

#define INT3 3 // En vez de poner 1
volatile byte cambia = LOW;

(...)

attachInterrupt(digitalPinToInterrupt(INT3), cambiaLED, FALLING);

-----------------------------------------------------------------------------------------

(Los Arduinos Mega2560 y el Leonardo, tienen más terminales para interrupciones).

Utilizo el mismo circuito anterior, pero cambio el código...

Código
/*
  Juan A. Villalpando
  kio4.com
  agosto 2015
 */

#define LED13 13

void setup()
{
  attachInterrupt(0, enciende, RISING); // 0 es la interrupción 0, es decir el terminal 2
  attachInterrupt(1, apaga, RISING);    // 1 es la interrupción 1, es decir el terminal 3
  pinMode(LED13, OUTPUT);
}

void loop()
{
  // Aquí puede haber otro código,
  // o, como en este caso, estar vacío.
}

  // Las rutinas de las interrupciones se llaman ISR.

void enciende() // Cuando hay interrupción 0 (terminal 2), actúa esta rutina.
{
   digitalWrite(LED13, HIGH);
}

void apaga()  // Cuando hay interrupción 1 (terminal 3), actúa esta rutina.
{
   digitalWrite(LED13, LOW);
}

- En esta caso no hay código en el bucle. El bucle no está consultando los botones.

- Es el mismo microcontrolador el que está consultando el estado de los terminales 2 y 3 que en este caso están configurado como interrupciones. Es una consulta por hardware.

- Se ha establecido la interrupción 0 (que es el terminal 2) como RISING, de manera que cuando este terminal sube de "low a high", se produce una interrupción que desvía el programa a la rutina de interrupción: encendido.

- Se ha establecido la interrupción 1 (que es el terminal 3) como RISING, de manera que cuando este terminal sube de "low a high", se produce una interrupción que desvía el programa a la rutina de interrupción: apagado.

Prueba otras posibilidades en vez del RISING, LOW, CHANGE, FALLING. (HIGH solo funciona con Arduino Due).

____________________________________
- Interrupción por sensor LDR.

- En este caso el LED13 parpadea lentamente (1000) cuando hay oscuridad.
- Cuando hay mucha iluminación, entra en funcionamiento la interrupción y establece el tiempo en 300, el LED13 parpadeará rápido.

- El funciomamiento de este circuito depende de la luminosidad externa, del valor de R. En mi caso le aplico una la luz de una linterna para que realice la interrupción.

- Fijate que la LDR no está conectada a una entrada Analógica, ya que solo queremos saber si el nivel del punto D3 es ALTO o BAJO, no queremos medir el valor resistivo como lo hicimos en otro tutorial.

- La caída de nivel de alto a bajo en D3 provocará la interrupción.

____________________

- Cuando hay iluminación "normal", en D3 tenemos 3 voltios (es nivel ALTO).
- Cuando oscurecemos más, en D3 tenemos 4 voltios (es nivel ALTO).

- Cuando ilumino la LDR con una linterna, en D3 tenemos 1 V (BAJO).

- Cuando D3 cae de ALTO a BAJO (FALLING), se produce la interrupción.

- La interrupción cambia el tiempo a 300.

- Para volver a tener el tiempo a 1000, pulsamos el pulsador.

Código
/*
  Juan A. Villalpando
  kio4.com
  agosto 2015
 */

#define LED13 13
#define pin2 2 // Actúa como pin normal
int boton2;
volatile int tiempo=1000;

void setup()
{
  attachInterrupt(1, rapido, FALLING);  // 1 es la interrupción 1, es decir el terminal 3
// FALLING significa que cae de un nivel alto oscuridad = 3 V, a un nivel bajo iluminado = 1 V
  pinMode(pin2, INPUT);
  pinMode(LED13, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  digitalWrite(LED13,HIGH);
  delay(tiempo);
  digitalWrite(LED13,LOW);
  delay(tiempo);
  Serial.println(tiempo);
  boton2 = digitalRead(pin2);
  if (boton2 == HIGH) { tiempo=1000;} 
}

void rapido()  // Cuando hay interrupción 1 (terminal 3), actúa esta rutina.
{
   tiempo=300;
}

____________________________________
Elementos que tienen interrupciones.

- Consulta el tutorial del giroscopio.

- Consulta el tutorial del sensor de inclinación.

____________________________________
- Limitaciones de las interrupciones
.

- Las rutinas de las interrupciones se denominan ISR (Interrupt Service Routine)

- Dentro de la rutina de la interrupción no funciona delay ni millis.

- Es conveniente que la rutina tenga pocas instrucciones para que se realice rápido.

- No poner Serial.print

- Pueden haber variables comunes en la rutina y en el resto del código, es conveniente declarar esas variables como volatile.

- Referencia en la web de Arduino:

https://www.arduino.cc/en/Reference/AttachInterrupt

Typically global variables are used to pass data between an ISR and the main program.
To make sure variables shared between an ISR and the main program are updated correctly, declare them as volatile.

____________________________________
- Nombre de los terminales de las interrupciones
. digitalPinToInterrupt( )

- Antes he comentado que en el Arduino UNO las interruciones son los terminales 2 y 3, que a su vez de denominan 0 y 1 en el código.

- Puede ocurrir que tengamos otro tipo de Arduino donde los terminales de interrupciones no sean los terminales 2 y 3.

- Así que hay otra manera de denominar los terminales que son interrupciones en el Arduino.

- Mediante: digitalPinToInterrupt( )

- Este código que indico no funciona, solo lo he puesto para indicar la manera de configurar los terminales mediante digitalPinToInterrupt( )

jEjemplo_terminales_int.ino

// Juan A. Villalpando.
// Abril 2018. KIO4.COM

  // Interrupciones.
#define INT2 2 // Terminal 2 del Arduino 
#define INT3 3 // Terminal 3 del Arduino
  volatile byte cambia1 = LOW;
  volatile byte cambia2 = LOW;

 
void setup(){
  Serial.begin(9600);
   // Establecimiento de la INTerrupcion.
pinMode(INT2, INPUT_PULLUP); pinMode(INT3, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(INT2), cambiaLED12, FALLING); attachInterrupt(digitalPinToInterrupt(INT3), cambiaLED13, FALLING); } void loop(){ digitalWrite(LED7, cambia1); // Interrupcion. digitalWrite(LED8, cambia2); // Interrupcion. } // FIN loop. ///////////// FUNCIONES /////////////////////////// ///// Interrupciones /////////////////////////// void cambiaLED12() { cambia1 = !cambia1; } void cambiaLED13() { cambia2 = !cambia2; }

__________________________________
- Propuestas

- Sensor de inclinación.

- Consulta el sensor de inclinación y realiza un código de interrupción.

- Adapta el código a la utilización de digitalPinToInterrupt( )

__________________________________
- Escribir y Leer información en la EEPROM del Arduino.

- Hola, esto no sabía donde ponerlo y lo puse aquí.

- Se trata de grabar informacion en la EEPROM del Arduino para más tarde recuperarla.

- Está basado en este tutorial...

http://www.instructables.com/id/Save-values-in-your-Arduinos-permanent-memory/

----------- Escribir

#include <EEPROM.h>

void setup() {
//EEPROM.write(ADDRESS,VALUE);

int MyVal=255;
EEPROM.write(0,77);
EEPROM.write(1,65);
EEPROM.write(2,82);
EEPROM.write(3,84);
EEPROM.write(4,73);
EEPROM.write(5,78);
}

------------ Leer

#include <EEPROM.h>

int MemoryAddr=0;
int Value=0;

void setup() {

Serial.begin(38400);
}

void loop() {
for (int MemoryAddr=0; MemoryAddr <= 5; MemoryAddr++) {
value = EEPROM.read(MemoryAddr);
char MyCharacter = char(value);
Serial.println(MyCharacter);
}
delay(5000);
}

________________________________

- Mi correo:
juana1991@yahoo.com
- KIO4.COM - Política de cookies. Textos e imágenes propiedad del autor:
© Juan A. Villalpando
No se permite la copia de información ni imágenes.
Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación y realizan análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. Acepto    Más información