Objetivos
Material requerido
Una Protoboard. | |
4 diodos LED de colores. | |
4 resistencia de 330 Ohmios. | |
Algunos cables de Protoboard macho-macho y macho-hembra. | |
Un módulo de reconocimiento de voz Elechouse Voice Recognition V3. |
MÓDULO DE RECONOCIMIENTO DE VOZ
A estas alturas ya nos hemos acostumbrados a poder interactuar con ciertos dispositivos electrónicos por medio de nuestra voz, sobre todo y como casi siempre, con los omnipresentes smartphones.
Y aunque con nuestros Arduinos no vamos a ser capaces de emular a Siri (o a Cortana), vamos a poder meternos de lleno en el tema del reconocimiento de voz de una forma sorprendentemente sencilla gracias al módulo Elechouse Voice Recognition V3.
Evidentemente, no podemos esperar que hablemos y de una forma innata nuestro Arduino entienda lo que decimos, sino que tendremos que grabar anteriormente los comandos que queramos utilizar en nuestro programa.
Antes de ponernos a trabajar con el módulo, vamos a hablar un poco de sus características y sus limitaciones. El módulo tiene capacidad para almacenar hasta 255 comandos de voz diferentes, pero sólo podremos utilizar a la vez 7 de ellos. Además los comandos pueden tener una duración de unos 2 o 3 segundos.
La forma de trabajar con él será la siguiente:
El módulo es muy fácil de conectar, tiene 2 pines para la alimentación y 2, Tx y Rx, para comunicarse con nuestro Arduino. Como vamos a utilizar la librería SoftwareSerial, podéis utilizar los pines que queráis, nosotros vamos a utilizar los pines 2 y 3 porque son para los que vienen configurados los ejemplos de la librería que vamos a utilizar. Además tenemos que conectarle el micrófono en el jak.
Y como acabamos de adelantar, necesitaremos descargar esta librería: voicerecognitionv3. La librería se encargará de hacer el trabajo “sucio”, y además tiene ya preparado el programa que nos servirá para grabar nuestros comandos de voz y cargarlos en el módulo.
GRABAR Y CARGAR EN EL MÓDULO LOS COMANDOS DE VOZ
Cada vez que queramos grabar, cargar, modificar o borrar los comandos que tengamos en el módulo, tendremos que arrancar uno de los ejemplos que vienen con la librería: vr_sample_train. Después de cargar el programa, abrimos el monitor serie y lo configuramos para trabajar a 115.500 baudios. Nos encontraremos con una pantalla como esta:
Ahí nos aparecen los comandos que tenemos disponibles y su forma de utilizarlos. Basta con introducirlos en la línea de comandos. Los que nosotros utilizaremos serán: sigtrain y load; aunque por supuesto podéis probar a utilizar los demás. En la columna “Comment” tenéis una breve explicación de la finalidad que tienen.
El primero que vamos a usar es el comando sigtrain que sirve para grabar los comandos de voz. Junto al comando le pasaremos la posición en la que queremos que se guarde y el nombre que queremos asignarle.
Como para probarlo vamos a utilizar un ejemplo que enciende y apaga un LED, tendremos que grabar dos voces, una para encenderlo y otro para apagarlo. Para grabar la primera escribiremos: “sigtrain 0 Encender”.
Cuando pulsemos ”Intro” veremos como en el módulo comienza a parpadear un LED naranja rápidamente. Es la señal para que nos preparemos. Tendremos que grabar cada comando dos veces, y si coinciden se guardarán. Si no es así tendremos que grabar más veces hasta que coincidan.
El procedimiento es el siguiente:
Mientras hacemos esto en el monitor serie veremos una serie de mensajes que nos irán guiando durante el proceso de grabación.
Para grabar el comando para apagar el procedimiento será exactamente el mismo, pero usaremos el comando “sigtrain 1 Apagar”.
Ahora tendremos que cargar las voces que hemos grabado. Para ello utilizaremos el comando load, indicándole que números de comando queremos cargar, en nuestro caso el 0 y el 1: “load 0 1”. Si se graban correctamente veremos un mensaje indicándonoslo en el monitor serie. Recordad que el máximo de comandos a cargar son 7 de entre los 255 que podemos llegar a grabar.
Para comprobar que todo funciona correctamente, vamos a abrir otro de los ejemplos que vienen con la librería: vr_sample_control_led. De momento no vamos a comentar nada de la programación (lo haremos más adelante), y nos limitaremos a ver que todo funcione correctamente.
Este programa lo que hace es encender y apagar el LED conectado al pin 13 de Arduino en función del comando de voz que reconozca el módulo. Es importante que hayáis grabado los comandos en el orden que hemos indicado, 0 para encender y 1 para apagar, u os funcionará al revés.
Dicho esto no tenéis más que cargarlo y probar si cuando decimos “Encender” o “Apagar” efectivamente el LED responde como debe. En el monitor serie podemos ver qué comandos se han cargado al cargar el programa, y nos mostrará cada vez que se reconozca un comando de voz.
PROGRAMA CON RECONOCIMIENTO DE VOZ
Bueno, pues una vez que ya sabemos grabar y cargar las voces, y hemos probado que funciona correctamente, vamos a ver cómo hacemos para crear un programa propio que incluya un mayor número de comandos.
Podemos usarlo para cualquier cosa: encender y apagar luces, relés, motores, posicionar servos… o cualquier cosa que se os ocurra. La limitación es que sólo podemos usar 7 comandos de voz en un mismo programa, y que no pueden durar más de 2 o 3 segundos.
Nosotros vamos a crear un programa que simule el encendido y apagado de luces de una casa, utilizando nuestra voz a modo de interruptor. Para ello Conectaremos 4 LEDs, que corresponderán al salón, la cocina, el baño y la habitación.
Lo que pretendemos es que cuando nombremos una de esas estancias se encienda la luz si estaba apagada, y se apague si estaba encendida. Además utilizaremos dos comandos de voz más: “Encender” para encender todos los LEDs y “Apagar” para apagar todos.
Así que, lo dicho, abrimos el programa para grabar y cargar los comandos y grabamos y cargamos los seis comandos que vamos a utilizar:
sigtrain 0 Salon sigtrain 1 Cocina sigtrain 2 Bano sigtrain 3 Habitacion sigtrain 4 Encender sigtrain 5 apagar load 0 1 2 3 4 5
A la hora de crear el programa, no vamos a hacerlo desde cero, sino que vamos a aprovechar el programa que viene de ejemplo con la librería que hemos utilizado antes y lo vamos a modificar a nuestro antojo, de forma que no tendremos que preocuparnos de la conversión y comparación de los comandos de voz. Mi consejo es que habráis el ejemplo que hemos utilizado anteriormente y le deis a “Guardar como”, de forma que le podremos poner el nombre que queramos y modificarlo a nuestra conveniencia a partir de ahora sin fastidiar el ejemplo.
Lo primero que tenemos que hacer es cambiar el la variable led que hay en el programa y que está asignada al pin 13 por los nuevos pines que vamos a utilizar:
int ledSalon = 10; int ledCocina = 11; int ledBano = 12; int ledHabitacion = 13;
Justo a continuación es donde definimos los comandos que vamos a utilizar, y que en nuestro caso son 6:
#define Salon (0) #define Cocina (1) #define Bano (2) #define Habitacion (3) #define Encender (4) #define Apagar (5)
Después tenemos un par de funciones que no vamos a tocar que son las que se encargan de trabajar con las voces: void printSignature y void printVR.
Ya en el setup, podéis cambiar el mensaje que nos aparece en el monitor serie, y tendremos que declarar como salida los pines que vamos a utilizar. Además los apagaremos todos al comenzar el programa:
Serial.println("Elechouse Voice Recognition V3 Prueba Prometec"); pinMode(ledSalon, OUTPUT); pinMode(ledCocina, OUTPUT); pinMode(ledBano, OUTPUT); pinMode(ledHabitacion, OUTPUT); digitalWrite(ledSalon, LOW); digitalWrite(ledCocina, LOW); digitalWrite(ledBano, LOW); digitalWrite(ledHabitacion, LOW);
Si os fijáis, también en el setup tenemos unas estructuras de tipo if, que son las que se encargan de avisar si se ha reconocido algo que hayamos dicho como unp de los comandos que hemos grabado anteriormente. Tenemos que cambiarlo por los comandos que hemos definido al inicio del programa:
if (myVR.load((uint8_t)Salon) >= 0) { Serial.println("Salon loaded"); } if (myVR.load((uint8_t)Cocina) >= 0) { Serial.println("Cocina loaded"); } if (myVR.load((uint8_t)Bano) >= 0) { Serial.println("Bano loaded"); } if (myVR.load((uint8_t)Habitacion) >= 0) { Serial.println("Habitacion loaded"); } if (myVR.load((uint8_t)Encender) >= 0) { Serial.println("Encender loaded"); } if (myVR.load((uint8_t)Apagar) >= 0) { Serial.println("Apagar loaded"); }
Ya en el loop podemos ver que tenemos una estructura del tipo “switch case” en donde indicamos lo que tiene que hacer nuestro programa en función del comando que haya reconocido. Ahí es donde hacemos que al nombrar una de las estancias utilicemos nuestra voz como un interruptor, o encendamos o apaguemos todos los LED.
void loop() { int ret; ret = myVR.recognize(buf, 50); if (ret > 0) { switch (buf[1]) { case Salon: digitalWrite(ledSalon, !digitalRead(ledSalon)); break; case Cocina: digitalWrite(ledCocina, !digitalRead(ledCocina)); break; case Bano: digitalWrite(ledBano, !digitalRead(ledBano)); break; case Habitacion: digitalWrite(ledHabitacion, !digitalRead(ledHabitacion)); break; case Encender: digitalWrite(ledSalon, HIGH); digitalWrite(ledCocina, HIGH); digitalWrite(ledBano, HIGH); digitalWrite(ledHabitacion, HIGH); break; case Apagar: digitalWrite(ledSalon, LOW); digitalWrite(ledCocina, LOW); digitalWrite(ledBano, LOW); digitalWrite(ledHabitacion, LOW); break; default: Serial.println("Record function undefined"); break; } /** voice recognized */ printVR(buf); } }
Y ya no os queda más que probar que todo funcione correctamente. Podéis descargar el programa completo aquí: reconocimiento_de_voz.
Resumen de la sesión
En esta sesión hemos aprendido varias cosas importantes: