Sie sind auf Seite 1von 61

UNIVERSIDAD AUTÓNOMA DE CHIHUAHUA

FACULTAD DE INGENIERÍA

“IMPLEMENTACIÓN DE UN PROTOTIPO A BAJO NIVEL QUE INTERACTÚA CON


HARDWARE HACIENDO USO DE COMANDOS DE VOZ”

QUE PARA OBTENER EL TÍTULO DE INGENIERO EN SISTEMAS


COMPUTACIONALES EN HARDWARE

PRESENTA:

MARCOS SAMUEL GÓMEZ GARCÍA

DIRECTOR DE TESIS:

FERNANDO MARTINEZ REYES

CHIHUAHUA, CHIHUAHUA MAYO DE 2011


“La mayoría de las ideas fundamentales de la ciencia son
esencialmente sencillas y, por regla general pueden ser expresadas
en un lenguaje comprensible para todos”

Albert Einstein
Agradecimientos

A Dios por todos los dones que me ha otorgado.

A mi familia por su apoyo incondicional, en especial a mi madre y abuelos que con


sus consejos me han guiado por el sendero de la vida.

A mis asesores de tesis por su distinguido criterio y sus valiosas aportaciones.

A los profesores de la Facultad de Ingeniería de la Universidad Autónoma de


Chihuahua por compartir conmigo sus experiencias y conocimientos,
especialmente a José Eduardo Acosta Cano de los Ríos y Enrique Gerardo
Hernández Vega que además de ser excelentes catedráticos los considero unas
personas admirables.

A mis compañeros de clase por su buena compañía a lo largo de la carrera, en


especial a Hugo César Ortiz Palma y Gerardo Arreola Vivanco que además de
haber sido mis compañeros se convirtieron en unos verdaderos amigos.

A mis amigos por escucharme y darme ánimos.

Y finalmente agradezco a mi director de tesis Fernando Martínez Reyes, por creer


en mí y motivarme a concluir mí trabajo de investigación armándose de paciencia
y profesionalismo.
ÍNDICE

I. INTRODUCCIÓN ............................................................................................. 1

II. ANÁLISIS DE FUNDAMENTOS ..................................................................... 2

III. IMPLEMENTACIÓN ..................................................................................... 5

3.1 Interfaz de hardware ............................................................................... 5

3.2 Software del lado del dispositivo periférico .......................................... 6

3.3 Comunicación entre computadora y microcontrolador ..................... 10

3.4 Software del lado del servidor ............................................................. 11

3.4.1 Configuración inicial y archivo grammar .......................................... 11

3.4.2 Reconocedor de voz ........................................................................... 12

3.4.3 Configuración del puerto serie .......................................................... 15

3.4.4 Sintetizador de voz ............................................................................. 18

3.5 Interacción con el sistema ................................................................... 20

IV. RESULTADOS........................................................................................... 23

V. CONCLUSIONES Y RECOMENDACIONES ................................................. 26

REFERENCIAS ................................................................................................... 28

ANEXOS .............................................................................................................. 30
ÍNDICE DE FIGURAS

Figura 1. Diagrama de bloques de los componentes del sistema……...……………5

Figura 2. Diagrama de conexión lógica del prototipo .............................................. 6

Figura 3. Diagrama de flujo de programa por parte del dispositivo periférico ......... 7

Figura 4. Diagrama de flujo de programa por parte de la interfaz de usuario ....... 20

Figura 5. Diagrama de bloques del funcionamiento del sistema ........................... 21

Figura 6. Fotografía del sistema prototipo ............................................................ 22

Figura 7. Fotografía del prototipo del lado del microcontrolador…………………...22

Figura 8. Ondas generadas durante una secuencia de comandos de voz………..24

Figura 9. Onda generada para la palabra start ..................................................... 24

Figura 10. Onda generada para la palabra exit ………………………………………23

Figura A1. Pantalla de inicio del entorno de desarrollo NetBeans…………………30

Figura A2. Localización del administrador de bibliotecas de NetBeans IDE..........31

Figura A3. Administrador de bibliotecas en NetBeans IDE…………………………31

Figura A4. Caja de diálogo para agregar Nueva biblioteca a NetBeans IDE……..32

Figura A5. Selección de librerías para agregar al entorno de desarrollo………….32

Figura A6. Menú emergente del proyecto en curso………………………………….33

Figura A7. Caja de diálogo de las Propiedades del proyecto……………………….34

Figura A8. Caja de diálogo para añadir una biblioteca al proyecto………………...34

Figura A9. Localización de la opción de agregar Proyecto Nuevo en NetBeans


IDE. ...................................................................................................................... 35

Figura A10. Caja de diálogo para la selección del tipo de proyecto……………….36


Figura A11. Caja de diálogo para la selección del nombre y la ubicación del
proyecto…………………………………………………………………………………...36

Figura A12. Pantalla de inicio del compilador PCWH Compiler de CCS………….42

Figura A13. Localización del botón de compilación en PCW Compiler……………49

Figura A14. Proceso de compilación de código en PCW Compiler………………..49

Figura A15. Localización del archivo usb_desc_cdc.h dentro del entorno de PCW
Compiler…………………………………………………………………………………..50

Figura A16. Interfaz del programa PICkit Programmer……………………………...51

Figura A17. Localización de la familia de dispositivos en PICkit Programmer……52

Figura A18. Localización de la opción de importación de archivo .HEX…………..52

Figura A19. Botones para programar el microcontrolador en PICkit Programmer.53

Figura A20. Interfaz de la herramienta generadora de archivos .INF para los


drivers de microcontroladores de Microchip…………………………………………..54

Figura A21. Configuración del conector tipo A para cables USB…………………..55


I. INTRODUCCIÓN
Los dispositivos electrónicos tales como computadoras, robots, televisores,
teléfonos celulares, entre otros, ofrecen una interface de interacción adecuada
para su operación. Generalmente esta interface de interacción se ofrece a través
de botones, teclados y pantallas.

Las interfaces de usuario se han ido mejorando gradualmente y cada vez es más
fácil manejarlas, tal es el caso de las pantallas táctiles donde la interfaz de entrada
es la misma que la de salida.

Existen sin embargo sistemas en los cuales este tipo de interfaces no cubren con
las necesidades de las personas, especialmente personas con capacidades
diferentes, las cuales podrían verse beneficiadas con interfaces basadas en voz.
El usuario puede interactuar con estos dispositivos vía voz parecido a la forma en
que lo haría con otro ser humano llevando la interacción hombre-máquina a otro
nivel.

El uso de reconocimiento de voz para el manejo de dispositivos electrónicos es el


tema que se aborda en este documento. En este trabajo se presenta la integración
de un sistema de reconocimiento de voz a bajo nivel en el cual el usuario puede
activar eventos a nivel hardware vía voz. El prototipo actual permite reconocer
comandos de voz de una, dos y hasta tres palabras y actúa en consecuencia con
la activación de sensores y actuadores.

Esta plataforma podría servir como punto de partida para poder iniciar la
exploración de temas de investigación como: procesamiento de voz, diseño e
implementación de sistemas embebidos, estudio de protocolos de comunicación
entre el host y sistemas ad-hoc, entre otros.

1
II. ANÁLISIS DE FUNDAMENTOS

Una de las formas de comunicación es el habla. Un mensaje puede ser


interpretado debido a su contenido pero también de acuerdo a la señal en
términos de onda acústica que genera. El procesamiento de dicha señal es
fundamental para lograr el reconocimiento de voz. Un sistema de reconocimiento
de voz opera mediante la identificación de palabras aisladas o fonemas. Una
palabra está compuesta por vocales y/o consonantes, cada vocal o consonante
genera una frecuencia determinada a la cual después de ser analizada se le
asigna cierto valor para su posterior interpretación.

Uno de los primeros trabajos con relación con el reconocimiento del habla se
atribuye a los sacerdotes griegos los cuales utilizaban sintetizadores mecánicos
dentro de la boca de una estatua para producir señales auditivas. [1]

Más recientemente en 1779 el profesor ruso Christian Kratzenstein explicó las


diferencias fisiológicas entre las vocales y construyó un aparato que las
reprodujera artificialmente haciendo uso de resonadores acústicos similares al
tracto vocal humano los cuales eran activados mediante vibraciones desde una
boquilla. Para el año de 1791 Wolfgang Von Kempelen introdujo su “Máquina
acústica-mecánica parlante” la cual era capaz de producir simples sonidos y
algunas combinaciones de estos. La máquina constaba principalmente de una
cámara de pulmones, una boquilla que hacia la función de cuerdas vocales y un
tubo de cuero para realizar la función del tracto vocal, manipulando la forma del
cuero se producían diferentes vocales. Las consonantes eran simuladas por
cuatro pasajes separados y controladas por los dedos. También incluyó un modelo
del tracto vocal que incluía una lengua y labios movibles para poder producir
sonidos no contemplados dentro del alfabeto. A mediados del siglo XIX Charles
Wheatstone construyó una versión mejorada de la máquina de Von Kempelen la
cual lograba producir una mayor cantidad de consonantes e incluso era posible
formar palabras. La máquina de Wheatstone inspiró a Alexander Graham Bell a
construir su propia máquina emisora de voz. Para finales del siglo XIX Bell inventó

2
el teléfono el cual fue un invento que revolucionó por completo la forma de
comunicarse a distancia haciendo uso de aparatos electro-mecánicos. [2]

A pesar de que al inicio del siglo XX la implementación del reconocimiento de voz


en un sistema aún parecía ser tema de ciencia ficción el científico húngaro
Tihamér Nemes diseña una máquina de transcripción automática de voz que
identificara secuencias de sonidos. [3]

Para 1939 Homer Dudley presentó en la feria mundial de Nueva York el primer
sintetizador de voz el cual es conocido como VODER o Voice Operating
Demonstration. [4]

El primer reconocedor de voz capza de reconocer los dígitos del 0 al 9 aparece en


1952. [5]

En 1959 P. Denes desarrolló un sistema capaz de reconocer 4 vocales y 9


consonantes, esto con la finalidad de dar variedad a los reconocedores existentes
hasta esa fecha. [6]

Para los años 60 se desarrolló hardware de propósito específico enfocado al


reconocimiento de voz y fue cuando las primeras compañías especializadas en el
área comenzaron a comercializar productos con funciones de reconocimiento de
voz.

El método Voiceprint Identification fue introducido por Lawrence G. Kersta en


1962, el cual consistía en identificar la voz de las personas haciendo uso de
impresiones espectográficas. [7]

Un siguiente nivel en los sistemas de reconocimiento de voz se da en los 70’s.


Estos sistemas se enfocaron en el uso de palabras aisladas, además se pretendía
construir reconocedores de habla continua y de grandes vocabularios. A principios
de esta década se lanza el primer sistema comercial de reconocimiento de voz
llamado VIP-100 por parte de Threshold Technologies el cual gana el U.S.
National Award en 1972.

3
Otro elemento importante en la evolución de los dispositivos de reconocimiento de
voz es su costo y funcionalidades ofrecidas. Las aplicaciones comerciales bajaron
durante esta década y los vocabularios de palabras se volvieron cada vez más
grandes, incluso se llegó a alcanzar uno de 20,000 palabras en 1986. [8]

Con la aparición de las computadoras multimedia, computadoras portátiles,


Internet y teléfonos inalámbricos se tienen sistemas de reconocimiento de voz más
eficientes, los vocabularios son cada vez más amplios y la interacción se vuelve
más fluida. Por ejemplo salen al mercado teléfonos celulares con marcación por
voz como el modelo V60 de Motorola que salió a la venta en el año 2002. [9] En
2005 la empresa Honda en alianza con IBM lanzan el Acura RL el cual incorpora
la tecnología Embedded ViaVoice capaz de reconocer cerca de 700 comandos de
voz. [10]

Como se ha observado el reconocimiento de voz ha evolucionado a lo largo de la


historia y hoy en día se considera como un elemento importante en los sistemas
de interacción humano-computadora. Dentro de sus aplicaciones se encuentra la
automatización dentro del hogar por ejemplo poder controlar vía voz el
comportamiento de la iluminación, las persianas, las puertas, entre otros. [11]

Algunos ejemplos en los que se observa la aplicación de sistemas de


reconocimiento de voz son el software Dragon Naturally Speaking de la compañía
Nuance el cual propone utilizar comandos de voz para navegar y operar una PC
en sustitución al teclado. [12] Otro ejemplo sería el software Icatiani, el cual es un
sistema de apoyo para la adquisición del lenguaje cuyo objetivo es cubrir una de
tantas necesidades en cuanto a herramientas de apoyo para reforzar la
enseñanza en México. [13]

En este trabajo se implementa un sistema de bajo nivel que permite reconocer


comandos de voz para activar eventos eléctricos.

4
III. IMPLEMENTACIÓN

El sistema de activación de eventos físicos con comandos de voz consta de 3


bloques: interfaz de usuario basada en voz, computadora y microcontrolador.

Reconocedor/
Micro
Sintetizador de PC
controlador
voz

Figura 1. Diagrama de bloques de los componentes del sistema

Básicamente el usuario interactúa con el sistema a través de una interfaz basada


en voz la cual está constituida por dispositivos electrónicos acústicos y de una
serie de librerías especializadas que los administran. Los comandos de voz
recibidos son procesados e interpretados para posteriormente ser enviados como
instrucciones de operación a través de algún puerto de comunicación de la
computadora hacia el microcontrolador, el cual se encarga de activar eventos
físicos de acuerdo al comando seleccionado. En las secciones siguientes se
presenta una descripción más detallada de cada uno de los componentes del
sistema.

3.1 Interfaz de hardware

El microcontrolador se conecta a la computadora utilizando el protocolo USB. Una


pantalla LCD de 2 líneas de 16 caracteres se conecta al microcontrolador por uno
de los puertos del mismo y su brillo se ajusta a través de un potenciómetro. Cuatro
pines de otro puerto son utilizados para conectar diodos emisores de luz los
cuales representan a los actuadores; se hace uso de lógica positiva así que éstos
se conectan a tierra y se espera la señal de encendido desde el microcontrolador.

5
Se utiliza un cristal de 12 MHz que es el que genera la base de tiempos o reloj. Un
capacitor de 470nF es conectado a tierra y al pin del microcontrolador que habilita
el uso del puerto USB. Además se cuenta con un botón de reinicio para el
microcontrolador el cual va conectado al pin destinado para realizar dicha tarea.

Figura 2. Diagrama de conexión lógica del prototipo

3.2 Software del lado del dispositivo periférico

El microcontrolador deberá de tener la capacidad de recibir una señal por parte de


la computadora y a su vez interpretar dicha señal para generar una salida de
acuerdo al comando especificado por el usuario.

6
Inicio

Se leen datos
desde del puerto
USB

No Dato Si Se envían instrucciones hacia


válido los puertos de salida

Figura 3. Diagrama de flujo de programa por parte del dispositivo periférico

El microcontrolador se comunicará con la computadora haciendo uso del protocolo


USB pero será reconocido como un dispositivo de comunicación serial. Para
configurar el microcontrolador de esta manera en particular se utilizará uno de los
proyectos de ejemplo que se encuentra dentro de la carpeta de proyectos de la
herramienta PCW Compiler, [14] esta carpeta viene incluida dentro de la
instalación del compilador. El código contenido en este ejemplo permite que el
microcontrolador quede configurado como un dispositivo de comunicación serial
pero con la funcionalidad de poder comunicarse con la computadora a través del
puerto USB. Dicho código será modificado cuanto sea necesario para que se
adapte a las necesidades del proyecto. El código completo se encuentra dentro de
la sección de anexos.

Es importante la inclusión de archivos de cabecera y bibliotecas específicas. Se


deben de incluir dentro del proyecto los archivos de cabecera con las
configuraciones necesarias para el uso de las funciones USB y para el manejo de
los recursos del microcontrolador correspondiente, además se debe incluir la

7
biblioteca que contiene las funciones necesarias para utilizar la pantalla LCD. Las
siguientes líneas de código muestran la forma de agregar estos archivos al
proyecto.

Archivo de cabecera con funciones para el manejo del puerto USB:

#include <usb_cdc.h>

Archivo de cabecera que contiene la configuración del microcontrolador a utilizar,


en este caso un PIC de modelo 18F4455:

#include <18F4455.h>

Biblioteca con funciones para el uso de la pantalla LCD:

#include <lcd.c>

La siguiente línea de código muestra la configuración de los fusibles del


microcontrolador. Esta configuración no cambia una vez programado el
microcontrolador, por eso se les denomina fusibles. El fusible de interés en este
proyecto es el fusible multiplicador de frecuencia el cual tiene un valor por defecto
de 4Mhz. Se pueden manejar frecuencias de reloj en múltiplos de 4, desde 4Mhz
hasta 48Mhz, en este caso se multiplicará el valor por 3 para obtener una
frecuencia de 12Mhz que es el cristal que se utiliza en la implementación de este
prototipo. La línea de código modificada quedaría de la siguiente manera:

#fuses HSPLL, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL3,


CPUDIV1, VREGEN

Otra línea de código de importancia es aquella donde se configuran los


parámetros de la comunicación serial. En esta línea de código se puede
determinar la velocidad de intercambio de datos así como los pines de transmisión
y recepción. La velocidad que se utilizará en este proyecto es de 9600 baudios

8
que es la velocidad que viene configurada por defecto. La línea de código es la
siguiente:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

La pantalla LCD debe ser inicializada para poder mostrar caracteres en ella. Esto
se realiza dentro de la función principal del programa:

lcd_init();

La recepción de datos y la activación de eventos de hardware se realizan dentro


de un ciclo infinito. Se comprueba constantemente si existen datos provenientes
del puerto USB y según el dato recibido se envían instrucciones a los puertos de
salida correspondientes:

while(TRUE) {
//Verifica si se reciben datos desde el puerto USB
if(usb_cdc_getc()=='Dato')
{
//Coloca el cursor de la pantalla LCD en la coordenada 1,1
lcd_gotoxy(1,1);
//Muestra la cadena deseada
printf(lcd_putc,"Hola Mundo");
//Se envía señal en alto hacia el pin correspondiente
output_high(PIN_B7);
//Se envía señal en bajo hacia el pin correspondiente
output_low(PIN_B6);
}
}

9
Una vez compilado el código se generan los archivos de cabecera y bibliotecas
declaradas anteriormente. El archivo usb_desc_cdc.h contiene las líneas de
código referentes a los identificadores del vendedor y del producto del dispositivo.
La sección de código donde se encuentran esas líneas es en la sección de
configuración del dispositivo USB. Se seleccionan los identificadores de producto y
de vendedor, los cuales pueden ser elegidos a elección del programador. Los
identificadores están compuestos por 4 dígitos hexadecimales, los cuales se
declaran por parejas de derecha a izquierda tal como se muestra en el siguiente
código:

const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={


0x61,0x04, //vendor id
0x61,0x04, //product id
};

Una vez elegidos los identificadores se compila de nuevo el código para que se
genere un archivo con extensión .HEX el cual contiene el código del programa con
las configuraciones previamente establecidas en formato hexadecimal. Este
archivo es el que se graba en el microcontrolador utilizando la herramienta de
grabación de preferencia. En los anexos se ofrece una guía sobre cómo realizar
este proceso de grabación.

3.3 Comunicación entre computadora y microcontrolador

Para que la computadora pueda reconocer al microcontrolador como un


dispositivo de comunicación serial es necesario generar un driver, el cual debe de
contener los identificadores de vendedor y de producto del dispositivo.

Para genera el driver se utiliza la herramienta INF Enumeración Datos uC PIC-


USB. [15] Con la ayuda de la herramienta se genera un archivo con extensión .inf,
el cual será solicitado por el sistema operativo al momento de conectar el
microcontrolador a la computadora a través del puerto USB.

10
En la sección de anexos se ofrece una guía sobre cómo generar el driver
utilizando la herramienta propuesta anteriormente.

3.4 Software del lado del servidor

La interfaz de usuario se desarrolla en el lenguaje Java utilizando el entorno de


desarrollo integrado NetBeans. [16] Esta interfaz permite la interacción con el
usuario mediante un sintetizador y un reconocedor de voz.

3.4.1 Configuración inicial y archivo grammar

Antes de desarrollar la interfaz de usuario se debe crear un archivo de texto que


contendrá los posibles comandos a elegir. Se pueden agregar cuantos comandos
sean necesarios. Se recomienda utilizar comandos cortos de no más de 5
palabras ya que el tiempo de escucha por parte del reconocedor es limitado. La
estructura del archivo es la siguiente:

#JSGF V1.0;
grammar javax.speech.demo;
public <sentence> =comando 1 | comando 2 | comando N;

El archivo creado se conoce como el archivo grammar, pero puede nombrarse de


otro modo. Es recomendable que la ruta de acceso del archivo sea de fácil de
acceder ya que dentro del código de la interfaz de usuario se hace referencia a
ella.

Una vez almacenado el archivo grammar se procede a la creación de la interfaz de


usuario. Para poder hacer uso de las funciones de síntesis y reconocimiento de
voz es necesario agregar a la carpeta del proyecto las librerías adecuadas.

Existen varias compañías que desarrollan librerías con funciones de síntesis y/o
reconocimiento de voz. En este proyecto se utilizan las librerías proveídas por la

11
compañía Cloud Garden las cuales llevan por nombre TalkingJava SDK versión
1.7.0. [17]

Una vez agregadas las librerías al proyecto se debe crear una clase de Java, la
cual contendrá el código del programa.

El código completo de la interfaz está disponible en la sección de anexos. En esta


sección se analizarán los bloques de código de relevancia.

3.4.2 Reconocedor de voz

Para poder trabajar con las funciones de síntesis y reconocimiento de voz se


adaptaron algunos ejemplos de la API Java Speech. [18]

Primero se hará el análisis del código del reconocedor de voz. Para poder hacer
uso de los recursos de reconocimiento de voz es necesario importar ciertas
librerías, las cuales se muestran a continuación.

//Contiene los elementos necesarios para hacer uso de los recursos de audio de la
computadora

import javax.speech.*;

//Permite hacer uso de las funciones de reconocimiento de voz

import javax.speech.recognition.*;

//Permite el acceso a archivos externos a la carpeta del proyecto

import java.io.FileReader;

//Librería con utilerías diversas

import java.util.Locale

Una vez importadas las librerías se procede a configurar el reconocedor. Dentro


de la clase principal se inicializa el reconocedor de voz y se configuran los

12
parámetros necesarios para su uso. Algunas líneas de código son explícitas pero
se explican las más importantes para su mejor comprensión:

//Crea el objeto correspondiente al reconocedor de voz

rec = Central.createRecognizer(

//Se configura al reconocedor para que entienda el idioma inglés

new EngineModeDesc(Locale.ENGLISH));

//Se inicializa el reconocedor

rec.allocate();

//Se especifica la ruta donde está contenido el archivo grammar

FileReader reader = new FileReader("c:/grammar.txt");

//Establece la forma en que debe de estar estructurado el archive grammar

RuleGrammar gram = rec.loadJSGF(reader);

//Inicializa el acceso al archivo grammar

gram.setEnabled(true);

//Se hace referencia a la clase de escucha del reconocedor

rec.addResultListener(new CLASE());

rec.commitChanges();

rec.requestFocus();

rec.resume();

13
3.4.2.1 Procesamiento de cadenas de texto

Una vez que se configura el reconocedor de voz y se comienza el proceso de


escucha se analizan las señales auditivas captadas por el micrófono las cuales
son comparadas con las palabras y/o frases contenidos en el archivo grammar. Si
el comando dictado por el usuario es reconocido y es válido se extrae del archivo
grammar la palabra o frase asignada a tal comando y después se envía a un
método del programa para su procesamiento. Este método se conoce como el
método resultAccepted y está contenido en la clase ResultAdapter la cual es
llamada desde la clase principal. La cadena se envía carácter por carácter, lo que
se conoce como envío de tokens. Una vez recibidos todos los elementos de la
cadena de texto éstos pueden ser manipulados a conveniencia del programador.
El código de bloque en el que están contenidos la clase y el método mencionados
es el siguiente:

public class JSUSB extends ResultAdapter {

//Declaración de objetos
static Recognizer rec;
//Método que recibe la cadena de texto proveniente del archivo grammar
public void resultAccepted(ResultEvent e){

Result r = (Result)(e.getSource());
//Se obtienen uno por uno los de elementos de la cadena de texto
ResultToken tokens[] = r.getBestTokens();
//Cadena que guardará la palabra o frase concatenada
String Palabra;
//Cadena que será utilizada para la cincatenación de los elementos
individuales generados por la librería de reconocimiento de voz
StringBuffer cad=new StringBuffer();
for (int i = 0; i < tokens.length; i++)

14
{
//Ciclo que concatena un elemento recibido después de otro hasta formas
una palabra o frase
cad.append((tokens[i].getSpokenText()+" "));
}
Palabra = cad.toString();
}

En este caso cada comando recibido se almacenará en la cadena “Palabra” la cual


puede ser utilizada para establecer condiciones en las estructuras de control.

Esta es la configuración básica del reconocedor de voz, la cual permite obtener


cadenas de texto según del comando dictado.

3.4.3 Configuración del puerto serie

Con estas cadenas se pueden establecer condiciones de acción. Una de las


acciones a realizar durante la ejecución del programa es el envío de datos hacia el
microcontrolador. Dependiendo de la cadena de texto recibida se realizará cierta
acción. Los datos serán enviados haciendo uso del protocolo de comunicación
serial. Para poder tener acceso a estos puertos es necesario agregar al proyecto
una librería con funciones de comunicación serial, en este caso se utilizó la librería
Giovynet Driver versión 1.0. [19]

Una vez agregada la librería al proyecto se puede proceder a hacer uso de las
bondades que ofrece. Antes de comenzar a usar las funciones de comunicación
serial es necesario importar al proyecto las librerías dentro del área de código. En
el siguiente bloque se puede observar las líneas de código necesarias para
realizar dicho fin:

//Necesario para desplegar lista de puertos de comunicación serial


disponibles

import java.util.List;

15
//Funciones generales de comunicación serial

import giovynet.nativelink.SerialPort;

//Permite establecer la velocidad de transmisión de datos

import giovynet.serial.Baud;

//Configuracion del puerto serial

import giovynet.serial.Com;

//Configuración de parámetros

import giovynet.serial.Parameters;

Teniendo las librerías necesarias se puede proceder a la configuración del puerto


de comunicación serial. Dentro de esta configuración se determina que puerto está
disponible y cual se usará, también se configura la velocidad de transmisión de
datos. El siguiente bloque de código contiene las líneas de código para dejar
configurado el puerto:

//Se crea un objeto para el manejo del puerto serial

serialPort = new SerialPort();

//Variable de tipo lista que almacenará los puertos libres


List<String> portsFree;

//Se verifica si existen puertos libres


portsFree = serialPort.getFreeSerialPort();
//Si existen puertos disponibles se despliega una lista mostrandolos
if (portsFree!=null&&portsFree.size()>0) {
for (String free : portsFree) {
System.out.println("Free port: "+free);
}

16
//Se crea el objeto que guardará los parámetros de configuración
Parameters parameters = new Parameters();
//Se selecciona puerto a utilizar
parameters.setPort(portsFree.get(0));
//Se determina la velocidad de transmisión de datos
parameters.setBaudRate(Baud._9600);
//Se crea un objeto el cual contiene la configuración previamente
establecida y el cual será al que se hará referencia cuando se quiera utilizar
el puerto serie
objCOM = new Com(parameters);
}
Una vez configurado el puerto serie se puede proceder al envío de datos a través
del mismo. Este bloque de código debe de estar dentro del método resultAccepted
para que los datos sean enviados cada vez que sea aceptado un comando. La
instrucción para realizar dicha tarea se encuentra dentro del siguiente bloque de
código:

3.4.3.1 Envío de datos

public class JSUSB extends ResultAdapter {

//Declaración de objetos
static Com pcom;

public void resultAccepted(ResultEvent e){


//Si la cadena recibida es igual a la de la condición se ejecuta el contenido
de la estructura
if(Palabra.equals("palabra ")
//Se envía un número 1 o cualquier caracter por el puerto serie
objCOM.sendSingleData('1');
}
}

17
El reconocedor de voz estará en estado de escucha hasta que se liberen los
recursos a los que accede. Para que el estado de escucha sea continuo se genera
un ciclo; no se podrá salir del ciclo a menos de que el usuario diga la palabra
asignada para la liberación de los recursos de reconocimiento de voz.

while(Palabra.equals("exit "))
{
rec.deallocate();
}

3.4.4 Sintetizador de voz

Teniendo configurados el reconocedor de voz y la comunicación serial se puede


crear una interfaz la cual sea capaz de reconocer comandos, interpretarlos y
enviar una instrucción por el puerto serie, pero para lograr una interacción más
amena con el usuario se utiliza un sintetizador de voz para sugerir al usuario
posibles comandos o confirmar acciones. Al igual que el reconocedor de voz el
sintetizador necesita de ciertas librerías las cuales vienen dentro del paquete
TalkingJava. Hacer uso del sintetizador es mucho más simple que utilizar el
reconocedor, el procedimiento básico consta en escribir dentro del código la
cadena de texto que se desea reproducir y el sintetizador se encarga de realizar la
conversión. Las librerías necesarias para utilizar las funciones del sintetizador son
las siguientes:

import javax.speech.*;

//Librería que permite utilizer funciones de síntesis de voz


import javax.speech.synthesis.*;

import java.util.Locale;

18
Una vez importadas las librerías correspondientes se puede llamar al sintetizador,
el cual puede ser invocado en cualquier clase del código principal. La
configuración del sintetizador de voz es la siguiente:

//Crea el sintetizador de voz


Synthesizer synth = Central.createSynthesizer(
//Configura el sintetizador en idioma inglés
new SynthesizerModeDesc(Locale.ENGLISH));
//Inicializa el sintetizador
synth.allocate();
synth.resume();
//Convierte la cadena de texto en señales de audio
synth.speakPlainText("Hello, world", null);
synth.waitEngineState(Synthesizer.QUEUE_EMPTY);
//Libera los recursos destinados al uso del sintetizador
synth.deallocate();

La interfaz de usuario creada debe permitir la recepción de comandos de voz y


enviar instrucciones de operación a través del puerto serie de la computadora.
Adicionalmente se agregan funciones de síntesis de voz para lograr una
interacción más amena a través de la interfaz.

19
Inicio

En espera de comandos de voz Se envía la instrucción


correspondiente a través
del puerto COM hacia el
microcontrolador

Recepción de comandos de
voz a través del micrófono de la
PC Se devuelve una cadena de
texto con el comando
No seleccionado al programa
principal

Se realiza la conversión del


comando de voz a una cadena Si
Comando
de texto y se compara con las válido
posibles opciones del archivo
“grammar”

Figura 4. Diagrama de flujo de programa por parte de la interfaz de usuario

3.5 Interacción con el sistema

Después de tener todos los elementos necesarios para la implementación del


prototipo se procede a agruparlos en un solo sistema para probar la funcionalidad
del mismo. El procedimiento básico de operación consta en inicializar el sistema y
esperar a que el usuario interactúe vía voz con la interfaz para generar la
activación de eventos a nivel de hardware. El siguiente diagrama de bloques
exhibe a grandes rasgos el sistema integrado:

20
PC
Interacción por voz
Usuario

Envío de instrucciones

Activar actuadores
Actuador µC

Figura 5. Diagrama de bloques del funcionamiento del sistema

En la sección de anexos se puede encontrar paso a paso el procedimiento que se


siguió para lograr la implementación del prototipo. Dentro del código ofrecido en la
sección de anexos se incluyen las funciones y métodos necesarios para poder
apagar y encender diodos emisores de luz haciendo uso de comandos de voz
específicos, los cuales se enlistan en dicha sección.

21
El prototipo real se puede observar en las siguientes imágenes:

Figura 6. Fotografía del sistema prototipo

Figura 7. Fotografía del prototipo del lado del microcontrolador

22
IV. RESULTADOS

En este trabajo se desarrolló la integración de un sistema prototipo que permite


generar eventos físicos por medio de comandos de voz a través de una
computadora personal. El prototipo consiste de tres bloques principales; el primero
se refiere a la etapa de reconocimiento de comandos de voz dictados por el
usuario a través de la utilización de las librerías de uso libre Talking Java SDK. La
segunda etapa comprende la interpretación y procesamiento de los comandos y al
envío de instrucciones de operación hacia el microcontrolador utilizando las
librerías Giovynet Driver. La tercera etapa consiste en la activación de eventos
físicos mediante el microcontrolador. Todos estos elementos permiten tener un
canal de comunicación desde el usuario hasta el actuador.

Una vez implementado el prototipo se hicieron pruebas para medir el alcance del
mismo, en las cuales cinco personas fueron invitadas para interactuar con el
sistema. Las pruebas consistieron en dictar comandos de una a cinco palabras.
Aunque no se tienen pruebas exhaustivas puesto que la población de los sujetos
de pruebas es reducida, los experimentos desarrollados con el sistema ayudaron a
probar las limitaciones y las bondades del prototipo.

Al parecer, un elemento que afecta el comportamiento del sistema es la velocidad


con la que se dictan los comandos. Se desarrollaron pruebas dictando comandos
diferentes con intervalos de uno a tres segundos entre cada comando dado. Se
observó que entre mayor es el intervalo de tiempo entre un comando y otro se
obtiene una mejor respuesta en lo que activación de eventos físicos se refiere ya
que el microcontrolador opera con mejor precisión. En la siguiente imagen se
muestra experimento controlado en el cual la activación de eventos físicos se
realizó de manera exitosa. En la parte inferior de la imagen aparece una regla la
cual permite que se pueda apreciar el tiempo en segundos en que es dictado un
comando respecto al otro. La secuencia de comandos que se siguió fue la
siguiente: start, full light, light at half, less light, more light, more light, more light,
less light, turn off light, reset y exit.

23
Figura 8. Ondas generadas durante una secuencia de comandos de voz

Se puede observar en la figura que la cuarta señal y la octava de izquierda a


derecha tienen una forma de onda parecida, ya que ambas se generan con el
mismo comando de voz. La quinta, sexta y séptima señal se generan cuando el
usuario utiliza la frase more light, también se puede observar un parecido entre
ellas y aunque no son exactamente iguales debido a que los comandos se
dictaron con diferente intensidad, el microcontrolador respondió satisfactoriamente
ya que tal señal es distinta a la de otros comandos. En las figuras siguientes se
muestra la comparativa de dos comandos con un mayor acercamiento para
visualizar mejor la onda generada por los mismos.

Figura 9. Onda generada para la palabra start

Figura 10. Onda generada para la palabra exit

24
Si se compara el desempeño del sistema durante el experimento anterior contra
uno de los experimentos no controlados se observó que el sistema puede
responder de forma incierta cuando los comandos son dictados con mayor
velocidad.

También se realizaron pruebas respecto a la distancia de captación de comandos


y se observó que al situarse a más de un metro del micrófono se tornaba más
complicado captar los comandos correctamente. Adicionalmente se probó dictar
comandos desde diferentes ángulos respecto al micrófono y se encontró que no
se ve afectado el desempeño del sistema. Una prueba un tanto extrema fue el
interactuar de espaldas al sistema; al realizar esta prueba no se obtuvo respuesta
por parte del sistema ya que los comandos no fueron reconocidos.

Dentro de los resultados obtenidos por los distintos experimentos destaca el hecho
de que el prototipo sea capaz de reconocer distintos tipos de comandos y activar
diferentes eventos a nivel hardware. Aunque ya existen aplicaciones comerciales
capaces de reconocer comandos de voz el objetivo fue recrear una experiencia
propia en la implementación de un sistema de este tipo. El prototipo en cuestión se
puede adecuar dependiendo de la aplicación final deseada, además cuenta con la
capacidad de manejar una gran cantidad de comandos en caso de ser necesario.

25
V. CONCLUSIONES Y RECOMENDACIONES

En este trabajo se ha integrado un sistema que permite al usuario activar eventos


físicos a través de comandos de voz. En general, se alcanzó el objetivo principal
ya que se logró desarrollar un prototipo que respondiera a la activación de eventos
físicos vía voz. El sistema que consiste de una computadora portátil conectada a
un microcontrolador permite al usuario utilizar comandos de voz para controlar, por
ejemplo, un sistema de iluminación.

Las pruebas desarrolladas con el prototipo son un aliciente, ya que fue posible
mostrar cómo se pueden ofrecer escenarios de interacción entre el humano y la
computación con interfaces diferentes al tradicional teclado y ratón. Aunque
básico, nuestro prototipo podría ser utilizado como plataforma para seguir
explorando distintas áreas de la ingeniería computacional tales como
reconocimiento de voz, automatización de tareas del medio, sistemas embebidos,
entre otros.

A pesar de que el desempeño del prototipo fue “aceptable” existen, sin embargo,
factores que pueden influir en el comportamiento del sistema. La orientación dela
persona respecto al micrófono es un factor importante para el reconocimiento de
los comandos. Pero existen otros factores como ruido ambiental y rapidez del
habla que al parecer también afectan el desempeño del sistema, y que no fueron
probados de forma exhaustiva.

No obstante sus limitaciones, en su estado actual, el sistema prototipo podría ser


aplicado para controlar ciertos elementos de una casa tales como la iluminación,
las puertas, el clima artificial y otras tareas afines donde se haga uso de
actuadores de uso común, esto con el fin de poder visualizar una aplicación más
real. Para este fin se podría mejorar la comunicación entre la interfaz de usuario y
el dispositivo periférico, sería de interés lograr una comunicación inalámbrica a
través de módulos ZigBee o por medio de tecnología Bluetooth.

26
Otra área de oportunidad podría ser los dispositivos móviles apoyándose en el
paquete de librerías Java Mobile Edition para poder utilizar el reconocimiento de
voz en dispositivos móviles.

Más ambicioso podría ser el profundizar en el código de las librerías de síntesis y


reconocimiento de voz para lograr entender mejor cómo funcionan y desarrollar
otras librerías en distintos idiomas que las actuales solo soportan el idioma inglés.

Finalmente se espera que la exploración de este trabajo aporte la suficiente


información para fomentar el interés por las interfaces con las cuales se interactúa
por medio de la voz y de esa manera sea posible encontrar nuevas aplicaciones
para este tipo de sistemas y lograr la implementación de novedosas interfaces de
interacción entre el humano y la computadora. Así mismo se desea contribuir al
desarrollo tecnológico del país y a la aportación de nuevas tecnologías en
beneficio de la sociedad haciendo uso de los conocimientos y habilidades
obtenidas dentro de los programas de las carreras de Ingeniería en Sistemas
Computacionales tanto en Hardware como en Software que la Facultad de
Ingeniería de la Universidad Autónoma de Chihuahua ofrece.

27
REFERENCIAS
[1] MILAN, S., Voice Recognition by Computer, Marburg, Tectum, Verlag, 2003,
ISBN 3-8288-8492-X, p. 8.
[2] LEMETTY, S., Review of Speech Synthesis Technology [tesis de maestría],
Espoo (FIN), Helsinki University of Techonology, 1999. También disponible en:
http://www.acoustics.hut.fi/publications/files/theses/lemmetty_mst/thesis.pdf
[3] ROJAS BELLO, R. N., Diseño y desarrollo de prototipo de sistema de
traducción instantánea de habla y transmisión en tiempo real, sobre el protocolo
RTP utilizando tecnologías de reconocimiento de voz [tesis de licenciatura],
Valdivia (CHL), Universidad Austral de Chile, 2005. También disponible en:
http://cybertesis.uach.cl/tesis/uach/2005/bmfcir741d/doc/bmfcir741d.pdf
[4] 120 Years of Electronic Music, The Voder & Vocoder, Fuente consultada en
Septiembre de 2010. Disponible en http://120years.net/machines/vocoder/
[5] JUANG, B.H., RABINER, L. R., Automatic Speech Recognition – A Brief History
of the Technology Development, Elsevier Encyclopedia of Language and
Linguistics, Second Edition, 2005. Disponible en:
http://www.ece.ucsb.edu/Faculty/Rabiner/ece259/
[6] JURAFSKY, D., MARTIN, J. H., Speech and Language Processing: An
Introduction to Natural Language Processing, Computacional Linguistics and
Speech Recognition, 2ª ed., Prentice Hall, 2008, ISBN 978-0-13-187321-6, p.331
[7] LEVINSON, D., Encyclopedia of crime and punishment: Vol 4, 1ª ed., United
States of America, Berkshire Publishing Group, 2002, p. 1692
[8] AHUACTZIN L., A., Diccionario español/inglés para el aprendizaje de
vocabulario utilizando una interfaz de voz [tesis de licenciatura], Puebla (MX),
Escuela de Ingeniería de la Universidad de las Américas, 1999.
[9] 54-9: El sitio argentino sobre celulares, 25 años de telefonía celular: la historia
según Motorola, Octubre 2008, Fuente consultada en septiembre de 2010.
http://54-9.com.ar/celulares/25-anos-de-telefonia-celular-la-historia-segun-motorola
[10] ROSENCRANCE, L., IBM, Honda deliver in-car-speech-recognition navigation
system: IBM's embedded ViaVoice technology recognizes spoken street and city
names, Octubre 2004, Fuente consultada en septiembre de 2010.

28
http://www.computerworld.com/s/article/95684/IBM_Honda_deliver_in_car_speech
_recognition_navigation_system
[11] FALCONI CEPEDA, L. F., JIMENEZ YEDRA, C. R., Estudio e implementación
de domótica activado por comandos de voz y comunicación en ZigBee [tesis de
licenciatura], Riobamba (ECU), Facultad de Informática y Electrónica de la Escuela
Superior Politécnica de Chimborazo, 2009. También disponible en:
http://dspace.espoch.edu.ec/bitstream/123456789/165/1/38T00156.pdf
[12] NUANCE, Software de reconocimiento de voz Dragon Naturally Speaking,
España, Fuente consultada en marzo de 2011. http://www.nuance.es/
[13] TOLEDO, M. T., Kirschning, I., Icatiani: un Sistema de Apoyo para la
Adquisición del Lenguaje [Memorias del 3er Simposium Internacional en
Tecnologías Inteligentes], Tlaxcala (MX), 2002. También disponible en:
http://ict.udlap.mx/people/ingrid/ingrid/Icatiani1.pdf
[14] CCS, Compilador de lenguaje C para microcontroladores Microchip, Fuente
consultada en marzo de 2011. http://www.ccsinfo.com/
[15] Generador de archivos .inf para los drivers USB de Microchip, Fuente
consultada en marzo de 2011.
http://www.unpocodelectronica.netau.net/generador-de-inf-para-los-drivers-usb-de-
microchip
[16] NetBeans IDE, Entorno de desarrollo con soporte para lenguaje Java. Fuente
consultada en marzo de 2011. http://netbeans.org/
[17] CLOUD GARDEN, Talking Java SDK, Paquete de librerías de síntesis y
reconocimiento de voz compatible con el lenguaje Java. Fuente consultada en
marzo de 2011. http://www.cloudgarden.com/
[18] JAVA SPEECH API, Interfaz de programación de aplicaciones con soporte de
síntesis y reconocimiento de voz. Fuente consultada en marzo de 2011.
http://java.sun.com/products/java-media/speech/
[19] GIOVYNET DRIVER, Paquete de librerías de comunicación serial
desarrolladas para lenguaje Java. Fuente consultada en marzo de 2011.
http://java.giovynet.com/Giovynet/

29
ANEXOS

A continuación se muestra paso a paso el procedimiento propuesto a seguir para


implementar la interfaz de usuario. El entorno de desarrollo utilizado para este fin
es Netbeans 6.8:

Figura A1. Pantalla de inicio del entorno de desarrollo NetBeans

Los pasos son los siguientes:

Se debe instalar la librería de reconocimiento de voz de Java. La librería con la


que se trabajará en este proyecto es la librería Talking Java SDK versión 1.7.0.
proporcionada por la compañía Cloud Garden. Una vez descargada esta librería
se procede a su instalación, esto se realiza de la siguiente manera:

30
Ir a la barra de menú y seleccionar Herramientas -> Bibliotecas

Figura A2. Localización del administrador de bibliotecas de NetBeans IDE.

Luego, pulsar el botón de Nueva biblioteca:

Figura A3. Administrador de bibliotecas en NetBeans IDE

31
Poner nombre a la biblioteca y pulsar en aceptar

Figura A4. Caja de diálogo para agregar Nueva biblioteca a NetBeans IDE.

Al volver a la ventana de Administrador de bibliotecas y una vez teniendo


seleccionada la nueva biblioteca pulsar en el botón de Agregar archivo
JAR/Carpeta

Se selecciona el archivo JAR correspondiente a la librería.

Figura A5. Selección de librerías para agregar al entorno de desarrollo.

32
Una vez seleccionada la librería se pulsa en Agregar archivo JAR/Carpeta. Con
esto se guardará la librería y estará disponible para ser utilizada.

Ahora se debe agregar la librería al proyecto, para realizar esto se debe


seleccionar el proyecto, que se localiza en la pestaña de proyectos en la parte
izquierda debajo de la barra de menú, una vez que se selecciona se debe pulsar el
botón derecho del mouse sobre él para poder seleccionar del menú emergente la
opción de Propiedades

Figura A6. Menú emergente del proyecto en curso.

33
Luego se debe de seleccionar la opción de Bibliotecas de las categorías
mostradas a la izquierda de la ventana y pulsar el botón de Añadir Biblioteca

Figura A7. Caja de diálogo de las Propiedades del proyecto.

Se debe seleccionar la biblioteca que se acaba de agregar al IDE y se pulsa en


Añadir Biblioteca:

Figura A8. Caja de diálogo para añadir una biblioteca al proyecto.

34
Una vez añadida la librería del reconocimiento de voz se debe proceder a agregar
la librería de comunicación con el puerto serie de la PC de la misma manera que
se agregó la librería de reconocimiento de voz. La librería que se utiliza en este
proyecto es Giovynet Driver versión 1.0.

Instaladas las librerías es necesario crear un nuevo proyecto en Java para poder
comenzar el desarrollo de la interfaz. Los pasos son los siguientes:

Ir a Archivo->Proyecto Nuevo…

Figura A9. Localización de la opción de agregar Proyecto Nuevo en


NetBeans IDE.

Luego se selecciona la opción Aplicación de Java de la carpeta Java y se pulsa


en siguiente:

35
Figura A10. Caja de diálogo para la selección del tipo de proyecto.

Se pone cualquier nombre al proyecto pero en el nombre de la clase hay que


colocar JSUSB que es el nombre de la clase en el código que se mostrará a
continuación y se pulsa en Terminar:

Figura A11. Caja de diálogo para la selección del nombre y la ubicación del
proyecto.

36
Ahora hay que colocar el siguiente código en la clase creada:

// @author Samuel Gómez

import java.util.List;
import app.Com;
import app.Parameters;
import core.SerialPort;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.speech.*;
import javax.speech.synthesis.*;
import javax.speech.recognition.*;
import java.io.FileReader;
import java.util.Locale;

public class JSUSB extends ResultAdapter {

static Recognizer rec;


static Com pcom;

@Override
public void resultAccepted(ResultEvent e){

String Palabra;
StringBuffer cad=new StringBuffer();

Result r = (Result)(e.getSource());
ResultToken tokens[] = r.getBestTokens();

for (int i = 0; i < tokens.length; i++)


{
cad.append((tokens[i].getSpokenText()+" "));
}
Palabra = cad.toString();

System.out.println();

if(Palabra.equals("start ")||Palabra.equals("reset ")){

try {
for(int i=0;i<6;i++){
pcom.sendSingleData('1');}

System.out.print("start/reset");

37
} catch (Exception ex) {
Logger.getLogger(JSUSB.class.getName()).log(Level.SEVERE, null, ex);
}

if(Palabra.equals("turn off light ")){


try {
for(int i=0;i<6;i++){
pcom.sendSingleData('2');}

System.out.print("turn off light");


} catch (Exception ex) {
Logger.getLogger(JSUSB.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(Palabra.equals("more light ")){

try {
for(int i=0;i<6;i++){
pcom.sendSingleData('3');}

System.out.print("more light");
} catch (Exception ex) {
Logger.getLogger(JSUSB.class.getName()).log(Level.SEVERE, null, ex);
}

}
if(Palabra.equals("less light ")){

try {
for(int i=0;i<6;i++){
pcom.sendSingleData('4');}

System.out.print("less light");
} catch (Exception ex) {
Logger.getLogger(JSUSB.class.getName()).log(Level.SEVERE, null, ex);
}

if(Palabra.equals("light at half ")){


try {
for(int i=0;i<6;i++){
pcom.sendSingleData('5');}

System.out.print("light at half");
38
} catch (Exception ex) {
Logger.getLogger(JSUSB.class.getName()).log(Level.SEVERE, null, ex);
}
}

if(Palabra.equals("full light ")){


try {
for(int i=0;i<6;i++){
pcom.sendSingleData('6');}

System.out.print("full light");
} catch (Exception ex) {
Logger.getLogger(JSUSB.class.getName()).log(Level.SEVERE, null, ex);
}
}

while(Palabra.equals("exit "))
{
try{
System.out.print("exit");
rec.deallocate();
}
catch(Exception ex)
{}
try {

Synthesizer synth = Central.createSynthesizer(


new SynthesizerModeDesc(Locale.ENGLISH));

synth.allocate();
synth.resume();

synth.speakPlainText("Application terminated", null);

synth.waitEngineState(Synthesizer.QUEUE_EMPTY);

synth.deallocate();
} catch (Exception es) {
es.printStackTrace();
}

System.exit(0);
}
}

39
public static void main(String args[])throws Exception {

SerialPort free = new SerialPort();

List<String> portList = free.getFreeSerialPort();


for (String string : portList)
System.out.println(string);

Parameters settings = new Parameters();


settings.setPort("COM3");
settings.setBaudRate("9600");
pcom = new Com(settings);

Synthesizer synth = Central.createSynthesizer(


new SynthesizerModeDesc(Locale.ENGLISH));

synth.allocate();
synth.resume();
synth.speakPlainText("Welcome to the world of voice
recognition", null);
synth.speakPlainText("You can turn on, or turn off led's,
by using voice commands", null);
synth.speakPlainText("Please refer to the command's
list, to know how to operate the system", null);

synth.waitEngineState(Synthesizer.QUEUE_EMPTY);

synth.deallocate();

rec = Central.createRecognizer(
new EngineModeDesc(Locale.ENGLISH));

rec.allocate();

FileReader reader = new FileReader("c:/grammar.txt");


RuleGrammar gram = rec.loadJSGF(reader);
gram.setEnabled(true);
rec.addResultListener(new JSUSB());

rec.commitChanges();

rec.requestFocus();
rec.resume();
}

40
El contenido del archivo grammar debe de ser de la siguiente forma:

#JSGF V1.0;
grammar javax.speech.demo;
public <sentence> = start | turn off light | more light | less light | light at half | full
light | reset | exit;

En este ejemplo se muestran 8 posibles opciones que el usuario puede


seleccionar:

START.- Despliega en la pantalla LCD la palabra “Bienvenido” y se prende el


primer LED.

TURN OFF LIGHT.- Despliega en la pantalla LCD la frase “Luz apagada” y se


apagan todos los LEDs.

MORE LIGHT.- Despliega en la pantalla LCD la frase “Aumentando luz” y


enciende un LED adicional a los que ya se encuentran prendidos.

LESS LIGHT.- Despliega en la pantalla LCD la frase “Disminuyendo luz” y apaga


en orden un LED de los que se encuentran encendidos.

LIGHT AT HALF.- Despliega en la pantalla LCD la frase “Media luz” y deja


encendidos solo la mitad de los LEDs.

FULL LIGHT.- Despliega en la pantalla LCD la frase “Luz completa” y se


encienden todos los LEDs.

RESET.- Realiza la misma función que el comando START.

EXIT.- Termina el programa principal.

Aún no se puede probar el código ya que mientras no se conecte el


microcontrolador por el puerto USB el programa no se ejecutará así que se debe
proceder a la configuración del microcontrolador.

El microcontrolador debe ser configurado para poder ser reconocido como un


dispositivo USB y que esté listo para la recepción y envío de datos.

El dispositivo será reconocido como un dispositivo de comunicaciones, para esto


se utilizará uno de los ejemplos que vienen dentro de la carpeta de proyectos de la
herramienta PCW Compiler. Este ejemplo emula un dispositivo de comunicación

41
serial por lo que al conectar el PIC a la computadora ésta lo reconocerá como un
dispositivo de comunicación serial. Dicho código será modificado cuanto sea
necesario para que se adapte a las necesidades del proyecto.

Figura A12. Pantalla de inicio del compilador PCWH Compiler de CCS.

Se debe que crear un nuevo proyecto en el entorno de desarrollo y pegar el


siguiente código:

#define __USB_PIC_PERIF__ 1

#if !defined(__PCH__)
#error USB CDC Library requires PIC18
#endif

#if __USB_PIC_PERIF__
#include <18F4455.h>
#fuses
HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VRE
GEN
#use delay(clock=48000000)
#else
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#endif

42
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#if __USB_PIC_PERIF__ && defined(__PCH__)


#define USB_CON_SENSE_PIN PIN_A5
#endif

#include <usb_cdc.h>
#include <lcd.c>

#define LCD_ENABLE_PIN PIN_D0


#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#define LCD_TRIS_LOCATION TRISD

void usb_debug_task(void) {
static int8 last_connected;
static int8 last_enumerated;
int8 new_connected;
int8 new_enumerated;
static int8 last_cdc;
int8 new_cdc;

new_connected=usb_attached();
new_enumerated=usb_enumerated();
new_cdc=usb_cdc_connected();

if (new_connected && !last_connected)


printf("USB connected, waiting for enumaration...\r\n\n");

if (!new_connected && last_connected)


printf("USB disconnected, waiting for connection...\r\n\n");

if (new_enumerated && !last_enumerated)


printf("USB enumerated by PC/HOST\r\n\n");

if (!new_enumerated && last_enumerated)


printf("USB unenumerated by PC/HOST, waiting for enumeration...\r\n\n");

43
if (new_cdc && !last_cdc) {
printf("Serial program initiated on USB<->UART COM Port\r\n\n");

last_connected=new_connected;
last_enumerated=new_enumerated;
last_cdc=new_cdc;
}

void main(void) {
char c;

lcd_init();

output_high(PIN_D0);
output_high(PIN_D1);
output_low(PIN_D2);
output_low(PIN_B7);
output_low(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

lcd_gotoxy(1,1);
printf(lcd_putc,"Esperando ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Comandos ");

#ifdef __PCH__
printf("PCH: v");
printf(__PCH__);
#else
printf("PCM: v");
printf(__PCM__);
#endif
printf("\r\n");

usb_init_cs();

#if !(__USB_PIC_PERIF__)
printf("USBN: 0x%X", usbn_get_version());
printf("\r\n\n");
#endif

while(TRUE) {

usb_task();
44
usb_debug_task();
if (usb_enumerated())
{
if(usb_cdc_kbhit())
{

if(usb_cdc_getc()=='1')
{

lcd_gotoxy(1,1);
printf(lcd_putc,"Bienvenido ");
lcd_gotoxy(1,2);
printf(lcd_putc," ");
output_high(PIN_B7);
output_low(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

delay_ms(150);
}

if(usb_cdc_getc()=='2')
{

printf(lcd_putc,"\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Luz ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Apagada ");
output_low(PIN_B7);
output_low(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

delay_ms(150);
}

if(usb_cdc_getc()=='3')
{

if(!input(PIN_B7)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Aumentando ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");
output_high(PIN_B7);
output_low(PIN_B6);
45
output_low(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);

else if(input(PIN_B7)&&!input(PIN_B6)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Aumentando ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");
output_high(PIN_B7);
output_high(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);
}

else if(input(PIN_B6)&&!input(PIN_B5)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Aumentando ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");
output_high(PIN_B7);
output_high(PIN_B6);
output_high(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);
}

else if(input(PIN_B5)&&!input(PIN_B4)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Aumentando ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");
output_high(PIN_B7);
output_high(PIN_B6);
output_high(PIN_B5);
output_high(PIN_B4);

//delay_ms(150);
}

46
}
if(usb_cdc_getc()=='4')
{

if(input(PIN_B4)&&input(PIN_B5)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Disminuyendo");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");

output_high(PIN_B7);
output_high(PIN_B6);
output_high(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);
}

else if(!input(PIN_B4)&&input(PIN_B5)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Disminuyendo");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");

output_high(PIN_B7);
output_high(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);
}
else if(!input(PIN_B5)&&input(PIN_B6)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Disminuyendo");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");

output_high(PIN_B7);
output_low(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);
}
else if(!input(PIN_B6)&&input(PIN_B7)){
lcd_gotoxy(1,1);
printf(lcd_putc,"Disminuyendo");
47
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");

output_low(PIN_B7);
output_low(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

//delay_ms(150);
}
}

if(usb_cdc_getc()=='5')
{

lcd_gotoxy(1,1);
printf(lcd_putc,"Media ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Luz ");
output_high(PIN_B7);
output_high(PIN_B6);
output_low(PIN_B5);
output_low(PIN_B4);

delay_ms(150);
}

if(usb_cdc_getc()=='6')
{

lcd_gotoxy(1,1);
printf(lcd_putc,"Luz ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Completa ");
output_high(PIN_B7);
output_high(PIN_B6);
output_high(PIN_B5);
output_high(PIN_B4);

delay_ms(150);
}
}
}
}

48
Una vez colocado el código se pulsa en la pestaña de Compilar y se compila el
código para que genere los archivos necesarios para la creación del archivo HEX
que es el necesario para grabar el programa en el microcontrolador.

Figura A13. Localización del botón de compilación en PCW Compiler.

Si no hay errores en la compilación debe aparecer la siguiente pantalla:

Figura A14. Proceso de compilación de código en PCW Compiler.

49
Una vez compilado el proyecto se generan archivos de cabecera y demás. Uno
muy importante que se genera es el archivo usb_desc_cdc.h que es el archivo que
contiene el VID&PID (identificadores del vendedor y fabricante) del dispositivo.
Para abrir este archivo se busca en el lado izquierdo del IDE donde hay una
pestaña llamada Files, ahí se selecciona tal archivo y se pulsa dos veces el botón
izquierdo del ratón.

Figura A15. Localización del archivo usb_desc_cdc.h dentro del entorno de


PCW Compiler.

Las líneas de código que poseen el VID y el PID son las siguientes:

const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={


//starts of with device configuration. only one possible
USB_DESC_DEVICE_LEN, //the length of this report ==0
0x01, //the constant DEVICE (DEVICE 0x01) ==1
0x10,0x01, //usb version in bcd ==2,3
0x02, //class code. 0x02=Communication Device Class ==4
0x00, //subclass code ==5
0x00, //protocol code ==6
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint
0. (SLOW SPEED SPECIFIES 8) ==7

50
0x61,0x04, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??) ==8,9
0x61,0x04, //product id ==10,11
0x00,0x01, //device release number ==12,13
0x01, //index of string description of manufacturer. therefore we point
to string_1 array (see below) ==14
0x02, //index of string descriptor of the product ==15
0x00, //index of string descriptor of serial number ==16
USB_NUM_CONFIGURATIONS //number of possible configurations
==17
};

Las líneas resaltadas se deben modificar para poner el ID de vendedor y de


producto, mismos que hay que tener en cuenta al momento de generar el driver
para la PC.

Una vez seleccionado el VID y el PID más conveniente se vuelve a compilar y se


genera el archivo HEX final que será el que se grabará en el microcontrolador.

Una vez generado el archivo HEX se procede a grabar los datos en el


microcontrolador, para esto se utilizará un programa llamado PICkit Programmer
(versión 2 en este caso).

La interfaz del programa es la siguiente:

Figura A16. Interfaz del programa PICkit Programmer

51
Para comenzar hay que conectar el grabador por medio del puerto USB de la PC y
colocar el PIC en el grabador. Ahora se selecciona la familia del dispositivo tal
como se muestra en la imagen:

Figura A17. Localización de la familia de dispositivos en PICkit Programmer.

Una vez realizado esto se procede a cargar el archivo HEX correspondiente, para
esto se debe acceder al menú de herramientas y seguir la siguiente ruta: File-
>Import HEX o en su defecto presionar Ctrl+I.

Figura A18. Localización de la opción de importación de archivo .HEX

52
Una vez que se selecciona el archivo se procederá a grabarlo en el PIC. Pero
primero se debe borrar la información previa que tenga grabada el PIC, esto se
realiza mediante el botón de Erase. Luego se puede verificar si la memoria del PIC
ya está vacía mediante el botón de Blank Check.

Para grabar el archivo se utiliza el botón de Write.

Figura A19. Botones para programar el microcontrolador en PICkit


Programmer.

Una vez que ya se tienen las conexiones de hardware correctas y que se tiene
grabado el programa correcto en el microcontrolador se procede a la generación
del driver para el host. Como la PC generalmente ya posee drivers para
dispositivos de comunicación (Puerto COM) el PIC será reconocido al instante en
cuanto se conecte, no obstante es necesario instalar el driver con las
especificaciones del VID y el PID para que cada vez que sea conectado la
computadora lo reconozca satisfactoriamente. Para esto se utiliza una herramienta
llamada V3.1 – INF Enumeración Datos uC PIC-USB en la cual se le especifica el
VID y PID del dispositivo. Es muy importante comprobar que el VID y el PID del
archivo a generar sean exactamente iguales al VID y PID grabados en el PIC.

En la siguiente imagen se muestra la interfaz de dicho programa donde se puede


observar el PID, el VID y el tipo de transferencia que se manejan en este proyecto.

Una vez ingresados los datos correctos se pulsa en Guardar para que se genere
el archivo correspondiente. El cual se guardará en la computadora para ser
utilizado cuando se solicite el driver correspondiente para el PIC.

53
Figura A20. Interfaz de la herramienta generadora de archivos .INF para los
drivers de microcontroladores de Microchip.

A continuación se muestran las líneas de código generadas en el archivo .INF


donde se muestra la identificación del fabricante y del producto.

;------------------------------------------------------------------------------
; Vendor and Product ID Definitions
;------------------------------------------------------------------------------
[SourceDisksFiles]
[SourceDisksNames]
[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_0461&PID_0461

[DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_0461&PID_0461

54
Con esto ya se tiene configurado todo para la prueba del prototipo, ahora solo hay
que conectar los componentes tal y como se muestra en el diagrama de
conexiones al principio de esta sección. Es importante tener en cuenta la
configuración del cable USB con el cual se conectará el microcontrolador a la
computadora:

La configuración del conector de tipo A (que es el que se usará) es la siguiente:

Figura A21. Configuración del conector tipo A para cables USB.

Se puede observar que el cable rojo corresponde a la alimentación de voltaje,


misma que será proporcionada por el puerto de la computadora donde se
conecte el cable, así mismo el cable negro corresponde a la tierra que también
proviene del puerto USB de la computadora.

Los cables verde y blanco sirven para el envío de datos, el verde envía y el
blanco recibe.

Siguiendo todos estos pasos se puede proceder a probar el sistema prototipo y


a observar su comportamiento.

55

Das könnte Ihnen auch gefallen