Controlando TV com Assistente de Voz e ESP8266

TV-Assistente-Voz-ESP8266
Font Size

Fala galera, tudo bem? Já pensou em controlar seus aparelhos apenas com o seu celular?! Bom, neste post apresentaremos como controlar sua TV com assistente de voz do Google e ESP8266, utilizando um hardware mínimo e uma configuração simples. Então, vamos nessa?!

Conhecendo a Infraestrutura do Sistema

O ambiente IoT (Internet das Coisas) tem proporcionado diversas maneiras de controlar e monitorar objetos em nosso cotidiano. A integração de tecnologias, como inteligência artificial, no aprimoramento de equipamentos e a inovação de sensores fazem parte das novas tendências desse ecossistema.

Com isso, muitas plataformas têm sido desenvolvidas para permitir a integração desses dispositivos sem a necessidade de conhecimentos específicos em programação. Exemplo disso é a plataforma gratuita IFTTT. Ela possibilita a conexão de diversos serviços por meio de comandos, como Twitter, Webhooks, Gmail, Assistente Google e outros.

Seu princípio de configuração é muito parecido com o método ECA (Evento – Condição – Ação) da programação orientada a eventos. O nome da plataforma já indica esse conceito: “If This, Then That”, ou seja, “Se isso acontecer, então faça aquilo”. Isso significa que ao ocorrer um evento, uma condição específica é verificada e com base em seu resultado uma ação apropriada é executada.

Dessa forma, utilizaremos dois serviços da plataforma para elaborar nosso sistema, o Assistente do Google e o Adafruit IO, um serviço em nuvem que permite a transmissão e interação de dados através do protocolo MQTT.

Desenvolvimento do Projeto TV Assistente Voz ESP8266

Agora que esclarecemos os serviços a serem utilizados, iremos compreender o desenvolvimento do projeto. Primeiramente, devemos configurar a plataforma IFTTT para receber os comandos do Assistente de voz do Google e enviá-los ao Adafruit IO.

Este se comunicará com nosso dispositivo NodeMCU que enviará os comandos à TV através de um emissor infravermelho, simulando um controle remoto. O sistema referido pode ser visto a seguir:

Figura 1 – Sistema de Conexão entre o Assistente de Voz com NodeMCU

Dessa forma, este post foi organizado em quatro partes principais:

A seguir, iniciaremos a configuração necessária do Adafruit IO e o passo-a- passo para a execução do projeto.

Configurando o Serviço Adafruit IO

Entre no site da plataforma e crie uma conta. Fique atento ao seu nome de usuário e seu AIO Key que podem ser localizados na parte superior da interface principal. Eles serão utilizados para a autenticação no aplicativo.

Em seguida, clique na guia “Feeds” para criarmos um novo campo. Um Feed equivale a um tópico do protocolo MQTT. Ele separa o fluxo de mensagens por assunto. Dessa forma, podemos restringir os nossos comandos em um Feed específico, no qual somente nosso sistema terá acesso.

Para isso, clicamos em “Actions” e, em seguida, “Create a New Feed”. No campo “Name” definiremos como “controleIR” e, por fim, clicamos em “create” para gerar nosso novo Feed. Podemos visualizar sua atividade em tempo real clicando sobre ele. Você pode observar abaixo os passos utilizados para criação do Feed:

Figura 2 – Passos para criar um Feed no Adafruit IO

Isto é tudo que precisamos, por enquanto. Em seguida, iremos configurar nossa plataforma IFTTT, definindo inclusive, nosso tópico recém criado.

Configurando a Plataforma IFTTT

Crie uma conta e entre na plataforma. A interface do aplicativo apresenta diversos serviços para se conectar. Você pode, então, selecioná-los e definir as ações que devem ser realizadas. Cada regra criada é chamada de Applet. Para isso, devemos clicar em nosso usuário (no cabeçalho à direita) e selecionar a opção “create”. Em seguida, realize os passos:

  1. Clique no símbolo “+ This” e procure o serviço Google Assistant.
  2. Clique na opção “Connect” e, em seguida, no cartão “Say a simple phrase”.
  3. Complete os campos fornecidos. No primeiro campo, escrevemos a frase a ser dita, por exemplo: “Turn on the TV”. Caso queira que o assistente responda com algo, você pode completar o quarto campo, como o exemplo: “Ok, é pra já mestre”.
  4. Clique em “Create Trigger” para definir o evento.

Nesse momento, acabamos de criar o gatilho ou evento. Agora, devemos definir a ação desejada ao recebê-lo. Então, continue com os seguintes passos:

  1. Clique no símbolo “+ That” e procure o serviço Adafruit.
  2. De forma semelhante, clique na opção “Connect” e, em seguida, no cartão “Send data to Adafruit IO”.
  3. No campo “Feed name” selecione o Feed que criamos no tópico anterior chamado “controleIR” e no campo “Data to Save” defina a mensagem que será enviada ou comando, por exemplo “command_01”. Assim, ficará fácil listar os comandos.
  4. Por último, clique em “finish” e, em seguida, em “Connect” caso não esteja conectado ainda.

A imagem abaixo resume os passos descritos:

Figura 3 – Passos para criar um Applet no IFTTT

Então, é isso. Você acabou de criar a sua primeira regra. Simples, não?! Você pode acompanhá-las na opção “My Applets” disposta na guia de seu usuário (no cabeçalho à direita). Inclusive, você pode criar novas frases, elaborando vários comandos para controlar sua TV.

Configurando Assistente de Voz

Como você viu no passo 3, o IFTTT só permite, até o momento, seis linguagens, estando como padrão, o inglês. Para contornar esse problema, podemos criar rotinas em nosso assistente que convertem as frases ditas em português para as definidas em nosso Applet. Portanto, faremos o seguinte:

  1. Entre nas configurações de sua conta Google e procure a opção “Assistente”.
  2. Em seguida, selecione a opção “Rotinas”.
  3. Selecione a opção “+ Adicionar uma rotina”.
  4. Na guia “Quando” selecione a opção “Adicionar comandos (obrigatório)” e escreva a frase a ser dita, como no exemplo: “Assistir TV agora”.
  5. Na guia “O assistente vai” selecione a opção “+ Adicionar ação” e escreva a frase que criamos em nosso Applet: “Turn on the TV”.
  6. Por último, selecione Salvar para criarmos a rotina.

A imagem abaixo ilustra os passos realizados:

Figura 4 – Configurando Rotinas no Assistente de Voz

A seguir, iremos apresentar a estrutura de hardware e a montagem do nosso circuito.

Montagem do Circuito

Conforme citado anteriormente, o controle da TV será realizado através de um emissor infravermelho (IR) conectado ao ESP8266 que receberá as informações do Adafruit IO. A seguir, apresentaremos a lista completa dos materiais necessários. Estes e muitos outros componentes podem ser encontrados em nossa loja.

Componentes do Projeto:

Agora, podemos iniciar a montagem do circuito. Primeiramente, devemos utilizar o módulo receptor KY-022 para detectar o padrão e salvar os códigos do nosso controle. Você pode encontrar o esquema eletrônico e o passo a passo para identificação dos comandos clicando aqui.

Para fins de simplificação, iremos focar apenas no desenvolvimento do circuito e código final. Após salvar os comandos do nosso controle remoto, montaremos o circuito com o módulo emissor KY-005 da seguinte forma:

Figura 5 – Ligação do Módulo Emissor KY-005 no NodeMCU

Nesta montagem, conectamos o pino de dados do emissor ao pino D2 do NodeMCU. Na IDE do Arduino este pino equivale ao número 4 (GPIO4), como será visto a seguir.

Código do Projeto

/*
    Projeto: Controlando TV com Assistente de Voz e ESP8266
    Autor: Daniel Fiuza - AutoCore Robótica
    Data: 13/03/2020
    Código de Domínio Público  
*/

// Declaração das Bibliotecas
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include "AdafruitIO_WiFi.h"

// Configuração dos Comandos
#define LIGAR_TV  0x20DF10EF
#define NETFLIX   0x20DF6A95
#define CONFIRMAR 0x20DF22DD

// Configuração Wifi
#define WIFI_SSID "seu_ssid"
#define WIFI_PASS "sua_senha_wifi"

// Configuração Adafruit IO
#define IO_USERNAME "seu_nome_de_usuario"
#define IO_KEY "sua_aio_key"

// Instancia Objeto io do Adafruit
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

// Definindo Feed do Adafruit IO
// OBS: Nome do Feed em minúsculo
AdafruitIO_Feed *topic = io.feed("controleir");

// Instancia objeto IRsend
// OBS: É importante escolher um pino que suporte PWM
// GPIO4 é equivalente ao pino D2 do NodeMCU
IRsend irsend(4);

void setup() {
  // Iniciando módulo IR
  irsend.begin();

  // Iniciando porta Serial
  Serial.begin(115200);

  // Espere o monitor serial abrir
  while(!Serial)
      delay(50);
  
  Serial.print("Conectando-se ao Adafruit IO");

  // Inicia uma conexão MQTT para o io.adafruit.com
  io.connect();

  // Definindo a função sendCommand para o método onMessage do MQTT.
  // Esta função será chamada sempre que o ESP8266 receber uma mensagem do Adafruit IO.
  // Então, ela processará a mensagem e enviará o comando para a TV.
  topic->onMessage(sendCommand);

  // Espere estabelecer a conexão MQTT.
  while(io.mqttStatus() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  // Conexão MQTT estabelecida.
  Serial.println();
  Serial.print("Conexão MQTT Estabelecida!");


}

void loop() {
  // Este método irá manter a conexão MQTT ativa.
  // Isto é suficiente, pois definimos o método onMessage que ficará
  // esperando uma nova mensagem para, então, processá-la.
  io.run();
}

void sendCommand(AdafruitIO_Data *data) {
  Serial.print("Comando recebido: ");
  Serial.println(data->value());
  
  // Copia o valor recebido para a string msg
  String msg = data->value();
  
  // Compara se a string msg é igual a 'command_01', então liga a TV.
  if(msg.equals("command_01")){ Serial.print("Ligando a TV"); irsend.sendNEC(LIGAR_TV);}
  // Compara se a string msg é igual a 'command_02', então inicia a Netflix.
  else if(msg.equals("command_02")){ Serial.print("Iniciar Netflix"); irsend.sendNEC(NETFLIX);}
  // Compara se a string msg é igual a 'command_03', então envia o comando OK do controle.
  else if(msg.equals("command_03")){ Serial.print("Botão Confirmar"); irsend.sendNEC(CONFIRMAR);}
  // Se msg não for igual a nenhum comando cadastrado, apenas imprime a seguinte mensagem.
  else{ Serial.print("Comando não encontrado.");}
}

Descrição Detalhada do Código

Primeiramente, foram declaradas as bibliotecas Arduino, IRremoteESP8266, IRsend e AdafruitIO_Wifi, como descrito abaixo:

#include <Arduino.h>            
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include "AdafruitIO_WiFi.h"

Posteriormente, definimos as configurações iniciais que serão utilizadas no decorrer do código. Primeiro criamos uma lista de defines contendo os códigos detectados do controle remoto e sua função, a fim de facilitar o uso dos comandos. Em seguida, realizamos os parâmetros do Wifi e do Adafruit IO.

Então, instanciamos o objeto io com os parâmetros definidos e indicamos o feed que criamos na etapa de configuração do Adafruit IO. Logo depois, instanciamos o objeto irsend que enviará os comandos pelo módulo emissor IR. As configurações são apresentadas a seguir:

<code>// Configuração dos Comandos 
#define LIGAR_TV  0x20DF10EF
#define NETFLIX   0x20DF6A95
#define CONFIRMAR 0x20DF22DD

// Configuração Wifi
#define WIFI_SSID "DANIEL_IBLTELECOM"
#define WIFI_PASS "cls21091996"

// Configuração Adafruit IO
#define IO_USERNAME "Daniel_Fiuza"
#define IO_KEY "f67b6380b08f4eebbee66af1f9d089ae"

// Instancia Objeto io do Adafruit
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

// Definindo Feed do Adafruit IO
// OBS: Nome do Feed em minúsculo
AdafruitIO_Feed *topic = io.feed("controleir");

// Instancia objeto IRsend
// OBS: É importante escolher um pino que suporte PWM
// GPIO4 é equivalente ao pino D2 do NodeMCU
IRsend irsend(4);</code>

Em seguida, inicializamos o módulo IR e a porta Serial, aguardando até que esta esteja aberta.

<code>// Iniciando módulo IR
irsend.begin();

// Iniciando porta Serial
Serial.begin(115200);

// Espere o monitor serial abrir
while(!Serial)
    delay(50);</code>

Logo após, iniciamos a conexão MQTT com o método io.connect e definimos o método onMessage e a função sendCommand. Este método é uma função de retorno de chamada. Ela é executada sempre que nosso cliente MQTT receber uma mensagem do Adafruit IO e, então, chama a função sendCommand.

Dessa forma, durante toda a execução do programa, ele ficará aguardando um novo dado por meio deste método para, em seguida, processá-lo.

<code>Serial.print("Conectando-se ao Adafruit IO");

// Inicia uma conexão MQTT para o io.adafruit.com
io.connect();

// Definindo a função sendCommand para o método onMessage do MQTT.
// Esta função será chamada sempre que o ESP8266 receber uma mensagem do Adafruit IO.
// Então, ela processará a mensagem e enviará o comando para a TV.
topic->onMessage(sendCommand);

// Espere estabelecer a conexão MQTT.
while(io.mqttStatus() &lt; AIO_CONNECTED) {
  Serial.print(".");
  delay(500);
}

// Conexão MQTT estabelecida.
Serial.println();
Serial.print("Conexão MQTT Estabelecida!");</code>

Na função loop, apenas manteremos a conexão MQTT aberta com o método io.run, visto a seguir:

void loop() {
  // Este método irá manter a conexão MQTT ativa.
  // Isto é suficiente, pois definimos o método onMessage que ficará
  // esperando uma nova mensagem para, então, processá-la.
  io.run();
}

Por fim, a função sendCommand recebe os dados como parâmetro, transfere para a string msg que criamos e compara com os comandos que desenvolvemos no tópico de configuração do IFTTT.

Dessa forma, caso seja igual a algum dos comandos definidos, será enviado o comando correspondente através da função irsend.sendNEC, conforme apresentado a seguir:

void sendCommand(AdafruitIO_Data *data) {
  Serial.print("Comando recebido: ");
  Serial.println(data->value());
  
  // Copia o valor recebido para a string msg
  String msg = data->value();
  
  // Compara se a string msg é igual a 'command_01', então liga a TV.
  if(msg.equals("command_01")){ Serial.print("Ligando a TV"); irsend.sendNEC(LIGAR_TV);}
  // Compara se a string msg é igual a 'command_02', então inicia a Netflix.
  else if(msg.equals("command_02")){ Serial.print("Iniciar Netflix"); irsend.sendNEC(NETFLIX);}
  // Compara se a string msg é igual a 'command_03', então envia o comando OK do controle.
  else if(msg.equals("command_03")){ Serial.print("Botão Confirmar"); irsend.sendNEC(CONFIRMAR);}
  // Se msg não for igual a nenhum comando cadastrado, apenas imprime a seguinte mensagem.
  else{ Serial.print("Comando não encontrado.");}
}

Resultado do Projeto

A seguir, deixo o vídeo onde demonstro como controlar a TV com o Assistente de Voz e o ESP8266, descritos em nosso projeto.

https://youtu.be/8XsvhKP7X5A

Então, gostou do nosso projeto? Caso haja alguma dúvida, comente abaixo.

Posts relacionados

Criando aplicativo com App Inventor: Parte 1

por Danilo Nogueira
5 anos ago

Utilizando a tecnologia RFID com Arduino

por Danilo Nogueira
5 anos ago

Como utilizar o sensor LM35 com Arduino?

por Danilo Nogueira
6 anos ago
Sair da versão mobile