Librería para manejar Arduino con un mando a distancia por infrarrojos

publicado en: Portada | 5

Una forma muy sencilla de usar Arduino en domótica es utilizando un mando a distancia por infrarrojos para controlarlo. Seguro que tienes en algún cajón el de una TV que ya has reciclado o un mando universal que puede dar más de sí. Además, puedes usarlo para controlar varias cosas a la vez; suponiendo, lógicamente, que la luz infrarroja llegue tanto al dispositivo original como al receptor que instales en Arduino.

Es posible recibir datos desde un mando a distancia por infrarrojos utilizando un fotodiodo o un fototransistor, pero será necesario filtrar la señal resultante, amplificarla y lo que es más delicado, demodularla; ya que los mandos a distancia utilizan una onda portadora sobre la que montan la información que se envía. Aunque es viable hacer un montaje sencillo e incluso demodular por software, lo más común es utilizar un dispositivo integrado que contenga los componentes necesarios para encargarse de todo el proceso y que generalmente ahorrará mucho espacio en el montaje (y en su caso en la aplicación) sin un sobre-coste apreciable o hasta ahorrando en el circuito final.

En la imagen de abajo se puede comparar el tamaño entre varios módulos de recepción de señal de mandos de infrarrojos (a la izquierda de la foto) y un fotodiodo y un fototransistor (a la derecha de la foto)

comparación entre el tamaño de módulos ir infrarrojos y fotodiodos y fototransistores

Cuando se opta por añadir al hardware o al software la demodulación, es decir, hacer «a mano» el trabajo de separar la portadora de la onda recibida, usando circuitería o en el programa, hay que conocer la frecuencia de la portadora. Cada protocolo utiliza su propia frecuencia portadora; por ejemplo a Sony le gusta la de 40 KHz, a Philips 36 KHz (aunque también tiene un protocolo a 38 KHz) y en el resto de fabricantes la más habitual es de 38 KHz

El esquema de la imagen de abajo representa la señal realmente emitida, con la portadora, en color claro y en color oscuro la señal que contiene la información que se interpreta una vez retirada la portadora.

esquema de la señal de un mando a distancia por infrarrojos y su onda portadora

Si decides utilizar un módulo receptor de infrarrojos, uno de más populares es el 1838 (AX-1838HS, en mi caso) que incluye además del fotodiodo receptor varias etapas de amplificación y filtrado para devolver una señal digital a un nivel que puede leerse directamente desde el microcontrolador. El 38 del nombre hace referencia a que trabaja con una señal modulada a 38 KHz. Aunque el componente probablemente funcionará sin más que alimentarlo y conectarlo a una entrada digital, el fabricante recomienda un circuito mínimo de aplicación principalmente para evitar rebotes de la señal y filtrar posibles ruidos producidos por la alimentación. En mis pruebas, conectándolo directamente con un cable de algo menos de medio metro y una alimentación sin ruidos funciona correctamente incluso sin los componentes pasivos que indica el fabricante en la hoja de datos del dispositivo.

receptor IR AX-1838HS 1838 para mando a distancia por infrarrojoscircuito de aplicación del receptor de infrarrojos AX-1838HS

Seguramente esperas poder utilizar un «mando a distancia universal» y que con estudiar ese tipo de señal ya esté todo resuelto. Malas noticias: no existen los mandos a distancia universales, por más que el nombre sí exista. Cuando compras un mando universal puede ser uno que utilice un formato concreto, nada universal y bastante habitual, uno que permite elegir el protocolo manualmente de entre una base de datos interna o un poco más avanzado, escaneando el dispositivo que se controla a partir de unas condiciones predeterminadas y el cuarto, el más avanzado, que es capaz de aprender cómo funciona cualquier mando, almacenar las órdenes en su memoria y reproducirlas después para controlar el dispositivo.

En la imagen de abajo puedes ver un ejemplo de los dos últimos tipos: el más pequeño es capaz de controlar la mayoría de los equipos de aire acondicionado detectando (probando) qué tipo de señal los hace funcionar; el más grande tiene un receptor, además del emisor, con el que puede «aprender» la señal de otro mando y reproducirla después. El último método es el más completo pero aún así puede que no funcione siempre ya que necesita el mando original para copiar las órdenes o detectar el protocolo así que suele incluir también la opción de prueba con los protocolos estándar (o, al menos, conocidos)

mandos a distancia por infrarrojos universales pero dentro de un orden

Buscando entre los mandos que tengo sin usar he encontrado que la mayoría trabajan con el protocolo NEC de mando a distancia por infrarrojos. Como es además el que usan los mandos que vienen incluidos en muchos módulos de recepción de infrarrojos para Arduino, usaré a lo largo del artículo ese protocolo, aunque lo que describo es fácilmente extrapolable a los demás con la documentación correspondiente, que puedes encontrar en la web de San Bergmans sobre los mandos a distancia por infrarrojos que mencionaba más arriba.

mandos a distancia que utilizan el protocolo NEC

Así que el siguiente paso, una vez resuelta la parte electrónica de la recepción de la señal infrarroja, es determinar cómo es a nivel lógico esta señal, es decir, determinar el protocolo que utiliza para enviar las órdenes al dispositivo controlado. Seguramente, la forma ortodoxa consiste en estudiar el manual de instrucciones del mando a distancia o, al menos, el del protocolo con el que se comunica. Si no está claro qué protocolo utiliza pueden aplicarse principalmente dos métodos para determinarlo: el primer método es utilizar hardware y/o software a tal efecto (un detector de protocolo infrarrojo) y el segundo método consiste en estudiar la señal con un analizador lógico genérico y compararla con los estándares de transmisión de señal infrarroja para mandos a distancia, que puedes encontrar, por ejemplo en el excelente trabajo de la web de San Bergmans sobre los mandos a distancia por infrarrojos.

analizar la señal del receptor IR AX-1838HS 1838 con el analizador lógico USBee AX pro

Por supuesto, para determinar que mis mandos utilizan el protocolo NEC, he seguido el segundo método, más largo pero mucho más instructivo. Como puede verse en la imagen de arriba, la conexión al hardware del analizador lógico es muy sencilla; se alimenta el receptor y se conecta GND al analizador y la salida del módulo AX-1838HS a uno de los canales del analizador; el cero, en mi caso.

Para realizar el análisis he utilizado PulseView, una excelente aplicación libre y multiplataforma, licenciada con la tercera versión de la GPL, que trabaja tanto con osciloscopios como con analizadores lógicos.

Para analizar la señal basta con elegir:

  • El dispositivo con el que se realiza el análisis; en mi caso un clon del USBee AX Pro.
  • Los canales que se analizan; el cero, en mi caso.
  • Las muestras que se van a tomar. He elegido 2 M para que sobre, ya que a priori no sé qué me voy a encontrar.
  • La frecuencia; 2 KHz, por la misma razón que en el punto anterior

Cuando todo está listo se pulsa sobre «run» en la aplicación y sobre un botón cualquiera en el mando a distancia para que envíe una señal infrarroja al receptor. En la ventana de PulseView aparecerá algo como lo que puede verse en la imagen de abajo.

senal_mando_distancia_infrarrojo_analizador_logico_pulseview_usbee_vista_general

Dejando pulsado el mismo botón se repite el patrón del grupo de la derecha así que lo primero que se aprecia es que existe un código de repetición que se usa en lugar de enviar una y otra vez la misma orden.

Señal de repetición del mando a distancia por infrarrojos. Análisis lógico con pulseview y USBee

Ampliando la representación de la señal y midiéndola con los cursores de la aplicación se puede apreciar que siempre tiene los mismos valores y que son diferentes de los enviados al representar una orden.

Valores de la señal de repetición del mando a distancia por infrarrojos. Análisis lógico con pulseview y USBee

En la captura de pantalla de abajo he ampliado el primer patrón que es presumiblemente (y se puede confirmar consultando la documentación) el código de la orden.

senal_mando_distancia_infrarrojo_analizador_logico_pulseview_usbee

Se pulse sobre el botón que se pulse, al principio del código de cada orden aparece la misma señal que además es muy diferente del resto del código que representa la orden. Se trata de una cabecera que sirve para indicar el comienzo y sincronizar la información ignorando otros pobres pulsos que se hubieran detectado antes.

Valores de la señal de cabecera del mando a distancia por infrarrojos. Análisis lógico con pulseview y USBee

Con esta información, que se puede obtener analizando la señal, ya se puede programar un control por infrarrojos que sería totalmente operativo pero contando con la documentación del protocolo NEC se puede sacar ventaja de las siguientes cuestiones:

  • Cada bit de la codificación está formado por un nivel bajo y otro alto, siendo más largo el segundo cuando se transmite un valor uno que cuando se transmite un valor cero. En mi caso, las gráficas del analizador lógico parecen indicar lo contrario, esto es debido a que, en el módulo de infrarrojos que he utilizado, la amplificación de la señal la invierte. Aunque invertir la señal es habitual en estos dispositivos, es conveniente verificarlo antes de empezar a programar.

  • Antes de enviar la orden se envía la dirección del dispositivo, lo que permite controlar varios del mismo tipo, por ejemplo, varios aparatos de TV, sin más que usar una dirección diferente para cada uno de ellos y el mando que los controla.

  • Tanto la dirección como la orden se envían dos veces, la primera sin modificar y la segunda con el valor negado (una operación lógica NOT a nivel de bits) para verificar que se leen correctamente.

  • Se utilizan ocho bits para expresar la dirección y otros ocho para la orden, como además ambos se envían también negados, se usan en total 32 bits para codificar cada operación conforme a este protocolo de comunicaciones por infrarrojos.

  • En primer lugar, vamos a ver si un Arduino Uno es capaz de recibir los datos a la velocidad que llegan y que desviación tiene la lectura con respecto a los valores «reales» de la documentación. Esta información será importante para usar esos tiempos a modo de calibración en el programa definitivo.

    Para poder utilizar la primera interrupción (la número cero) de Arduino, se conecta el receptor de infrarrojos, además de la alimentación, al pin correspondiente a esta interrupción, PIN_IR: el número 2 en el caso de un Arduino Uno o al 3 de un Arduino Leonardo.

    Una vez monitorizados los tiempos de los pulsos de la señal se puede probar a interpretar la información para verificar que corresponde con lo observado utilizando el analizador lógico y/o la información de la documentación del protocolo de comunicaciones del mando a distancia por infrarrojos.

    El programa anterior mostrará un código (~) para indicar que se ha recibido el final de un periodo de inactividad del mando a distancia, otro (C) para indicar una cabecera, un tercero (O) para una orden y un cuarto (R) cuando se recibe una repetición. Si se reciben datos se codifican los bit representándolos con punto o guión según sean cero o uno. También he incluido un código (X) para indicar que la información recibida no respeta la duración de pulsos esperada.

    En las constantes que representan los tiempos puede verse lo que he medido con el primer programa. Es posible que sea necesario que calcules tus propios valores dependiendo del microcontrolador que tenga la placa concreta que utilices e incluso haya que corregirlos si hay mucho código que modifique el tiempo de ejecución.

    El siguiente programa calcula el código de la orden recibido. Es un número de 32 bits en el que están incluidos tanto la dirección como el código de la orden en sentido estricto así como sus versiones negadas de verificación. Esta aplicación ya es funcional, se pueden detectar las teclas pulsadas como diferentes y establecer una opción diferente para cada una de ellas.

    Para calcular el código recibido se utiliza un contador de bits que los va rotando desde el último al primero para reconstruir su orden lógico. De esta forma, el primer bit recibido quedará en la posición más significativa y en la menos significativa el último. Para evitar números negativos, el contador se decrementa antes de empezar a operar.

    Como se sabe por la documentación que se usa como marca en cada bit un pulso corto, sólo se contabilizan bits cuando el nivel del pin de entrada es bajo; debería haber sido al contrario pero hay que recordar que, como se apreciaba con el analizador lógico, la señal está invertida por la amplificación.

    Como decía más arriba, el programa anterior es perfectamente funcional pero no está muy optimizado. Por una parte no aprovecha la posibilidad de discriminar direcciones de órdenes y por otra la verificación del código con su versión negada. Además requeriría comparar números muy grandes lo que requeriría más tiempo y sobre todo más memoria para almacenar los códigos.

    En la versión de abajo se almacenan por separado las cuatro partes del código para poder compararlas y devolver el código sólo si es coherente, discriminando además dirección de operación. Para hacerlo se usa un contador de grupos de bits (palabras) además del contador de bits que es el que determina el incremento del primero cuando termina su decremento (empieza en el MSB y termina en el LSB) En esta versión he utilizado un límite negativo para el contador de forma que se ilustran las dos opciones cada una en el contexto de programa más ventajoso.

    El código ya está lo bastante refinado como para usarlo en producción en una aplicación pero sobre todo para generalizarlo, por ejemplo haciendo una librería, hay un inconveniente: se han usado interrupciones como forma de asegurarse que va a responder cuando llegue la señal y pero hay pocas y puede que no siempre estén disponibles en función de la aplicación. Ahora que no se usan interrupciones, puede cambiarse el valor de PIN_IR a otro diferente. El siguiente código es simplemente una adaptación que permite verificar si va a funcionar antes de programarlo como librería para usarlo en otros proyectos. En lugar de verificar la llegada de señal con la variable nuevo_dato_ir ahora se comprueba en el bucle principal si el nivel del pin conectado al módulo de infrarrojos ha cambiado de valor.

    Para integrar el código del bucle principal también he cambiado la comprobación en cascada con else if para sustituir la verificación de la duración de los pulsos de datos por la recepción y dentro de ella el orden de comprobación: primero verificar si ya se han recibido todas las palabras y sólo después si está en bajo (cero) el nivel del pin al que se conecta el receptor de infrarrojos para el mando a distancia.

    Y para terminar, queda convertir en una librería para Arduino el código anterior. La primera caja de código de abajo es un ejemplo de cómo se usaría la librería para lectura de códigos de un mando a distancia por infrarrojos, las dos siguientes cajas corresponden al código de la librería.

    Para usar esta librería, puedes copiar el código en tu IDE de Arduino o, si te resulta más cómo, puedes descargar la librería para controlar Arduino con un mando a distancia por infrarrojos desde el enlace y copiarlo en la carpeta libraries correspondiente. Recuerda que funciona con el protocolo NEC y con un módulo receptor 1838 que invierte la señal, por lo que puede que tengas que cambiar el código dependiendo del hardware en concreto que uses.

    Víctor Ventura

    Desarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que había tenido desde siempre. Ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.

    Más entradas - Página web

    Sígueme:
    TwitterLinkedIn

Seguir Víctor Ventura:

Programador multimedia y web + IoT. Mejor con software libre.

Desarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que había tenido desde siempre. Ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.

5 Respuestas

  1. Ricardo Galindo

    Saludos Victor , tu publicación me ha ayudado mucho a comprender el funcionamiento de los controles IR , como funciona el protocolo NEC , que es el mas comun en la mayoria de controles y sobre todo el como hacer tu propia libreria , aun no entiendo bien todo el codigo , mi idea es hacer una pequeña libreria para un attiny ya sea 85 o 45 , en vez del atmega 328 , ya que las que hay disponibles no las puedo hacer funcionar en ninguno de esos dos micros , y no hay mucha informacion disponible , con esto que publicas ya me puedo dar mas o menos una idea de por donde ir empezando y a pesar de que tengo muy poco en esto de arduino , espero poder lograrlo.

    • Víctor Ventura

      Hola, Ricardo.

      Estoy encantado de ser de utilidad y te deseo mucha suerte en tu proyecto ¡seguro que lo consigues!

      Muchas gracias por visitar el blog.

  2. DOMINGO ORTIZ

    Saludos, quiero leer un codigo de un mando a distancia marca samsung pero tengo un arduino uno, la pregunta es seria el mismo codigo?

    • Víctor Ventura

      Hola, Domingo.

      Puedes ver cómo es el código de (casi) cada marca de mandos en la web de San Bergmans sobre los mandos a distancia por infrarrojos. En el menú de navegación (arriba a la derecha) puedes encontrar una lista de los protocolos sobre los que tiene información.

      El código de ejemplo del artículo puedes usarlo en cualquier placa Arduino siempre que utilices el pin de la interrupción correspondiente.

      ¡Suerte con tu proyecto y gracias por visitar polaridad.es!

  3. Yillmer

    Existe otra opcion que no sea USBee X pro y como descargo el pulseview . Gracias por tu aporte.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *