Skip to Content

Cómo controlar un ESP32 con un mando a distancia IR (3 ejemplos)

Cómo controlar un ESP32 con un mando a distancia IR (3 ejemplos)

En este tutorial, aprenderás cómo usar un mando a distancia por infrarrojos (IR) con un ESP32. Los mandos IR se utilizan habitualmente para controlar distintos dispositivos electrónicos como televisores, reproductores de DVD y aires acondicionados. Al integrar un mando IR con un ESP32, podemos crear un sistema de automatización para el hogar, controlar luces de colores o construir un robot controlado a distancia.

El ESP32 es un microcontrolador potente que ofrece conectividad Wi-Fi y Bluetooth integradas, lo que lo convierte en una opción ideal para proyectos de IoT. Con la ayuda de un módulo receptor IR, podemos recibir y decodificar señales de un mando a distancia IR, permitiéndonos controlar diferentes componentes y dispositivos.

En este artículo, veremos las piezas necesarias para este proyecto, entenderemos cómo funciona un mando IR y aprenderemos a conectar el receptor IR al ESP32. También exploraremos cómo leer señales IR, controlar un LED, regular su brillo y hacer sonar un zumbador.

¡Vamos allá!

Componentes necesarios

A continuación tienes los componentes necesarios para este proyecto. Si ya tienes un mando IR, no necesitarás el Kit de Receptor IR, solo el Módulo Receptor IR. Sin embargo, no todos los mandos IR serán compatibles. Por otro lado, si compras o tienes el Kit, no necesitarás el Módulo Receptor IR, ya que viene incluido en el Kit.

Además, para este proyecto estoy usando una placa ESP32 antigua, que ya está descatalogada pero aún se puede conseguir a buen precio. Es la que aparece en la lista de abajo.

ESP32 lite Lolin32

ESP32 lite

USB data cable

Cable de datos USB

Dupont wire set

Juego de cables Dupont

Half_breadboard56a

Protoboard

Kit de resistencias & LED

Infrared (IR) receiver module

Módulo receptor IR

Kit de receptor IR

Zumbador activo

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

¿Cómo funciona un mando IR?

Un mando a distancia IR ( Infrarrojo ) es un dispositivo que utiliza luz infrarroja para transmitir señales y controlar aparatos electrónicos. Utiliza un Transmisor IR y un LED IR para enviar señales IR a un Receptor IR :

Function of an IR Remote
Función de un mando IR

Luz infrarroja

La luz infrarroja (IR) forma parte del espectro electromagnético, igual que la luz visible, las ondas de radio y las microondas. Sin embargo, tiene una longitud de onda mayor que la luz visible, por lo que es invisible al ojo humano.

IR spectrum
Espectro IR

La luz infrarroja se utiliza a menudo para comunicaciones porque produce poca interferencia con otros dispositivos electrónicos.

IR vs. Radiofrecuencia (RF) vs. Bluetooth

Ten en cuenta que la comunicación IR es diferente de la radiofrecuencia (RF) y de la comunicación Bluetooth. Aunque las tres se pueden usar para comunicación inalámbrica, tienen características distintas.

La comunicación IR está limitada a la transmisión en línea de visión, es decir, el receptor debe estar en la línea directa de visión del transmisor. Se usa normalmente para comunicación a corta distancia, como controlar dispositivos en la misma habitación.

La comunicación por radiofrecuencia (RF), en cambio, utiliza ondas de radio para transmitir señales. Tiene mayor alcance que el IR y no requiere línea de visión directa. RF se usa para comunicación inalámbrica entre dispositivos, como mandos de puertas de garaje o teclados inalámbricos.

Bluetooth es una tecnología inalámbrica que opera en la banda de 2,4 GHz. Ofrece mayor alcance que el IR y permite comunicación bidireccional. Bluetooth se usa normalmente para conectar dispositivos como smartphones, auriculares y altavoces.

Transmisor IR

El transmisor IR está oculto dentro del propio mando a distancia. Genera señales con un patrón específico para comunicarse con el receptor IR. Las señales se convierten en luz IR mediante un LED IR. Si te fijas bien, normalmente verás un LED transparente en la parte frontal del mando. Ese es el LED IR que emite la señal infrarroja.

IR remote with IR LED at the front
Transmisor IR

El protocolo más común para la comunicación IR es el protocolo NEC (Nihon Electronics Corporation).

Protocolo NEC para comunicación IR

El NEC protocolo define una forma estándar de codificar y decodificar datos transmitidos mediante señales infrarrojas. Este protocolo se usa mucho en electrónica de consumo, y lo más probable es que la mayoría de los mandos IR de tu casa lo utilicen (la excepción suelen ser los aires acondicionados).

El protocolo NEC utiliza una frecuencia portadora de 38 kHz, lo que significa que la señal infrarroja se modula a esa frecuencia. La señal modulada consiste en ráfagas de luz infrarroja, donde cada ráfaga representa un dígito binario (0 o 1).

Para transmitir datos, el mando IR envía una serie de ráfagas, cada una compuesta por un bloque de datos con una Dirección, su inversa (complemento), un Comando y su inversa. Básicamente, cada botón de tu mando está asociado a un bloque de datos de 32 bits, codificado así.

Formato de trama del protocolo NEC IR
Dirección Inverso de Dirección Comando Inverso de Comando
Bits 0-7 Bits 8-15 Bits 16-23 Bits 24-31

Los bits del bloque de datos se convierten en pulsos, donde un bit 0 se envía como 562,5µs en alto + 562,5µs en bajo, y un bit 1 como 562,5µs en alto + 1,6875ms en bajo. En un osciloscopio, verías una señal como esta:

IR Pulses
Pulsos IR

En el lado del receptor, un módulo receptor IR detecta las ráfagas de luz infrarroja y las desmodula para extraer los datos binarios.

Receptor IR

El receptor IR es el componente que recibe las señales infrarrojas del mando a distancia. Consiste en un fotodiodo que detecta la luz infrarroja entrante y la convierte en señales eléctricas. Abajo puedes ver un módulo receptor IR típico.

IR receiver module
Módulo receptor IR

Para recibir y decodificar el protocolo NEC, el receptor IR debe estar conectado a un microcontrolador capaz de leer e interpretar las señales entrantes. Esto permite que el microcontrolador entienda las pulsaciones de los botones y realice las acciones deseadas.

En la siguiente sección, te mostraré cómo conectar un receptor IR a una placa ESP32 para recibir y decodificar señales IR. ¡No te lo pierdas!

Conectando el receptor IR

Conectar el módulo receptor IR al ESP32 es muy sencillo. El esquema de Fritzing de abajo te muestra cómo hacerlo. Ten en cuenta que aquí estoy usando un Lolin32 lite, pero casi cualquier otra placa de desarrollo ESP32 también funcionará.

Connecting ESP32 Lolin32 to IR receiver module
Conexión del módulo IR al ESP32

Primero conectamos el pin de tierra (GND) del ESP32 al carril negativo de la protoboard, usando un cable azul. Después conectamos el carril positivo de la protoboard (marcado con una línea roja), con un cable rojo al pin llamado 3.3V en la placa ESP32.

Ahora que ya tenemos alimentación en la protoboard, podemos conectar el módulo receptor IR. Conecta el pin marcado con el signo (-) del módulo IR con un cable azul al carril negativo de la protoboard. Luego conecta el pin marcado con una (S) de Signal al Pin 4 del ESP32 (cable amarillo). Por último, conecta el pin restante del receptor IR con un cable rojo al carril positivo. ¡Listo!

Decodificando señales IR

Para usar nuestro mando IR necesitamos saber qué botón envía qué código. El siguiente código te ayudará a averiguarlo. Para más detalles, consulta nuestro tutorial How to use an IR receiver and remote with Arduino.

#include "IRremote.hpp"

const int irReceiverPin = 4;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(irReceiverPin , ENABLE_LED_FEEDBACK);  
}

void loop() {
  if (IrReceiver.decode()) {
    IrReceiver.printIRResultShort(&Serial);
    IrReceiver.resume();
  }
}

Funciona así: primero incluimos la biblioteca IRremote. Luego definimos la constante irReceiverPin para indicar a la biblioteca a qué pin está conectado el receptor IR.

La función setup

En la función setup() iniciamos la comunicación serie a 9600 baudios, lo que permite que el Arduino se comunique con el ordenador. Después llamamos a la función begin() del objeto IrReceiver, pasando irReceiverPin y ENABLE_LED_FEEDBACK como argumentos. Esto inicializa el receptor IR y activa el feedback LED en el módulo receptor IR. Es decir, verás parpadear un LED cada vez que pulses un botón en tu mando y el módulo lo detecte.

La función loop

En la función loop() comprobamos si el receptor IR ha recibido una señal. Si se detecta una señal, la función IrReceiver.decode() devuelve true. En ese caso, llamamos a rReceiver.printIRResultShort(), que imprime un resumen corto de la señal infrarroja recibida en el monitor serie. Luego, se llama a la función IrReceiver.resume() para preparar el receptor IR para la siguiente señal.

Por ejemplo, si pulso algunos botones en mi mando, obtengo la siguiente salida en el monitor serie. Puedes ver que se detectó el protocolo NEC y qué valores de Dirección y Comando se enviaron.

Serial output with decoded IR signal command values

Decodificando mi mando IR

Cuando ejecuto el código anterior y apunto los códigos de los comandos individuales, obtengo la siguiente asignación de botones a comandos para mi mando IR:

IR remote with command codes
Botón Dirección Código de comando
On/Off 0x00 0x52
Mode 0x00 0x4E
Set 0x00 0x40
Arriba 0x00 0x41
Abajo 0x00 0x44

Fíjate que la Dirección (0x00) es siempre la misma para todos los botones. Suele ser así, pero diferentes mandos IR pueden tener direcciones distintas. Para tu mando, esta asignación de botones y códigos de comando será diferente y tendrás que usar el código anterior para averiguarlo.

Una vez que tengas los códigos de tu mando IR, puedes usarlos para controlar todo tipo de dispositivos. En las siguientes secciones te daré algunos ejemplos.

Encender y apagar un LED

En esta sección te mostraré cómo encender y apagar un LED usando el botón On/Off del mando.

Circuito para encender y apagar un LED

Primero, necesitamos añadir un LED a nuestro circuito. Es muy sencillo. Solo tienes que colocar un LED en la protoboard y conectar su ánodo (la pata más larga) a través de una resistencia de 68Ω al Pin 2 del ESP32. Después, conecta el cátodo del LED (la pata más corta) a tierra en la protoboard.

Connecting ESP32 Lolin32 to IR receiver module and an LED
Conexión del ESP32 al módulo receptor IR y un LED

Ten en cuenta que la placa ESP32 funciona a 3,3V. Por eso necesitas usar un valor de resistencia bastante bajo comparado con un circuito Arduino, que funciona a 5V. Si usas una resistencia mayor, el LED seguirá encendiendo pero con menos intensidad.

Código para encender y apagar un LED

Ahora podemos usar el siguiente código para encender o apagar el LED de la placa.

#include "IRremote.hpp"

const int irReceiverPin = 4;
const int ledPin = 2;

void toggle(uint8_t pin) {
  auto state = digitalRead(pin);
  digitalWrite(pin, !state);
}

void setup() {
  pinMode(ledPin, OUTPUT);
  IrReceiver.begin(irReceiverPin, ENABLE_LED_FEEDBACK);
}

void loop() {
  if (IrReceiver.decode()) {
    uint16_t command = IrReceiver.decodedIRData.command;
    if (command == 0x52) {  // On/Off
      toggle(ledPin);
    }
    delay(100);
    IrReceiver.resume();
  }
}

El código es prácticamente igual al anterior. Solo añadimos una nueva constante (ledPin) para el pin donde está conectado el LED

const int ledPin = 2;

y una función que alterna el estado de salida de ese pin:

void toggle(uint8_t pin) {
  auto state = digitalRead(pin);
  digitalWrite(pin, !state);
}

Cada vez que llamamos a esta función, el estado de la salida cambia de encendido a apagado y viceversa. Esto hace que el LED se encienda o apague. Sin embargo, no olvides definir el pin como salida en la función setup() !

void setup() {
  pinMode(ledPin, OUTPUT);
  IrReceiver.begin(irReceiverPin, ENABLE_LED_FEEDBACK);
}

En el bucle principal añadimos un if statement que comprueba si el código de comando recibido es 0x52. Ese es el código de comando del botón On/Off que identificamos antes.

void loop() {
  if (IrReceiver.decode()) {
    uint16_t command = IrReceiver.decodedIRData.command;
    if (command == 0x52) {  // On/Off
      toggle(ledPin);
    }
    delay(100);
    IrReceiver.resume();
  }
}

Si es así, alternamos el LED. No hace falta comprobar la dirección enviada por el IrReceiver, ya que siempre es la misma. Sin embargo, si quieres reaccionar a señales de diferentes mandos usando el mismo receptor IR, puede que tengas que hacerlo.

Por último, esperamos 100ms para evitar que el LED cambie de estado repetidamente si el botón On/Off se mantiene pulsado un poco más.

¡Y eso es todo! Ahora puedes controlar un LED, un relé o cualquier otro dispositivo de conmutación con tu mando IR.

Regular el brillo de un LED

Vamos a probar algo un poco más avanzado. En vez de simplemente encender o apagar el LED, vamos a controlar su brillo. Usamos el mismo LED y circuito que antes, pero cambiamos el código así:

#include "IRremote.hpp"

const int irReceiverPin = 4;
const int ledPin = 2;
const int inc = 10;

int brightness = 100;

void init() {
  pinMode(ledPin, OUTPUT);
  analogWrite(ledPin, brightness);
}

void execute(uint16_t command) {
  if (command == 0x41) {  // UP
    brightness = min(brightness + inc, 255);
  }
  if (command == 0x44) {  // DOWN
    brightness = max(brightness - inc, 0);
  }
  analogWrite(ledPin, brightness);
  delay(100);
}

void setup() {
  IrReceiver.begin(irReceiverPin, ENABLE_LED_FEEDBACK);
  init();
}

void loop() {
  if (IrReceiver.decode()) {
    execute(IrReceiver.decodedIRData.command);
    IrReceiver.resume();
  }
}

Para entender este código, vamos a ver primero las funciones setup y loop . Suelen ser casi idénticas en la mayoría de aplicaciones, así que las he hecho lo más genéricas posible. En la función setup llamo a una función init() que inicializa los pines y otras cosas. Y en la función loop llamo a una función execute() que ejecuta un comando recibido del mando IR.

void setup() {
  IrReceiver.begin(irReceiverPin, ENABLE_LED_FEEDBACK);
  init();
}

void loop() {
  if (IrReceiver.decode()) {
    execute(IrReceiver.decodedIRData.command);
    IrReceiver.resume();
  }
}

Con este esquema podemos mantener las funciones setup() y loop() iguales para diferentes aplicaciones y solo tenemos que implementar o modificar las funciones init() y execute().

La función init

Por ejemplo, para controlar el brillo del LED, implementamos la función init() así:

void init() {
  pinMode(ledPin, OUTPUT);
  analogWrite(ledPin, brightness);
}

Esto configura el pin del LED como salida y también establecemos el brillo inicial del LED mediante analogWrite(), donde brightness es una variable que hemos definido.

La función execute

La función execute() toma un comando recibido del mando IR y, si el comando es 0x41 (botón de subir), aumenta el brillo. Si el comando es 0x44 (botón de bajar), lo disminuye.

void execute(uint16_t command) {
  if (command == 0x41) {  // UP
    brightness = min(brightness + inc, 255);
  }
  if (command == 0x44) {  // DOWN
    brightness = max(brightness - inc, 0);
  }
  analogWrite(ledPin, brightness);
  delay(100);
}

Para cambiar el brillo, sumamos o restamos un incremento predefinido (inc). Si el incremento es grande, el brillo cambiará más rápido. Si es pequeño, el cambio será más suave pero más lento.

Usamos analogWrite() para escribir el valor de brillo en el ledPin. Sin embargo, el rango de valores que puedes escribir en una salida analógica va de 0 a 255. Hay que tener cuidado y evitar valores fuera de ese rango. Por eso usamos las funciones min() y max() aquí. Así nos aseguramos de que los incrementos no hagan que el valor de brillo se salga del rango válido.

Por último, analogWrite() requiere que el pin de salida sea compatible con PWM (modulación por ancho de pulso). Pero en la mayoría de placas de desarrollo ESP32, casi todos los pines soportan PWM, así que normalmente no hay problema. Si tienes dudas, consulta el pinout y busca el símbolo de onda.

En la siguiente sección usaremos el mismo esquema y principio para controlar la frecuencia de un zumbador.

Hacer sonar un zumbador

De forma similar al brillo de los LEDs, la frecuencia de un zumbador activo se puede controlar mediante una señal PWM. Eso significa que, con unos pequeños cambios, podemos usar prácticamente el mismo código que antes. Pero primero vamos a montar el circuito.

Circuito para hacer sonar un zumbador

Quitamos el LED y lo sustituimos por un zumbador. No necesitamos resistencia, solo hay que asegurarse de conectar el polo negativo del zumbador al carril negativo de la protoboard y el polo positivo al Pin 2 del ESP32.

Connecting ESP32 Lolin32 to IR receiver module and a Buzzer
Conexión del ESP32 al módulo receptor IR y un zumbador

Ten en cuenta que los zumbadores suelen tener un pequeño signo más en la parte superior que indica el polo positivo. Como es difícil de ver, asegúrate de conectar el lado positivo al Pin 2 del ESP32. Además, asegúrate de que tienes un zumbador active y no uno pasivo.

Código para hacer sonar un zumbador

Como prometí, el código para controlar el zumbador es muy parecido al del LED.

#include "IRremote.hpp"

const int irReceiverPin = 4;
const int buzzerPin = 2;
const int inc = 10;

int freq = 1000;
bool do_sound = false;

void init() {
  pinMode(buzzerPin, OUTPUT);
  noTone(buzzerPin);
}

void execute(uint16_t command) {
  switch (command) {
    case 0x41:  // Up
      freq = min(freq + inc, 65535);
      break;
    case 0x44:  // Down
      freq = max(freq - inc, 0);
      break;
    case 0x52:  // Stop
      do_sound = !do_sound;
      delay(100);
      break;
  }
  do_sound ? tone(buzzerPin, freq) : noTone(buzzerPin);
  delay(10);
}

void setup() {
  IrReceiver.begin(irReceiverPin, ENABLE_LED_FEEDBACK);
  init();
}

void loop() {
  if (IrReceiver.decode()) {
    execute(IrReceiver.decodedIRData.command);
    IrReceiver.resume();
  }
}

En la función init() configuramos el pin al que está conectado el zumbador como salida. Luego nos aseguramos de que el zumbador esté apagado al inicio llamando a no Tone().

void init() {
  pinMode(buzzerPin, OUTPUT);
  noTone(buzzerPin);
}

Ten en cuenta que noTone() y tone() son funciones integradas de Arduino. No necesitas incluir ninguna librería adicional para usarlas.

En la función execute() volvemos a escuchar un comando del receptor IR y reaccionamos a él.

void execute(uint16_t command) {
  switch (command) {
    case 0x41:  // Up
      freq = min(freq + inc, 65535);
      break;
    case 0x44:  // Down
      freq = max(freq - inc, 0);
      break;
    case 0x52:  // Stop
      do_sound = !do_sound;
      delay(100);
      break;
  }
  do_sound ? tone(buzzerPin, freq) : noTone(buzzerPin);
  delay(10);
}

Si se pulsa el botón de subir (0x41), aumentamos la frecuencia, y si se pulsa el de bajar (0x44), la disminuimos. Los valores válidos para la frecuencia van de 0 a 65535. Así que, como antes, usamos min() y max() para limitar el rango de valores.

También quería poder encender o apagar el sonido. Por eso el código también detecta el botón Stop (0x52) y alterna la variable booleana do_sound. Después añadimos un retardo de 100ms para que el cambio no sea demasiado rápido.

Lo último que tenemos que hacer es reproducir el sonido, lo que se consigue con esta línea de código:

do_sound ? tone(buzzerPin, freq) : noTone(buzzerPin);

Si do_sound es True, reproducimos el tono a la frecuencia establecida; si no, apagamos el zumbador.

Las funciones setup() y loop() son iguales que antes. ¡Listo! Ahora tienes tres ejemplos de cómo usar un mando IR para controlar diferentes dispositivos. Además, tienes una pequeña estructura de código donde solo tienes que implementar las funciones init() y execute() para controlar otros dispositivos.

Por ejemplo, si quieres controlar motores, echa un vistazo a nuestros tutoriales sobre How to Control a Servo with an IR Remote y Control a Stepper Motor with an IR Remote.

Por último, este circuito y código solo te permite recibir señales IR. Si quieres enviar señales, lee How to build a universal, programmable IR remote.

Conclusión

En este tutorial hemos aprendido a usar un mando IR con un ESP32. Empezamos viendo los componentes necesarios para el proyecto, que incluyen una placa ESP32 y un receptor IR.

Después, exploramos cómo funciona un mando IR y cómo envía señales al receptor IR. Luego pasamos a conectar el receptor IR a la placa ESP32, asegurándonos de que los pines necesarios estuvieran bien conectados.

Una vez completado el montaje, nos metimos en el código y aprendimos a leer las señales IR usando la librería IRremote. Implementamos varias funciones, como encender y apagar un LED, regular su brillo y hacer sonar un zumbador, según las señales IR recibidas.

Siguiendo este tutorial, ahora deberías tener una buena base para integrar un mando IR con un ESP32 y controlar diferentes componentes usando las señales recibidas. Esto abre un montón de posibilidades para tus proyectos, desde crear un sistema de automatización para el hogar hasta construir un mando personalizado para tus propias aplicaciones.

Si tienes más preguntas o encuentras algún problema mientras trabajas en este proyecto, consulta la sección de Preguntas Frecuentes más abajo. Además, encontrarás enlaces útiles a recursos y documentación para seguir aprendiendo y mejorando tus habilidades en este tema.

¡Feliz cacharreo!

Preguntas Frecuentes

Aquí tienes algunas preguntas habituales sobre el uso de un mando IR con un ESP32:

P: ¿Puedo usar cualquier mando IR?

R: Sí, la biblioteca IRRemote y el módulo IRReceiver que hemos usado aquí, reconocen la mayoría de mandos IR estándar. Otra opción posible es la biblioteca IRremoteESP8266. Sin embargo, es importante comprobar la compatibilidad de frecuencia del mando con el módulo receptor IR que estés usando.

P: ¿Cómo encuentro los códigos IR de mi mando?

R: Hay varios métodos para encontrar los códigos IR de tu mando. Una forma es usar un módulo receptor IR y un Arduino o ESP32 para capturar y decodificar las señales, como hemos mostrado arriba. O puedes comprar un simple Component tester que pueda decodificar señales IR. La última opción es buscar en internet el modelo específico de tu mando y ver si los códigos están disponibles.

P: ¿Puedo controlar varios dispositivos con un solo mando IR?

R: Sí, puedes controlar varios dispositivos con un solo mando IR usando diferentes códigos IR para cada dispositivo. Decodificando las señales IR y asignándolas a acciones concretas, puedes controlar varios dispositivos como LEDs, motores o incluso electrodomésticos.

P: ¿Hasta dónde llega la señal de un mando IR?

R: El alcance de un mando IR depende de varios factores, como la potencia del mando, la sensibilidad del receptor IR y los obstáculos en la línea de visión. Por lo general, el alcance puede variar desde unos pocos metros hasta unos 10 metros.

P: ¿Puedo usar un mando IR con otros microcontroladores o placas de desarrollo?

R: Sí, los mandos IR se pueden usar con varios microcontroladores y placas de desarrollo. Consulta nuestro tutorial sobre How to use an IR receiver and remote with Arduino, por ejemplo.

Si tienes cualquier otra pregunta o necesitas más ayuda, no dudes en preguntar en los comentarios de abajo.

Enlaces

A continuación tienes algunos enlaces para ampliar información