En este ejemplo probamos el sistema de encendido de lámparas y equipos eléctricos conectados al voltaje de red manejado por un control remoto estándar (IR = Infrarrojo). Los comandaremos con teclas elegidas del control remoto, que primero identificaremos con un simple programa en Arduino.
Si usted desea leer con más detalle sobre control remoto con infrarrojo desde Arduino, le recomendamos el artículo Módulo transmisor de infrarrojo KY-005 (Kit de sensores Keyes 5) en nuestra página.
Para controlar artefactos con voltaje de red, usaremos las salidas normalmente abiertas de un módulo de relé. Si no conoce los módulos de relé que son estándar en la línea Arduino, recomendamos leer el artículo que inició esta serie Módulos de relé y Arduino: Domótica (1).
Utilizamos el mismo circuito armado en el artículo anterior: Control con relés por interfaz serie: Domótica(2). Le agregamos únicamente el sensor de recepción de infrarrojos, un sensor VS1838B proveniente de China, muy común en los kits de Arduino y en el mercado.
Se puede utilizar cualquier receptor de control remoto, incluso uno obtenido de desarme, si se tienen identificados sus pines de conexión.
El sensor no es un tan solo un fototransistor, posee un circuito integrado interno que filtra la señal de 38 KHz que modula el haz de infrarrojo, y es la que contiene los comandos de control. La salida de señal entrega una onda cuadrada de niveles TTL entre 0 y 5V. Existen modelos que entregan señal a niveles de 0 a 3,3V.
Es posible que usted encuentre el kit de la imagen que sigue en los sitios especializados, pero no es necesario. Alcanza con conectar el sensor al Arduino y utilizar un control remoto cualquiera de los que haya en su casa.
El sensor utilizado en este kit es, justamente, el VS1838B.
La que sigue es la manera más básica de conectarlo al Arduino, y es el circuito con el que comenzaremos a trabajar en las pruebas iniciales. La principal de ellas, obtener el listado de los datos que llegan al Arduino al presionar cada tecla.
Advertencia: cuando realiza proyectos que están conectados a la red eléctrica, realmente debe saber lo que está haciendo, de lo contrario, puede producirse un accidente. Este es un tema serio y queremos que esté seguro. Si no está 100% seguro de lo que va a hacer, por favor no toque nada.
¡Pregúntele a alguien que sepa!
El siguiente programa utiliza la biblioteca IRemote (creada por >shirriff). Consiste de un ciclo continuo que espera a que llegue un comando de control remoto, y entonces lo muestra por el Monitor Serie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <IRremote.h> int pinEntrada = 11; IRrecv receptorIR(pinEntrada); // define el receptor y su entrada decode_results resultados; // crea estructura de variables del receptor void setup() { Serial.begin(9600); // ininia la interfaz serie receptorIR.enableIRIn(); // inicia el receptor } void loop() { if (receptorIR.decode(&resultados)) { unsigned int valor = resultados.value; Serial.println(valor); // si desea hexadecimal use // Serial.println(valor,HEX); receptorIR.resume(); // a recibir el siguiente valor } delay(1000); } |
Con este programa en el Arduino y la pantalla del monitor serie abierta, pulsar cada tecla del control remoto para conocer sus valores. Es conveniente escribir los valores en un TXT para utilizarlos cada vez que sea necesario. Una lista como la que sigue, que corresponde a un control remoto de Direct TV. Los valores están en decimal.
48799: [guide]
45244: [active]
38057: [list]
33026: [exit]
57063: [back]
4985: [menu]
864: [info]
64187: [rojo]
14499: [verde]
49424: [amar]
59787: [azul]
57375 63414: [vol+]
53295 63414: [vol-]
31762: [guion bl]
16195: [enter]
65001: [prev]
61455: [mute]
6654: [flecha adel]
1579: [flecha atrás]
57094: [flecha derecha]
38068: [flecha izquierda]
22183: [select]
32630: [1]
23217: [2]
28078: [3]
59460: [4]
44135: [5]
37740: [6]
54067: [7]
11155: [8]
45264: [9]
29399: [0]
26583 26583 39270 63414: [on]
26583 26583 39270 63414: [off]
32895 63414: [tv input]
El control remoto del kit de sensor IR Keyes posee los siguientes valores en hexadecimal (puede diferir según el modelo):
0xFFA25D: CH-
0xFF629D: CH
0xFFE21D: CH+
0xFF22DD: PREV
0xFF02FD: NEXT
0xFFC23D: PLAY/PAUSE
0xFFE01F: VOL-
0xFFA857: VOL+
0xFF906F: EQ
0xFF6897: 0
0xFF9867: 100+
0xFFB04F: 200+
0xFF30CF: 1
0xFF18E7: 2
0xFF7A85: 3
0xFF10EF: 4
0xFF38C7: 5
0xFF5AA5: 6
0xFF42BD: 7
0xFF4AB5: 8
0xFF52AD: 9
Circuito para estas pruebas
Nota: en este circuito se alimentan los led emisores de los optoacoples desde la misma fuente de los relés. Para separar totalmente los circuitos, quitar el jumper entre VCC y JD-VCC y alimentar VCC desde los 5V de la placa Arduino.
Criterio de control
En este primer experimento hemos elegido como comandos para encender y apagar las salidas un conjunto de letras a enviar por línea serie. Para el relé 1 enviamos la letra “A” para encender, y la letra “a” para apagar. El relé 2 se enciende con la letra “B” y se apaga con la “b”. Y así sucesivamente si hubiese más relés. Para apagar todo al mismo tiempo elegimos enviar un “0” (cero).
La lista de comandos es como sigue:
Botón 1 – Activa el relé 1 / Botón 2 – Apaga el relé 1
Botón 3 – Activa el relé 2 / Botón 4 – Apaga el relé 2
Botón 0 – Apaga todos los relés
Programa 1 para dos relés
Copie el siguiente código en su IDE de Arduino y súbalo a su placa.
Advertencia: no es conveniente cargar código nuevo cuando su Arduino
está conectado al módulo de relés. Siempre quite la alimentación de 5V a este módulo.
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 |
/* Para 2 relés */ #include <IRremote.h> void controlEncendido(char val); // declarar rutina auxiliar #define encender LOW // definicion de valores para accionar reles #define apagar HIGH int rele1 = 2; // definicion de nombres de salidas int rele2 = 3; int RECV_PIN = 11; //definir el pin de entrada en Arduino IRrecv irrecv(RECV_PIN); decode_results resultado; void setup() { pinMode(rele1,OUTPUT); // definir las salidas para reles pinMode(rele2,OUTPUT); Serial.begin(9600); // iniciar comunicacion serie irrecv.enableIRIn(); // inicia la recepción digitalWrite(rele1,apagar); digitalWrite(rele2,apagar); } void loop() { /**************************************************************************/ if (irrecv.decode(&resultado)) { unsigned int valor = resultado.value; switch(valor) { case 32630: // 1 controlEncendido('A'); // codigo para encender rele 1 break; case 23217: // 2 controlEncendido('a'); // codigo para encender rele 1 break; case 28078: // 3 controlEncendido('B'); // codigo para apagar rele 2 break; case 59460: // 4 controlEncendido('b'); // codigo para apagar rele 2 break; case 29399: // 0 controlEncendido('0'); // codigo para apagar todos break; default: Serial.println(valor); // imprime valor no usado break; } delay(150); irrecv.resume(); // recibir el siguiente } } /**************************************************************************/ // rutina auxiliar void controlEncendido(char val) { switch (val) { case 'A': digitalWrite(rele1,encender); Serial.println("Encender relé 1"); break; case 'a': digitalWrite(rele1,apagar); Serial.println("Apagar relé 1"); break; case 'B': digitalWrite(rele2,encender); Serial.println("Encender relé 2"); break; case 'b': digitalWrite(rele2,apagar); Serial.println("Apagar relé 2"); break; case '0': digitalWrite(rele1,apagar); digitalWrite(rele2,apagar); Serial.println("Todos Apagados"); break; default: break; } } |
Programa 2
En esta modificación de programa utilizamos una opción que nos permite usar una única letra de comando para encender y apagar. El «truco» consiste en alternar el estado del relé de encendido a apagado en cada recepción de la letra, utilizando una operación lógica NOT, que se representa con el símbolo !
Criterio de control
En este caso la lista de comandos es como sigue:
Botón 1 – Activa el relé 1 / Botón 1 apaga el relé 1 al pulsar de nuevo
Botón 2 – Activa el relé 2 / Botón 2 apaga el relé 2 al pulsar de nuevo
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 |
/* Para 2 relés */ #include <IRremote.h> void controlEncendido(char val); // declarar rutina auxiliar #define encender LOW // definicion de valores para accionar reles #define apagar HIGH int rele1 = 2; // definicion de nombres de salidas int rele2 = 3; int RECV_PIN = 11; //definir el pin de entrada en Arduino IRrecv irrecv(RECV_PIN); decode_results resultado; void setup() { pinMode(rele1,OUTPUT); // definir las salidas para reles pinMode(rele2,OUTPUT); Serial.begin(9600); // iniciar comunicacion serie irrecv.enableIRIn(); // inicia la recepción digitalWrite(rele1,apagar); digitalWrite(rele2,apagar); } void loop() { /**************************************************************************/ if (irrecv.decode(&resultado)) { unsigned int valor = resultado.value; switch(valor) { case 32630: // 1 controlEncendido('a'); // codigo para accionar rele 1 break; case 23217: // 2 controlEncendido('b'); // codigo para accionar rele 2 break; case 29399: // 0 controlEncendido('0'); // codigo para apagar todos break; default: Serial.println(valor); // imprime valor no usado break; } delay(500); // pruebe valores para ajustar a la repeticion del control irrecv.resume(); // recibir el siguiente } } /**************************************************************************/ // rutina auxiliar void controlEncendido(char val) { int valor = 0; switch (val) { case 'a': valor = !digitalRead(rele1); digitalWrite(rele1,valor); if (valor == HIGH) Serial.println("RELE 1 apagado"); else Serial.println("RELE 1 activo"); break; case 'b': valor = !digitalRead(rele2); digitalWrite(rele2,valor); if (valor == HIGH) Serial.println("RELE 2 apagado"); else Serial.println("RELE 2 activo"); break; case '0': digitalWrite(rele1,apagar); digitalWrite(rele2,apagar); Serial.println("Todos apagados"); break; default: break; } } |
Programa 3:
El que sigue es un ejemplo para ampliar el manejo a 4 relés. Como observarán, sólo es necesario copiar y pegar y usar los códigos correspondientes.
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 |
/* Para 4 relés */ #include <IRremote.h> void controlEncendido(char val); // declarar rutina auxiliar #define encender LOW // definicion de valores para accionar reles #define apagar HIGH int rele1 = 2; // definicion de nombres de salidas int rele2 = 3; int rele3 = 4; int rele4 = 5; int RECV_PIN = 11; //definir el pin de entrada en Arduino IRrecv irrecv(RECV_PIN); decode_results resultado; void setup() { pinMode(rele1,OUTPUT); // definir las salidas para reles pinMode(rele2,OUTPUT); pinMode(rele3,OUTPUT); pinMode(rele4,OUTPUT); Serial.begin(9600); // iniciar comunicacion serie irrecv.enableIRIn(); // inicia la recepción digitalWrite(rele1,apagar); digitalWrite(rele2,apagar); digitalWrite(rele3,apagar); digitalWrite(rele4,apagar); } void loop() { /**************************************************************************/ if (irrecv.decode(&resultado)) { unsigned int valor = resultado.value; switch(valor) { case 32630: // 1 controlEncendido('a'); // codigo para accionar rele 1 break; case 23217: // 2 controlEncendido('b'); // codigo para accionar rele 2 break; case 28078: // 3 controlEncendido('c'); // codigo para accionar rele 3 break; case 59460: // 4 controlEncendido('d'); // codigo para accionar rele 4 break; case 29399: // 0 controlEncendido('0'); // codigo para apagar todos break; default: Serial.println(valor); // imprime valor no usado break; } delay(500); irrecv.resume(); // recibir el siguiente } } /**************************************************************************/ // rutina auxiliar void controlEncendido(char val) { int valor = 0; switch (val) { case 'a': valor = !digitalRead(rele1); digitalWrite(rele1,valor); if (valor == HIGH) Serial.println("RELE 1 apagado"); else Serial.println("RELE 1 activo"); break; case 'b': valor = !digitalRead(rele2); digitalWrite(rele2,valor); if (valor == HIGH) Serial.println("RELE 2 apagado"); else Serial.println("RELE 2 activo"); break; case 'c': valor = !digitalRead(rele3); digitalWrite(rele3,valor); if (valor == HIGH) Serial.println("RELE 3 apagado"); else Serial.println("RELE 3 activo"); break; case 'd': valor = !digitalRead(rele4); digitalWrite(rele4,valor); if (valor == HIGH) Serial.println("RELE 4 apagado"); else Serial.println("RELE 4 activo"); break; case '0': digitalWrite(rele1,apagar); digitalWrite(rele2,apagar); digitalWrite(rele3,apagar); digitalWrite(rele4,apagar); Serial.println("Todos apagados"); break; default: break; } } |
En estos programas, la parte del código donde llega el código de comando está entre dos hileras de asteriscos. Reemplazando ese bloque de código es posible utilizar otros métodos de ingreso de datos para comandar la placa de relés.
Puede ser utilizando caracteres llegados desde una placa bluetooth, por I2C o SPI desde otro microcontrolador, un módulo de interfaz RS-485, o diversos sistemas basados en RF o enlaces de luz infrarroja, láser, etc.
En todos los casos, la comunicación de control se basará en caracteres de control ingresados por TX/RX u otro medio similar, incluyendo un ingreso directo implementado con entradas digitales y pulsadores.
El resto del código será siempre el mismo, la función con la estructura Switch…Case.
Las opciones las desarrollamos en la serie de artículos anteriores y los que siguen a este.
Artículos relacionados:
■ Módulos de relé y Arduino: Domótica (1)
■ Control con relés por interfaz serie: Domótica (2)
■ Control de relés con control remoto IR: Domótica (3)
■ Control de relés por enlace de 2,4 GHz – módulos NRF24L01: Domótica (4)
■ Descripción y funcionamiento del Bus I2C
■ ¿Qué es la comunicación serie?