En este proyecto vamos a utilizar el módulo KY-022 y 9 LED con el Arduino, donde vamos a controlar 9 LED según el número que presionemos en el control. Para este ejemplo vamos a utilizar uno de estos kit que traen el módulo KY-022 y el control remoto.
En el proyecto anterior aprendimos a capturar los valores enviados por un control remoto infrarrojo e interactuar con estos valores. Este proyecto consta de dos partes, la primera es para aprender a capturar el código hexadecimal del comando y en la segunda vamos a hacer que nuestro Arduino haga algo cuando presionemos algunos de estos botones, este es un código bastante sencillo y muy fácil de implementar.
Módulo KY-022
El módulo KY-022 está compuesto por un receptor infrarrojo VS1838B, su resistencia (1KΩ) y un LED, que nos indica cuando ha captado una señal IR y sus 3 conectores (GND, VCC, Señal). Este es un módulo receptor infrarrojo que podemos utilizar para recibir señales de controles remotos u otros proyectos. Este receptor esta sincronizado para solo detectar señales en el espectro de 38KHz e ignorar cualquier otra frecuencia.
Especificaciones:
- Voltaje de operación: 2.7 – 5.5V
- Consumo de corriente: 0.4mA ~ 1.5mA
- Distancia Máxima: ~18m
- Frecuencia: 38KHz
- Angulo de recepción: ±45°
- Voltaje de bajo nivel: 0.4 Volts
- Voltaje de alto nivel: 4.5 Volts
- Filtro de luz ambiente: > 500 LUX
Control Remoto
Para este proyecto utilizamos un Kit que viene con el control y con el módulo de receptor infrarrojo, pero puede ser cualquier control remoto de infrarrojos, inclusive el del TV. En el proyecto anterior utilizamos otro control similar que usaba el protocolo NEC también.
El control que utilizaremos en este proyecto utiliza el protocolo NEC, es uno de los mas comunes, en el proyecto que hoy vamos a realizar no vamos a discriminar por el protocolo.
Ya me he tomado la molestia de registrar todos lo botones del control en la siguiente tabla
Tecla | Dirección Hexadecimal | Comando Hexadecimal | Dato 32 Bits Hexadecimal |
1 | 0x00 | 0x45 | 0xBA45FF00 |
2 | 0x00 | 0x46 | 0xB946FF00 |
3 | 0x00 | 0x47 | 0xB847FF00 |
4 | 0x00 | 0x44 | 0xBB44FF00 |
5 | 0x00 | 0x40 | 0xBF40FF00 |
6 | 0x00 | 0x43 | 0xBC43FF00 |
7 | 0x00 | 0x7 | 0xF807FF00 |
8 | 0x00 | 0x15 | 0xEA15FF00 |
9 | 0x00 | 0x9 | 0xF609FF00 |
* | 0x00 | 0x16 | 0xE916FF00 |
0 | 0x00 | 0x19 | 0xE619FF00 |
# | 0x00 | 0xD | 0xF20DFF00 |
↑ | 0x00 | 0x18 | 0xE718FF00 |
← | 0x00 | 0x8 | 0xF708FF00 |
OK | 0x00 | 0x1C | 0xE31CFF00 |
→ | 0x00 | 0x5A | 0xA55AFF00 |
↓ | 0x00 | 0x52 | 0xAD52FF00 |
Botón | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Comando Hexadecimal | 0x45 | 0x46 | 0x47 | 0x44 | 0x40 | 0x43 | 0x7 | 0x15 | 0x9 |
¿De dónde vienen estos valores? Al utilizar IrReceiver.printIRResultShort();
recibimos un resumen de estos valores cada vez que presionamos un botón, la siguiente línea es un ejemplo de presionar el «1».
Protocol=NEC Address=0x0 Command=0x45 Raw-Data=0xBA45FF00 32 bits LSB first
En la primera parte del proyecto vamos a ver el código con el cual podemos obtener todos los valores de la señal de cada botón.
Componentes
Para conectar el módulo KY-022 solo debemos conectar el pin 2 del Arduino a la salida del módulo (S) , luego conectar el VCC del módulo al 5V del Arduino y por último conectar el GND del módulo al del Arduino.
Posteriormente conectaremos todas los cátodos de los LED a su correspondiente resistencia de 220Ω, para finalizar conectamos todos los ánodos a los pines 3-11 del Arduino como nos muestra la siguiente tabla.
LED | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Pin del Arduino | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Instalando la librería IRremote
Para hacer funcionar el receptor IR hay varias librerías en la biblioteca de Arduino, estas librerías nos va a ahorrar el digitar mucho código ya que todos los cálculos y operaciones los tiene la librería y nosotros solo debemos interpretarlos resultados. En la página del proyecto IRremote hay tutoriales para manejar la librería, ejemplos y la migración del código de la versión 2 a la versión 3.
La instalación de la biblioteca, es bastante simple, lo primero es ir al menú Programa> Incluir Librería> Administrar bibliotecas, aquí hay que esperar un poco a que se actualice el indice librerías o bibliotecas instaladas.
Una vez termine de actualizar vamos al cuadro de búsqueda y digitamos «IRremote». Nos aparecerían varios resultados, pero seleccionamos la creada por Armin Joachimsmeyer y le damos instalar.
Código Primera Parte
#include <IRremote.hpp> int pinReceptor = 2; void setup() { Serial.begin(115200); IrReceiver.begin(pinReceptor, ENABLE_LED_FEEDBACK); // INICIA LA RECEPCIÓN Serial.println("Listo para comenzar a recibir"); } void loop() { if (IrReceiver.decode()) { IrReceiver.printIRResultShort(&Serial); IrReceiver.resume(); } }
Explicación del código
Comenzaremos a revisar el código, primero vamos a ver las declaraciones de las variables.
#include <IRremote.hpp> int pinReceptor = 2;
Lo primero que vemos es que incluimos la librería IRremote.hpp, la cual hará todo el trabajo complejos de recibir y analizar las señales. Luego declaramos un entero pinReceptor al cual le asignamos el número 2 , el cual va a ser el pin en el que hemos conectado la salida de nuestro receptor.
Función setup()
Serial.begin(115200); IrReceiver.begin(pinReceptor, ENABLE_LED_FEEDBACK); // INICIA LA RECEPCIÓN Serial.println("Listo para comenzar a recibir");
Como bien sabemos en el setup ponemos todo lo que debe ser inicializado o ejecutado una sola vez, el el caso de este proyecto lo primero que vemos es la inicialización de la comunicación serial a una velocidad el 115200 baudios, la cual utilizaremos para poder ver los valores de nuestro sensor. La siguiente línea es donde iniciamos el receptor IR, al cual le entregamos dos parámetros, primero el pin en el cual está conectado el receptor y el segundo parámetro es si queremos que el LED del Arduino actúe como testigo de la recepción de una señal. La última línea nos imprime en el monitor de serie la frase «Listo para comenzar a recibir».
Función loop()
if (IrReceiver.decode()) { IrReceiver.printIRResultShort(&Serial); IrReceiver.resume(); }
Iniciamos la función loop con una condicional, donde preguntamos, si hay una señal en el receptor de infrarrojos entonces hacemos los siguientes pasos:
Dentro del If vemos en la primera línea que imprimimos por el monitor serial el resultado completo de la información de la señal de la tecla presionada «Protocol=NEC Address=0x0 Command=0x45 Raw-Data=0xBA45FF00 32 bits LSB first».
Por último vemos IrReceiver.resume();
el cual inicia una nueva recepción.
De esta forma vamos sacando todos los valores de todas teclas del control remoto. No olviden que en este ejemplo utilizamos un control remoto específico, pero se puede usar cualquier control para este ejemplo, inclusive el de su televisor.
Código Segunda Parte
#include <IRremote.hpp> int pinReceptor = 2; int totalLed = 9; const int pines[] = {3,4,5,6,7,8,9,10,11}; void setup() { for (int i=0; i<totalLed; i++) { pinMode(pines[i], OUTPUT); } IrReceiver.begin(pinReceptor, ENABLE_LED_FEEDBACK); // INICIA LA RECEPCIÓN } void loop() { if (IrReceiver.decode()) { if (IrReceiver.decodedIRData.command == 0x45) { apagarTodos(); prenderLed(1); } else if (IrReceiver.decodedIRData.command == 0x46) { apagarTodos(); prenderLed(2); } else if (IrReceiver.decodedIRData.command == 0x47) { apagarTodos(); prenderLed(3); } else if (IrReceiver.decodedIRData.command == 0x44) { apagarTodos(); prenderLed(4); } else if (IrReceiver.decodedIRData.command == 0x40) { apagarTodos(); prenderLed(5); } else if (IrReceiver.decodedIRData.command == 0x43) { apagarTodos(); prenderLed(6); } else if (IrReceiver.decodedIRData.command == 0x7) { apagarTodos(); prenderLed(7); } else if (IrReceiver.decodedIRData.command == 0x15) { apagarTodos(); prenderLed(8); } else if (IrReceiver.decodedIRData.command == 0x9) { apagarTodos(); prenderLed(9); } else { apagarTodos(); } IrReceiver.resume(); } } void apagarTodos() { for(int i=0; i<totalLed; i++) { digitalWrite(pines[i],LOW); } } void prenderLed(int led) { for(int i=0; i<led; i++) { digitalWrite(pines[i],HIGH); } }
Explicación del código
Este es un código fácil de revisar, parece algo largo pero solo es por todas la condiciones para cada uno de los 9 botones que podemos presionar en el control remoto. Vamos pues a ver la declaración de variables.
#include <IRremote.hpp> int pinReceptor = 2; int totalLed = 9; const int pines[] = {3,4,5,6,7,8,9,10,11};
Lo primero que vemos es que incluimos la librería IRremote.hpp, la cual hará todo el trabajo complejos de recibir y analizar las señales. Luego declaramos un entero pinReceptor al cual le asignamos el número 2 , el cual va a ser el pin en el que hemos conectado la salida de nuestro receptor. Acto seguido declaramos una variable tel tipo entero para definir la cantidad de LED que vamos a tener en el proyecto. Por último declaramos un arreglo de números enteros con los pines del Arduino a los que les vamos a conectar cada uno de los LED.
Función setup()
for (int i=0; i<totalLed; i++) { pinMode(pines[i], OUTPUT); } IrReceiver.begin(pinReceptor, ENABLE_LED_FEEDBACK); // INICIA LA RECEPCIÓN
Como bien sabemos en el setup ponemos todo lo que debe ser inicializado o ejecutado una sola vez, el el caso de este proyecto lo primero que vemos es un for, el cual tiene como finalidad la de inicializar todos los pines del arreglo como pines de salida. Una vez salimos del for vemos que iniciamos el receptor IR, al cual le entregamos dos parámetros, primero el pin en el cual está conectado el receptor y el segundo parámetro es si queremos que el LED del Arduino actúe como testigo de la recepción de una señal.
Función apagarTodos()
void apagarTodos() { for(int i=0; i<totalLed; i++) { digitalWrite(pines[i],LOW); } }
Antes de ver la función loop como es habitual, vamos a ver dos funciones que hemos creado para encender y apagar los LED. La primera de ella es apagarTodos(), esta función vemos que inicia con void, lo que quiere decir es que no devuelve ningún valor. Al interior de la función tenemos un ciclo for que inicia en 0 y se va a ejecutar mientras que sea menor que el número de LED (9) y se va a incrementar de a 1, esto va a suceder 9 veces (cuando «i» vale 0, 1, 2, 3, 4, 5, 6, 7, 8).
Al interior del for vemos que hay un digitalWrite(), donde le asignamos al pin[i] (que es arreglo de los pines de salida del Arduino) el valor «LOW», es decir que los apagamos, entonces como ya vimos anteriormente se va a ejecutar 9 veces, es decir que va a apagar los 9 LED.
Función prenderTodos()
void prenderLed(int led) { for(int i=0; i<led; i++) { digitalWrite(pines[i],HIGH); } }
Ahora vamos a ver la función que hemos creado con el nombre prenderLed(). Al igual que la función anterior inicia en void, lo cual nos indica que no devuelve ningún valor, pero entre los paréntesis vemos «int led» (a esto le denominamos parámetros de la función), esto significa que cuando llamemos a esta función le debemos entregar un numero entero, este valor lo vamos a utilizar dentro de esta función. Al interior de la función tenemos un ciclo for que inicia en 0 y se va a ejecutar mientras que sea menor al número que le entregamos como parámetro y de nombre led, lo que lograríamos con ese ciclo es encender tantos LED como le entreguemos como parámetro.
Función loop()
if (IrReceiver.decode()) { if (IrReceiver.decodedIRData.command == 0x45) { apagarTodos(); prenderLed(1); } else if (IrReceiver.decodedIRData.command == 0x46) { apagarTodos(); prenderLed(2); } else if (IrReceiver.decodedIRData.command == 0x47) { apagarTodos(); prenderLed(3); } else if (IrReceiver.decodedIRData.command == 0x44) { apagarTodos(); prenderLed(4); } else if (IrReceiver.decodedIRData.command == 0x40) { apagarTodos(); prenderLed(5); } else if (IrReceiver.decodedIRData.command == 0x43) { apagarTodos(); prenderLed(6); } else if (IrReceiver.decodedIRData.command == 0x7) { apagarTodos(); prenderLed(7); } else if (IrReceiver.decodedIRData.command == 0x15) { apagarTodos(); prenderLed(8); } else if (IrReceiver.decodedIRData.command == 0x9) { apagarTodos(); prenderLed(9); } else { apagarTodos(); } IrReceiver.resume(); }
Al igual que el código de la primera parte iniciamos la función loop con una condicional, donde preguntamos, si hay una señal en el receptor de infrarrojos. Al cumplirse esta condición ya nuestro código entrará a evaluar qué tecla fue presionada.
Para esto tenemos una series de condicionales, donde primero preguntamos si el comando recibido es igual a 0x45 (el botón 1 de nuestro control), entonces llamamos a la función apagarTodos(), para apagar todos los LED y luego llamamos la función prenderLed(), a la cual le entregamos un 1, lo que hace que se encienda sólo el primer LED.
Luego vemos que si la condición anterior, entonces vuelve a preguntar si el comando recibido es igual a 0x46 (el botón 2 de nuestro control), entonces llamamos a la función apagarTodos(), para apagar todos los LED y luego llamamos la función prenderLed(), a la cual le entregamos un 2, lo que hace que se enciendan sólo los dos primeros LED.
Luego vemos que si las condiciones anteriores, entonces vuelve a preguntar si el comando recibido es igual a 0x47 (el botón 3 de nuestro control), entonces llamamos a la función apagarTodos(), para apagar todos los LED y luego llamamos la función prenderLed(), a la cual le entregamos un 3, lo que hace que se enciendan sólo los tres primeros LED.
… Y así hasta con cada uno de los códigos correspondientes a los botones del 4 al 9, donde iremos prendiendo los LED correspondientes a cada uno de los botones presionados.
Por último dentro de nuestro condicional encontramos un ultimo else, donde ejecutamos solo la función apagarTodos(), esto que quiere decir? Que si no se cumplen las condiciones anteriores entonces apagaremos todos los LED, en otras palabras, cuando presionemos cualquier otro botón que no sean de 1-9, entonces se apagarán nuestro LED.
Por último vemos IrReceiver.resume();
el cual inicia una nueva recepción nos prepara para una nueva recepción.
Resumen
Al conectar el Arduino lo convertimos en un receptor de señales infrarrojas en el rango de los 38KHz y podemos comenzar a interactuar con cualquier control remoto, primero capturando sus comandos y en la segunda parte prenderemos la cantidad de LED correspondiente al numero de la tecla que presionamos.
Buenos días,
en un principio agradecerte la documentación y he observado un posible error en el código de la «SEGUNDA PARTE», aparece conectado el pinreceptor en la patilla 2, sin embargo en la imagen, nos muestra que está conectada en el pin 1.
Un saludo y muchas gracias por compartir.
Muchas gracias Tomás, tienes toda la razón en el diagrama está en el pin 1 y el código está en uso el pin 2, inclusive en el video usé el pin 2. Voy a corregir el diagrama al pin 2. De nuevo muchas gracias.