Skip to Content

Como controlar um ESP32 com um comando IR (3 Exemplos)

Como controlar um ESP32 com um comando IR (3 Exemplos)

Neste tutorial, vais aprender a usar um comando IR com um ESP32. Comandos IR (Infravermelhos) são frequentemente usados para controlar vários dispositivos eletrónicos como TVs, leitores de DVD e ar condicionados. Ao integrar um comando IR com o ESP32, podemos criar um sistema de automação doméstica inteligente, controlar iluminação colorida ou construir um robô controlado remotamente.

O ESP32 é um microcontrolador potente que oferece Wi-Fi e Bluetooth integrados, tornando-o uma escolha ideal para projetos de IoT. Com a ajuda de um módulo recetor IR, podemos receber e descodificar sinais de um comando IR, permitindo controlar diferentes componentes e dispositivos.

Neste artigo, vamos abordar as peças necessárias para este projeto, perceber como funciona um comando IR e aprender a ligar o recetor IR ao ESP32. Também vamos explorar como ler sinais IR, controlar um LED, regular a intensidade de um LED e ativar um buzzer.

Vamos a isso!

Componentes Necessários

Em baixo encontras os componentes necessários para este projeto. Se já tens um comando IR, não precisas do Kit Recetor de Comando IR, apenas do Módulo Recetor IR. No entanto, nem todos os comandos IR são adequados. Por outro lado, se comprares ou já tiveres o Kit, não precisas do Módulo Recetor IR, pois já faz parte do Kit.

Além disso, para este projeto, estou a usar uma placa ESP32 mais antiga, que já foi descontinuada mas ainda se encontra a um preço acessível. É essa que está listada em baixo.

ESP32 lite Lolin32

ESP32 lite

USB data cable

Cabo de Dados USB

Dupont wire set

Conjunto de Cabos Dupont

Half_breadboard56a

Breadboard

Kit de Resistores & LED

Infrared (IR) receiver module

Módulo Recetor IR

Kit Recetor de Comando IR

Buzzer Ativo

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.

Como funciona um Comando IR

Um comando IR ( Infravermelhos ) é um dispositivo que usa luz infravermelha para transmitir sinais e controlar aparelhos eletrónicos. Utiliza um Transmissor IR e um LED IR para enviar sinais IR para um Recetor IR :

Function of an IR Remote
Função de um Comando IR

Luz Infravermelha

A luz infravermelha (IR) faz parte do espectro eletromagnético, tal como a luz visível, ondas de rádio e micro-ondas. No entanto, tem um comprimento de onda maior do que a luz visível, tornando-a invisível ao olho humano.

IR spectrum
Espectro IR

A luz infravermelha é frequentemente usada para comunicações devido à sua baixa interferência com outros dispositivos eletrónicos.

IR vs. Rádio RF vs. Bluetooth

Nota que a comunicação IR é diferente da comunicação por Rádio RF e Bluetooth. Embora as três possam ser usadas para comunicação sem fios, têm características distintas.

A comunicação IR está limitada à transmissão em linha de vista, ou seja, o recetor tem de estar na linha direta do transmissor. É normalmente usada para comunicações de curto alcance, como controlar dispositivos na mesma sala.

A comunicação por Rádio RF, por outro lado, usa ondas de rádio para transmitir sinais. Tem um alcance maior comparado ao IR e não requer linha de vista. O Rádio RF é usado para comunicação sem fios entre dispositivos, como comandos de portões de garagem ou teclados sem fios.

O Bluetooth é uma tecnologia sem fios que opera na frequência de 2.4 GHz. Oferece um alcance maior do que o IR e suporta comunicação bidirecional. O Bluetooth é normalmente usado para ligar dispositivos como smartphones, auscultadores e colunas.

Transmissor IR

O transmissor IR está escondido dentro do próprio comando. Cria sinais com um padrão específico para comunicar com o recetor IR. Os sinais são convertidos em luz IR através de um LED IR. Se olhares com atenção, normalmente vês um LED transparente na frente do comando. Esse é o LED IR que emite o sinal.

IR remote with IR LED at the front
Transmissor IR

O protocolo mais comum usado para comunicação IR é o NEC (Nihon Electronics Corporation).

Protocolo NEC para Comunicação IR

O NEC protocolo define uma forma padrão de codificar e descodificar dados transmitidos por sinais infravermelhos. Este protocolo é muito usado em eletrónica de consumo, e é provável que a maioria dos comandos IR em tua casa o utilize (a exceção são os comandos de ar condicionado).

O protocolo NEC usa uma frequência portadora de 38 kHz, o que significa que o sinal infravermelho é modulado a essa frequência. O sinal modulado consiste em rajadas de luz IR, sendo cada rajada um dígito binário (0 ou 1).

Para transmitir dados, o comando IR envia uma série de rajadas, cada uma composta por um bloco de dados com um Endereço, o seu inverso (complemento), um Comando e o seu inverso. Basicamente, cada botão do comando está associado a um bloco de dados de 32 bits, codificado assim.

Formato de Frame do Protocolo NEC IR
Endereço Inverso do Endereço Comando Inverso do Comando
Bits 0-7 Bits 8-15 Bits 16-23 Bits 24-31

Os bits do bloco de dados são convertidos em pulsos, onde um bit 0 é enviado como 562.5µs em nível alto + 562.5µs em nível baixo, e um bit 1 é enviado como 562.5µs em nível alto + 1.6875ms em nível baixo. Num osciloscópio, verias um sinal assim:

IR Pulses
Pulsos IR

No lado do recetor, um módulo recetor IR deteta as rajadas de luz infravermelha e demodula-as para extrair os dados binários.

Recetor IR

O recetor IR é o componente que recebe os sinais infravermelhos do comando. Consiste num fotodíodo que deteta a luz IR recebida e a converte em sinais elétricos. Em baixo podes ver um módulo recetor IR típico.

IR receiver module
Módulo Recetor IR

Para receber e descodificar o protocolo NEC, o recetor IR precisa de estar ligado a um microcontrolador capaz de ler e interpretar os sinais recebidos. Isto permite ao microcontrolador perceber os botões pressionados e executar as ações desejadas.

Na próxima secção, vou mostrar-te como ligar um recetor IR a uma placa ESP32 para receber e descodificar sinais IR. Fica atento!

Ligar o Recetor IR

Ligar o módulo recetor IR ao ESP32 é fácil. O circuito Fritzing abaixo mostra como se faz. Nota que estou a usar aqui um Lolin32 lite. No entanto, quase qualquer outra placa de desenvolvimento ESP32 também serve.

Connecting ESP32 Lolin32 to IR receiver module
Ligar Módulo IR ao ESP32

Primeiro, ligamos o pino de terra (GND) do ESP32 ao rail negativo da breadboard, usando um fio azul. Depois, ligamos o rail positivo da breadboard (marcado com uma linha vermelha), com um fio vermelho ao pino 3.3V da placa ESP32.

Agora, como já temos alimentação na breadboard, podemos ligar o módulo recetor IR. Liga o pino marcado com o sinal (-) do módulo recetor IR com um fio azul ao rail negativo da breadboard. Depois liga o pino marcado com (S) de Sinal ao Pino 4 do ESP32 (fio amarelo). Por fim, liga o pino restante do recetor IR com um fio vermelho ao rail positivo. Pronto!

Descodificar sinais IR

Para usarmos o nosso comando IR precisamos de saber que botão envia que código. O código seguinte vai ajudar-te a descobrir isso. Para mais detalhes vê o nosso 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 assim: Primeiro incluímos a biblioteca IRremote. Depois definimos a constante irReceiverPin para indicar à biblioteca a que pino está ligado o recetor IR.

A função setup

Na função setup() iniciamos a comunicação série a 9600 bauds, o que permite ao Arduino comunicar com o computador. Depois chamamos a função begin() do objeto IrReceiver, passando irReceiverPin e ENABLE_LED_FEEDBACK como argumentos. Isto inicializa o recetor IR e ativa o feedback LED no módulo recetor IR. Ou seja, vais ver um LED a piscar sempre que carregares num botão do comando e o módulo o detetar.

A função loop

Na função loop() verificamos se há um sinal recebido pelo recetor IR. Se for detetado um sinal, a função IrReceiver.decode() devolve true. Nesse caso, chamamos I rReceiver.printIRResultShort(), que imprime um resumo do sinal IR recebido no monitor Série. Depois, a função IrReceiver.resume() é chamada para preparar o recetor IR para o próximo sinal.

Por exemplo, se carregar em alguns botões do meu comando, obtenho a seguinte saída no monitor Série. Podes ver que foi detetado o protocolo NEC e quais os valores de Endereço e Comando enviados.

Serial output with decoded IR signal command values

Descodificar o meu comando IR

Quando executo o código acima e aponto os códigos dos comandos individuais, obtenho o seguinte mapeamento de botões para comandos no meu comando IR:

IR remote with command codes
Botão Endereço Código do comando
On/Off 0x00 0x52
Mode 0x00 0x4E
Set 0x00 0x40
Up 0x00 0x41
Down 0x00 0x44

Nota que o Endereço (0x00) é sempre o mesmo para todos os botões. Isso é habitual, mas comandos IR diferentes terão endereços diferentes. Para o teu comando IR este mapeamento de botões e códigos de comando será diferente e tens de usar o código acima para descobrir quais são.

Depois de teres os códigos do teu comando IR podes usá-lo para controlar todo o tipo de dispositivos. Nas próximas secções dou-te alguns exemplos.

Ligar e desligar um LED

Nesta secção vou mostrar-te como ligar e desligar um LED, usando o botão On/Off do comando.

Circuito para ligar/desligar um LED

Primeiro, precisamos de adicionar um LED ao nosso circuito. É simples. Basta colocar um LED na breadboard e ligar o seu ânodo (o pino mais comprido) através de uma resistência de 68Ω ao Pino 2 do ESP32. Depois, ligamos o cátodo do LED (o pino mais curto) ao GND da breadboard.

Connecting ESP32 Lolin32 to IR receiver module and an LED
Ligar ESP32 ao módulo recetor IR e a um LED

Nota que a placa ESP32 funciona a 3.3V. Por isso é necessário usar um valor de resistência relativamente baixo comparado com um circuito Arduino, que funciona a 5V. Com uma resistência maior o LED ainda acende, mas com menos intensidade.

Código para ligar/desligar um LED

Agora podemos usar o seguinte código para ligar ou desligar o LED na 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();
  }
}

O código é praticamente igual ao anterior. Só adicionamos uma nova constante (ledPin) para o pino onde o LED está ligado

const int ledPin = 2;

e uma função que alterna o estado de saída desse pino:

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

Sempre que chamamos esta função, o estado da saída alterna entre ligado e desligado. Isto faz com que o LED acenda ou apague. No entanto, não te esqueças de definir o pino como saída na função setup() !

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

No loop principal adicionamos um if statement que verifica se o código de comando recebido é 0x52. Esse é o código do botão On/Off que identificámos antes.

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

Se for esse o caso, alternamos o LED. Nota que não precisamos de verificar o endereço enviado pelo IrReceiver, pois é sempre o mesmo. No entanto, se quiseres reagir a sinais de comandos diferentes usando o mesmo recetor IR, podes ter de o fazer.

Por fim, esperamos 100ms para evitar alternar o LED repetidamente, caso o botão On/Off seja pressionado durante mais tempo.

E é isto. Agora já podes controlar um LED, um relé ou qualquer outro dispositivo de comutação com o teu comando IR.

Regular a intensidade de um LED

Vamos experimentar algo um pouco mais avançado. Em vez de simplesmente ligar ou desligar o LED, vamos controlar o seu brilho. Usamos o mesmo LED e circuito de antes, mas mudamos o código assim:

#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 perceber este código, vamos olhar primeiro para as funções setup e loop . Estas costumam ser praticamente iguais para a maioria das aplicações, por isso tornei-as o mais genéricas possível. Na função setup chamo uma função init() que inicializa os pinos e outras coisas. E na função loop chamo uma função execute() que executa um comando recebido do comando IR.

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

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

Com esta estrutura podemos manter as funções setup() e loop() iguais para diferentes aplicações e só precisamos de implementar ou modificar as funções init() e execute().

A função init

Por exemplo, para controlar o brilho do LED, implementamos a função init() assim:

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

Isto define o pino do LED como saída e também define o brilho inicial do LED através de analogWrite(), onde brightness é uma variável que definimos.

A função execute

A função execute() recebe um comando do comando IR e, se o comando for 0x41 (botão up), aumenta o brilho. Se o comando for 0x44 (botão down), diminui o brilho.

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 alterar o brilho, somamos ou subtraímos um incremento pré-definido (inc). Incrementos maiores mudam o brilho mais rapidamente. Incrementos menores dão uma alteração mais suave mas mais lenta.

Usamos analogWrite() para escrever o valor de brilho no ledPin. No entanto, o intervalo de valores que podes escrever numa saída analógica vai de 0 a 255. Temos de ter cuidado para não ultrapassar estes limites. Por isso usamos as funções min() e max() aqui. Elas garantem que os incrementos não fazem o valor do brilho sair do intervalo válido.

Por fim, analogWrite() exige que o pino de saída suporte PWM (Modulação por Largura de Pulso). Mas na maioria das placas ESP32 quase todos os pinos suportam PWM, por isso normalmente não há problema. Se tiveres dúvidas, consulta o pinout e procura um símbolo ondulado.

Na próxima secção vamos usar a mesma estrutura e princípio para controlar a frequência de um buzzer.

Ativar um Buzzer

Tal como o brilho dos LEDs, a frequência de um buzzer ativo pode ser controlada por um sinal PWM. Ou seja, com pequenas alterações podemos usar praticamente o mesmo código de antes. Mas primeiro vamos montar o circuito.

Circuito para ativar um Buzzer

Removemos o LED e substituímo-lo por um Buzzer. Não precisamos de resistência, só temos de garantir que ligamos o polo negativo do Buzzer ao rail negativo da breadboard e o polo positivo ao Pino 2 do ESP32.

Connecting ESP32 Lolin32 to IR receiver module and a Buzzer
Ligar ESP32 ao módulo recetor IR e a um Buzzer

Nota que o buzzer costuma ter um pequeno sinal de mais no topo que indica o polo positivo. Como é difícil de ver, certifica-te de que ligas o lado positivo ao Pino 2 do ESP32. Também garante que tens um buzzer active e não um passivo.

Código para ativar um Buzzer

Como prometido, o código para controlar o buzzer é muito semelhante ao do 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();
  }
}

Na função init() definimos o pino do buzzer como saída. Depois garantimos que o buzzer está desligado no início chamando no Tone().

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

Nota que noTone() e tone() são funções incorporadas do Arduino. Não precisas de incluir nenhuma biblioteca adicional para as usar.

Na função execute() voltamos a ouvir um comando do recetor IR e reagimos a ele.

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);
}

Se o botão Up (0x41) for pressionado aumentamos a frequência e se o botão Down (0x44) for pressionado diminuímos. Os valores válidos para a frequência vão de 0 a 65535. Por isso, como antes, usamos min() e max() para limitar o intervalo de valores.

Também quis poder ligar ou desligar o som. Por isso o código também verifica o botão Stop (0x52) e alterna a variável booleana do_sound. Depois disso, adicionamos um delay de 100ms para que a comutação não seja demasiado rápida.

A última coisa que precisamos de fazer é realmente tocar o som, o que é feito por esta linha de código:

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

Se do_sound for True, tocamos o tom na frequência definida, caso contrário desligamos o buzzer.

As funções setup() e loop() são as mesmas de antes. Pronto! Agora tens três exemplos de como usar um comando IR para controlar diferentes dispositivos. Também ficaste com uma estrutura de código simples, onde só tens de implementar as funções init() e execute() para controlar outros dispositivos.

Por exemplo, se quiseres controlar motores, vê os nossos tutoriais sobre How to Control a Servo with an IR Remote e Control a Stepper Motor with an IR Remote.

Por fim, este circuito e código só te permite receber sinais IR. Se quiseres enviar sinais, lê How to build a universal, programmable IR remote.

Conclusão

Neste tutorial, aprendemos a usar um comando IR com um ESP32. Começámos por perceber os componentes necessários para este projeto, que incluem uma placa ESP32 e um recetor IR.

De seguida, explorámos como funciona um comando IR e como envia sinais para o recetor IR. Depois passámos à ligação do recetor IR à placa ESP32, garantindo que os pinos necessários estão corretamente ligados.

Depois de montar o hardware, passámos ao código e aprendemos a ler os sinais IR usando a biblioteca IRremote. Implementámos várias funcionalidades, como ligar/desligar um LED, regular a intensidade de um LED e ativar um buzzer, com base nos sinais IR recebidos.

Ao seguires este tutorial, deves agora perceber como integrar um comando IR com um ESP32 e controlar diferentes componentes usando os sinais recebidos. Isto abre um leque enorme de possibilidades para os teus projetos, desde criar um sistema de automação doméstica controlado remotamente até construir um comando personalizado para as tuas próprias aplicações.

Se tiveres mais dúvidas ou encontrares algum problema ao trabalhar neste projeto, consulta a secção de Perguntas Frequentes abaixo. Além disso, podes encontrar links úteis para recursos e documentação relevantes para aprofundares os teus conhecimentos nesta área.

Boas experiências!

Perguntas Frequentes

Aqui estão algumas perguntas frequentes sobre o uso de um comando IR com um ESP32:

P: Posso usar qualquer comando IR?

R: Sim, a biblioteca IRRemote e o módulo IRReceiver que usámos aqui reconhecem a maioria dos comandos IR padrão. Outra opção possível é a biblioteca IRremoteESP8266. No entanto, é importante verificar a compatibilidade de frequência do comando com o módulo recetor IR que estás a usar.

P: Como descubro os códigos IR do meu comando?

R: Existem vários métodos para descobrir os códigos IR do teu comando. Uma forma é usar um módulo recetor IR e um Arduino ou ESP32 para capturar e descodificar os sinais, como mostrámos acima. Ou podes comprar um simples Component tester que consiga descodificar sinais IR. A última opção é procurar online pelo modelo específico do comando e ver se os códigos estão disponíveis.

P: Posso controlar vários dispositivos com um só comando IR?

R: Sim, podes controlar vários dispositivos com um único comando IR usando códigos IR diferentes para cada dispositivo. Ao descodificar os sinais IR e associá-los a ações específicas, podes controlar vários dispositivos como LEDs, motores ou até eletrodomésticos.

P: Qual é o alcance do sinal do comando IR?

R: O alcance de um comando IR depende de vários fatores, incluindo a potência do comando, a sensibilidade do recetor IR e obstáculos na linha de vista. Geralmente, o alcance pode variar de alguns metros até cerca de 10 metros.

P: Posso usar um comando IR com outros microcontroladores ou placas de desenvolvimento?

R: Sim, comandos IR podem ser usados com vários microcontroladores e placas de desenvolvimento. Vê o nosso tutorial sobre How to use an IR receiver and remote with Arduino, por exemplo.

Se tiveres outras perguntas ou precisares de mais ajuda, sente-te à vontade para perguntar na secção de comentários abaixo.

Links

Em baixo encontras alguns links para mais informações