0% encontró este documento útil (0 votos)
98 vistas140 páginas

Tesis Audiometro Con Raspberry Pi

El proyecto describe el diseño e implementación de un audiómetro utilizando una Raspberry Pi. Un audiómetro mide el umbral de audición de una persona mediante tonos puros. El proyecto reproduce tonos puros en diferentes frecuencias controlados por una aplicación en un teléfono móvil a través de UDP. La Raspberry Pi reproduce los tonos a través de auriculares calibrados. La aplicación móvil muestra los resultados de la audiometría y permite enviar un informe por correo electrónico. El sistema cumple con los estándares requer

Cargado por

carlos figueroa
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
98 vistas140 páginas

Tesis Audiometro Con Raspberry Pi

El proyecto describe el diseño e implementación de un audiómetro utilizando una Raspberry Pi. Un audiómetro mide el umbral de audición de una persona mediante tonos puros. El proyecto reproduce tonos puros en diferentes frecuencias controlados por una aplicación en un teléfono móvil a través de UDP. La Raspberry Pi reproduce los tonos a través de auriculares calibrados. La aplicación móvil muestra los resultados de la audiometría y permite enviar un informe por correo electrónico. El sistema cumple con los estándares requer

Cargado por

carlos figueroa
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA

Y SISTEMAS DE TELECOMUNICACIÓN

PROYECTO FIN DE GRADO

TÍTULO: “Diseño e implementación de un audiómetro con


Raspberry Pi”

AUTOR: Víctor Manuel Díaz Conejo

TITULACIÓN: Grado en Ingeniería de Sonido e Imagen

TUTOR: Antonio Mínguez Olivares

DEPARTAMENTO: Ingeniería Audiovisual y Comunicaciones

VºBº

Miembros del Tribunal Calificador:

PRESIDENTE: Eduardo Nogueira Díaz

TUTOR: Antonio Mínguez Olivares

SECRETARIO: Jorge Grundman Isla

Fecha de lectura: 25 de Julio de 2019

Calificación:

El Secretario,
Diseño e implementación de un audiómetro con Raspberry Pi
Resumen

Resumen

El proyecto lleva como título diseño e implementación de un audiómetro con Raspberry


Pi, el desarrollo del mismo se resume a continuación.

En primer lugar se ha de explicar qué es un audiómetro. Un audiómetro es un aparato de


medida cuya funcionalidad consiste en establecer el umbral de audición de la persona
que es sometida a la prueba. Esta evaluación lleva por nombre audiometría, y consiste
en pruebas subjetivas para evaluar la pérdida de audición de la persona que se somete a
ella. Dichos ensayos audiométricos han de cumplir la normativa ISO 8253, la cual
indica cómo se ha de proceder en los mismos: la disposición del oyente, la cualificación
del operario que realiza la medición, las condiciones en el entorno para que este ensayo
sea realizado, la incertidumbre de estas medidas, cómo se han de preparar la
instrumentación sometida a ensayo, la lectura de los audiogramas, el ruido ambiente
admitido, etc. En el caso del proyecto diseñado, las audiometrías se realizarán por
conducción aérea y la señal de ensayo serán tonos puros. Las frecuencias a evaluar son
las llamadas frecuencias convencionales (FC), que son las octavas que van desde 125Hz
a 8 kHz. La norma ISO 7029 establece una distribución estadística de los umbrales de
audición, pero para este proyecto se han utilizado los umbrales de audición obtenidos de
la tesis doctoral de Antonio Rodríguez Valiente [1], que son clasificados, al igual que la
norma anteriormente mencionada, en función de la edad, el sexo, pero son pruebas en lo
referente a la población española. Dichas curvas establecen los umbrales de audición en
niveles SPL dB. Por umbral de audición se entiende como el nivel mínimo de presión
sonora necesario para ser detectado por un oyente, en ausencia de otros sonidos. Dicho
umbral depende de diversas características del sonido que se emite y del receptor que lo
oye.

En lo referente a audiómetros, el equipo ha de cumplir la norma UNE-EN 60645-1, la


cual habla de requisitos relacionados con la respuesta en frecuencia, la distorsión
armónica, la relación señal a ruido, los niveles de presión, etc. A su vez, se diferencian
cuatro tipos de audiómetros, el audiómetro a implementar en este proyecto, es el de tipo
2. Los requisitos de este tipo de audiómetro se ajustan mejor a los objetivos de este
proyecto.

Para el desarrollo del mismo se ha utilizado la placa de desarrollo Raspberry Pi 3 B+


[2], a la que por medio de los pines GPIO (General Purpose Input/Output) se ha
añadido la tarjeta de sonido estéreo Audio injector [3]. En dicha placa está embebido el
sistema operativo Raspbian de Mathworks. En dicho sistema se encuentra instalada la
aplicación del audiómetro, que ha sido diseñada desde MATLAB/Simulink. Dicha
aplicación permite recibir vía UDP (User Datagram Protocol) las directrices necesarias
para hacer una correcta audiometría, es decir, son la selección del tono de frecuencia
que se desea ser emitido, el nivel del mismo y el canal por el que se desea transmitir.
Página 1
Diseño e implementación de un audiómetro con Raspberry Pi
Resumen

Estas órdenes llegan a un código implementado en MATLAB (System object) que lo


procesa y lo ejecuta. Como salida del sistema referente a la Raspberry Pi se encuentran
los auriculares DD45, que cumplen los requisitos para realizar estas medidas,
habiéndose sido calibrados previamente. Estos son conectados a la tarjeta de sonido por
medio del conector de auriculares (headphones).

La interfaz que ayuda al operario a comunicarse con el oyente es un teléfono móvil, con
sistema operativo Android 9, en él está instalada la aplicación que permite al operario
modificar los parámetros antes mencionados, así como ver representada en forma de
gráfica el umbral de audición del oyente (una vez haya terminado la prueba) junto a la
curva típica según su edad y sexo. Una vez finalizada la audiometría, se podrá obtener
un informe detallado de los resultados de la prueba, en ambos canales, y ser enviado al
paciente vía correo electrónico a la dirección que haya indicado en la aplicación. El
lenguaje de programación utilizado para el diseño de esta aplicación es Java, y XML
(eXtensible Markup Language) para la interfaz gráfica.

Como ha sido citado anteriormente, el protocolo de comunicación entre estos dos


equipos es el protocolo UDP. Para que haya comunicación entre ambos estos han de
estar en la misma red. Es por ello por lo que se crea desde el teléfono móvil un punto de
acceso inalámbrico (wireless access point, WAP), dando lugar a una red privada entre el
dispositivo móvil y la Raspberry Pi. Es necesario asignar previamente una dirección IP
estática a la Raspberry, para poder así crear un socket y comunicar ambos dispositivos.
Una vez creada esta comunicación se procede al envío de datagramas desde el teléfono
a la Raspberry con la información del canal, la frecuencia y el nivel. Esta procesa dicha
información de forma continua y a tiempo real, y se lo transmite a la tarjeta de sonido
para ser reproducida. Tras evaluar todas las frecuencias y canales se obtendrá el
resultado de la audiometría.

En lo referente al presupuesto del mismo es de 205,94€, de los cuales el alumno ha


asumido 63,26€ y el resto son artículos aportados por la Universidad Politécnica de
Madrid (UPM).

Los resultados de las audiometrías realizadas, filtradas por edad y sexo, tienen gran
correlación con los umbrales de audición medios, de acuerdo a esos parámetros.

Página 2
Diseño e implementación de un audiómetro con Raspberry Pi
Abstract

Abstract

The project has the title of design and implementation of an audiometer with Raspberry
Pi, the development of that it is summarized below.

At first, it has to be explained what is an audiometer. An audiometer is a measurement


device. This evaluation is called audiometry, and it can measure the threshold of hearing
of a person with subjective tests. These audiometric tests must comply with ISO 8253
standard, which indicates how to proceed: the position of the listener, the qualification
of the operator who has to performance the measurement, the weather conditions for
this test to be carried out, the uncertainty of these measurements, how to prepare the
instrumentation, the reading of the audiograms, the accepted ambient noise, etc. In the
case of the designed project, the audiometries will be performed by air conduction and
the test signal will be pure tones. The frequencies to be evaluated are called
conventional frequencies, which are the octaves ranging from 125Hz to 8 kHz. The ISO
7029 standard establishes a statistical distribution of the hearing thresholds, but for this
project it has used the hearing threshold obtained from the doctoral thesis of Antonio
Rodríguez Valiente [1], which are classified, as the previous norm, based on age, sex,
but they are tests in relation to the Spanish people only. These curves establish the
hearing thresholds in SPL dB levels. The threshold of hearing is understood as the
minimum level of sound pressure necessary to be detected by a listener, in absence of
the other sounds. This threshold depends on various characteristics of the sound that is
emitted, and the receiver that listen it.

Regarding audiometers, the system has to comply with UNE-EN 60645-1 standard,
which determined the requirements related with frequency response, harmonic
distortion, signal to noise ratio, pressure levels, etc. In this norm talks about four types
of audiometers, the audiometer to be implemented in this project is type 2. The
requirements of this type are better adjusted to the objectives of this project.

To the development of this audiometer has been used the single-board computer of
Raspberry Pi 3 B+ [2], which by GPIO (General Purpose Input/Output) pins has been
added the stereo sound card Audio Injector [3]. The Raspbian operating system of
Mathworks is embedded in this board. In this system is installed the audiometer
application, which has been designed from MATLAB/Simulink. This application allows
receiving via UDP (User Datagram Protocol) the necessary guidelines to make a correct
audiometry. These are the selection of the frequency of the tone, the level of the same
one and the channel by which it is desired to transmit. These parameters arrive at a code
implemented in MATLAB (System object) that processes it and executes it. As output
of the Raspberry system is the DD45 headphones, these complies the requirements to
realize these measurements, having been previously calibrated (by an ear simulator).
These are connected to the sound card by means of the headphone jack.

Página 3
Diseño e implementación de un audiómetro con Raspberry Pi
Abstract

The interface that helps the user to communicate with the listener is a mobile phone,
with Android 9 operating system, in this mobile phone it is installed the application
which permit to the technician change the parameters (previous mentioned), as well as
seeing the listener‟s hearing threshold (once the test is finished) represented next to the
typical curve according to age and sex. Once the audiometry is finished, the user can
obtain the results of the test, in both channels, and sent to the patient via email (to the
address indicated in the application). The programming language used for the design of
this application is Java, and XML (eXtensible Markup Language) for the graphic
interface.

As mentioned above, the communication protocol between these two devices is the
UDP protocol. In order to be communicate this devices, they have to be in the same
network. This is the reason about a WAP (Wireless Access Point) is created from the
mobile phone, allowing a private network between the mobile device and the Raspberry
Pi. It is necessary previously to assign a static IP address to the Raspberry, in order to
create a socket and communicate both devices. Once this communication is created,
datagrams are sent from the phone to the Raspberry with the channel, frequency and
level information. It processes this information continuously and in real time, and
transmits it to the sound card to be reproduced. At the end, after evaluating all the
frequencies and channels, the result of the audiometry will be obtained.

With regard to the Budget of the Project is 205.94€, of which the student has paid
63.26€ and the rest are articles contributed by Universidad Politécnica de Madrid
(UPM).

The results of the audiometries performed, filter by age and sex, have a high correlation
with the average hearing thresholds, according to these parameters.

Página 4
Diseño e implementación de un audiómetro con Raspberry Pi
Índice

Índice:

Resumen ........................................................................................................................... 1
Abstract ............................................................................................................................. 3
Índice: ............................................................................................................................... 5
Índice de figuras ............................................................................................................... 7
Índice de tablas ............................................................................................................... 10
Lista de acrónimos .......................................................................................................... 11
Introducción .................................................................................................................... 12
Objetivos......................................................................................................................... 14
Audiómetro ..................................................................................................................... 15
Definición .............................................................................................................. 15
Normativa.............................................................................................................. 17
Requisitos generales................................................................................ 18
Requisitos de seguridad .......................................................................... 19
Requisitos de la señal de ensayo ............................................................. 19
Transductores .......................................................................................... 21
Calibración ............................................................................................................ 21
Manual de instrucciones ........................................................................................ 24
Audiometría .................................................................................................................... 25
Definición .............................................................................................................. 25
Normativa.............................................................................................................. 26
Preparación de la audiometría ................................................................. 28
Determinación del umbral de audición, en condución aérea, por
audiometría de frecuencias fijas.............................................................. 28
Procedimiento de ensayo sin enmascaramiento ...................................... 29
Audiometría de reconocimiento .............................................................. 29
Audiograma............................................................................................. 30
Ruido ambiente admisible....................................................................... 30
Mantenimiento del equipo audiométrico ................................................ 30
Problemas médicos ......................................................................................................... 32
Umbrales de audición ..................................................................................................... 34
Marco tecnológico y recursos ......................................................................................... 39

Página 5
Diseño e implementación de un audiómetro con Raspberry Pi
Índice

Diseño e implementación del proyecto .......................................................................... 41


Diagrama de bloques ............................................................................................. 41
Creación del punto de acceso ................................................................................ 42
Diagrama de red .................................................................................................... 43
Raspberry Pi ................................................................................................................... 45
Raspberry Pi 3 Modelo B+.................................................................................... 45
MATLAB/Simulink .............................................................................................. 47
Configuración de la Raspberry.............................................................................. 48
Comunicación con MATLAB/Simulink. .............................................................. 51
Tarjeta de sonido estéreo Audio Injector .............................................................. 53
Características de la tarjeta de sonido estéreo de Audio Injector ........... 54
Aplicación: Audiómetro ........................................................................................ 57
Teléfono móvil con Android .......................................................................................... 70
Android y Huawei P20 Lite .................................................................................. 70
Configuración comunicación con entorno de programación ................................ 72
Aplicación: Audiómetro ........................................................................................ 73
Manual de usuario .......................................................................................................... 81
Resultados....................................................................................................................... 87
Presupuesto ..................................................................................................................... 89
Conclusiones................................................................................................................... 90
Referencias ..................................................................................................................... 92
Anexos ............................................................................................................................ 94
Anexo 1: Código AndroidManifest.xml ............................................................... 94
Anexo 2: Código String.xml ................................................................................. 95
Anexo 3: MainActivity ......................................................................................... 97
Anexo 4: SectionPagerAdapter ........................................................................... 101
Anexo 5: FragmentDatos .................................................................................... 102
Anexo 6: FragmentAudiometria ......................................................................... 108
Anexo 7: UDPClientThread ................................................................................ 115
Anexo 8: FragmentGrafica .................................................................................. 118
Anexo 9: PdfManager ......................................................................................... 131

Página 6
Diseño e implementación de un audiómetro con Raspberry Pi
Índice de figuras

Índice de figuras

Figura 1 – Oido artificial (izq), Instrumento de medida (der) ........................................ 21

Figura 2 – Calibración del instrumento de medida......................................................... 22

Figura 3 – Auriculares DD45 - TDH39 .......................................................................... 22

Figura 4 – Calibración auriculares.................................................................................. 23

Figura 5 – Distorsión armónica a 1 kHz ......................................................................... 23

Figura 6 – Curvas isofónicas Norma ISO 226 [7] .......................................................... 33

Figura 7 - Media del umbral de audición para hombres ................................................. 36

Figura 8 - Muestra la media del umbral de audición para mujeres ................................ 38

Figura 9 - Diagrama de bloques ..................................................................................... 42

Figura 10 – Zona Wi-Fi .................................................................................................. 42

Figura 11 – Configuración zona Wi-Fi .......................................................................... 43

Figura 12 - Diagrama de red ........................................................................................... 44

Figura 13 – Logo Raspberry Pi [8] ................................................................................. 45

Figura 14 – Raspberry Pi 3 Modelo B+ [2] .................................................................... 46

Figura 15 – Raspberry Pi 3 B+ características ............................................................... 47

Figura 16 – Logo MATLAB [9] ..................................................................................... 47

Figura 17 – Paquetes a instalar en MATLAB ................................................................ 48

Figura 18 – Descarga del sistema operativo ................................................................... 49

Figura 19 – Configuración de red en la Raspberry (A) .................................................. 49

Figura 20 - Configuración de red en la Raspberry (B) ................................................... 50

Figura 21 - Configuración de red en la Raspberry (C) ................................................... 50

Figura 22 – Logo PuTTY ............................................................................................... 51

Figura 23 ......................................................................................................................... 51

Página 7
Diseño e implementación de un audiómetro con Raspberry Pi
Índice de figuras

Figura 24 – Fichero: /etc/network/interfaces .................................................................. 52

Figura 25 – Fichero: /etc/wpa_supplicant/wpa_supplicant.conf .................................... 52

Figura 26 – Tarjeta de sonido estéreo Audio Injector [3] .............................................. 53

Figura 27 – Pines GPIO Raspberry Pi 3 B + [10] .......................................................... 54

Figura 28 – Fichero: /boot/config.txt.............................................................................. 56

Figura 29 - AlsaMixer .................................................................................................... 57

Figura 30 – Aplicación Audiómetro en Simulink .......................................................... 58

Figura 31 – Audiómetro: Comunicación con Android ................................................... 59

Figura 32 – Audiómetro: Configuración bloque UDP ................................................... 60

Figura 33 – Audiómetro: Generación del tono ............................................................... 60

Figura 34 – Audiómetro: System object ......................................................................... 61

Figura 35 – Audiómetro: Bloque Matrix Concatenate ................................................... 63

Figura 36 – Audiómetro: Salida AudioInjector .............................................................. 64

Figura 37 – Audiómetro: Bloque Ganancia .................................................................... 64

Figura 38 – Audiómetro: Bloque Data Type Conversion .............................................. 65

Figura 39 – Audiómetro: Bloque ALSA Audio Playback .............................................. 65

Figura 40 – Audiómetro: Control LED .......................................................................... 66

Figura 41 – Audiómetro: Bloque Generador de Pulsos .................................................. 66

Figura 42 – Audiómetro: Bloque Data Type Conversion .............................................. 67

Figura 43 – Audiómetro: Bloque LED ........................................................................... 67

Figura 44 – Audiómetro: Osciloscopio .......................................................................... 68

Figura 45 – Audiómetro: Analizador en tiempo ............................................................. 68

Figura 46 – Audiómetro: Analizador de espectros ......................................................... 69

Figura 47 – Logo Android .............................................................................................. 70

Página 8
Diseño e implementación de un audiómetro con Raspberry Pi
Índice de figuras

Figura 48 – Huawei P20 Lite [12] .................................................................................. 71

Figura 49 – Android Studio [13] .................................................................................... 72

Figura 50 – Depuración aplicación Android .................................................................. 72

Figura 51 – Permisos depuración aplicación desde Android ......................................... 73

Figura 52 – Directorio de la aplicación Audiometría en AndroidStudio ....................... 75

Figura 53 – Configuración zona Wi-Fi .......................................................................... 81

Figura 54 – Ubicación aplicación Audiómetro............................................................... 82

Figura 55 – Confirmación permisos de lectura/escritura ............................................... 83

Figura 56 – Pestaña “DATOS” ....................................................................................... 83

Figura 57 – Pestaña “CONFIGURACIÓN AUDIOMETRÍA” ...................................... 84

Figura 58 – Pestaña “CONFIGURACIÓN AUDIOMETRÍA”, creación de gráfica ..... 85

Figura 59 – Pestaña “RESULTADO” ............................................................................ 85

Figura 60 – Envío de los resultados de la audiometría ................................................... 86

Figura 61 – Datos del oyente .......................................................................................... 87

Figura 62 – Resultados del oyente canal izquierdo ........................................................ 87

Figura 63 – Resultados del oyente canal derecho........................................................... 88

Página 9
Diseño e implementación de un audiómetro con Raspberry Pi
Índice de figuras

Índice de tablas

Tabla 1 – Requisitos de los diferentes tipos de audiómetros .......................................... 18

Tabla 2 – Rango mínimo de valores de nivel ................................................................. 20

Tabla 3 – Condiciones distorsión armónica total ........................................................... 20

Tabla 4 – Valores nominales para 110 dB ...................................................................... 23

Tabla 5 – Distorsión armónica total ............................................................................... 24

Tabla 6 – Umbral de audición sexo masculino............................................................... 35

Tabla 7 – Umbral de audición sexo femenino ................................................................ 37

Tabla 8 – Características Raspberry Pi 3 B+ .................................................................. 46

Tabla 9 – Características de la tarjeta de sonido estéreo Audio Injector ........................ 55

Tabla 10 – Característica Huawei P20 Lite .................................................................... 71

Tabla 11 – Presupuesto ................................................................................................... 89

Página 10
Diseño e implementación de un audiómetro con Raspberry Pi
Índice de tablas

Lista de acrónimos

Frecuencias Convencionales - FC

General Purpose Input/Output - GPIO

User Datagram Protocol - UDP

eXtensible Markup Language - XML

Wireless Access Point - WAP

Extended-High Frequencies - EHF

Extensión en Altas Frecuencias - EAF

Organización Mundial de la Salud – OMS

World Health Organization - WHO

Desviación Estándar - DE

Intervalo de Confianza - IC

Secure SHell - SSH

Service Set Identifier - SSID

Central Processing Unit - CPU

Light-Emitting Diode - LED

Portable Document Format - PDF

MATrix LABoratory - MATLAB

Hardware Attached on Top - HAT

Media Access Control - MAC

Página 11
Diseño e implementación de un audiómetro con Raspberry Pi
Introducción

Introducción

El proyecto se enmarca en un contexto social de creciente preocupación por la


contaminación acústica, esta provoca daños importantes en la salud, entre ellos la
pérdida de capacidad auditiva en la población, al estar expuesta en muchas ocasiones a
altos niveles de ruido constante. El ruido es conocido como el contaminante silencioso,
pues cuando la fuente que lo genera cesa su actividad, la contaminación desaparece, es
por ello, entre otras cosas, que la población tiende a no estar tan concienciada. A pesar
de ello, y como ejemplo de la importancia de esta fuente de contaminación, la
Organización Mundial de la Salud situó en seis grandes ciudades europeas al ruido del
tráfico como el segundo factor más importante en términos de impacto en la salud
pública en estas ciudades.

Por medio de las administraciones públicas se intenta reducir los graves y peligrosos
efectos que tiene la contaminación acústica sobre la salud personas; una de las
principales medidas es limitar los niveles de ruido generados por ciertas actividades a
través de legislaciones que limitan el ruido permitido, teniendo en cuenta diversos
factores sociales y laborales. Del mismo modo se otorgan subvenciones para mejorar el
aislamiento en los hogares que se enfrentan a diario a altos niveles de contaminación
acústica, los cuales no pueden ser paliados de otro modo ya que no pueden ser a penas
limitados.

En lo referente al marco tecnológico, se enmarca dentro de un contexto de continua


evolución y desarrollo, con posibilidades infinitas. En este nuevo espacio, la Fundación
Raspberry Pi [4] crea un controlador de bajo coste, con funcionalidades muy diversas,
un tamaño muy reducido, y alta funcionalidad y escalabilidad para el usuario. En esta
placa base pueden ser implementadas infinitas aplicaciones prácticas, con un coste muy
reducido.

El proyecto nace de la idea del desarrollo de aplicaciones de audio sobre la


tarjeta de Raspberry Pi. Dado la versatilidad y escalabilidad de la misma no pondrá esta
ninguna restricción a casi cualquiera de las aplicaciones que se escoja.

Haciéndose eco de la relación directa entre la sensibilidad auditiva en la ciudadanía y su


calidad de vida, la importancia de estas, y de la posibilidad que otorgan las nuevas
tecnologías, como es el caso ya mencionado de Raspberry Pi, se procede a implementar
un dispositivo medidor, de bajo coste, que pueda servir al usuario, a ciertas
instituciones, o centros de salud con bajo presupuesto, a controlar la perdida
sensibilidad auditiva del paciente; este medidor es conocido como Audiómetro. La
implementación del mismo ha de respetar las normativas europeas y nacionales
referentes a este tipo de medidores. En estas se distinguen diferentes tipos de
Audiómetro, diferenciándolos entre diversas características que se explicarán a
continuación. En concreto, se ha desarrollado bajo estas características un Audiómetro
tipo 2.
Página 12
Diseño e implementación de un audiómetro con Raspberry Pi
Introducción

Este proyecto se define en cinco grandes bloques, el primero trata acerca de los
audiómetros, su normativa y restricciones, a continuación se menciona en qué consiste
una audiometría y cómo esta ha de ser realizada, de acuerdo a la normativa relacionada
con la ejecución de las mismas. El segundo bloque trata de la implementación del
audiómetro, defición y comunicación entre todos los componentes del proyecto. El
tercer bloque trata sobre el desarrollo de la aplicación en la Raspberry Pi, las
características de la misma, la aplicación desarrollada en ella, su salida y comunicación
con el paciente. El cuarto bloque aborda la comunicación con este controlador, que se
hace a través de una aplicación desde un teléfono móvil con el sistema operativo
Android. Por último, se muestran las audiometrías realizadas a diversos oyentes para
comprobar el correcto funcionamiento del audiómetro. Se finaliza la memoria con una
conclusión acerca del desarrollo del proyecto.

Página 13
Diseño e implementación de un audiómetro con Raspberry Pi
Objetivos

Objetivos

El objetivo principal del proyecto es el diseño e implementación de un audiómetro de


diagnóstico (tipo II) sobre Raspberry-Pi, respetando las normativas correspondientes al
diseño de los mismos (UNE-EN 60645-1). Se tratará de un sistema autónomo, capaz de
generar y reproducir las señales auditivas al usuario, previamente seleccionadas por el
técnico que esté guiando la audiometría. Las frecuencias con las que trabajará serán las
frecuencias convencionales, las octavas de 125 Hz a 8 kHz, seleccionado el canal de
ensayo.

Para realizar este objetivo, se implementa una aplicación sobre el sistema operativo
embebido en la Raspberry-Pi, la cual permitirá seleccionar el canal de trabajo, la
frecuencia y el nivel del tono.

A su vez, se diseñará una interfaz entre el técnico que realiza la audiometría y el


sistema. Esta debe permitir seleccionar los parámetros de principal interés en este
sistema, como son: el canal, la frecuencia y el nivel. Ha de ser de fácil uso y permitir
dar por acabado el test audiométrico, obteniendo el resultado del mismo, respetando la
normativa referente a las audiometrías realizadas con este tipo de audiómetro (UNE-EN
ISO 8253-1).

Para la comunicación entre estos dispositivos se creará una red inalámbrica entre estos
dispositivos desde un teléfono móvil, de fácil implementación y que el usuario pueda
activar de una manera simple, sin necesidad de ser reconfigurada una vez haya sido
diseñada.

Aparte de lo indicado anteriormente, también se hará uso de una tarjeta de sonido sobre
la Raspberry-Pi que permitirá gestionar las salidas y demás funcionalidades de audio.

Página 14
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

Audiómetro

Definición
Un audiómetro es un instrumento que sirve para medir la audición de un oyente.
Mediante la repetición de pruebas subjetivas se conocerá el límite para el cual el oyente
deja de percibir un sonido. A esto se le llama umbral de audición, se tratará sobre ello
más adelante. Las pruebas que delimitan el umbral de umbral de audición son conocidas
como audiometrías.

En lo referente a la materia que se va a tratar hay varios términos que han de ser
conocidos para poder ser tratados posteriormente, todos ellos han sido obtenidos
directamente de la normativa UNE-EN 60645-1 [5]:

- Audiometría de tonos puros:


Instrumento para la medición de la audición para tonos puros y en particular
del umbral de audición.
- Audiómetro manual:
Audiómetro en el que la representación de las señales y el registro de los
resultados se realizan manualmente.
- Audiómetro de registro automático:
Audiómetro en el que la presentación de las señales, la variación del nivel de
audición, la selección o la variación de la frecuencia y el registro de las
respuesta de los sujetos se realizan automáticamente.
- Audiómetro para audiometría vocal:
Instrumento para medición de la audición para material de ensayo vocal.
- Conducción aérea:
Transmisión del sonido a través del oído externo y medio al oído interno.
- Conducción ósea:
Estimulación del oído interno por mediación principalmente de la vibración
mecánica de los huesos del cráneo.
- Alta frecuencia extendida; EHF:
Frecuencia de ensayo audiométrico en el rango de 8 000 Hz a 16 000 Hz.
- Persona otológicamente normal:
Persona en un estado de salud normal que esté libre de todos los signos y
síntomas de enfermedades del oído y de cera que obstruya el canal auditivo y
que no tenga antecedentes de exposición indebida al ruido, a fármacos
potencialmente ototóxicos, o de una pérdida hereditaria de audición.
- Nivel de presión acústica umbral equivalente; escucha monoaural con
auricular:
Para un oído dado, a una frecuencia especificada, para un tipo de auricular
especificado y para una fuerza de aplicación del auricular al oído humano
establecida, el nivel de presión acústica generado por el auricular en un
simulador de oído o en un acoplador acústico especificado cuando el auricular

Página 15
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

se activa por aquella señal eléctrica de entrada que, con el auricular aplicado
al oído implicado, correspondería al umbral de audición.
- Nivel de presión acústica umbral equivalente de referencia; RETSPL:
A una frecuencia concreta, el valor medio, modal o mediana de los niveles de
presión acústica equivalentes de un número suficientemente grande de oídos de
personas otológicamente normales de uno y otro sexo de edades entre 18 y 25
años inclusive, expresando el umbral de audición en un simulador de oído o en
un acoplador acústico para un tipo de auriculares determinado.
- Nivel de fuerza umbral equivalente de referencia; RETFL:
A una frecuencia especificada, el valor medio de los niveles de fuerza umbral
equivalentes de un número suficientemente grande de oídos de personas
otológicamente normales, de uno y otro sexo, con edades entre los 18 años y los
25 años inclusive, expresando el umbral de audición en un acoplador mecánico
especificado, para una configuración especificada del vibrador óseo.
- Nivel de audición de un tono puro; HL:
A una frecuencia especificada, para un tipo de transductor específico y para
una manera de aplicación especificada, el nivel de presión acústica o el nivel de
fuerza vibratoria generado por el transductor en un simulador de oído,
acoplador acústico o acoplador mecánico especificados, menos el RETSPL o el
RETVFL apropiado.
- Nivel umbral de audición para tonos puros:
A una frecuencia especificada, el umbral de audición a esa frecuencia
expresado como nivel de audición.
- Simulador de oído:
Dispositivo para medir la salida acústica de fuentes de sonido donde la presión
acústica se mide mediante un micrófono calibrado acoplado a la fuente de
forma que la impedancia acústica total del dispositivo se aproxima a la de un
oído humano normal en una localización dada y en una banda de frecuencias
dada.
- Enmascaramiento:
Proceso mediante el cual el nivel de audición de un sonido se eleva por la
presencia de otro sonido (enmascarante).
- Nivel de enmascaramiento efectivo:
Nivel de un sonido enmascarante especificado que es numéricamente igual a
aquél nivel de audición al que el umbral de tono de la persona normal ideal se
elevaría por la presencia de ese sonido enmascarante.

Una vez se han descrito diferentes conceptos básicos para tratar el tema que nos ocupa
nos podemos centrar en la realización del audiómetro y en los requisitos básicos que
este debe tener.

Para adentrarnos en esta materia hay que citar en un primer lugar que se va a
implementar un audiómetro de tipo 2, destinado a realizar audiometrías por vía aérea de

Página 16
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

tonos puros, en el rango de frecuencias de las frecuencias comprendidas entre el rango


de frecuencias que van desde 125 Hz a 8 kHz, respetando la normativa relacionada con
dichos audiómetros. Dicha normativa es la UNE-EN 60645. Esta normativa consta de 7
partes, cada una de ellas destinadas a un tipo de audiómetro, por ejemplo la parte dos es
destinada a equipos para la audiometría vocal, la parte tres a equipos con señales de
ensayo de duración corta, la cuatro sobre equipos para la audiometría de alta frecuencia
extendida, etc. Para el objetivo de este proyecto se realizará respetando la normativa
UNE-EN 60645 - Parte 1, “Equipos para la audiometría de tonos puros”, la cual se
procede a explicar a continuación.

Las frecuencias comprendidas entre 9.000 Hz y 20.000 Hz son conocidas como


frecuencias extendidas (Extended-High Frequencies, EHF). En castellano se suele
utilizar el término extensión en altas frecuencias (EAF). Este sonómetro no trabaja con
estas frecuencias, y generalmente son muy poco utilizadas, casi siempre a nivel
experimental. Aunque son de utilidad en la detección precoz de ciertas patologías que
desembocan en un pérdida de audición [1].

Normativa
La norma UNE-EN 60645-1 cubre los requisitos para los audiómetros de tonos puros.
Esta norma describe el equipo que está diseñado para las mediciones de la audición en
el rango de frecuencias de 125 Hz a 16 000 Hz (el margen de frecuencias para el equipo
que se desarrollará es, sin la alta frecuencia extendida, únicamente las octavas que van
desde 125 Hz a 8 000 Hz.). Los objetivos primordiales de esta norma son dos: que los
ensayos de audición realizados en el rango de frecuencias mencionado, en un oído
humano, realizados con audiómetros diferentes que cumplan esta normativa, den
resultados sustancialmente iguales; y el otro objetivo es que los resultados obtenidos
representen una comparación válida entre la audición del oído ensayado y el umbral de
audición de referencia [5].

Esta norma especifica cuatro tipos diferentes de audiómetros, en este proyecto se


implementa un audiómetro tipo 2. En la tabla 1 se compara los requisitos para los
diferentes tipos de audiómetros. En el caso del audiómetro implementado, este se desvía
de la norma en algunas cosas específicas que serán citadas a continuación.

- Dicho audiómetro no tiene implementado ninguna opción de realización de


audiometrías por conducción ósea.
- El audiómetro implementado no trabaja con ruido enmascarante de banda
estrecha.
- No posee entrada para señales externas.
- Tampoco dispone de un sistema de comunicación verbal con el sujeto,
haciéndose esta de forma visual entre el operario y el oyente. No resultó de

Página 17
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

interés desarrollarlo, aunque esta puede ser desarrollada con facilidad en el caso
de que en un futuro quiera implementarse.
- Del mismo modo que el anterior punto, la respuesta por parte del sujeto ha de
ser visual.

Tabla 1 – Requisitos de los diferentes tipos de audiómetros


Tipo 1 Tipo 3
Tipo 2 Tipo 4
Equipamiento Clínico/Investigación Diagnóstico
Clínico Exploración/monitorizado
avanzado básico
X
Conducción aérea dos
También con auricular X X X
auriculares
de inserción adicional

Conducción ósea X X X

Niveles de audición y
frecuencias de ensayo

Ruido enmascarante de
X X X
banda estrecha

Entrada para señales


X X
externas
Conmutación de tonos: X
- Presentación de tono. Sin interrupción
X X X
- Interrupción de tono de tono, ni tono
- Tono pulsado. pulsado.
X
Vía del enmascaramiento: También auricular
X X
Auricular contralateral ipsilateral y vibrador
óseo.
X
Tono de referencia:
También presentación X
Presentación alternante
simultanea
Sistema de respuesta del
X X X X
sujeto

Salida de señal eléctrica X X

Indicador de señal X X

Monitorización audible de
X
la señal de ensayo
X
X
Comunicación verbal Solo operado al
Bidireccional
oyente
NOTA: El rango de alta frecuencia extendido es opcional para los cuatro tipos de audiómetros

Requisitos generales

Se ha de profundizar en la normativa, y en cada apartado de la tabla 1, para así


comprender cuáles son las cualidades básicas que ha de tener dicho audiómetro.

Lo referente de la normativa a la fuente de señal externa y al ruido enmascarante no son


mencionados pues no han sido implementados.

Página 18
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

Requisitos de seguridad

Como requisitos de seguridad, la normativa UNE- EN 60645-1 indica que en lo


referente a temas acústicos, se ha de avisar al operador en la interfaz que él maneja que
cuando el nivel de audición generado se encuentra por encima de los 100 dB SPL puede
causar daños auditivos permanentes en el oyente.

En lo referente a las condiciones ambientales ha de encontrarse dentro del rango de


temperatura de 15ºC a 35ºC, de humedad relativa dentro del rango del 30% al 90% y de
presión ambiental dentro del rango de 98 kPa a 104 kPa.

Se deben indicar los valores reales de estos parámetros ambientales en el momento de la


calibración del equipo. En el momento de las calibraciones se han realizado estas en las
condiciones habituales del laboratorio, cumpliendo los límites indicados en la
normativa.

La norma también indica que si el suministro eléctrico del audiómetro es por red
eléctrica, como es el caso, si se produce cualquier interrupción del suministro eléctrico
de hasta 5s, el audiómetro debe revertir a una condición que ni pondrá en peligro la
audición del sujeto, ni dará lugar a resultados no válidos. Esto se cumplirá siempre en el
caso del audiómetro implementado en este proyecto, ya que el control de esto se realiza
por medio de una interfaz con una batería portátil. Las salas de ensayo para los ensayos
subjetivos deben cumplir con los requisitos relacionados con el ruido de fondo, en la
sección de Audiometría.

También indica que el operario ha de ser incapaz de realizar ningún cambio no


intencionado de la calibración del audiómetro por medio de cualquier interfaz. Dicha
característica también la cumple el audiómetro diseñado.

Requisitos de la señal de ensayo

En lo referente a las señales de ensayo ha de cumplirse varias especificaciones en el tipo


de audiómetro diseñado. En la tabla 2 se muestra el rango mínimo de valores del nivel
según la frecuencia de audición para audiómetros de frecuencias fijas. El valor mínimo
debe ser de -10 dB SPL o inferior.

La exactitud del nivel de audición debe ensayarse al menos a 1kHz en un simulador de


oído establecido. En el caso del sonómetro implementado se ha ensayado en el
simulador de oído para todas las frecuencias de trabajo. Se cita esto en el apartado de
calibración de la memoria.

Página 19
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

En lo referente a la exactitud en la frecuencia, para los audiómetros de frecuencias fijas,


la normativa permite ciertas tolerancias. La frecuencia ha de ser igual a los valores
establecidos dentro de una tolerancia de ±1,5%, para el tipo de audiómetro que se va a
implementar.

Respecto a la distorsión armónica total máxima no debe exceder los valores indicado en
la tabla 3. Se ha indicado únicamente por conducción aérea.

Tabla 2 – Rango mínimo de valores de nivel

Niveles de audición
En dB
Tipo 1 Tipo 4
Tipo 2 Tipo 3
Clínico/Investigación Exploración/
Clínico Diagnóstico básico
Frecuencia [Hz] avanzado monitorizado

Aire Hueso Aire Hueso Aire Hueso Aire

125 70 - 60 - - - -

250 90 45 80 45 70 35 70

500 120 60 110 60 100 50 70

750 120 60 - - - - -

1000 120 70 110 70 100 60 70

1500 120 70 110 70 - - -

2000 120 70 110 70 100 60 70

3000 120 70 110 70 100 60 70

4000 120 60 110 60 100 50 70

6000 110 50 100 - 90 - 70

8000 100 - 90 - 80 - -

Tabla 3 – Condiciones distorsión armónica total


Conducción aérea
Rango de frecuencias [Hz] 125 a 200 250 a 400 500 a 8000
Distorsión armónica total
3 3 3
en %

La normativa indica que si se provee de un indicador del nivel de señal, el fabricante ha


de especificar un punto de referencia para el nivel del tono. La aplicación coge como
referencia para iniciar la emisión del tono los -10dB SPL.

Cuando un canal de señal está conectado al auricular, el nivel de presión acústica


producido menos el nivel umbral equivalente de referencia, no debe diferir en más de

Página 20
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

±3,7 dB del valor indicado para cualquier ajuste del dial del nivel de audición a las
frecuencias indicadas en el rango de 125 Hz a 4 kHz y no en más de ±6,2 dB a
frecuencias hasta 8 kHz inclusive. Estas limitaciones indicadas en la normativa son
cumplidas por el audiómetro implementado, tal y como se indica en la sección de
calibración de la memoria del proyecto.

Transductores

En lo referente a los transductores, los tipos de transductores utilizados en audiometría


de tonos puros son auriculares de diferentes tipos (supraaurales, circumaural, y de
inserción), vibradores óseos y altavoces. En este caso se hará uso de unos auriculares
supraaurales.

Calibración
Se pasa a explicar la calibración del audiometro. Para ello se hace uso de un instrumento
de medida como el de la figura 1 (derecha) y un oído artificial, figura 1 (izquierda).

Instrumento de medida: Tipo 2636, Brüel & Kjaer

Oído artificial: Modelo 4153, Brüel & Kjaer

Figura 1 – Oido artificial (izq), Instrumento de medida (der)

Previamente a la calibación del audiómetro, se ha de calibrar el instrumento de medida.


Esto es realizado por medio del calibrador multifunción tipo 4226 (fulfils IEC 942, clase
1), marca Brüel & Kjaer (figura 2, derecha); y un micrófono de instrumentación
previamente calibrado. Una vez que se ha relizado este proeceso y se observa que
cumplen con los valores esperados (figura 2, izquierda), se pasa a calibrar el equipo.

Página 21
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

Figura 2 – Calibración del instrumento de medida

El equipo que se desea calibrar son los auriculares DD45 - TDH39, figura 3.

El sistema de calibración queda por tanto montado tal y como se indica en la figura 4
(izquierda), para el canal izquierdo; y figura 4 (derecha) para el canal derecho. Se
registran los valores nominales, a cada frecuencia y cada canal, que proporcionan los
niveles de 110 dB de presión sonora, asegurándose previamente que estos valores se
encuentran en el rango de comportamiento lineal del equipo, y que no distorsionan.
Estos datos se registrarán en la aplicación para obtener todos los niveles posibles de
presión, con saltos de 5 dB en 5 dB, hasta el mínimo valor de -10 dB SPL.

Figura 3 – Auriculares DD45 - TDH39

Página 22
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

Figura 4 – Calibración auriculares

En la tabla 4 se indican los valores nominales obtenidos a cada frecuencia y cada canal
para obtener 110 dB SPL de presión sonora.

Tabla 4 – Valores nominales para 110 dB


CANAL IZQUIERDO CANAL DERECHO
Frecuencia [Hz] Nivel nominal Nivel nominal
125 0.0386 0.105
250 0.0328 0.04
500 0.034 0.0235
1000 0.0395 0.029
2000 0.0375 0.025
4000 0.1 0.074
8000 0.144 0.098

En lo referente a las medidas de distorsión sonora, figura 5, se indica en la tabla 5 el


valor de la distorsión armónica en el rango de 125Hz – 8kHz, comparando con las
exigencias de la normativa.

Figura 5 – Distorsión armónica a 1 kHz

Página 23
Diseño e implementación de un audiómetro con Raspberry Pi
Audiómetro

Tabla 5 – Distorsión armónica total


CANAL CANAL NORMATIVA
IZQUIERDO DERECHO
Frecuencia [Hz] Distorsión armónica Distorsión Distorsión
total [%] armónica total [%] armónica total
[%]
125 1.35e-13 1.35e-13 3
250 3.87e-13 3.87e-13 3
500 7.7e-13 7.7e-13 3
1000 3.86e-12 3.86e-12 3
2000 6.8e-12 6.8e-12 3
4000 1.1e-11 1.1e-11 3
8000 6.1e-12 6.1e-12 3

Manual de instrucciones
El manual de instrucciones diseñado cumple con las características indicadas en la
norma mencionada. Se limita a ser una ayuda al operario para indicarle cómo ha de ser
realizada la audiometría junto a este tipo de audiómetro implementado.

Página 24
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

Audiometría

Definición
Tal y como ya se ha mencionado, las audiometrías son pruebas subjetivas que se
realizan para dictaminar el umbral de audición de un oyente, haciendo uso de un
instrumento llamado audiómetro. El tipo de audiómetro que se implementa en este
proyecto es un audiómetro tipo 2, por conducción aérea, en el rango de frecuencias
convencionales.

Se han de completar la definición de varios términos, que no han sido mencionados


anteriormente, para poder ser tratados con conocimiento en los siguientes apartados,
todos ellos han sido obtenidos directamente de la normativa UNE-EN ISO 8253-1 [6].

- Audiograma:
Presentación, en forma de un gráfico o de una tabla, de los niveles liminares de
audición de los oídos del sujeto sometido a ensayo, determinados en
condiciones especificadas y según el método especificado, en función de la
frecuencia.
- Umbral de audición:
Nivel de presión acústica, o nivel de fuerza vibratoria, más bajo para el que, en
condiciones especificadas, una persona da un porcentaje predeterminado de
respuestas correctas de detección en ensayos repetidos.
- Efecto de oclusión:
Cambio de nivel de una señal por conducción ósea que alcanza el oído interno
cuando se coloca un auricular o un tapón sobre, o dentro de, la entrada del
conducto auditivo, formando de esta forma un volumen de aire cerrado en el
oído externo.
- Audiometría automática de frecuencia fija:
Audiometría cuyas variaciones en el nivel de audición son controladas por el
sujeto sometido a ensayo y se registran automáticamente para frecuencias
específicas.
- Audiometría de barrido en frecuencia:
Audiometría cuyas variaciones en el nivel de audición son controladas por el
sujeto sometido a ensayo y donde la frecuencia varía continuamente o por pasos
mucho más pequeños que una banda de tercio de octava.
- Audiometría de reconocimiento:
Procedimiento de acierto-fallo donde se presentan los tonos puros a un nivel
fijo, denominado nivel de reconocimiento.
- Nivel liminar de audición de un oído determinado:
A una frecuencia especificada y para un tipo de transductor específico, el
umbral de audición a esa frecuencia, expresado como nivel de audición.

Página 25
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

- Acoplador de acústico:
Dispositivo para medir la señal de salida acústica de las fuentes sonoras donde
la presión acústica se mide con un micrófono calibrado, acoplado a la fuente
mediante una cavidad con forma y volumen predeterminado.
- Vibrador óseo:
Transductor electromecánico destinado a producir la sensación de audición
haciendo vibrar los huesos del cráneo.
- Nivel equivalente de presión acústica liminar:
Para un oído determinado, a una frecuencia especificada, para un modelo de
auricular específico y para una fuerza de aplicación determinada del auricular
al oído humano, nivel de presión acústica producido por el auricular en un
simulador de oído o un acoplador acústico específico, cuando el auricular es
alimentado por la tensión que corresponde al umbral de audición del oído en
cuestión cuando este auricular está aplicado sobre el oído.

Una vez conocidos estos conceptos se detalla cómo realizar estos ensayos
audiométricos, y qué requisitos se han de cumplir.

La normativa encargada en tratar cómo se realizan dichos ensayos es la UNE-EN ISO


8253. Dicha norma consiste en tres partes, bajo el título general “Acústica. Métodos de
ensayos audiométricos”. En el caso que nos ocupa, la norma de interés es la Parte 1:
“Audiometría de tonos puros por conducción aérea y por conducción ósea.”. La parte
dos de la norma trata sobre ensayos audiométricos en campo sonoro (por señales de
tonos puros y señales de banda estrecha), y la parte tres sobre audiometrías vocales.

A continuación se pasa a explicar un breve resumen acerca de dicha parte de la norma, y


cuáles son los requisitos fundamentales a tener en cuenta a la hora de realizar dichos
ensayos, al igual que cómo se realizan las calibraciones del equipo.

Normativa
La norma UNE-EN ISO 8253-1 es una norma internacional que especifica los requisitos
y procedimientos para la realización de ensayos audiométricos fundamentales, donde
los tonos puros se presentan al sujeto de ensayo utilizando auriculares o vibradores
óseos, en el caso del audiómetro implementado se trata de auriculares.

La audiometría que se desea realizar con el audiómetro implementado será una


audiometría con un audiómetro manual, aunque esta norma también permite que se
realice con un audiómetro registrador automático; o bien, con un equipo audiométrico
controlado por ordenador.

Página 26
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

Los niveles laminares de audición se pueden determinar por audiometría por


conducción aérea y por conducción ósea. En la audiometría por conducción aérea el
oyente es sometido al ensayo por medio de auriculares, en la de por conducción ósea se
realiza por medio de un vibrador óseo, pudiéndose colocar este sobre la frente del
oyente.

Dichos niveles laminares se pueden determinar haciendo uso de tonos de ensayo con
frecuencias fijas o una señal de ensayo con una frecuencia que varía con el tiempo de
acuerdo con la tasa de variación predefinida. El audiómetro implementado se define
como un audiómetro capaz de realizar audiometrías de tonos puros, con un audiómetro
manual, por lo que la parte de la norma referente a audiometrías con barridos en
frecuencia será obviada, al igual que las audiometrías realizadas con los vibradores
óseos.

ASPECTOS GENERALES

A continuación, se van a tratar diversos temas generales que se han de tener en cuenta
para la realización de los ensayos audiométricos.

Respecto al operario, este ha de estar cualificado para la realización de las pruebas. La


persona que realice los ensayos audiométricos ha de haber seguido una formación
previa que le cualifique para realizar estos, tanto de forma teórica como práctica. Esta
puede ser concretada por autoridades nacionales, o por otros organismos competentes.

El operario tiene libertad de:

- Escoger qué oído se somete primero a la prueba.


- Si se requiere enmascaramiento (esto no ha sido implementado en el audiómetro
de este proyecto).
- Si las respuestas del sujeto de ensayo corresponden con las señales de ensayo, o
no.
- Si existen eventos de ruido externos que puedan invalidar el ensayo, y tomar las
medidas oportunas, interrumpiendo el ensayo o repitiéndolo.

En lo referente a la duración del ensayo, se ha de tener en cuenta que se trata de una


prueba subjetiva, y que someter al sujeto a una fatiga excesiva pueda dificultar obtener
resultados fiables. Se recomienda una duración máxima aproximada de unos 20
minutos, sino el oyente necesitaría un descanso para continuar.

La medición de la incertidumbre de las pruebas es muy dificultosa, pues resulta


complicado expresar numéricamente este aspecto con una cifra válida, dado a la
complejidad del proceso de medición. Esta depende de varios parámetros, como son: el
rendimiento del equipo utilizado, el tipo de transductor utilizado, la frecuencia de los
tonos de ensayo, las condiciones del entorno donde se realizan las pruebas (el ruido
existente en la sala), la cualificación del operario, la cooperación del oyente.

Página 27
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

Preparación de la audiometría

Tal y como ya se ha mencionado, el sujeto sometido al ensayo audiométrico ha de


encontrarse en un estado de relajación, sin haberse estado sometido previamente a unos
altos niveles de ruido (esto puede causar una elevación temporal del umbral de
audición). Para que esto no ocurra la normativa recomienda que el usuario se encuentre
en el lugar citado para la realización de la prueba al menos cinco minutos antes del
ensayo.

Normalmente, el ensayo audiométrico va precedido por un examen otoscópico realizado


por la persona cualificada, si el oyente tiene cerumen que obstruye los conductos
auditivos, este ha de ser retirado.

Seguido de esto se ha de indicar al usuario, por parte del operario, el procedimiento que
tiene esta prueba y el modo de respuesta que ha de dar el oyente. En el caso del
sonómetro implementado, un ejemplo común de respuesta sería levantar o bajar a mano
una vez se escuche dicho sonido.

Del mismo modo, el oyente debería quitarse cualquier adorno de la cabeza, así como
gafas, aparatos de corrección auditiva, etc. Para que los transductores se fijen del mejor
modo posible, como han sido diseñados.

Determinación del umbral de audición, en condución aérea, por audiometría de

frecuencias fijas

El orden de presentación de los tonos de ensayo, cuando se trata de un audiómetro


manual, se debe hacer en orden creciente a partir de 1000Hz, seguido por el rango de
frecuencias inferior en sentido descendiente. Para terminar se tiene que realizar una
repetición del ensayo a 1000Hz en el primer oído sometido a ensayo, comprobando que
se obtienen resultados análogos.

El sonido debe ser continuo y presentado durante 1s – 2s. El equipo está diseñado para
que se presente durante dos segundos. El intervalo debe ser variado si se produce una
respuesta.

Antes de la determinación del umbral, conviene que el oyente se familiarice con el


equipo, para ello se presentará al usuario una señal de intensidad suficiente para que
este pueda responder de forma afirmativa a la percepción de dicha señal. Por ejemplo,
un tono de 1kHz con un nivel de 40 dB, a un sujeto con una audición normal debería ser
suficiente, e ir reduciéndolo hasta que este no sea percibido.

Página 28
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

Procedimiento de ensayo sin enmascaramiento

La norma indica que existen dos procedimientos de ensayo: un método por encuadre y
un método ascendente. Difieren solo en la secuencia de los niveles de los tonos de
ensayo presentados al sujeto. En el ascendente: de menos a más, hasta que se produce
una respuesta del oyente. El método por encuadre: similar al anterior, primero de menos
a más y luego de más a menos (el mismo tono).

Fase 1

Presentar el primero sonido de ensayo a un nivel 10 dB por debajo del nivel más bajo de
la respuesta en la sesión de familiarización. Cada vez que el sujeto no responda al
sonido, se aumentará el nivel del mismo en incrementos de 5 dB hasta que se produzca
una respuesta por parte del oyente.

Fase 2

Método ascendente: Tras la respuesta, se disminuye el nivel en pasos de 10 dB hasta


que la respuesta desaparezca y se empieza una nueva serie ascendente en incrementos
de 5 dB. Tres respuestas al mismo nivel de un máximo de cinco series ascendentes dará
el nivel liminar de audición a ese tono.

Método por encuadre: Tras la respuesta, se aumenta el nivel del sonido de ensayo en 5
dB y se empieza una serie descendente, durante la cual el nivel del sonido disminuye en
pasos de 5 dB hasta que no se produzca ninguna respuesta del sujeto sometido a ensayo.
Conviene repetir este proceso completando tres series.

Fase 3

Se continúa con la siguiente frecuencia de ensayo comenzando con un nivel considerado


como audible, en concordancia con las respuestas previas. Repitiendo la fase 2, y
completando todas las frecuencias de trabajo. Se vuelve a repetir la medición a 1 kHz, y
se confirma que concuerda con la anterior prueba realizada a esa frecuencia.

Fase 4

Se termina cuando se hayan sometido a la prueba los dos oídos. Obteniéndose el nivel
liminar de audición a cada frecuencia y para los dos oídos.

Audiometría de reconocimiento

Los tonos de ensayo al nivel de reconocimiento son audibles o inaudibles para el sujeto.
Los resultados de este ensayo muestra si los niveles liminares de audición del oyente
son mejores (más bajos), o peores (más altos) que el nivel de reconocimiento utilizado.

Página 29
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

Mismo método que el ensayo sin enmascaramiento.

La variación es que se ajusta el nivel de señal al nivel de reconocimiento requerido y se


presentan dos tonos de duración 1s a 2s, con un intervalo de 3s a 5s. si se perciben los
dos sonidos, el sujeto de ensayo ha pasado el ensayo de reconocimiento a esta
frecuencia. Si solo percibió uno, se presenta un tercero, si oye este, el sujeto ha
superado el ensayo de reconocimiento, si no ha fallado el examen de reconocimiento a
1kHz al nivel de reconocimiento escogido. Se continúa con las otras frecuencias de
ensayo, y se procede a continuación con el otro oído.

Audiograma

Para la representación gráfica de los niveles liminares de audición, no se ha respetado


los símbolos indicados en esta norma para explicar el tipo de ensayo realizado, o el tipo
de ensayo al que se refiere tal audiograma, o tal tabla de respuesta del nivel umbral de
audición. Hay un desvío de la norma en este apartado, ya que se ha considerado más
sencillo para describir los resultados y que sean entendidos para el paciente la
descripción escrita, y no por simbología.

Ruido ambiente admisible

En este apartado de la norma se ha de centrar en el control psicoacústico del ruido


ambiente, ya que no se puede hacer ningún control real con sonometría. Realizando un
ensayo audiométrico en al menos dos oyentes que se sabe que tienen audiogramas
estables y que a todas las frecuencias tienen niveles liminares de audición mejores que
los niveles de audición más bajos a utilizar durante los ensayos normales. Si los niveles
liminares de audición son superiores a 5 dB, entonces indica que se requiere una
reducción del ruido en el recinto de ensayo.

Mantenimiento del equipo audiométrico

En lo referente al tema que aquí se menciona se ha seguir el siguiente esquema:

- En primer lugar controles de rutina y ensayos subjetivos: se ha de realizar


semanalmente a todos los equipos en uso.
- En segundo lugar controles objetivos periódicos: frecuencia desde 3 a 12 meses.
- Por último se han de realizar ensayos de calibración básica. Se requieren cuando
se produce un fallo o un error grave en el equipo, o cuando este no cumple con
las especificaciones.

Controles de rutina y ensayos subjetivos


Página 30
Diseño e implementación de un audiómetro con Raspberry Pi
Audiometría

El objetivo de esta etapa es garantizar que el equipo funciona correctamente. Que la


calibración del mismo no se ha alterado de manera significativa y que el cableado y los
accesorios no presentan ningún defecto significativo. No son necesarios instrumentos de
medición para esta fase de mantenimiento, solo consiste en pruebas subjetivas por un
operario con una audición inalterada. Estos controles consisten en:

- Una correcta limpieza y comprobación de que no hay nada estropeado.


- Se enciende el equipo y se respeta el tiempo de precalentamiento recomendado,
si el fabricante no especifica ningún tiempo (como es el caso) se esperará cinco
minutos para que los circuitos se estabilicen.
- Se comprueba que la salida del audiómetro es aproximadamente correcta, con
barridos a un nivel de audición de por ejemplo 10 o 15 dB SPL.
- Se ha de verificar que todos los botones de control están bien fijados y que las
luces e indicadores funcionan correctamente.
- Se escucha a bajos niveles para intentar cualquier signo de ruido o zumbido,
sonidos no deseados (diafonía).
- Se verifican los circuitos de comunicación verbal (en este caso no existe). Habrá
que verificar que el oyente puede comunicarse con el operario de otro modo.

Comprobaciones objetivas periódicas

Dicha etapa consiste en medir y comparar los resultados con las normas adecuadas para:

- Frecuencias de las señales de ensayo.


- Niveles de presión acústica emitidos por los auriculares medidos en un
acoplador acústico o en un simulador de oído.
- Los saltos del atenuador (especialmente por debajo de 60 dB SPL).
- La distorsión armónica.

Ensayos de calibración básicos

La calibración básica se debe realizar por parte de un laboratorio competente. El equipo


audiométrico debe cumplir los requisitos aplicables a la Norma IEC 60645-1.

Página 31
Diseño e implementación de un audiómetro con Raspberry Pi
Problemas médicos

Problemas médicos

Para este proyecto se trabajan con tonos de diferentes frecuencias. El nivel necesario
para ser escuchado por el oyente es diferente para cada frecuencia. El oído humano no
es igual de sensible a cualquier frecuencia, su sensibilidad es mayor a frecuencias
medias (500-4000Hz), y tiene una sensibilidad menor a frecuencias bajas y altas. La
respuesta de nuestro sistema auditivo tendría una forma equivalente a un filtro paso
banda. El nivel de presión sonora se mide en dB SPL.

En el estudio de la pérdida de audición tiene especial relevancia la presbiacusia e


hipoacusia. La presbiacusia es la pérdida de sensibilidad en función de la edad, a
medida que el oyente es más longevo, tiene especial relevancia a frecuencias altas
(aunque también se da en frecuencias medias). Esto se observa fácilmente comparando
los niveles de los umbrales de audición entre una persona joven y una de mayor edad.
Otra enfermedad es la hipoacusia, esta es la pérdida parcial de la capacidad auditiva,
tiene diversos orígenes: genética o adquirida, congénitas o tardías. Tiene especial
relevancia en la vida cotidiana de las personas. Según la Organización Mundial de la
Salud (OMS; World Health Organization, WHO), la hipoacusia es la tercera patología
que implica años de vida con discapacidad (WHO, 2006). Según este organismo, el 5%
de la población mundial sufre de este problema (WHO, 2001) [1]. Se habla de pérdida
de audición discapacitante, entendendiéndose así como pérdidas de audición superiores
a 40dB en los adultos y de 30dB en el caso de los niños. Este tipo de problemas pueden
ser encontrados por medio de los ensayos audiométricos anteriormente citados.

El estudio de hipoacusia en las personas tiene gran relevancia para la población, pues
influye en gran medida no solo en la pérdida de la calidad de vida, sino en una gran
cantidad de años con discapacidades. Según la WHO en 2006, la mitad de los casos de
sordera se pueden prevenir si las causas comunes se atienden en el nivel de la atención
primaria de salud. Para ello la detección e intervención tempranas son factores
importantes para minimizar las consecuencias de la pérdida de audición.

La sonoridad (se mide en fonios) está vinculada con la intensidad del sonido. El oído
humano no tiene igual sensibilidad para todas las frecuencias. Este necesita mayor
energía para sentir las frecuencias más graves y las más agudas, siendo más sensible en
las frecuencias que van desde los 500Hz, a los 4kHz.

Para tratar esta esta sensibilidad dependiente de la frecuencia del sistema auditivo
humano, se desarrollaron las curvas isofónicas, las cuales representan curvas con el
mismo nivel de sensación sonora. Las primeras curvas fueron establecidas por Fletcher
y Munson en 1933, y recalculadas más tarde por Robinson y Dadson en 1956. La curva
de 0 fonios corresponden con el umbral de audición y la de 120 fonios con el umbral del
dolor.

Página 32
Diseño e implementación de un audiómetro con Raspberry Pi
Problemas médicos

La figura 6, muestra las curvas isofónicas normales para tonos puros en condiciones de
escucha en campo libre, según la norma ISO 226 (2003) [7].

Figura 6 – Curvas isofónicas Norma ISO 226 [7]

Para poder ser controlada esta pérdida de audición, se establecen unos umbrales típicos
para cada rango de edad y género. Estos facilitarán al médico su diagnóstico y ayudarán
al oyente a tener una mejor calidad de vida. Lo referente a estos se trata a continuación.

Página 33
Diseño e implementación de un audiómetro con Raspberry Pi
Umbrales de audición

Umbrales de audición

Según la norma ISO 7029 se establecen una distribución estadística de los umbrales de
audición (en función de la edad y género), especificando el valor medio esperado de los
umbrales de audición con respecto al umbral de audición medio.

Al tratarse de valores internacionales y no ceñirse a la población española, estos datos


no han sido recogidos en la implementación de este proyecto. Se ha optado por los
valores obtenidos por el doctor Antonio Rodríguez Valiente en su tesis doctoral con
título: “Determinación de los umbrales de audición en la población española”, resultaba
ser de mayor interés en las audiometrías que serán realizadas con el tipo de audiómetro
implementado en este proyecto.

En comparación con la norma ISO 7029 (2000), para los grupos de edad de 20 a 69, el
autor de la tesis doctoral encontró que los umbrales de audición de su estudio eran
peores (más elevados) que los que proporcionaba dicha norma, especialmente para las
frecuencias entre 125 y 500Hz, para las frecuencias superiores a dicho rango había gran
correlación con las proporcionadas por la norma.

En la tabla 6 y tabla 7 [1], se indican los umbrales de audición seleccionados para la


implementación del audiómetro de este proyecto, los datos están dados en dB SPL para
las frecuencias convencionales (octavas de 125Hz a 8kHz). Se dan los valores de media,
mediana y desviación estándar (DE), aunque para establecer dicho umbral medio se han
seleccionado únicamente el referente a la media. Dichos datos se han redondeado a la
unidad más cercana. También se ha de mencionar que los datos referentes al rango de
edad entre 3 a 4 años han sido eliminados.

La tabla 6 hace referencia al sexo masculino y la tabla 7 al femenino.

Página 34
Diseño e implementación de un audiómetro con Raspberry Pi
Umbrales de audición

Tabla 6 – Umbral de audición sexo masculino

Grupo edad
Frecuencia (Hz)
(años)
125 250 500 1.000 2.000 4.000 8.000
5-19 (n=158)
Media 17 14 12 9 7 8 11
Mediana 15 15 10 10 5 10 10
DE 6,57 5,97 5,15 5,67 5,56 5,75 7,32
20-29 (n=55)
Media 15 12 11 8 6 8 8
Mediana 15 10 10 10 5 10 5
DE 6,04 7,67 6,65 6,17 5,98 6,84 7,47
30-39 (n=85)
Media 16 13 12 9 6 13 11
Mediana 15 15 10 10 5 10 10
DE 6,13 5,99 6,29 5,87 6,07 10,53 10,83
40-49 (n=56)
Media 16 13 12 10 7 13 16
Mediana 15 12 10 10 5 10 15
DE 6,99 6,17 6,18 5,95 6,20 7,92 10,23
50-59 (n=57)
Media 18 15 15 14 11 18 25
Mediana 20 15 15 15 10 20 25
DE 5,80 5,42 6,10 5,57 6,69 10,17 14,55
60-69 (n=63)
Media 20 16 16 15 15 29 36
Mediana 20 15 15 15 15 25 30
DE 6,49 5,42 5,90 6,92 9,91 16,19 19,09
70-79 (n=39)
Media 21 19 18 20 26 42 53
Mediana 20 20 15 20 20 40 55
DE 6,30 6,89 7,66 8,62 16,19 19,82 18,22
80-90 (n=17)
Media 25 21 22 22 36 56 67
Mediana 25 20 25 25 35 55 70
DE 7,88 5,80 7,08 8,48 9,80 11,11 17,68

Página 35
Diseño e implementación de un audiómetro con Raspberry Pi
Umbrales de audición

La figura 7 [1], muestra la media del umbral de audición para hombres. Las barras de
error representan el IC (Intervalo de Confianza) del 95%.

Figura 7 - Media del umbral de audición para hombres

Página 36
Diseño e implementación de un audiómetro con Raspberry Pi
Umbrales de audición

Tabla 7 – Umbral de audición sexo femenino

Grupo edad
Frecuencia (Hz)
(años)
125 250 500 1.000 2.000 4.000 8.000
5-19 (n=147)
Media 18 15 13 10 6 7 11
Mediana 20 15 15 10 5 10 10
DE 6,15 5,99 6,13 5,34 5,17 5,59 7,33
20-29 (n=79)
Media 13 10 10 7 5 6 9
Mediana 15 10 10 5 5 5 5
DE 5,75 6,13 5,15 5,38 5,28 6,26 9,38
30-39 (n=87)
Media 15 13 12 10 7 9 9
Mediana 15 10 15 10 10 10 10
DE 6,02 6,41 6,59 6,66 5,74 7,19 8,19
40-49 (n=68)
Media 17 15 14 11 9 12 15
Mediana 15 15 12 10 10 10 15
DE 7,06 6,69 6,91 6,52 6,73 6,89 9,54
50-59 (n=80)
Media 18 14 14 15 12 16 20
Mediana 15 15 15 15 10 15 20
DE 5,67 5,83 5,37 6,40 7,06 8,52 10,28
60-69 (n=76)
Media 19 17 17 16 17 25 36
Mediana 20 15 15 15 15 25 40
DE 5,60 5,68 6,62 6,92 9,53 10,92 15,92
70-79 (n=35)
Media 21 19 20 19 24 33 49
Mediana 20 15 20 15 25 30 50
DE 6,65 6,47 5,93 7,77 10,34 16,44 18,46
80-90 (n=21)
Media 24 21 24 24 34 51 68
Mediana 25 25 25 25 35 50 70
DE 6,30 6,69 8,53 9,69 11,39 14,76 15,29

Página 37
Diseño e implementación de un audiómetro con Raspberry Pi
Umbrales de audición

La figura 8 [1], muestra la media del umbral de audición para mujeres. Las barras de
error representan el IC del 95%.

Figura 8 - Muestra la media del umbral de audición para mujeres

Página 38
Diseño e implementación de un audiómetro con Raspberry Pi
Marco tecnológico y recursos

Marco tecnológico y recursos

Las telecomunicaciones han supuesto una nueva revolución para todo el mundo, la
forma de vida de las personas ha cambiado mucho de una década a otra, como raras
veces han ocurrido a lo largo de la historia. Esto ha afectado a todos los aspectos de la
vida: en las relaciones sociales, laborales y familiares; en la forma de trabajo y hasta en
el contenido de los trabajos; también en la salud de las personas, y en el estudio y
control de esta. Vivimos en un contexto tecnológico en continua evolución y desarrollo,
en el que cada vez existen más posibilidades de progresar tecnológicamente hablando.

Existen posibilidades infinitas, y en eso se sustenta este proyecto. En este nuevo espacio
que se ha creado, la Fundación Raspberry Pi crea un controlador de bajo coste, con
funcionalidades muy diversas, un tamaño muy reducido, y alta funcionalidad y
escalabilidad para el usuario. En esta placa base pueden ser implementadas muy
diversas aplicaciones prácticas, con un coste muy reducido. Es por ello que para el
objetivo de este proyecto se opta por esta placa de desarrollo.

Del mismo modo los teléfonos móviles han experimentado un progreso exponencial, en
escasos años han pasado de ser meros teléfonos portátiles a tener múltiples
funcionalidades, desde servir como tarjetas de crédito, a representar en ellos señales
cardiacas en tiempo real, etc. Es por ello que se utilizarán estos para servir como
interfaz entre el operario y la Raspberry para el desarrollo de estas audiometrías.
Desarrollando una aplicación bajo el sistema operativo de Android 9, con el lenguaje de
programación Java, y el lenguaje XML para el diseño de la interfaz gráfica.

Otro recurso necesario para poder implementar dicho audiómetro es el ordenador y el


mundo de la telemática. Las telecomunicaciones han servido para crear grandes puentes
de comunicación en todo el mundo, entre otras cosas estos avances han sido capaces de
poder comunicar computadoras muy distantes, por medio de diferentes canales de
comunicación, vía cable o de forma inalámbrica transfiriendo las señales mediante
ondas electromagnéticas a diferentes frecuencias. Para ello se establecieron diferentes
estándares/protocolos de comunicación con diferentes características. Muchos de estos
estándares llevan asentados varios años en esta nueva forma de comunicación, para este
objetivo que nos ocupa se hace uso del protocolo UDP, creado en el año 1980.

A su vez un recurso muy importante del que se hace uso para elaborar este proyecto es
el entorno de desarrollo MATLAB/Simulink, el cual facilita la programación enfocada a
la Raspberry Pi, reduciendo su complejidad y poniendo el foco en los conceptos que se
desean implementar. En el apartado de Raspberry Pi se detallará la programación en
este controlador.

Los auriculares que se utilizarán cumplen con la normativa mencionada y han sido
calibrados haciendo uso de un simulador de oído. El tema de la calibración será
abordado cuando se hable de la aplicación del Audiómetro en Android.

Página 39
Diseño e implementación de un audiómetro con Raspberry Pi
Marco tecnológico y recursos

Una vez citado el contexto tecnológico en el cual se enmarca este proyecto, y tras hacer
un repaso de los recursos que se poseen para abordar el objetivo marcado, se pasa a
tratar la interconexión de todos estos dispositivos en forma de diagrama de bloques. De
forma simultánea se determina la configuración en la red de estos dispositivos, para
poder ser tratados en profundidad en capítulos posteriores.

Página 40
Diseño e implementación de un audiómetro con Raspberry Pi
Diseño e implementación del proyecto

Diseño e implementación del proyecto

Para la implementación del proyecto, se ha buscar la manera de que el usuario pueda


modificar la señal que desea transmitir. Ser modificada desde la propia Raspberry
resultaba difícil, poco eficiente e impedía tener representado el umbral de audición antes
de ser transferido al oyente el registro de la audiometría. Por esta razón se opta por el
desarrollo de una aplicación implementada en un teléfono móvil (bajo Android) que
permita comunicarse con la tarjeta Raspberry: modificar los parámetros de interés de la
señal, mostrar la señal antes de ser transmitida, generar un documento resumen de los
resultados de la audiometría junto con los datos del oyente y del técnico. La aplicación
instalada en la Raspberry debe recibir estos datos y trabajar con ellos en tiempo real.
Para ello esta aplicación, desarrollada bajo el sistema operativo de Raspbian con
MATLAB/Simulink, será capaz de comunicarse con la aplicación implementada en el
móvil vía UDP. Los datos recibidos vía UDP serán procesados mediante el System
object que controla el audiómetro para determinar correctamente qué señal de
audiometría se requiere. Las señales de audiometría serán enviadas a los auriculares del
oyente mediante la tarjeta de sonido acoplada en la Raspberry.

Para que esto ocurra y que el sistema trabaje correctamente, los dispositivos se han de
encontrar en una misma red, para que puedan comunicarse entre sí. En el apartado del
diagrama de red se explicará en profundidad las características de esta red y de los
dispositivos en ella.

Diagrama de bloques
El sistema queda resumido en la figura 9. El operario por medio de la interfaz del
teléfono móvil es capaz de comunicarse con el oyente, enviando datagramas, mediante
el protocolo UDP, a la Raspberry. Estos datagramas contienen datos sobre el canal, la
frecuencia y el nivel del tono a emitir. El oyente responde al operario cuando percibe el
sonido, fijando así el umbral de audición. El ordenador se comunica vía SSH (Secure
SHell) con la Raspberry para configurarla e instalar en ella la aplicación del audiómetro.
La configuración del driver de la tarjeta de sonido (ALSA) permite que las señales de
audiometría sean accesibles por el oyente a través de sus auriculares.

Página 41
Diseño e implementación de un audiómetro con Raspberry Pi
Diseño e implementación del proyecto

Figura 9 - Diagrama de bloques

En el capítulo siguiente se muestra el diagrama de red de la red creada para realizar la


comunicación entre estos dispositivos.

Creación del punto de acceso


Se creará un punto de acceso a la red (WAP) desde el teléfono móvil, creando una red
privada entre diferentes dispositivos móviles.

Figura 10 – Zona Wi-Fi

La configuración es tal y como se muestra en la figura 11, la SSID (Service Set


Identifier) de la red Wi-Fi es: “VictorRaspberry”. El tipo de cifrado es WPA2 PSK (Wi-
Fi Protected Access 2); no se entra en detalles en el tipo de cifrado. La contraseña:
“raspberry”. Se fija un máximo de dos usuarios capaces de conectarse a la vez a esta red
para restringir el acceso a otros usuarios no deseados. La banda de AP es de 2,4 GHz y
el canal de difusión es el canal 1. No se configura ningún temporizador para apagar
dicha red, ya que esto podría perjudicar nuestro trabajo. Dichos datos han de ser

Página 42
Diseño e implementación de un audiómetro con Raspberry Pi
Diseño e implementación del proyecto

configurados tanto en el ordenador portátil como en la Raspberry; la configuración en


esta última se explica cómo se realiza en el siguiente apartado.

Figura 11 – Configuración zona Wi-Fi

Diagrama de red
En el diagrama de red de la figura 12 se muestra la configuración de la misma. Se
detalla también los puertos UDP de la Raspberry con los que se comunican los dos
dispositivos.

La red “VictorRaspberry” está diseñada para que se comuniquen tres dispositivos: el


propio teléfono móvil, que hace de router, la Raspberry y el ordenador, que servirá para
instalar la aplicación en la Raspberry y examinar el rendimiento de la misma.

La asignación de direcciones es la siguiente:

- Teléfono móvil:
o Dirección IP dinámica 192.168.43.X
o Máscara de subred: 255.255.255.0
o Puerta de enlace: 192.168.43.1
- Raspberry Pi:
o Dirección IP estática: 192.168.43.147
o Máscara de subred: 255.255.255.0
o Puerta de enlace: 192.168.43.1
- Ordenador portátil:
o Dirección IP dinámica 192.168.43.X
o Máscara de subred: 255.255.255.0

Página 43
Diseño e implementación de un audiómetro con Raspberry Pi
Diseño e implementación del proyecto

o Puerta de enlace: 192.168.43.1

Las direcciones MAC de cada máquina no se indican pues no resulta de interés para el
desarrollo de la memoria del proyecto.

Figura 12 - Diagrama de red

Se han elegido direcciones IP dinámicas tanto para el ordenador portátil como para el
teléfono móvil, pues no necesitan ser conocidas/registradas por ninguno de los
dispositivos presentes en el sistema, por lo que es irrelevante cuál sea esta. No existe
comunicación en ningún momento de este proceso entre el móvil y el ordenador, en lo
referente al envío de información para la audiometría, pero es el teléfono quien le da
acceso a la red, por eso está presente ese enlace en la figura 12. Este sí que se comunica
con la Raspberry para la instalación de la aplicación y para configurar esta, vía SSH. El
teléfono envía datagramas a la Raspberry, con el protocolo UDP, en los puertos: 26000,
26001 y 26002 (de la Raspberry). Este protocolo no tiene establecimiento de la
conexión, ni control de los paquetes que se envían, es por ello que no es necesario el
conocimiento de la IP de origen.

Página 44
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Raspberry Pi

Para la implementación del audiómetro se seleccionó la placa de desarrollo de


Raspberry Pi. Se tratan de placas de un reducido tamaño, bajo coste y gran
funcionalidad. Dicha compañía (Raspberry Pi Foundation) es de Reino Unido, y lleva
perfeccionando esta idea desde el año 2012, actualmente se encuentra a la venta el
último modelo Raspbery Pi 4. Pero para este proyecto, se ha implementado el
audiómetro sobre una Raspberry Pi 3 B +. Ya que este último modelo salió cuando ya
estaba en proceso este proyecto.

Figura 13 – Logo Raspberry Pi [8]

Se trata de hardware libre o con derechos de marca, es un producto con propiedad


registrada pero se permite su uso libre. Es fácilmente escalable, por medio de sus pines
de expansión, como ya se mencionará más adelante.

En lo referente al sistema operativo, el sistema operativo oficial es una versión adaptada


de Debian, llamada Raspbian, siendo este embebido en una tarjeta MicroSD. Aunque
también existen otros sistemas operativos, por ejemplo NOOBS, Ubuntu, Windows 10,
OSMC... Para este proyecto se utilizará una versión del Sistema Operativo Raspbian
Linux, requerida para trabajar en MATLAB y Simulink, distribuido por MathWorks,
concretamente trabaja bajo la versión 18.2.0.

Se pasa a hablar sobre la placa en cuestión, bajo la cual se ha trabajado en este proyecto.

Raspberry Pi 3 Modelo B+
El modelo en cuestión con el que se ha trabajado es el que aparece en la figura 14.

Las características de la placa se resumen en la tabla 8, Están reflejadas todas las


características técnicas de la misma. A destacar de la misma es la calidad del
procesador, que permitirá un rendimiento óptimo de la aplicación que se instalará en
ella, la diversidad de opciones de comunicación (WiFi y Ethernet). En esta aplicación se
hace uso del módulo de WiFi para poder comunicarse entre todos los dispositivos. El
puerto MicroSD para cargar en él el sistema operativo de MathWorks-Raspbian y el
almacenamiento de la aplicación del audiómetro. Se hace uso a su vez de los 40 pines

Página 45
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

de expansión (GPIO) para poder agregar a la Raspberry Pi la tarjeta de sonido de


AudioInjector.

La entrada de alimentación de la placa es una fuente de alimentación micro USB de


2,5A.

Figura 14 – Raspberry Pi 3 Modelo B+ [2]

Tabla 8 – Características Raspberry Pi 3 B+

RASPBERRY PI 3 MODEL B+ Características


CPU + GPU Broadcom BCM2837B0, Cortex-A53 (ARMv8) 64-bit SoC @
Velocidad 1.4GHz
Memoria RAM 1GB LPDDR2 SDRAM
Red: Wi-Fi + 2.4GHz y 5GHz IEEE 802.11.b/g/n/ac
Bluetooth Bluetooth 4.2, BLE
Ethernet Gigabit Ethernet sobre USB 2.0 (300 Mbps)
Pines de expansión GPIO de 40 pines
Salida de vídeo HDMI / Vídeo Compuesto
Puertos USB 2.0 4
Entrada de Vídeo Conector CSI
DSI Puerto DSI para conectar una pantalla táctil
Salida de audio 3,5mm Jack
Almacenamiento MicroSD
Power-over-Ethernet (PoE)

Página 46
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Para poder localizar todos los componentes sobre la placa se adjunta la figura 15, en la
que es posible identificar los componentes antes mencionados.

Figura 15 – Raspberry Pi 3 B+ características

Una vez han sido descritas las características del modelo de tarjeta Raspberry Pi, se pasa
a describir la configurar de la misma, previa referencia al entorno de trabajo de
MATLAB.

MATLAB/Simulink
MATLAB (MATrix LABoratory) es un sistema de cómputo numérico que ofrece un
entorno de desarrollo integrado (IDE) con un lenguaje de programación propio. Está
disponible para plataformas Unix, Windows, Mac OS X y GNU/Linux [9].

Figura 16 – Logo MATLAB [9]

Página 47
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Simulink es un entorno de programación visual, que funciona sobre el entorno de


programación MATLAB. Simulink sirve para realizar una programación y modelados
complejos, sobre una interfaz gráfica sencilla, cómoda de ser utilizada y fácilmente
modificable. Esta herramienta de simulación de modelos y sistemas permite mediante el
conexionado de módulos, los cuales ya han sido programados, crear sistemas muy
complejos, desde radares, sistema de monitoreado de cámaras, etc. Hasta este propio
caso que es la implementación de un Audiómetro sobre Raspberry Pi.

Para ello han de ser instalados previamente dos paquetes de MATLAB y agregados a la
configuración del mismo, para que este pueda comunicarse con la Raspberry, tal y como
se ha mencionado previamente. Los paquetes a instalar son dos: “MATLAB Support
Package for Raspberry Pi Hardware” y “Simulink Support Package for Raspberry Pi
Hardware”.

Figura 17 – Paquetes a instalar en MATLAB

Configuración de la Raspberry
Recordando la figura 12 (direcciones IP del sistema), se asigna a la placa de Raspberry
una dirección que se encuentre dentro del rango permitido de la red creada (esto puede
ser realizado a la hora de instalar el sistema operativo). En el diseño de la red, esta debe
de ser capaz de comunicarse con el ordenador, el cual le transferirá la aplicación del
audiómetro que correrá en el sistema operativo antes mencionado, y también con el
teléfono móvil, que le enviará información relevante para la evaluación audiométrica
del oyente.

Se procede a instalar el Sistema Operativo descargado desde el paquete de MATLAB:


“Simulink Support Package for Raspberry Pi Hardware” (dentro de la configuración del
mismo), se configura directamente para que este dispositivo esté en la red WiFi (figura
19, 20 y 21), la cual se creó previamente desde el teléfono móvil (apartado “Creación
del punto de acceso”). Se reescriben las característica configuradas en el punto de
acceso a la red anteriormente creado, el SSID (nombre de la red), su contraseña, junto a
las características de seguridad de la misma.

La instalación y descarga de este sistema operativo se realiza por medio de Simulink.

Página 48
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 18 – Descarga del sistema operativo

Figura 19 – Configuración de red en la Raspberry (A)

Página 49
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 20 - Configuración de red en la Raspberry (B)

Figura 21 - Configuración de red en la Raspberry (C)

Para que la placa pueda comunicarse con el resto de dispositivos ha de tener una
dirección IP estática, dentro del rango permitido, y la misma puerta de red (Default
Gateway) que el resto de dispositivos. En este caso se ha escogido como dirección IP:
“192.168.43.147” para la Raspberry, la máscara de red es “255.255.255.0” y la puerta
de red: “192.168.43.1”.

Página 50
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Comunicación con MATLAB/Simulink.


Se ha de poder comunicar el ordenador donde se encuentra instalado
MATLAB/Simulink, donde se trabaja con la Raspberry Pi en la que se instalará la
aplicación desarrollada. Para ello ha de encontrarse en la misma red que se acaba de
mencionar, la dirección IP de este ordenador no es necesario que se disponga de una
dirección estática, puede ser designación automática, pues no hace falta que otro
dispositivo de nuestro sistema sepa de antemano la dirección de este ordenador. Es por
eso que se opta por el hecho de una asignación automática, para no entrar en problemas
de coincidencia de asignaciones de IP cuando se comuniquen con este punto de acceso.

Una vez el ordenador esté en la misma red, con SSID: “VictorRaspberry”, es posible
trabajar en MATLAB con la Raspberry, sin la necesidad de red Ethernet.

Por medio del protocolo SSH se puede acceder remotamente a la Raspberry. Para ello se
hace uso de la aplicación PuTTY, aplicación con licencia libre, disponible en varias
plataformas, que puede ser llamada desde MATLAB. Los comandos necesarios para
acceder remotamente a la Raspberry aparecen en la figura 23, en dicha figura se observa
a su vez que se accede exitosamente a la Raspberry.

Figura 22 – Logo PuTTY

Figura 23

Una vez dentro de la misma se puede acceder al fichero donde se configura los datos de
red, y la asignación de dirección IP estática que se había configurado anteriormente, a la

Página 51
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

hora de instalar el sistema operativo. El fichero se encuentra en: /etc/network/interfaces,


y se accede a él con el parámetro: sudo nano /etc/network/interfaces (figura 24).

Figura 24 – Fichero: /etc/network/interfaces

Figura 25 – Fichero: /etc/wpa_supplicant/wpa_supplicant.conf

En la figura 25 muestra la configuración del acceso a la red “VictorRaspberry”.

Utilizando este protocolo se podrá, entre otras cosas, configurar la tarjeta de sonido, por
medio de la cual obtendremos la salida de nuestra aplicación, examinar el rendimiento
de la aplicación, el rendimiento de la CPU (Central Processing Unit), comprobar
niveles de entrada y salida de audio, etc.

Página 52
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Tarjeta de sonido estéreo Audio Injector


Se trata de una tarjeta (figura 26) que se comunica con la Raspberry vía los pines de
expansión de la Raspberry (GPIO, Entrada/Salida de Propósito General), mencionados
anteriormente en la descripción de las características de la placa. La descripción de cada
pin queda refleja en la figura 27. No se adentra en la descripción de cada pin pues no es
el objetivo de esta memoria, ya que dicha placa no ha sido diseñada por el alumno, y la
implementación de ella no ha sido el objetivo del proyecto.

Figura 26 – Tarjeta de sonido estéreo Audio Injector [3]

Página 53
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 27 – Pines GPIO Raspberry Pi 3 B + [10]

Características de la tarjeta de sonido estéreo de Audio Injector

La tarjeta seleccionada para la implementación del audiómetro es una tarjeta sencilla


pero de alta de calidad que trabaja para Raspberry, con un coste bajo. Las características
de esta son las siguientes:

Dispone de dos canales de entrada de audio y otros dos de salida. Incluye un control de
volumen de hardware tanto para entrada como para salidas, se puede modificar el nivel
de estas entradas y salidas con un sencillo fader rotativo. A su vez, dispone de un
preamplificador de auriculares, e incluye la tarjeta un micrófono, no de muy buena
calidad. Utiliza condensadores de desacoplamiento de tantalium DC para tener una alta
calidad de sonido. La frecuencia de muestreo es de 92 kHz, y trabaja sobre 32 bits.

Proporciona el mismo encabezado GPIO para poder ser ampliado el sistema, aunque
esto no será necesario para el objetivo de este proyecto.

Página 54
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

El resumen de estas características se muestra en la tabla 9.

Tabla 9 – Características de la tarjeta de sonido estéreo Audio Injector

Resolución de audio digital


Frecuencia de muestreo 96 kHz
Tamaño de la muestra 32 bits

Entradas y salidas analógicas


Micrófono Incluido en la placa
Conector Conector para auriculares a 18 mW de
Potencia máxima / 16 Ω
Conector RCA estéreo
Voltaje 3.3V

Control analógico Control de volume knobs (Entrada y salida)


Driver ALSA
Reloj Crystal codec (low jitter)

Una vez conectada la tarjeta de sonido a la Raspberry, se procede a configurar la misma


para que reconozca Raspberry reconozca como prioritaria esta tarjeta de sonido y se
pueda trabajar con ella. Esto se realiza por control remoto desde el ordenador, por
medio del protocolo SSH antes mencionado, con la aplicación Putty. Es una operación
sencilla y rápida, que permitirá avanzar en el desarrollo del audiómetro.

Para instalar la tarjeta de audio se ha de modificar el fichero /boot/config.txt para ello se


ha de acceder al directorio mencionado (/boot). Con el comando cd.. se accede al
directorio raíz de la Raspberry, para a continuación acceder a dicha carpeta (cd boot).
Con el comando ls se listan todos los archivos existentes en dicho directorio y se
encuentra el archivo a modificar, con el comando sudo nano config.txt, se permite al
usuario modificar el mismo con todos los permisos de lectura y escritura.

Este finalmente queda modificado como se indica en la figura 28, para guardar dicho
archivo se ha de pulsar Ctrl+X y guardar el mismo. Esto hará que quede definida como
tarjeta principal de audio la tarjeta de Audio Injector, y quedará establecida como
principal. Para que queden registradas dichas operaciones se ha de reiniciar el
dispositivo. Esto se hace con el comando sudo reboot. Una vez realizadas estas
operaciones, cada vez que se inicie el equipo arrancará con esta configuración.

Página 55
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 28 – Fichero: /boot/config.txt

Se han de configurar los parámetros necesarios para que la salida del sonido se realice
por los conectores oportunos, así como configurar ciertas entradas para que se puedan
realizar pruebas previas acerca del buen funcionamiento de la tarjeta. Para ello se
enviará el comando alsamixer. Viendo todas las configuraciones posibles del sonido, se
quedará tal y como se muestra en la figura 29. Activando y desactivando las entradas y
salidas oportunas, así como la entrada de micrófono, etc. La ganancia del Master de
salida ha de ser de 0 dB. Para activar y desactivar entradas y salidas, se realiza pulsando
la tecla „m‟ o espacio, así se pueden conmutar todas estas opciones. Para salir se pulsa la
tecla escape, y se reinicia el sistema para dejar esta configuración salvada.

Página 56
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 29 - AlsaMixer

Aplicación: Audiómetro
Se ha de adentrar en el objetivo principal del proyecto que no es otro que la
implementación de un audiómetro sobre Raspberry Pi.

Para ello se ha diseñado el modelo en Simulink, habiéndose sido configurado


previamente MATLAB. Este lleva por nombre “Audiometro.slx”, y el modelo queda
definido como se muestra en la figura 30, a continuación se procede a describir con
detalle el modelo.

Página 57
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 30 – Aplicación Audiómetro en Simulink

Para que sea más cómodo de explicar el desarrollo de la aplicación se ha dividido la


misma en áreas (así es como llama Simulink a esos rectángulos de trabajo de color
grisáceo). Concretamente la aplicación dispone de 5 áreas bien diferenciadas:

- Comunicación con Android.


- Generación del tono.
- Audioinjector: Salida.
- Control LED (Light-Emitting Diode).
- Osciloscopio.

A continuación se procede a describir cada uno de las áreas/bloques:

Comunicación con Android

Esta área ha sido diseñada para recibir información enviada por el usuario desde el
teléfono móvil, concretamente la información consiste en datos acerca de la frecuencia,
nivel y canal de escucha. Dicho bloque ha sido implementado para escuchar de forma
independiente en tres sockets distintos y bien diferenciados (figura 31).

Página 58
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 31 – Audiómetro: Comunicación con Android

El protocolo de comunicación es UDP. Se trata de un protocolo de la capa de transporte


basado en el intercambio de datagramas. Una de sus características principales es que no
es necesario un establecimiento previo de conexión, ya que dichos datagramas
contienen toda la información necesaria para llegar a su destino. Dicho protocolo
tampoco tiene confirmación de recepción del mensaje, ni control de flujo del mismo. A
pesar de ello se opta por dicho protocolo por diversos motivos, por la facilidad del
mismo a la hora de comunicarse, así como la sencillez de la implementación, pero sobre
todo porque se utiliza una red privada dedicada exclusivamente al correcto desarrollo de
esta aplicación, no habrá ningún problema de saturación de paquetes, ni de alto tráfico
de datos en ella. Por lo que la tasa de error en dicha transmisión tiende a ser nula.

Adentrándose en cada uno de los módulos, se puede conocer la configuración de los


mismos. Por ejemplo para el módulo de UDP canal, figura 32 (izquierda), se observa
que espera recibir un dato de tipo double, en el puerto 26 000, un único dato y que
muestrará el canal en búsqueda del siguiente dato cada 0.01 segundos. El resto de
módulos tienen una configuración similar, por ejemplo el de la frecuencia (figura 32,
centro) está configurado para recibir en el puerto 26 001, un dato tipo double, y la
frecuencia de muestreo será la misma que el UDP de canal. El módulo de comunicación
UDP destinado a recibir el dato del nivel (figura 32, derecha) espera recibir el dato en el
puerto 26 002, igualmente tipo double, bajo la misma frecuencia de muestreo. Se trata
de configuraciones sencillas. No se trata de la configuración más eficiente, pues se hace
uso de tres puertos diferentes para la recepción de solamente de un dato por módulo,
pero resulta más sencillo de efectuar, y dado que el sistema está dedicado expresamente
a esta funcionalidad se ha optado por esta opción. Otra podría ser, por ejemplo,

Página 59
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

concatenar los tres datos en un mismo datagrama y enviarlos por un único puerto, y una
vez lleguen al destino, a la Raspberry, obtener la información referente a estos tres datos
que fueron encapsulados en un único datagrama. Esta opción es más costosa y resulta
poco eficiente pues el coste computacional del uso de estos tres puertos no supone un
problema para este sistema.

Figura 32 – Audiómetro: Configuración bloque UDP

Generación del tono

Esta área (figura 33) está dedicada a la gestión de la información que proviene de los
módulos UDP para convertirlos en los tonos que escuchará el oyente. El sistema
dispone de tres entradas diferenciadas, como los tres argumentos que gestiona, mediante
la interfaz, el operador para dictaminar el umbral de audición del oyente. Una vez
procesada dicha información se genera un tono que es enviado a la salida. El sistema
posee dos salidas, como los dos canales de audición a evaluar.

Figura 33 – Audiómetro: Generación del tono

Página 60
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Esto es implementado en MATLAB/Simulink con un System object. Estos objetos son


sistemas dinámicos diseñados para trabajar con entradas que cambian con el tiempo.
Estas pueden ser modificadas desde la propia aplicación de Simulink, pero en el
objetivo de este proyecto se desea que sea modificado por un agente externo, de forma
independiente, y así ha sido diseñado. Resumiendo consiste en un pequeño sistema
capaz de gestionar entradas y salidas de manera dinámica, por medio de un código
diseñado por el programador. Este código es creado en MATLAB, por lo que tiene una
extensión .m. En el caso de la aplicación del audiómetro, se ha llamado al código
PruebaTonos.m (figura 34).

Figura 34 – Audiómetro: System object

A continuación se muestra el código del fichero PruebaTonos.m:


classdef PruebaTonos < matlab.System
% Víctor Manuel Díaz Conejo, PFG Junio 2019
% Tutor: Antonio Mínguez Olivares.
% Audiómetro sobre Raspberry-Pi.
%
% This template includes the minimum set of functions required
% to define a System object with discrete state.

% Public, non tunable properties (no modificables durante la


% ejecución)
properties(Nontunable)
Fs=48000; % Definimos la variable frecuencia de
% Muestreo (Hz)
duracion_segundos=2; % Definimos la duración de nuestro
% sonido
end
% Public, tunable properties (pueder ser modificadas durante la
% ejecución)
Properties

end

properties(DiscreteState)

end

Página 61
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

% Non public, non tunable properties (ocultas y no modificables


% durante la ejecución)
properties(Access = private, Nontunable)
N; % Número de muestras del Frame de entrada (canales L y R)
t; % Tiempo
end
% Non public, tunable properties (ocultas y modificables durante
% la ejecución)
% Pre-computed constants
properties(Access = private)
yL; % Frame del canal L (Salida)
yR; % Frame del canal R (Salida)
end

methods(Access = protected)
function setupImpl(obj,canal,frecuencia,nivel)
% Perform one-time calculations, such as computing
% constants
% Inicialización de variables
obj.N=24576; %longitud de los
frames de datos de entrada
obj.t=(0:obj.N-1)/(obj.Fs); %Duración del tiempo

% datos de entrada
obj.yL=zeros(obj.N,1); % Frame de salida canal L
obj.yR=zeros(obj.N,1); % Frame de salida canal R

%obj.N=480; %longitud de los


frames de datos de entrada
%obj.t=(0:obj.N-1)/(obj.Fs); %Duración del tiempo

end

function [outL, outR] = stepImpl(obj,canal,frecuencia,nivel)


% Implement algorithm. Calculate y as a function of input
% u and discrete states.

b=frecuencia*2*pi; % Definimos variable b a utilizar en


% nuestta función a·sin(bt+c)
x=[nivel.*sin(b*obj.t)];

outL=obj.yL(1:obj.N,1);
outR=obj.yR(1:obj.N,1);

% Bypass ("1") o efecto ("0")


if canal == 0 %Bypass: "1" derecho / "0" izquierdo
outL=x(1:obj.N,1);
outR=obj.yR(1:obj.N,1);

elseif canal == 1 %Bypass: "1" derecho


outL=obj.yL(1:obj.N,1);
outR=x(1:obj.N,1);
end

end

Página 62
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

function resetImpl(obj)
% Initialize / reset discrete-state properties
end
end
end

Queda explicada dicha función por medio de comentarios agregados al desarrollo de la


aplicación.

Por último resta por explicar el último módulo de esta área, se trata de un módulo
llamado Matrix Concatenate (figura 35), cuya traducción explica el funcionamiento del
mismo. Se trata de un módulo dedicado a concatenar las dos salidas del System object,
los dos canales (estéreo), en una única señal de salida. Se crea una matriz de dichas
dimensiones para poder ser transferida al siguiente área dedicada a crear la salida del
sistema.

Figura 35 – Audiómetro: Bloque Matrix Concatenate

Audioinjector: Salida

El área dedicada a la salida del Audio Injector (figura 36) contiene tres módulos bien
diferenciados y fáciles de describir. Esta área consiste en armar una señal capaz de ser
enviada al driver ALSA de salida de la tarjeta Audio Injector estéreo para Raspberry.

Página 63
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 36 – Audiómetro: Salida AudioInjector

El primer módulo que se encuentra la señal llegada del Matrix Concatenate es el de


ganancia (figura 37). El cual no tiene mayor explicación que la que se muestra en la
figura indicada.

Figura 37 – Audiómetro: Bloque Ganancia

El siguiente módulo se llama Data Type Conversion (figura 38) es el encargado de


convertir la señal que le llega en datos de tipo int32 a su salida, ya que, como se
mencionó en el apartado de las características de la tarjeta de sonido, esta trabaja con
datos de 32 bits. El tipo de redondeo es floor evitando saturaciones y valores no
deseados.

Página 64
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 38 – Audiómetro: Bloque Data Type Conversion

Por último el bloque dedicado a la reproducción ALSA Audio Playback (figura 39), la
salida es una señal analógica. Se trata de un convertidor que envía al driver de la tarjeta
de sonido la señal analógica generada. Las dimensiones de la matriz son [Nx2], donde N
es el tamaño de la muestra. La frecuencia de muestreo ha de coincidir con la cual se ha
generado la señal en el área de Generación del tono: 48 000 Hz, tal y como se refleja en
la figura indicada que ha sido seleccionada en este módulo. El campo que indica el
nombre del dispositivo (Device name) es plughw:card,device los dos últimos
parámetros han sido configurados con anterioridad, pueden ser obtenidos utilizando el
comando “aplay –l” en la ventana de comandos de la Raspberry. Una vez enviada la
señal al usuario, este interactuará con el operario indicándole si es capaz de escuchar la
señal.

Figura 39 – Audiómetro: Bloque ALSA Audio Playback

Página 65
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Control LED

Área encargada de mostrar de forma visual al operario que la aplicación está abierta y
trabajando (figura 40). Se trata de una generación de pulsos periódicos que son
reproducidos en forma de señal luminosa, en el LED ubicado en la placa de la
Raspberry Pi. Esta señal se reproduce siempre que la aplicación está corriendo. Esta
función se divide en tres módulos, tal y como se aprecia en la figura 40.

Figura 40 – Audiómetro: Control LED

El primer bloque de esta área (figura 41) es el encargado de generar una señal tipo pulso
que será enviada tras pasar por un convertidor al LED para ser emitida como señal
lumínica. Como parámetros relevantes de interés, en la figura anteriormente
mencionada se puede observar que la amplitud seleccionada es la más alta posible, que
se trata de una señal periódica con un periodo de 0.5s, que el ancho del periodo es de
10%. El resto de parámetros son los configurados por defecto.

Figura 41 – Audiómetro: Bloque Generador de Pulsos

El siguiente bloque (figura 42), conectado al del Generador de pulsos, es el Data Type
Conversion, la configuración es similar al otro bloque del mismo tipo mencionado
Página 66
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

anteriormente, con la gran salvedad de que el tipo de datos a la salida de este bloque y
entregado al módulo dedicado al LED es: Inherit, que es el tipo de dato requerido para
este cometido.

Figura 42 – Audiómetro: Bloque Data Type Conversion

Por último en esta área se encuentra el bloque dedicado al LED (figura 43). Este bloque
es perteneciente a la librería Simulink orientado a Raspberry Pi, como son los bloques
de recepción UDP y Alsa Audio Playback. En este bloque se ha de seleccionar el
modelo de Raspberry con el que se trabaja, que en este caso es: Raspberry Pi 3 Modelo
B+, y como solo se tiene un LED para trabajar con él, se selecciona el led0, color verde
(Green).

Figura 43 – Audiómetro: Bloque LED

Osciloscopio

Por último el área dedicada a la representación de la señal que se emite, llamada


Osciloscopio (figura 44), se obtiene la señal justo en el momento de ser enviada a los
auriculares. Y se consigue ver representada en el dominio del tiempo y de la frecuencia
con los dos módulos siguientes.

Página 67
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 44 – Audiómetro: Osciloscopio

El módulo llamado Analizador en Tiempo (figura 45) es capaz de representar la señal de


los dos canales en el dominio del tiempo, en función también de su amplitud. A tiempo
real.

Figura 45 – Audiómetro: Analizador en tiempo

El otro bloque llamado Analizador de espectros (figura 46) es capaz de representar la


señal de los dos canales en función de la frecuencia, a tiempo real. Existen muchos
parámetros a configurar en dicho bloque, como la frecuencia de muestreo, etc. Y otros
para la representación de la señal. En este bloque se puede observar claramente el tono
que se está generando en el oyente, así como su amplitud medida en dB.

Página 68
Diseño e implementación de un audiómetro con Raspberry Pi
Raspberry Pi

Figura 46 – Audiómetro: Analizador de espectros

Página 69
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Teléfono móvil con Android

Para el desarrollo de la interfaz que se ha de comunicar con la Raspberry Pi, se ha


optado por la implementación de una aplicación sobre un teléfono móvil con el sistema
operativo Android.

Antes de explicar la aplicación se ha de explicar el modelo de móvil con el que se


trabajará y el tipo de sistema operativo.

Figura 47 – Logo Android

Android y Huawei P20 Lite


El sistema operativo de Android fue inicialmente desarrollado por la empresa Android
Inc. (2003, California), empresa que fue adquirida por Google en 2005. Android fue
presentado en 2007, con el fin de progresar con los estádares abiertos de los dispositivos
móviles. Una de las razones por las que se ha optado por del desarrollo de la aplicación
sobre este sistema operativo es que Android es el sistema operativo móvil más utilizado
del mundo, la cuota de mercado en 2017 suponía más del 80% [11].

Se trata de un sistema operativo móvil basado en el Kernel de Linux y otros software


de código abierto. Actualmente en el mercado hay infinitos tipos de dispositivos que
tienen este sistema operativo embebido, desde teléfonos móviles, tabletas, relojes, hasta
automóviles, etc.

Ha habido 16 versiones diferentes de este sistema operativo, durante la corta vida que
tiene. La aplicación desarrollada en este proyecto se instala sobre la última versión de
este sistema operativo: Android 9.0 (“Pie”).

Antes de adentrarse en la implementación de la aplicación, se ha de tratar las


características del teléfono móvil en el que se instalará dicha aplicación. Se trata de un
Huawei P20 Lite, según se muestra en la figura 48.

Página 70
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Figura 48 – Huawei P20 Lite [12]

Las características del mismo se resumen en la tabla 10 [12].

Tabla 10 – Característica Huawei P20 Lite


HUAWEI P20 Lite - Características
Procesador 4x2.36GHz (Cortex A53), 4x1.7GHz (Cortex A53)
Monitor 5.84”
Resolución: 2280x1080px
Tecnología: LTPS TFT
Memoria Interna: 4 GB de RAM, 64 GB de Flash
Externa: tarjeta microSDTM de hasta 256 GB
Cámara Frontal: 16MP f2.0, FF
Trasera: 16MP f2.2 + 2MP f2.4
Batería 3000mAh (valor típico), 2900mAh (valor mínimo)
En espera: 471 h * (GSM), 454 h * (WCDMA), 433 h * (LTE)
Tiempo de conversación: 30 h * (GSM), 17 h * (WCDMA)
* Los datos se derivan de pruebas de laboratorio.
SIM Tarjeta Nano-SIM + Nano-SIM / tarjeta microSDTM
RED 4G FDD: B1/B3/B7/B8/B20
3G WCDMA: B1/B2/B5/B8
Conectividad WiFi: 802.11 b / g / n / a / ac, 2.4 GHz y 5 GHz
Bluetooth®: BT 4.2, aptXTM, aptXTM HD
NFC: sí
Conector USB: USB Type-C TM
Tipo de USB: USB 3.0
Funciones USB: OTG, anclaje a red, MTP, PTP, carga
Peso Producto (incluida la batería): 145 gramos
Huella digital Sí

Página 71
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Configuración comunicación con entorno de programación


Para el desarrollo de la aplicación sobre Android se ha escogido el entorno de desarrollo
integrado oficial para este sistema operativo: llamado Android Studio.

Figura 49 – Android Studio [13]

También hay que recordar que anteriormente se creó una red privada para que puedan
comunicarse todos estos dispositivos, en la cual el teléfono móvil estaba configurado
como router con una IP dinámica. Además, se estableció que el SSID de la red fuera
“VictorRaspberry”.

Para instalar la aplicación y establecer la comunicación con el ordenador portátil se han


de dar los permisos oportunos. Se conecta el teléfono móvil al ordenador vía USB 3.0
tipo C, se configura para “Transferir archivos”, y se habilita la “Depuración USB”
dentro de los ajustes del teléfono. Finalmente se ha de permitir la Depuración USB con
el ordenador en el que se está trabajando.

Figura 50 – Depuración aplicación Android

Página 72
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Figura 51 – Permisos depuración aplicación desde Android

A continuación se pasa a explicar la propia aplicación del audiómetro entrando en los


detalles de su programación.

Aplicación: Audiómetro
Uno de los objetivos del proyecto es diseñar una aplicación móvil que sirva de interfaz
para comunicarse con la tarjeta Raspberry Pi y poder enviar los parámetros necesarios
para generar la señal de audiometría (sinusoide) y esta pueda ser percibida por el
oyente, y a la vez obtener el audiograma, resultado de la audiometría.

En un primer momento se pensó en realizar una nueva tarjeta que sirviese de esta
interfaz, pero sus funcionalidades se quedaban limitadas, es por eso que se buscó por
nuevas soluciones. Entre ellas se descubrió que la mejor opción posible era una
aplicación sobre un dispositivo portátil como es un teléfono móvil, desde donde se
pudiese transferir estos parámetros, necesarios para la creación de los tonos de
frecuencia delimitados por la normativa anteriormente explicada.

Desde esta aplicación se desea comunicar con la tarjeta Raspberry Pi, vía UDP (por
medio de tres sockets) para modificar las características de la señal emitida, representar
el umbral de audición del oyente y generar un documento “pdf” con todos los resultados
del ensayo para posteriormente enviarlo al paciente.

Esta programación sobre Android requiere de conocimientos en Java y XML, para la


interfaz gráfica. A su vez, es necesario el uso de librerías externas para la generación del
documento PDF (Portable Document Format) y para la representación de gráficas.

La aplicación lleva por nombre “Audiometria” y la estructura de la misma se describe a


continuación (figura 52):

Página 73
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

En android cada actividad tiene su parte lógica, un archivo *.java, y su parte gráfica, un
archivo *.xml. Para poder explicar de forma correcta esta aplicación se procederá por
partes, y como el uso de la misma siempre tiene una secuencia igual, se seguirá la
secuencia de uso de la misma para poder ser explicada. Se detallará primero el código
del fichero java, cuál es el objetivo del mismo, y luego la interfaz gráfica.

Antes de proceder con ello, en la figura 52 (lado izquierdo) se ve la estructura de la


aplicación Android, con su parte de ficheros java, dividos en dos paquetes. Uno de ellos
puede ser definido como raíz (com.example.audiometria), en el que se encuentran:
MainActivity, la actividad principal; PdfManager, la gestión de la creación de la
memoria de la audiometría (la generación del documento pdf); y UdpClientThread, el
hilo que gestiona la comunicación con la RaspberryPi. El otro subpaquete (ui.main)
recoge todos los Fragment de la aplicación (los tres) y la gestión del mismo.

Por otro lado en la carpeta manifests se guarda el fichero AndroidManifest.xml


(realmente en app/src/main/res/AndroidManifest.xml), donde se recoge gran parte de la
información más importante para el desarrollo de la aplicación.

Por último mencionar la “carpeta” res, donde se encuentran las vistas (las interfaces
gráficas de la aplicación, los layout) y los valores generales como strings.xml que serán
utilizados más tarde en la aplicación.

La figura 52 (lado derecho), se muestran los archivos del proyecto: a destacar las dos
librerías externas de las que se hará uso (app/libs): GraphView-4.0.1.jar e itextpdf-
5.4.4.jar.

Página 74
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Figura 52 – Directorio de la aplicación Audiometría en AndroidStudio

En el fichero AndroidManifest.xml se indican entre otras cosas cuál será la actividad


principal de la aplicación: MainActivity y cuáles son los permisos que requiere del
sistema operativo para su correcto desarrollo: acceso a la red wifi e internet, para poder
comunicarse vía UDP con la Raspberry Pi; estado de red; y permisos para leer y escribir
en la memoria externa e interna, para poder registrar la memoria (*.pdf) de la
audiometría que realice el operario.

El detalle del código del fichero AndroidManifest.xml se muestra en el anexo 1.

Antes de adentrarse más en la aplicación combiene describir uno de los recursos


importantes para la misma que es el fichero String.xml. En él se guardan cadenas de
caracteres que serán utilizadas a posteriori en la aplicación: aquí se registran el nombre
de la aplicación (app_name), de los diversos fragments que la componen (tab_text_1,
etc) y de los Spinner que serán utilizados para la selección de diversos parámetros de la
misma (canal, frecuencia, sexo, nivel, etc).

El detalle del código del fichero Strings.xml se muestra en el anexo 2.

A continuación se explica la aplicación desde la actividad principal: MainActivity.java.


Se ha de recordar que se encuentra guardada en el paquete (com.example.audiometria).

Página 75
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Esta clase implementa las interfaces FragmentGrafica.FragmentGraficaListener,


FragmentAudiometria.FragmentAudiometriaListener,
FragmentDatos.FragmentDatosListener. Estas servirán para comunicar entre los
diferentes Fragments datos relevantes para el desarrollo de la aplicación. Este recurso
replica esos datos entre las diferentes actividades para que sean conocidos por todos y
sirve de canal de comunicación entre todos ellos. Los datos a los que se está haciendo
referencia son los siguientes: los datos de los niveles del canal izquierdo y derecho para
todas las frecuencias; el nombre, apellidos, edad, sexo y correo del sujeto sometido a la
audiometría; y el nombre, correo y teléfono del operario que realiza la audiometría.

Aparte de esto, configura el esqueleto de la aplicación, cargado a su vez en la interfaz


gráfica esqueleto de la aplicación. Hace referencia al SectionPagerAdapter, que
contendrá los diferentes Fragments de la aplicación solicitando la confirmación de los
permisos de lectura y escritura en el teléfono móvil, para poder registrar en él los
resultados de la memoria (esta reconfirmación de los permisos es obligatorio realizarla
desde las últimas versiones del sistema operativo Android).

Se muestra el código de esta clase de la aplicación: MainActivity.java, seguido del


layout de la actividad: activity_main.xml, en el anexo 3.

La siguiente clase a mencionar es la clase SectionsPagerAdapter, que hereda de


FragmentStatePagerAdapter. La función de esta es la gestión de las pestañas
anteriormente mencionadas, el manejo del número de ellas implementado (3 pestañas) y
la posición en la que se está trabajando. También fija el nombre de la misma, el cual es
obtenido del recurso antes mencionado String.xlm. Esta clase se encuentra en el
subpaquete com.example.audiometria.ui.main.

El código de esta clase se muestra en el anexo 4.

El este primer Fragment (FragmentDatos) del código destinado al registro de los datos
tanto del oyente como del operario; los cuales han de ser enviados a la actividad
principal, por medio de la interfaz: FragmentDatosListener, como ya se había
mencionado.

Esta clase queda guardada en el subpaquete com.example.audiometria.ui.main.

Por medio de Spinner y EditText se obtienen todos los datos necesarios para formalizar
el registro de los agentes implicados en la audiometría. Este registro se realiza cuando el
operario pincha en el botón de registrar datos, y estos se envían al canal de
comunicación de toda la aplicación que es la actividad principal, por medio de la
interfaz anteriormente mencionada.

Página 76
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

La vista contenida en este Fragment es el layout datos.xml. El Layout: LinearLayout


donde se ubican uno por uno todos los EditText, Spinner, etc., está contenido en un
ScrollView, el cual permite deslizar hacia abajo y hacia arriba la vista del mismo,
estéticamente ayuda al desarrollo de la aplicación para poder separar la parte del
operario y la del oyente. A destacar también en este código .xml es que el LinearLayout
distribuye linealmente todos los componentes que en él se ubican. Finaliza esta vista
con un FrameLayout en el que se contiene el botón que permite registrar la información.
Dicho botón registra la información sobreescribiéndola cada vez que es presionado.

En el anexo 5 se muestra el código de la clase, seguido del layout de la vista


correspondiente.

FragmentAudiometria es una de las más importantes de la aplicación. Ella da a lugar a


la comunicación con la Raspberry Pi. Queda recogida dicha clase en el mismo
subpaquete que el resto de Fragments: com.example.audiometria.ui.main.

Esta clase es la interfaz entre el operario y la Raspberry. En esta se selecciona (tal y


como era el objetivo primario de esta aplicación) el canal de emisión de los tonos de
frecuencia, la frecuencia de la señal (Hz) y el nivel de la misma (dB de presión sonora).

Mediante el uso de Spinner y botones para seleccionar el valor de la frecuencia y del


nivel se configura la señal que se ha de enviar al oyente. Una vez seleccionada la señal
deseada, se ha de pulsar el FloatingActionButton con el icono de play, el cual llama al
hilo (Thread) para que arranque el mismo. La programación de dicho hilo se explica en
el siguiente punto de la aplicación. Al hilo que gestiona la comunicación se le pasa
como parámetros los datos obtenidos mediante los Spinner (canal, frecuencia y nivel).

Cuando el oyente comunica al operario cuál es su umbral de audición (por medio de la


repetición de estas pruebas audiométricas) se procede a registrar el dato de este,
pulsando en el botón que permite guardar el mismo. Se definen variables de arrays de
dos dimensiones, con la intención de que se registren en ellas los datos referentes a los
niveles de audición de los dos canales para todas las frecuencias, uno para registrar los
valores (tipo double) y otro (tipo boolean) que indica cuando se han registrado todos los
valores. Una vez se pulsa el botón de registrar valores y se han guardado los datos para
todas las frecuencias, se puede proceder a la visualización de la gráfica del umbral de
audición, apareciendo un mensaje informativo para el operario de que esto ha ocurrido.
Igualmente se puede corregir el valor umbral para cualquier frecuencia y cualquier
canal, siendo registrado de nuevo el mismo.

Cada vez que se desea reproducir un tono diferente se ha de accionar el botón play
indicado. Creando un nuevo hilo en cada ocasión. Este muere cuando finaliza el envío.

Página 77
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

A su vez, se define la interfaz FragmentAudiometriaListener, que servirá para enviar al


canal de comunicación de la aplicación (la actividad principal) los datos acerca de los
niveles registrados por el operario, los cuales fijan el umbral de audición del paciente.

Dicha clase, dicho Fragment, contiene como vista el Layout llamado audiometría.xml,
que se muestra a continuación del código de la clase FragmentAudiometria. Este Layout
sigue la misma lógica que el del Fragment de datos, con la única salvedad de los
FloatingActionButton, que sirven para reproducir la señal y el segundo para indicar que
ya se encuentra accesible la gráfica de la audiometría. Este último se muestra oculto
hasta que se completa de registrar todos los valores del ensayo audiométrico, es
entonces cuando se visualiza.

En el anexo 6 se muestra el código de la clase, seguido del layout de la vista


correspondiente.

Se procede a explicar la clase del hilo que ha sido declarado en la anterior clase:
UdpClientThread. La clase se guarda en el paquete principal: com.example.audiometria.

Como se explicó en el diagrama de bloques del sistema, es necesario que se realice una
comunicación entre el teléfono móvil y la Raspberry, la cual tiene como dirección IP en
la red “VictorRaspberry”: "192.168.43.147". La Raspberry se va a encontrar
escuchando información en los puertos UDP: 26000, 26001 y 26002; en dichos puertos
se envía la siguiente información: canal, frecuencia y nivel, respectivamente.

Esta clase no contiene ninguna vista, pues es un hilo que corre ajeno al hilo principal de
la aplicación. Cada vez que se crea, arranca y muere. La clase se llama
UdpClientThread y hereda de la clase Thread.

Cuando se instancia lo hace con los valores anteriormente explicados. Cuando corre
(run) es cuando se intenta realizar estas transmisiones.

Si como parámetro del canal es igual a “Izquierdo”, entonces se transmite el valor 0


(tipo double); si es “Derecho”, se envía el valor 1. A continuación se crea un
DatagramSocket y se envía por él un DatagramPacket con los el dato del canal, la
longitud de este dato, la dirección IP donde se encuentra la Raspberry y el puerto UDP
donde se encuentra escuchando este dato. Posteriormente se produce el envío del nivel
de frecuencia. Dicho envío sigue la misma lógica, salvo que se transforma el dato
directamente recibido en un buffer de bytes para transferir este dato. Se envía al puerto
mencionado anteriormente. El siguiente dato que se envía es el nivel, con la misma
lógica que el anterior, con la salvedad de que aquí se transforman los valores de dB SPL
en valores nominales para poder ser transferidos a la Raspberry Pi. Esta conversión se
realiza por medio de los valores obtenidos en la calibración (desde los 110 dB SPL a
cada frecuencia de trabajo, hasta los -10 dB SPL).

Página 78
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

Una vez transferidos todos los DatagramPacket, a sus correspondientes socket, se


procede a cerrar estos socket, dando por finalizado el hilo y el envío.

En el anexo 7 se muestra el código. Esta clase no tiene asociado ningún layout ya que se
trata de un hilo.

Prosiguiendo con la complejidad de la aplicación, se pasa a explicar el último Fragment


de la aplicación, la última pestaña, la clase FragmentGrafica.

Al igual que el resto de Fragment este se encuentra guardado en el subpaquete:


com.example.audiometria.ui.main. La función de esta clase tiene como objetivo generar
el documento *.pdf y mostrar las gráficas relacionados con los umbrales de audición.

Se crean tres gráficos/audiogramas (GraphView, haciendo uso de la librería


correspondiente) diferentes, uno para ser mostrado al usuario/operario, y los otros dos
para generar el fichero imagen que se almacenará/copiará en la memoria de la
audiometría. La vista (layout) que contiene esta pestaña es el grafica.xml. Se encuentra
“bloqueada” y no permite bajar para ver el resto de gráficos, solo se puede ver el que se
modifica para ser mostrado al usuario. Con el Spinner que se encuentra al principio del
layout se permite seleccionar el canal que se muestra al operario.

Al comienzo de la clase se fijan los ejes de las gráficas, las leyendas de los mismos y la
estética de estas, a la vez que se agregan las series (LineGraphSeries) a los gráficos. Se
continúa instancializando los arrays referentes al valor de las frecuencias, y al array
multidimensional referente a los umbrales medios de audición, dependientes del sexo,
rango de edad y frecuencia de la población española, citados anteriormente en la
memoria del proyecto.

Por el canal de comunicación de la actividad principal, se obtienen los datos referentes


al sexo, edad del oyente, etc, que ayudan a filtrar los datos de los umbrales de audición,
y dependiendo del canal seleccionado en el Spinner se genera un gráfico u otro.
Mostrando la serie referente al umbral de audición del oyente sometido al ensayo
audiométrico, y la otra serie, media correspondiente a su edad y sexo.

A continuación se fijan los límites superior e inferior del eje de abscisas (mínima y
máxima frecuencias evaluadas).

Y un “setOnDataPointTapListener”, que permite mostrar un mensaje informativo al


operario del punto seleccionado en la serie de la gráfica.

El método “onActivityCreated” se encarga de crear los ficheros de las imágenes en la


carpeta con el nombre indicado (INVOICES_FOLDER = "Audiometrias"):
audiometria_izq.png y audiometria_dch.png, de los GraphView antes indicados, dentro
de la carpeta de Descargas del teléfono móvil.

Página 79
Diseño e implementación de un audiómetro con Raspberry Pi
Teléfono móvil con Android

El botón destinado a generar el documento pdf queda habilitado cuando se muestran los
dos canales. Habiéndose obtenido previamente, tal y como se ha mencionado, todos los
datos del oyente y del operario vía el canal de comunicación de la actividad principal, se
pasa a generar el documento pdf, que tendrá como nombre: FILENAME =
"Audiometria_" seguido del nombre y apellidos del oyente. Se creará un objeto de la
clase PdfManager, el cual por medio del método “createPdfDocument” se generará el
archivo pdf, con todos los parámetros necesarios. Una vez hecho esto, se enviará por
email el mismo con el método: “sendPdfByEmail”.

A su vez, se define una interfaz encargada de recoger los datos del canal de
comunicación creado con la actividad principal de la aplicación, llamada
“FragmentGraficaListener”.

En el anexo 8 se muestra el código de la clase, seguido del layout de la vista


correspondiente.

Por último, se explica la clase PdfManager que utiliza la librería externa


correspondiente a la generación del documento pdf. Esta clase tampoco tiene ninguna
vista (layout).

No resulta de interés explicar el código de esta clase, pues consiste en la creación de la


memoria, resultado de la audiometría realizada (en formato pdf), con los parámetros que
se le transfieren. Se crea una tabla resumen, comparando los resultados del paciente con
los típicos en su caso concreto, y se adjuntas las imágenes de las gráficas anteriormente
generadas.

Dicha clase está guardada en el paquete: com.example.audiometria. En el anexo 9 se


muestra el código de la clase.

Página 80
Diseño e implementación de un audiómetro con Raspberry Pi
Manual de usuario

Manual de usuario

Si se dispone a realizar una nueva audiometría, y es la primera vez que se enfrenta a


realizar un ensayo de este tipo, en primer lugar se debe conocer la normativa
relacionada con el tipo de audiometría con la que se va a trabajar (audiómetro de
diagnóstico, tipo 2, de tonos puros, por conducción aérea). La normativa relacionada
con las audiometrías implementadas con este tipo de audiómetro es la UNE-EN ISO
8253-1.

En un primer lugar se ha de crear una Zona WiFi desde el teléfono móvil para que se
puedan enviar datos entre los dos dispositivos. Dicha red ya está configurada y solo será
necesario activar la zona Wifi para que sea posible la comunicación entre ambos. Para
ello se ha de acceder al menú de “Ajustes”, luego a la opción de “Conexiones
inalámbricas y redes”. Se pulsa a continuación en “Anclaje y zona Wi-Fi”, después
“Zona Wi-Fi portátil”, para finalmente seleccionar “VictorRaspberry”. Ya se habrá
activado la misma y se podrá regresar al menú principal del teléfono móvil.

Figura 53 – Configuración zona Wi-Fi

Página 81
Diseño e implementación de un audiómetro con Raspberry Pi
Manual de usuario

Una vez realizadas estas acciones podrá comenzar la audiometría. Para ello ha de
conectar la tarjeta Raspberry-Pi a la corriente eléctrica, por medio de un cargador
universal USB 3.0 tipo C, y conectar los auriculares DD45 - TDH39 a la salida de
auriculares.

Una vez conectada la aplicación del audiómetro empieza a correr de forma autónoma en
la Raspberry. Está en continua espera de recibir información desde la aplicación
instalada en el móvil, sin necesidad de realizar nada más sobre el sistema de la
Raspberry.

A continuación se ha de encender la aplicación del teléfono móvil. Se accede


directamente a la aplicación desde el menú principal del teléfono, la cual ya se
encuentra instalada en el mismo.

Figura 54 – Ubicación aplicación Audiómetro

Nada más arrancar la aplicación, si es la primera vez, se solicitan los permisos de


escritura los cuales tienen que ser concedidos; en caso de haber sido concedidos
previamente la aplicación lo notifica al operario.

Página 82
Diseño e implementación de un audiómetro con Raspberry Pi
Manual de usuario

Figura 55 – Confirmación permisos de lectura/escritura

Nada más iniciar la aplicación aparece la pestaña “DATOS”. Han de ser rellenados
todos los campos: los referidos al paciente (con especial relevancia a la edad y al sexo
son obligatorios) y los del operario (visibles utilizando la pestaña hacia abajo).

Una vez estos han sido rellenados, se ha de pulsar en “REGISTRAR DATOS” para que
estos sean guardados. Si esto se ha realizado correctamente la aplicación lo notifica al
operario con el siguiente mensaje: “Se han registrado los datos del paciente”. En el caso
de que haya habido un error se puede volver a pulsar en “REGISTRAR DATOS”.

Figura 56 – Pestaña “DATOS”

A continuación comienza la audiometría. Se ha de ir configurando continuamente el


canal por el que se desea emitir, la frecuencia del tono y el nivel con el que se desea
Página 83
Diseño e implementación de un audiómetro con Raspberry Pi
Manual de usuario

reproducir, pulsando play a continuación. Se reproduce y se va modificando el nivel


para esa frecuencia hasta que se encuentra el nivel umbral de audición. Cuando este es
obtenido se pulsa en “REGISTRAR DATO” y se repite el proceso para el resto de
frecuencias y canales.

Figura 57 – Pestaña “CONFIGURACIÓN AUDIOMETRÍA”

Una vez se han registrado todos los valores (de 125Hz – 8000Hz, para los dos canales)
el programa indica al operario que ya “Se ha dibujado la gráfica” y se indica en la
esquina derecha un icono de una gráfica, indicando al operario que ya puede pasar a la
siguiente pestaña para ver los resultados. Igualmente todavía puede ser modificada
alguna frecuencia si así lo desea el operario.

Página 84
Diseño e implementación de un audiómetro con Raspberry Pi
Manual de usuario

Figura 58 – Pestaña “CONFIGURACIÓN AUDIOMETRÍA”, creación de gráfica

En la última pestaña de la aplicación pueden verse representados los umbrales de


audición del oyente para los dos canales, seleccionando cada uno de ellos. Para poder
descargarse la memoria de la audiometría se han de visualizar desde la aplicación los
dos canales.

Figura 59 – Pestaña “RESULTADO”

Página 85
Diseño e implementación de un audiómetro con Raspberry Pi
Manual de usuario

Como una utilidad añadida de la gráfica se puede pulsar en cualquier valor de las dos
series que se representan y ver su valor para la frecuencia seleccionada, indicando a su
vez la serie que ha sido escogida.

La serie “Media” (color rojo) indica la media del umbral de audición para el rango de
edad y sexo seleccionado por el operario al que pertenece el paciente.

La serie “Paciente” (color azul) es el umbral de audición para el oyente que se ha


sometido a la audiometría.

Una vez hecho esto se visualiza y habilita el botón “GENERAR Y ENVIAR PDF”. Se
selecciona el método/aplicación de envío. Finaliza enviando al oyente sus resultados por
la vía de envío escogida.

Figura 60 – Envío de los resultados de la audiometría

Para realizar otra audiometría justo a continuación conviene, cerrar la aplicación y


volver a ser abierta de nuevo.

Página 86
Diseño e implementación de un audiómetro con Raspberry Pi
Resultados

Resultados

En las figuras 61,62 y 63 se muestra el resultado de la audiometría de un paciente. Se


trata del documento que se obtiene como resultado de la medición.

Figura 61 – Datos del oyente

Figura 62 – Resultados del oyente canal izquierdo

Página 87
Diseño e implementación de un audiómetro con Raspberry Pi
Resultados

Figura 63 – Resultados del oyente canal derecho

Página 88
Diseño e implementación de un audiómetro con Raspberry Pi
Presupuesto

Presupuesto

El presupuesto indicado en la tabla 11 sólo se refiere al coste de los distintos elementos


hardware. No se hace referencia alguna a otro tipo de coste que no sea el coste de los
diferentes dispositivos hardware.

Tabla 11 – Presupuesto
PRECIO Presupuesto parcial
ARTÍCULO UNIDADES
(EUR €)/Unidad (EUR €)

Placa de desarrollo
Raspberry Pi 3 Modelo B+ 1 35,66
BCM2837B0 – MPU 35,66

(Más información: https://es.rs-online.com/web/p/kits-de-desarrollo-de-procesador-y-


microcontrolador/1373331/?sra=pmpn )
,

Tarjeta de memoria micro


1 7,30
SDHC 32 GB. Clase 10
7,30
(Más información: https://www.pccomponentes.com/samsung-microsdhc-evo-plus-32gb-
clase-10-adaptador )
,

Tarjeta de sonido estéreo


1 18,50
Audio injector
18,50
,

(Más información: https://www.amazon.es/Tarjeta-sonido-Raspberry-micr%C3%B3fono-


incorporado/dp/B01HCC0210/ref=sr_1_1?ie=UTF8&qid=1512466365&sr=8-
1&keywords=audioinjector )
,

Cable audio mini Jack


estéreo macho a 2 RCA 1 1,80 1,80
Macho, 1.5mts

Auriculares DD45 - TDH39


1 142,68
Headsets (*)
142,68
(Más información: https://es.aliexpress.com/item/TDH-39-Audiometer-Earphone-
Sets/1693413286.html
,

Presupuesto general (EUR €) 205,94

(*) Son artículos aportados por la Universidad Politécnica de Madrid (UPM).

Página 89
Diseño e implementación de un audiómetro con Raspberry Pi
Conclusiones

Conclusiones

El proyecto cumple con los objetivos planteados en un principio. Se ha de recordar que


fueron el diseño e implementación de un audiómetro de diagnóstico (tipo II) sobre la
tarjeta Raspberry-Pi, respetando todas las normativas relacionadas con la
implementación del mismo.

Se trata de un sistema de bajo coste que puede ser replicado y utilizado en entornos con
bajos presupuestos, para tener control sobre la población en este problema de la pérdida
de capacidad auditiva, ya que si esta no es controlada puede derivar en años de
discapacidad y pérdida de calidad de vida.

Tanto la aplicación desarrollada sobre la Raspberry, como la aplicación en el teléfono


móvil cumplen con los objetivos secundarios que fueron ideados, y funcionan
correctamente sin ningún tipo de error.

Hay ciertos aspectos de la normativa que no han sido implementados, como la


comunicación operario – oyente, que resultaría de interés si los ensayos audiométricos
se realizasen en salas de ensayos insonorizadas, destinadas a la realización de estas
pruebas, pero dado que los ensayos no se realizan de esta manera no resultaba necesario
implementar este apartado. Como tampoco se trabajan con las frecuencias por encima
de 8kHz, las cuales la normativa no obliga hacerlo, y dado que la respuesta en
frecuencia de los auriculares con los que se realiza el ensayo no es plana, tampoco es de
interés generar estos tonos, puesto que los resultados pueden ser incorrectos. De un
modo similar ocurre con la señal de enmascaramiento; sería una posibles mejora a
añadir en una actualización futura.

En un principio, en el desarrollo del diseño de la aplicación se pensó en la


implementación de una tarjeta HAT (Hardware Attached on Top) colocada sobre los
pines GPIO de la tarjeta de sonido, en la que el operario pudiese modificar los niveles y
las frecuencias de ensayo, además del canal de emisión. Esta idea se desechó porque se
veía que podía quedarse incompleto el desarrollo del audiómetro y daría dificultades al
operario a la hora de trabajar. Se optó por el diseño de esta aplicación en Android, que
finalmente es realmente versátil, y permite ser ampliada en un futuro con facilidad, en el
caso de que la norma cambiase, o en el caso que se quisiese añadir más funciones a la
misma. Además emite fácilmente los resultados al usuario que se somete a la prueba. En
caso contrario daría grandes problemas si se quisiera realizar esta funcionalidad sobre
esa posible tarjeta HAT.

Del mismo modo, se dudó en el protocolo de comunicación entre el dispositivo Android


y la Raspberry-Pi, esto fue tomando diferentes formas. En un principio fue ideada la
comunicación sobre Bluetooth, pero había poca documentación para ser implementado
esto con MATLAB/Simulink en la Raspberry; tras ser trabajado se pensó en otros
modos de comunicarse más sencillos que este. En segundo lugar se ideó una

Página 90
Diseño e implementación de un audiómetro con Raspberry Pi
Conclusiones

comunicación por un dispositivo USB OTG desde el teléfono móvil, que se comunicaba
con la Raspberry vía cable Ethernet (conector RJ45); viendo que el operario debía estar
conectado de una forma poco cómoda al manejo del dispositivo, se acabó desechando;
y, por último, se optó por la comunicación vía UDP, bajo una red creada por el mismo
dispositivo móvil. Esta fue la más útil, cómoda y efectiva forma de realizar la
comunicación.

La valoración de los resultados obtenidos, con el uso del sistema implementado,


guardan correlación con los umbrales medios de audición de la población española,
sacados de la tesis doctoral mencionada en el desarrollo de la memoria. Desde aquí
quisiera agradecer a todas las personas que se han ofrecido a realizar la audiometría.

Como valoración personal de la implementación del audiómetro tipo II (destinado a


realizar audiometrías por vía aérea, de tonos puros, en el rango de frecuencias
comprendidas en el rango de 125 Hz a 8 kHz), me encuentro satisfecho, ya que aparte
de haber cumplido con los objetivos definidos al comienzo del proyecto, he adquirido
conocimientos sobre trabajar con la tarjeta de sonido AudioInjector, y lo más importante
con la placa de Raspbery-Pi, aprendiendo a programar con MATLAB/Simulink para la
placa, y gestionando los protocolos de comunicación entre los dos dispositivos, y
trabajando en ellos con lenguajes de programación diferentes.

Entre las futuras líneas de mejora del audiómetro implementado se encuentran las
siguientes: adaptar el mismo para poder cumplir con otras normativas, realizar
audiometrías para señales vocales, señales de ensayo de duración corta, audiometrías de
alta frecuencia extendida, audiometrías por vía ósea, etc.; diferenciando las nuevas
funcionalidades agregadas a las actuales. Concretando qué clase de audiómetro es cada
uno, y si cumple o no las normativas oportunas. Del mismo modo se pueden
implementar los requisitos oportunos para que el audiómetro que se ha diseñado en este
proyecto cumpla con los requisitos de un audiómetro tipo 1.

Otra de las posibles mejoras que pudiese tener la aplicación es la de implementar, en el


teléfono móvil, un algoritmo que permitiese agregar de forma sencilla calibraciones
para distintos auriculares, y tenerlo registrado en memoria, permitiéndose trabajar con
diferentes auriculares.

Otra mejora de interés para el correcto cumplimiento de la normativa referenciada en la


memoria sería permitir trabajar con ruido enmascarante a la hora de la realización de las
audiometrías, e implementar la comunicación entre el operario y el oyente (el hardware
de la tarjeta de sonido Audio Injector y el teléfono móvil permite que esto se realice).

Página 91
Diseño e implementación de un audiómetro con Raspberry Pi
Referencias

Referencias

[1] Rodríguez Valiente, Antonio (2015). Determinación de los umbrales de audición en


la población española. Patrones de normalidad de la totalidad del espectro auditivo
humano. (Tesis doctoral). UNIVERSIDAD AUTÓNOMA DE MADRID, Madrid,
[disponible on-line:
https://repositorio.uam.es/bitstream/handle/10486/667533/rodriguez_valiente_antonio.p
df], consultado en mayo de 2019.

[2] Fundación Raspberry Pi. (Sin fecha). Raspberry Pi 3 Model B+, [disponible on-
line: https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/], consultado en
Abril de 2019.

[3] Audio Injector. (Sin fecha). Stereo Raspberry pi sound card, [disponible on-line:
http://www.audioinjector.net/rpi-hat], consultado en Abril de 2019.

[4] Raspberry Pi. (Sin fecha). Wikipedia, [disponible on-line:


https://es.wikipedia.org/wiki/Raspberry_Pi], consultado en Mayo de 2019.

[5] AENOR, Electroacústica. Equipos audiométricos. Parte 1: Equipos para la


audiometría de tonos puro, UNE-EN 60645-1:2015, enero de 2015.

[6] AENOR, Acústica. Métodos de ensayo audiométricos. Parte 1: Audiometría de


tonos puros por conducción aérea y por conducción, UNE-EN ISO 8253-1:2011,
noviembre de 2010.

[7] AENOR, Acústica. Líneas isofónicas normales., UNE-ISO 226-1:2013, septiembre


de 2013.

[8] Fundación Raspberry Pi. (2015). Raspberry Pi Logo. [Figura]. Recuperado de


https://www.raspberrypi.org/trademark-rules/.

[9] MATLAB. (Sin fecha). Wikipedia, [disponible on-line:


https://es.wikipedia.org/wiki/MATLAB], consultado en Junio de 2019.

[10] Raspberry Pi Spy. (2012). Raspberry Pi 40-pin GPIO Layout. [Figura].


Recuperado de https://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-
header-and-pins/#prettyPhoto/1/.

[11] Android. (Sin fecha). Wikipedia, [disponible on-line:


https://es.wikipedia.org/wiki/Android], consultado en Junio de 2019.

[12] Huawei. (Sin fecha). Huawei P20 Lite, [disponible on-line:


https://consumer.huawei.com/es/support/phones/p20-lite/], consultado en Junio de 2019.

Página 92
Diseño e implementación de un audiómetro con Raspberry Pi
Referencias

[13] Android. (2016). Logo de Android Studio. [Figura]. Recuperado de


https://commons.wikimedia.org/wiki/File:Android_Studio_icon.svg.

Página 93
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexos

Anexo 1: Código AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.audiometria">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="com.example.audiometria.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW"/>
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="${applicationId}">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths"/>
</provider>
</application>

<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.READ_INTERNAL_STORAGE"/>
</manifest>

Página 94
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 2: Código String.xml


<resources>
<string name="app_name">Audiómetro</string>
<string name="tab_text_1">Datos</string>
<string name="tab_text_2">Configuración Audiometría</string>
<string name="tab_text_3">Resultado</string>

<string-array name="canalGrafica">
<item>Seleccionar Canal:</item>
<item>Canal: Izquierdo</item>
<item>Canal: Derecho</item>
</string-array>

<string-array name="canal">
<item>Izquierdo</item>
<item>Derecho</item>
</string-array>

<string-array name="sexo">
<item>...</item>
<item>Hombre</item>
<item>Mujer</item>
</string-array>

<string-array name="frecuencia">
<item>125</item>
<item>250</item>
<item>500</item>
<item>1000</item>
<item>2000</item>
<item>4000</item>
<item>8000</item>
</string-array>

<string-array name="nivel">
<item>-10</item>
<item>-5</item>
<item>0</item>
<item>5</item>
<item>10</item>
<item>15</item>
<item>20</item>
<item>25</item>
<item>30</item>
<item>35</item>
<item>40</item>
<item>45</item>
<item>50</item>
<item>55</item>
<item>60</item>
<item>65</item>
<item>70</item>
<item>75</item>
<item>80</item>
<item>85</item>
<item>90</item>
<item>95</item>

Página 95
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<item>100</item>
<item>105</item>
<item>110</item>
</string-array>
</resources>

Página 96
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 3: MainActivity
package com.example.audiometria;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.widget.Toast;

import com.example.audiometria.ui.main.FragmentDatos;
import com.example.audiometria.ui.main.FragmentGrafica;
import com.example.audiometria.ui.main.FragmentAudiometria;
import com.example.audiometria.ui.main.SectionsPagerAdapter;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends FragmentActivity implements


FragmentGrafica.FragmentGraficaListener,
FragmentAudiometria.FragmentAudiometriaListener,
FragmentDatos.FragmentDatosListener{

SectionsPagerAdapter sectionsPagerAdapter;
ViewPager viewPager;
private List<Fragment> listaFragments;
public double[] datosIzq,datosDer;
public String
nombre,apellidos,edad,sexo,correo,nombreTecnico,correoTecnico,telefono
Tecnico;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

datosDer = new double[7];


for(int x=0;x<datosDer.length;x++)
datosDer[x]=-2;
datosIzq = new double[7];
for(int x=0;x<datosIzq.length;x++)
datosIzq[x]=-2;

// Creamos una lista de Fragments


listaFragments = new ArrayList<Fragment>();
listaFragments.add(new FragmentDatos());
listaFragments.add(new FragmentAudiometria());
listaFragments.add(new FragmentGrafica());

sectionsPagerAdapter = new
SectionsPagerAdapter(this,getSupportFragmentManager(),
listaFragments);

Página 97
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

// Instanciamos nuestro ViewPager


viewPager = findViewById(R.id.view_pager);

// Establecemos el Adapter
viewPager.setAdapter(sectionsPagerAdapter);

TabLayout tabs = findViewById(R.id.tabs);


tabs.setupWithViewPager(viewPager);

//TabLayout
tabs.setTabMode(TabLayout.MODE_FIXED);

// Permisos
//if (Build.VERSION.SDK_INT >= 23) { //permission is
automatically granted on sdk<23 upon installation
if(ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED &&
//ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) !=
ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,},
1000);
}
else{
Toast.makeText(this, "Tiene permisos de lectura y
escritura en la memoria" , Toast.LENGTH_LONG).show();
}
}

@Override
public void onDatosIngresados(double[] datosIzq, double[]
datosDer) {
this.datosIzq = datosIzq;
this.datosDer = datosDer;
}

@Override
public double[] getDatosIzq() {
return this.datosIzq;
}

@Override
public double[] getDatosDer() {
return this.datosDer;
}

@Override
public String getNombre() {
return this.nombre;
}

@Override
public String getApellidos() {
return this.apellidos;

Página 98
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

@Override
public String getEdad() {
return this.edad;
}

@Override
public String getSexo() {
return this.sexo;
}

@Override
public String getCorreo() {
return this.correo;
}

@Override
public String getNombreTecnico() {
return this.nombreTecnico;
}

@Override
public String getCorreoTecnico() {
return this.correoTecnico;
}

@Override
public String getTelefonoTecnico() {
return this.telefonoTecnico;
}

@Override
public void onDatosPacienteIngresados(String nombre, String
apellidos, String edad, String sexo, String correo,
String nombreTecnico, String
correoTecnico, String telefonoTecnico) {
this.nombre = nombre;
this.apellidos = apellidos;
this.edad = edad;
this.sexo = sexo;
this.correo = correo;
this.nombreTecnico = nombreTecnico;
this.correoTecnico = correoTecnico;
this.telefonoTecnico = telefonoTecnico;
}
}

Página 99
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="?actionBarSize"
android:padding="@dimen/appbar_padding"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar
.Title" />

<android.support.v7.widget.Toolbar
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="23dp"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|enterAlways"

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"></android.support
.v7.widget.Toolbar>

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>

</android.support.design.widget.CoordinatorLayout>

Página 100
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 4: SectionPagerAdapter
package com.example.audiometria.ui.main;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.example.audiometria.R;
import java.util.List;

/**
* A [FragmentPagerAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/

public class SectionsPagerAdapter extends FragmentStatePagerAdapter{

@StringRes
private static final int[] TAB_TITLES = new
int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
private List<Fragment> fragments;

public SectionsPagerAdapter(Context context, FragmentManager fm,


List<Fragment> fragments) {
super(fm);
mContext = context;
// TODO Auto-generated constructor stub
this.fragments = fragments;
}

@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given
page.
// Return a PlaceholderFragment (defined as a static inner
class below).
return fragments.get(position);
}

@Nullable
@Override
public CharSequence getPageTitle(int position) {
return
mContext.getResources().getString(TAB_TITLES[position]);
}

@Override
public int getCount() {
// Show 3 total pages.
return 3; // return fragments.size();
}
}

Página 101
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 5: FragmentDatos
package com.example.audiometria.ui.main;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.support.v4.app.Fragment;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.example.audiometria.R;

/**
* A placeholder fragment containing a simple view.
*/

public class FragmentDatos extends Fragment {

private FragmentDatosListener listener;


Button buttonPaciente;
TextView
Nombre,Apellidos,Edad,Correo,NombreTecnico,CorreoTecnico,TelefonoTecni
co;
Spinner Sexo;

@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof FragmentDatosListener){
this.listener = (FragmentDatosListener) context;
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.datos, container, false);


buttonPaciente = v.findViewById(R.id.buttonDatosPaciente);
Nombre = v.findViewById(R.id.editTextNombre);
Apellidos = v.findViewById(R.id.editTextApellidos);
Edad = v.findViewById(R.id.editTextEdad);
Sexo = v.findViewById(R.id.spinnerSexo);
Correo = v.findViewById(R.id.editCorreoPaciente);
NombreTecnico = v.findViewById(R.id.editTextNombreTecnico);
CorreoTecnico = v.findViewById(R.id.editTextCorreoTecnico);
TelefonoTecnico =
v.findViewById(R.id.editTextTelefonoTecnico);

// TODO Auto-generated method stub


return v;
}

Página 102
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
buttonPaciente.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
listener.onDatosPacienteIngresados(Nombre.getText().toString(),Apellid
os.getText().toString(),
Edad.getText().toString(),(String)Sexo.getSelectedItem().toString(),Co
rreo.getText().toString(),
NombreTecnico.getText().toString(),CorreoTecnico.getText().toString(),
TelefonoTecnico.getText().toString());

Toast.makeText(arg0.getContext(), "Se han registrado


los datos del paciente. ", Toast.LENGTH_SHORT).show();
}
});
}

public interface FragmentDatosListener{


public void onDatosPacienteIngresados(String nombre, String
apellidos, String edad, String sexo, String correo,
String nombreTecnico,
String correoTecnico, String telefonoTecnico);
}
}

Página 103
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.PlaceholderFragment">

<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<LinearLayout
android:layout_width="395dp"
android:layout_height="715dp"
android:orientation="vertical"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="6dp"
app:layout_constraintStart_toStartOf="parent">

<Space
android:layout_width="match_parent"
android:layout_height="25dp" />

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nombre"
android:textSize="24sp"
android:textStyle="bold" />

<EditText
android:id="@+id/editTextNombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:hint=" ..." />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Apellidos"
android:textSize="24sp"
android:textStyle="bold"/>

Página 104
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<EditText
android:id="@+id/editTextApellidos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:hint=" ..." />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Edad"
android:textSize="24sp"
android:textStyle="bold"/>

<EditText
android:id="@+id/editTextEdad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:maxLength="2"
android:hint=" ..." />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<TextView
android:id="@+id/textView8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sexo"
android:textSize="24sp"
android:textStyle="bold"/>

<Spinner
android:id="@+id/spinnerSexo"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:entries="@array/sexo" />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<TextView
android:id="@+id/textView33"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Correo"
android:textSize="24sp"
android:textStyle="bold"/>

Página 105
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<EditText
android:id="@+id/editCorreoPaciente"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textEmailAddress"
android:hint=" ..." />

<Space
android:layout_width="match_parent"
android:layout_height="170dp" />

<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nombre Técnico"
android:textSize="24sp"
android:textStyle="bold"/>

<EditText
android:id="@+id/editTextNombreTecnico"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Víctor Manuel Díaz Conejo" />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Correo Técnico"
android:textSize="24sp"
android:textStyle="bold"/>

<EditText
android:id="@+id/editTextCorreoTecnico"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textEmailAddress"
android:text="[email protected]" />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<TextView
android:id="@+id/textView6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Teléfono Técnico"
android:textSize="24sp"

Página 106
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

android:textStyle="bold"/>

<EditText
android:id="@+id/editTextTelefonoTecnico"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="phone"
android:text="916875234" />

<Space
android:layout_width="match_parent"
android:layout_height="70dp" />

</LinearLayout>

</ScrollView>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/buttonDatosPaciente"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Registrar Datos" />

</FrameLayout>

</android.support.constraint.ConstraintLayout>

Página 107
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 6: FragmentAudiometria
package com.example.audiometria.ui.main;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;

import com.example.audiometria.R;
import com.example.audiometria.UdpClientThread;

public class FragmentAudiometria extends Fragment {

FloatingActionButton fab,grafica;
UdpClientHandler udpClientHandler;

FloatingActionButton butMasFrec, butMenFrec;


FloatingActionButton butMasNiv, butMenNiv;

Button butregistrarDato;

double[][]datos;
boolean[][]datosBoolean;

Spinner canal,frecuencia,nivel;

UdpClientThread udpClientThread;

private FragmentAudiometriaListener listener;

@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof FragmentAudiometriaListener){
this.listener = (FragmentAudiometriaListener) context;
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {

// TODO Auto-generated method stub


View v = inflater.inflate(R.layout.audiometria, container,
false);
canal = (Spinner) v.findViewById(R.id.spinnerCanal);
frecuencia = (Spinner) v.findViewById(R.id.spinnerFrecuencia);

Página 108
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

nivel = (Spinner) v.findViewById(R.id.spinnerNivel);


butMasFrec = v.findViewById(R.id.buttonMasFreq);
butMenFrec = v.findViewById(R.id.buttonMenosFreq);
butMasNiv = v.findViewById(R.id.buttonMasNivel);
butMenNiv = v.findViewById(R.id.buttonMenosNivel);
butregistrarDato = v.findViewById(R.id.buttonRegistrarDato);

datos = new double[canal.getCount()][frecuencia.getCount()];


datosBoolean = new
boolean[canal.getCount()][frecuencia.getCount()];

for(int x=0;x<(canal.getCount()-1);x++) {
for (int y = 0; y <(frecuencia.getCount()-1); y++) {
datosBoolean[x][y] = false;
datos[x][y] = 0;
}
}
fab = v.findViewById(R.id.fab);
grafica = v.findViewById(R.id.grafica);
udpClientHandler = new UdpClientHandler(this);

return v;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);

butMasFrec.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if
(frecuencia.getSelectedItemPosition()<(frecuencia.getCount()-1))
frecuencia.setSelection(frecuencia.getSelectedItemPosition()+1);
}
});
butMenFrec.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (frecuencia.getSelectedItemPosition()>(0))
frecuencia.setSelection(frecuencia.getSelectedItemPosition()-1);
}
});
butMasNiv.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (nivel.getSelectedItemPosition()<(nivel.getCount()-
1))
nivel.setSelection(nivel.getSelectedItemPosition()+1);
}
});

Página 109
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

butMenNiv.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (nivel.getSelectedItemPosition()>(0))
nivel.setSelection(nivel.getSelectedItemPosition()-1);
}
});

butregistrarDato.setOnClickListener(new View.OnClickListener()
{
@SuppressLint("RestrictedApi")
@Override
public void onClick(View arg0) {
datos[canal.getSelectedItemPosition()][frecuencia.getSelectedItemPosit
ion()] = Double.parseDouble(nivel.getSelectedItem().toString());

datosBoolean[canal.getSelectedItemPosition()][frecuencia.getSelectedIt
emPosition()] = true;

Toast.makeText(arg0.getContext(), "Se ha registrado


este umbral a la frecuencia indicada. ", Toast.LENGTH_SHORT).show();

// TODO Auto-generated method stub


boolean enviar = true;

for(int x=0;x<(canal.getCount());x++) {
for (int y = 0; y <(frecuencia.getCount()); y++) {
if(datosBoolean[x][y] == false){
enviar = false;
}
}
}
if(enviar == true){
grafica.setVisibility(View.VISIBLE);
//AQUÍ SE ENVÍA TODO
listener.onDatosIngresados(datos[0],datos[1]);
Snackbar.make(arg0, "Se ha dibujado ya la
gráfica.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
});
//Enviar datos a la Raspberry-Pi
fab.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Snackbar.make(arg0, "Se va a reproducir el tono
indicado", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();

udpClientThread = new UdpClientThread(


(String)canal.getSelectedItem().toString(),
(String)frecuencia.getSelectedItem().toString(),
(String)nivel.getSelectedItem().toString(),
udpClientHandler);

Página 110
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

udpClientThread.start();
}
});
}
private void updateState(String state){
}
private void updateRxMsg(String rxmsg){
}
private void clientEnd(){
udpClientThread = null;
fab.setEnabled(true);
}
public static class UdpClientHandler extends Handler {
public static final int UPDATE_STATE = 0;
public static final int UPDATE_MSG = 1;
public static final int UPDATE_END = 2;
private FragmentAudiometria parent;

public UdpClientHandler(FragmentAudiometria parent) {


super();
this.parent = parent;
}

@Override
public void handleMessage(Message msg) {
switch (msg.what){
case UPDATE_STATE:
parent.updateState((String)msg.obj);
break;
case UPDATE_MSG:
parent.updateRxMsg((String)msg.obj);
break;
case UPDATE_END:
parent.clientEnd();
break;
default:
super.handleMessage(msg);
}
}
}
public interface FragmentAudiometriaListener{
public void onDatosIngresados(double[] datosIzq, double[]
datosDer);
}
}

Página 111
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.PlaceholderFragment">

<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"
tools:ignore="MissingConstraints">

<Space
android:layout_width="match_parent"
android:layout_height="25dp" />

<TextView
android:id="@+id/textViewCanal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="Canal"
android:textSize="30sp"
android:textStyle="bold" />

<Spinner
android:id="@+id/spinnerCanal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="35dp"
android:entries="@array/canal" />

<Space
android:layout_width="match_parent"
android:layout_height="25dp" />

<TextView
android:id="@+id/textViewFrecuencia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="Frecuencia"
android:textSize="30sp"
android:textStyle="bold" />

<FrameLayout
android:layout_width="match_parent"

Página 112
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

android:layout_height="wrap_content">

<android.support.design.widget.FloatingActionButton
android:src="@android:drawable/button_onoff_indicator_on"
android:id="@+id/buttonMenosFreq"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
app:backgroundTint="#003F3D3D"
app:borderWidth="5dp" />

<Spinner
android:id="@+id/spinnerFrecuencia"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@null"
android:entries="@array/frecuencia" />

<android.support.design.widget.FloatingActionButton
android:id="@+id/buttonMasFreq"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:clickable="true"
android:src="@android:drawable/ic_input_add"
app:backgroundTint="#8B6D6B6B"
app:borderWidth="5dp"
app:rippleColor="#003F3D3D" />
</FrameLayout>

<Space
android:layout_width="match_parent"
android:layout_height="40dp" />

<TextView
android:id="@+id/textViewNivel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="Nivel"
android:textSize="30sp"
android:textStyle="bold" />

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.design.widget.FloatingActionButton
android:id="@+id/buttonMenosNivel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:src="@android:drawable/button_onoff_indicator_on"
app:backgroundTint="#003F3D3D"
app:borderWidth="22dp" />

<Spinner
android:id="@+id/spinnerNivel"

Página 113
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@null"
android:entries="@array/nivel" />

<android.support.design.widget.FloatingActionButton
android:id="@+id/buttonMasNivel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:clickable="true"
android:src="@android:drawable/ic_input_add"
app:backgroundTint="#8B6D6B6B"
app:borderWidth="5dp" />
</FrameLayout>

<Space
android:layout_width="match_parent"
android:layout_height="50dp"/>

<Button
android:id="@+id/buttonRegistrarDato"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Registrar Dato" />

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.FloatingActionButton
android:id="@+id/grafica"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:visibility="invisible"
app:srcCompat="@android:drawable/ic_menu_report_image"
/>

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_media_play" />
</FrameLayout>
</LinearLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>

Página 114
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 7: UDPClientThread
package com.example.audiometria;

import android.os.Message;
import com.example.audiometria.ui.main.FragmentAudiometria;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

public class UdpClientThread extends Thread {


String dstAddress;
int dstPort1,dstPort2,dstPort3;
String canal, frecuencia, nivel;
private boolean running;
FragmentAudiometria.UdpClientHandler handler;

//DatagramSocket socket;
InetAddress address;

public UdpClientThread(String canal, String frecuencia, String


nivel, FragmentAudiometria.UdpClientHandler handler) {
super();

dstAddress = "192.168.43.147"; //Conectado con la zona wifi


del móvil
dstPort1 = 26000;
dstPort2 = 26001;
dstPort3 = 26002;

this.canal = canal;
this.frecuencia = frecuencia;
this.nivel = nivel;
this.handler = handler;
}

public void setRunning(boolean running){


this.running = running;
}

private void sendState(String state){


handler.sendMessage(
Message.obtain(handler,
FragmentAudiometria.UdpClientHandler.UPDATE_STATE, state));
}

@Override
public void run() {
running = true;

try {
DatagramSocket socketCanal = new DatagramSocket();
address = InetAddress.getByName(dstAddress);

if(canal.equals("Izquierdo")) {//Bypass: "1" derecho / "0"


izquierdo

Página 115
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

double value = 0;
byte[] bufCanal = new byte[8];
ByteBuffer buffer =
ByteBuffer.allocate(bufCanal.length);
buffer.putDouble(value);
DatagramPacket packetCanal =
new DatagramPacket(buffer.array(),
buffer.array().length, address, dstPort1);
socketCanal.send(packetCanal);
}else if(canal.equals("Derecho")){
double value = 1;
byte[] bufCanal = new byte[8];
ByteBuffer buffer =
ByteBuffer.allocate(bufCanal.length);
byte[] output = new byte[8];
long lng = Double.doubleToLongBits(value);
for(int i = 0; i < 8; i++) output[i] = (byte)((lng >>
((i) * 8)) & 0xff);

buffer.putDouble(value);
DatagramPacket packetCanal =
new DatagramPacket(output, output.length,
address, dstPort1);
socketCanal.send(packetCanal);
}

DatagramSocket socketFrecuencia = new DatagramSocket();


address = InetAddress.getByName(dstAddress);
double vIntFrecuencia = Double.parseDouble(frecuencia);
byte[] bufFrecuencia = new byte[8];
ByteBuffer bufferFrecuencia =
ByteBuffer.allocate(bufFrecuencia.length);

byte[] outputFrec = new byte[8];


long lngFrec = Double.doubleToLongBits(vIntFrecuencia);
for(int i = 0; i < 8; i++) outputFrec[i] = (byte)((lngFrec
>> ((i) * 8)) & 0xff);

bufferFrecuencia.putDouble(vIntFrecuencia);
DatagramPacket packetFrecuencia =
new DatagramPacket(outputFrec, outputFrec.length,
address, dstPort2);
socketFrecuencia.send(packetFrecuencia);

DatagramSocket socketNivel = new DatagramSocket();


double vIntNivel = Double.parseDouble(nivel);
byte[] bufNivel = new byte[8];
ByteBuffer bufferNivel =
ByteBuffer.allocate(bufNivel.length);
double exponente=(110-vDoubleNivel)/5;
double vNominalNivel=0;

double base = 0.562341325190349;


double reduc = (double) Math.pow(base, exponente);

if(canal.equals("Izquierdo")){
if(vIntFrecuencia==125){
vNominalNivel = 0.0386 * reduc;
}else if(vIntFrecuencia==250){

Página 116
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

vNominalNivel = 0.0328 * reduc;


}else if(vIntFrecuencia==500){
vNominalNivel = 0.034 * reduc;
}else if(vIntFrecuencia==1000){
vNominalNivel = 0.0395 * reduc;
}else if(vIntFrecuencia==2000){
vNominalNivel = 0.0375 * reduc;
}else if(vIntFrecuencia==4000){
vNominalNivel = 0.1 * reduc;
}else if(vIntFrecuencia==8000){
vNominalNivel = 0.144 * reduc;
}
}
else if(canal.equals("Derecho")){
if(vIntFrecuencia==125){
vNominalNivel = 0.105 * reduc;
}else if(vIntFrecuencia==250){
vNominalNivel = 0.04 * reduc;
}else if(vIntFrecuencia==500){
vNominalNivel = 0.0235 * reduc;
}else if(vIntFrecuencia==1000){
vNominalNivel = 0.029 * reduc;
}else if(vIntFrecuencia==2000){
vNominalNivel = 0.025 * reduc;
}else if(vIntFrecuencia==4000){
vNominalNivel = 0.074 * reduc;
}else if(vIntFrecuencia==8000){
vNominalNivel = 0.098 * reduc;
}
}
byte[] bufNivel = new byte[8];
ByteBuffer bufferNivel =
ByteBuffer.allocate(bufNivel.length);

byte[] outputNiv = new byte[8];


long lngNiv = Double.doubleToLongBits(vNominalNivel);
for(int i = 0; i < 8; i++) outputNiv[i] = (byte)((lngNiv
>> ((i) * 8)) & 0xff);

bufferNivel.putDouble(vNominalNivel);
DatagramPacket packet =
new DatagramPacket(outputNiv, outputNiv.length,
address, dstPort3);
socketNivel.send(packet);
socketCanal.close();
socketFrecuencia.close();
socketNivel.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Página 117
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 8: FragmentGrafica
package com.example.audiometria.ui.main;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;

import com.example.audiometria.PdfManager;
import com.itextpdf.text.DocumentException;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.DataPointInterface;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.jjoe64.graphview.series.OnDataPointTapListener;
import com.jjoe64.graphview.series.Series;
import com.example.audiometria.R;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class FragmentGrafica extends Fragment{


Button butPdf;
private FragmentGraficaListener listener;

private Spinner canal;//, frecuencias;


private List<String> listaCanal;

public LineGraphSeries<DataPoint> mSerie, mSerieIzq,mSerieDch;


public LineGraphSeries<DataPoint> serieEdad;
public int canalGrafica;
public View v;
public double[] frecuencia;
public double[][][] umbralEdad;
public boolean booleanIzq = false;
public boolean booleanDer = false;

private String INVOICES_FOLDER = "Audiometrias";


private String FILENAME = "Audiometria_";
//Declaramos la clase PdfManager
private PdfManager pdfManager = null;
public String
nombre,apellidos,edad,sexo,correoPaciente,nombreTecnico,correoTecnico,

Página 118
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

telefonoTecnico;

public int edadInt=0, sexoInt=0;

public GraphView graph, graph_izq, graph_der;

public int getCanalGrafica() {


return canalGrafica;
}

public void setCanalGrafica(int canalGrafica) {


this.canalGrafica = canalGrafica;
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof FragmentGraficaListener){
this.listener = (FragmentGraficaListener) context;
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {

v = inflater.inflate(R.layout.grafica, container, false);


butPdf = v.findViewById(R.id.buttonPdf);
// TODO Auto-generated method stub

canal = (Spinner) v.findViewById(R.id.spinnerCanalGrafica);


listaCanal = new ArrayList<String>();

InicializarFrecuencias();
InicializarUmbralesEdad();
ListarCanales();

// La que nos interesa es esta


graph = (GraphView) v.findViewById(R.id.graph);
graph_izq = (GraphView) v.findViewById(R.id.graph_izq);
graph_der = (GraphView) v.findViewById(R.id.graph_der);
mSerie = new LineGraphSeries<DataPoint>();
mSerieIzq = new LineGraphSeries<DataPoint>();
mSerieDch = new LineGraphSeries<DataPoint>();
serieEdad = new LineGraphSeries<DataPoint>();

graph.addSeries(mSerie);
graph.addSeries(serieEdad);
graph.getViewport().setScalable(true); // Sirve para hacer
escalable la grafica
graph.getViewport().setXAxisBoundsManual(true);

graph_izq.addSeries(mSerieIzq);
graph_izq.addSeries(serieEdad);
graph_izq.getViewport().setScalable(true); // Sirve para hacer
escalable la grafica
graph_izq.getViewport().setXAxisBoundsManual(true);

Página 119
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

graph_der.addSeries(mSerieDch);
graph_der.addSeries(serieEdad);
graph_der.getViewport().setScalable(true); // Sirve para hacer
escalable la grafica
graph_der.getViewport().setXAxisBoundsManual(true);

graph_der.getGridLabelRenderer().setHorizontalAxisTitle("f[Hz]");
graph.getGridLabelRenderer().setHorizontalAxisTitle("f[Hz]");

graph_izq.getGridLabelRenderer().setHorizontalAxisTitle("f[Hz]");

graph_der.getGridLabelRenderer().setVerticalAxisTitle("SPL[dB]");
graph.getGridLabelRenderer().setVerticalAxisTitle("SPL[dB]");

graph_izq.getGridLabelRenderer().setVerticalAxisTitle("SPL[dB]");

graph.getGridLabelRenderer().setNumHorizontalLabels(4);
graph.getGridLabelRenderer().setVerticalAxisTitleTextSize(20);
graph_der.getGridLabelRenderer().setNumHorizontalLabels(4);

graph_der.getGridLabelRenderer().setVerticalAxisTitleTextSize(20);
graph_izq.getGridLabelRenderer().setNumHorizontalLabels(4);

graph_izq.getGridLabelRenderer().setVerticalAxisTitleTextSize(20);

return v;
}

private void InicializarFrecuencias() {


frecuencia = new double[7];
frecuencia[0] = 125;
frecuencia[1] = 250;
frecuencia[2] = 500;
frecuencia[3] = 1000;
frecuencia[4] = 2000;
frecuencia[5] = 4000;
frecuencia[6] = 8000;
}
private void InicializarUmbralesEdad() {
umbralEdad = new double[2][8][7]; //Sexo,Edad,Frecuencia

//HOMBRE = 0
//EDAD: 5-19 = 0
umbralEdad[0][0][0] = 17; //125 Hz
umbralEdad[0][0][1] = 14; //250 Hz
umbralEdad[0][0][2] = 12; //500 Hz
umbralEdad[0][0][3] = 9; //1000 Hz
umbralEdad[0][0][4] = 7; //2000 Hz
umbralEdad[0][0][5] = 8; //4000 Hz
umbralEdad[0][0][6] = 11; //8000 Hz
//EDAD: 20-29 = 1
umbralEdad[0][1][0] = 15; //125 Hz
umbralEdad[0][1][1] = 12; //250 Hz
umbralEdad[0][1][2] = 11; //500 Hz
umbralEdad[0][1][3] = 8; //1000 Hz
umbralEdad[0][1][4] = 6; //2000 Hz
umbralEdad[0][1][5] = 8; //4000 Hz

Página 120
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

umbralEdad[0][1][6] = 8; //8000 Hz
//EDAD: 30-39 = 2
umbralEdad[0][2][0] = 16; //125 Hz
umbralEdad[0][2][1] = 13; //250 Hz
umbralEdad[0][2][2] = 12; //500 Hz
umbralEdad[0][2][3] = 9; //1000 Hz
umbralEdad[0][2][4] = 6; //2000 Hz
umbralEdad[0][2][5] = 13; //4000 Hz
umbralEdad[0][2][6] = 11; //8000 Hz
//EDAD: 40-49 = 3
umbralEdad[0][3][0] = 16; //125 Hz
umbralEdad[0][3][1] = 13; //250 Hz
umbralEdad[0][3][2] = 12; //500 Hz
umbralEdad[0][3][3] = 10; //1000 Hz
umbralEdad[0][3][4] = 7; //2000 Hz
umbralEdad[0][3][5] = 13; //4000 Hz
umbralEdad[0][3][6] = 16; //8000 Hz
//EDAD: 50-59 = 4
umbralEdad[0][4][0] = 18; //125 Hz
umbralEdad[0][4][1] = 15; //250 Hz
umbralEdad[0][4][2] = 15; //500 Hz
umbralEdad[0][4][3] = 14; //1000 Hz
umbralEdad[0][4][4] = 11; //2000 Hz
umbralEdad[0][4][5] = 18; //4000 Hz
umbralEdad[0][4][6] = 25; //8000 Hz
//EDAD: 60-69 = 5
umbralEdad[0][5][0] = 20; //125 Hz
umbralEdad[0][5][1] = 16; //250 Hz
umbralEdad[0][5][2] = 16; //500 Hz
umbralEdad[0][5][3] = 15; //1000 Hz
umbralEdad[0][5][4] = 15; //2000 Hz
umbralEdad[0][5][5] = 29; //4000 Hz
umbralEdad[0][5][6] = 36; //8000 Hz
//EDAD: 70-79 = 6
umbralEdad[0][6][0] = 21; //125 Hz
umbralEdad[0][6][1] = 19; //250 Hz
umbralEdad[0][6][2] = 18; //500 Hz
umbralEdad[0][6][3] = 20; //1000 Hz
umbralEdad[0][6][4] = 26; //2000 Hz
umbralEdad[0][6][5] = 42; //4000 Hz
umbralEdad[0][6][6] = 53; //8000 Hz
//EDAD: 80-90 = 7
umbralEdad[0][7][0] = 25; //125 Hz
umbralEdad[0][7][1] = 21; //250 Hz
umbralEdad[0][7][2] = 22; //500 Hz
umbralEdad[0][7][3] = 22; //1000 Hz
umbralEdad[0][7][4] = 36; //2000 Hz
umbralEdad[0][7][5] = 56; //4000 Hz
umbralEdad[0][7][6] = 67; //8000 Hz

//MUJER = 1
//EDAD: 5-19 = 0
umbralEdad[1][0][0] = 17; //125 Hz
umbralEdad[1][0][1] = 14; //250 Hz
umbralEdad[1][0][2] = 12; //500 Hz
umbralEdad[1][0][3] = 9; //1000 Hz
umbralEdad[1][0][4] = 7; //2000 Hz

Página 121
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

umbralEdad[1][0][5] = 8; //4000 Hz
umbralEdad[1][0][6] = 11; //8000 Hz
//EDAD: 20-29 = 1
umbralEdad[1][1][0] = 15; //125 Hz
umbralEdad[1][1][1] = 12; //250 Hz
umbralEdad[1][1][2] = 11; //500 Hz
umbralEdad[1][1][3] = 8; //1000 Hz
umbralEdad[1][1][4] = 6; //2000 Hz
umbralEdad[1][1][5] = 8; //4000 Hz
umbralEdad[1][1][6] = 8; //8000 Hz
//EDAD: 30-39 = 2
umbralEdad[1][2][0] = 16; //125 Hz
umbralEdad[1][2][1] = 13; //250 Hz
umbralEdad[1][2][2] = 12; //500 Hz
umbralEdad[1][2][3] = 9; //1000 Hz
umbralEdad[1][2][4] = 6; //2000 Hz
umbralEdad[1][2][5] = 13; //4000 Hz
umbralEdad[1][2][6] = 11; //8000 Hz
//EDAD: 40-49 = 3
umbralEdad[1][3][0] = 16; //125 Hz
umbralEdad[1][3][1] = 13; //250 Hz
umbralEdad[1][3][2] = 12; //500 Hz
umbralEdad[1][3][3] = 10; //1000 Hz
umbralEdad[1][3][4] = 7; //2000 Hz
umbralEdad[1][3][5] = 13; //4000 Hz
umbralEdad[1][3][6] = 16; //8000 Hz
//EDAD: 50-59 = 4
umbralEdad[1][4][0] = 18; //125 Hz
umbralEdad[1][4][1] = 15; //250 Hz
umbralEdad[1][4][2] = 15; //500 Hz
umbralEdad[1][4][3] = 14; //1000 Hz
umbralEdad[1][4][4] = 11; //2000 Hz
umbralEdad[1][4][5] = 18; //4000 Hz
umbralEdad[1][4][6] = 25; //8000 Hz
//EDAD: 60-69 = 5
umbralEdad[1][5][0] = 20; //125 Hz
umbralEdad[1][5][1] = 16; //250 Hz
umbralEdad[1][5][2] = 16; //500 Hz
umbralEdad[1][5][3] = 15; //1000 Hz
umbralEdad[1][5][4] = 15; //2000 Hz
umbralEdad[1][5][5] = 29; //4000 Hz
umbralEdad[1][5][6] = 36; //8000 Hz
//EDAD: 70-79 = 6
umbralEdad[1][6][0] = 21; //125 Hz
umbralEdad[1][6][1] = 19; //250 Hz
umbralEdad[1][6][2] = 18; //500 Hz
umbralEdad[1][6][3] = 20; //1000 Hz
umbralEdad[1][6][4] = 26; //2000 Hz
umbralEdad[1][6][5] = 42; //4000 Hz
umbralEdad[1][6][6] = 53; //8000 Hz
//EDAD: 80-90 = 7
umbralEdad[1][7][0] = 25; //125 Hz
umbralEdad[1][7][1] = 21; //250 Hz
umbralEdad[1][7][2] = 22; //500 Hz
umbralEdad[1][7][3] = 22; //1000 Hz
umbralEdad[1][7][4] = 36; //2000 Hz
umbralEdad[1][7][5] = 56; //4000 Hz
umbralEdad[1][7][6] = 67; //8000 Hz

Página 122
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

private void ListarCanales() {


listaCanal.add("Seleccionar Canal:");
listaCanal.add("Canal: Izquierdo");
listaCanal.add("Canal: Derecho");
ArrayAdapter<String> adaptador = new
ArrayAdapter<String>(getContext(),
android.R.layout.simple_spinner_item, listaCanal);

adaptador.setDropDownViewResource(android.R.layout.simple_spinner_drop
down_item);
canal.setAdapter(adaptador);

canal.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View
view, int pos, long id) {

setCanalGrafica(pos);

if(pos!=0){
Toast.makeText(parent.getContext(), "Seleccionada:
" + parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_SHORT).show();
}

edad = listener.getEdad();
sexo = listener.getSexo();
double edadDouble=0;

if (edad != null && !edad.isEmpty())


edadDouble = Double.parseDouble(edad);
edadInt = 0;
if (edadDouble >= 10)
edadInt = (int) (Math.floor(edadDouble/10) - 1);
if (edadInt==8)
edadInt =7;

if(pos==0){
graph.removeAllSeries();
graph_der.removeAllSeries();
graph_izq.removeAllSeries();
mSerie = new LineGraphSeries<DataPoint>();
graph.addSeries(mSerie);
for(int x=0;x<(frecuencia.length);x++) {
mSerie.appendData(new DataPoint(frecuencia[x],
0), true, 160);
}
}
if(pos==1){
graph.removeAllSeries();
graph_izq.removeAllSeries();
mSerie = new LineGraphSeries<DataPoint>();
serieEdad = new LineGraphSeries<DataPoint>();
mSerieIzq = new LineGraphSeries<DataPoint>();
serieEdad.setColor(Color.RED);
graph.addSeries(mSerie);

Página 123
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

graph.addSeries(serieEdad);
graph_izq.addSeries(serieEdad);
graph_izq.addSeries(mSerieIzq);
double[] datosIzq = listener.getDatosIzq();
for(int x=0;x<(frecuencia.length);x++) {
mSerie.appendData(new DataPoint(frecuencia[x],
datosIzq[x]), true, 160);
mSerieIzq.appendData(new
DataPoint(frecuencia[x], datosIzq[x]), true, 160);
if (sexo != null){
if (sexo.equals("Hombre")){
sexoInt=0;
serieEdad.appendData(new
DataPoint(frecuencia[x], umbralEdad[0][edadInt][x]), true, 160);
}else if (sexo.equals("Mujer")){
sexoInt=1;
serieEdad.appendData(new
DataPoint(frecuencia[x], umbralEdad[1][edadInt][x]), true, 160);
}
}else{
serieEdad.appendData(new
DataPoint(frecuencia[x], 0), true, 160);
}
}
booleanIzq = true;
}
if(pos==2){
graph.removeAllSeries();
graph_der.removeAllSeries();
mSerie = new LineGraphSeries<DataPoint>();
serieEdad = new LineGraphSeries<DataPoint>();
mSerieDch = new LineGraphSeries<DataPoint>();
serieEdad.setColor(Color.RED);
graph.addSeries(mSerie);
graph.addSeries(serieEdad);
graph_der.addSeries(serieEdad);
graph_der.addSeries(mSerieDch);
double[] datosDer = listener.getDatosDer();
for(int x=0;x<(frecuencia.length);x++) {
mSerie.appendData(new DataPoint(frecuencia[x],
datosDer[x]), true, 160);
mSerieDch.appendData(new
DataPoint(frecuencia[x], datosDer[x]), true, 160);
if (sexo != null){
if (sexo.equals("Hombre")){
serieEdad.appendData(new
DataPoint(frecuencia[x], umbralEdad[0][edadInt][x]), true, 160);
}else if (sexo.equals("Mujer")){
serieEdad.appendData(new
DataPoint(frecuencia[x], umbralEdad[1][edadInt][x]), true, 160);
}
}else{
serieEdad.appendData(new
DataPoint(frecuencia[x], 0), true, 160);
}
}
booleanDer = true;
}

Página 124
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

if((booleanIzq == true)&&(booleanDer == true)){


butPdf.setVisibility(View.VISIBLE);
}

mSerie.setTitle("Paciente");
mSerieDch.setTitle("Paciente");
mSerieIzq.setTitle("Paciente");
serieEdad.setTitle("Media");
// Display the legend.
graph.getLegendRenderer().setVisible(true);
graph_izq.getLegendRenderer().setVisible(true);
graph_izq.getLegendRenderer().setFixedPosition(0,0);
graph_izq.getLegendRenderer().setWidth(250);

graph_der.getLegendRenderer().setVisible(true);
graph_der.getLegendRenderer().setFixedPosition(0,0);
graph_der.getLegendRenderer().setWidth(250);
//Así podemos fijar el eje de la gráfica
graph_der.getViewport().setMinX(125);
graph_der.getViewport().setMaxX(8000);
graph_izq.getViewport().setMinX(125);
graph_izq.getViewport().setMaxX(8000);
graph.getViewport().setMinX(125);
graph.getViewport().setMaxX(8000);

// Escucha por pantalla y muestra el dato seleccionado


en la grafica
serieEdad.setOnDataPointTapListener(new
OnDataPointTapListener() {
@Override
public void onTap(Series series,
DataPointInterface dataPoint) {
// TODO Auto-generated method stub
Toast.makeText(getContext(), "Serie Media
Edad: El punto seleccionado es: "+dataPoint.getY() + " dB a "
+dataPoint.getX() + " Hz", Toast.LENGTH_SHORT).show();
}
});
mSerie.setOnDataPointTapListener(new
OnDataPointTapListener() {
@Override
public void onTap(Series series,
DataPointInterface dataPoint) {
// TODO Auto-generated method stub
Toast.makeText(v.getContext(), "Serie Datos
Paciente: El punto seleccionado es: " +dataPoint.getY() + " dB a "
+dataPoint.getX() + " Hz", Toast.LENGTH_SHORT).show();
}
});
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);

Página 125
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

butPdf.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

File ruta = null;

if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageStat
e())) {
ruta = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTO
RY_DOWNLOADS), INVOICES_FOLDER);
if(ruta != null) {
if(!ruta.mkdirs()) {
if(!ruta.exists()) {
}
}
}
}
File fichero = null;
if(ruta != null) {
fichero = new File(ruta, "audiometria_izq.png");
if(fichero.exists()) {
// El fichero ya existe, borrarlo
fichero.delete();
}
fichero = new File(ruta, "audiometria_izq.png");
}

FileOutputStream output = null;


try {
output = new
FileOutputStream(fichero.getAbsolutePath(),true);

Bitmap bitmap =
Bitmap.createBitmap(graph_izq.getWidth(), graph_izq.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
graph_izq.draw(canvas);
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
output);
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

ruta = null;

if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageStat
e())) {
ruta = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTO
RY_DOWNLOADS), INVOICES_FOLDER);
if(ruta != null) {
if(!ruta.mkdirs()) {
if(!ruta.exists()) {
}

Página 126
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

}
}
}
fichero = null;
if(ruta != null) {
fichero = new File(ruta, "audiometria_dch.png");
if(fichero.exists()) {
// El fichero ya existe, borrarlo
fichero.delete();
}
fichero = new File(ruta, "audiometria_dch.png");
}

output = null;
try {
output = new
FileOutputStream(fichero.getAbsolutePath(),true);
Bitmap bitmap =
Bitmap.createBitmap(graph_der.getWidth(), graph_der.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
graph_der.draw(canvas);
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
output);
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

nombre = listener.getNombre();
apellidos = listener.getApellidos();
edad = listener.getEdad();
sexo = listener.getSexo();
correoPaciente = listener.getCorreo();
nombreTecnico = listener.getNombreTecnico();
correoTecnico = listener.getCorreoTecnico();
telefonoTecnico = listener.getTelefonoTecnico();

FILENAME = FILENAME + nombre + "_"+ apellidos +


".pdf";
try {
//Instanciamos la clase PdfManager
pdfManager = new PdfManager(getContext());
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
//Create PDF document
assert pdfManager != null;
pdfManager.createPdfDocument(FILENAME, nombre,
apellidos, edad, sexoInt,
correoPaciente,nombreTecnico,correoTecnico,telefonoTecnico,
frecuencia, listener.getDatosIzq(),
listener.getDatosDer(),umbralEdad[sexoInt][edadInt],
umbralEdad[sexoInt][edadInt]);

Página 127
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

pdfManager.sendPdfByEmail(FILENAME,correoPaciente,correoTecnico,
getContext());
}
});
}
@Override
public void onResume() {
super.onResume();
}

public interface FragmentGraficaListener{


public double[] getDatosIzq();
public double[] getDatosDer();
public String getNombre();
public String getApellidos();
public String getEdad();
public String getSexo();
public String getCorreo();
public String getNombreTecnico();
public String getCorreoTecnico();
public String getTelefonoTecnico();
}
}

Página 128
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

<?xml version="1.0" encoding="utf-8"?>


<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".ui.main.PlaceholderFragment">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Space
android:layout_width="match_parent"
android:layout_height="20dp" />

<Spinner
android:id="@+id/spinnerCanalGrafica"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:entries="@array/canalGrafica" />

<Space
android:layout_width="match_parent"
android:layout_height="15dp" />

<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
android:id="@+id/layout_graph_vista"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbars="horizontal|vertical">

<com.jjoe64.graphview.GraphView
android:id="@+id/graph"
android:layout_width="345dp"
android:layout_height="373dp"
android:layout_gravity="center"
android:visibility="visible" />

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom">

<Space
android:layout_width="match_parent"

Página 129
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

android:layout_height="80dp" />

<Button
android:id="@+id/buttonPdf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:visibility="invisible"
android:text="Generar y Enviar PDF" />
</FrameLayout>
</LinearLayout>

<LinearLayout
android:id="@+id/layout_graph_oculta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<Space
android:layout_width="match_parent"
android:layout_height="800dp" />

<com.jjoe64.graphview.GraphView
android:id="@+id/graph_izq"
android:layout_width="350dp"
android:layout_height="373dp"
android:visibility="visible" />

<com.jjoe64.graphview.GraphView
android:id="@+id/graph_der"
android:layout_width="350dp"
android:layout_height="373dp"
android:visibility="visible" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>

Página 130
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

Anexo 9: PdfManager
package com.example.audiometria;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.content.FileProvider;
import android.widget.Toast;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

public class PdfManager {


private static Context mContext;
private static final String APP_FOLDER_NAME = "Audiometrias";
public String
FILENAME,nombre,apellidos,edad,correoPaciente,nombreTecnico,correoTecn
ico,telefonoTecnico;
public double[] frecuencia, datosIzq, datosDer;
public double[] datosIzqEdad, datosIzqDif,datosDerEdad,
datosDerDif;
public int sexo;

//Constructor set fonts and get context


public PdfManager(Context context) throws IOException,
DocumentException {
mContext = context;
}
//Generando el documento PDF
public void createPdfDocument(String FILENAME, String nombre,
String apellidos, String edad, int sexo,String correoPaciente,
String nombreTecnico, String
correoTecnico, String telefonoTecnico, double[] frecuencia, double[]
datosIzq, double[] datosDer,
double[] datosIzqEdad, double[]
datosDerEdad) {
this.FILENAME=FILENAME;
this.nombre=nombre;
this.apellidos=apellidos;
this.edad=edad;

Página 131
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

this.sexo=sexo;
this.frecuencia=frecuencia;
this.datosDer=datosDer;
this.datosIzq=datosIzq;
this.datosIzqEdad=datosIzqEdad;
this.datosDerEdad=datosDerEdad;
this.correoPaciente=correoPaciente;
this.nombreTecnico=nombreTecnico;
this.correoTecnico=correoTecnico;
this.telefonoTecnico=telefonoTecnico;

// Se crea el documento
Document document = new Document();
try {
//Creamos las carpetas en nuestro dispositivo, si existen
las eliminamos.
File fichero = createDirectoryAndFileName();
FileOutputStream ficheroPDF = new
FileOutputStream(fichero.getAbsolutePath());

PdfWriter writer = PdfWriter.getInstance(document,


ficheroPDF);
// Se abre el documento.
document.open();

//Creamos los metadatos del alchivo


addMetaData(document);

//Creamos el título del documento


addTitlePage(document);

datosIzqDif = new double[frecuencia.length];


datosDerDif = new double[frecuencia.length];
for (int y = 0; y <(frecuencia.length); y++) {
datosIzqDif[y] = datosIzqEdad[y] - datosIzq[y];
datosDerDif[y] = datosDerEdad[y] - datosDer[y];
}

//Creamos el contenido en form de tabla del documento


addInvoiceContent(document,"Izquierdo",frecuencia,datosIzq,datosIzqEda
d, datosIzqDif);
//IMAGEN CANAL IZQ
addImageCanal(document, "izq.png");
addInvoiceContent(document,"Derecho",frecuencia,datosDer,datosDerEdad,
datosDerDif);

//IMAGEN CANAL DERECHO


addImageCanal(document, "dch.png");

document.close();

Toast.makeText(mContext, "Se ha creado el PDF


satisfactoriamente", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
private File createDirectoryAndFileName(){
File ruta = null;

Página 132
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageStat
e())) {
ruta = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTO
RY_DOWNLOADS), APP_FOLDER_NAME);

if(ruta != null) {
if(!ruta.mkdirs()) {
if(!ruta.exists()) {
return null;
}
}
}
}
File fichero = null;
if(ruta != null) {
fichero = new File(ruta, FILENAME);
if(fichero.exists()) {
// El fichero ya existe, borrarlo
fichero.delete();
}
fichero = new File(ruta, FILENAME);
}
return fichero;
}
//PDF library add file metadata function
private void addMetaData(Document document) {
document.addTitle("Audiometría de " + nombre + " " +
apellidos);
document.addKeywords("Audiometria, Raspberry, UPM, PFG");
document.addAuthor("Víctor Manuel Díaz Conejo");
document.addCreator("Víctor Manuel Díaz Conejo");
}

//Creando el Título y los datos de la Empresa y el Cliente


private void addTitlePage(Document document)
throws DocumentException {
Paragraph preface = new Paragraph();
// Adicionamos una línea en blanco
addEmptyLine(preface, 1);
preface.add(new Paragraph("Audiometría"));
addEmptyLine(preface, 1);
preface.add(new Paragraph("" + new Date()));

//Adicionamos los datos de


preface.add(new Paragraph("Universidad Politécnica de Madrid,
Campus sur" ));
preface.add(new Paragraph("ETSIST" ));
preface.add(new Paragraph("Vallecas" ));
preface.add(new Paragraph("España"));

addEmptyLine(preface, 1);

//Adicionamos los datos del Paciente


preface.add(new Paragraph("Paciente" ));
preface.add(new Paragraph(nombre + " " + apellidos));
preface.add(new Paragraph(edad + " años"));

Página 133
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

if(sexo == 0) {
preface.add(new Paragraph("Sexo: Hombre"));
}else if(sexo == 1) {
preface.add(new Paragraph("Sexo: Mujer"));
}
addEmptyLine(preface, 1);

//Adicionamos los datos del Técnico


preface.add(new Paragraph("Técnico" ));
preface.add(new Paragraph(nombreTecnico));
preface.add(new Paragraph(correoTecnico));
preface.add(new Paragraph(telefonoTecnico));
addEmptyLine(preface, 1);

//Adicionamos el párrafo creado al documento


document.add(preface);

// Si queremos crear una nueva página //document.newPage();


}
//Creamos el contenido de la, las líneas con los artículos.
private static void addInvoiceContent(Document document, String
canal, double[] frecuencia, double[] datosCanal, double[]
datosCanalEdad, double[] datosCanalDif) throws DocumentException {
Paragraph paragraph = new Paragraph();
addEmptyLine(paragraph, 1);
document.newPage();

// Creamos una tabla con los títulos de las columnas


createInvoiceTable(paragraph, canal,
frecuencia,datosCanal,datosCanalEdad, datosCanalDif);

// Adicionamos el párrafo al documento


document.add(paragraph);
}
//Procedimiento para crear los títulos de las columnas.
private static void createInvoiceTable(Paragraph tableSection,
String canal, double[] frecuencia, double[] datosCanal, double[]
datosCanalEdad, double[] datosCanalDif)
throws DocumentException {
tableSection.add(new Paragraph("Canal " + canal));
tableSection.add(new Paragraph(" "));

int TABLE_COLUMNS = 4;
//Instaciamos el objeto Pdf Table y creamos una tabla con las
columnas definidas en TABLE_COLUMNS
PdfPTable table = new PdfPTable(TABLE_COLUMNS);// number of
table columns
//Definimos el ancho que corresponde a cada una de las 4
columnas
float[] columnWidths = new float[]{100f, 150f, 150f, 80f};
table.setWidths(columnWidths);

//Definimos el ancho de nuestra tabla en %


table.setWidthPercentage(100);

//Definimos los títulos para cada una de las 4 columnas


PdfPCell cell = new PdfPCell(new Phrase("Frecuencia"));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);

Página 134
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

//Adicionamos el título de la primera columna


table.addCell(cell);
cell = new PdfPCell(new Phrase("Valor obtenido"));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);

//Adicionamos el título de la segunda columna


table.addCell(cell);
cell = new PdfPCell(new Phrase("Valor normal a su edad"));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);

//Adicionamos el título de la tercera columna


table.addCell(cell);
cell = new PdfPCell(new Phrase("Diferencia"));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);

//Adicionamos el título de la cuarta columna


table.addCell(cell);

//Creamos la fila de la tabla con las cabeceras


table.setHeaderRows(1);

//Creamos las lineas con los artículos de la factura;


//SE PONEN LOS DATOS DE TODAS LAS FRECUENCIAS
createInvoiceLine(frecuencia, datosCanal, datosCanalEdad,
datosCanalDif, table);
tableSection.add(table);
}

//Procedimiento para crear una lines vacía


private static void addEmptyLine(Paragraph paragraph, int number)
{
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
//Procedimiento para adicionar una imagen al documento PDF
private static void addImage(Document document) throws
IOException, DocumentException {
Bitmap bitMap =
BitmapFactory.decodeResource(mContext.getResources(),
R.mipmap.ic_launcher);

ByteArrayOutputStream stream = new ByteArrayOutputStream();


bitMap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
byte[] bitMapData = stream.toByteArray();
Image image = Image.getInstance(bitMapData);
//Posicionamos la imagen el el documento
image.setAbsolutePosition(400f, 650f);
document.add(image);
}

//Procedimiento para adicionar canal izquierdo una imagen al


documento PDF
private static void addImageCanal(Document document, String dir)
throws IOException, DocumentException {
File ruta = null;

Página 135
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

// Así va correctamente la dirección


if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageStat
e())) {
ruta = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTO
RY_DOWNLOADS), APP_FOLDER_NAME);
if(ruta != null) {
if(!ruta.mkdirs()) {
if(!ruta.exists()) {
ruta = null;
}
}
}
}
File fichero = null;
if(ruta != null) {
fichero = new File(ruta, "audiometria_" + dir);
}
try
{
Image foto = Image.getInstance(fichero.getAbsolutePath());
foto.scaleToFit(300, 300);
foto.setAlignment(Chunk.ALIGN_MIDDLE);
document.add(foto);
}
catch ( Exception e )
{
e.printStackTrace();
}
Paragraph paragraph = new Paragraph();
addEmptyLine(paragraph, 1);
// Adicionamos el párrafo al documento
document.add(paragraph);
}
//Procedimiento para crear las líneas de la factura en forma de
tabla.
private static void createInvoiceLine(double[] frecuencia,
double[] datosCanal, double[] datosCanalEdad, double[] datosCanalDif,
PdfPTable table) {
PdfPCell cell = new PdfPCell();
//Definimos los títulos para cada una de las 4 columnas.
//SON 4 COLUMNAS EN ESTE ORDEN: FRECUENCIA, VALOR OBTENIDO,
VALOR NORMAL A SU EDAD, DIFERENCIA
for (int y = 0; y <(frecuencia.length); y++) {
cell.setPhrase(new Phrase(String.valueOf(frecuencia[y])));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);

cell.setPhrase(new Phrase(String.valueOf(datosCanal[y])));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
cell.setPhrase(new
Phrase(String.valueOf(datosCanalEdad[y])));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
cell.setPhrase(new
Phrase(String.valueOf(datosCanalDif[y])));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);

Página 136
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

}
}
//Procedimiento para mostrar el documento PDF generado
public void showPdfFile(String fileName, Context context){
Toast.makeText(context, "Leyendo documento",
Toast.LENGTH_LONG).show();
File ruta = null;
// Así va correctamente la dirección
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageStat
e())) {
ruta = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTO
RY_DOWNLOADS), APP_FOLDER_NAME);
if(ruta != null) {
if(!ruta.mkdirs()) {
if(!ruta.exists()) {
ruta = null;
}
}
}
}
File fichero = null;
if(ruta != null) {
fichero = new File(ruta, fileName);
}
Uri uri;
Intent viewFile = new Intent(Intent.ACTION_VIEW);
uri = FileProvider.getUriForFile(context,
BuildConfig.APPLICATION_ID, fichero);
viewFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
viewFile.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
viewFile.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
viewFile.putExtra(Intent.EXTRA_STREAM, uri);
viewFile.setType("application/pdf");
try {
context.startActivity(viewFile);
//startActivity(viewFile);
}
catch (ActivityNotFoundException e) {
Toast.makeText(context, "No Application Available to View
PDF", Toast.LENGTH_SHORT).show();
}
}
//Procedimiento para enviar por email el documento PDF generado
public void sendPdfByEmail(String fileName, String emailTo, String
emailCC, Context context){
File ruta = null;
// Así va correctamente la dirección
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageStat
e())) {
ruta = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTO
RY_DOWNLOADS), APP_FOLDER_NAME);
if(ruta != null) {
if(!ruta.mkdirs()) {
if(!ruta.exists()) {
ruta = null;
}
}

Página 137
Diseño e implementación de un audiómetro con Raspberry Pi
Anexos

}
}
File fichero = null;
if(ruta != null) {
fichero = new File(ruta, fileName);
}
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Audiometría: " +
nombre + " " + apellidos);
emailIntent.putExtra(Intent.EXTRA_TEXT, "Muchas gracias. Esta
es su audiometría, cuídese.");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new
String[]{emailTo});
emailIntent.putExtra(Intent.EXTRA_BCC, new String[]{emailCC});

Uri uri;
uri = FileProvider.getUriForFile(context,
BuildConfig.APPLICATION_ID, fichero);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
emailIntent.setType("application/pdf");
context.startActivity(Intent.createChooser(emailIntent, "Send
email using:"));
}
}

Página 138

También podría gustarte