EEG - Biblioteca ORT [PDF]

Apr 10, 2014 - Electrodos: sensores de potencial bioeléctrico. 4.1. Responsabilidades. Los electrodos son el primer esl

15 downloads 26 Views 8MB Size

Recommend Stories


Biblioteca Digital [PDF]
Parcours identitaire au travers des langues dans Le bleu des abeilles de Laura Alcoba. Orianne Guy. # File (.pdf). # Abstract Published in 2013, Le bleu des abeilles gives word to an anonymous Argentinean girl who joins her mother exiled in France. L

Biblioteca Digital UniRedentor [PDF]
Huffman, Jeff C.; Mastromauro, Carol A.; Boehm, Julia K.; Seabrook, Rita; Fricchione, Gregory L.; Denninger, John W.; Lyubomirsky, Sonja ... las investigaciones de las Ciencias Humanas, sus contribuciones teóricas, empíricas y posibles aplicaciones.;

WILMAN PACHECO (BIBLIOTECA).pdf
Be who you needed when you were younger. Anonymous

PDF EEG pocketflyer Download
Don't fear change. The surprise is the only way to new discoveries. Be playful! Gordana Biernat

Biblioteca Digital [PDF]
Parcours identitaire au travers des langues dans Le bleu des abeilles de Laura Alcoba. Orianne Guy. # File (.pdf). # Abstract Published in 2013, Le bleu des abeilles gives word to an anonymous Argentinean girl who joins her mother exiled in France. L

biblioteca
The best time to plant a tree was 20 years ago. The second best time is now. Chinese Proverb

Ort, Datum
If you want to become full, let yourself be empty. Lao Tzu

Biblioteca
If your life's work can be accomplished in your lifetime, you're not thinking big enough. Wes Jacks

Biblioteca
At the end of your life, you will never regret not having passed one more test, not winning one more

biblioteca
Don't count the days, make the days count. Muhammad Ali

Idea Transcript


Universidad ORT Uruguay Facultad de Ingeniería

Adquisidor de actividad eléctrica del cerebro, señales de electroencefalograma (EEG).

Entregado como requisito para la obtención del título de Ingeniero en Electrónica

Daniel Merlinski - 146455 Diego Alonso - 153259 Gonzalo de León - 158545

Tutores: André Fonseca Ismael Garrido

2014

Declaración de autoría Nosotros, Daniel Merlinski, Diego Alonso y Gonzalo de León, declaramos que el trabajo que se presenta en esa obra es de nuestra propia mano. Podemos asegurar que: La obra fue producida en su totalidad mientras realizábamos el trabajo nal de carrera; Cuando hemos consultado el trabajo publicado por otros, lo hemos atribuido con claridad; Cuando hemos citado obras de otros, hemos indicado las fuentes. Con excepción de estas citas, la obra es enteramente nuestra; En la obra, hemos acusado recibo de las ayudas recibidas; Cuando la obra se basa en trabajo realizado conjuntamente con otros, hemos explicado claramente qué fue contribuido por otros, y qué fue contribuido por nosotros; Ninguna parte de este trabajo ha sido publicada previamente a su entrega, excepto donde se han realizado las aclaraciones correspondientes.

Daniel Merlinski

Diego Alonso

Gonzalo de León

10 de Abril de 2014

2

Agradecimientos En primer lugar queremos agradecer a nuestras respectivas familias por el apoyo y conanza brindados durante todos estos años, sin ellos nada de esto hubiera sido posible. Agradecer a nuestros amigos y compañeros a lo largo de la carrera, Martín Ljubicic, Sebastián Barbat, Christian Kuster, Paolo Principi, Sebastián Bardacosta, Joaquin Oldan, Tabaré Camacho, Andrés Burel, Gerónimo Peradotto, Florencia Pla, Agustín García y Gonzalo Guerrero, por acompañarnos durante este largo emprendimiento, contagiándonos su alegría, enseñándonos diferentes maneras de ver y disfrutar la vida. Gracias por hacer divertida esta trayectoria de aprendizaje y conocimientos. A la Universidad ORT por brindarnos la posibilidad de desarrollarnos en el ámbito académico, personal y laboral. Al Ing. Andrés Azar, a la Dra. Neuropediatra Elisa Sirio y a la Dra. Anestesista Carmen Estela por su asesoramiento técnico sobre la temática elegida. Por último queremos agradecer a nuestros tutores André Fonseca e Ismael Garrido por la ayuda brindada a lo largo de este proyecto.

3

Abstract En el presente documento se expone la investigación llevada a cabo para desarrollar un equipo adquisidor de señales de electroencefalograma, así como el desarrollo propiamente dicho, acompañado de un software que demuestre las funcionalidades y el potencial del equipo. El sistema utiliza electrodos del tipo activos que se sitúan sobre el cuero cabelludo, para obtener la señal eléctrica generada por las neuronas. Esta señal se transmite a una placa para su amplicación, la que a su vez realiza un ltrado grueso de la misma. Luego es capturada por un microcontrolador que se encarga de la digitalización y acondicionamiento. Finalmente, se transmiten los datos a un PC donde se realiza un ltrado más no, para su posterior visualización y se ejecutan algoritmos que detectan patrones en las señales. Las principales características que se destacan sobre el trabajo realizado, es que se logró un equipo compacto, móvil, exible y de bajo costo. El emprendimiento de este proyecto fue motivado por las expectativas que genera un equipo de estas características en un sinnúmero de aplicaciones que podría tener el mismo. Dichas aplicaciones podrían contemplar una amplia variedad de campos, desde las consolas de videojuegos, la robótica y el control de procesos hasta la medicina. Como claro ejemplo de aplicación y del potencial de este prototipo, cabe destacar la posibilidad de que personas que presentan incapacidad motriz puedan valerse por sí mismas.

4

Índice Declaración de autoría

2

Agradecimientos

3

Abstract

4

Palabras Clave

10

Glosario

12

1. Introducción 1.1.

15

Objetivos del proyecto

. . . . . . . . . . . . . . . . . . . . . . .

15

2. Descripción del sistema

17

3. Estudio previo en neurología

20

3.1. 3.2.

Introducción a la anatomía del cerebro humano

. . . . . . . . .

20

Introducción a la electroencefalografía . . . . . . . . . . . . . . .

22

3.2.1.

Posicionamiento de los electrodos, Sistema 10 - 20 [1]

22

3.2.2.

Conguración y montaje de los electrodos

. .

. . . . . . . .

23

3.3.

Parámetros de la señal de electroencefalografía . . . . . . . . . .

24

3.4.

Ritmos cerebrales . . . . . . . . . . . . . . . . . . . . . . . . . .

27

3.4.1.

Ritmo Alfa

. . . . . . . . . . . . . . . . . . . . . . . . .

27

3.4.2.

Ritmo Beta

. . . . . . . . . . . . . . . . . . . . . . . . .

30

3.5.

Artefactos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

3.6.

Potenciales cerebrales . . . . . . . . . . . . . . . . . . . . . . . .

34

4. Electrodos: sensores de potencial bioeléctrico

35

4.1.

Responsabilidades . . . . . . . . . . . . . . . . . . . . . . . . . .

35

4.2.

Desarrollo

35

4.3.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Implementación nal

. . . . . . . . . . . . . . . . . . . . . . . .

38

4.3.1.

Material utilizado para la construcción

. . . . . . . . . .

38

4.3.2.

Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . .

39

5

4.3.3.

Técnica de medida

. . . . . . . . . . . . . . . . . . . . .

41

4.3.4.

Electrodo de referencia . . . . . . . . . . . . . . . . . . .

41

4.3.5.

Montaje y posicionamiento . . . . . . . . . . . . . . . . .

41

5. Interferencia

44

5.1.

Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

44

5.2.

Fuentes de interferencia . . . . . . . . . . . . . . . . . . . . . . .

44

5.3.

Soluciones para minimizar los efectos

46

. . . . . . . . . . . . . . .

6. Proyecto OpenEEG

49

7. Placa Amplicadora

50

7.1.

Descripción

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

50

7.2.

Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51

Alimentación del circuito . . . . . . . . . . . . . . . . . . . . . .

51

7.3.1.

. . . . . . . . . . . . . .

52

. . . . . . . . . . . . . . . . . . . . . . . . .

54

7.3. 7.4.

Tierra virtual y plano de tierra

Etapas del circuito 7.4.1.

Filtro supresor de ondas de radio

. . . . . . . . . . . . .

54

7.4.2.

Circuito de protección

. . . . . . . . . . . . . . . . . . .

57

7.4.3.

Etapa de amplicación diferencial . . . . . . . . . . . . .

58

7.4.4.

Segunda etapa de amplicación

. . . . . . . . . . . . . .

61

7.4.5.

Filtrado antialiasing

. . . . . . . . . . . . . . . . . . . .

64

7.4.6.

Circuito de pierna derecha . . . . . . . . . . . . . . . . .

67

7.4.7.

Elección de los amplicadores operacionales

. . . . . . .

69

Características de los integrados . . . . . . . . .

70

7.4.7.1. 7.5.

Ruido provocado por los Amplicadores [15] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7.6.

Respuesta en frecuencia de la placa amplicadora

. . . . . . . .

8. Etapa Digital

71 75

78

8.1.

Conversor analógico-digital . . . . . . . . . . . . . . . . . . . . .

78

8.2.

Comunicación microcontrolador-computadora

79

8.3.

Elección de módulos para comunicación BlueTooth

8.4.

Elección del microcontrolador

8.5.

Algoritmo del microcontrolador para conversión A/D y envío de

. . . . . . . . . . . . . . . . .

80

. . . . . . . . . . . . . . . . . . .

81

datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9. Software Monitor de señales cerebrales

82

85

9.1.

Implementación del software . . . . . . . . . . . . . . . . . . . .

85

9.2.

Serial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

86

6

9.3.

Buer

9.4.

Proceso 9.4.1.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

86

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

86

Acondicionador 9.4.1.1.

86 87

9.4.2.

Diezmado

9.4.3.

Detección de ritmos y generación de señales de control

9.4.4.

. . . . . . . . . . . . . . . . . . . . . . . . . .

89

9.4.3.1.

Interfaz cerebro computadora - BCI . . . . . . .

89

9.4.3.2.

Reconocimiento de ritmos cerebrales

. . . . . .

91

. . . . . . . . . . . .

95

BCI basada en ritmo alfa occipital 9.4.4.1.

Estimador potencia Alfa . . . . . . . . . . . . .

96

9.4.4.2.

Filtro pasa banda . . . . . . . . . . . . . . . . .

96

9.4.4.3.

Filtro de suavizado . . . . . . . . . . . . . . . .

98

9.4.4.4.

Umbral

9.4.4.5.

Umbral adaptativo . . . . . . . . . . . . . . . . 104

9.4.4.6.

Performance de la BCI basada en ritmo alfa . . 105

. . . . . . . . . . . . . . . . . . . . . . 101

BCI basada en ritmo alfa frontal

9.4.6.

BCI basada en potenciales miográcos

. . . . . . . . . . . . . 115 . . . . . . . . . . 115

9.4.6.1.

Detección del parpadeo

9.4.6.2.

Señales de control a partir de los parpadeos

Visualización 9.4.7.1.

Servidor 9.5.1.

88

.

9.4.5.

9.4.7. 9.5.

. . . . . . . . . . . . . . . . . . . . . . .

Filtro 40 Hz . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . 116 . . 116

. . . . . . . . . . . . . . . . . . . . . . . . 120

Velocidad de barrido . . . . . . . . . . . . . . . 120

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

Comandos . . . . . . . . . . . . . . . . . . . . . . . . . . 120

10.Aplicación de prueba de la BCI

122

11.Pruebas realizadas sobre el funcionamiento del sistema

123

11.1. Pruebas con cable sin mallar y mallado . . . . . . . . . . . . . . 123 11.2. Medición del ruido

. . . . . . . . . . . . . . . . . . . . . . . . . 125

11.3. Frecuencia de corte y atenuación en la banda de paso y a la frecuencia de 512 Hz

. . . . . . . . . . . . . . . . . . . . . . . . 127

11.4. Vericación de la frecuencia de muestreo y envío de datos del microcontrolador

. . . . . . . . . . . . . . . . . . . . . . . . . . 127

11.5. Pruebas realizadas al software de monitoreo

12.Conclusiones

. . . . . . . . . . . 128

129

12.1. Planicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 12.2. Posibles mejoras a futuro . . . . . . . . . . . . . . . . . . . . . . 132

Referencias Bibliográcas

134

7

A. Apéndice

136

A.1. Ecuaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 A.1.1. Filtro supresor de ondas de radio A.1.2. Etapa de amplicación variable

. . . . . . . . . . . . . 137 . . . . . . . . . . . . . . 140

A.1.3. Filtro antialiasing . . . . . . . . . . . . . . . . . . . . . . 142 A.1.4. Exigencia de CMRR

. . . . . . . . . . . . . . . . . . . . 147

A.1.5. Cálculo del ruido producido por los amplicadores operacionales A.2. Manual de usuario

. . . . . . . . . . . . . . . . . . . . . . . . . . 147 . . . . . . . . . . . . . . . . . . . . . . . . . 152

A.2.1. Instrucciones de puesta en marcha . . . . . . . . . . . . . 152 A.2.2. Alimentación del electroencefalógrafo . . . . . . . . . . . 153 A.2.3. Software de monitoreo

. . . . . . . . . . . . . . . . . . . 154

A.2.3.1.

Descripción . . . . . . . . . . . . . . . . . . . . 154

A.2.3.2.

Requerimientos . . . . . . . . . . . . . . . . . . 155

A.2.3.3.

Funcionamiento . . . . . . . . . . . . . . . . . . 155

A.2.4. Programa de prueba para la BCI [17] . . . . . . . . . . . 160 A.2.4.1.

Requerimientos . . . . . . . . . . . . . . . . . . 160

A.2.4.2.

Instrucciones de puesta en marcha del robot . . 161

A.2.4.3.

Instrucciones de uso

. . . . . . . . . . . . . . . 162

A.3. Código del microcontrolador ATmega 2560 . . . . . . . . . . . . 163 A.4. Códigos de Scicoslab para ltros digitales . . . . . . . . . . . . . 168 A.4.1. Código de ltro Gauss

. . . . . . . . . . . . . . . . . . . 169

A.4.2. Código Filtro IIR pasa bajo

. . . . . . . . . . . . . . . . 172

A.4.3. Código ltro IIR pasa banda . . . . . . . . . . . . . . . . 175 A.4.4. Código para generar ltro pasa bajo IIR A.4.5. Código para generar ltro pasa banda IIR A.4.6. Código para modelado de la BCI

. . . . . . . . 183

. . . . . . . . . . . . . 188

A.5. Códigos de JAVA para el software de monitoreo A.5.1. Clases del dominio

. . . . . . . . . 179

. . . . . . . . . 192

. . . . . . . . . . . . . . . . . . . . . 193

A.5.1.1.

Clase buer . . . . . . . . . . . . . . . . . . . . 193

A.5.1.2.

Clase escribir archivo . . . . . . . . . . . . . . . 198

A.5.1.3.

Clase FFT

A.5.1.4.

Clase gráca

A.5.1.5.

Clase leer archivo . . . . . . . . . . . . . . . . . 212

A.5.1.6.

Clase procesamiento de señal

A.5.1.7.

Clase proceso . . . . . . . . . . . . . . . . . . . 227

A.5.1.8.

Clase serial

A.5.1.9.

Clase sistema . . . . . . . . . . . . . . . . . . . 243

. . . . . . . . . . . . . . . . . . . . 201 . . . . . . . . . . . . . . . . . . . 204 . . . . . . . . . . 215

. . . . . . . . . . . . . . . . . . . . 237

A.5.1.10. Clase servidor . . . . . . . . . . . . . . . . . . . 246

8

A.5.2. Clases de Interfaz . . . . . . . . . . . . . . . . . . . . . . 249 A.5.2.1.

Clase ventana . . . . . . . . . . . . . . . . . . . 249

A.5.2.2.

Clase main

. . . . . . . . . . . . . . . . . . . . 285

A.6. Código de programa de comunicación PC - NXT . . . . . . . . . 287 A.7. Código robot NXT

. . . . . . . . . . . . . . . . . . . . . . . . . 291

A.8. Diagrama esquemático de la placa amplicadora . . . . . . . . . 295 A.9. Layout de la placa amplicadora . . . . . . . . . . . . . . . . . . 298

B. Anexo

300

B.1. Hoja de datos ATmega 2560 . . . . . . . . . . . . . . . . . . . . 301 B.2. Hoja de datos LM78xx . . . . . . . . . . . . . . . . . . . . . . . 710 B.3. Hoja de datos INA114BP

. . . . . . . . . . . . . . . . . . . . . 739

B.4. Hoja de datos TLC277 . . . . . . . . . . . . . . . . . . . . . . . 757 B.5. Hoja de datos HC05

. . . . . . . . . . . . . . . . . . . . . . . . 795

B.6. Hoja de datos HC06

. . . . . . . . . . . . . . . . . . . . . . . . 809

9

Palabras Clave EEG Electrodo Filtrado Microcontrolador BCI BT ATMEGA 2560 Fusiformes Ritmo cerebral ERS ERD Artefacto PR PE BRD DRL EMI CMRR Vcm Cable mallado VGND OpenEEG Placa Arduino INA114BP TLC277P Filtro antialiasing

10

Conversor A/D Diagrama de Bode AAMI IEC RMS Relación señal-ruido LM7805 FTDI puerto COM Filtros IIR Filtros FIR Enventanado Tiempo de establecimiento Nivel de background

11

Glosario EEG: Electroencefalograma, registro de los potenciales eléctricos que se originan en la corteza cerebral.

Electrodo:

Conductor eléctrico utilizado para hacer contacto con una parte

no metálica de un circuito.

Filtrado:

Discriminación de una determinada frecuencia o gama de frecuen-

cias de una señal eléctrica.

Microcontrolador:

Circuito integrado programable, capaz de ejecutar las

órdenes grabadas en su memoria.

BCI: Interfaz Cerebro-Computadora (por sus siglas en inglés,

Brain Com-

puter Interface ).

BT:

BlueTooth, protocolo de comunicaciones diseñado especialmente para

dispositivos de bajo consumo, que requieren corto alcance de emisión y basados en transceptores de bajo costo.

ATMEGA 2560: Microcontrolador utilizado para este proyecto. Fusiformes: Que tengan una forma redondeada. Ritmo cerebral: Oscilaciones eléctricas que genera el cerebro. ERS: Evento relativo a la sincronización. ERD: Evento relativo a la desincronización. Artefacto: Toda señal eléctrica que aparece en el registro de electroencefalografía y no pertenece a la actividad bioeléctrica del cerebro.

PR: Potenciales Relacionados, generan una disminución en la amplitud base del ritmo cerebral.

PE: Potenciales Evocados, cambios en la señal bioeléctrica producto de estímulos externos.

BRD: Archivo del programa EAGLE Circuit Board File. DRL: Circuito derivador de pierna derecha (por sus siglas en inglés, Driven

12

Right Leg ), es el circuito encargado de generar la tensión para el electrodo de referencia, además de aumentar la relación de rechazo al modo común.

EMI: Interferencias electromagnéticas (por sus siglas en inglés, ElectroMagnetic Interference ), son señales de origen externo que pueden introducir un error en la señal a medir.

CMRR: Relación de rechazo al modo común (por sus siglas en inglés, Common Mode Rejection Ratio ), representa la habilidad del amplicador para rechazar las tensiones de modo común presentes en las entradas.

Vcm:

Tensión de modo común, diferencia de potencial entre el usuario y la

masa del circuito.

Cable mallado:

Tipo de cable recubierto por una malla o un tubo metálico

que actúa de jaula de Faraday para evitar el acople de ruidos y otras interferencias.

VGND: Es la referencia de la señal medida. OpenEEG: Proyecto open source creado con el n de construir electroencefalógrafos de bajo costo.

Placa Arduino:

Placa sobre la cual viene montado el microcontrolador

ATmega 2560.

INA114BP: Amplicador de instrumentación utilizado para la primera etapa de la placa.

TLC277P:

Amplicador operacional utilizado para la segunda etapa la

placa.

Filtro antialiasing:

Filtro pasa bajo analógico que precede a la etapa de

conversión analógica-digital, cuya función es limitar el ancho de banda de señal a la mitad de la frecuencia de muestreo.

Conversor A/D: Conversor analógico digital. Diagrama de Bode: Representación gráca que sirve para caracterizar la respuesta en frecuencia de un sistema.

AAMI: Association for the Advancement of Medical Instrumentation. IEC: International Electrotechnical Commission. RMS: Valor ecaz (por sus siglas en inglés, Root Mean Square ), es

una

medida estadística de magnitud.

13

Relación señal-ruido:

Valor medido en decibeles, que se utiliza para com-

parar el nivel de la señal de interés con el nivel de ruido. Considerando valores medidos en voltios, se calcula como

Se˜ nal 20 × log( Ruido ).

LM7805: Regulador de tensión utilizado para la alimentación de la placa. FTDI: Conversor Serie-USB (TTL) que permite conectar dispositivos TTL por USB.

puerto COM: Interfaz de comunicación serial de datos digitales. Filtros IIR: Filtros de respuesta impulsiva infnita. Filtros FIR: Filtros de respuesta impulsiva nita. Enventanado: Proceso de multiplicar una señal por una ventana. Tiempo de establecimiento: Tiempo necesario para que la señal alcanze en 95% del valor nal.

Nivel de background:

Nivel base de un ritmo cerebral.

14

1. Introducción El proyecto consiste en la creación de un prototipo compacto, móvil y exible para la adquisición de señales similares a las obtenidas mediante un electroencefalografo. Para lograr el objetivo se construyeron tres placas electrónicas, todas ellas realizadas por el grupo. La primera fue realizada con componentes disponibles en plaza (excepto los amplicadores operacionales) mientras que la segunda y tercera son placas doble faz y se montaron con componentes traídos desde EEUU. El emprendimiento de este proyecto fue motivado por las expectativas que genera un equipo de estas características en un sinnúmero de aplicaciones que podría tener el mismo. Dichas aplicaciones podrían contemplar una amplia variedad de campos, desde el de las consolas de video juegos, la robótica y el control de procesos hasta la medicina.

1.1. Objetivos del proyecto El objetivo del proyecto fue realizar un prototipo que cumpla con las siguientes características:

Compacto y móvil:

se desea obtener un prototipo con estas característi-

cas para que sea fácilmente trasladable, cómodo de usar y que no requiera prácticamente ningún mantenimiento.

Bajo costo:

como parte de los objetivos, se priorizó que el dispositivo lo-

.

grado sea de bajo costo

Componentes accesibles: los componentes utilizados deberán ser conseguidos sin mayores dicultades.

Independencia en la implementación:

el prototipo logrado debe ser lo

más universal posible, es decir, debe funcionar para cualquier persona y sobre

15

cualquier sistema operativo. A lo largo del desarrollo del proyecto dichos conceptos fueron establecidos como premisas a la hora de tomar decisiones.

16

2. Descripción del sistema Este capítulo tiene como objetivo dar una descripción global del proyecto, con el objetivo de facilitar la lectura de los siguientes capítulos. El prototipo logrado se puede dividir en 2 grupos, por un lado está la etapa de adquisición de señal y por otro lado el sistema de monitoreo. Para cumplir la primera etapa se diseñó un equipo compacto que permita adquirir la señal eléctrica presente en el cerebro. El adquisidor a su vez se compone de 3 elementos fundamentales, que son los electrodos, la placa de amplicación y el microcontrolador. Como segunda parte, se realizó un software de monitoreo que graque en un eje de coordenadas y en tiempo real, las señales eléctricas generadas, y que permita la aplicación en un caso de uso con la construcción de una Interfaz Cerebro-Computadora (BCI, por sus siglas en inglés, Brain Computer Inter-

face ). En la gura 2.1 se muestra un diagrama de bloques general del sistema, según lo mencionado recientemente, seguido de una breve introducción de cada elemento.

Figura 2.1.: Diagrama global del sistema.

Electrodos: los electrodos se sitúan sobre la supercie del cráneo, son utilizados para la obtención de las señales bioeléctricas generadas por el cerebro.

17

Se compone únicamente de un pequeño circuito y del cable mallado a través del cual se transmite la señal.

Placa de amplicación: la señal de

µVobtenida

esta parte del sistema se encarga de amplicar

con los electrodos y de realizar un ltrado primario

(ltrado grueso). La señal amplicada luego se transmite a la siguiente etapa mediante un cable convencional.

Placa Arduino con microcontrolador ATMEGA:

este microcontrola-

dor recibe las señales de la placa amplicadora. Es el encargado de digitalizar y enviar los datos a un PC mediante BlueTooth (BT). Se incorpora un módulo adicional que permite la comunicación utilizando dicho protocolo.

Sistema de monitoreo: El software de monitoreo diseñado realiza el tratamiento de los datos para gracar la señal obtenida y características particulares de la misma. Además funciona como un servidor local, enviando información sobre la señal a posibles clientes. Consta de software y un pequeño hardware adicional para hacer posible la comunicación por BT.

Los electrodos utilizados son del tipo activos y particularmente en este proyecto, se trabajó con los electrodos de Joerg Hansmann. El hardware o casco sobre el cual fueron montados los electrodos es un diseño propio. Se establecieron determinadas características a la hora de realizar el diseño del casco; el mismo debería ser ajustable a distintos usuarios para que pueda ser utilizado por varias personas, además era de vital importancia lograr que los puntos de contacto de los electrodos puedan ejercer una presión adecuada sobre el cuero cabelludo. También era deseable poder colocar los electrodos en ciertas zonas de interés, y nalmente se debería lograr todo lo anterior con un diseño robusto y simple, para poder ser transportado fácilmente. En el capítulo

4 se explicará

la evolución del prototipo y los distintos elementos que lo componen. El desarrollo del hardware de la placa de amplicación se basa en un modelo open source obtenido de la página openEEG.org, con algunas modicaciones realizadas para lograr un diseño más compacto, económico, con un mayor rechazo a la interferencia de la red eléctrica y con una mayor excursión de la señal de salida. En el capítulo 7 se explica en detalle este elemento del proyecto. Los elementos de software de este proyecto son tres, el software del micro-

18

controlador ATMEGA, el software de monitoreo y la aplicación de prueba para la BCI. Todos son independientes entre sí y se conectan en el orden que están mencionados. Los primeros dos se comunican utilizando BT, mientras que los últimos dos se conectan localmente mediante sockets. La conexiones entre microcontrolador y el software de monitoreo es automática una vez que ambos están en funcionamiento, como se explicará en la sección 8.3, esto evita que el usuario requiera conocimiento en este ámbito. La conexión entre el software de monitoreo (servidor) y la aplicación de prueba (cliente) se completa al aceptar la petición del cliente desde el servidor. El software desarrollado para el microcontrolador tiene como objetivo la digitalización de la señal analógica a una tasa de muestreo adecuada, para su posterior transmisión a un PC. El mismo puede ser implementado sobre cualquier microcontrolador, cuyos registros utilizados, frecuencia de reloj y tensión de operación, sean iguales a las del ATMEGA 2560. El funcionamiento en detalle de este sistema se explica en el capítulo 8. El software diseñado para el monitoreo puede ser ejecutado sobre cualquier sistema operativo. Este elemento permite la visualización de la señal de EEG obtenida en el tiempo, además de algunas señales que se consideran de interés, el funcionamiento de este software se explicará en el capítulo 9.

19

3. Estudio previo en neurología Para el comienzo del proyecto, fue necesario realizar un estudio introductorio sobre todos los temas relacionados a la electroencefalografía. El estudio que se realizó se considera de carácter fundamental para el éxito en la posterior implementación, teniendo como objetivo profundizar el conocimiento en las siguientes áreas: En dónde y porqué se generan las señales bioeléctricas. Tipo de señales que se pueden obtener en amplitud y frecuencia. Posición en la que se deben colocar los electrodos para obtener las señales. Ritmos cerebrales detectables. Ruidos e interferencias en señales de electroencefalograma.

3.1. Introducción a la anatomía del cerebro humano El cerebro humano se divide en dos hemisferios, derecho e izquierdo, a su vez los hemisferios se subdividen en regiones denominadas lóbulos dependiendo de su funcionalidad. Estas subregiones son, lóbulo frontal, occipital, temporal y parietal. La corteza cerebral es un capa de tejido gris de aproximadamente 10.000 millones de neuronas que cubre la supercie de los hemisferios cerebrales. Es la encargada de interpretar los estímulos provenientes de los órganos sensoriales, del control de los movimientos, de producir el razonamiento y el juicio. Las neuronas que constituyen el tejido nervioso del cerebro son células excitables, es decir posen la capacidad de recibir, interpretar y trasmitir impulsos eléctricos los cuales pueden ser captados por electrodos situados sobre el cuero cabelludo.

20

Lóbulo frontal: situado en la parte anterior de la cabeza, alberga la corteza motora primaria, se encarga del movimiento ocular voluntario e interviene en el razonamiento y en el habla. Lóbulo occipital: se encuentra en la parte posterior de la cabeza, contiene a la corteza visual. Lóbulo parietal: esta ubicado entre el lóbulo frontal y occipital debajo del hueso parietal, interviene en la interpretación del dolor, reconocimiento espacial y sentido del tacto. Lóbulo temporal: se sitúa debajo del lóbulo parietal, contiene a la corteza primaria auditiva, interviene en la memoria y en el sentido del olfato.

Figura 3.1.: Encéfalo.

21

3.2. Introducción a la electroencefalografía El electroencefalograma (EEG) es el registro de los potenciales eléctricos que se originan en la corteza cerebral. Dicha actividad es adquirida por electrodos situados sobre la supercie del cuero cabelludo. Los pequeños potenciales recogidos por los electrodos son trasmitidos al electroencefalógrafo que amplica e imprime en una pantalla los grafos de las señales obtenidas.

3.2.1. Posicionamiento de los electrodos, Sistema 10 20 [1] Los electroencefalógrafos en la actualidad poseen entre 20 y 40 canales lo que les permiten capturar la actividad bioeléctrica de varias regiones del cerebro simultáneamente. La posición los electrodos fue estandarizada internacionalmente según el denominado sistema

10 − 20

(propuesto por Jasper en 1958),

cuyo nombre deriva de la distancia que hay entre dos electrodos subyacentes, esta puede ser 10 o 20 por ciento de la distancia que existe entre la región posterior y anterior de la cabeza (gura 3.2). Dicha estandarización tiene como objetivo comparar las señales eléctricas de un sujeto en el tiempo o con las de otros individuos. Este sistema se basa en la relación entre la ubicación de los electrodos y la zona subyacente de la corteza cerebral. De esta manera cada región de la supercie del cráneo se identica con una letra que representa al lóbulo subyacente y un número que determina su posición relativa. Los números pares corresponden al hemisferio derecho y los impares al hemisferio izquierdo. Las letras 'F', 'O', 'T' y 'P' corresponden a los lóbulos frontales, occipitales, temporales y parietales respectivamente. También se prevé en la nomenclatura del sistema la letra 'C' que identica a los electrodos situados en el centro del cráneo, la letra 'A' para los puntos utilizados como referencia y 'Z' (cero) como subíndice para indicar las posición media entre dos electrodos.

22

Figura 3.2.: Sistema 10/20. [1]

3.2.2. Conguración y montaje de los electrodos Los electrodos se pueden congurar de manera monopolar, bipolar o laplaciana según se observa en la gura 3.3. [2] Monopolar: se registra el potencial eléctrico de cada electrodo en comparación al electrodo de referencia.

Bipolar (Diferencial): se registra la diferencia de potencial entre dos electrodos.

Laplaciana: se registra la diferencia de potencial entre un electrodo primario y el promedio de varios electrodos secundarios que rodean al primario.

Figura 3.3.: Conguraciones de los electrodos. [2]

23

El montaje de los electrodos determina como se conectan entre sí. Los montajes expuestos a continuación son utilizados para sistemas de canales diferenciales (gura 3.4). [1]

Montaje circular (halo): describe una circunferencia.

Montaje longitudinal (para sagital): sigue una linea anteroposterior en ambos hemisferios cerebrales.

Montaje transversal (tiara media): sigue una linea transversal que recorre ambos hemisferios.

Figura 3.4.: Montaje circular, montaje longitudinal y montaje transversal. [1]

3.3. Parámetros de la señal de electroencefalografía A continuación se detallarán los parámetros básicos en el análisis electroencefalográco.

Frecuencia

24

Es la característica más importante, las señales EEG tienen frecuencias que van desde pocos Hz hasta

100 Hz.

El espectro se divide principal-

mente en 5 bandas que se nombran con las siguientes letras griegas,

θ , α, β , γ ,

δ

,

(ver cuadro 3.1).

delta (δ) theta (θ) alfa (α) beta (β) gamma (γ )

< 4 Hz 4 − 8 Hz 8 − 12 Hz 12 − 32 Hz > 32 Hz

Cuadro 3.1.: Bandas de la señal EEG.[1]

Es importante tener en cuenta que los límites de estos rangos no son precisos y que pueden presentar leves diferencias, según la biografía.

Amplitud Normalmente existe menor amplitud en la región anterior respecto a la zona posterior. Si bien las amplitudes absolutas de las señales carecen de importancia, este parámetro cumple un rol importante cuando se presenta asimetría en las señales que provienen de regiones homólogas de ambos hemisferios.

Simetría En condiciones normales se espera obtener señales similares tanto en frecuencia como en amplitudes que provengan de áreas homologas de ambos hemisferios. En consecuencia existen anomalías de asimetría en frecuencia, asimetría en amplitud o asimetría de amplitud y frecuencia, este último es el caso más común y se observa en la gura 3.5.

25

Figura 3.5.: Se observa en áreas izquierdas una asimetría de mayor amplitud y menor frecuencia constituida por ondas delta a 2 Hz. [1]

Morfología Debido a que no se puede denir la morfología de una señal ya que la forma de las señales puede variar con cada persona, identicaremos a las señales normales como aquellas que presenten características fusiformes, es decir que tengan una forma redondeada, como se muestra en la gura 3.6 A. La gura 3.6 B presenta lo inverso a lo anterior, ondas irregulares, con cambios bruscos, no fusiforme.

Figura 3.6.: Morfología de la señal EEG. [1]

26

3.4. Ritmos cerebrales En ciertas condiciones, el cerebro es capaz de generar determinadas oscilaciones, llamadas ritmos cerebrales. Estos ritmos, pueden ser detectados utilizando cualquier método de electroencefalografía, desde los invasivos a los no invasivos realizados en el cuero cabelludo. Los ritmos cerebrales aparecen en distintas frecuencias, los más importantes son el ritmo alfa (α) y el beta (β ). El primero se encuentra en el rango de 8−12 Hz (mismo rango que la banda alfa), mientras que el segundo en el rango de 12−24 Hz. Por lo general, se cumple que la potencia de los ritmos disminuye al aumentar la frecuencia, debido a que los ritmos de más alta frecuencia, son generados por grupos de neuronas más pequeños. Existen distintos tipos de ritmos cerebrales, estos aparecen o son bloqueados con distintas actividades cerebrales (por ejemplo tareas visuales, motoras, de concentración, etc.). Cada ritmo tiene sus propias características, pero en la mayoría de ellos se observa que los ritmos son generados por grupos de neuronas que se encuentran en reposo, es decir que no están realizando su actividad típica. Dentro de la zona occipital, en la región encargada del procesamiento visual puede observarse un ejemplo de lo mencionado, si estamos con los ojos abiertos la potencia del ritmo alfa es muy pequeña, pero al cerrarlos, esta aumenta signicativamente. La relación entre la potencia alfa con ojos cerrados y con ojos abiertos varía según la persona, sexo y edad e incluso puede variar un poco para una misma persona en cuestión de minutos. A este fenómeno de intensicación del ritmo se le llama sincronización asociada al evento o ERS (por sus siglas en inglés Event Related Synchronization , lo que en español se traduce como evento relacionado a la sincronización), mientras que al fenómeno de la atenuación del ritmo se le llama desincronización asociada al evento o ERD (por sus siglas en inglés Event Related Desynchro-

nization ).

3.4.1. Ritmo Alfa El ritmo alfa fue estudiado desde los comienzos de la electroencefalografía a principios del siglo XX, y su estudio y análisis continúa hasta hoy en día. Siempre es el punto de comienzo para el análisis visual de los estudios de EEG, investigando si el ritmo alfa está presente y si sus características son apropia-

27

das para la edad. Además de proveer pistas acerca el estado de ansiedad o excitación del paciente, la presencia y características del ritmo alfa occipital son determinantes críticos en la evaluación del signicado de otras actividades presentes.

Frecuencia En los adultos, el rango normal de la frecuencia del ritmo occipital alfa, es usualmente de

8 − 12 Hz. A continuación se muestra la distribución de

la frecuencia central del ritmo alfa en un estudio realizado a 200 adultos con edades entre 24 y 35 años (gura 3.7), y la evolución de la misma desde temprana edad, (gura 3.8). [3]

Figura 3.7.: Distribución de la frecuencia del ritmo Alfa.

28

Figura 3.8.: Evolución de la frecuencia del ritmo Alfa.

Amplitud El ritmo alfa se encuentra siempre que las grabaciones son hechas directamente sobre las regiones apropiadas y en individuos no anestesiados. Ciertamente, una gran cantidad de generadores del ritmo alfa existen en la corteza y las profundidades del cerebro, y producen ritmos de alto voltaje. Por otra parte, el voltaje del ritmo alfa obtenido en el cuero cabelludo, generalmente, no es mucho mayor que el nivel de ruido de los amplicadores (ver 7.5). Los estudios han demostrado que entre el 6 y 7 por ciento de los adultos sanos, tienen ritmos alfa por debajo de los

15 µV,

el 75 % entre

15 − 45 µV

y el resto entre

45 − 100 µV.

Regulación Una buena regulación de la frecuencia y el voltaje del ritmo alfa occipital es característica de los electroencefalogramas de aproximadamente el 80 % de los adultos jóvenes. Al aumentar la edad, hay una tendencia de

29

la actividad alfa de volverse menos regulada (alteración en amplitud y frecuencia).

Distribución La región occipital es el sitio de mayor voltaje del ritmo alfa en el 65 % de los adultos y el 95 % de los niños. Sin embargo, es posible que en algunos individuos normales la amplitud de la actividad alfa en la región central y temporal, sea igual o más alta que en la occipital. En el 32 % de los jóvenes adultos normales, la actividad alfa está ampliamente distribuida. Los estudios con electrodos implantados muestran que existen múltiples generadores del ritmo alfa en el cerebro humano, no sólo en la región occipital, sino que también en la región central y temporal. Estos generadores se superponen e inuencian entre sí, por lo tanto lo que es medido en el cuero cabelludo reeja un  promedio de la actividad alfa.

Comportamiento El ritmo Alfa aparece como un ERS al cerrar los ojos y como un ERD luego abrirlos. El comportamiento del ritmo alfa en relación a otros eventos distintos al cierre-apertura de los ojos, es variable. Hans Berger en 1924, descubrió que la amplitud del ritmo alfa de un individuo disminuye o es  bloqueada durante períodos de concentración mental, como la realización de cálculos. Se ha sugerido, pero no completamente demostrado, que en algunos sujetos el ritmo alfa puede ser bloqueado o disminuido en amplitud por la ansiedad.

3.4.2. Ritmo Beta Este ritmo está asociado a la actividad motora y por esta razón se localiza principalmente en la corteza sensomotora (gura 3.1). La frecuencia de este ritmo se extiende desde los

12 Hz

hasta

24 Hzen

la mayoría de la población.

Amplitud

30

Las señales de gran amplitud correspondientes al ritmo beta, están presentes en la corteza cerebral en pacientes no anestesiados. Esta actividad

98 % de los niños 20 µV, en el 70 % es tensiones de 25 µV o más, es

es mayormente atenuada en el cuero cabelludo. En el y adultos normales, la amplitud está por debajo de de

10 µV

o menos. La actividad beta con

generalmente considerada anormal en los electroencefalogramas, aunque la presencia de estos altos voltajes tiene poca utilidad en los diagnósticos, excepto cuando se sospecha la ingestión de drogas por parte del paciente.

Distribución A pesar de que el ritmo Beta se encuentra principalmente en la corteza sensomotora, también es posible encontrarlo con mayor intensidad en la región frontocentral u occipital, aunque este aumento no parece tener importancia alguna.

Comportamiento El ritmo Beta aparece como un ERS al realizar los movimientos y como un ERD luego de estos. Cuando se mueve un extremo izquierdo, se genera el ritmo en el lóbulo parietal derecho y viceversa.

3.5. Artefactos Se dene como artefacto o articio a toda señal eléctrica que aparece en el registro de electroencefalografía y no pertenece a la actividad bioeléctrica del cerebro. Se pueden distinguir dos grupos de articios, por un lado se encuentran los que proviene por culpa de deciencias técnicas como electrodos mal jados, mala calibración del equipo de electroencefalografía, interferencia de corriente alterna (gura 3.9), etc. Este tipo de articios son evitables tomando las precauciones necesarias, la degradación de la señal de EEG sufrida por culpa de este tipo de artefactos vuelve inutilizable el registro.

31

Figura 3.9.: Interferencia por corriente alterna. [1]

El segundo grupo de articios, son los articios siológicos. Estos dependen del sujeto y no pueden ser evitados, tienen como ventaja que al ser de corta duración solo invalidan parte del registro. Es necesario identicarlos ya que de no ser así las conclusiones obtenidas a partir de dicho registro serian incorrectas. Estas señales espurias en su mayoría son producto de la contracción de los músculos frontales, temporales y maseteros. Los electrodos captan las señales eléctricas provenientes de los músculos, que son de orden mayor que los potenciales generados por las neuronas, sumado a que el movimiento de los electrodos, producto de la contracción, modica las impedancias de los mismos registrando señales anómalas. El parpadeo de los ojos también es captado al igual que el movimiento ocular, debido a que el ojo está polarizado constituyendo un dipolo córnea-retina que genera diferencias de potencial que simula señales de baja frecuencia (gura 3.10).

32

Figura 3.10.: Articio por parpadeo. [1]

En ocasiones los electrodos captan los potenciales cardíacos, estos últimos son fácilmente distinguibles por su periodicidad (gura 3.11).

Figura 3.11.: Interferencia por electrocardiograma. [1]

33

3.6. Potenciales cerebrales Los potenciales cerebrales se pueden clasicar en dos grupos, potenciales espontáneos y evocados. En el primer grupo está comprendido por los ritmos cerebrales (ver sección 3.4) y los potenciales relacionados (PR), estos últimos son producto de eventos puntuales como la actividad motora o concentración. Los PR generan una disminución en la amplitud base del ritmo cerebral (nivel de background), a este fenómeno se conoce como ERD, los ERS suceden cuando los PR se extinguen. Un ejemplo de este fenómeno sucede en la ERD y ERS del ritmo alfa occipital al abrir y cerrar los parpados. Este tipo de potenciales son de gran interés para las BCI (ver 9.4.3.1) ya que son controlados por la voluntad del sujeto. Los potenciales evocados (PE) son cambios en la señal bioeléctrica producto de estímulos externos aplicados sobre los órganos sensoriales o nervios periféricos. Debido a que las variaciones, que son producto de estos estímulos, son demasiado pequeñas con respecto al EEG de fondo se utiliza la técnica de promediación. Dicha técnica consiste en aplicar una serie de estímulos consecutivos para posteriormente promediar las señales de EEG obtenidas. Dado que los estímulos mantienen una relación temporal, al aumentar el número de muestras, aumentara la amplitud del PE, por otro lado como el ritmo de fondo del EEG no mantiene ningún relación temporal, tenderá a desaparecer de la señal promedio. Los potenciales evocados son muy utilizados por los neurólogos ya que brindan información patológica del cerebro. No son utilizados para el uso de BCI (ver 9.4.3.1) dado que dichas señales no son controladas por el sujeto y el análisis de estos eventos no se pueden realizar en tiempo real.

34

4. Electrodos: sensores de potencial bioeléctrico

4.1. Responsabilidades Los electrodos son el primer eslabón de la cadena de medida. Tienen la misión de integrar en el circuito a una persona, con el n de poder medir los potenciales bioeléctricos generados por las neuronas. Siempre serán posicionados sobre el cuero cabelludo, de forma de obtener un buen contacto con la piel. En base a estos requisitos, se realizó una investigación inicial de los tipos de electrodos disponibles. En este capítulo se describen los electrodos utilizados para el proyecto y las distintas modicaciones realizadas sobre este componente hasta la actualidad.

4.2. Desarrollo Uno de los puntos más importantes en la medición de señales de EEG, es que la señal de entrada es del orden de los microvoltios. Para distinguir las señales EEG de otras señales, normalmente se utilizan amplicadores de instrumentación, que permiten tomar 2 señales y rechazan la parte de la señal que es común en ambas entradas como se muestra en la gura 4.1.

35

Figura 4.1.: Esquema de un electrodo pasivo o convencional.

El caso ideal sería cuando el amplicador rechaza todo el ruido, dejando limpia la señal de EEG. El punto que se analizó en este caso, fue la inuencia de la impedancia pielelectrodo para la medición de la señal. Esta impedancia se encuentra en serie con la impedancia de entrada del amplicador de instrumentación, es decir que cuanto mayor sea dicha impedancia, menor es la señal que llega al amplicador, esto signica que como primer premisa se debe obtener una impedancia piel-electrodo pequeña. Por otra parte, las impedancias vistas por ambas señales deben ser iguales, para que el ruido que llegue al amplicador sea de igual magnitud, de lo contrario, las señales ruidosas de entrada del amplicador tendrán diferentes amplitudes y no se rechazará todo el ruido común. La segunda premisa entonces, será obtener impedancias iguales, para lo cual generalmente se utiliza un gel conductor. Con el objetivo de lograr mejorar el proyecto en estos dos aspectos se comenzó a investigar y trabajar sobre electrodos del tipo activos, que fundamentalmente incorporan un amplicador operacional, en la modalidad de seguidor de tensión, montado físicamente sobre el electrodo, como se muestra en la gura 4.2.

36

Figura 4.2.: Esquema de un electrodo activo.

Cuando se coloca el amplicador operacional cercano a la zona de medición, la alta impedancia de entrada y baja impedancia de salida del mismo, actúa directamente sobre las premisas planteadas. Cuanto mayor es la impedancia de entrada del amplicador operacional, menor peso tiene la impedancia pielelectrodo, es decir, sigue siendo un factor importante, pero no como en el caso de los electrodos pasivos. Por otra parte las impedancias de salida son bajas e iguales, lo cual contribuye a que llegue el mismo nivel de señal a la etapa de amplicación. [4] Para el proyecto en particular, es válido decir que el tipo de electrodos utilizados fue evolucionando a medida que se deseaba mejorar la calidad de la señal obtenida y la versatilidad del dispositivo. Al comenzar el proyecto, se decidió utilizar electrodos pasivos de plata clorada (AgCl). Una ventaja de este tipo de electrodos es que son de uso común en los hospitales, para estudios de electrocardiograma (señales del orden de 1000 veces mayores) y por lo tanto no es difícil conseguirlos. Su precio es accesible para público en general, su diseño hace que se adapte perfectamente en cualquier parte del cráneo y fundamentalmente no era necesario ningún tipo de acondicionamiento para poder incluirlo en el prototipo. Como grandes desventajas se encontró que estos electrodos no son re-utilizables, es decir, se necesitaba una gran cantidad de ellos para poder realizar todas las pruebas necesarias durante el proyecto. No se pueden utilizar en supercies con pelo, lo cual limitaba mucho la zonas de estudio disponibles y los sujetos de prueba.

37

Finalmente, la relación señal-ruido que ofrecen es la más baja, con respecto a otro tipo de modelos. El siguiente paso fue la implementación de electrodos activos, básicamente un seguidor de tensión, que aumenta la impedancia del sistema de amplicación con respecto a la impedancia piel-electrodo, como ya se explicó anteriormente. La principal desventaja que presentaron al inicio, era que requerían de un estudio previo para la construcción y tiempo de implementación en cuanto al diseño de las placas, compra de componentes y construcción. Luego, este tipo de electrodos resultó ser muy superior a los anteriores por varias razones. El tipo de construcción permitía utilizarlo aún en zonas con pelo, son re-utilizables y no requieren de ningún gel conductor para su utilización.

4.3. Implementación nal 4.3.1. Material utilizado para la construcción Debido a que el material estará en contacto directo con la piel se deben tomar algunas consideraciones. La piel es un tejido conductivo cuyo material intracelular y extracelular está compuesto de soluciones electrolíticas, en la cual la corriente es transportada por iones, por otro lado, los electrodos están compuestos principalmente por una supercie de metal, altamente conductivo, en el cual la corriente es transportada por electrones, es decir, el electrodo debe convertir las corrientes iónicas, que son el mecanismo de conducción de las señales bioeléctricas en los tejidos, en corrientes eléctricas, en consecuencia, esto genera que la interfaz piel-electrodo, sea una interfaz ruidosa. [5] Cuando se habla de materiales más utilizados para la construcción de electrodos de supercie, se trata de oro, plata, acero inoxidable, platino entre otros. El desafío consiste en lograr que la impedancia de contacto piel-electrodo se mantenga constante en el tiempo o lo más constante posible. Sobre este aspecto, basados en un estudio realizado por A.Searle y L.Kirkup sobre la impedancia de contacto piel-electrodo, para distintos materiales de electrodos, el material seleccionado para los electrodos del proyecto, tanto para los activos como para el electrodo de referencia, fue plata (Ag). La gráca de la gura 4.3 muestra los resultados obtenidos por A.Searle y L.Kirkup [6] de la impedancia con respecto al tiempo (La gráca muestra un

38

promedio de datos tomados sobre 5 sujetos de prueba). [6]

Figura 4.3.: Impedancia del contacto piel-electrodo en el tiempo para distintos materiales de construcción.

Como se observa, la respuesta más constante se obtiene para el caso de electrodos Ag/AgCl. Otro de los aspectos importantes al seleccionar el material, es la característica de polarización de los mismos. Esto signica que la carga eléctrica puede acumularse en la supercie del material generando un voltaje de continua que puede rondar los

200 mV,

lo cual es de magnitud mucho mayor a lo que se

desea medir. Es necesario entonces un material cuyo potencial no varíe considerablemente, cuando la corriente pasa a través de él. En este sentido, los electrodos de Ag/AgCl cumplen las características deseadas. [4] Para la construcción de los electrodos de este proyecto se utilizó como material de contacto con la piel, alambre de plata para los electrodos del lóbulo occipital y una placa de plata para el electrodo frontal y para el electrodo de referencia.

4.3.2. Diseño El diseño del circuito de los electrodos se baso en el prototipo Jarek Foltynsky, con las modicaciones sugeridas por Joerg Hansmann. [7]

39

La elección de este diseño de electrodos activos en vez de otros disponibles [[8]], se debió a que el mismo era respaldado en otros proyectos, a su vez la guía de construcción era la más completa, con detalle de las pruebas realizadas, sumado a un circuito preciso, prolijo, y con la posibilidad de adquirir todos sus materiales sin mayores dicultades. En las guras 4.4 y 4.5 se muestra el circuito de los electrodos activos y el diseño BRD

1

de los mismos, respectivamente.

Figura 4.4.: Circuito de electrodo activo.

1 BRD,

archivo del programa EAGLE Circuit Board File.

40

Figura 4.5.: Diseño del circuito de los electrodos activos.

4.3.3. Técnica de medida La técnica más común para la adquisición de biopotenciales utiliza tres electrodos. Mediante dos de ellos se captura la señal bioeléctrica en modo diferencial y el electrodo restante opera como electrodo de masa o electrodo de referencia. Dicha técnica es la utilizada en este proyecto para la medición.

4.3.4. Electrodo de referencia Estos electrodos miden con respecto a un electrodo de referencia, también conocido como electrodo DRL (driven right leg). El funcionamiento en detalle del mismo, se explicará más adelante (ver subsección 7.4.6). En lo que reere a la construcción, el electrodo de referencia de este proyecto, consiste de una placa de plata.

4.3.5. Montaje y posicionamiento Como ya se mencionó anteriormente, para obtener una buena señal es fundamental, tener un buen contacto entre el electrodo y la piel. Es necesario que la presión que ejerce el electrodo sea uniforme, que tenga la menor movilidad posible, evitando así las interferencias por movimiento. También se consideró importante a la hora de diseñar el prototipo, que la posición pueda ser ajustable previendo de este modo, que sea adaptable al sujeto de prueba y poder medir potenciales en distintos puntos de interés.

41

Es válido mencionar que para los electrodos pasivos, no fue necesario ningún hardware, ya que los mismos vienen con un autoadhesivo muy práctico. Una vez que se comenzó a trabajar con electrodos activos, los mismos fueron dispuestos sobre una banda elástica, como se muestra en la gura 4.6. Esto nos permitió comenzar a trabar y realizar las primeras pruebas del prototipo.

Figura 4.6.: Electrodos montados sobre banda elástica.

Este diseño tenía como ventaja que los electrodos eran móviles, deslizándose a través del elástico, pero introdujo algunos problemas ya que la presión que otorgaba la vincha no se traducía en un buen contacto electrodo-piel, lo que generaba una importante inestabilidad en la medida. Esto trajo como consecuencia, una pequeña modicación en la disposición de los componentes de estos electrodos, se decidió pasar la parte de contacto hacia el centro, de modo de poder ejercer una presión más uniforme. En la gura 4.7, se muestra el BRD, de dichos electrodos. Otra de las desventajas de este modelo, se encuentra en el electrodo DRL, el mismo debía ser sostenido por el usuario, haciendo presión con el dedo pulgar, lo que afectaba la concentración y generaba artefactos provocados por los músculos.

42

Figura 4.7.: Electrodos activos con la parte de contacto en el centro.

Finalmente, en el diseño denitivo, los electrodos construidos (ambos modelos) fueron montados sobre el arnés de un casco de protección (gura 4.8) para poder ajustarse alrededor de la cabeza. Los electrodos que van sobre el lóbulo occipital, son los diseñados en primera instancia, mientras que el electrodo frontal es el diseñado en segunda instancia. En este último, la zona de contacto, se cambio por una placa de plata. Además se agrega en el casco, el electrodo DRL, próximo al electrodo frontal, de forma tal que el usuario se despreocupa del mismo.

Figura 4.8.: Foto del diseño nal de la vincha.

43

5. Interferencia

5.1. Introducción Una de las dicultades que se presentan en la adquisición de señales biopo-

1

tenciales son las interferencias electromagnéticas (EMI) generadas por fuentes externas y en particular por la red de distribución eléctrica. Esto se debe a que las señales de EEG son muy susceptibles a ser afectadas por diferentes tipos de señales eléctricas tanto internas al circuito, como externas. Se denomina interferencia a las señales de origen externo que podrán generar un error en la señal adquirida. Las interferencias son un fenómeno físico que ocurre cuando dos o más ondas se superponen para formar una onda resultante de mayor o menor amplitud que las anteriores [9]. En este caso dicho fenómeno ocurre con ondas de tensión. Estas ondas ingresan al sistema de medida de distintas formas y se utilizan varios métodos y técnicas que permiten la reducción o eliminación de las mismas. Para eliminar el efecto de las fuentes de error es necesario entender de donde provienen y de que manera afectan la señal que se desea medir.

5.2. Fuentes de interferencia En esta sección se describen algunas fuentes de interferencia, luego, en la gura 5.1 se muestra un modelo reducido de como se ven afectadas las señales por las interferencias. [10] 1. Capacidad parásita que se forma entre la red de distribución y los cables de medida y electrodos. 2. Capacidad parásita que se forma entre la red de distribución y el paciente.

1 EMI

por su sigla en inglés, ElectroMagnetic Interference

44

3. Interferencia generada por campos magnéticos, como los cables de adquisición y el usuario forman un circuito de lazo cerrado, si la supercie de dicho lazo es atravesada por un campo magnético variable se generan corrientes parásitas que distorsionan la señal medida. 4. Potencial en el contacto: diferencia de potencial entre los electrodos y el paciente que varía con el movimiento del electrodo. 5. Potencial bioeléctrico: interferencia generada por los músculos, como consecuencia del movimiento del paciente.

Figura 5.1.: Capacidades parásitas que producen interferencia. [13]

En esta imagen, Z1, Z2 y Zg corresponden a las impedancias de los electrodos. La capacidad parásita que se forma entre la red de distribución y los cables que se utilizan para la medición está representada por los capacitores C1 y C2, mientras que la capacidad que se forma entre la red de distribución y la etapa de amplicación se representa mediante C3. La capacidad parásita que se forma entre la red de distribución y el paciente se representa como el capacitor Cb. Zi representa la impedancia de entrada a la etapa de amplicación. Los valores estimados por distintos autores para estos elementos, son los siguientes:

45

Cb: Capacidad Línea-Paciente. (0,2 pF − 5 pF) (Pallas Areny, 1991 [11]). C1, C2: Capacidad Línea-Cable. (≈

0,1 pF/m)

(Grimbergen, 1991 [11]).

Z1, Z2: Impedancia de contacto del electrodo i. (1 kΩ

− 1 MΩ)

(Rosell,

1988 [11]). Zi: Impedancia de entrada de modo común.

Vcm :

Tensión de Modo Común. Es un parámetro de gran importancia,

representa la diferencia de potencial entre el usuario y la masa del circuito. Si bien el usuario no tiene un único potencial y se denen varios nodos sobre él, lo que se hace usualmente es considerar al mismo como isopotencial, basados en que las impedancias de internas son pequeñas en comparación con las demás impedancias, y dicho potencial se dene la sobre la impedancia del tercer electrodo.

5.3. Soluciones para minimizar los efectos Es importante tener en cuenta la importancia de minimizar las interferencias desde la captura de la señal, para evitar la propagación de la misma por las distintas etapas, ya que si bien existen varias opciones de procesamiento digital de señales, para eliminar la interferencia de la red luego de la captura, resulta difícil hacerlo sin deteriorar la señal, en particular la fase, y más difícil aún efectuar estos procesamientos en tiempo real. La principal causa de interferencia es generada por la red de distribución eléctrica. Esta interferencia afecta la señal a través de la tensión

Vcm ,

funda-

mentalmente a través de 2 mecanismos. En primer lugar porque la Relación

2

de Rechazo al Modo Común (CMRR)

del amplicador es un parámetro nito

y en segundo lugar esta interferencia puede pasar de modo común a modo diferencial debido a las diferencias en las impedancias. El primer modo es fácilmente reducible mediante los amplicadores de instrumentación como se verá más adelante en la subsección 7.4.3. El circuito de adquisición y amplicación debe tener un CMRR elevado, que permita eliminar el efecto de dichas señales, lo que lo vuelve un parámetro de diseño crítico

2 CMRR representa la habilidad del amplicador para rechazar las tensiones de modo común

presentes en las entradas.

46

para el circuito y determina entre otros elementos la elección de los operacionales a utilizar. El segundo mecanismo requiere que la impedancia de entrada de modo común tenga un valor muy elevado. Una solución muy utilizada cuando se utilizan sistemas de medición de 3 electrodos es la utilización de circuitos activos, que a partir de una realimentación negativa de

Vcm ,

permiten una disminución

importante de la misma. En la subsección 7.4.6 se explicará en detalle el funcionamiento de este circuito. Otros métodos que fueron utilizados en este proyecto para minimizar el efecto de la interferencia se enumeran a continuación. 1. Utilización de cables mallado para la transmisión de la señal analógica, conectando la malla del cable a VGND. Esto permite evitar la formación de capacidades parásitas entre la pantalla y el cable y además, de esta forma, se provee un camino de baja impedancia a las corrientes que circulan por C1 y C2, evitando que circulen a través de las impedancias de los electrodos, lo cual de otro modo, produciría una tensión de modo diferencial considerable, dependiendo de las diferencias entre las impedancias de los electrodos. También se redujo, dentro de lo posible, la longitud de los cables de los electrodos, de forma de disminuir las capacidades C1 y C2. 2. La etapa de amplicación fue diseñada de forma tal que tuviese baja ganancia a señales en modo común, respecto de la ganancia a señales diferenciales. 3. En esta aplicación, no se tomó en cuenta la disminución del área de ujo del campo magnético ya que los electrodos se posicionan muy próximos unos de otros, lo que hace que las áreas expuestas sean reducidas y la interferencia producida por fem inducida en el lazo de conexión no genere distorsiones importantes. Cuando se trata de este tipo de interferencia resulta efectivo un blindaje magnético de toda el área involucrada, pero no es una solución aplicable para equipos portátiles. 4. Mantener los electrodos lo más limpios posibles. 5. El usuario se debe de mantener lo más quieto posible.

47

6. El equipo se alimenta mediante baterías (o pilas), esto hace que la impedancia de aislación sea grande, disminuyendo las interferencias electromagnéticas.

48

6. Proyecto OpenEEG En un principio se pretendía realizar un diseño propio del hardware necesario para la obtención de datos, luego de asesoramiento sobre el tema con una empresa que trabajó con equipos similares, se repensó esta idea debido a que la construcción del hardware tomaría un tiempo cercano a un año, que era el tiempo que se contaba para el desarrollo de este proyecto. En particular se recomendó la utilización del proyecto openEEG [12]. Gran parte del hardware fue diseñado en base al proyecto openEEG , el cual fue creado con el objetivo de poder construir electroencefalógrafos de bajo costo para la adquisición de señales cerebrales, con nes de aplicarlo en entrenamiento con EEG biofeedback, o en interfaces cerebro-computadora (ver 9.4.3.1) o simplemente para observar la actividad cerebral. Este proyecto consta de todas las partes necesarias en el proceso de la adquisición de señales cerebrales, desde el hardware utilizado para la medición de las señales hasta el software para la visualización de las mismas en la computadora. Se realizaron diversos cambios respecto al diseño original con distintos nes: para reducir los costos aumentar la seguridad y comodidad para el usuario facilitar la construcción y aumentar la calidad de la señal medida. Los cambios realizados, se explicaran en detalle en los capitulos 7 y 8.

49

7. Placa Amplicadora

7.1. Descripción La placa amplicadora cumple la función de recibir la señal capturada por los electrodos en el cuero cabelludo (señal del orden de los

µV),

amplicarla

en una excursión que va desde 0 a 5 V (la referencia de la señal es VGND = 2,5 VVGND

= 2,5V)

y posteriormente ltrarla para luego ser enviada al

microcontrolador con el objetivo de ser digitalizada.

1

También cuenta con una etapa llamada  circuito de pierna derecha (DRL) , la cual cumple la función de disminuir el ruido de modo común. En la gura 7.1 se muestra el diagrama de bloques simplicado para un solo canal.

Figura 7.1.: Esquema de la placa de amplicación.

1 DRL

por sus siglas en ingles (driven right leg)

50

7.2. Diseño El diseño fue realizado en base al proyecto OpenEEG como se explicó anteriormente. Previo a la construcción, se estudió cada etapa para vericar su correcto funcionamiento teórico. Con este modelo de placa, cada una de ellas es capaz de capturar dos canales, por lo tanto, se construyeron dos placas para lograr la adquisición de cuatro canales. La primera placa fue realizada íntegramente por el grupo de trabajo, con componentes disponibles en plaza (excepto los amplicadores operacionales). Las dos placas nales, son de doble faz y fueron montadas con componentes traídos desde EEUU. Es posible también variar la ganancia de cada placa por separado en función de la resistencia de un potenciómetro variable.

7.3. Alimentación del circuito La alimentación del circuito es un tema de vital importancia, esta debe ser muy estable para obtener una señal constante y de buena calidad. Se utiliza una alimentación con fuente simple o única, es decir que se tiene sólo tensión positiva, en este caso de

0

a

5V

.

La placa digital diseñada por el proyecto openEEG contaba con toda la etapa de alimentación, además el diseño incluye el microcontrolador ATMEL AT90S4433P utilizado. Esta placa fue sustituida por una placa Arduino, con un microcontrolador ATMEL ATMEGA2560, con el objetivo de simplicar su construcción, reducir los costos y mejorar la calidad de la señal. La placa original utilizaba alimentación de la red eléctrica, la que luego se transformaba en corriente continua. Este aspecto fue modicado para el proyecto y se utiliza alimentación mediante baterías. Este cambio trae considerables ventajas al proyecto. En primer lugar, esta mejora aumenta signicativamente la seguridad del usuario evitando el contacto con la red eléctrica (mediante componentes). Cabe señalar que openEEG aísla eléctricamente al usuario, pero es aún más seguro utilizar baterías. Además de brindar una mayor protección,

51

al aislar el prototipo se protege al equipo de posibles irregularidades en la red y, como ya se mencionó anteriormente, se aumenta el rechazo a las EMI`s. Otra gran ventaja de utilizar baterías se debe a que no hay necesidad de utilizar transformadores o fuentes conmutadas, se eliminan los condensadores y bobinas necesarios para el pasaje de alterna a continua, de manera que se evita el ruido producido por los mismos y se reduce en gran medida el hardware necesario, lo que conlleva también a una reducción en el costo. En aplicaciones tan delicadas como lo es la obtención de señales cerebrales es muy importante intentar de eliminar todas las posibles fuentes de interferencia. Por último, el uso de baterías permite la movilidad del prototipo, cumpliendo así con uno de los objetivos propuestos en el proyecto. La desventaja que se presenta en el uso de baterías, radica en que las mismas se agotan, aunque considerando el poco consumo del prototipo, las baterías pueden mantenerse cargadas durante días. Además, para mitigar el gasto generado por el recambio de las mismas, se decidió utilizar baterías recargables. Se midio el consumo del sistema total, resultando en un valor promedio de

71 mA. A partir de este valor y conciderando que las baterías utilizadas tienen un poder de 900 mAh, se logra un tiempo de uso continuo teórico de 12,7 horas aproximadamente. Para obtener los

5V

estables para alimentar la placa amplicadora y el mi-

crocontrolador, se utilizó un integrado LM7805 (ver desc="Generated Code"> private void initComponents() { ventanaConfiguracion = new javax.swing.JDialog(); jPanel2 = new javax.swing.JPanel(); tiempoReal = new javax.swing.JRadioButton(); tiempoSimulado = new javax.swing.JRadioButton(); panelSerial = new javax.swing.JPanel(); Puertos = new javax.swing.JComboBox(); botonBuscar = new javax.swing.JButton(); botonConectar = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); baudRates = new javax.swing.JComboBox(); CantidadCanales = new javax.swing.JComboBox(); jLabel3 = new javax.swing.JLabel();

grupoTiempo = new javax.swing.ButtonGroup(); ventanaElegirArchivo = new javax.swing.JDialog(); elegirArchivo = new javax.swing.JFileChooser(); ventanaPruebaBCI = new javax.swing.JDialog(); jPanel1 = new javax.swing.JPanel(); BCI1 = new javax.swing.JPanel(); botonAlfaON1 = new javax.swing.JButton(); botonAlfaOFF1 = new javax.swing.JToggleButton(); botonDosParpadeos1 = new javax.swing.JButton(); botonTresParpadeos1 = new javax.swing.JToggleButton(); jPanel3 = new javax.swing.JPanel(); botonAlfaON2 = new javax.swing.JButton(); botonAlfaOFF2 = new javax.swing.JToggleButton(); botonDosParpadeos2 = new javax.swing.JButton(); botonTresParpadeos2 = new javax.swing.JToggleButton(); jPanel4 = new javax.swing.JPanel(); botonAlfaON4 = new javax.swing.JButton(); botonAlfaOFF4 = new javax.swing.JToggleButton(); botonDosParpadeos4 = new javax.swing.JButton(); botonTresParpadeos4 = new javax.swing.JToggleButton(); BCI2 = new javax.swing.JPanel(); botonAlfaON3 = new javax.swing.JButton(); botonAlfaOFF3 = new javax.swing.JToggleButton(); botonDosParpadeos3 = new javax.swing.JButton(); botonTresParpadeos3 = new javax.swing.JToggleButton(); panelFondo = new javax.swing.JPanel(); texto = new javax.swing.JLabel(); jToolBar1 = new javax.swing.JToolBar(); botonEnviar = new javax.swing.JButton(); botonIniciar = new javax.swing.JButton(); stop = new javax.swing.JButton(); jSeparator1 = new javax.swing.JToolBar.Separator(); scroll = new javax.swing.JScrollBar(); panelEscritorio = new javax.swing.JDesktopPane(); Fondo = new javax.swing.JLabel(); panel2 = new javax.swing.JPanel(); texto1 = new javax.swing.JLabel(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); menuAbrrir = new javax.swing.JMenuItem(); menuAceptarCliente = new javax.swing.JMenuItem(); menuConfiguracion = new javax.swing.JMenu(); menuConfiguacion = new javax.swing.JMenuItem(); menuElectrodos = new javax.swing.JMenuItem();

ventanaConfiguracion.setTitle("Configuración"); ventanaConfiguracion.setModal(true); ventanaConfiguracion.setName("ventanaConfiguracion"); // NOI18N ventanaConfiguracion.setResizable(false);

jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Tiempo")); grupoTiempo.add(tiempoReal); tiempoReal.setSelected(true); tiempoReal.setText("Real"); grupoTiempo.add(tiempoSimulado); tiempoSimulado.setText("Simulado"); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(16, 16, 16) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.LEADING) .addComponent(tiempoSimulado) .addComponent(tiempoReal, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(37, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(tiempoReal) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATE D)

.addComponent(tiempoSimulado) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) );

panelSerial.setBorder(javax.swing.BorderFactory.createTitledBorder("Configura ción Serial")); Puertos.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { PuertosActionPerformed(evt); } }); botonBuscar.setText("Buscar"); botonBuscar.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); botonBuscar.setOpaque(false); botonBuscar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonBuscarActionPerformed(evt); } }); botonConectar.setText("Conectar"); botonConectar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonConectarActionPerformed(evt); } }); jLabel1.setText("Puertos"); jLabel2.setText("Baud Rates"); baudRates.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "9600", "230400", "500000" })); javax.swing.GroupLayout panelSerialLayout = new javax.swing.GroupLayout(panelSerial); panelSerial.setLayout(panelSerialLayout); panelSerialLayout.setHorizontalGroup(

panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LE ADING) .addGroup(panelSerialLayout.createSequentialGroup() .addGap(18, 18, 18) .addGroup(panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Ali gnment.LEADING) .addGroup(panelSerialLayout.createSequentialGroup() .addGroup(panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Ali gnment.LEADING, false) .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(26, 26, 26) .addGroup(panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Ali gnment.LEADING, false) .addComponent(Puertos, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(baudRates, 0, 83, Short.MAX_VALUE))) .addGroup(panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Ali gnment.TRAILING, false) .addComponent(botonConectar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 91, Short.MAX_VALUE) .addComponent(botonBuscar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap(59, Short.MAX_VALUE)) ); panelSerialLayout.setVerticalGroup( panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LE ADING) .addGroup(panelSerialLayout.createSequentialGroup() .addContainerGap()

.addGroup(panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Ali gnment.BASELINE) .addComponent(jLabel1) .addComponent(Puertos, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(11, 11, 11) .addGroup(panelSerialLayout.createParallelGroup(javax.swing.GroupLayout.Ali gnment.BASELINE) .addComponent(jLabel2) .addComponent(baudRates, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(botonBuscar, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATE D) .addComponent(botonConectar) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); CantidadCanales.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "3", "4" })); CantidadCanales.setName("CantidadCanales"); // NOI18N CantidadCanales.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { CantidadCanalesActionPerformed(evt); } }); jLabel3.setText("Cantidad de canales"); javax.swing.GroupLayout ventanaConfiguracionLayout = new javax.swing.GroupLayout(ventanaConfiguracion.getContentPane());

ventanaConfiguracion.getContentPane().setLayout(ventanaConfiguracionLayou t); ventanaConfiguracionLayout.setHorizontalGroup( ventanaConfiguracionLayout.createParallelGroup(javax.swing.GroupLayout.Alig nment.LEADING) .addGroup(ventanaConfiguracionLayout.createSequentialGroup() .addContainerGap() .addGroup(ventanaConfiguracionLayout.createParallelGroup(javax.swing.Grou pLayout.Alignment.LEADING) .addComponent(panelSerial, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(ventanaConfiguracionLayout.createSequentialGroup() .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(CantidadCanales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(102, Short.MAX_VALUE)) ); ventanaConfiguracionLayout.setVerticalGroup( ventanaConfiguracionLayout.createParallelGroup(javax.swing.GroupLayout.Alig nment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ventanaConfiguracionLayout.createSequentialGroup() .addContainerGap() .addComponent(panelSerial, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addGroup(ventanaConfiguracionLayout.createParallelGroup(javax.swing.Grou pLayout.Alignment.LEADING) .addGroup(ventanaConfiguracionLayout.createSequentialGroup() .addGap(18, 18, 18) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(ventanaConfiguracionLayout.createSequentialGroup() .addGap(27, 27, 27) .addGroup(ventanaConfiguracionLayout.createParallelGroup(javax.swing.Grou pLayout.Alignment.BASELINE) .addComponent(CantidadCanales, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3)))) .addContainerGap(70, Short.MAX_VALUE)) ); elegirArchivo.setMinimumSize(new java.awt.Dimension(500, 500)); elegirArchivo.setPreferredSize(new java.awt.Dimension(680, 500)); elegirArchivo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { elegirArchivoActionPerformed(evt); } }); javax.swing.GroupLayout ventanaElegirArchivoLayout = new javax.swing.GroupLayout(ventanaElegirArchivo.getContentPane()); ventanaElegirArchivo.getContentPane().setLayout(ventanaElegirArchivoLayout) ; ventanaElegirArchivoLayout.setHorizontalGroup( ventanaElegirArchivoLayout.createParallelGroup(javax.swing.GroupLayout.Alig nment.LEADING) .addGroup(ventanaElegirArchivoLayout.createSequentialGroup() .addComponent(elegirArchivo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addContainerGap(24, Short.MAX_VALUE)) ); ventanaElegirArchivoLayout.setVerticalGroup( ventanaElegirArchivoLayout.createParallelGroup(javax.swing.GroupLayout.Alig nment.LEADING) .addGroup(ventanaElegirArchivoLayout.createSequentialGroup() .addComponent(elegirArchivo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 34, Short.MAX_VALUE)) ); ventanaPruebaBCI.setTitle("Ventana manejo Robot"); BCI1.setBorder(javax.swing.BorderFactory.createTitledBorder("BCI 1")); BCI1.setToolTipText("BCI 1"); botonAlfaON1.setText("AlfaON"); botonAlfaON1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaON1ActionPerformed(evt); } }); botonAlfaOFF1.setText("AlfaOFF"); botonAlfaOFF1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaOFF1ActionPerformed(evt); } }); botonDosParpadeos1.setText("2 parpadeos"); botonDosParpadeos1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonDosParpadeos1ActionPerformed(evt); } }); botonTresParpadeos1.setText("3 parpadeos"); botonTresParpadeos1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) { botonTresParpadeos1ActionPerformed(evt); } }); javax.swing.GroupLayout BCI1Layout = new javax.swing.GroupLayout(BCI1); BCI1.setLayout(BCI1Layout); BCI1Layout.setHorizontalGroup( BCI1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING ) .addGroup(BCI1Layout.createSequentialGroup() .addContainerGap() .addGroup(BCI1Layout.createParallelGroup(javax.swing.GroupLayout.Alignme nt.LEADING) .addComponent(botonTresParpadeos1, javax.swing.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE) .addComponent(botonDosParpadeos1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaON1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaOFF1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); BCI1Layout.setVerticalGroup( BCI1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING ) .addGroup(BCI1Layout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaON1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonAlfaOFF1)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonDosParpadeos1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonTresParpadeos1)) ); jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("BCI 2")); botonAlfaON2.setText("AlfaON"); botonAlfaON2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaON2ActionPerformed(evt); } }); botonAlfaOFF2.setText("AlfaOFF"); botonAlfaOFF2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaOFF2ActionPerformed(evt); } }); botonDosParpadeos2.setText("2 parpadeos"); botonDosParpadeos2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonDosParpadeos2ActionPerformed(evt); } }); botonTresParpadeos2.setText("3 parpadeos"); botonTresParpadeos2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonTresParpadeos2ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup(

jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.TRAILING) .addComponent(botonTresParpadeos2, javax.swing.GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE) .addComponent(botonDosParpadeos2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaOFF2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaON2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addComponent(botonAlfaON2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaOFF2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonDosParpadeos2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonTresParpadeos2) .addContainerGap()) );

jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("BCI 4")); botonAlfaON4.setText("AlfaON"); botonAlfaON4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaON4ActionPerformed(evt); } }); botonAlfaOFF4.setText("AlfaOFF"); botonAlfaOFF4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaOFF4ActionPerformed(evt); } }); botonDosParpadeos4.setText("2 parpadeos"); botonDosParpadeos4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonDosParpadeos4ActionPerformed(evt); } }); botonTresParpadeos4.setText("3 parpadeos"); botonTresParpadeos4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonTresParpadeos4ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() .addContainerGap()

.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.TRAILING) .addComponent(botonTresParpadeos4, javax.swing.GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE) .addComponent(botonDosParpadeos4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaOFF4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaON4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaON4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonAlfaOFF4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonDosParpadeos4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonTresParpadeos4)) ); BCI2.setBorder(javax.swing.BorderFactory.createTitledBorder("BCI 3")); BCI2.setToolTipText("BCI 1"); botonAlfaON3.setText("AlfaON"); botonAlfaON3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaON3ActionPerformed(evt);

} }); botonAlfaOFF3.setText("AlfaOFF"); botonAlfaOFF3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonAlfaOFF3ActionPerformed(evt); } }); botonDosParpadeos3.setText("2 parpadeos"); botonDosParpadeos3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonDosParpadeos3ActionPerformed(evt); } }); botonTresParpadeos3.setText("3 parpadeos"); botonTresParpadeos3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonTresParpadeos3ActionPerformed(evt); } }); javax.swing.GroupLayout BCI2Layout = new javax.swing.GroupLayout(BCI2); BCI2.setLayout(BCI2Layout); BCI2Layout.setHorizontalGroup( BCI2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING ) .addGroup(BCI2Layout.createSequentialGroup() .addContainerGap() .addGroup(BCI2Layout.createParallelGroup(javax.swing.GroupLayout.Alignme nt.LEADING) .addComponent(botonTresParpadeos3, javax.swing.GroupLayout.DEFAULT_SIZE, 103, Short.MAX_VALUE) .addComponent(botonDosParpadeos3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

.addComponent(botonAlfaON3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaOFF3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); BCI2Layout.setVerticalGroup( BCI2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING ) .addGroup(BCI2Layout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(botonAlfaON3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonAlfaOFF3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonDosParpadeos3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(botonTresParpadeos3)) ); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(20, 20, 20) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.TRAILING) .addComponent(BCI2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(BCI1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.LEADING) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(20, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(34, 34, 34) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.LEADING, false) .addComponent(BCI1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) .addGap(29, 29, 29) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Align ment.LEADING) .addComponent(BCI2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(38, Short.MAX_VALUE))

); BCI1.getAccessibleContext().setAccessibleDescription("B"); javax.swing.GroupLayout ventanaPruebaBCILayout = new javax.swing.GroupLayout(ventanaPruebaBCI.getContentPane()); ventanaPruebaBCI.getContentPane().setLayout(ventanaPruebaBCILayout); ventanaPruebaBCILayout.setHorizontalGroup( ventanaPruebaBCILayout.createParallelGroup(javax.swing.GroupLayout.Align ment.LEADING) .addGroup(ventanaPruebaBCILayout.createSequentialGroup() .addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(51, Short.MAX_VALUE)) ); ventanaPruebaBCILayout.setVerticalGroup( ventanaPruebaBCILayout.createParallelGroup(javax.swing.GroupLayout.Align ment.LEADING) .addGroup(ventanaPruebaBCILayout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 16, Short.MAX_VALUE)) );

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("EEG Project"); setIconImage(getIconImage()); setName("ventanaPrincipal"); // NOI18N panelFondo.setBackground(new java.awt.Color(0, 0, 0)); texto.setForeground(new java.awt.Color(0, 204, 204)); jToolBar1.setBackground(new java.awt.Color(0, 0, 0)); jToolBar1.setFloatable(false);

jToolBar1.setForeground(new java.awt.Color(102, 102, 102)); jToolBar1.setRollover(true); botonEnviar.setForeground(new java.awt.Color(255, 255, 255)); botonEnviar.setText("Capturar"); botonEnviar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonEnviarActionPerformed(evt); } }); jToolBar1.add(botonEnviar); botonIniciar.setForeground(new java.awt.Color(255, 255, 255)); botonIniciar.setText("Play"); botonIniciar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { botonIniciarActionPerformed(evt); } }); jToolBar1.add(botonIniciar); stop.setForeground(new java.awt.Color(255, 255, 255)); stop.setText("Stop"); stop.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { stopActionPerformed(evt); } }); jToolBar1.add(stop); jToolBar1.add(jSeparator1); scroll.setBackground(new java.awt.Color(102, 102, 102)); scroll.setForeground(new java.awt.Color(0, 204, 204)); scroll.setOrientation(javax.swing.JScrollBar.HORIZONTAL); scroll.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

panelEscritorio.setBorder(javax.swing.BorderFactory.createEtchedBorder()); panelEscritorio.setOpaque(false); Fondo.setBackground(new java.awt.Color(51, 51, 255)); Fondo.setForeground(new java.awt.Color(51, 102, 255));

Fondo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/EEG Project.png"))); // NOI18N Fondo.setBounds(0, 0, 1586, 980); panelEscritorio.add(Fondo, javax.swing.JLayeredPane.DEFAULT_LAYER); panel2.setBackground(new java.awt.Color(255, 255, 255)); panel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(51, 51, 255))); javax.swing.GroupLayout panel2Layout = new javax.swing.GroupLayout(panel2); panel2.setLayout(panel2Layout); panel2Layout.setHorizontalGroup( panel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADIN G) .addGap(0, 362, Short.MAX_VALUE) ); panel2Layout.setVerticalGroup( panel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADIN G) .addGap(0, 189, Short.MAX_VALUE) ); panel2.setBounds(200, 200, 364, 191); panelEscritorio.add(panel2, javax.swing.JLayeredPane.DEFAULT_LAYER); texto1.setForeground(new java.awt.Color(0, 204, 204)); javax.swing.GroupLayout panelFondoLayout = new javax.swing.GroupLayout(panelFondo); panelFondo.setLayout(panelFondoLayout); panelFondoLayout.setHorizontalGroup( panelFondoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LE ADING) .addGroup(panelFondoLayout.createSequentialGroup() .addComponent(scroll, javax.swing.GroupLayout.DEFAULT_SIZE, 1125, Short.MAX_VALUE)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATE D) .addComponent(texto, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(texto1, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(27, 27, 27)) .addComponent(panelEscritorio) .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); panelFondoLayout.setVerticalGroup( panelFondoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LE ADING) .addGroup(panelFondoLayout.createSequentialGroup() .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(panelFondoLayout.createParallelGroup(javax.swing.GroupLayout.Al ignment.LEADING) .addComponent(scroll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(texto, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(texto1, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(11, 11, 11) .addComponent(panelEscritorio, javax.swing.GroupLayout.DEFAULT_SIZE, 951, Short.MAX_VALUE)) ); jMenu1.setText("Menu");

menuAbrrir.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event. KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK)); menuAbrrir.setText("Abrrir EEG"); menuAbrrir.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuAbrrirActionPerformed(evt); } }); jMenu1.add(menuAbrrir);

menuAceptarCliente.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.a wt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK)); menuAceptarCliente.setText("Aceptar cliente"); menuAceptarCliente.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuAceptarClienteActionPerformed(evt); } }); jMenu1.add(menuAceptarCliente); jMenuBar1.add(jMenu1); menuConfiguracion.setText("Configuración"); menuConfiguracion.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { menuConfiguracionMouseClicked(evt); } });

menuConfiguacion.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.aw t.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK)); menuConfiguacion.setText("Configuración"); menuConfiguacion.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuConfiguacionActionPerformed(evt); } }); menuConfiguracion.add(menuConfiguacion);

menuElectrodos.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.e vent.KeyEvent.VK_T, java.awt.event.InputEvent.CTRL_MASK)); menuElectrodos.setText("Testear BCI"); menuElectrodos.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuElectrodosActionPerformed(evt); } }); menuConfiguracion.add(menuElectrodos); jMenuBar1.add(menuConfiguracion); setJMenuBar(jMenuBar1); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(panelFondo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(panelFondo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); pack(); }// /* @Override public Image getIconImage() { Image retValue = Toolkit.getDefaultToolkit(). getImage(ClassLoader.getSystemResource("imagenes/cerebro.png")); return retValue; }*/

private void menuConfiguracionMouseClicked(java.awt.event.MouseEvent evt) { // TODO add your handling code here: } private void botonIniciarActionPerformed(java.awt.event.ActionEvent evt) { miSistema.getProceso().setPlay(true); } private void botonEnviarActionPerformed(java.awt.event.ActionEvent evt) { if(miSistema.getSerial().getConectado()){ miSistema.getSerial().enviarPorSerial(this.CantidadCanales.getSelectedIndex() +1); miSistema.getBuffer().setCantidadDeCanales(this.CantidadCanales.getSelecte dIndex()+1); miSistema.getProceso().start(); System.out.println("capturando"); }else{ this.mensaje("Imposible capturar", "ERROR",2 ); } } private void stopActionPerformed(java.awt.event.ActionEvent evt) { miSistema.getProceso().setPlay(false); } private void menuAbrrirActionPerformed(java.awt.event.ActionEvent evt) { int respuesta = this.elegirArchivo.showOpenDialog(null); // Si apretamos en aceptar ocurrirá esto if (respuesta == JFileChooser.APPROVE_OPTION) { File selectedFile = elegirArchivo.getSelectedFile(); System.out.println(selectedFile.toString()); this.miSistema.getBuffer().cargarDeArchivo(selectedFile.toString()); // Si apretamos en cancelar o cerramos la ventana ocurrirá esto } //Elegiremos archivos del directorio

} private void elegirArchivoActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void botonBuscarActionPerformed(java.awt.event.ActionEvent evt) { ArrayList misPuertos = miSistema.getSerial().getPuertos(); Puertos.removeAll(); for (int i = 0; i < misPuertos.size(); i++) { this.Puertos.addItem(misPuertos.get(i)); } } private void botonConectarActionPerformed(java.awt.event.ActionEvent evt) { if (Puertos.getSelectedItem() == null) { this.mensaje("Seleccione un puerto", "ATENCION", 2); } else { String baudRate = (String) this.baudRates.getSelectedItem(); System.out.println(baudRate); miSistema.getSerial().initialize(Puertos.getSelectedItem(), Integer.valueOf(baudRate)); } } private void PuertosActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void menuConfiguacionActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: this.ventanaConfiguracionShow(); } private void menuElectrodosActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: this.ventanaElectrodosShow(); }

private void CantidadCanalesActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: miSistema.getBuffer().setCantidadDeCanales(this.CantidadCanales.getSelecte dIndex()+1); } private void botonTresParpadeos1ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {0,3}; miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaON1ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {0,1}; miSistema.getServidor().enviarPorSocket(vec); } private void botonDosParpadeos1ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {0,2}; miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaOFF1ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {0,0}; miSistema.getServidor().enviarPorSocket(vec); } private void menuAceptarClienteActionPerformed(java.awt.event.ActionEvent evt) { miSistema.getServidor().acept(); } private void botonAlfaON2ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {1,1};

miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaOFF2ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {1,0}; miSistema.getServidor().enviarPorSocket(vec); } private void botonDosParpadeos2ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {1,2}; miSistema.getServidor().enviarPorSocket(vec); } private void botonTresParpadeos2ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {1,3}; miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaON3ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {2,1}; miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaOFF3ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {2,0}; miSistema.getServidor().enviarPorSocket(vec); } private void botonDosParpadeos3ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {2,2}; miSistema.getServidor().enviarPorSocket(vec); }

private void botonTresParpadeos3ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {2,3}; miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaON4ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {3,1}; miSistema.getServidor().enviarPorSocket(vec); } private void botonAlfaOFF4ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {3,0}; miSistema.getServidor().enviarPorSocket(vec); } private void botonDosParpadeos4ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {3,2}; miSistema.getServidor().enviarPorSocket(vec); } private void botonTresParpadeos4ActionPerformed(java.awt.event.ActionEvent evt) { byte[] vec = {3,3}; miSistema.getServidor().enviarPorSocket(vec); } /** * @param args the command line arguments */ // Variables declaration - do not modify private javax.swing.JPanel BCI1; private javax.swing.JPanel BCI2; private javax.swing.JComboBox CantidadCanales; private javax.swing.JLabel Fondo; private javax.swing.JComboBox Puertos; private javax.swing.JComboBox baudRates; private javax.swing.JToggleButton botonAlfaOFF1;

private javax.swing.JToggleButton botonAlfaOFF2; private javax.swing.JToggleButton botonAlfaOFF3; private javax.swing.JToggleButton botonAlfaOFF4; private javax.swing.JButton botonAlfaON1; private javax.swing.JButton botonAlfaON2; private javax.swing.JButton botonAlfaON3; private javax.swing.JButton botonAlfaON4; private javax.swing.JButton botonBuscar; private javax.swing.JButton botonConectar; private javax.swing.JButton botonDosParpadeos1; private javax.swing.JButton botonDosParpadeos2; private javax.swing.JButton botonDosParpadeos3; private javax.swing.JButton botonDosParpadeos4; private javax.swing.JButton botonEnviar; private javax.swing.JButton botonIniciar; private javax.swing.JToggleButton botonTresParpadeos1; private javax.swing.JToggleButton botonTresParpadeos2; private javax.swing.JToggleButton botonTresParpadeos3; private javax.swing.JToggleButton botonTresParpadeos4; private javax.swing.JFileChooser elegirArchivo; private javax.swing.ButtonGroup grupoTiempo; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JMenu jMenu1; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JToolBar jToolBar1; private javax.swing.JMenuItem menuAbrrir; private javax.swing.JMenuItem menuAceptarCliente; private javax.swing.JMenuItem menuConfiguacion; private javax.swing.JMenu menuConfiguracion; private javax.swing.JMenuItem menuElectrodos; private javax.swing.JPanel panel2; private javax.swing.JDesktopPane panelEscritorio; private javax.swing.JPanel panelFondo; private javax.swing.JPanel panelSerial; private javax.swing.JScrollBar scroll; private javax.swing.JButton stop; private javax.swing.JLabel texto;

private javax.swing.JLabel texto1; private javax.swing.JRadioButton tiempoReal; private javax.swing.JRadioButton tiempoSimulado; private javax.swing.JDialog ventanaConfiguracion; private javax.swing.JDialog ventanaElegirArchivo; private javax.swing.JDialog ventanaPruebaBCI; // End of variables declaration }

A.5.2.2.

Clase main

285

package Ventanas; import Dominio.Buffer; import Dominio.Proceso; import Dominio.Serial; import Dominio.Sistema; import Dominio.Servidor; /** * ***************************Clase main************************************** * * Se encarga de ejecutar el sistema */ public class EEG { public static void main(String[] args) { // TODO code application logic here Sistema miSistema = new Sistema(); Buffer unB = new Buffer(miSistema); Serial unS = new Serial(miSistema); Proceso unProceso = new Proceso(miSistema); Ventana unV = new Ventana(miSistema); Servidor unServidor = new Servidor(); unServidor.initServer(miSistema); miSistema.setVentana(unV); miSistema.setBuffer(unB); miSistema.setSerial(unS); miSistema.setProceso(unProceso); miSistema.setServidor(unServidor); unV.setVisible(true); } }

A.6. Código de programa de comunicación PC - NXT

287

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import lejos.pc.comm.NXTCommLogListener; import lejos.pc.comm.NXTConnector; import java.io.* ; import java.net.* ; public class ComunicacionPC_NXT { //Se crea una variable que indica que la conexión sera local static final String HOST = "localhost"; //Se elige el puerto de conexión static final int PUERTO = 5000; public static void main(String[] args) { //Se crea el objeto que se utilizara para la conexión BT con el NXT NXTConnector conn = new NXTConnector(); // conn.addLogListener(new NXTCommLogListener(){ public void logEvent(String mensaje) { System.out.println("Log de envío BT: "+mensaje); } public void logEvent(Throwable throwable) { System.out.println("Log de envío BT - rastreo de pila: "); throwable.printStackTrace(); } } ); //me conecto via BT al NXT boolean connected = conn.connectTo("btspp://"); //Si fallo la conexión, lo indico y termino el programa if (!connected) { System.err.println("Conexión a NXT fallida"); System.exit(1);

} //Se crea el canal de comunicación bidireccional DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); DataInputStream dis = new DataInputStream(conn.getInputStream()); byte data; boolean recibiCanal = false; byte canal = 0; try { //Se crea el socket local conectandose al puerto 5000 Socket skCliente = new Socket(HOST,PUERTO); //Se crea comunicación bidireccional InputStream aux = skCliente.getInputStream(); DataInputStream flujo = new DataInputStream( aux );

OutputStream auxOut = skCliente.getOutputStream(); DataOutputStream flujoOut = new DataOutputStream(auxOut); //hasta que el servidor cierre la conexión while(connected){ try { //se espera el envío de datos data = flujo.readByte(); //Si se recibe el comando de finalizar if(data==4){ connected = false; dos.writeByte(data); dos.flush(); }else{ if(recibiCanal){ if(canal==0){ if((data==2) || (data==3)){ dos.writeByte(data); dos.flush(); }

}else if(canal==1){ if((data==0) || (data==1)){ dos.writeByte(data); dos.flush(); } } recibiCanal = false; }else{ canal=data; recibiCanal = true; } }

} catch (IOException ioe) { System.out.println("Error enviando datos:"); System.out.println(ioe.getMessage()); }

} try { //se cierra el socket skCliente.close(); //se cierran los canales de comunicación con el NXT dis.close(); dos.close(); //Se cierra la comunicación con el NXT conn.close(); } catch (IOException ioe) { System.out.println("Error cerrando la conexión:"); System.out.println(ioe.getMessage()); } } catch( Exception e ) { System.out.println( e.getMessage() ); } } }

A.7. Código robot NXT

291

import java.io.DataInputStream; import lejos.nxt.Motor; import lejos.robotics.navigation.DifferentialPilot; import java.io.DataOutputStream; import lejos.nxt.LCD; import lejos.nxt.comm.BTConnection; import lejos.nxt.comm.Bluetooth; public class ProgramaNXT { public static void main(String [] args) throws Exception { //Se crea un objeto pilot que controla los motores del NXT DifferentialPilot pilot= new DifferentialPilot(5.6, 10.3, Motor.A, Motor.B); //Se indica la velocidad de movimiento en cm/s pilot.setTravelSpeed(8);

boolean terminar =false; //se dibuja el mensaje esperando en la pantalla del NXT LCD.drawString("Esperando...",0,0); LCD.refresh(); //Se espera una conexion por BT BTConnection btc = Bluetooth.waitForConnection(); //Se limpia la pantalla y se imprime conectado LCD.clear(); LCD.drawString("Conectado",0,0); LCD.refresh(); //se cren los canales de comunicación DataInputStream dis = btc.openDataInputStream(); DataOutputStream dos = btc.openDataOutputStream(); byte recibo=0; //mientras no reciba el comando de terminar while (!terminar) {

//espero el envío de datos recibo=dis.readByte(); //si recibe 1 avanza if(recibo==1){ pilot.forward(); LCD.clear(); LCD.drawString("Conectado",0,0); LCD.drawString("Estoy avanzando", 0, 1); //si recibe 0 para }else if(recibo==0){ pilot.stop(); LCD.clear(); LCD.drawString("Conectado",0,0); LCD.drawString("Estoy quieto", 0, 1); //si recibe 12 gira a la derecha }else if(recibo==2){ pilot.setRotateSpeed(22.5); pilot.rotateRight(); LCD.clear(); LCD.drawString("Conectado",0,0); LCD.drawString("Giro a la", 0, 1); LCD.drawString("derecha", 0, 2); //si recibe 3 gira a la izquierda }else if(recibo==3){ pilot.setRotateSpeed(22.5); pilot.rotateLeft(); LCD.clear(); LCD.drawString("Conectado",0,0); LCD.drawString("Giro a la", 0, 1); LCD.drawString("izquierda", 0, 2); }else if(recibo==4){ terminar=true; }

} //se cierra la conexión dis.close(); dos.close(); Thread.sleep(100); LCD.clear(); LCD.drawString("Cerrando",0,0);

LCD.refresh(); btc.close(); LCD.clear(); } }

A.8. Diagrama esquemático de la placa amplicadora

295

2k2 3 1 1

3

3

100pF

Q201 BC557

R214

1µF

1 6

2k2 R215

C220

8

2k2

3

Q203 BC557

R201

HP 1 pole fc=0.16

IC202

VGND

CH2+ 2k2

+5V/2

2

2

2

Q207 BC547

2k2

1 1

100pF

2

2

10pF C204

C209 Channel 2 + Electrode

Q205 BC547

3

2k2

G=12.2

R207

V+ V-

2k2

2k2

R205

R206

R224

HF rejection CH2- R202

C205

Channel 2 Electrode

PAD201

Electrode DC checkpoint ESD protection and user current limiter R208

5 7 4

C217 100nF C214

100nF

INA114P AGND VGND

IC204B 5

R219

Electrode DC checkpoint

R204

Channel 1 + Electrode

CH1+

2k2

2k2

G=12.2

1 1

R216

1µF

1 6

2k2 R217

C221

8 3

Q204 BC557

3

HP 1 pole fc=0.16

2

2k2

PAD205 COM

+5V/2

IC203

VGND

2k2 R203

R211

2 3

100pF

1 1

2

2

Q208 BC547

R212

Q202 BC557

3

3 2

10pF C206

C210

C207

100pF

2k2 Q206 BC547

TLC277P

V+ V-

2k2

2k2

R209

R210

R226

CH1-

10k

6

PAD202

Channel 1 Electrode

VGN

7

Input Voltage Full Scale (10 Bit) = 512uVpp Input Voltage Resolution (1 LSB) = 0.5 uVpp Total gain = 7812.5 Input can handle up to +/-100mV DC electrode offset

5 7

C218

4

C215

100nF 100nF

INA114P AGND VGND +5V/2

VGN

100nF

PAD206 AGND AGND

8

IC204A 3

R_LEG

1nF R213

R_LEG

TLC277P

6

TLC277P

IC204PWR

VGND

VGND

7 1

IC201B

2

20k P201

C212

C219

1

5

200k

3

Right Leg Electrode

2

10k

4

1

GND

R218

C216

VCC

C226

right leg driver

100nF

3

AGND

1nF

simulates ele

Right-leg driver (DRL) notes:

AGND

PAD20

P201 is not needed when INA114 instrumentation amplifiers are used. You may replace it with a short wire from pin 2 and pin 1 (VGND).

Important usage instructions for the DRL. If you only want to use one channel, never let the other channel float. Always connect the unused terminals to VGND, or the DRL will not work properly.

DRL design from http://www.biosemi.com/publications/artikel7.htm, fig.3

ModularEEG - 2-channel EEG amplifier module See http://openeeg.sf.net for more information.

TITLE:

modEEGamp_v1.1

Authors: Moritz v. Buttlar, Joerg Hansmann, Andreas R

Document Number: Date: 07/08/2013 05:46:47 p.m.

REV: Sheet:

1/1

02/06/2014 08:34:18 p.m. D:\Lalo\Proyecto\ModularEEG-v1.1.1\modEEGamp_v1.1.sch (Sheet: 1/1)

u cal

If P201 is needed, adjust potentiometer so DRL=0mV (referred to VGND) when _all_ amplifier inputs are shorted to the DRL output (R_LEG).

Cal_G

PAD20

U_cal

G=16 R232

C229

33nF 5% IC205B

R228

3

C232

C2 C227

100k

IC205PWR

C222

4

VGND 1nF

100nF

8.2k VGND

100nF

100k

1k

P202 20k

R230 VCC

1

VGND

R229

7.5k

+5V/2

TLC277P

8

3

R231

R221

R2

7 6

GND

2

R220 1

15k

1M

1M

TLC277P

10k

220nF 5%

1µF

C231

1 2

3

ADIN1

5

220nF 5%

IC205A

C234

C225

G=40 G=6..100

c=0.16 Hz

AGND

VGND

1nF 3rd order "Besselworth" filter, fc = 59 Hz. The 3rd pole is located on the digital board. AGND

G=16

C236 33nF 5%

R237

R233

1µF

10k

15k

3

5

100k C233

C1

IC206PWR

C224

4

VGND 1nF

1nF

C230

8.2k VGND

VCC

R235

100nF

100k

1k

VGND

R234

7.5k

+5V/2

TLC277P

8

1

P203 20k

6

GND

3

R236

R225

R1

7

220nF 5%

2

R222 1

C235

1M

TLC277P

1M

1 2

3

ADIN0

IC206B

220nF 5%

C228

C223

IC206A

100nF

G=40 G=6..100

c=0.16 Hz

AGND

VGND

AGND +5V/2

8

100nF +

es electrode impedance PAD204

R238

Cal_GND

10k

ADIN0P +5V/2

Vcc analog

TLC277P

ADIN1P

+ 47µF

C208

4

ref. voltage +2V, buffered

10nF

2

C203

1

2.0V C202

3

100nF VGND

Only insert IC201 on _one_ board when using 2 or 3 amplifier boards

IC201A

10nF C213

C211

C201 47µF tan 1ohm AGND

R240 100

Ground plane is VGND

PAD203

R239

R227

R223

U_cal

10k

1M

1M

voltage divider 1:20000 5Vp-p +/-10% => 250µVp-p +/-10% 250µVpp +/-10%, 0.1 .. 100Hz Square wave Calibration Signal

2.0V buf

AGND The solder-jumpers (SJ201 - SJ206) to the right, are used for channel mapping. This allows multiple amplifier boards to share the same connector. 2 channels must be selected on each board by closing two jumper gaps with solder. Use SJ201 and SJ204 for the first board.

J201 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33

2.0V 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34

ADIN0P 1 1 1

1 1 1

2 2 2

ADIN1P

PWM

PINHD-2X17 PWM cal (PB1) Output Voltage Full Scale (10 Bit) = 4.000 Vp-p (Range 0..4V) => 3.9mV bitstep at 10 bit resolution.

2 2 2

A.9. Layout de la placa amplicadora

298

J201

C211

IC204

C216

C226 C228

3

R213

1

IC201

R219 R218 COM

+

C204 R201

1

Q205

1 R208 R207 R206 R205 1

C224

C230

IC206

R222 R225 R226

3

C233

C223

C215 R215 R214

3

C236

R237 R236 R235 R234 R233

C229 C235 C234

1

3

3

C222

C227

IC205

C209

Q208

IC202

-

Q201 R202 C205

C218

1 P202

1

Q204

C220

C206 R203

1

C217

+

R212 R211 R210 R209

C219

R217 R216 IC203

C210

1

Q206

R204 C207

1

P203

R220 R221 R224

C212

P201 Q202

AGND

C221

3

C208

Cal_GND U_cal

R2

C213

C202 C201

ModularEEG C2 amplifier v1.1.0 C1

R1

C203

-

R240 R239 R238

R227 R223

C232

R232 R231 R230 R229 R228

1 C214

Q203 Q207

C225

02/06/2014 08:39:37 p.m. f=2.00 D:\Lalo\Proyecto\ModularEEG-v1.1.1\modEEGamp_v1.1.brd

C231

B. Anexo

300

B.1. Hoja de datos ATmega 2560

301

Features • High Performance, Low Power AVR® 8-Bit Microcontroller • Advanced RISC Architecture











• •

– 135 Powerful Instructions – Most Single Clock Cycle Execution – 32 x 8 General Purpose Working Registers – Fully Static Operation – Up to 16 MIPS Throughput at 16 MHz – On-Chip 2-cycle Multiplier Non-volatile Program and Data Memories – 64K/128K/256K Bytes of In-System Self-Programmable Flash Endurance: 10,000 Write/Erase Cycles – Optional Boot Code Section with Independent Lock Bits In-System Programming by On-chip Boot Program True Read-While-Write Operation – 4K Bytes EEPROM Endurance: 100,000 Write/Erase Cycles – 8K Bytes Internal SRAM – Up to 64K Bytes Optional External Memory Space – Programming Lock for Software Security JTAG (IEEE std. 1149.1 compliant) Interface – Boundary-scan Capabilities According to the JTAG Standard – Extensive On-chip Debug Support – Programming of Flash, EEPROM, Fuses, and Lock Bits through the JTAG Interface Peripheral Features – Two 8-bit Timer/Counters with Separate Prescaler and Compare Mode – Four 16-bit Timer/Counter with Separate Prescaler, Compare- and Capture Mode – Real Time Counter with Separate Oscillator – Four 8-bit PWM Channels – Six/Twelve PWM Channels with Programmable Resolution from 2 to 16 Bits (ATmega1281/2561, ATmega640/1280/2560) – Output Compare Modulator – 8/16-channel, 10-bit ADC – Two/Four Programmable Serial USART (ATmega1281/2561,ATmega640/1280/2560) – Master/Slave SPI Serial Interface – Byte Oriented 2-wire Serial Interface – Programmable Watchdog Timer with Separate On-chip Oscillator – On-chip Analog Comparator – Interrupt and Wake-up on Pin Change Special Microcontroller Features – Power-on Reset and Programmable Brown-out Detection – Internal Calibrated Oscillator – External and Internal Interrupt Sources – Six Sleep Modes: Idle, ADC Noise Reduction, Power-save, Power-down, Standby, and Extended Standby I/O and Packages – 51/86 Programmable I/O Lines (ATmega1281/2561, ATmega640/1280/2560) – 64-lead (ATmega1281/2561) – 100-lead (ATmega640/1280/2560) – 100-lead TQFP (64-lead TQFP Option) Temperature Range: – -40°C to 85°C Industrial Speed Grade: – ATmega1281/2561V/ATmega640/1280/2560V: 0 - 4 MHz @ 1.8 - 5.5V, 0 - 8 MHz @ 2.7 - 5.5V – ATmega640/1280/1281/2560/2561: 0 - 8 MHz @ 2.7 - 5.5V, 0 - 16 MHz @ 4.5 - 5.5V

8-bit Microcontroller with 256K Bytes In-System Programmable Flash ATmega1281/25 61/V ATmega640/128 0/2560/V Advance Information

2549A–AVR–03/05

2

PA1 (AD1)

80

PA2 (AD2)

81

PJ7

82

PA0 (AD0)

83

GND

84

VCC

85

PK6 (ADC14/PCINT22)

86

PK7 (ADC15/PCINT23)

87

PK4 (ADC12/PCINT20)

88

PK5 (ADC13/PCINT21)

89

PK2 (ADC10/PCINT18)

90

PK3 (ADC11/PCINT19)

91

PK0 (ADC8/PCINT16)

92

PK1 (ADC9/PCINT17)

PF7 (ADC7/TDI)

93

PF5 (ADC5/TMS)

94

PF6 (ADC6/TDO)

95

PF3 (ADC3)

96

PF4 (ADC4/TCK)

97

PF1 (ADC1)

98

PF2 (ADC2)

AREF

GND

100 99

PF0 (ADC0)

Figure 1. Pinout ATmega640/1280/2560

AVCC

79

78

77

76

(OC0B) PG5

1

75

PA3 (AD3)

(RXD0/PCINT8) PE0

2

74

PA4 (AD4)

(TXD0) PE1

3

73

PA5 (AD5)

(XCK0/AIN0) PE2

4

72

PA6 (AD6)

(OC3A/AIN1) PE3

5

71

PA7 (AD7)

(OC3B/INT4) PE4

6

70

PG2 (ALE)

(OC3C/INT5) PE5

7

69

PJ6 (PCINT15)

(T3/INT6) PE6

8

68

PJ5 (PCINT14)

(CLKO/ICP3/INT7) PE7

9

67

PJ4 (PCINT13)

VCC

10

66

PJ3 (PCINT12)

GND

11

65

PJ2 (XCK3/PCINT11)

(RXD2) PH0

12

64

PJ1 (TXD3/PCINT10)

(TXD2) PH1

13

63

PJ0 (RXD3/PCINT9)

(XCK2) PH2

14

62

GND

(OC4A) PH3

15

61

VCC

(OC4B) PH4

16

60

PC7 (A15)

(OC4C) PH5

17

59

PC6 (A14)

(OC2B) PH6

18

58

PC5 (A13)

(SS/PCINT0) PB0

19

57

PC4 (A12)

(SCK/PCINT1) PB1

20

56

PC3 (A11)

(MOSI/PCINT2) PB2

21

55

PC2 (A10)

(MISO/PCINT3) PB3

22

54

PC1 (A9)

(OC2A/PCINT4) PB4

23

53

PC0 (A8)

(OC1A/PCINT5) PB5

24

52

PG1 (RD)

(OC1B/PCINT6) PB6

25

51

PG0 (WR)

INDEX CORNER

42

43

44

45

46

47

48

49

50

(T1) PD6

41

(T0) PD7

40

(ICP1) PD4

39

(XCK1) PD5

GND

XTAL2

38

(TXD1/INT3) PD3

VCC

37

(RXD1/INT2) PD2

RESET

36

(SCL/INT0) PD0

(TOSC2) PG3

(TOSC1) PG4

35

(SDA/INT1) PD1

(T4) PH7

34

PL6

33

PL7

32

(OC5B) PL4

31

(OC5C) PL5

30

(OC5A) PL3

29

(T5) PL2

28

(ICP5) PL1

27

XTAL1

26

(OC0A/OC1C/PCINT7) PB7

ATmega640/1280/2560

(ICP4) PL0

Pin Configurations

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561

(OC0B) PG5

1

(RXD0/PCINT8/PDI) PE0

2

Note:

Disclaimer

VCC

PA0 (AD0)

PA1 (AD1)

PA2 (AD2)

51

50

49

53

52

PF7 (ADC7/TDI)

GND

54

PF5 (ADC5/TMS)

PF6 (ADC6/TDO)

56

55

PF3 (ADC3)

PF4 (ADC4/TCK)

58

57

PF1 (ADC1)

PF2 (ADC2) 59

61

60

AREF

PF0 (ADC0)

63

62

AVCC

GND

64

Figure 2. Pinout ATmega1281/2561

INDEX CORNER

48

PA3 (AD3)

47

PA4 (AD4)

(TXD0/PDO) PE1

3

46

PA5 (AD5)

(XCK0/AIN0) PE2

4

45

PA6 (AD6)

(OC3A/AIN1) PE3

5

44

PA7 (AD7)

(OC3B/INT4) PE4

6

43

PG2 (ALE)

(OC3C/INT5) PE5

7

42

PC7 (A15)

(T3/INT6) PE6

8

41

PC6 (A14)

(ICP3/CLKO/INT7) PE7

9

40

PC5 (A13)

(SS/PCINT0) PB0

10

39

PC4 (A12)

(SCK/ PCINT1) PB1

11

38

PC3 (A11)

(MOSI/ PCINT2) PB2

12

37

PC2 (A10)

(MISO/ PCINT3) PB3

13

36

PC1 (A9)

(OC2A/ PCINT4) PB4

14

35

PC0 (A8)

(OC1A/PCINT5) PB5

15

34

PG1 (RD)

(OC1B/PCINT6) PB6

16

33

PG0 (WR)

25

26

27

28

29

30

31

32

(SCL/INT0) PD0

(SDA/INT1) PD1

(RXD1/INT2) PD2

(TXD1/INT3) PD3

(ICP1) PD4

(XCK1) PD5

(T1) PD6

(T0) PD7

23

24

XTAL2

22 GND

XTAL1

20

21

19 (TOSC1) PG4

VCC

18 (TOSC2) PG3

RESET

17 (OC0A/OC1C/PCINT7) PB7

ATmega1281/2561

The large center pad underneath the QFN/MLF package is made of metal and internally connected to GND. It should be soldered or glued to the board to ensure good mechanical stability. If the center pad is left unconnected, the package might loosen from the board.

Typical values contained in this datasheet are based on simulations and characterization of other AVR microcontrollers manufactured on the same process technology. Min and Max values will be available after the device is characterized.

3 2549A–AVR–03/05

Overview The ATmega640/1280/1281/2560/2561 is a low-power CMOS 8-bit microcontroller based on the AVR enhanced RISC architecture. By executing powerful instructions in a single clock cycle, the ATmega640/1280/1281/2560/2561 achieves throughputs approaching 1 MIPS per MHz allowing the system designer to optimize power consumption versus processing speed.

Block Diagram Figure 3. Block Diagram PF7..0

PK7..0

PORT F (8)

PORT K (8)

PJ7..0

PE7..0

VCC

RESET

GND

Power Supervision POR / BOD & RESET

PORT J (8)

PORT E (8)

Watchdog Timer

Watchdog Oscillator

Analog Comparator

JTAG

A/D Converter

EEPROM

Internal Bandgap reference

USART 0

XTAL1 Oscillator Circuits / Clock Generation

16bit T/C 3

USART 3

16bit T/C 5

XTAL2 CPU

PA7..0

PORT A (8)

16bit T/C 4 USART 1

PG5..0

PORT G (6)

XRAM

PC7..0

PORT C (8)

TWI

FLASH

SPI

SRAM

16bit T/C 1

8bit T/C 0

USART 2

8bit T/C 2

NOTE: Shaded parts only appear in the 100 pin version. The ADC, T/C4 and T/C5 only have full functionality in the 100 pin version.

4

PORT D (8)

PORT B (8)

PORT H (8)

PORT L (8)

PD7..0

PB7..0

PH7..0

PL7..0

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561 The AVR core combines a rich instruction set with 32 general purpose working registers. All the 32 registers are directly connected to the Arithmetic Logic Unit (ALU), allowing two independent registers to be accessed in one single instruction executed in one clock cycle. The resulting architecture is more code efficient while achieving throughputs up to ten times faster than conventional CISC microcontrollers. The ATmega640/1280/1281/2560/2561 provides the following features: 64K/128K/256K bytes of In-System Programmable Flash with Read-While-Write capabilities, 4K bytes EEPROM, 8K bytes SRAM, 54/86 general purpose I/O lines, 32 general purpose working registers, Real Time Counter (RTC), six flexible Timer/Counters with compare modes and PWM, 4 USARTs, a byte oriented 2-wire Serial Interface, a 16-channel, 10bit ADC with optional differential input stage with programmable gain, programmable Watchdog Timer with Internal Oscillator, an SPI serial port, IEEE std. 1149.1 compliant JTAG test interface, also used for accessing the On-chip Debug system and programming and six software selectable power saving modes. The Idle mode stops the CPU while allowing the SRAM, Timer/Counters, SPI port, and interrupt system to continue functioning. The Power-down mode saves the register contents but freezes the Oscillator, disabling all other chip functions until the next interrupt or Hardware Reset. In Power-save mode, the asynchronous timer continues to run, allowing the user to maintain a timer base while the rest of the device is sleeping. The ADC Noise Reduction mode stops the CPU and all I/O modules except Asynchronous Timer and ADC, to minimize switching noise during ADC conversions. In Standby mode, the Crystal/Resonator Oscillator is running while the rest of the device is sleeping. This allows very fast start-up combined with low power consumption. In Extended Standby mode, both the main Oscillator and the Asynchronous Timer continue to run. The device is manufactured using Atmel’s high-density nonvolatile memory technology. The On-chip ISP Flash allows the program memory to be reprogrammed in-system through an SPI serial interface, by a conventional nonvolatile memory programmer, or by an On-chip Boot program running on the AVR core. The boot program can use any interface to download the application program in the application Flash memory. Software in the Boot Flash section will continue to run while the Application Flash section is updated, providing true Read-While-Write operation. By combining an 8-bit RISC CPU with In-System Self-Program mable Flash on a monolithic ch ip, the Atmel ATmega640/1280/1281/2560/2561 is a powerful microcontroller that provides a highly flexible and cost effective solution to many embedded control applications. The ATmega640/1280/1281/2560/2561 AVR is supported with a full suite of program and system development tools including: C compilers, macro assemblers, program debugger/simulators, in-circuit emulators, and evaluation kits.

5 2549A–AVR–03/05

Comparison Between ATmega1281/2561 and ATmega640/1280/2560 Each device in the ATmega640/1280/1281/2560/2561 family differs only in memory size and number of pins. Table 1 summarizes the different configurations for the six devices. Table 1. Configuration Summary Device

Flash

EEPROM

RAM

General Purpose I/O pins

16 bits resolution PWM channels

Serial USARTs

ADC Channels

ATmega640

64KB

4KB

8KB

86

12

4

16

ATmega1280

128KB

4KB

8KB

86

12

4

16

ATmega1281

128KB

4KB

8KB

54

6

2

8

ATmega2560

256KB

4KB

8KB

86

12

4

16

ATmega2561

256KB

4KB

8KB

54

6

2

8

Pin Descriptions VCC

Digital supply voltage.

GND

Ground.

Port A (PA7..PA0)

Port A is an 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port A output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port A pins that are externally pulled low will source current if the pull-up resistors are activated. The Port A pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port A also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 88.

Port B (PB7..PB0)

Port B is an 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port B output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port B pins that are externally pulled low will source current if the pull-up resistors are activated. The Port B pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port B has better driving capabilities than the other ports. Port B also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 89.

Port C (PC7..PC0)

Port C is an 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port C output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port C pins that are externally pulled low will source current if the pull-up resistors are activated. The Port C pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port C also serves the functions of special ATmega640/1280/1281/2560/2561 as listed on page 92.

Port D (PD7..PD0)

6

features

of

the

Port D is an 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port D output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port D pins that are externally pulled low will source

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561 current if the pull-up resistors are activated. The Port D pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port D also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 94. Port E (PE7..PE0)

Port E is an 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port E output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port E pins that are externally pulled low will source current if the pull-up resistors are activated. The Port E pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port E also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 96.

Port F (PF7..PF0)

Port F serves as analog inputs to the A/D Converter. Port F also serves as an 8-bit bi-directional I/O port, if the A/D Converter is not used. Port pins can provide internal pull-up resistors (selected for each bit). The Port F output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port F pins that are externally pulled low will source current if the pull-up resistors are activated. The Port F pins are tri-stated when a reset condition becomes active, even if the clock is not running. If the JTAG interface is enabled, the pull-up resistors on pins PF7(TDI), PF5(TMS), and PF4(TCK) will be activated even if a reset occurs. Port F also serves the functions of the JTAG interface.

Port G (PG5..PG0)

Port G is a 6-bit I/O port with internal pull-up resistors (selected for each bit). The Port G output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port G pins that are externally pulled low will source current if the pull-up resistors are activated. The Port G pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port G also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 102.

Port H (PH7..PH0)

Port H is a 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port H output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port H pins that are externally pulled low will source current if the pull-up resistors are activated. The Port H pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port H also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 104.

Port J (PJ7..PJ0)

Port J is a 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port J output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port J pins that are externally pulled low will source current if the pull-up resistors are activated. The Port J pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port J also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 106.

Port K (PK7..PK0)

Port K serves as analog inputs to the A/D Converter.

7 2549A–AVR–03/05

Port K is a 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port K output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port K pins that are externally pulled low will source current if the pull-up resistors are activated. The Port K pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port K also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 108. Port L (PL7..PL0)

Port L is a 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port L output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port L pins that are externally pulled low will source current if the pull-up resistors are activated. The Port L pins are tri-stated when a reset condition becomes active, even if the clock is not running. Port L also serves the functions of various special features of the ATmega640/1280/1281/2560/2561 as listed on page 110.

RESET

Reset input. A low level on this pin for longer than the minimum pulse length will generate a reset, even if the clock is not running. The minimum pulse length is given in Table 23 on page 58. Shorter pulses are not guaranteed to generate a reset.

XTAL1

Input to the inverting Oscillator amplifier and input to the internal clock operating circuit.

XTAL2

Output from the inverting Oscillator amplifier.

AVCC

AVCC is the supply voltage pin for Port F and the A/D Converter. It should be externally connected to VCC, even if the ADC is not used. If the ADC is used, it should be connected to VCC through a low-pass filter.

AREF

This is the analog reference pin for the A/D Converter.

About Code Examples

This documentation contains simple code examples that briefly show how to use various parts of the device. Be aware that not all C compiler vendors include bit definitions in the header files and interrupt handling in C is compiler dependent. Please confirm with the C compiler documentation for more details. These code examples assume that the part specific header file is included before compilation. For I/O registers located in extended I/O map, "IN", "OUT", "SBIS", "SBIC", "CBI", and "SBI" instructions must be replaced with instructions that allow access to extended I/O. Typically "LDS" and "STS" combined with "SBRS", "SBRC", "SBR", and "CBR".

8

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561 AVR CPU Core Introduction

This section discusses the AVR core architecture in general. The main function of the CPU core is to ensure correct program execution. The CPU must therefore be able to access memories, perform calculations, control peripherals, and handle interrupts.

Architectural Overview

Figure 4. Block Diagram of the AVR Architecture

Data Bus 8-bit

Flash Program Memory

Program Counter

Status and Control

32 x 8 General Purpose Registrers

Control Lines

Direct Addressing

Instruction Decoder

Indirect Addressing

Instruction Register

Interrupt Unit SPI Unit Watchdog Timer

ALU

Analog Comparator

I/O Module1

Data SRAM

I/O Module 2

I/O Module n EEPROM

I/O Lines

In order to maximize performance and parallelism, the AVR uses a Harvard architecture – with separate memories and buses for program and data. Instructions in the program memory are executed with a single level pipelining. While one instruction is being executed, the next instruction is pre-fetched from the program memory. This concept enables instructions to be executed in every clock cycle. The program memory is InSystem Reprogrammable Flash memory. The fast-access Register File contains 32 x 8-bit general purpose working registers with a single clock cycle access time. This allows single-cycle Arithmetic Logic Unit (ALU) operation. In a typical ALU operation, two operands are output from the Register File,

9 2549A–AVR–03/05

the operation is executed, and the result is stored back in the Register File – in one clock cycle. Six of the 32 registers can be used as three 16-bit indirect address register pointers for Data Space addressing – enabling efficient address calculations. One of the these address pointers can also be used as an address pointer for look up tables in Flash program memory. These added function registers are the 16-bit X-, Y-, and Z-register, described later in this section. The ALU supports arithmetic and logic operations between registers or between a constant and a register. Single register operations can also be executed in the ALU. After an arithmetic operation, the Status Register is updated to reflect information about the result of the operation. Program flow is provided by conditional and unconditional jump and call instructions, able to directly address the whole address space. Most AVR instructions have a single 16-bit word format. Every program memory address contains a 16- or 32-bit instruction. Program Flash memory space is divided in two sections, the Boot Program section and the Application Program section. Both sections have dedicated Lock bits for write and read/write protection. The SPM instruction that writes into the Application Flash memory section must reside in the Boot Program section. During interrupts and subroutine calls, the return address Program Counter (PC) is stored on the Stack. The Stack is effectively allocated in the general data SRAM, and consequently the Stack size is only limited by the total SRAM size and the usage of the SRAM. All user programs must initialize the SP in the Reset routine (before subroutines or interrupts are executed). The Stack Pointer (SP) is read/write accessible in the I/O space. The data SRAM can easily be accessed through the five different addressing modes supported in the AVR architecture. The memory spaces in the AVR architecture are all linear and regular memory maps. A flexible interrupt module has its control registers in the I/O space with an additional Global Interrupt Enable bit in the Status Register. All interrupts have a separate Interrupt Vector in the Interrupt Vector table. The interrupts have priority in accordance with their Interrupt Vector position. The lower the Interrupt Vector address, the higher the priority. The I/O memory space contains 64 addresses for CPU peripheral functions as Control Registers, SPI, and other I/O functions. The I/O Memory can be accessed directly, or as the Data Space locations following those of the Register File, 0x20 - 0x5F. In addition, the ATmega640/1280/1281/2560/2561 has Extended I/O space from 0x60 - 0x1FF in SRAM where only the ST/STS/STD and LD/LDS/LDD instructions can be used.

ALU – Arithmetic Logic Unit

The high-performance AVR ALU operates in direct connection with all the 32 general purpose working registers. Within a single clock cycle, arithmetic operations between general purpose registers or between a register and an immediate are executed. The ALU operations are divided into three main categories – arithmetic, logical, and bit-functions. Some implementations of the architecture also provide a powerful multiplier supporting both signed/unsigned multiplication and fractional format. See the “Instruction Set” section for a detailed description.

Status Register

The Status Register contains information about the result of the most recently executed arithmetic instruction. This information can be used for altering program flow in order to perform conditional operations. Note that the Status Register is updated after all ALU operations, as specified in the Instruction Set Reference. This will in many cases

10

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561 remove the need for using the dedicated compare instructions, resulting in faster and more compact code. The Status Register is not automatically stored when entering an interrupt routine and restored when returning from an interrupt. This must be handled by software. The AVR Status Register – SREG – is defined as: Bit

7

6

5

4

3

2

1

0

I

T

H

S

V

N

Z

C

Read/Write

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

Initial Value

0

0

0

0

0

0

0

0

SREG

• Bit 7 – I: Global Interrupt Enable The Global Interrupt Enable bit must be set for the interrupts to be enabled. The individual interrupt enable control is then performed in separate control registers. If the Global Interrupt Enable Register is cleared, none of the interrupts are enabled independent of the individual interrupt enable settings. The I-bit is cleared by hardware after an interrupt has occurred, and is set by the RETI instruction to enable subsequent interrupts. The Ibit can also be set and cleared by the application with the SEI and CLI instructions, as described in the instruction set reference. • Bit 6 – T: Bit Copy Storage The Bit Copy instructions BLD (Bit LoaD) and BST (Bit STore) use the T-bit as source or destination for the operated bit. A bit from a register in the Register File can be copied into T by the BST instruction, and a bit in T can be copied into a bit in a register in the Register File by the BLD instruction. • Bit 5 – H: Half Carry Flag The Half Carry Flag H indicates a Half Carry in some arithmetic operations. Half Carry Is useful in BCD arithmetic. See the “Instruction Set Description” for detailed information. • Bit 4 – S: Sign Bit, S = N

⊕V

The S-bit is always an exclusive or between the Negative Flag N and the Two’s Complement Overflow Flag V. See the “Instruction Set Description” for detailed information. • Bit 3 – V: Two’s Complement Overflow Flag The Two’s Complement Overflow Flag V supports two’s complement arithmetics. See the “Instruction Set Description” for detailed information. • Bit 2 – N: Negative Flag The Negative Flag N indicates a negative result in an arithmetic or logic operation. See the “Instruction Set Description” for detailed information. • Bit 1 – Z: Zero Flag The Zero Flag Z indicates a zero result in an arithmetic or logic operation. See the “Instruction Set Description” for detailed information. • Bit 0 – C: Carry Flag The Carry Flag C indicates a carry in an arithmetic or logic operation. See the “Instruction Set Description” for detailed information.

11 2549A–AVR–03/05

General Purpose Register File

The Register File is optimized for the AVR Enhanced RISC instruction set. In order to achieve the required performance and flexibility, the following input/output schemes are supported by the Register File: •

One 8-bit output operand and one 8-bit result input



Two 8-bit output operands and one 8-bit result input



Two 8-bit output operands and one 16-bit result input



One 16-bit output operand and one 16-bit result input

Figure 5 shows the structure of the 32 general purpose working registers in the CPU. Figure 5. AVR CPU General Purpose Working Registers 7

0

Addr.

R0

0x00

R1

0x01

R2

0x02

… R13

0x0D

General

R14

0x0E

Purpose

R15

0x0F

Working

R16

0x10

Registers

R17

0x11

… R26

0x1A

X-register Low Byte

R27

0x1B

X-register High Byte

R28

0x1C

Y-register Low Byte

R29

0x1D

Y-register High Byte

R30

0x1E

Z-register Low Byte

R31

0x1F

Z-register High Byte

Most of the instructions operating on the Register File have direct access to all registers, and most of them are single cycle instructions. As shown in Figure 5, each register is also assigned a data memory address, mapping them directly into the first 32 locations of the user Data Space. Although not being physically implemented as SRAM locations, this memory organization provides great flexibility in access of the registers, as the X-, Y- and Z-pointer registers can be set to index any register in the file.

12

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561 The X-register, Y-register, and Z-register

The registers R26..R31 have some added functions to their general purpose usage. These registers are 16-bit address pointers for indirect addressing of the data space. The three indirect address registers X, Y, and Z are defined as described in Figure 6. Figure 6. The X-, Y-, and Z-registers 15 X-register

XH

XL

7

0

R27 (0x1B)

YH

YL

7

0

R29 (0x1D)

Z-register

0

R26 (0x1A)

15 Y-register

0

7

0

7

0

R28 (0x1C)

15

ZH

7

0

ZL 7

R31 (0x1F)

0 0

R30 (0x1E)

In the different addressing modes these address registers have functions as fixed displacement, automatic increment, and automatic decrement (see the instruction set reference for details).

Stack Pointer

The Stack is mainly used for storing temporary data, for storing local variables and for storing return addresses after interrupts and subroutine calls. The Stack Pointer Register always points to the top of the Stack. Note that the Stack is implemented as growing from higher memory locations to lower memory locations. This implies that a Stack PUSH command decreases the Stack Pointer. The Stack Pointer points to the data SRAM Stack area where the Subroutine and Interrupt Stacks are located. This Stack space in the data SRAM must be defined by the program before any subroutine calls are executed or interrupts are enabled. The Stack Pointer must be set to point above 0x0200. The initial value of the stack pointer is the last address of the internal SRAM. The Stack Pointer is decremented by one when data is pushed onto the Stack with the PUSH instruction, and it is decremented by three when the return address is pushed onto the Stack with subroutine call or interrupt. The Stack Pointer is incremented by one when data is popped from the Stack with the POP instruction, and it is incremented by three when data is popped from the Stack with return from subroutine RET or return from interrupt RETI. The AVR Stack Pointer is implemented as two 8-bit registers in the I/O space. The number of bits actually used is implementation dependent. Note that the data space in some implementations of the AVR architecture is so small that only SPL is needed. In this case, the SPH Register will not be present. Bit

Read/Write

Initial Value

15

14

13

12

11

10

9

8

SP15

SP14

SP13

SP12

SP11

SP10

SP9

SP8

SPH

SP7

SP6

SP5

SP4

SP3

SP2

SP1

SP0

SPL

7

6

5

4

3

2

1

0

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

0

0

1

0

0

0

0

1

1

1

1

1

1

1

1

1

13 2549A–AVR–03/05

Extended Z-pointer Register for ELPM/SPM - RAMPZ

Bit

7

6

5

4

3

2

1

0

RAMPZ7

RAMPZ6

RAMPZ5

RAMPZ4

RAMPZ3

RAMPZ2

RAMPZ1

RAMPZ0

Read/Write

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

Initial Value

0

0

0

0

0

0

0

0

RAMPZ

For ELPM/SPM instructions, the Z-pointer is a concatenation of RAMPZ, ZH, and ZL, as shown in Figure 7. Note that LPM is not affected by the RAMPZ setting. Figure 7. The Z-pointer used by ELPM and SPM Bit ( Individually)

7

0

7

0

RAMPZ

Bit (Z-pointer)

7

ZH

23

16

0 ZL

15

8

7

0

The actual number of bits is implementation dependent. Unused bits in an implementation will always read as zero. For compatibility with future devices, be sure to write these bits to zero. Extended Indirect Register EIND

Bit

7

6

5

4

3

2

1

0

EIND7

EIND6

EIND5

EIND4

EIND3

EIND2

EIND1

EIND0

Read/Write

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

Initial Value

0

0

0

0

0

0

0

0

EIND

For EICALL/EIJMP instructions, the Indirect-pointer to the subroutine/routine is a concatenation of EIND, ZH, and ZL, as shown in Figure 8. Note that ICALL and IJMP are not affected by the EIND setting. Figure 8. The Indirect-pointer used by EICALL and EIJMP Bit (Individually)

7

Bit (Indirectpointer)

23

0

7

16

15

EIND

0

7

8

7

ZH

0 ZL

0

The actual number of bits is implementation dependent. Unused bits in an implementation will always read as zero. For compatibility with future devices, be sure to write these bits to zero.

Instruction Execution Timing

This section describes the general access timing concepts for instruction execution. The AVR CPU is driven by the CPU clock clkCPU, directly generated from the selected clock source for the chip. No internal clock division is used. Figure 9 shows the parallel instruction fetches and instruction executions enabled by the Harvard architecture and the fast-access Register File concept. This is the basic pipelining concept to obtain up to 1 MIPS per MHz with the corresponding unique results for functions per cost, functions per clocks, and functions per power-unit.

14

ATmega640/1280/1281/2560/2561 2549A–AVR–03/05

ATmega640/1280/1281/2560/2561 Figure 9. The Parallel Instruction Fetches and Instruction Executions T1

T2

T3

T4

clkCPU 1st Instruction Fetch 1st Instruction Execute 2nd Instruction Fetch 2nd Instruction Execute 3rd Instruction Fetch 3rd Instruction Execute 4th Instruction Fetch

Figure 10 shows the internal timing concept for the Register File. In a single clock cycle an ALU operation using two register operands is executed, and the result is stored back to the destination register. Figure 10. Single Cycle ALU Operation T1

T2

T3

T4

clkCPU Total Execution Time Register Operands Fetch ALU Operation Execute Result Write Back

Reset and Interrupt Handling

The AVR provides several different interrupt sources. These interrupts and the separate Reset Vector each have a separate program vector in the program memory space. All interrupts are assigned individual enable bits which must be written logic one together with the Global Interrupt Enable bit in the Status Register in order to enable the interrupt. Depending on the Program Counter value, interrupts may be automatically disabled when Boot Lock bits BLB02 or BLB12 are programmed. This feature improves software security. See the section “Memory Programming” on page 335 for details. The lowest addresses in the program memory space are by default defined as the Reset and Interrupt Vectors. The complete list of vectors is shown in “Interrupts” on page 69. The list also determines the priority levels of the different interrupts. The lower the address the higher is the priority level. RESET has the highest priority, and next is INT0 – the External Interrupt Request 0. The Interrupt Vectors can be moved to the start of the Boot Flash section by setting the IVSEL bit in the MCU Control Register (MCUCR). Refer to “Interrupts” on page 69 for more information. The Reset Vector can also be moved to the start of the Boot Flash section by programming the BOOTRST Fuse, see “Memory Programming” on page 335. When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.

15 2549A–AVR–03/05

There are basically two types of interrupts. The first type is triggered by an event that sets the Interrupt Flag. For these interrupts, the Program Counter is vectored to the actual Interrupt Vector in order to execute the interrupt handling routine, and hardware clears the corresponding Interrupt Flag. Interrupt Flags can also be cleared by writing a logic one to the flag bit position(s) to be cleared. If an interrupt condition occurs while the corresponding interrupt enable bit is cleared, the Interrupt Flag will be set and remembered until the interrupt is enabled, or the flag is cleared by software. Similarly, if one or more interrupt conditions occur while the Global Interrupt Enable bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the Global Interrupt Enable bit is set, and will then be executed by order of priority. The second type of interrupts will trigger as long as the interrupt condition is present. These interrupts do not necessarily have Interrupt Flags. If the interrupt condition disappears before the interrupt is enabled, the interrupt will not be triggered. When the AVR exits from an interrupt, it will always return to the main program and execute one more instruction before any pending interrupt is served. Note that the Status Register is not automatically stored when entering an interrupt routine, nor restored when returning from an interrupt routine. This must be handled by software. When using the CLI instruction to disable interrupts, the interrupts will be immediately disabled. No interrupt will be executed after the CLI instruction, even if it occurs simultaneously with the CLI instruction. The following example shows how this can be used to avoid interrupts during the timed EEPROM write sequence.. Assembly Code Example in cli

r16, SREG

; store SREG value

; disable interrupts during timed sequence

sbi EECR, EEMPE

; start EEPROM write

sbi EECR, EEPE out SREG, r16

; restore SREG value (I-bit)

C Code Example char cSREG; cSREG = SREG;

/* store SREG value */

/* disable interrupts during timed sequence */ __disable_interrupt(); EECR |= (1

Smile Life

When life gives you a hundred reasons to cry, show life that you have a thousand reasons to smile

Get in touch

© Copyright 2015 - 2024 PDFFOX.COM - All rights reserved.