Control por voz de dispositivos con ESP8266

Publicado por Marc en

Cuando no encontramos una solución al mercado compatible con Google Home o con Amazon Alexa, tenemos una solución fácil y económica:

Utilizar una microcontrolador ESP8266 para controlar el dispositivo que deseamos y a través del servicio de Adafruit MQTT y la plataforma IFTTT.com, poder controlarlo por voz.

Vamos por partes:

Utilizamos la placa de desarrollo Wemos d1 mini basada con el chip ESP8266 que lo utilizaremos como pequeño «ordenador» para controlar lo que necesitamos. Aquí puedes encontrar más información

Esta placa tiene 11 pines digitales de entrada y salida y 1 pin analógico que podemos utilizar para conectar sensores o actuadores.

Placa Wemos D1 mini basada en el chip ESP8266

Esta placa de desarrollo, la podemos encontrar aquí.

Esta placa tendremos que programarla para que haga lo que nosotros queramos.

Para programarla, debemos descargar gratuitamente el software IDE de Arduino ya sea por MAC, Linux o Windows. Puedes encontrarlo aquí.

Una vez descargado, lo abrimos y tenemos que ir a File y Preferences.

Vamos al campo «Additional Boards Manager» y añadimos el siguiente enlace: https://arduino.esp8266.com/stable/package_esp8266com_index.json

Con esto hacemos que, aunque la placa Wemos no es de Arduino, la podamos programar con el mismo IDE de Arduino.

Entonces vamos a Tools, Board y Boards Manager …

Escribimos «Wemos» y «Install» y se nos descargará el pack de las placas Wemos para que las podamos programar.

Vamos a Tools, Board, y seleccionamos la placa Wemos D1 Mini. Ahora ya podremos programar la placa

Conectamos la placa Wemos d1 mini con un cable microUSB – USB en el ordenador donde hayamos descargado el software IDE Arduino

Vamos al software IDE Arduino y vamos a Tools, Puerto y seleccionamos el puerto que aparezca (que será el que hayamos conectado la placa)

Ahora ya tenemos la placa preparada para poder programarla. Vamos a exponer un ejemplo, que se puede cambiar por la necesidad específica que tengamos haciendo pocos cambios: Control de un relé.

Un relé tiene 3 contactos: Un contacto COMÚN (C), un normally CLOSED (NC) y un normally OPEN (NO) y tiene una alimentación, en nuestro caso 5V (VCC y GND y una señal de activación (SIG).

Este relé, lo podemos conectar encima del Wemos d1 mini y sólo tendremos que conectar los contactos C y NO. La señal le vendrá por pin D1.

Este relé lo podemos encontrar aquí.

En este relé, como ejemplo podemos conectar una bombilla:

Ahora vamos a programar la placa Wemos d1 mini para que cuando llegue la orden de voz «Activar luz«, se active el relé y encienda la bombilla y cuando llegue la orden «Desactivar luz«, se desactive el relé y se apague la luz.

Antes de poder programarla tenemos que ir a la web adafruit.io y registrarnos con nuestro correo de GMAIL y una contraseña.

Vamos a Feeds, Actions y «Create a New Feed«

Le ponemos un nombre, por ejemplo: rele_on_off

y hacemos clic en Create

Vamos a Dashboards, Actions y «Create a New Dashboard»

Le ponemos un nombre, por ejemplo: Rele

y hacemos clic en Create

Una vez creado este Dashboard, hacemos clic en «Rele».

Pulsamos el «+» y seleccionamos el primer icono, un block ON / OFF

Seleccionamos el Feed que hemos creado antes: rele_on_off y «Next step«

Ponemos un nombre al block, por ejemplo: Rele y y hacemos clic en Create block

Sin movernos de la página, seleccionamos el icono con el símbolo de una llave y copiamos lo que está marcado de color rojo, lo pegaremos en el código en el software de Arduino IDE.

Ahora si, ya podemos ir al código que tendremos que pegar al software Arduino IDE que nos hemos descargado. El código lo tenéis aquí, sólo tienes que cambiar el nombre y contraseña de tu WIFI y el USERNAME y el KEY de tu dashboard de Adafruit.

Ahora ya podremos subir el código en la placa Wemos, comprobamos que la placa esté conectada a un puerto USB del PC y que tengamos el puerto y el tipo de placa (Wemos d1 mini) seleccionada.

Seleccionamos la «Flecha» para hacer un «Upload» y subir el código en la placa.

Esperamos 1 minuto hasta que aparezca un texto en la parte inferior izquierda «Done uploading«

Colocamos el relé encima la placa Wemos y podemos probar desde la aplicación de Adafruit si el relé se activa, ya que lleva un led azul y además se siente el ruido de «clic». También se puede conectar la luz para comprobar que funcione.

Si funciona, ahora vamos al último paso, para poder controlar el relé y la luz por voz.

Vamos a la web https://ifttt.com/ Esta web sirve para conectar muchísimos servicios que están conectados a internet. Nos registraremos con el correo de GMAIL que utilizamos en nuestro Google Assistant y una contraseña.

Vamos al icono del usuario y seleccionamos «Create«

Pulsamos en «+» y seleccionamos el servicio «Google Assistant» y «Say a simple phrase» y rellenamos el siguiente recuadro:

Podemos poner diferentes nombres para activar el mismo dispositivo y podemos poner que queremos que nos responda el asistente para confirmarnos que ha hecho la acción que le pedimos.

Elegimos la opción Spanish y seleccionamos «Create trigger«

Pulsamos en «+» (en este cado el That) y seleccionamos el servicio «Adafruit» y «Send data to Adafruit.io«

Seleccionamos el Feed rele_on_off y en Data to save ponemos en este caso «ON«

Y pulsamos «Create action«

Ahora tendremos que repetir estos últimos 2 pasos para dar una orden de voz para apagar el relé y la luz. En este caso, la Data to save deberá ser «OFF«.

El último paso es intentar dar las órdenes de voz y comprobar que funcione:

«Ok Google» «Activar luz»

«Ok Google» «Desactivar luz»


16 commentarios

francisco · 10/05/2020 a las 08:58

Muy bien explicado todo, gracias.
Tengo una pregunta, se podrían cargar a la Wemos mas de un usuario y contraseña de AIO? con el fin de poder controlar, por ejemplo, dos o más relés con comandos de voz distintos. Gracias.

Marc · 10/05/2020 a las 21:39

Buenas Francisco,
Si, puedes controlar diferentes relés, por supuesto.

Para empezar, tienes que ir a adafruit.io y crear un nuevo feed (por ejemplo: rele2_on_off) y un nuevo dashboard (por ejemplo: Rele2) y crear un bloque de ON/OFF como explico en el post.

Después te vas al codigo del ESP8266 y creas éstas lineas:

// Aquí decides al pin en que conectas tu nuevo relé, p.ej al pin D2
int RELE = D1;
int RELE2 = D2;

// Esta línea ya la tienes creada, solo se trata de duplicarla y cambiar el nombre del Feed por el nuevo que has creado en Adafruit.io
Adafruit_MQTT_Subscribe rele_on_off = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME «/f/rele_on_off»);
Adafruit_MQTT_Subscribe rele2_on_off= Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME «/f/rele2_on_off»);

//En voidSetup añades la nueva salida y el estado inicial…
pinMode(RELE, OUTPUT);
pinMode(RELE2, OUTPUT);
digitalWrite(RELE, HIGH);
digitalWrite(RELE2, HIGH);

//Subscribe to the onoff topic. Añades el nuevo feed
mqtt.subscribe(&rele_on_off);
mqtt.subscribe(&rele2_on_off);

//La siguiente parte del código lo pegas justo después de la parte del código que tienes igual con los datos del rele1 (con el nombre del nuevo Feed y del nuevo Relé).
if (subscription == &rele2_on_off)
{
//Print the new value to the serial monitor
Serial.print(«Rele2_ON_OFF: «);
Serial.println((char*) rele2_on_off.lastread);

//If the new value is «ON», turn the relay on.
//Otherwise, turn it off.
if (!strcmp((char*) rele2_on_off.lastread, «ON»))
{
//active low logic
digitalWrite(RELE2, LOW);
}
else if (!strcmp((char*) rele2_on_off.lastread, «OFF»))
{
digitalWrite(RELE2, HIGH);
}
}

Lo subes al ESP8266 y ya puedes probarlo desde la ventana de Dashboard de Adafruit.io. Si te funciona ya puedes ir a ifttt.com y crear 2 nuevos Applets ahora con el Feed del Rele2 (1 para ON y otro para OFF).

Ahora lo he probado y funciona perfectamente. Si tienes alguna duda, ya sabes.
Un saludo, suerte!

    francisco · 13/05/2020 a las 21:22

    Genial!!! Muchas gracias por responder!

Oscar · 08/06/2020 a las 11:15

Buenas!
Lo he hecho y funciona genial, pero tengo una duda. Ahora me aparece en casa una red ESP-BXXXXX. Que en principio no sirve para poder acceder a una web que te permita el control del arduino. Hay alguna posibilidad de ocultar dicha red por código? Lo digo para evitar el posible acceso de personas no deseadas que puedan hackearlo y acceder a mi red.

Gracias!

Marc · 08/06/2020 a las 21:49

Buenas Oscar, si añades ésta línea en el voidsetup te deshabilitará el SSID que crea de punto de acceso:

WiFi.softAPdisconnect (true);

Un saludo!

    Oscar · 09/06/2020 a las 07:47

    Muchas Gracias por tu ayuda Marc! Me funciono perfecto!
    Un saludo!

bruno · 28/06/2020 a las 15:18

Muy bueno la verdad , buenas , disculpe la molestias pero esto se podría hacer con una lampara rgb y poder cambiar los colores por voz??

Luis · 30/06/2020 a las 17:18

Hola,
Necesito ayuda con el sketch. Quiero intercalar el uso por voz con un interruptor a través de una entrada.
He hecho esto como si se tratara de una condición «O», es decir que lo active la web de adafruit o bien el interruptor, pero no logro que funcione.

#include
#include «Adafruit_MQTT.h»
#include «Adafruit_MQTT_Client.h»
#define FEED_NAME_ON_OFF «rele_on_off»
#define FEED_STATE «estado_rele»
#define MQTT_SERV «io.adafruit.com»
#define MQTT_PORT 1883

int RELE = 5; // D1(gpio5)
int button = 4; //D2(gpio4)
int buttonState=0;

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);

Adafruit_MQTT_Subscribe rele_on_off = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME «/f/rele_on_off»);

void setup()
{
Serial.begin(9600);
pinMode(RELE, OUTPUT);
pinMode(button, INPUT);
digitalWrite(RELE, LOW);

//Connect to WiFi
Serial.print(«\n\nConnecting Wifi>»);
WiFi.begin(WIFI_SSID, WIFI_PASS);
WiFi.softAPdisconnect (true);

while (WiFi.status() != WL_CONNECTED)
{
Serial.print(«>»);
delay(50);
}
Serial.println(«OK!»);

//Subscribe to the onoff topic
mqtt.subscribe(&rele_on_off);
}

void loop()
{
buttonState=digitalRead(button);
//Connect/Reconnect to MQTT
MQTT_connect();

//Read from our subscription queue until we run out, or
//wait up to 5 seconds for subscription to update
Adafruit_MQTT_Subscribe * subscription;
while ((subscription = mqtt.readSubscription(5000)))
{
//If we’re in here, a subscription updated…
if (subscription == &rele_on_off)
{
//Print the new value to the serial monitor
Serial.print(«Rele_ON_OFF: «);
Serial.println((char*) rele_on_off.lastread);

//If the new value is «ON», turn the light on.
//Otherwise, turn it off.
if (!strcmp((char*) rele_on_off.lastread, «ON»)||(buttonState == 1))
{
//active low logic
digitalWrite(RELE, HIGH);
}
else if (!strcmp((char*) rele_on_off.lastread, «OFF»)||(buttonState == 0))
{
digitalWrite(RELE, LOW);
}
}
}
}

void MQTT_connect()
{

// // Stop if already connected
if (mqtt.connected() && mqtt.ping())
{
// mqtt.disconnect();
return;
}

int8_t ret;

mqtt.disconnect();

Serial.print(«Connecting to MQTT… «);
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
{
Serial.println(mqtt.connectErrorString(ret));
Serial.println(«Retrying MQTT connection in 5 seconds…»);
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries–;
if (retries == 0)
{
ESP.reset();
}
}
Serial.println(«MQTT Connected!»);
}

Muchas gracias de antemano.

Y enhorabuena por la web, es muy útil para hacer divulgación para gente amateur de la programación como yo 🙂

Marc · 02/07/2020 a las 22:09

Y si pruebas de poner ésto justo después de void loop() ?

void loop()
{
if (digitalRead(D2) == LOW){
//active low logic
digitalWrite(RELE, LOW);
}
else if (digitalRead(D2) == HIGH){
//active low logic
digitalWrite(RELE, HIGH);
}

Marc · 02/07/2020 a las 22:09

Y si pruebas de poner ésto justo después de void loop() ?

void loop()
{
if (digitalRead(D2) == LOW){
//active low logic
digitalWrite(RELE, LOW);
}
else if (digitalRead(D2) == HIGH){
//active low logic
digitalWrite(RELE, HIGH);
}

Aryel · 29/07/2020 a las 07:22

Hola, qué tal, tengo un problema, cambié el foco por una tira LED unicolor que se alimenta de 12V. Solo que cuando mando la señal para que cambie el estado a quejado apagado, la tira queda encendida. El relé no suena aunque sí enciende su LED que indica el cambio de estado… ¿Qué podría hacer para cambiar eso? No estoy ocupando el transistor que está en el circuito ¿es obligatorio usarlo?

Manu · 22/09/2020 a las 00:27

Hola buenas noches, estoy intentando hacer este proyecto pero con Nodemcu esp8266 esp12e cp2102. y a la hora de cargar el codigo me salta error.

wemos_rele:14:27: fatal error: Adafruit_MQTT.h: No such file or directory
#include «Adafruit_MQTT.h»
^
compilation terminated.
exit status 1
Adafruit_MQTT.h: No such file or directory

Alguno me podría ayudar. Muchas gracias

Responder a Luis Cancelar la respuesta

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