Full text
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA GRADO EN INGENIERÍA DE LA SALUD: INGENIERÍA BIOMÉDICA. REGISTRO REMOTO DE DATOS BIOMÉDICOS “BAJO DEMANDA” REMOTE REGISTRY OF BIOMEDICAL DATA ON DEMAND Realizado por María Sanzo Díaz. Tutorizado por Rafael de Jesús Navas González. Manuel Jesús Martín Vázquez. Departamento Electrónica. UNIVERSIDAD DE MÁLAGA MÁLAGA, Septiembre, 2016 Fecha defensa: El Secretario del Tribunal
1 Resumen: Este trabajo fin de grado consiste en especificar, diseñar e implementar un sistema básico para la adquisición y el registro remoto de datos biomédicos de pacientes monitorizados in situ, y localizados en diferentes ubicaciones, a medida que esta información es solicitada desde un operador o gestor centralizado. En este sistema, la iniciativa de la comunicación la lleva el operador del sistema centralizado, que, cuando estima oportuno, solicita al sistema de monitorización la realización de una medida y, por tanto, el envío de los datos solicitados. Así, las tareas de este trabajo comprenden el estudio de las necesidades y requerimientos del sistema, la elección de los elementos hardware, y el desarrollo de las aplicaciones software apropiadas para su implementación. Estas tareas cubren aspectos relativos a la concepción e implantación de un sistema básico de e-Salud. El sistema desarrollado contempla aspectos básicos como son: el registro de un conjunto de medidas biomédicas (temperatura corporal, pulsioximetría, electrocardiografía (ECG), etc,) en una pequeña comunidad de pacientes, gestionada desde un servidor remoto por un operador. El funcionamiento global del sistema podría resumirse de la siguiente manera: El operador selecciona un paciente de los que han sido dados de alta en el sistema, y solicita un registro biomédico, por ejemplo su temperatura corporal actual. La orden es enviada al sistema de monitorización del paciente en su localización. El resultado de la medida es remitido de vuelta al servidor. Éste recibe los valores obtenidos y los almacena, de modo que puedan ser recuperados y analizados posteriormente. Además, desde el puesto del operador es posible realizar una gestión de pacientes y un análisis básico de los datos. Palabras clave: Bajo demanda, sensores biomédicos, Arduino, e-salud, red inalámbrica, servidor web, monitorización de variables fisiológicas. Abstract: The thesis here presented aims to specify, design and implement a basic system for the remote acquisition and record of biomedical data of patients with in situ monitoring situated at several locations. This information should be accessible as requested by a centralized agent. Therefore, is the agent the responsible for initiating the communication and demanding to the monitoring system the record and delivery of the data of a specific measurement. This project comprehends the study of the needs and requirements of the desired system, the selection of the hardware elements, and the development of all software applications needed for the implementation of the system. These tasks involve aspects related to the conception and implementation of a basic e-Health system. The developed system includes basic aspects such as: the record of a combination of biomedical measurements (body temperature, pulse oximetry, electrocardiogram (ECG)) in a reduced number of patients, controlled by an agent from a remote server. The global operation of the system can be summarized as follows: the agent selects a
2 name from the list of patients being monitored by the system and requests the record of some biomedical data, e.g. the current body temperature. This command is sent to the monitoring system of the patient, that performs the requested measurements and delivers the results back to the central server. Once the values are received by the server, these are saved so that they can be accessed and analysed at any given time. Furthermore, the agent controlling the central server is able to manage the patients’ information and perform a basic analysis of the data. Keywords: On demand, biomedical sensors, Arduino and eHealth, wireless network, web server, monitoring of physiological variables.
3 INDICE INDICE DE FIGURAS ........................................................................................ 5 INDICE DE TABLAS ........................................................................................... 7 GLOSARIO ......................................................................................................... 8 Capítulo 1: Introducción. ..................................................................................... 9 1.1 Motivaciones ..................................................................................................... 9 1.2 Objetivos ......................................................................................................... 10 1.3 Estructura del documento ............................................................................... 11 Capítulo 2: Arquitectura del sistema ................................................................. 13 2.1 Sistema de adquisición de datos ..................................................................... 14 2.2 Sistema de control remoto .............................................................................. 15 2.3 Sistema de registro de datos ........................................................................... 15 2.4 Sistema de administración y consulta ............................................................. 16 2.5 Visión general.................................................................................................. 16 Capítulo 3. Sistema de adquisición de datos .................................................... 18 3.1 Arquitectura ..................................................................................................... 18 3.1.1 Microcontrolador ....................................................................................... 20 3.1.2 Placa e-Health........................................................................................... 22 3.1.3 Sensores ................................................................................................... 22 3.1.4 WiFi ........................................................................................................... 24 3.2 Análisis del funcionamiento ............................................................................. 25 3.3 Estructura del software del sistema ................................................................. 27 3.3.1 Bucle principal ........................................................................................... 28 3.3.2 Implementación del bucle principal ........................................................... 29 3.3.3 Muestreo continuo ..................................................................................... 41 Capítulo 4. Sistema de registro de datos .......................................................... 44 4.1 Análisis y arquitectura del sistema .................................................................. 44 4.2 Protocolo de comunicación entre el cliente y el servidor web ......................... 46 4.3 Implementación ............................................................................................... 47 4.3.1 Implementación del proceso Disparo de medidas..................................... 47 4.3.2 Implementación del proceso de registro de datos ..................................... 49 4.3.3 Implementación del proceso de consulta de tareas .................................. 52
4 Capítulo 5. Sistema de gestión y consulta ........................................................ 54 5.1 Página web...................................................................................................... 56 5.1.1 Arquitectura de la página web ................................................................... 59 Capítulo 6. Pruebas y resultados ...................................................................... 61 6.1 Pruebas sobre la base de datos ...................................................................... 61 6.2 Pruebas sobre la página web .......................................................................... 61 6.3 Pruebas en la conexión WiFi y transmisión de datos ...................................... 64 6.4 Pruebas técnicas ............................................................................................. 65 7. Conclusiones. ............................................................................................... 69 8. Bibliografía. ................................................................................................... 70 9. Apéndices. .................................................................................................... 72 Apéndice A: Tecnologías implicadas ..................................................................... 72 Apéndice B: Código completo de Arduino ............................................................. 89 Apéndice C: Archivos de recepción de datos ...................................................... 103 Apéndice D: Árbol de carpetas y archivos de la interfaz web .............................. 106
5 INDICE DE FIGURAS Figura 1: Arquitectura del sistema ............................................................................ 13 Figura 2: Sistema de adquisición de datos sin sensores conectados. ...................... 15 Figura 3: Sistema de adquisición de datos ............................................................... 18 Figura 4: Dispositivo con todas las placas conectadas ............................................ 19 Figura 5: Placa con led ............................................................................................. 19 Figura 6: Diagrama de conexiones del dispositivo ................................................... 20 Figura 7: Esquema de conexiones de la placa Arduino ............................................ 21 Figura 8: Esquema entrada y salida del microcontrolador ........................................ 21 Figura 9: Placa e-Health vista desde arriba .............................................................. 22 Figura 10: Placa e-Health vista desde abajo ............................................................ 22 Figura 11: Conexión de los sensores a la placa e-Health ........................................ 24 Figura 12: Placa "Communication Shield" para Arduino ........................................... 24 Figura 13: Estructura del módulo WiFi ..................................................................... 25 Figura 14: Placa e-Health junto a la placa de comunicación y el módulo WiFi ......... 25 Figura 15: Diagrama de procesos del software del sistema ..................................... 28 Figura 16: Representación por máquina de estados del bucle principal .................. 30 Figura 17: Código Arduino correspondiente al estado CONFIGURACIÓN WIFI ...... 31 Figura 18: Implementación del estado INI ESPERA en el software de Arduino ....... 32 Figura 19: Código Arduino relacionado con el estado ERROR ................................ 33 Figura 20: Creación de una página web indicando que se ha conectado un cliente y comprobación del tiempo de espera. ........................................................................ 33 Figura 21: Implementación del estado INI CONFIRMA ............................................ 34 Figura 22: Implementación del estado LEELINEA en Arduino ................................. 35 Figura 23: Implementación del estado FLAG ........................................................... 36 Figura 24: Búsqueda de flag activo .......................................................................... 37 Figura 25: Captura y envío de un dato de temperatura ............................................ 38 Figura 26: Captura y envío de un dato de temperatura ............................................ 39 Figura 27: Captura de datos de ECG en Arduino ..................................................... 40 Figura 28: Implementación de la captura de datos de ECG ..................................... 40 Figura 29: Implementación del envío de datos de ECG ........................................... 41 Figura 30: Uso de la librería "TimerOne" .................................................................. 42 Figura 31: Esquema del sistema de control y registro .............................................. 45 Figura 32: Comunicación Cliente/Servidor ............................................................... 46 Figura 33: Ejemplo de petición tipo GET .................................................................. 47 Figura 34: Ejemplo de petición tipo POST ................................................................ 47 Figura 35: Solicitud de un dato de temperatura en el servidor ................................. 48 Figura 36: Solicitud de datos en la Página Web ....................................................... 48 Figura 37: Diagrama de flujo de recepción de datos de temperatura. ...................... 49 Figura 38: Diagrama de flujo de recepción de datos de pulso .................................. 50 Figura 39: Diagrama de flujo de recepción de datos de ECG................................... 51
12 Encontraremos un apartado dedicado a la bibliografía consultada para la realización del proyecto. Y por último, en el apartado Apéndices, se aloja información extra que no se ha visto necesaria incluirla a lo largo del documento, como son los códigos de Arduino y de recepción de datos.
13 Capítulo 2: Arquitectura del sistema En este capítulo, se presentan de forma general, los principales bloques funcionales que constituyen el sistema, y cómo se integran para conseguir la funcionalidad requerida. Se ha dejado para posteriores capítulos una descripción más detallada de su implementación, tanto de los elementos hardware y software que los constituyen, como del software específico desarrollado. Los requerimientos del sistema se basan en realizar capturas de datos biomédicos y transmitirlos vía WiFi para almacenarlos en una base de datos. Para ello, la solución generada es la que encontramos representada en el esquema de la figura 1. Figura 1: Arquitectura del sistema En dicha figura, se observan dos bloques principales, por un lado tenemos un sistema de adquisición de datos que tiene interfaz directa con el paciente y, por otro lado, el servidor web donde está el sistema de gestión desde el que se realiza la demanda de datos, su almacenamiento y se proporciona el interfaz necesario para su recuperación y visualización de datos por parte del operador. La conexión entre ambos bloques se realiza de modo inalámbrico mediante una red WiFi. El sistema de adquisición está formado por un procesador basado en Arduino UNO, un conjunto de sensores biomédicos y su circuitería de acondicionamiento y adquisición reunida en la placa e-Health para arduino, y un módulo WiFi, controlado
14 desde el procesador y que permite la comunicación con el sistema de gestión y, por tanto, el envío de los datos capturados. El sistema de gestión está formado por un Servidor Web en conexión con una base de datos. Los datos recibidos desde el sistema de adquisición son incorporados a la base de datos mediante el proceso de recepción implementado en dicho servidor, y son visualizados a través de una interfaz web. Cada uno de estos sistemas se introduce en los siguientes apartados. 2.1 Sistema de adquisición de datos El sistema de adquisición de datos es el encargado de realizar la toma de medidas solicitadas por el operador del sistema centralizado. En la base de datos encontramos tres variables de estado, correspondientes a cada sensor. Cuando hablamos de variable de estado, nos referimos a un variable que puede adoptar dos estados distintos, 0 lógico o 1 lógico, indicando, según el valor que tenga, su estado inactivo o activo, respectivamente. Antes de empezar la toma de medidas, hay que comprobar que la variable de estado, está activa. Esta consulta se puede realizar de dos formas distintas. Una de ellas, es un método al que hemos denominado polling, y la otra es un método basado en interrupciones. El método polling es un método de consulta continua, es decir, está realizando consultas constantes a la base de datos para saber si la variable de estado está activa. En una de esas consultas, encontrará la variable con valor 1, indicando así, que se puede empezar la toma de medidas. El método basado en interrupciones, se lleva a cabo cuando se manda la orden de solicitud de un dato desde otro sistema, el sistema de control remoto, y esta orden es recibida por el sistema de adquisición de datos. En ese momento, se manda una interrupción y se realiza una consulta a la base de datos para comprobar que la variable de estado está activa, y por tanto, empezar la captura de datos. La variable que se encuentre activa en el momento de realizar la consulta, es la que indica la medida que se tiene que tomar. El sistema de toma de datos está formado por la unión de la placa Arduino Uno, la placa e-salud, el módulo WiFi y una serie de sensores. En la figura 2, se puede observar el conjunto completo que conforma el sistema de toma de datos.
15 Figura 2: Sistema de adquisición de datos sin sensores conectados. 2.2 Sistema de control remoto El sistema de control remoto es aquél que actúa en el usuario y en el sistema de adquisición. El sistema de control remoto en el usuario, es el responsable de iniciar la captura de datos. Este sistema está controlado por un profesional sanitario que, en el momento que quiera saber un dato de un paciente, lo solicita haciendo uso de una interfaz web. Dicha solicitud implica dos acciones, una de ellas activar la variable flag correspondiente que se encuentra alojada en la base de datos, y otra, que manda la orden de solicitud al sistema de adquisición. El sistema de control remoto en el sistema de adquisición, está realizando consultas constantes por polling y, la acción de mandar una solicitud de un dato, es la que adelanta esta consulta actuando como interrupción, es decir, en el momento en que se mande la orden de solicitud, se está mandando una interrupción al sistema de adquisición indicando que realice una consulta sobre la base de datos. 2.3 Sistema de registro de datos El sistema de registro de datos es el encargado de recibir la información referente a los datos médicos capturados en el sistema de adquisición. Los datos son recibidos y almacenados en la base de datos correspondiente. De esta forma, permite al operador del sistema consultar cualquier información de un paciente en el momento que desee.
16 2.4 Sistema de administración y consulta El sistema de administración y consulta es el que permite, al profesional sanitario que esté haciendo uso de él, consultar la información que desee mediante una interfaz de usuario. Para ello, hace uso de la base de datos y la información contenida en ella, que ha sido almacenada por el sistema de registro de datos. Este sistema constará de un control de usuarios, y cada uno de ellos tendrá diferentes permisos para acceder a información determinada de un paciente y para realizar unas u otras acciones. 2.5 Visión general Así pues, una vez que se ha explicado la función de cada bloque que compone el sistema global, donde la iniciativa de la comunicación la tiene el encargado del sistema de control remoto, se citan a continuación las herramientas que son necesarias para su correcto funcionamiento. Se pueden dividir en herramientas hardware y sus herramientas software correspondiente. Estas herramientas se encuentran detalladas en el apéndice A. Herramientas hardware: - Ordenador Pc o compatible. - Arduino UNO - Plataforma e-Health V2.0 para arduino y Raspberry-pi - Kit de sensores para medidas biomédicas para Plataforma e-Health V2.0 18 - “Communication Shield” para Arduino - Módulo WiFi para Arduino: "Roving RN-XVee" - Router WiFi - Herramientas eléctricas (Protoboard, leds, resistencias y cables).
17 Herramientas software: - IDE arduino y librerías de comunicaciones. - Librerías Arduino para Plataforma e-Health V2.0 - PHP, JavaScript, HTML como herramientas de desarrollo web. - APACHE. Servidor HTTP. - SQLite como gestor de bases de datos.
18 Capítulo 3. Sistema de adquisición de datos A lo largo del capítulo 3, se profundiza en el sistema de toma o captura de datos, citado en el capítulo anterior, al que se hace referencia en la siguiente figura. Figura 3: Sistema de adquisición de datos En la figura 3, se puede ver que el sistema de toma de datos es el dispositivo que, a través de los sensores que tiene conectados, captura los datos y los envía a través de conexión inalámbrica vía WiFi, como ya se ha introducido anteriormente. 3.1 Arquitectura En este apartado se procede a explicar la descripción del hardware del sistema del sistema de captura de datos. La parte hardware del sistema de adquisición está compuesta por la unión de la placa Arduino UNO, la placa e-Health, la placa “Communication Shield” y el módulo WiFi, una encima de otra, a través de los pines digitales y analógicos, y de los respectivos conectores para el caso de la conexión de los sensores biomédicos al dispositivo. El hardware del sistema explicado se puede observar en la figura 4. CAPTURA DE DATOS
19 Figura 4: Dispositivo con todas las placas conectadas La placa cuenta con pines digitales y analógicos. En los pines digitales libres se encuentra conectada una protoboard con un led, que se enciende en el momento que se inicia la captura de un dato (figura 5). La placa Arduino UNO debe estar conectada a una fuente de alimentación, ya sea un ordenador, una batería externa, etc. Figura 5: Placa con led El diagrama de conexiones existente entre las distintas partes del sistema se puede ver a continuación.
20 Figura 6: Diagrama de conexiones del dispositivo En el diagrama de conexiones representado en la figura 6, se presentan dos líneas referentes a pines digitales y a pines analógicos, de manera que el microcontrolador, el módulo WIFI y la placa e-Health están conectados a pines digitales indicados por flechas de color verde, y a pines analógicos indicados con flechas de color amarillo. El microcontrolador se conecta usando los pines digitales 0-12 y los pines analógicos 0-5, el módulo WIFI usa los pines digitales 0-9 y la placa e-Health los pines digitales 0-13 y analógicos 0-5. 3.1.1 Microcontrolador El microcontrolador de Arduino está formado por diversos elementos que vemos en la figura 7, que permiten la conexión y unión con las otras partes del sistema.
21 Figura 7: Esquema de conexiones de la placa Arduino El microcontrolador dispone de un pin de referencia analógica, que se aprecia en la imagen con color naranja, y que se conoce como pin AREF. Los pines digitales van del 0 al 13 teniendo en cuenta que los pines 0 y 1 son pines digitales de entrada y salida del puerto serie, son los pines TX y RX localizados en color verde oscuro. Los pines analógicos son los pines 0-5 de color azul claro. Además también se puede ver la señal de tierra digital en verde claro (GND), un botón de reset en azul oscuro y la entrada de la fuente de alimentación externa (X1). En amarillo se muestra el puerto USB, que es el puerto serie que usamos para conectar el dispositivo al ordenador. El microcontrolador puede recibir información de las entradas, la procesa y escribe un 1 o un 0 (5V ó 0V) en las salidas, actuando sobre el dispositivo que tenemos conectado, como se ve representado en la figura 8. Figura 8: Esquema entrada y salida del microcontrolador
28 Figura 15: Diagrama de procesos del software del sistema El bucle principal está implementado usando una máquina de estados, donde la primera tarea es la conexión a la red, de ahí pasa a la espera por tareas y, por último, a un estado de captura y envío de datos. 3.3.1 Bucle principal El bucle principal, comienza con el estado de conexión a la red, que es lo primero que debe ocurrir para que se lleve a cabo la comunicación entre el cliente y el servidor. En Arduino se programa la configuración del módulo WiFi, de manera que, el módulo ejecuta las órdenes y se conecta a la red correspondiente. Puede estar configurado para establecer una conexión de forma manual o automática. La red ha sido proporcionada por un teléfono móvil, con su nombre y contraseña correspondientes. En el momento en que el módulo WiFi detecta esta red, accede a ella de forma automática.
29 El siguiente estado es la espera por tareas, en el cuál, el sistema se puede configurar de dos formas, como cliente o como servidor. Una vez que el sistema está conectado a una red WiFi, se configura como servidor y espera la conexión de algún cliente. Si no hay ningún cliente disponible, entonces se vuelve a la configuración inicial donde está establecido como cliente y pasa al siguiente estado. El último estado que compone el bucle principal es la captura y envío de datos. Para que este proceso se lleve a cabo es necesario que la variable flag esté actualizada con valor 1, indicando así que se puede empezar la toma de medidas. Una vez que se comprueba que el estado del flag es 1, se procede a capturar la medida correspondiente haciendo uso de las funciones que facilita la librería de salud. Cuando la medida está tomada, Arduino realiza una petición HTTP al servidor web para enviar el dato capturado y, que pueda ser recibido y almacenado en la base de datos por el sistema de registro. La captura y envío de datos varían según el tipo de dato que se quiere capturar y enviar. En el caso del sensor de temperatura, es un dato simple que se recoge y se envía en una petición GET al servidor. Si lo que queremos capturar es una medida de pulso, entonces estamos hablando de dos valores que se tienen que capturar y mandar, uno que recoge la saturación de oxígeno en sangre y otro que recoge las pulsaciones por minuto del paciente. Son dos datos que provienen de un dispositivo inteligente. Y, por último, cuando se trata de datos de ECG se trata de un conjunto de datos los que hay que capturar y mandar. 3.3.2 Implementación del bucle principal Este apartado trata la implementación del bucle principal, los estados que lo forman y cómo se evoluciona de un estado a otro. La máquina de estados implementada se muestra en la figura 16.
30 Figura 16: Representación por máquina de estados del bucle principal Recordando las partes que integraban el bucle principal representado en la figura 15, teníamos tres procesos principales: conexión a la red, espera por tareas y, captura y envío de datos. A continuación se procede a la explicación de cada estado, desde que se realiza la conexión a la red, hasta que se captura y envía el dato solicitado.
31 CONFIGURACIÓN RED Es el primer estado con el que se inicia el proceso, ya que, lo primero que hay que hacer es configurar el módulo WiFi para conectarse a una red y poder establecer una comunicación entre el cliente y el servidor. Se establece nombre y contraseña de la red a la que queremos conectarnos, y se configura el dispositivo como cliente con la función determinada que ofrece la librería del módulo WiFi. Si se ha conectado a la red, muestra un mensaje indicando la unión correcta. Figura 17: Código Arduino correspondiente al estado CONFIGURACIÓN WIFI En la figura 17, está el código implementado en arduino cuyo nombre de estado es CONFIGWIFI.
32 INI ESPERA Este estado está implementado para programar lo necesario antes de pasar al siguiente estado de ESPERA, esto es: para abrir un socket servidor donde recibir la interrupción y programar el temporizador (timeoutflag). Este estado está implementado en Arduino de la siguiente forma. Figura 18: Implementación del estado INI ESPERA en el software de Arduino En la figura 18 están representadas las dos acciones que se realizan en este estado. En la acción referente a programar un temporizador se hace uso de la función “millis()” que devuelve la hora actual. De esta forma, la variable que actúa como temporizador se actualiza cada vez que lleguemos a este estado teniendo en cuenta que TIMEOUTFLAG es una variable definida que indica el intervalo de tiempo entre dos búsquedas de flag por polling. La otra acción es crear un socket servidor indicando el puerto donde tiene que recibir la información, es decir, la interrupción provocada cuando se solicita un dato. El puerto que está definido en la variable XLOCALPORT es el 80. Además, se realiza un control para saber si el servidor ya contiene información, lo que significa que ya ha recibido una interrupción anteriormente, y en este caso, se elimina la información que contiene para dejarlo libre a una futura interrupción. Los estados que implementan estas acciones, están definidos como CONFIGWEBSERVER y CONFIGTIMEOUT. ERROR Este estado es a donde van aquellos estados que no han podido realizar su tarea. Por ejemplo, en el caso de no poder configurar la red WiFi, pasamos a este estado donde esperará un tiempo concreto antes de probar de nuevo a realizar la conexión. Se añade un tiempo de espera con la función delay() y vuelve a reiniciarse la configuración.
33 Figura 19: Código Arduino relacionado con el estado ERROR El código que se utiliza en arduino para implementar este estado es el que se muestra en la imagen 19. ESPERA Una vez que llegamos a este estado, se detecta si ha llegado alguna conexión de forma correcta. En caso negativo, se comprueba si el tiempo de espera programado ha expirado. Figura 20: Creación de una página web indicando que se ha conectado un cliente y comprobación del tiempo de espera.
34 En la figura 20, está implementado el código de arduino que hace referencia al estado ESPERA y que recibe el nombre de TEST. INI CONFIRMA En este estado de inicio de confirmación se comprueba si existe una toma de datos pendiente, que en caso de producirse un error, pasaría al estado ERROR. Para saber si hay una toma de datos pendiente, hay que realizar una petición al servidor para que éste devuelva el valor de los flags, y así, si alguno de ellos está activo, sabemos que hay que realizar la toma de una medida. Esto se muestra en la figura 21. Figura 21: Implementación del estado INI CONFIRMA En dicha figura hay que abrir una conexión indicando el puerto y la dirección del servidor que está recogida en una variable definida como XCENTRAL, y tomará el valor de la dirección IP a la queramos conectarnos. Una vez mandada la petición, el sistema está esperando la respuesta por parte del servidor. Este estado se implementa en arduino en el estado CONFIGGET. LEELINEA Llegamos a este estado una vez que se ha realizado la petición y lo que queremos es leer línea a línea la salida para determinar el estado de los flags.
35 Para leer la respuesta, se hace uso de un array en el que se va almacenando la información recibida. Figura 22: Implementación del estado LEELINEA en Arduino En la figura 22, se ve como se inicializa el array que usamos posteriormente para guardar la información que se va leyendo. Se actualiza el tiempo de espera de la misma forma que se ha indicado en otros estados y, se comprueba si el tiempo de espera ha expirado, es decir, si no se recibe información tras esperar el tiempo programado. Una vez que encuentra información disponible, se lee y se almacena en el array definido para ello hasta que llegue a fin de línea. Es entonces cuando habrá leído toda la información y pasa al siguiente estado. Los estados implementados en arduino reciben el nombre de ESPERAFLAG y LEELINEA. FLAG En el estado FLAG se va a determinar el estado de los flags. Para ello se hace uso de la función strstr que compara dos cadenas, carácter a carácter. En este caso se
36 compara la cadena almacenada en el estado anterior en el array s con una cadena “flag”. De esta forma, puede encontrar tres cadenas, “flagTemp”, “flagPulso” y “flagECG”, como se muestra en la figura 23. Figura 23: Implementación del estado FLAG En dicha figura, se encuentra implementado el código que realiza la búsqueda del flag. Cuando encuentre un flag, pasará al siguiente estado ACCIONES. ACCIONES
37 Este estado se encarga de llamar a los sensores para realizar la toma de medidas correspondiente al flag que se ha encontrado activo en el estado anterior. Si llegamos a este estado y no hay ninguna medida pendiente para realizar, entonces vuelve al estado INI ESPERA para esperar que haya una nueva solicitud de medida. En función del flag que se encuentre activo, se realizará una acción u otra. En la figura 24 se puede observar que, según el flag que ha encontrado, pasa al estado correspondiente para realizar la toma de la medida solicitada. Figura 24: Búsqueda de flag activo Si encuentra el flag de temperatura activo, pasa al estado donde se capturan las medidas de temperatura. Si es flagPulso el que está activo, pasa al estado donde se capturan los datos de pulso. Además, en ese momento se inicia el pulsioxímetro y se manda una interrupción, de manera que, al pulsar el botón del dispositivo se activa la captura de datos y el led correspondiente se enciende. Por último, si es flagECG el que se encuentra con valor 1, pasamos al estado donde se captura un ECG. Los dos estados anteriores, FLAG y ACCIONES están recogidos en arduino como un único estado llamado LEEFLAG, en el que se realiza la búsqueda del flag y según el que encuentre, pasa a uno de los siguientes estados, sin pasar por un estado intermedio.
44 Capítulo 4. Sistema de registro de datos A lo largo de este capítulo, se van a presentar los principales aspectos del sistema de control y registro de datos, una vez que sabemos cómo se capturan y envían éstos. En primer lugar, se hace un análisis general del sistema, luego se verá qué tipos de protocolos de comunicación se usan para el intercambio de datos, y cómo se lleva a cabo la implementación de los procesos que componen el sistema. 4.1 Análisis y arquitectura del sistema El sistema de registro de datos está formado principalmente por tres procesos. El proceso de disparo de medidas, el proceso de consulta de tareas, y el de registro de los datos que se reciben desde Arduino, desde sistema de adquisición de datos. Estos procesos se realizan en el servidor y el primero que se lleva a cabo es el disparo de medidas, ya que, es el que indica e inicia la comunicación entre el cliente y el servidor. En el esquema que aparece en la figura 31 se pueden ver estos procesos representados de forma gráfica.
45 Figura 31: Esquema del sistema de control y registro El proceso de disparo de medidas consiste en lanzar una petición ejecutada por un operador que solicita un dato a Arduino. El proceso que representa la recepción de esta petición, es el que aparece como cliente con sensores, ya que, es ahí, donde están conectados los sensores y el dispositivo de Arduino a un paciente determinado y, por tanto, donde se realiza la captura de datos. Además, este proceso necesita interactuar con la base de datos, de manera que actualiza el estado de la variable flag a 1 para que comience la toma de datos. En segundo lugar, tenemos el proceso de consulta de tareas, que permite consultar cualquier dato sobre la base de datos. El cliente con los sensores conectados, manda una petición al proceso de consulta de tareas para consultar el valor del flag, y éste, hace una consulta sobre la base de datos para obtenerlo. El proceso número 3, registro de datos, es un proceso de recepción de los datos capturados. Los datos que han sido tomados al cliente son mandados al servidor y, recibidos y almacenados en este proceso.
46 Además, el usuario que lleva a cabo el proceso de gestión y consulta, también accede a la base de datos para obtener la información que desee. 4.2 Protocolo de comunicación entre el cliente y el servidor web Para que exista comunicación entre el cliente y el servidor, es necesario el uso de un protocolo de petición y respuesta. (Figura 32). Figura 32: Comunicación Cliente/Servidor En este caso, el protocolo HTTP es el que se usa, y es un protocolo que nos suministra dos tipos de primitivas para el intercambio de datos entre el cliente y el servidor. Son las órdenes GET y POST. Tanto GET como POST están compuestos por un envío al servidor conocido como petición y una respuesta a dicha solicitud. GET significa obtener información del servidor, es decir, traer datos que están en el servidor, ya sea en un archivo o en la base de datos, al cliente, teniendo en cuenta que para recibir esos datos, tenemos que enviar otros que el servidor procesa y envía la respuesta. POST es enviar información desde el cliente para que sea procesada y actualice o agregue información en el servidor. Son métodos que, al fin y al cabo, lo que hacen es mandar una petición al servidor y esperar una respuesta de éste, es decir, el objetivo es el mismo. La diferencia entre los dos métodos radica en la forma de mandar los datos a la página. Mientras que el método GET envía los datos usando la URL, el método POST los envía de forma que no podemos verlos en la URL, quedan ocultos al usuario.
47 Algo que favorece el método POST es que se puede mandar mucha más cantidad de datos que por GET. En este proyecto hemos trabajado con método GET, ya que, la cantidad de datos que usamos no es muy grande. Lo hacemos pasando los valores a través de la url o link. Con el mismo tipo de protocolo HTTP con el que se envía la petición, desde hacerse la recepción de ésta. En las siguientes dos imágenes se puede apreciar la diferencia entre una petición de tipo GET (figura 33) y una petición de tipo POST (figura 34). Figura 33: Ejemplo de petición tipo GET Figura 34: Ejemplo de petición tipo POST 4.3 Implementación La implementación del sistema de control y registro de datos se realiza en el servidor, ejecutando distintos scripts que hacen uso del lenguaje PHP. Este lenguaje nos permite recibir la información que se manda desde el dispositivo arduino, e interpretarla y trabajar con ella. 4.3.1 Implementación del proceso Disparo de medidas Como se ha comentado, este proceso comienza cuando el operador solicita un dato a Arduino en el servidor, y actualizando la variable de estado a 1. Esto se realiza con lenguaje PHP como se muestra a continuación.
48 Figura 35: Solicitud de un dato de temperatura en el servidor Como se observa en la figura 35, lo primero que se hace es, una vez guardados los datos que el usuario introduce a través de la interfaz web, abrir la base de datos y, si el dato es de temperatura, como en este caso, se actualiza a 1 el valor de la variable flagTemp alojada en la tabla PacienteArduino. Si el dato solicitado es otro distinto de temperatura, se procede de la misma forma, actualizando la variable asociada a ese dato. Para que el operador de la interfaz web pueda solicitar un dato, se dispone en el servidor web de script como el que tenemos a continuación. Figura 36: Solicitud de datos en la Página Web El código html que aparece en la figura 36, es el que permite que el operador indique en la página web el dato que quiere solicitar y de qué paciente.
49 4.3.2 Implementación del proceso de registro de datos Después de solicitar un dato al cliente, éste envía la medida capturada al servidor, que debe procesarla y registrarla en la base de datos. En este caso, se crean dos scripts distintos para cada medida solicitada. Un archivo que recibe la información del cliente y la procesa y registra, y otro, que es el que permite la visualización de esta información en la interfaz web. El proceso de recepción y registro no se hace de la misma forma, si se trata de un dato de temperatura, de pulso, o si es un dato de ECG. A continuación, se puede ver en los siguientes diagramas de flujo los pasos que sigue desde que se recibe un dato hasta que se almacena, ya sea un dato de temperatura, pulso o ECG, respectivamente. Figura 37: Diagrama de flujo de recepción de datos de temperatura.
50 Figura 38: Diagrama de flujo de recepción de datos de pulso
51 Figura 39: Diagrama de flujo de recepción de datos de ECG. Como se muestra en los diagramas de flujo de las figuras 37, 38 y 39, temperatura, pulso y ECG comparten los primeros pasos. Una vez que se recibe el dato desde arduino, se guarda en una variable para poder trabajar con ella. Es necesario realizar la apertura de la base de datos indicando la ruta de su localización y se realiza una consulta para obtener el identificador del paciente con el que estamos trabajando.
52 Figura 40: Procesos compartidos en la recepción de datos de temperatura, pulso y ECG La diferencia reside en la forma de insertar los datos en la base de datos. No sólo se insertan en tablas distintas, sino que, en el caso de temperatura y pulso es una inserción sencilla de datos simples, pero en el caso del ECG, se trata de insertar varios paquetes de datos. Cada uno de estos paquetes se manda de forma separada, es decir, primero llega un paquete identificado como paquete 0, y luego van llegando los demás. De esta forma, el primer paquete se inserta directamente de forma usual, pero, el resto de paquetes que van llegando no se pueden insertar de la misma manera porque sustituye los datos ya existentes. Así que, en lugar de realizar una inserción, hay que hacer una actualización de la variable en la que se almacenen los datos de cada paquete, teniendo al final, todos los datos de los paquetes recibidos enlazados unos detrás de otros en la misma variable. El código en lenguaje PHP, localizado en el servidor, correspondiente al registro y almacén de datos, se encuentra en el Apéndice C. 4.3.3 Implementación del proceso de consulta de tareas Como ya se ha comentado, este proceso es el que permite hacer la consulta del flag o la dirección IP que tiene el cliente, sobre la base de datos. El resultado de esta consulta, se puede visualizar en la página web, pero no se manda al cliente. Desde arduino se envía una petición al servidor, solicitando el estado del flag. Es entonces cuando, el servidor recibe esta petición y la procesa. (Figura 41).
53 Figura 41: Código en lenguaje PHP que implementa la consulta del "flag" en el servidor En la figura 41, se ve como recibe la variable idarduino que se envía en la petición mandada desde el dispositivo y, una vez abierta la base de datos, se hace la consulta sobre ella de los flags, así como, se actualiza la IP usando la estructura $_SERVER [‘REMOTE_ADDR’] que nos da la IP del cliente que esté conectado en ese momento, y la asignamos en la base de datos. En definitiva, el sistema de control y registro es el que permite que los datos capturados sean procesados y almacenados en el servidor.
60 Figura 49: Arquitectura general de la Aplicación Web Se puede ver en la figura 49 que, Administrador y Médico, son usuarios que comparten gran cantidad de acciones, porque son los que mayor uso darán a la web. En cambio, un enfermero, se considera en este proyecto, que el número de acciones que realiza es mucho más limitado, centrándose en consulta y visualización de datos, básicamente.
61 Capítulo 6. Pruebas y resultados Se han realizado diversas pruebas para comprobar el correcto funcionamiento de la base de datos, el de la página web, conexión WiFi y la transmisión de datos y, por tanto, la conexión entre Arduino y la página web. 6.1 Pruebas sobre la base de datos Consultas para que muestre todos los pacientes de la tabla Pacientes, o bien, si queremos un paciente determinado estableciendo una restricción. Por ejemplo, sobre la tabla PacienteArduino para que muestre qué valor de flag está a 1, que es una de las consultas principales en este proyecto, ya que, es lo que indica que se puede comenzar la toma de medidas. La consulta que nos muestra los valores del flag sería tal y como aparece en la figura 50. Figura 50: Consulta sobre la tabla PacienteArduino Si lo que queremos es consultar una medida concreta, la consulta la haríamos sobre la tabla que contiene la información de los valores medidos. De esta forma, si queremos saber el valor de la temperatura corporal de un paciente indicado: (Figura 51). Figura 51: Consulta de un dato de temperatura Y del mismo modo si queremos saber datos de pulso o ECG. 6.2 Pruebas sobre la página web Pruebas para comprobar que hay un control correcto de usuarios, para que se visualicen los datos, para ver un listado de pacientes, para ver la gráfica del ECG, añadir y eliminar pacientes, etc. En general pruebas realizadas para comprobar que las acciones que se añaden en la página web funcionan correctamente. Si se accede de forma correcta o incorrecta, muestra un mensaje en la página web indicándolo. Si se accede correctamente, indicará el permiso que tiene. (Figura 52).
62 Figura 52: Control correcto o erróneo de usuarios Cuando añadimos un nuevo paciente, la interfaz web que aparece es la siguiente: Figura 53: Procedimiento para añadir un nuevo paciente a la base de datos En la figura 53 nos muestra toda la información que se solicita para que el operador de la página realice un registro de un paciente que no está en la base de datos. Cuando se introducen todos los datos de forma correcta, nos muestra un listado con los pacientes donde se puede comprobar que el último registro se ha realizado correctamente.
63 Figura 56: Generador de señales A la hora de visualizar una medida, debemos introducir el paciente y la medida que queremos solicitar para que posteriormente nos devuelva lo que hemos pedido. (Figura 54). Figura 54: Proceso para visualizar una medida Una de las pruebas que más se han realizado es la representación gráfica de los datos capturados de ECG. Para estas pruebas, era necesario atenuar la señal montando un divisor de tensión en una protoboard(figura 55), y con ayuda del generador de señales (figura 56) y del osciloscopio se iba probando a diferentes frecuencias para ver el comportamiento según la frecuencia de muestreo utilizada. Figura 55: Divisor de tensión en la protoboard En la siguiente tabla (Figura 57) se recogen distintas gráficas de las pruebas realizadas. La columna de la derecha es la gráfica que se obtiene en el osciloscopio y la de la izquierda la gráfica que se visualiza a través de la página web.
64 Figura 557: Representaciones gráficas de ECG En la figura 57, se representan gráficas de ECG para valores de 10, 15, 20 y 25 milisegundos. Estos valores indican que las frecuencias a las que hemos muestreado son de 1.2, 1.8, 2.4 y 3 Hz respectívamente. Para ello, hemos tenido en cuenta que el número máximo de muestras que podemos mandar es de 120. El intervalo en el que trabajamos estará entre 60 y 130 pulsaciones por minuto, sabiendo que 60 p/m, equivale a 1 p/s. Con todo esto, observamos que los 50 milisegundos de los que hablamos en capítulos anteriores, no puede ser la elección porque no podríamos ver una señal normal de ECG, ya que la frecuencia sería menor de 1Hz. Como se puede observar, cuanto mayor es la frecuencia, mayor es el conjunto de ciclos de ECG que se pueden visualizar. 6.3 Pruebas en la conexión WiFi y transmisión de datos A la hora de realizar la conexión del módulo WiFi hubo que hacer pruebas en relación a los comandos que hay que usar, ya que, en muchos comandos se pueden tomar
65 distintos valores. Por ejemplo, para que se conecte de forma automática o manual, o para elegir un tipo de protocolo u otro. Una vez que se conecta a la red, se hicieron pruebas para la transmisión y recepción de datos. Tanto con GET, como con POST, probamos a mandar desde datos simples como un número, hasta con cadenas de caracteres. Sabiendo que el objetivo de los dos métodos es el mismo, pero si queremos mandar una cantidad mayor de datos era mejor con POST. Además, con el mismo método que se mandaban los datos, teníamos que recibirlos en el servidor y de forma correcta. Por ejemplo, hacer una transmisión de un dato de temperatura desde Arduino y recibirlo en el servidor, Wifly.println(GET/temperatura.php?temp=36); //Transmisión $temperatura = $_GET[‘temp’]; //Recepción 6.4 Pruebas técnicas En la parte técnica empezamos con la conexión vía USB con la placa Arduino Uno. Para comprobar que todo estaba correcto, el software de Arduino ofrece multitud de ejemplos sencillos. Por ejemplo, encender un led, o simplemente que se encienda una luz de la placa al pulsar una letra, y que se apague al pulsar otra. (Figura 58). Figura 56: Prueba para encender la luz de la placa
66 De la misma manera cuando unimos la placa e-Health a la de Arduino Uno y, posteriormente, el módulo WiFi. En cuanto a sensores, con pruebas simples como captar una temperatura o una toma de pulso y que se muestre en el monitor para comprobar que tomaba los datos de forma correcta. También para comprobar que encendía un led al tomar un dato concreto. Con estas pruebas nos dimos cuenta que la placa con la que hemos trabajado sólo dispone de un puerto UART y fue ahí cuando tuvimos que hacer un cambio quitando dos pines y haciendo puente con otros, para que la transmisión de datos se realizara de forma correcta. Pero, no sólo eso. Finalmente no se pudo conseguir una correcta transmisión de datos entre el cliente y el servidor. Para ello, se optó por usar la placa ethernet como alternativa. (Figura 59). Figura 57: Placa Ethernet La gran diferencia de lo que habíamos hecho hasta ahora es que la transmisión de datos con esta placa es por cable y no de forma inalámbrica. Esta placa nos permite conectarnos a Internet y sus principales características son: ·Está basada en el chip W5100. ·Soporta hasta 4 conexiones de sockets simultáneas. ·Usa la librería Ethernet para escribir programas que se conecten a internet usando la Shield. ·Dispone de unos conectores que permiten la unión de otras placas encima. ·Utiliza los pines 10,11, 12 y 13 para comunicarse con el W5100. ·El botón de reset que dispone, resetea ambos, el chip y Arduino.
67 ·Los sketchs se cargan de la misma forma que con la placa Arduino. Una vez subidos, se puede desconectar del ordenador y alimentar la placa con una fuente externa. Para realizar la conexión, hemos usado un cable cruzado entre el dispositivo y el ordenador. El código programado en arduino está diseñado para poder trabajar con módulo WiFi y con módulo Ethernet, como se muestra en la figura 60. Figura 58: Configuración del hardware en el IDE de arduino Según el que queremos usar, se comenta uno u otro. De esta forma, sólo se ejecutarán unas funciones y órdenes si trabajamos con el módulo WiFi y otras, si trabajamos con módulo Ethernet. La configuración del nuevo módulo se muestra en la figura 61, donde se establecen los parámetros de forma distinta a como se hacía con el módulo WiFi y se crea un servidor y un cliente, con los que se trabaja en el programa para realizar la comunicación y la transmisión de datos. Figura 59: Configuración Ethernet
68 Al final, realizando pruebas con esta alternativa, pudimos comprobar que la transmisión se realizaba correctamente, y que, creemos que el problema reside en los conflictos que da la librería asociada al módulo WiFi. El resultado final es la unión de la placa Arduino Uno, la placa Ethernet y la placa eHealth junto con la unión de una protoboard con LED. (Figura 61). Figura 60: Dispositivo final
69 7. Conclusiones. En este Trabajo de Fin de Grado: ·Se ha implementado un sistema de adquisición y registro de datos biomédicos, formado por Arduino Uno, plataforma e-Health con sus respectivos sensores, la placa de comunicación junto con el módulo WiFi Roving RN-XV 171. ·Se ha implementado un sistema de gestión y recepción de datos. Para ello se ha usado el servidor web Apache en el que se ha alojado una base de datos y la página web. ·Se ha conseguido establecer un protocolo de intercambio de información desde el microcontrolador de Arduino hasta el servidor web mediante comunicación WiFi, donde la iniciativa en la comunicación y transmisión de la información la lleva siempre acabo el operador del sistema centralizado. ·La conexión a internet se ha realizado por cable con el uso del módulo Ethernet como alternativa a la inicialmente planteada mediante WiFi. ·Se ha conseguido una correcta recepción de datos enviados desde Arduino al servidor. ·Se ha conseguido un correcto funcionamiento de la página web para poder visualizar los datos. ·Se ha creado una base de datos donde almacenar toda la información.
76 Elementos hardware -Ordenador Pc o compatible. El ordenador y sistema operativo con el que se ha trabajado es Windows, pero sin problema se puede trabajar con Linux o Mac OS, ya que el entorno de desarrollo del proyecto es accesible también a ellos. -Arduino Arduino es una compañía de hardware libre, la cual desarrolla placas de desarrollo que integran un microcontrolador y un entorno de desarrollo (IDE), diseñado para facilitar el uso de la electrónica en proyectos multidisciplinarios. Arduino es una compañía que desarrolla placas de hardware libre y que integran un microcontrolador y un entorno de desarrollo IDE, como se ha comentado en un punto anterior. El microcontrolador está integrado por un circuito que se alimenta con un voltaje de +5 voltios, posee multiplicadores de voltaje y condensadores que permiten la implementación de puertos serie en dispositivos que tengan esta alimentación de 5 voltios. La placa, además del microcontrolador, posee puertos digitales y analógicos de entrada y de salida que pueden conectarse a otras placas para extender el funcionamiento de ésta. Las especificaciones de la placa Arduino Uno son las siguientes: Tabla 2: Especificaciones técnicas de Arduino
77 Y a continuación podemos ver un esquema de la placa en la figura 63. Figura 61: Esquema de la placa Arduino Como se puede ver en la imagen, dispone de un botón RESET, que nos permitirá resetear la placa y por tanto, el programa que esté cargado en ella y así indicarle que comience de nuevo. El conector de alimentación que nos permitirá prescindir de la conexión por cable a un ordenador, que se lleva a cabo por le entrada USB que dispone. -Plataforma e-Health V2.0 para arduino y Raspberry-pi La placa e-Salud permite a los usuarios de Arduino y Rasperry Pi llevar a cabo aplicaciones médicas donde el monitoreo del cuerpo es necesario mediante el uso de 10 sensores diferentes: pulso , de oxígeno en la sangre (SpO2) , el flujo de aire (respiración) , la temperatura corporal , electrocardiograma (ECG) , glucómetro , la respuesta galvánica de la piel (GSR - sudoración) , la presión arterial (esfigmomanómetro) , la posición del paciente (acelerómetro) y electromiografía (EMG ) . Esta información se puede utilizar para monitorizar en tiempo real el estado de un paciente o para obtener datos sensibles con el fin de ser analizados posteriormente para el diagnóstico médico. La información de los datos se puede enviar de forma inalámbrica utilizando cualquiera de las opciones de conectividad disponibles: Wi-Fi , 3G , GPRS , Bluetooth , ZigBee 802.15.4 y dependiendo de la aplicación.
78 Si se necesita el diagnóstico por imagen en tiempo real de una cámara se puede conectar al módulo 3G con el fin de enviar fotos y vídeos del paciente a un centro de diagnóstico médico. En este proyecto los sensores que se han utilizado son el pulsioxímetro, el sensor de temperatura y el sensor de electrocardiografía, y el tipo de conectividad es vía WiFi. Figura 62: Placa e-Health conectada a Arduino En la imagen 64, se ve la placa de salud conectada con Arduino para trabajar con él. - Kit de sensores para medida biomédicas para Plataforma e-Health V2.0. Sensor de temperatura Este sensor permite medir la temperatura corporal de un paciente. Hoy en día, una gran cantidad de enfermedades están acompañadas por cambios característicos en la temperatura corporal, por lo tanto, sería de gran utilidad trabajar con él en las condiciones que se especifican a lo largo del documento.
79 Figura 63: Sensor de temperatura En la imagen se muestra la realidad del uso de un sensor de temperatura, que se pega en la yema del dedo por la que circulan numerosos vasos y se conecta a la placa, que nos permitirá usar la función determinada para calcular la temperatura corporal. Los rangos son los siguientes: ·Hipotermia <35,0 º C (95,0 º F) ·Normal 36,5 a 37,5 º C (97,7 – 99,5 º F) ·Fiebre o hipertermia >37,5 a 38,3 º C (99,5 a 100,9 º F) ·Hiperpirexia >40,0 a 41,5 º C (104 a 106,7 º F) Cuando se utiliza el sensor de temperatura, lo que se está midiendo en realidad es una tensión, por cada tensión se obtiene una correspondencia de temperatura, por lo que es muy importante la calibración de este sensor para que mida correctamente el nivel de temperatura corporal. El circuito asociado a este sensor es el siguiente:
80 Figura 64: Circuito del funcionamiento del sensor de temperatura El diseño para el sensor de temperatura se basa en un puente de Wheatstone. El puente de Wheatstone ha sido diseñado para cubrir el rango de temperaturas de interés: entre 25ºC y 50ºC. La tensión de salida diferencial del puente de Wheatstone es amplificada y referenciada a tierra mediante un amplificador de instrumentación. Este sensor se comunica mediante el pin analógico 3 de Arduino. Sensor de pulso Este sensor mide la cantidad de oxígeno que hay en la sangre y el recuento de pulsaciones por minuto al que late el corazón. La saturación de oxígeno se define como la cantidad de oxígeno que hay disuelto en la sangre, sobre la base de la detección de hemoglobina (Hb) y desoxihemoglobina (HbO2). El funcionamiento es detectar la hemoglobina y desoxihemoglobina. Utiliza dos longitudes de onda de luz diferentes para medir la diferencia real en los espectros de absorción de HbO2 y Hb. La circulación sanguínea se ve afectada por la concentración de Hb y HbO2 en sangre, y sus coeficientes de absorción se miden usando dos longitudes de onda, 660 nm (espectros de luz roja ) y 940 nm (espectros de luz infrarroja) . Hemoglobina desoxigenada y oxigenada se encargan de absorber las diferentes longitudes de onda.
81 Figura 65: Sensor de pulsioximetría En la imagen 67, se observa que, introduciendo el dedo índice en el pulsioxímetro y pulsando el botón de inicio, a través de luz infraroja, se detecta la hemoglobina en la sangre y muestra en la pantalla los resultados de saturación y pulso. Este tipo de sensores son útiles cuando se posee un paciente con nivel de oxígeno en sangre inestable, debido a enfermedades crónicas. Este tipo de enfermedades requieren un control de los niveles de oxígeno para comprobar si se necesita suplemento de oxígeno. Los rangos normales son entre 95 y 99 %. Sensor de ECG El electrocardiograma es una herramienta de diagnóstico que se utiliza para evaluar las funciones eléctricas y musculares del corazón. El electrocardiograma (ECG) es uno de los exámenes médicos más usados actualmente. Se utiliza para diagnosticar patologías cardíacas como isquemia o infarto, siendo esto de gran utilidad para los médicos. El valor que se obtiene es tensión medida en voltios.
82 Figura 66: Sensor de ECG Como se observa, el sensor dispone de tres polos, positivo(rojo), negativo(negro) y neutro(blanco), cada uno de ellos conectado a la placa en el lugar correspondiente. A continuación, se muestra una gráfica de lo que sería un ECG normal, con intervalos P y T positivos, picos Q y S negativos y un pico característico R. Cada uno de ellos tiene una duración y voltaje determinados para que se pueda analizar y especificar si hay alguna anomalía o está correcto. Figura 67: Curva característica de ECG
83 El circuito correspondiente: Figura 68: Circuito del funcionamiento de ECG La electrónica de adaptación necesaria para el electrocardiograma, ha sido basada en las especificaciones técnicas de un amplificador de instrumentación. Este dispositivo es el encargado de amplificar la señal diferencial de entrada proveniente de los electrodos izquierdo y derecho. Se utilizan amplificadores operacionales para completar las distintas etapas necesarias para la medición de la señal de ECG. Este sensor utiliza el pin analógico 0 de Arduino para la comunicación. -“Communication Shield” para Arduino La placa “Communication Shield” dispone de un pequeño interruptor con dos posiciones disponibles: una llamada XBEE y otra llamada USB. El esquema que muestra la diferencia entre una configuración u otra se muestra a continuación. Figura 69: Posiciones que ofrece la placa de comunicación En la posición XBEE, la salida del módulo WiFi está conectada al pin de escucha del microcontrolador y la entrada del WiFi a la salida del micro, pero hay que tener en cuenta que los pines comunicación del micro siguen conectados al puerto de comunicaciones del Arduino y este al ordenador.
84 En XBEE no podemos subir ni compilar ningún sketch con código. Figura 70: Modo de funcionamiento XBEE Para poder cargar el código del programa hay que usar el modo USB, donde el módulo WiFi estará conectado al puerto USB, es decir, el módulo se comunica directamente con nuestro ordenador. Una vez que el programa ha sido cargado en Arduino, se puede cambiar la posición del interruptor y ponerlo en XBEE. Figura 71: Modo de funcionamiento en USB La solución final fue deshabilitar la conexión física del puerto de comunicaciones entre la placa “Communication Shield” y Arduino, y se creó un puente o canal serie entre el micro y el módulo WiFi. De esta manera el puerto serie se comunica con el Arduino y el Arduino se comunica con el módulo WiFi y no es necesario estar cambiando el interruptor. Esta comunicación se realiza por otro puerto serie diferente por lo que podemos usar el puerto serie nativo para tareas de depuración. Lo que hacemos es quitar los pines 0 y 1 de nuestra placa para inhabilitar la comunicación serie y que no entren en contacto con Arduino y creamos un canal virtual serie entre los pines 8 y 9 de Arduino. Para ello, usaremos la librería SoftwareSerial, ya mencionada anteriormente. El interruptor debe estar en la posición XBEE porque
85 lo que se quiere conseguir es que el módulo WiFi se comunique con el microprocesador para intercambiar comandos. De este modo Arduino dispondrá de dos puertos serie: el nativo USB que usaremos para programarlo y para enviar información de depuración y el puerto virtual para la comunicación entre el microprocesador y el módulo WiFi. Figura 72: Dispositivo Arduino con la apertura del puerto virtual Una vez que está listo la configuración del hardware, creamos en Arduino el puerto virtual con las siguientes líneas de comandos: Figura 73: Creación del puerto virtual en el código de Arduino Módulo WiFi para Arduino: "Roving RN-XVee" El módulo "Roving RN-XVee" es el modelo que hemos usado. El módulo RN-XV integra un RN-171 Wi-Fi, un radio 802.11 b/g, un procesador de 32 bits, un stack TCP/IP, un reloj de tiempo real, un crypto acelerador, una unidad de manejo de potencia y una interfaz análoga. El módulo tiene pre-grabado un firmware que simplifica la integración y minimiza el tiempo de desarrollo teniendo una simple configuración de hardware donde solo se tienen cuatro conexiones PWR, TX, RX y GND. Características
92 int pulso_cuenta ; //Funcion que lee datos del pulsioximetro void readPulsioximeter(){ pulso_cuenta ++; if (pulso_cuenta == 50) { // solo tomamos una de cada 50 medidas eHealth.readPulsioximeter(); pulso_cuenta = 0; if( estado == CAPTURADATOSPULSO ) estado = CAPTURADATOSPULSO2 ; } } #endif // CONPULSO unsigned cuenta ; #ifdef CONECG int flagECG; #define ecgLENGTH 10 //Longitud maxima del array s int ecg[ecgLENGTH]; //Creamos un array para leer datos de ECG #define ALENGTH 120 int a[ALENGTH]; volatile int por_a; //Me va a indicar por donde va la interrupcion String dato; void timerIsr(); #endif void check(void) ; #define SLENGTH 100 //Longitud maxima del array s char s[SLENGTH + 1]; //Creamos un array para leer datos unsigned long timeoutflag; unsigned long timeout; #define TIMEOUTFLAG 100000 /* intervalo de tiempo entre dos busquedas de los flag por pulling */ #define TIMEOUTCHAR 10000 /* tiempo maximo que se puede esperar la llegada del proximo byte en una conexion */ void setup() { #ifdef A_LEO while ( ! Serial ) ; #endif //Inicializamos pulsioxímetro #ifdef CONPULSO pinMode(ledPulso, OUTPUT); digitalWrite( ledPulso , LOW ) ; eHealth.initPulsioximeter(); #endif
93 //Inicializamos ECG #ifdef CONECG por_a = -1; Timer1.initialize(50000); Timer1.attachInterrupt(timerIsr);//Inicio de interrupcion #endif estado = CONFIGWIFI; estado_old = ESPERA ; } void loop() { if ( estado != estado_old ) { switch ( estado ) { case CONFIGWIFI : Serial.println( F("CONFIGWIFI") ) ; break ; case CONFIGWEBSERVER : Serial.println( F("CONFIGWEBSERVER") ) ; break ; case TEST : Serial.println( F("TEST") ) ; break ; case CONFIGGET : Serial.println( F("CONFIGGET") ) ; break ; case ESPERAFLAG: Serial.println( F("ESPERAFLAG") ) ; break ; case LEELINEA : Serial.println( F("LEELINEA") ) ; break ; case LEEFLAG2 : Serial.println( F("LEEFLAG2") ) ; break ; case LEEFLAG : Serial.println( F("LEEFLAG") ) ; break ; case ESPERA1 : Serial.println( F("ESPERA1") ) ; break ; #ifdef CONTEMP case CAPTURADATOSTEMP : Serial.println( F("CAPTURADATOSTEMP") ) ; break ; #endif #ifdef CONPULSO case CAPTURADATOSPULSO : Serial.println( F("CAPTURADATOSPULSO") ) ; break ; case CAPTURADATOSPULSO2 : Serial.println( F("CAPTURADATOSPULSO2") ) ; break ; #endif #ifdef CONECG case CAPTURADATOSECG : Serial.println( F("CAPTURADATOSECG") ) ; break ; #endif case CONFIGTIMEOUT : Serial.println( F("CONFIGTIMEOUT") ) ; break ; case ESPERA : Serial.println( F("ESPERA") ) ; break ; case ERROR_ : Serial.println( F("ERROR_") ) ; break ; } estado_old = estado ; } static int nn ; switch (estado) { case CONFIGWIFI:
94 //Configuramos la conexion a la red Serial.begin(9600); #ifdef C_WIFI wifiSerial.begin(9600); if (!wifly.begin(&wifiSerial, &Serial)) { Serial.println("Failed to start wifly"); estado = ERROR_ ; break ; } if (! wifly.isAssociated()) { wifly.setProtocol(WIFLY_PROTOCOL_TCP); wifly.setPort(XLOCALPORT); wifly.setSSID(mySSID); wifly.setPassphrase(myPassword); wifly.enableDHCP(); if (wifly.join()) { Serial.println("Joined wifi network"); } } Serial.print("MAC: "); Serial.println(wifly.getMAC (s, sizeof(s))); Serial.print("IP: "); Serial.println(wifly.getIP(s, sizeof(s))); Serial.print("Netmask: "); Serial.println(wifly.getNetmask(s, sizeof(s))); Serial.print("Gateway: "); Serial.println(wifly.getGateway(s, sizeof(s))); wifly.setDeviceID("Wifly-WebClient"); #endif // C_WIFI #ifdef C_ETH Ethernet.begin( mac , ip , _dns , gw , sn ) ; #endif //C_ETH estado = CONFIGTIMEOUT; break; case ERROR_ : // Estado en el que se espera un tiempo antes de reiniciar // el sistema delay( 60000000 ) ; // 1 minuto estado = CONFIGWIFI ; break ; case CONFIGWEBSERVER: //Se configura el servidor #ifdef CONPULSO digitalWrite( ledPulso , LOW ) ; PCintPort::detachInterrupt( 6 ) ; #endif
95 #ifdef C_WIFI if (wifly.isConnected()) { wifly.close(); } wifly.setProtocol(WIFLY_PROTOCOL_TCP); if (wifly.getPort() != XLOCALPORT ) { wifly.setPort(XLOCALPORT); wifly.save(); Serial.println(F("Set port to 80, rebooting to make it work")); if ( wifly.reboot() ) { Serial.println( "No funciona el reset, lo forzamos" ) ; delay( 1000 ) ; break; asm volatile (" jmp 0"); } delay(3000); } else #endif // C_WIFI #ifdef C_ETH Ethernet.begin( mac , ip , _dns , gw , sn ) ; if( server != NULL ) { RedCliente.close( ) ; delete server ; server = NULL ; } server = new EthernetServer(XLOCALPORT) ; #endif { estado = TEST ; } Serial.println(F("Listo")); cuenta = 0 ; break; case TEST: //Este estado se corresponde con el estado ESPERA de la maquina de estados cuenta = 0 ; #if defined( C_ETH ) RedServicio = server->available( ) ; #endif if (RedServicio.available( ) > 0) { // Se ha conectado un cliente, devolvemos una pagina indicandolo Serial.println( F("Conexion entrante")) ; RedServicio.flushRx() ;
96 RedServicio.println(F("HTTP/1.1")); RedServicio.println(F("Content-Type: text/html")); RedServicio.println(F("Transfer-Encoding: chunked")); RedServicio.println(); RedServicio.sendChunkln(F("<html><head>")); RedServicio.sendChunkln(F("<title>Arduino</title>")); RedServicio.sendChunkln(F("</head><body>")); RedServicio.sendChunk(F("<h1>Conectado a arduino ")) ; snprintf( s , 9 , "%d" , cuenta ) ; RedServicio.sendChunk( s ) ; RedServicio.sendChunkln(F("</h1>")); RedServicio.sendChunkln(F("<hr>")); RedServicio.sendChunkln(F("</body></html>")); RedServicio.sendChunkln(); RedServicio.close( ) ; estado = CONFIGGET ; break; } else if (millis() > timeoutflag) { // expira el tiempo antes de chequear el estado de los flags de medidas estado = CONFIGGET; break; } else { estado = TEST; break; } break; case CONFIGGET: //Estado INI CONFIRMA en la máquina de estados cuenta ++ ; // Abrimos una conexión con el puerto 80, para verificar // el estado de los flags. RedCliente.close( ) ; if (RedCliente.open(XCENTRAL, 80)) { Serial.print(F("Connected to Apache 1\n")); //Una vez conectados, se manda la peticion para leer el flag RedCliente.print(F("GET /Pagina/medico/leeFlag.php?idarduino=3")); RedCliente.println(F(" HTTP/1.0")); RedCliente.println(F("Host: " XCENTRAL )); RedCliente.println("Connection: close"); RedCliente.println(F("")); estado = ESPERAFLAG; timeout = millis( ) + TIMEOUTCHAR ; #ifdef CONTEMP flagTemp = -1; #endif #ifdef CONPULSO flagPulso = -1; #endif #ifdef CONECG flagECG = -1;
97 #endif } else { // no esta disponible el servidor estado = CONFIGTIMEOUT; RedCliente.close( ) ; } break; case ESPERAFLAG: // Se lee linea a linea la salida para determinar el estado de los flags de tares if (RedCliente.available() > 0) { nn = 0 ; s[nn] = 0 ; estado = LEELINEA ; timeout = millis( ) + TIMEOUTCHAR ; } else if ( timeout < millis() ) { //Si expira el tiempo de espera estado = ESPERA ; } break; case LEELINEA : //Entra dentro del estado LEELINEA de la maquina de estados { bool x = false; if ( (nn < SLENGTH) && (RedCliente.available() > 0) ) { #define ACARACTERES #ifdef ACARACTERES timeout = millis() + TIMEOUTCHAR; //Vamos leyendo la informacion y almacenandola en un array s[nn] = RedCliente.read(); // Serial.print( s+nn ) ; delay( 1 ) ; if ((s[nn] == '\n') || (s[nn] == '\r')) { Serial.print( "fin de linea\n" ) ; estado = LEEFLAG2 ; } else if (nn > 4 && strncmp("<br/>", &s[nn - 4], 5) == 0) { Serial.println("Llega br\n"); estado = LEEFLAG2; } #else // ACARACTERES nn = wifly.gets( s , SLENGTH , 10000 ) ; estado = nn > 0 ? LEEFLAG2 : ESPERA ; #endif // ACARACTERES if( nn >= 0 ) s[++nn] = 0 ; } else if ( nn >= SLENGTH ) { estado = LEEFLAG2 ; } else if ( (RedCliente.available() < 1) || (x = (millis() > timeout)) ) { if (x) {
98 Serial.println("Timeout"); } if (nn > 0) { estado = LEEFLAG2; } else { estado = ESPERA ; RedCliente.close( ) ; } break; } } break ; //Cuando termine de leer, llega a este estado que es el estado //FLAG en la maquina de estados case LEEFLAG2 : nn = 0 ; Serial.print("ws: "); if ( s[0] ) { Serial.print( s ) ; } { //Comparamos el contenido del array s con la cadena "flag" char * S = s[0] ? strstr( s , "flag" ) : 0 ; if ( S > 0) { #ifdef CONTEMP if ( 1 == sscanf( S , "flagTemp : %d" , &flagTemp ) ) { Serial.print( "Detectado :" ) ; Serial.print(S); Serial.print( "\r\n" ) ; } else #endif #ifdef CONPULSO if ( 1 == sscanf( S , "flagPulso : %d" , &flagPulso ) ) { Serial.print( "Detectado :" ) ; Serial.print(S); Serial.print( "\r\n" ) ; } else #endif #ifdef CONECG if ( 1 == sscanf( S , "flagECG : %d" , &flagECG ) ) { Serial.print( "Detectado :" ) ; Serial.print(S); Serial.print( "\r\n" ) ; } else #endif Serial.print( "flag") ; // TODO quitar } else { estado = ESPERAFLAG; break;
99 } } #ifdef CONTEMP //Si encuentra el flag de temperatura activo if (flagTemp == 1) { RedCliente.close( ) ; estado = CAPTURADATOSTEMP; break; } else #endif #ifdef CONPULSO //Si encuentra el flag de pulso activo if (flagPulso == 1) { RedCliente.close( ) ; estado = CAPTURADATOSPULSO; eHealth.initPulsioximeter(); pulso_cuenta = 0 ; PCintPort::attachInterrupt(6, readPulsioximeter, RISING); digitalWrite( ledPulso , HIGH ) ; timeout = 30000+millis() ; break; } else #endif #ifdef CONECG //Si encuentra el flag de ECG activo if (flagECG == 1) { RedCliente.close( ) ; estado = CAPTURADATOSECG; break; } else #endif ; { //Si no se encuentra ninguno activo, volvemos a ESPERAFLAG //para buscar de nuevo estado = ESPERAFLAG; break; } case CONFIGTIMEOUT: case ESPERA: if (RedCliente.available() > 0) { Serial.println( F("Cerrando conexion 1")) ; RedCliente.close( ) ; Serial.println( F("Cerrada")) ; break; } if (RedCliente.isConnected()) { Serial.println( F("Cerrando conexion 2")) ; int t = millis() ; RedCliente.close(); Serial.println( F("Cerrada")) ;
100 Serial.println( (millis() -t) / 1000 ) ; } //Se configura el temporizador timeoutflag timeoutflag = millis() + TIMEOUTFLAG; //millis es una funcion que nos devuelve la hora actual, le sumamos x segundos //Pasaría de nuevo a esperar que se conecte algun cliente estado = CONFIGWEBSERVER ; break; #ifdef CONTEMP case CAPTURADATOSTEMP: //Encender LED que indica que se están capturando datos de temperatura. digitalWrite(ledTemp,HIGH); if (RedCliente.isConnected()) RedCliente.close(); { //Captura float temp = eHealth.getTemperature(); Serial.print(F("Temperatura (ºC): ")); Serial.print(temp, 2); Serial.println(""); //Envío snprintf( s, SLENGTH, "GET /Pagina/medico/temperatura.php?flag=%d&temp=%d&idarduino=%d", (int) flagTemp , (int) temp, (int) idarduino ) ; Serial.print( s ) ; if ( RedCliente.open(XCENTRAL, 80) ) { RedCliente.println(s); RedCliente.println(F("HTTP/1.0\r\n")); RedCliente.println(F("\r\n")); } else { estado = ESPERA ; break ; } } estado = CONFIGTIMEOUT; break; #endif #ifdef CONPULSO case CAPTURADATOSPULSO: //Si no llega la interrupcion de haber pulsado el boton if( millis( ) > timeout ) { Serial.println( "Tiempo excedido, cancelada" ) ; estado = CONFIGTIMEOUT ; } break ; case CAPTURADATOSPULSO2: { //Captura Serial.print("PRbpm : ");
101 int bpm = eHealth.getBPM(); Serial.print(bpm); //Captura Serial.print(" SPo2 : "); int oxigeno = eHealth.getOxygenSaturation(); Serial.println(oxigeno); if( oxigeno < 10 ) { //Control para que no tome muestras con valor menor de 10 estado = CAPTURADATOSPULSO ; break ; } Serial.print("\n"); Serial.println("============================="); //Envío snprintf( s, SLENGTH, "GET /Pagina/medico/pulso.php?flag=%d&bpm=%d&oxigeno=%d&idarduino=%d", (int) flagPulso , (int) bpm, (int) oxigeno, (int) idarduino ) ; Serial.print( s ) ; if( RedServicio.open(XCENTRAL, 80) ) { RedServicio.println(s); RedServicio.println("HTTP/1.0\r\n"); RedServicio.println("\r\n"); } } estado = CONFIGTIMEOUT; break; #endif #ifdef CONECG case CAPTURADATOSECG: if (RedCliente.isConnected()) RedCliente.close(); { // tomamos las muestras for (por_a = 0; por_a < ALENGTH;) { delay(25); } { //Creamos un string con json para guardar los datos String dato = "{\"datos\":["; int cont = 0; //Me indica el paquete que se envía int iteracion = 0; //Los datos capturados los almacenamos en el string for (int j = 0; j <= 119; j++) { dato += a[j]; cont++; //Si llega a 25, se manda un paquete //Si llega a 119, ha terminado el envío if ((cont == 25) || (j == (119))) { if (j == 119) {
108