Objetivos
Material requerido.
Kit inicio UNO | |
Kit Inicio Mega |
Los mandos de infrarrojos
Estamos tan acostumbrados a los mandos a distancia infrarrojos que no dedicamos un momento a pensar en ellos y simplemente nos parece normal, algo que a nuestros abuelos les hubiera parecido magia.
Nos parece normal que los equipos electrónicos, televisores, cadenas de música, aires acondicionados, respondan a nuestras instrucciones sin levantarnos del sofá, pero esto no ha sido siempre así, es más, es relativamente reciente, que estos mandos se popularizaron.
Hemos oído que funcionan por infrarrojos y poco más. Me pregunto cuántos usuarios responderían correctamente a la pregunta de que son los infrarrojos y cuál es el principio de funcionamiento de un mando a distancia de este tipo.
Para centrar un poco las ideas, empecemos diciendo que las ondas electromagnéticas se caracterizan, principalmente, por su frecuencia o lo que es lo mismo, por el inverso de ésta que es la longitud de onda.
Son similares a las ondas de sonido. A las de menor frecuencia las llamamos infrasonidos, y luego vienen las ondas de sonido claro. Un poco más arriba tenemos los ultrasonidos (Nombres sorprendentes, que básicamente significan por debajo y por encima de lo que se oye.
En el espectro electromagnético, nos encontramos enseguida con las ondas de radio y luego con las microondas. Después como veis en este gráfico que he pillado de la Wikipedia viene el infrarrojo (Por debajo del rojo), el espectro de luz visible con los familiares colores (Que solo son una forma en que nuestro cerebro percibe las frecuencias de luz) y luego el ultravioleta (Por encima del violeta, eso es echarle imaginación a los nombres, si señor).
Más arriba en la escala encontramos los rayos X (Cuando el alemán Roentgen descubrió esta radiación a finales del XIX, no tenía ni idea de que era, y le parecía una buena idea llamarlos Rayos X, o sea desconocidos, y todavía hoy seguimos con este cachondeo) y por último los rayos gamma o cósmicos.
La capacidad energética de la radiación crece rápidamente con la frecuencia y por eso los rayos X y los gamma son muy dañinos para los seres vivos.
Una manera de describir los infrarrojos, seria como una luz con un color diferente, que no vemos, pero luz a pesar de todo.
Una curiosidad no muy conocida, es que seguramente la cámara de tu teléfono móvil, o tableta es capaz de ver, y mostrarte, la radiación IR de tus mandos a distancia. Aquí os pongo un mini video grabado con mi móvil, un iPhone 4S:
La luz infrarroja es adecuada para hacer mandos a distancia porque:
Así que es práctico, sencillo y barato (lo que les encanta a los fabricantes), aunque tienen también inconvenientes.
El principal es que cualquier cosa con una cierta temperatura, incluidos nosotros, emitimos radiación infrarroja. Es por eso que las cámaras IR que veis en las pelis, pueden mostrar nítidamente en plena oscuridad a una persona o animal.
Y esto podría interferir con el mando a distancia IR, lo mismo que cosas como la calefacción, el sol y demás cosas calientes. Así que la solución para evitarlo es modular la señal con una portadora.
La idea básica es mandar un tren de ondas estable (La portadora) y mezclarlo con la información que queremos enviar (La señal). Este mismo principio se usa con la radio y casi con cualquier señal radioeléctrica que se envié por el aire.
He encontrado este Gif en la página de sbprojects y me ha parecido ideal para mostrar el proceso de modulación y transmisión.
El emisor es un sencillo transistor que gobiernan un LED infrarrojo muy similar a los LEDs rojitos normales que hemos usado hasta ahora, solo que diseñados para emitir luz en un color que no vemos.
Un pequeño procesador en el mando gobierna, la generación de la señal y la mezcla con la portadora, para garantizar que nuestra tele no recibe órdenes espurias.
El receptor tiene un poco más de complejidad porque, las normas de emisión de IR para mandos a distancia, aparecieron como setas tras una tormenta y poco menos que cada fabricante presento su propia norma.
Al final la industria acabo diseñando unos receptores capaces de recibir y demodular casi cualquier cosa, y como se venden como churros (Porque nos encanta mantener nuestro culo pegado al sofá) valen muy poco y son un prodigio tecnológico.
Un receptor IR típico actual, incluye el receptor, amplificador demodulador y lo que se te ocurra encapsulado y listo para usarse. No os imagináis la cantidad de electrónica que va incluido esta piececita de aspecto inocente.
Receptores de IR
Un típico receptor de infrarrojos, es el AX-1838HS, que se consigue por poco más de unos euros. En su hoja de normas encontráis este diagrama, y son relativamente fáciles de encontrar, en dos formas. Independientes y montados en un soporte para utilizar sin complicaciones con nuestros Duinos.
El esquema de conexión nuevamente es trivial, pues el AX-1838HS solo tiene 3 pines: Vcc, GND y señal. Como vamos a usar una interrupción para leer la señal es imprescindible, que llevéis el pin de señal a el pin2 de Arduino (La interrupción 0) o al pin3 (La interrupción 1).
Yo lo voy a conectar al pin 2 y así lo reflejan los programas y los ejemplos.
Programa de control
Para poderlos usar de una forma cómoda, vamos a descargarnos alguna librería, que nos facilite la vida. De las varias disponibles me ha gustado la de Nico Hood http: //nicohood.wordpress.com/, por varios motivos.
Lo primero es descargarnos la librería IRLremote.zip, y después instalarla siguiendo el procedimiento habitual que vimos en sesiones anteriores. Una vez hecho para usarla como siempre usamos el importar librería, que os pondrá:
#include "IRLremote.h"
Y para inicializarla:
IRLbegin<IR_ALL>(interruptIR);
Vamos a empezar por un ejemplo que nos recomienda el autor para reconocer el mando a distancia que usamos. Podeis cargarlo con ejemplos IRLremote\ReceiveInterrupt
#include "IRLremote.h" const int interruptIR = 0; // Arduino interrupcion 0: Pin 2 uint8_t IRProtocol = 0; // Variables para recibir los datos uint16_t IRAddress = 0; uint32_t IRCommand = 0; void setup() { Serial.begin(115200); // Fijate en la velocidad Serial.println("Startup"); IRLbegin<IR_ALL>(interruptIR); } void loop() { uint8_t oldSREG = SREG; // Parar las interrupciones cli(); if (IRProtocol) // Si reconoce el protocolo { Serial.print("Protocol:"); Serial.println(IRProtocol); Serial.print("Address:"); Serial.println(IRAddress, HEX); Serial.print("Command:"); Serial.println(IRCommand, HEX); IRProtocol = 0; } SREG = oldSREG; } void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { IRProtocol = protocol; // Recogemos los valores y nos volvemos IRAddress = address; IRCommand = command; }
Este programa, simplemente tratará de leer tu mando a distancia y enviar esa información a la consola. Asegúrate de que has puesto la velocidad a 115200:
Como veréis la rutina de servicio de la interrupción simplemente recoge los valores del protocolo que amablemente reconoce sobre la marcha la librería. Los valores que presenta son
Yo he probado con 5 mandos IR diferentes (Tengo muchos trastos) y me ha reconocido correctamente 4 a la primera. Los que han entrado sin problemas son los de Panasonic, Sony, LG y Keyes.
El que no sabía lo que era, ha sido un mando viejo de una TV Schneider que soy incapaz de saber de dónde ha salido.
Y en este programa está ya implícito todo lo necesario para utilizar un mando IR en tus proyectos. EL resto de la sesión será sencillamente un ejemplo de cómo gestionar esos golpes de teclas con u Swuitch que es una instrucción C++ que hasta ahora no habíamos usado y que nos viene al pelo.
Vamos a montar un circuito con Arduino y 4 LEDs de colores para encerderlos de uno en uno o apagarlos todos de golpe, mediante el mando IR a distancia.
Esquema de conexión
La conexión será muy sencilla:
Y el esquema de protoboard, cuesta más dibujarlo que montarlo:
Programa de control
Al principio de esta sesión vimos que ya recibíamos las instrucciones del mando (Espero) y nos ponía en la consola el valor del protocolo, dirección del mando y Commando que corresponde al botón pulsado. Estos comandos son lo que necesitais para diparar vuestro programa
En primer lugar correr el programa anterior para anotar los códigos que corresponden a cada tecla de vuestro mando, y haceros una tabla. No hace falta que anoteis todas las teclas por ahora, pero si al menos las que vayamos a usar.
En mi mando LG el resultado es este:
Arriba | Abajo | Izquierda | Derecha | OK |
---|---|---|---|---|
0x02FD | 0x827D | 0xE01F | 0x609F | 0x22DD |
Y con esto ya podemos escribir el programa de control. Vamos a utilizar la instrucción switch case, que es muy comoda cuando tienes que comprobar muchos valores y tomar acciones en respuesta a una variable. LA idea básica es como esto:
switch (IRCommand) { case 0x02FD: Serial.println("Arriba"); digitalWrite(8, HIGH); break; case 0x827D: Serial.println("Abajo"); digitalWrite(9, HIGH); break; case 0xE01F: Serial.println("Izquierda"); digitalWrite(10, HIGH); break; case 0x609F: Serial.println("Derecha"); digitalWrite(11, HIGH); break; case 0x22DD: Serial.println("OK"); for (int k =0 ; k <12 ; k++) digitalWrite(k, LOW); break; }
Le pasamos a switch la variable, cuyo valor determina la acción, en este caso el comando pulsado. Y después se establece una clausula de case para cada valor posible finalizando con dos puntos. Escribe las instrucciones a ejecutar y finaliza con break.
He puesto a propósito lo del Serial.println() para que veais que podeis poner varias líneas sin necesidad de bloques que ya esta implícito en el case. Y por fin finaliza la clausula con un break.
Puedes incluir una ultima clausula default, sin otro valor para poner una acción que se ejecute si el valor de la variable no coincide con niguno de los caso comprobados mas arriba.
#include "IRLremote.h" const int interruptIR = 0; uint8_t IRProtocol = 0; // Variables para recibir los datos uint16_t IRAddress = 0; uint32_t IRCommand = 0; void setup() { Serial.begin(115200); // Fijate en la velocidad for (int i = 8 ; i<12 ; i++) pinMode(i, OUTPUT); IRLbegin<IR_ALL>(interruptIR); }
La única novedad ha sido hasta aquí, definir como salidas los pines del 8 al 11
void loop() { uint8_t oldSREG = SREG; // Parar las interrupciones cli(); if (IRProtocol) { switch (IRCommand) // Aqui tenemos la clausula switch con sus case: { case 0x02FD: Serial.println("Arriba"); digitalWrite(8, HIGH); break; case 0x827D: Serial.println("Abajo"); digitalWrite(9, HIGH); break; case 0xE01F: Serial.println("Izquierda"); digitalWrite(10, HIGH); break; case 0x609F: Serial.println("Derecha"); digitalWrite(11, HIGH); break; case 0x22DD: Serial.println("OK"); for (int k =0 ; k <12 ; k++) digitalWrite(k, LOW); break; } IRProtocol = 0; } SREG = oldSREG; } void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { IRProtocol = protocol; // Recogemos los valores IRAddress = address; IRCommand = command; }
La cláusula switch es muy útil para evitar if else encadenados que al final te hacen perder el hilo. Imagínate si tienes que comprobar todas las posibles teclas del mando.
Aquí teneís un minivideo con el resultado
Por ultimo y antes de terminar, comentar que el autor de la librería recomienda que si vamos a usar un solo mando, sustituyamos la líne
IRLbegin<IR_ALL>(interruptIR);
Por la que corresponda a nuestro modelo, porque ahorraremos en memoria y ganaremso en velocidad en la decodificación de las señales. En mi caso que me reporta el protocolo 3 , IR_NEC sería:
IRLbegin<IR_NEC >(interruptIR);
Resumen de la sesión
Hoy hemos aprendido en nuestro curso de arduino lo siguiente: