Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
UNIVERSIDADE FEDERAL DE ITAJUBÁ – UNIFEI
SISTEMA DE MONITORAMENTO CARDÍACO
DE PACIENTES EM DOMICÍLIO
Autor
Pedro Henrique Pinto Lucas
UNIFEI
Itajubá
2018
SISTEMA DE MONITORAMENTO CARDÍACO
DE PACIENTES EM DOMICÍLIO
Autor
Pedro Henrique Pinto Lucas
Monografia apresentada como trabalho final de
graduação, requisito parcial para obtenção do título
de Bacharel em Sistemas de Informação, sob
orientação do Prof. Dr. Roberto Affonso da Costa
Junior.
UNIFEI
Itajubá
2018
RESUMO
Os últimos avanços tecnológicos computacionais e de comunicação wireless, juntamente com
a popularidade dos dispositivos móveis com possibilidade de conexão direta à internet e o uso
cada vez mais crescente de dispositivos médicos para aquisição de sinais vitais têm alavancado
o surgimento de aplicações e modalidades de telemonitoramento de pacientes, permitindo, desta
forma, o acompanhamento e o diagnóstico em tempo real de doenças crônicas (BASHSHUR,
R. L. et al, 2002). Tendo consciência da importância da informação na área da saúde, foi
proposto o desenvolvimento de um sistema capaz de monitorar a frequência cardíaca de
pacientes em seu próprio domicílio, cujos dados serão disponibilizados via web para o médico
responsável, possibilitando que o mesmo tenha um acompanhamento mais estreito sobre a
saúde cardíaca de seus pacientes.
Palavras chave: Arduino, Android, Sistema de Monitoramento Cardíaco, Monitoramento
Cardíaco, Sistema Cardíaco, e-Health.
ABSTRACT
The latest advances in computer technology and wireless communication along with the
recent popularity of mobile devices with direct connection to the internet that have been
increasingly used in medical devices to assess vital signs has leveraged the emergence of
ways of mobile monitoring of patients and real time diagnosis of chronic diseases
(BASHSHUR, R.L. et al, 2002). Being aware of the importance of precise and timely
informations in the health sector, it was proposed to develop a system capable of monitoring
the heart rate of patients through own mobile gadget, which will keep the data available via
web to the doctor in charge, enabling him to have a constant and close assessing on heart
health of their patients.
LISTA DE FIGURAS
2.1 – Placa Arduino Uno...........................................................................................................16
2.2 – Seleção do Kit Arduino....................................................................................................17
2.3 – Seleção da Porta Serial.....................................................................................................17
2.4 – Interface da Plataforma Arduino......................................................................................18 2.5 – Sensor de Batimento Cardíaco - Pulse Sensor.................................................................19
2.6 – Sístole e Diástole Cardíaca...............................................................................................20
2.7 – Sistema de Condução Cardíaca........................................................................................21
2.8 – Representação Gráfica de um Eletrocardiograma............................................................22
2.9 – Sensor na Ponta do Dedo..................................................................................................23
2.10 – Sensor no Lóbulo da Orelha...........................................................................................23
2.11 – Fatores que Interferem na Absorção de Luz...................................................................23
2.12 – Onda de Pulso Captada pelo Pulse Sensor.....................................................................24
2.13 – Amplitude Utilizada na Detecção da Frequência Cardíaca............................................24
2.14 – Arquitetura do Android..................................................................................................26
2.15 – Componentes de uma Aplicação Android......................................................................28
2.16 – Ciclo de Vida de uma Aplicação Android......................................................................30
2.17 – Arquitetura do Padrão Bluetooth....................................................................................32
2.18 – Topologia de uma Rede Bluetooth..................................................................................33
2.19 – Estabelecimento de Conexão do Bluetooth....................................................................34
2.20 – Arquitetura de três Camadas...........................................................................................38
3.1 – Desenho Esquemático da Configuração do Módulo HC-05............................................40
3.2 – Desenho Esquemático do Protótipo.................................................................................41
3.3 – Tela de Autenticação........................................................................................................42
3.4 – Tela de Cadastro...............................................................................................................42
3.5 – Dispositivos Encontrados.................................................................................................43
3.6 – Pareamento Bluetooth......................................................................................................43
3.7 – Tela Principal...................................................................................................................44
3.8 – Menu da Tela Principal....................................................................................................44
3.9 – Estrutura dos Dados no Realtime Database.....................................................................45
3.10 – Código da Inicialização do SDK do Javascript..............................................................46
3.11 – Visão da Aplicação Web................................................................................................47
3.12 – Visão da Aplicação Web quando Pressionado o Botão.................................................47
LISTA DE TABELAS
1 – Especificações do Arduino Uno.....................................................................................15
LISTA DE ABREVIATURAS E SIGLAS
TI Tecnologia da Informação
WIFI Wireless Fidelity
ANS Agência Nacional de Saúde
TISS Troca de Informação em Saúde Suplementar
ADS Assistência Domiciliar à Saúde
IDE Integrated Development Environment
USB Universal Serial Bus
PWM Pulse Width Modulation
ICSP In Circuit Serial Program
LED Light Emitting Diode
IBI Inter Beat Interval
OHA Open Handset Alliance
BPM Batimento Por Minuto
SDK Software Development Kit
API Application Programming Interfaces
GSM System for Mobile Communications
SSL Secure Socket Layer
DVM Dalvik Virtual Machine
SIG Bluetooth Special Interest
ISM Industrial, Scientific and Medical
FHSS Frequency Hopping Spread Spectrum
W3C World Wide Web Consortium
HTTP Hypertext Transfer Protocol
UDDI Universal Description, Discovery and Integration
FTP File Transfert Protocol
SMTP Simple Mail Transfer Protocol
SDK Software Development Kit
JSON Javascript Object Notation
CN Computação em Nuvem
URL Uniform Resource Locator
SUMÁRIO
1. INTRODUÇÃO .................................................................................................................. 11
1.1. Objetivo ......................................................................................................................... 12
1.1. Metodologia .................................................................................................................. 12
1.2. Organização .................................................................................................................. 13
2. FUNDAMENTAÇÃO TEÓRICA ..................................................................................... 15
2.1. Arduino ......................................................................................................................... 15
2.1.1. Hardware Arduino ................................................................................................ 15
2.1.2. Ambiente de Desenvolvimento Arduino .............................................................. 16
2.2. Pulse Sensor .................................................................................................................. 19
2.2.1. Princípio da Fotopletismografia .......................................................................... 19
2.2.2. Ciclo Cardíaco ....................................................................................................... 20
2.2.3. Sistema de Condução Cardíaca ........................................................................... 20
2.2.4. Funcionamento do Sensor .................................................................................... 22
2.3. Android ......................................................................................................................... 25
2.3.1. Plataforma.............................................................................................................. 25
2.3.2. Arquitetura ............................................................................................................ 26
2.3.3. Estrutura das Aplicações ...................................................................................... 27
2.3.4. Ciclo de Vida de uma Aplicação .......................................................................... 29
2.4. Bluetooth ....................................................................................................................... 31
2.4.1. Arquitetura ............................................................................................................ 32
2.4.2. Topologia ................................................................................................................ 33
2.4.3. Estabelecimento de Conexão ................................................................................ 34
2.5. Computação em Nuvem .............................................................................................. 35
2.5.1. Modelos de Serviço ................................................................................................ 35
2.5.2. Backend as a Service ............................................................................................. 36
2.5.3. Firebase .................................................................................................................. 37
2.6. Aplicação Web .............................................................................................................. 38
3. DESENVOLVIMENTO ..................................................................................................... 39
3.1. Hardware ...................................................................................................................... 39
3.1.1. Configuração do módulo HC-05 .......................................................................... 40
3.1.2. Funcionamento do hardware ............................................................................... 40
3.2. Aplicativo Android ...................................................................................................... 41
3.2.1. Autenticação .......................................................................................................... 42
3.2.2. Comunicação Bluetooth ........................................................................................ 43
3.2.3. Persistência em Banco de Dados .......................................................................... 44
3.3. Aplicação Web .............................................................................................................. 45
3.3.1. Banco de Dados ..................................................................................................... 46
4. CONCLUSÃO ..................................................................................................................... 48
4.1. Trabalhos Futuros ....................................................................................................... 49
5. REFERÊNCIAS ................................................................................................................. 50
APÊNDICE A - Código de Configuração do Módulo Bluetooth HC-05 ........................... 53
APÊNDICE B - Código do Arduino ..................................................................................... 54
APÊNDICE C – Código de Login e Signup do Aplicativo Android .................................. 56
APÊNDICE D – Código das Classes Bluetooth e Main do Aplicativo Android ............... 71
APÊNDICE E – Código da Classe Patient e Persistência do Aplicativo Android ............ 84
APÊNDICE F – Código da Aplicação Web ......................................................................... 87
11
1. INTRODUÇÃO
As Tecnologias da Informação (TIs) têm se tornado parte integrante na vida das pessoas. Os
avanços notórios nas redes de informações, telecomunicações e tecnologias computacionais
estão favorecendo a migração de um novo e revolucionário paradigma no que diz respeito ao
cuidado em saúde, fazendo com que a aplicação e o uso de produtos tecnológicos baseados em
computador, tal como os sistemas de informação, sofram um processo de permanente evolução
na área médica (BAGGIO, 2009).
Os últimos avanços tecnológicos computacionais e de comunicação wireless, como por
exemplo o Bluetooth, Wireless Fidelity (WIFI), juntamente com a popularidade dos
dispositivos móveis e o uso cada vez mais crescente de dispositivos médicos para aquisição de
sinais vitais têm alavancado o surgimento de aplicações e modalidades de telemonitoramento
de pacientes, permitindo, desta forma, o acompanhamento e o diagnóstico em tempo real de
doenças crônicas (BASHSHUR, R. L. et al, 2002).
Tendo consciência da importância da informação na área da saúde, governos e empresas
buscam desenvolver projetos de TI que atendam às necessidades médicas. Há uma proposta do
governo americano que através de um smartphone, os pacientes possam acessar suas próprias
informações relacionadas à saúde, como históricos médicos, resultados laboratoriais e
prescrição de medicamentos, tornando mais rápido e prático o acesso à informação (LANDRO,
2011).
De acordo com a Agência Nacional de Saúde (ANS), o governo brasileiro busca estabelecer
através do padrão Troca de Informação em Saúde Suplementar (TISS) a interoperabilidade
entre os sistemas de informação em saúde a fim de instaurar a padronização obrigatória de troca
eletrônica de dados de atenção à saúde dos beneficiários dos planos.
Os fornecedores de serviços de saúde oferecem recursos tecnológicos como equipamentos
médicos, aparelhos e todo suporte para a chamada Assistência Domiciliar à Saúde (ADS)
promovendo o conforto e bem-estar do paciente que não necessita mais de cuidados
hospitalares, mas sim de atenção especializada domiciliar. Deste modo, o custo de manutenção
de pacientes com doenças crônicas ou de longa duração se tornam mais baixos, a qualidade de
sua recuperação melhor, além de reduzir a taxa de ocupação de leitos hospitalares (AMARAL,
2001).
12
Segundo Baggio (2004), as evoluções em tecnologia computacional e telecomunicação,
permitiram o surgimento de ferramentas e componentes cada vez menores para auxiliar os
prestadores de serviços em saúde no cuidado baseado na evidência e no monitoramento de
saúde remota dos pacientes.
1.1. Objetivo
Nesse contexto, este trabalho tem como objetivo a implementação de um sistema capaz de
monitorar a frequência cardíaca de pacientes em seu próprio domicílio, cujos dados serão
disponibilizados via web para o médico, possibilitando que o mesmo tenha um
acompanhamento sobre a saúde cardíaca de seus pacientes.
No que diz respeito ao hardware para aquisição dos batimentos cardíacos será utilizado a
plataforma de prototipagem eletrônica Arduino, o sensor chamado Pulse Sensor desenvolvido
pela World Famous Eletronics e o módulo para conexão bluetooth HC-05. O Arduino e o sensor
de batimentos poderão ser acoplados, respectivamente, ao braço e ao lóbulo da orelha do
paciente, de forma a causar o menor incômodo possível ao decorrer do dia.
Com o uso do smartphone cada vez mais comum e presente na vida das pessoas, aliado a
possibilidade de conexão direta à internet, tornou-se viável o desenvolvimento de um aplicativo
em Android para receber os dados proveniente do Arduino via Bluetooth e servir de interface
na disponibilização dos dados coletados através de uma aplicação web.
1.1. Metodologia
A metodologia utilizada para a realização do projeto foi dividida em etapas para melhor
compreensão, que estão abaixo listadas:
• Fundamentação Teórica: Constitui em pesquisar e estudar os conceitos e ferramentas
que serão utilizadas no projeto, sendo tais:
o Fornecer uma visão do Arduino, uma placa de prototipagem rápida voltada para
projetos de eletrônica.
o Fornecer uma visão do Pulse Sensor, um sensor utilizado junto ao Arduino para
aquisição da frequência cardíaca.
13
o Fornecer uma introdução à tecnologia Android, mostrando a plataforma, sua
arquitetura, bem como o ciclo de vida das aplicações Android.
o Fornecer uma introdução à tecnologia Bluetooth, mostrando a tecnologia, a
plataforma, a topologia da rede formada, assim como o estabelecimento de
conexão.
o Fornecer uma introdução a Computação em Nuvem, mostrando os modelos de
serviço e a plataforma Backend as a a Service chamada Firebase.
o Fornecer uma introdução ao conceito de aplicação web e o modelo de três
camadas.
• Desenvolvimento: Esta etapa é marcada, de fato, pela implementação do sistema
proposto. Para facilitar a documentação do mesmo, adotou-se o desenvolvimento em
três partes, conforme segue:
1. Hardware: Nesta etapa será desenvolvida toda a montagem de hardware
envolvendo o Arduino, o sensor de batimentos, o módulo Bluetooth, bem como
a implementação do código no Arduino para comunicação com a aplicação
Android para envio de dados.
2. Aplicação Android: Nesta segunda etapa será desenvolvida a aplicação Android
para envio de dados a um banco de dados.
3. Aplicação Web: Esta última etapa será desenvolvida a aplicação web
responsável em possibilitar o acompanhamento do médico aos dados cardíacos
do paciente.
• Conclusão: Nesta última fase do projeto, será feita as devidas conclusões sobre o
projeto, assim como possíveis melhorias.
1.2. Organização
A organização do trabalho está descrita a seguir.
O capítulo 2 apresenta a fundamentação teórica, abordando os conceitos e funcionamento das
tecnologias utilizadas.
O capítulo 3 apresenta o desenvolvimento do projeto, descrevendo os componentes utilizados,
bem como a montagem e o funcionamento do sistema criado.
14
E por fim, o capítulo 4 apresenta as conclusões e possíveis aperfeiçoamentos futuros para o
projeto.
15
2. FUNDAMENTAÇÃO TEÓRICA
2.1. Arduino
O Arduino surgiu em um projeto na cidade italiana chamada Ivrea em 2005, com o professor
Massimo Banzi e outros colaboradores para auxiliar estudantes de design e artes no ensino de
eletrônica. O principal objetivo foi desenvolver uma plataforma de baixo custo para que os
estudantes pudessem ter um controle integrado sobre seus projetos de design e interação,
envolvendo sensores elétricos, atuadores eletromecânicos e processamento digital com o menor
custo possível.
A plataforma do Arduino é open-source de prototipagem eletrônica rápida e flexível, fácil de
usar, baseada em software e hardware. O ambiente de desenvolvimento é baseado no ambiente
Processing, e a programação é baseada na linguagem de programação Wiring. É destinado a
artistas, designers e qualquer pessoa que esteja interessada em criar objetos ou ambientes
interativos, podendo ser usado para o desenvolvimento de objetos interativos autônomos ou
comunicar-se com um computador por meio de software. O seu ambiente de desenvolvimento
integrado (IDE) é de código aberto e pode ser baixado gratuitamente no site oficial do Arduino
(ARDUINO, 2015).
A composição do Arduino é dividida em duas partes fundamentais: a própria placa, que é a peça
de hardware onde é feito todo o trabalho do circuito e a montagem dos objetos; e a Integrated
Development Environment (IDE), ou seja, o ambiente de desenvolvimento onde é criado o
código para ser executado na placa Arduino (BANZI, 2008).
2.1.1. Hardware Arduino
O Arduino Uno, que será utilizado no projeto, é uma placa com microcontrolador baseado no
ATmega 328. Contém 14 pinos digitais de entrada/saída (sendo que 6 deles podem ser usados
como saída PWM – Pulse Width Modulation), 6 entradas analógicas, um cristal oscilador de 16
MHz, uma conexão Universal Serial Bus (USB), um cabeçalho In Circuit Serial Program
(ICSP), e um botão de reset (ARDUINO, 2015). Na figura 2.1 tem-se a imagem da placa do
Arduino UNO.
16
Figura 2.1 – Placa Arduino Uno
Fonte: http://www.embarcados.com.br/arduino-primeiros-passos
A tabela 2.1 descreve algumas das suas características técnicas relevantes.
TABELA 2.1 – Especificações do Arduino Uno
Microcontrolador ATmega328P
Tensão de funcionamento 5V
Tensão de entrada (recomendado) 7-12V
Tensão de entrada (limite) 6-20V
Pinos digitais E/S 14 (dos quais 6 são PWM)
Pinos de entrada analógicos 6
Corrente DC por pino E/S 20 mA
Corrente DC por pino 3.3V 50 mA
Memória Flash 32 KB, sendo 2 KB usados pelo bootloader
SRAM 2 KB
EEPROM 1 KB
Velocidade de clock 16 MHz
Fonte: https://www.arduino.cc/en/Main/ArduinoBoardUno
2.1.2. Ambiente de Desenvolvimento Arduino
Com relação ao ambiente de desenvolvimento dos códigos na plataforma Arduino, é importante
destacar que se faz necessário definir o modelo do kit usado e a porta serial onde está ligado ao
computador. Para isso, deve-se ir em Ferramentas >> Placa e escolher o kit Arduino adequado,
neste caso, a opção selecionada é Arduino Uno. A figura 2.2 mostra os passos sequenciais
classificados em ordem numérica.
17
Figura 2.2 – Seleção do Kit Arduino
Fonte: Autor
Depois que o modelo do Arduino foi selecionado, deve-se selecionar a porta serial na qual o kit
está e, desta forma, ir em Ferramentas >> Porta Serial e escolher uma das portas disponíveis.
A figura 2.3 mostra os passos para serem seguidos numericamente.
Figura 2.3 – Seleção da Porta Serial
Fonte: Autor
18
Abaixo tem-se um breve resumo das funções e ferramentas da IDE do Arduino, seguindo a
orientação numérica de acordo com a figura 2.4.
Figura 2.4 – Interface da Plataforma Arduino
Fonte: Autor
1. Barra de menus (Composta por 5 opções e dentre elas é possível abrir e salvar projetos,
carregar exemplos, localizar partes de código-fonte, verificar e compilar códigos,
escolher kit Arduino, configurar porta USB em que a placa está conectada e obter ajuda).
2. Botão verificar (Realiza a verificação de erros no código-fonte preenchendo com
exceções no caso de algum erro o espaço do item 10).
3. Botão carregar (Inicia o verificador, e logo após o compilador, que por sua vez
transforma o código-fonte em linguagem de máquina. Após concluir este processo de
compilação o programa será carregado na memória flash do Arduino que iniciará sua
execução).
4. Botão novo (Cria um novo projeto (sketch)).
5. Botão abrir (Abre um sketch existente).
6. Botão salvar (Salva as alterações realizadas em um sketch existente).
7. Botão abas (Controla a organização de abas para vários sketch’s abertos na mesma
tela).
8. Botão monitor serial (Monitora informações do programa, a placa Arduino pode
escrever diretamente na porta serial, possibilitando a recuperação da informação em
outras interfaces, além de auxiliar na depuração do código para correção de erros).
19
9. Editor de código-fonte (Espaço disponível para o desenvolvimento do programa).
10. Informações e status (Espaço disponível para exibição de erros de digitação,
compilação e conclusões de tarefas bem sucedidas).
2.2. Pulse Sensor
Pulse Sensor é um projeto de hardware Open Source desenvolvido por Joel Murphy e Yury
Gitman com o intuito de possibilitar a utilização da frequência cardíaca em projetos com o
Arduino de forma simples e prática (PULSE SENSOR, 2015). Para realizar a captação dos
batimentos cardíacos utiliza-se o princípio de fotopletismografia (ver sessão 2.2.1). O sensor é
mostrado na figura 2.5.
Figura 2.5 – Sensor de Batimento Cardíaco - Pulse Sensor
Fonte: http://pulsesensor.com/
2.2.1. Princípio da Fotopletismografia
A frequência cardíaca pode ser obtida através do princípio de fotopletismografia, um método
não-invasivo capaz de mensurar a quantidade de luz infravermelha absorvida ou refletida pelo
sangue, através de alterações do volume do fluxo sanguíneo provocadas por variações de
pressão nos vasos, que ocorrem ao longo do ciclo cardíaco. Com isso, é possível observar a
variação do volume de sangue com base na luz captada pelo sensor (AKAY, 2006). Para que o
sensor obtenha maior êxito na detecção da variação do volume sanguíneo, deve-se aplicar em
locais onde tenham maior perfusão periférica e poucas camadas de tecido (GOLDBERG, 2008),
por isso locais como o lóbulo da orelha e ponta dos dedos são boas opções.
20
2.2.2. Ciclo Cardíaco
O ciclo cardíaco, responsável pelo fluxo sanguíneo ao longo de todo o corpo, é constituído por
duas fases principais: a diástole e a sístole. Na figura 2.6 pode ser visto o processo de diástole
e sístole cardíaca.
Na fase de diástole, conhecida também por fase de relaxamento, o sangue entra nos átrios direito
(vindo das veias cava inferior e superior) e esquerdo (vindo das veias pulmonares). Nesta etapa,
as válvulas atrioventriculares estão abertas, permitindo, desse modo, a passagem de sangue dos
átrios para os ventrículos. A fase de relaxamento provoca uma diminuição de pressão nos vasos
sanguíneos.
Na fase de sístole, ou também conhecida como fase de contração, as válvulas pulmonar e aórtica
são abertas e o sangue é rapidamente ejetado do ventrículo direito para a artéria pulmonar e, do
ventrículo esquerdo para a aorta, provocando um aumento de pressão nos vasos sanguíneos.
A medição da variação da pressão, com base na fase do ciclo cardíaco permite estimar a
frequência cardíaca (PLUX, 2015).
Figura 2.6 – Sístole e Diástole Cardíaca
Fonte: http://pt.slideshare.net/LaraTavares/sist-circulatrio-23848942
2.2.3. Sistema de Condução Cardíaca
O estímulo elétrico nasce no próprio coração, em uma região localizada no átrio direito
denominada nodo sinusal ou sinoatrial, que por sua vez, tem a função de marca-passo
fisiológico, coordenando o ritmo cardíaco. O estímulo então alcança, em sequência, o átrio
21
esquerdo, o nodo atrioventricular, o feiche de His e seus ramos (esquerdo e direito), as fibras
de Purkinje e os ventrículos (FELDIMAN & GOLWASSER, 2004). A figura 2.7 ilustra os
elementos envolvidos no processo de atividade elétrica cardíaca.
Ao se distribuírem por todo o músculo do coração, os impulsos elétricos induzem íons de cálcio
a entrarem nas células cardíacas, promovendo o processo de despolarização elétrica, que
estimula a contração muscular. Logo após o processo de contração, íons de potássio saem das
células, em um processo de repolarização, preparando as células para nova despolarização
(PINHEIRO, 2012);
Figura 2.7 – Sistema de Condução Cardíaca
Fonte: http://www.medicinaintensiva.com.br/ecg.htm
Traçado básico de um eletrocardiograma
O eletrocardiograma é um exame que registra a atividade elétrica do coração, possibilitando
mensurar o número de batimentos por minuto, o ritmo cardíaco e, dessa forma, identificar
problemas como arritmias (ritmo cardíaco alterado), problemas relacionados à condução
elétrica, dentre outros (CORAÇÃO ALERTA, 2013). A seguir é mostrado a representação
gráfica da atividade cardíaca no eletrocardiograma (figura 2.8) e o significado das ondas
características.
22
Figura 2.8 – Representação Gráfica de um Eletrocardiograma
Fonte: http://www.medicinaintensiva.com.br/ecg.htm
• Onda P – Responsável pela despolarização atrial, é nesse momento que ocorre a sístole
(contração) atrial.
• Intervalo P-R – É o intervalo de tempo do começo da despolarização atrial até o
começo da despolarização ventricular.
• Complexo QRS – Responsável pela despolarização dos ventrículos, ou seja, momento
da sístole (contração) ventricular.
• Onda T – Nesse momento ocorre a repolarização ventricular, toda atividade elétrica é
cessada até os ventrículos sofrerem o processo de diástole (ou relaxamento).
• Segmento S-T – Período de inatividade elétrica, depois do miocárdio estar
despolarizado.
• Onda U – Segue a onda T, originada no início da diástole.
• Intervalo Q-T – Intervalo de tempo necessário para que a despolarização e
repolarização ventricular ocorram.
2.2.4. Funcionamento do Sensor
O funcionamento do sensor ocorre através do princípio de fotopletismografia (mais detalhes
ver sessão 2.2.1), usado de forma totalmente não-invasiva. Para medir a variação do fluxo
sanguíneo, o fotodetector (responsável pela detecção da quantidade de luz ambiente) e o Light
Emitting Diode (LED) verde ficam no mesmo plano. O usuário, por sua vez, se utilizar o dedo
indicador deverá posioná-lo em cima do sensor e do LED (conforme imagem 2.9), ou caso
prefira o lóbulo da orelha deverá prender o sensor com a ajuda de um grampo (conforme
imagem 2.10). Os ossos, tecidos, pele, sangue venoso e arterial absorvem a luz emitida pelo
23
LED e a variação da quantidade de luz recebida pelo fotodetector é, essencialmente,
consequência da variação do fluxo sanguíneo durante o ciclo cardíaco.
Figura 2.9 – Sensor na Ponta do Dedo Figura 2.10 – Sensor no Lóbulo da Orelha
Fonte: http://pulsesensor.com Fonte: http://pulsesensor.com
Com relação aos fatores que promovem a absorção de luz citados acima, estes são divididos em
dois componentes: o componente basal, com transmitância constante ao longo do tempo,
constituído de elementos não pulsáteis como os tecidos, capilares, sangue venoso e pele e o
componente pulsátil, proveniente do fluxo de sangue arterial no tecido, que em sincronia com
o ciclo cardíaco, muda de intensidade ao longo do tempo. No momento de sístole, o aumento
do volume sanguíneo promoverá maior absorção de luz e, consequentemente, menor
transmitância, enquanto para o momento de diástole, a diminuição do volume sanguíneo
acarretará menor luz absorvida e maior quantidade de luz transmitida (TREMPER & BARKER,
1987). É possível observar esses componentes na figura 2.11.
Figura 2.11 – Fatores que Interferem na Absorção de Luz
Fonte: http://www.scielo.br/scielo.php?script=sci_arttext&pid=S0104-11691999000200011
24
A representação da onda do pulso elétrico captado pelo Pulse Sensor pode ser vista na figura
2.12. Segundo os desenvolvedores do sensor, Joel Murphy e Yury Gitman, o objetivo é
encontrar o momento exato do batimento e medir o tempo entre eles chamado Inter Beat
Interval (IBI). Ao seguir a forma e o padrão da onda obtida, pode-se encontrar esse momento
facilmente.
Figura 2.12 – Onda de Pulso Captada pelo Pulse Sensor
Fonte: http://pulsesensor.com/pages/pulse-sensor-amped-arduino-v1dot1
Com a onda repetindo-se de forma previsível, poderia ser escolhido qualquer ponto com
característica reconhecível como um ponto de referência e mensurar a frequência entre seus
intervalos, porém a leitura torna-se imprecisa com susceptíveis ruídos. Adotou-se, após testes,
que o ponto de referência seria na metade do pico de onda máximo, ou seja, quando o sinal
atravessar os 50% da amplitude da onda será obtido o IBI. Para maior precisão, os batimentos
por minuto (BPM) serão derivados da média de 10 IBI’s anteriores (PULSE SENSOR, 2015).
A figura 2.13 ilustra o momento em que a amplitude da onda máxima chega a 50%.
Figura 2.13 – Amplitude Utilizada na Detecção da Frequência Cardíaca
Fonte: http://pulsesensor.com/pages/pulse-sensor-amped-arduino-v1dot1
25
2.3. Android
O Android é uma plataforma aberta (Open Source) desenvolvida pela Google voltada para
dispositivos móveis, que foi divulgada em 5 de novembro de 2007. Atualmente é mantida pela
Open Handset Alliance (OHA), um grupo constituído por várias empresas das quais figuram o
próprio Google e outras de importância nos ramos de fabricação de celulares (Motorola),
fabricação de semicondutores (Intel), telefonia (Telefonica), dentre várias outras que se uniram
com o intuito de aprimorar e acelerar o desenvolvimento de serviços e aplicações (ALVES,
2008).
Segundo Lecheta (2010), o Android é uma plataforma de desenvolvimento para dispositivos
móveis, com sistema operacional baseado em Linux, interface visual rica, com diversas
aplicações já instaladas e ainda um ambiente de desenvolvimento poderoso, inovador e flexível.
O sistema Android está presente em muitos smartphones e tablets de variados modelos, alguns
de seus atributos são: browser rápido, sincronização em nuvem, sistema multitarefa, facilidades
para se conectar e compartilhar, milhares de aplicativos disponíveis para download, entre outros
(LECHETA, 2010).
2.3.1. Plataforma
A plataforma Android utilizada na construção de aplicativos para dispositivos móveis é baseada
em Linux 2.6 e emprega a linguagem Java para criação destas aplicações. No processo de
desenvolvimento, o compilador nativo do Java transforma todo o código em Bytecodes (.class),
na sequência, todos estes Bytescodes são agrupados e convertidos em um formato .dex (Dalvik
Executable), que representa a aplicação Android compilada. Informações que possam conter
dados redundantes no código-fonte são agrupados na compilação do arquivo .dex, resultando
em um arquivo menor e otimização do desempenho.
Logo após, os arquivos .dex e outros recursos como vídeos e imagens, sofrem o processo de
compactação, sendo transformados em um único arquivo com a extensão .apk (Android
Package File), pronta para ser instalada.
A plataforma disponibiliza uma ferramenta de desenvolvimento chamada Software
Development Kit (SDK) que proporciona um conjunto de Application Programming Interfaces
(API) necessárias para o desenvolvimento das aplicações, tendo como recursos principais:
26
• SQLite: Sistema Gerenciador de Banco de Dados embutido;
• Suporte Multimídia: Suporte multimídia para formatos de áudio, vídeo e imagem;
• Telefonia Global System for Mobile Communications (GSM);
• Bluetooth, 3G e Wireless Fidelity (WIFI);
• Dalvik Virtual Machine: Máquina Virtual JAVA voltada para dispositivos móveis;
• Ambiente de desenvolvimento oferecendo um plugin para Eclipse;
• Navegador Web integrado;
• Câmera, GPS, bússola e acelerômetro;
• Poderoso ambiente de desenvolvimento;
• Framework de aplicação;
• Gráficos otimizados;
2.3.2. Arquitetura
O Android é uma plataforma que apresenta Sistema Operacional, middleware e aplicativos. A
arquitetura é segmentada em camadas, das quais são: kernel Linux, runtime, bibliotecas,
framework e aplicativos, como pode ser visto na figura 2.14.
Figura 2.14 – Arquitetura do Android
Fonte: http://www.dicas-l.com.br/arquivo/conhecendo_o_android.php
27
Na camada Kernel Linux (Linux Kernel), localiza-se o sistema operacional da plataforma,
baseado no kernel do GNU/Linux versão 2.6. O kernel funciona como uma camada de abstração
entre o hardware e softwares da plataforma, sendo responsável por vários serviços de baixo
nível, como gerenciamento de memória, processos e segurança, tornando transparente para o
usuário.
Na camada Bibliotecas (Libraries), encontram-se as bibliotecas nativas escritas em C/C++,
usados pelos componentes do sistema, como renderização 3D (OpenGL ES), gerenciamento de
base de dados (SQLite), suporte à vários formatos de áudio e vídeo, encriptação de dados
enviados pela internet (SSL), dentre outros.
A camada runtime (Android Runtime) permite que as aplicações sejam executadas. Um dos
componentes dessa camada são as core libraries, sendo responsável por disponibilizar uma API
Java para programação. Outro componente da camada é a Dalvik Virtual Machine (DVM), que
de fato será a responsável pela execução da aplicação.
Na camada framework (Application Framework), localizam-se as APIs do Android usadas
pelas aplicações, como gerenciadores de serviços de telefonia, gerenciamento de pacotes,
gerenciamento de atividades, gerenciamento de localização, dentre outros.
Por fim, na camada de aplicação (Applications) encontram-se os aplicativos que são executados
sobre a plataforma do Android. As aplicações podem ser nativas como por exemplo calendário
e contatos, ou aplicações desenvolvidas por terceiros.
2.3.3. Estrutura das Aplicações
O desenvolvimento de aplicações Android é baseado em uma arquitetura de componentes, a
fim de se atingir o objetivo final da aplicação. Entretanto, a aplicação não precisa
necessariamente utilizar todos eles. A figura 2.15 ilustra os componentes de uma aplicação.
Atrelado a estes componentes, existe um arquivo chamado AndroidManifest.xml cuja presença
é obrigatória, sendo responsável pelas configurações gerais da aplicação e dos componentes
usados por ela. Somando a esta estrutura, tem-se dois importantes itens para que os
componentes funcionem: as Intents e as Views.
28
Figura 2.15 – Componentes de uma Aplicação Android
Fonte: http://www.softblue.com.br/blog/home/postid/11/CONHECENDO_O_ANDROID
No desenvolvimento de aplicações Android, as Activities são um dos componentes mais
comuns, sendo responsável por gerenciar os eventos de tela e definir qual view será mostrada,
portanto, toda exibição visual é por conta da activity.
Os Services são códigos executados em segundo plano e não apresentam interface gráfica.
Normalmente são utilizados para tarefas que precisam de um tempo grande de execução, sendo
executados na thread principal do processo que o criou, eliminando a chance de bloqueio ou
interferência em outros componentes.
Os Broadcast Receivers são componentes que ficam aguardando a ocorrência de determinados
eventos do sistema, reagindo de alguma forma sobre esses eventos. Uma aplicação pode utilizar
um broadcast receiver para ser notificada quando o dispositivo encontrar uma rede sem fio, e
com base nessa informação, efetuar alguma ação.
Os Content Providers permitem que as aplicações possam compartilhar dados entre si,
tornando um conjunto específico de informações disponíveis para uso. Uma aplicação pode
utilizar, por exemplo, um content provider para ler os contatos armazenados no dispositivo de
forma bastante simples.
As Intents são mensagens enviadas por um componente da aplicação para o sistema do
Android, a fim de informar uma intenção de inicializar outro componente da mesma ou de outra
aplicação.
29
As Views são utilizadas para criação de qualquer componente gráfico, sendo a base para os
componentes visuais exibidos na tela, com o objetivo de prover interação com o usuário, como
por exemplo, botões, caixas de texto, spinners, mapas, entre outros.
O AndroidManifest.xml é o arquivo principal e único do projeto localizado no diretório raiz,
sendo responsável por todas as configurações da aplicação. O propósito deste arquivo é conter
e fornecer informações relevantes sobre a aplicação para o sistema Android, como os
componentes utilizados, nomes para as activities, modo de orientação da tela, permissões de
acesso a recursos como Bluetooth ou Internet, entre outros.
2.3.4. Ciclo de Vida de uma Aplicação
O ciclo de vida de uma aplicação Android pode ser definida pelos possíveis estados:
executando, temporariamente interrompida em segundo plano ou completamente destruída
(LECHETA, 2010).
Segundo Lecheta (2010), faz-se necessário compreender o termo ciclo de vida como algo que
tem um início, meio e fim, sendo que a documentação do Android há três subníveis do ciclo de
vida, que por sua vez ficam se repetindo durante a execução da sua aplicação, sendo eles:
• Entire lifetime, representando o ciclo de vida completo entre o início e destruição da
activity da aplicação. Esse ciclo ocorre entre os métodos onCreate() e onDestroy().
• Visible lifetime, no qual a activity está iniciada, porém pode estar no topo da pilha
interagindo com o usuário ou temporariamente em segundo plano. Esse ciclo ocorre
entre os métodos onStart() e o onStop().
• Foreground lifetime, no qual a activity está no topo da pilha interagindo com o usuário.
Esse ciclo ocorre entre os métodos onResume() e onPause().
A figura 2.16 mostra o ciclo de vida completo da activity de uma aplicação, apresentando os
estados e a chamada de cada método.
30
Figura 16 – Ciclo de Vida de uma Aplicação Android
Fonte: http://www.felipesilveira.com.br/tag/ciclo-de-vida/
O método onCreate() é a primeira função a ser executada em uma activity e é apenas executada
uma única vez, neste momento cria-se a view e invoca-se o método setContentView(view) para
que seja exibida a tela representada pela view.
O método onStart() é chamado imediatamente após o método onCreate() e também quando
uma activity que estava em background volta a ter foco.
O método onRestart() é chamado quando uma activity está parada temporariamente e em
processo de reinicio, chamando de forma automática o método onStart().
O método onResume() é chamado quando a activity começa a interagir com o usuário,
representando o estado de execução da aplicação. É iniciada sempre após o método onStart().
O método onPause() é chamado quando a activity encontrada no topo da pilha deve ser
temporariamente interrompida por algum evento do sistema. Geralmente neste método utiliza-
31
se a gravação de dados não salvos até aquele momento, possibilitando a recuperação no método
onResume().
O método onStop() é chamado quando a activity está sendo encerrada e não está mais visível
ao usuário. Caso a activity for reiniciada, o método onRestart() é chamado ou no caso de ficar
por um tempo considerado alto, o Android pode chamar o método onDestroy()
automaticamente, encerrando a aplicação.
O método onDestroy() é a última função a ser executada, depois dela a activity é morta,
encerrando completamente o processo da aplicação.
2.4. Bluetooth
O Bluetooth é uma tecnologia desenvolvida com o intuito de conectar, a uma pequena distância,
dispositivos como smartphones, mouses, teclados, televisões, computadores pessoais,
notebooks, tablets, câmeras, impressoras, entre outros, formando uma rede ad hoc entre os
equipamentos (FOROUZAN, 2008).
A tecnologia inicialmente foi desenvolvida pela Ericsson em 1994 com o intuito de substituir
os cabos que conectavam todos estes dispositivos, substituindo todas as soluções proprietárias
existentes para conectá-los, prezando o baixo consumo de potência, baixo custo, cobertura
pequena (geralmente até 10 metros) e transmissão de voz, dados e sinalização (TELECO, 2015).
Todas as especificações referentes ao Bluetooth são definidas pelo Bluetooth Special Interest
(SIG), sendo responsável direto pela padronização da tecnologia, possibilitando a utilização em
todo o mundo (HARTE, 2004).
Para a transmissão de dados, é utilizada a faixa de transmissão ISM (Industrial, Scientific and
Medical), operando com frequências na faixa de 2.400 GHz até 2.483 GHz e por ser uma faixa
de frequência aberta, não necessita de licença para utilização (HARTE, 2004).
O Bluetooth utiliza a técnica de transmissão FHSS (Frequency Hopping Spread Spectrum),
dividindo a faixa de frequência utilizada pelo ISM em 79 canais de 1 MHz cada, e
constantemente muda de frequência para evitar interferências, sendo que a cada segundo são
realizados 1600 saltos, para que os dados sejam enviados e recebidos (PEDRALHO, 2005).
32
2.4.1. Arquitetura
A arquitetura de comunicação Bluetooth é constituída por várias camadas, cada uma
possuindo suas próprias responsabilidades (LOUREIRO et al, 2003). A seguir, são
apresentada as camadas da arquitetura do Bluetooth (figura 2.17), assim como a definição de
cada uma delas:
Figura 2.17 – Arquitetura do Padrão Bluetooth
Fonte: http://homepages.dcc.ufmg.br/~loureiro/cm/docs/sbrc03.pdf
• RF (Radio Frequency) – também chamada de Rádio, esta camada é responsável por
definir aspectos físicos da transmissão do sinal, como frequência de operação, potência
e técnicas de modulação e transmissão.
• Baseband – esta camada preocupa-se com o estabelecimento de conexão dentro de uma
piconet. Trata da transmissão dos bits, especificando a forma dos saltos de frequência,
slots de tempo, formato e tipo dos pacotes, endereço dos dispositivos e tipos de
conexões.
• Áudio – camada utilizada diretamente com a baseband, já que os dados são enviados
diretamente da aplicação para a baseband, possibilitando conexão direta de áudio entre
dois dispositivos.
• LMP (Link Management Protocol) – camada responsável por gerenciar o processo de
autenticação, estabelecimento de conexão, configuração entre dispositivos e controle de
consumo de energia.
• L2CAP (Logical Link Control and Adaptation Protocol) – é um protocolo utilizado para
transmissão de dados assíncronos, fornecendo serviços orientados e não-orientados à
conexão para as camadas superiores, como multiplexação de canal, segmentação e
remontagem de pacotes, parâmetros de qualidade e abstração de grupo.
33
• TCP/IP (Transmission Control Protocol/Internet Protocol) – é um protocolo de envio e
recebimento de dados na internet adotado pelo Bluetooth para facilitar a comunicação
entre dispositivos.
• SDP (Service Discover Protocol) – protocolo responsável por permitir que dispositivos
obtenham informações sobre serviços disponíveis de outros dispositivos.
• RFCOMM (Radio Frequency Communications port) – protocolos desenvolvido pela
SIG, utilizado para transferência de dados serial, emulando sinais RS-232.
• Aplicação – camada desenvolvida pela empresa que fabricou o dispositivo Bluetooth.
2.4.2. Topologia
As redes Bluetooth são formadas quando dois ou mais dispositivos iniciam uma comunicação
através de uma conexão, sendo denominadas piconets. O aparelho que inicia a conexão é
chamado master e dentre as responsabilidades estão enquadradas a regulação da transmissão de
dados e o sincronismo dos dispositivos na rede. O aparelho responsável por aceitar a conexão
é denominado slave (HARTE, 2004).
Uma piconet pode-se ter no máximo 8 dispositivos compartilhando informações entre si, sendo
1 master e 7 slaves. Estas redes também podem conectar-se com outras quando um ou mais
dispositivo de uma piconet conecta-se com outro de outra piconet, formando uma scatternet.
Um dispositivo master só pode estar em uma única rede, enquanto os slaves podem estar em
mais de uma rede ao mesmo tempo (HARTE, 2004). O esquema da topologia do Bluetooth é
ilustrado na figura 2.18.
Figura 2.18 – Topologia de uma Rede Bluetooth
Fonte: http://www.devmedia.com.br/prototipo-de-comunicacao-bluetooth-ieee-802-15-1-em-
tecnologia-movel-parte-01/7808
34
2.4.3. Estabelecimento de Conexão
Os estados para que uma conexão entre dispositivos utilizando a tecnologia Bluetooth IEEE
802.15.1 seja realizada, são definidos conforme o diagrama do estabelecimento de conexão na
figura 2.19.
Figura 2.19 – Estabelecimento de Conexão do Bluetooth
Fonte: http://www.devmedia.com.br/prototipo-de-comunicacao-bluetooth-ieee-802-15-1-em-
tecnologia-movel-parte-01/7808
O procedimento inicial é através do estado inquiry, onde o dispositivo mestre envia requisições
para todos os dispositivos que estejam dentro do alcance. Para responder a esta requisição, o
dispositivo destino deve-se encontrar no estado inquiry scan. Ao receber o pacote inquiry, ele
passa para o estado inquiry response, no qual um pacote de resposta é enviado ao dispositivo
mestre contendo o endereço físico e o relógio.
Após a ocorrência do processo inquiry, o procedimento de tentativa de conexão inicia-se com
o estado de page, enviando pacotes de paging requests a aparelhos que responderam com
informações no inquiry, aguardando pacotes de paging response ou também conhecido como
slave response de dispositivos que estejam em page scan, na qual escuta o canal esperando por
mensagens. Por sua vez, o dispositivo mestre envia um pacote master response solicitando o
início da conexão que é confirmado pelo dispositivo escravo.
35
Depois que os procedimentos inquiry e paging foram realizados, os dispositivos podem
estabelecer um canal de comunicação para troca de informações, são definidos 4 modos de
operação:
• Active: Participação ativa na conexão, seja escutando a rede ou enviando e recebendo
dados. O consumo de energia neste estado é máximo.
• Sniff: Diminuição da taxa de escuta da rede, que pode ser programado conforme a
utilização, este estado possibilita um menor consumo de energia.
• Hold: No caso de não haver tráfego de dados, o dispositivo master coloca algum
dispositivo slave neste modo, a fim de consumir uma menor quantidade de energia. No
estado Hold, utilizá-se apenas o clock interno do dispositivo para sincronismo com os
demais.
• Park: Mesmo caso do Hold, onde não há tráfego, o dispositivo perde seu endereço de
membro ativo (MAC). É o estado cujo o consumo de energia é menor e mais eficiente.
2.5. Computação em Nuvem
A Computação em Nuvem (CN), muito conhecida também pelo termo em inglês Cloud
Computing, possibilita oferecer como serviço recursos de hardware e/ou software, de modo
transparente para os usuários seja em qualquer local, seja em qualquer hora.
CN é a entrega de serviços de computação – servidores, armazenamento, bancos de dados,
redes, software, inteligência – pela Internet, permitindo oferecer inovação mais rápida, recursos
flexíveis e economia de escala, pagando apenas pelos serviços utilizados (MICROSOFT, 2018).
Segundo Mell (2011), CN é um modelo utilizado para permitir o acesso onipresente,
conveniente e sob-demanda de recursos computacionais compartilhados (redes, servidores,
armazenamento, aplicações e serviços) que podem ser rapidamente fornecido e liberado com o
menor esforço gerencial ou interação do provedor de serviço.
2.5.1. Modelos de Serviço
Diversos tipos de CN são ofercidos como um serviço aos usuários, recursos computacionais
são alugados e nenhum recurso de hardware ou software é comprado diretamente pelo usuário
(WILLIAMS, 2010).
O National Instutite of Standards and Technology (NIST) apresenta três modalidades de
serviços:
36
• Software as a Service (SaaS): Oferece ao usuário a execução de softwares em uma
infraestrutura de nuvem. As aplicações são acessíveis a partir de vários dispositivos
clientes, como um navegador web ou uma interface de programa. O usuário não
gerencia ou controla o infraestrutura de nuvem, limitando-se a configurações do
aplicativo.
• Platform as a Service (PaaS): Neste modelo, o usuário é possibilitado de implantar
aplicações na nuvem, sejam próprias ou de terceiros, nas linguagens, bibliotecas e
ferramentas suportadas pelo provedor. O usuário não gerencia ou controla a
infraestrutura de nuvem, mas tem o controle sobre os aplicativos implantados e
possivelmente definições de configuração para o ambiente de hospedagem de
aplicativo.
• Infrastructure as a Service (IaaS): Este modelo permite ao usuário provisionar o
processamento, armazenamento, redes e outros recursos fundamentais para a
computação. O consumidor não gerencia nem controla a nuvem, mas tem controle sobre
sistemas operacionais, armazenamento e aplicativos implantados; e possivelmente
controle limitado de componentes de rede selecionados (por exemplo, firewalls de host).
Possuem outros modelos de serviços, de forma genérica chamados de XaaS (Anything as a
Service). Dependendo da necessidade inserem atributos e tecnologias para prover diferentes
tipos de serviços “XaaS”, no qual o “X” pode ser negócios, dados, infraestrutura, plataforma,
hardware, software, etc (RIMAL; CHOI; LUMB, 2009).
A próxima sessão será apresentado um novo modelo de serviço chamado Backend as a Service
(BaaS).
2.5.2. Backend as a Service
O modelo de serviço BaaS ou Backend as a Service comporta-se como um middleware,
oferecendo, aos desenvolvedores, a possibilidade de conexão de suas aplicações a serviços em
nuvem através de SDK e API (PAIVA; LEAL; QUEIRÓS, 2016). Com isso, torna-se possível
prover, por exemplo, recursos como autenticação, armazenamento e notificação.
37
O BaaS facilita o desenvolvimento de aplicações, fornecendo recursos significativos e
necessário para seu negócio, retirando a complexidade de implantação e gerenciamento de sua
própria infraestrutura.
O Google detém um modelo de serviço BaaS chamado Firebase, o qual veremos a seguir.
2.5.3. Firebase
Construída sobre a infraestrutura do Google, o Firebase é definido como um modelo de
serviço Backend as a Service, e tem como intuito facilitar o desenvolvimento de aplicações
web e mobile, disponibilizando serviços como banco de dados, autenticação de usuário,
hosting, analytics, além de tornar um produto escalável (FIREBASE, 2018).
Através da console do Firebase, é possível realizar a criação e todo o gerenciamento do
projeto, como por exemplo a escolha do método de autenticação, a criação de regras de acesso
ao banco de dados. A inserção do Firebase a aplicação é realizada através da inicialização do
seu SDK, o qual possui informações sobre o projeto, possibilitando a utilização dos demais
serviços do FIREBASE (2018), como:
• Authentication: serviço para autenticar usuários na aplicação. Este serviço fornece
suporte para autenticação por meio de senhas, números de telefone e provedores de
identidades federadas, como: Google, Facebook, Twitter entre outros.
• Storage: serviço para realizar o armazenamento de objetos como imagens, áudios,
vídeos ou qualquer outro conteúdo gerado pelo usuário. Estes objetos ficam
armazenados em um repositório do Google Cloud Storage e são acessados através do
SDK do Firebase que permite realizar upload e download dos mesmos.
• Database: é um banco de dados de tempo real hospedado na nuvem. Os dados são
armazenados no formato JSON e sincronizados em tempo real com todos os usuários
conectados. Todos os usuários que compartilham uma instância do Realtime Database,
independente se a plataforma for IOS, Android ou JavaScript, recebem
automaticamente atualização com os dados mais recentes.
• Hosting: é o serviço disponibilizado para hospedar páginas estáticas com HTML, CSS
e JavaScript.
38
2.6. Aplicação Web
Uma aplicação web pode ser definida como um software que utiliza o ambiente web para sua
execução (CONALLEN, 2000). Por sua vez, o acesso e visualização a essa aplicação se dá
através de um software chamado browser, instalado na máquina cliente, servindo-se da
infraestrutura da internet para comunicação através do protocolo HTTP.
Segundo Deitel (2009), aplicações baseadas na web são aplicações divididas em camadas,
responsáveis pelas divisões das funcionalidades em camadas separadas, sendo tais: camada
inferior (camada de dados), camada intermediária (camada da lógica de negócio) e camada
superior (camada de interface com o usuário). A figura 2.22 ilustra a arquitetura básica de uma
aplicação web com três camadas.
A camada inferior ou conhecida também por camada de dados se encarrega por manter os
dados da aplicação, armazenando, de forma geral, no banco de dados.
A camada intermediária é responsável pela implementação de toda a lógica de negócio, de
controle e apresentação dos dados. Atua como um intermediário entre os dados e os clientes.
A lógica de negócio assegura as regras básicas da aplicação, impondo como os clientes acessam
os dados e como as aplicações os processam. A lógica de controle processa todo tipo de
solicitação dos clientes e obtém os dados do banco de dados. Por fim, a lógica apresentação
processa os dados da camada inferior e os apresentam ao cliente em HTML.
A camada superior é a interface do usuário propriamente dita, na qual o cliente irá interagir
diretamente com a aplicação. Geralmente consiste em um browser.
Portanto, quando o usuário clica em um link, a camada superior interage com a camada
intermediária para fazer a solicitação e obtenção dos dados da camada inferior. A camada
superior então exibe os dados solicitados pelo cliente, porém, essa camada nunca interage
diretamente com a camada inferior.
39
Figura 2.20 – Arquitetura de três Camadas
Fonte: DEITEL, 2009, p. 437.
3. DESENVOLVIMENTO
O desenvolvimento do sistema proposto foi dividido em três partes para melhor compreensão,
sendo elas:
• Hardware
• Aplicativo Android
• Aplicativo Web
3.1. Hardware
Esta etapa foi caracterizada pela montagem e configuração do hardware para a coleta da
frequência cardíaca. Foi utilizada a placa Arduino, juntamente com o sensor de batimentos
chamada Pulse Sensor e um módulo bluetooth chamado HC-05. A fim de suportar a confecção
desse protótipo, necessitou-se a utilização de uma protoboard, jumpers para ligação do circuito
e um conversor de nível lógico 3.3V – 5V para o correto funcionamento do módulo.
O módulo HC-05 permite a abstração da comunicação sem fio necessária para a comunicação
bluetooth ocorrer, fornecendo uma interface serial para o Arduino receber ou enviar dados, além
de possibilitar diversas configurações e funcionalidades que podem ser acessadas via comandos
AT, padrão na indústria para configuração de equipamentos através de uma série de cadeias de
texto, que podem ser combinados para emitir comandos.
40
3.1.1. Configuração do módulo HC-05
Para realizar a configuração do módulo bluetooth HC-05 foi necessária a montagem do circuito
representado pela imagem 3.1 e o desenvolvimento de um programa que permite a comunicação
serial entre a interface USB do computador e o módulo. Basicamente o programa tem por
finalidade enviar para a serial tudo o que for recebido pelo módulo e enviar para o módulo
qualquer informação recebida pela serial. O código pode ser verificado no Apêndice A.
Figura 3.1 – Desenho Esquemático da Configuração do Módulo HC-05
Fonte: Autor
Com o circuito montado e a comunicação serial entre USB e módulo realizados, possibilitou
através do Monitor Serial da IDE de desenvolvimento do Arduino, realizar a configuração do
módulo. Os comandos AT utilizados nesta etapa foram:
• AT+NAME=myheart (define um nome de exibição para o módulo)
• AT+PASS=1234 (define uma senha para o pareamento com outros dispositivos)
• AT+ROLE=0 (define o módulo como slave, ou seja, apenas aceitará conexões
originadas de outro dispositivo)
3.1.2. Funcionamento do hardware
O funcionamento do protótipo começa pela aquisição da frequência cardíaca através do sensor
chamado Pulse Sensor, sendo um sensor de fácil aplicação. Ele conta com 3 pinos para conexão,
sendo saída para o sinal analógico, alimentação (3V a 5V) e terra. Utilizando o princípio de
fotopletismografia, consegue-se ter um formato de onda previsível, possibilitando a captura do
batimento cardíaco através da flutuação do nível de tensão. O sinal capturado pelo sensor
precisa ser então amplificado e normalizado pelo Arduino. De acordo com a variação da
41
intensidade de luz absorvida pelo receptor infravermelho do sensor, permite-se encontrar o
momento exato do batimento cardíaco e medir o tempo entre eles (IBI), e para uma melhor
precisão, o BPM é calculado com base nos 10 últimos IBI coletados.
A frequência cardíaca é adicionada ao buffer de transmissão do módulo bluetooth HC-05,
juntamente com um delimitador ‘\n’ para separar os valores da frequência cardíaca e enviar ao
dispositivo Android de forma organizada. O Arduino sempre fará a verificação no buffer de
transmissão do bluetooth para realizar o envio da informação. Neste projeto, adotou-se o
intervalo de 10 segundos para o envio do batimento. Na figura 3.2 é possível visualizar o
circuito montado e no Apêndice B o código do Arduino.
Figura 3.2 – Desenho Esquemático do Protótipo
Fonte: Autor
3.2. Aplicativo Android
Esta fase foi marcada pelo desenvolvimento da aplicação Android responsável pelo
recebimento da frequência cardíaca do paciente e, após isso, a persistência deste dado em banco.
O aplicativo também tem por finalidade o gerenciamento da conexão bluetooth com o Arduino.
Para melhor entendimento da aplicação, houve a necessidade da divisão em algumas partes,
sendo elas:
• Autenticação
• Comunicação bluetooth
• Persistência em banco de dados
42
3.2.1. Autenticação
Ao iniciar a aplicação, é necessária a autenticação do paciente. Utilizou-se a plataforma
Firebase para realizar a autenticação do usuário no formato de login e senha, conforme a figura
3.3. O ponto de partida para a realização do login foi através da instância criada da classe
FirebaseAuth durante o método OnCreate() da activity.
Ainda no ciclo de vida da activity de login, especificamente no método onStart(), foi necessária
a verificação da autenticação do paciente através da classe FirebaseUser, para checar se o
mesmo já estava logado, pois se estivesse pularia a etapa de login direto para a tela principal do
aplicativo, caso contrário seria necessária a autenticação. Ao efetuar o login é invocado o
método signInWithEmailAndPassword, passando como parâmetros o email e senha.
Figura 3.3 – Tela de Autenticação Figura 3.4 – Tela de Cadastro
Fonte: Autor Fonte: Autor
Um novo paciente para realizar o cadastro basta clicar em “Não possui uma conta ainda?
Registre-se” e inserir os dados para cadastro com nome, email, telefone e senha e clicar no
botão criar conta de acordo com a figura 3.4. Ao realizar o login, independente da tela de login
ou de cadastro será direcionado para a parte principal da aplicação. Os códigos da
43
LoginActivity, SignupActivity, assim como o layout de cada tela podem ser visualizados no
Apêndice C.
3.2.2. Comunicação Bluetooth
Para ocorrer a comunicação entre aplicativo android e arduino, é necessário realizar antes o
pareamento do dispositivo com o módulo bluetooth HC-05 nas configurações do smartphone.
As figuras 3.5 e 3.6 mostram esta etapa. O nome visível do HC-05, assim como a senha foram
definidos no processo de configuração do módulo como é mostrado na sessão 3.1.1.
Figura 3.5 – Dispositivos Encontrados Figura 3.6 – Pareamento Bluetooth
Fonte: Autor Fonte: Autor
Após autenticado no aplicativo, será possibilitado o acesso a tela principal (figuras 3.7 e 3.8).
No menu principal possuem alguns botões para deslogar (encerrando a sessão de usuário),
conectar e desconectar a comunicação bluetooth com o arduino.
Na tela principal, uma vez que haja comunicação com o módulo bluetooth, é mostrado no
display a frequência cardíaca em tempo real. Ainda na tela principal, possui também um botão
44
de emergência que notifica o médico, através de sua aplicação web, permitindo tomar alguma
medida cabível.
Para o aplicativo iniciar a comunicação com o módulo bluetooth HC-05, é necessário pressionar
o botão conectar no menu, e deste modo, inicia-se a tentativa do estabelecimento de conexão
criando uma nova thread e, em caso de sucesso, obtém-se um socket de comunicação entre eles,
possibilitando o envio de mensagens neste canal criado.
A thread espera a chegada de mensagens no buffer de recepção e faz o parser destes dados
através do delimitador ‘\n’ que foi utilizado no envio dos dados pelo módulo HC-05. Apenas
ocorre a interrupção da thread caso o botão desconectar for pressionado fechamento do
aplicativo (onDestroy()). O código completo da classe que realiza a conexão bluetooth e a classe
principal pode ser visto no Apêndice D.
Figura 3.7 – Tela Principal Figura 3.8 – Menu da Tela Principal
Fonte: Autor Fonte: Autor
3.2.3. Persistência em Banco de Dados
Para a realização da persistência a nível de banco de dados, utilizou-se o Realtime Database da
plataforma Firebase. Com ele foi possível armazenar dados JSON em banco NoSQL em nuvem.
A persistência ocorre em três momentos durante a aplicação, sendo eles:
45
• Cadastro de usuário – ao realizar o cadastro no aplicativo, as informações pessoais
referentes ao paciente como nome, email e telefone são armazenadas na child ‘info’.
• Coleta da frequência cardíaca – no instante em que o aplicativo recebe um batimento
cardíaco proveniente do circuito com o Arduino, é realizado a persistência da
frequência cardíaca e o horário na child ‘heartbeat’.
• Botão de ajuda – ao pressionar o botão de ajuda é persistido um boolean na child
‘help’, ou seja, quando o botão for pressionado é enviado o valor ‘1’, caso contrário
‘0’.
A fim de manter a organização da coleta das informações pessoais do paciente, assim como sua
frequência cardíaca e horário houve a necessidade da criação da classe Patient. A persistência
se dá através da instância da classe do Firebase chamada DatabaseReference, no qual é
necessária passar a referência do banco. A figura 3.9 mostra a estrutura de persistência criada
em JSON. O código da classe Patient e os trechos de persistência dos dados podem ser vistos
no Apêndice E.
Figura 3.9 – Estrutura dos Dados no Realtime Database
Fonte: Autor
3.3. Aplicação Web
Nesta etapa foi realizada a criação da aplicação web, a fim de possibilitar que o médico consulte
em tempo real a frequência cardíaca do paciente e tenha um histórico desta informação por
46
meio de gráfico, assim como o maior e menor batimento. Esta aplicação também servirá para
notificar o médico através de um status em tela quando o paciente pressionar o botão de ajuda
em seu aplicativo Android. As figuras 3.11 e 3.12 mostram a interface da aplicação.
Foi desenvolvida utilizando HTML5, CSS3 com a biblioteca Bootstrap, Chart.js para a criação
gráfica e Javascript para realizar as consultas em banco.
3.3.1. Banco de Dados
Para realizar operações básicas no banco de dados é necessário antes inicializar o SDK do
Javascript. A imagem 3.10 mostra o trecho do código de inicialização do SDK.
Com o SDK inicializado, torna-se possível a leitura ou gravação em banco após receber a
referência do mesmo. Os dados podem ser recuperados anexando um listener assíncrono a uma
referência. No escopo deste projeto houve a necessidade da utilização de listeners para notificar
alterações no banco, como por exemplo a inserção de um novo batimento e, deste modo, refletir
na tela do médico, alterando o gráfico, o batimento atual ou até mesmo o maior ou menor
batimento. O código completo da aplicação pode ser visualizado no apêndice F.
Figura 3.10 – Código da Inicialização do SDK do Javascript
Fonte: Autor
47
Figura 3.11 – Visão da Aplicação Web
Fonte: Autor
Figura 3.12 – Visão da Aplicação Web quando Pressionado o Botão
Fonte: Autor
48
4. CONCLUSÃO
A partir da proposta inicial de realizar a coleta da frequência cardíaca até a disponibilização da
mesma via web, foi possível a conclusão do projeto em sua integralidade. A escolha da
plataforma Arduino na construção do hardware foi um fator fundamental para o projeto, pois
sua documentação é bem rica, a comunidade bastante ativa e conta com uma série de módulos
e sensores desenvolvidos por terceiros, o qual facilitou a confecção. A utilização do smartphone
Android atuando como intermediário entre o recebimento do batimento e o armazenamento em
banco de dados foi outra peça chave no projeto, permitindo o gerenciamento da conexão
bluetooth com Arduino, o acesso a internet de forma simples, bem como a utilização do SDK
do Firebase para realizar tarefas complexas como autenticação e armazenamento dos dados sem
a necessidade de preocupação com infraestrutura. A junção dos itens mencionados
proporcionou, através de uma aplicação web, o monitoramento em tempo real da frequência
cardíaca.
Vale ressaltar alguns pontos percebidos no sensor de batimento e a conexão bluetooth. O sensor
demonstrou ser bastante frágil, sendo necessário uma adaptação para reforçar as conexões de
seus três pinos. Por usar o princípio de fotopletismografia, houve bastante problemas com ruído
externo e, novamente foi necessária a adaptação colocando um material isolante para a
utilização do sensor. Sobre a conexão bluetooth, não foi pensado em nenhum momento do
projeto na economia de energia, ocasionando um enorme gasto de bateria no smartphone.
Através dos estudos realizados sobre o funcionamento do coração e seu sistema de condução,
concluí-se que a frequência cardíaca é uma varíavel importantíssima para monitoramento e,
uma vez identificada qualquer anormalidade no ritmo cardíaco é possível tomar medidas
rápidas para salvar uma vida.
Finalmente, o conhecimento obtido a partir do desenvolvimento deste trabalho de conclusão de
curso foi muito grande, principalmente pelo fato do projeto envolver todo o desenvolvimento
de um dispositivo, realizando toda a montagem do hardware até o desenvolvimento do software
final.
49
4.1. Trabalhos Futuros
Para trabalhos futuros, recomenda-se a substituição do módulo bluetooth HC-05 pelo HM-10,
oferecendo suporte ao bluetooth de baixo consumo, impactando diretamente no consumo de
bateria do smartphone e do próprio hardware.
A fim de melhorar a assertividade das análises cardíacas, sugere-se também a utilização de mais
sensores, como por exemplo o mpu6050, um acelerômetro de 3 eixos que permite que
identifique movimentação. Deste modo, seria possível cruzar informações e identificar que o
aumento repentino da frequência cardíaca estivesse relacionada a uma atividade física
momentânea.
Implementação de um chat entre aplicativo android e aplicação web para comunicação direta
entre paciente e médico.
50
5. REFERÊNCIAS
BAGGIO, Maria A. et al. Cuidado humano e tecnologia na enfermagem contemporânea e
complexa, 2009. Disponível em: <http://www.scielo.br/pdf/tce/v19n2/21.pdf> Acesso em: 10
out. 2015.
BASHSHUR, R. L. et al. Telemedicine/Telehealth: An International Perspective,
Telemedicine Journal and e-Health, 2002, vol. 8, nº 1.
LANDRO, Laura. U.S. Plan Would Boost Acess to Last Result. 2011. Disponível em:
<online.wsj.com/article/SB10001424053111903374004576580731136618202.html>.
Acessado em: 12 out. 2015.
AMARAL, Nilcéia N. et al. Assistência Domiciliar à Saúde (Home Health Care). Revista
Neurociências, São Paulo, P. 111-117, 2001.
TISS – Padrão para Troca de Informações de Saúde Suplementar. Disponível em:
<http://www.ans.gov.br/prestadores/tiss-troca-de-informacao-de-saude-suplementar>. Acesso
em: 20 oct. 2015.
Arduino – Arduino Uno. Disponível em: <http://playground.arduino.cc/Portugues/HomePage
09/11> Acesso em: 22 oct. 2015.
BANZI, Massimo. Getting Started with Arduino. 3ª edição. Estados Unidos: Editora O„Reilly
Media/Make, 2008. 128 páginas.
ALVES, Luciano da Silva. Aprenda Passo a Passo A Programar Em Android Clube de
Autores, 2008, 622 páginas.
LECHETA, Ricardo R. - Google Android – Aprenda a criar aplicações para dispositivos
móveis com o Android SDK. 2010, ed. Novatec, 608 páginas.
FOROUZAN, Behrouz A. – Comunicação de Dados e Redes de Computadores 3ª edição
Bookman 2008 840 páginas.
51
Teleco – Bluetooth. Disponível em: <http://www.teleco.com.br/tutoriais/tutorialblue/> Acesso
em: 01 nov. 2015.
Harte, L.; Introduction to Bluetooth - Technology, Market, Operation, Profiles, and Services.
Althos, 2004. 60 páginas.
PEDRALHO, A. Bluetooth: Da teoria à prática. O mundo sem cabos – Parte I. Número 3,
Pág. 16-20, 2005.
LOUREIRO, Antonio A. F. et al (2003). Redes de Sensores sem Fio. Disponível em: <
http://homepages.dcc.ufmg.br/~loureiro/cm/docs/sbrc03.pdf >. Acesso em: 01 nov.
2015.
SOA Web Services – Como Funcionam os Web Services. Disponível em:
<http://www.soawebservices.com.br/como-funciona.aspx.> Acesso em: 10 nov. 2015.
W3C – Web Services Architecture. Disponível em: < http://www.w3.org/TR/ws-arch/>
Acesso em: 11 nov. 2015.
AKAY, M. Wiley Encyclopedia of Biomedical Engineering. Wiley - Interscience, 2006.
FELDMAN, José; GOLDWASSER, Gerson P. Eletrocardiograma: recomendações para a sua
interpretação – Revista Brasileira de Cardiologia. Disponível em:
<http://www.rbconline.org.br/artigo/eletrocardiograma-recomendacoes-para-a-sua-
interpretacao >. Acesso em: 13 nov. 2015.
Pulse Sensor – Referências sobre o sensor de pulso cardíaco. Disponível em:
<http://pulsesensor.com>. Acesso em: 12 nov. 2015.
GOLDBERG, C. – A practical guide to clinical medicine. Disponível em:
<http://meded.ucsd.edu/clinicalmed/vital.htm>. Acesso em: 11 nov. 2015.
52
CORAÇÃO ALERTA – Eletrocardiograma em repouso (ECG). Disponível em: <
http://coracaoalerta.com.br/tratamento-do-infarto/eletrocardiograma-em-repouso-ecg/ >.
Acesso em: 12 nov. 2015.
PINHEIRO, Dr. Pedro – Entenda o seu eletrocardiograma (ECG). MD Saúde. Disponível em:
< http://www.mdsaude.com/2012/07/exame-eletrocardiograma-ecg.html>. Acesso em: 12
nov. 2015.
PLUX – PLUX wireless biosignals. Disponível em: <http://www.plux.info/>. Acesso em: 12
nov. 2015.
TREMPER, K.K.; BARKER, S.J. Pulse oximetry. Anesthesiology, v. 70, p. 98-108, 1987.
CONALLEM, J.: “Building Web Applications with UML”. Addison Wesley, 2000.
DEITEL, Paul J.; Deitel, Harvey M. Ajax, Rich Internet Application e desenvolvimento: Web
para programadores. 2009. Ed. Pearson. 776 páginas.
Microsoft Azure – What is cloud computing. Disponível em: <https://azure.microsoft.com/en-
in/overview/what-is-cloud-computing>. Acesso em: 3 nov. 2018.
MELL, P.; GRANCE, T. The nist definition of cloud computing. Computer Security Division,
Information Technology Laboratory, National Institute of Standards and Technology
Gaithersburg, 2011.
WILLIAMS, M. I. A quick start guide to cloud computing: moving your business into the cloud.
[S.l.]: Kogan Page Publishers, 2010.
RIMAL, B. P.; CHOI, E.; LUMB, I. A taxonomy and survey of cloud computing systems.
NCM, v. 9, p. 44–51, 2009
FIREBASE. Firebase. 2018. Documentação do Firebase. Disponível em:
<https://firebase.google.com/docs/>. Acessado em: 3 nov. 2018
53
APÊNDICE A - Código de Configuração do Módulo Bluetooth HC-05
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(5, 6); // RX | TX
void setup() {
pinMode(13, OUTPUT);
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
Serial.begin(9600);
BTSerial.begin(9600);
delay(1000);
Serial.println("Comando AT:");
}
void loop() {
if (BTSerial.available()){
digitalWrite(13, HIGH);
Serial.write(BTSerial.read());
digitalWrite(13, LOW);
}
if (Serial.available()){
digitalWrite(13, HIGH);
BTSerial.write(Serial.read());
digitalWrite(13, LOW);
}
}
54
APÊNDICE B - Código do Arduino
#include <SoftwareSerial.h>
//Variáveis usadas no serviço de interrupção
volatile int BPM; // Batimento
volatile int Signal; // Sinal bruto
volatile int IBI = 600; // Intervalo entre as batidas
volatile boolean Pulse = false; // True quando é uma pulsação verdadeira
int pulsePin = 0; // Pulse Sensor - pino analógico 0
int blinkPin = 13; // Pisca led no pino 13 a cada batida
String bluetooth_tx_buffer = ""; // Buffer de envio de batimentos
char DELIMITER = '\n'; // Delimitador usado para separar os batimentos
int RX_PIN = 5; // Rx - pino digital 5
int TX_PIN = 6; // Tx - pino digital 6
SoftwareSerial bluetooth(RX_PIN, TX_PIN);
void setup(){
pinMode(blinkPin,OUTPUT);
Serial.begin(9600);
bluetooth.begin(9600); // Inicializa o módulo bluetooth HC-05 em baud rate 9600
interruptSetup(); // Faz a leitura do sinal do sensor de batimentos a cada 2mS
Serial.println("Inicializado.");
}
void parseWriteBuffer() {
// Encontra o primeiro delimitador no buffer
int inx = bluetooth_tx_buffer.indexOf(DELIMITER);
55
// Sai caso não tenha nenhum
if (inx == -1) return;
// Obtém um batimento, incluindo o delimitador
String message = bluetooth_tx_buffer.substring(0, inx + 1);
// Remove a mensagem do buffer
bluetooth_tx_buffer = bluetooth_tx_buffer.substring(inx + 1);
// Envia o batimento pelo módulo bluetooth HC-05 e printa na interface serial
bluetooth.print(message);
Serial.print("[ENVIADO] " + message);
// Procura por mais batimentos no buffer
parseWriteBuffer();
}
void loop(){
bluetooth_tx_buffer += BPM;
bluetooth_tx_buffer += '\n';
parseWriteBuffer();
delay(10000); //Envia os batimentos a cada 10 segundos
}
56
APÊNDICE C – Código de Login e Signup do Aplicativo Android
LoginActivity.java
package com.example.pedro.myheart;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.Map;
public class LoginActivity extends BaseActivity implements
View.OnClickListener {
private static final String TAG = "LoginActivity";
private EditText _emailText;
private EditText _passwordText;
57
private Button _btnLogin;
private TextView _linkSignup;
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mDatabase = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
// Views
_emailText = findViewById(R.id.input_email);
_passwordText = findViewById(R.id.input_password);
// Botões
_btnLogin = (Button) findViewById(R.id.btn_login);
_btnLogin.setOnClickListener(this);
_linkSignup = (TextView) findViewById(R.id.link_signup);
_linkSignup.setOnClickListener(this);
}
@Override
public void onStart() {
super.onStart();
// Checa se o usuário está logado e atualiza a UI
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
58
}
// Método para cadastrar paciente com login e senha
private void signIn(String email, String password) {
Log.d(TAG, "signIn:" + email);
if (!validateForm()) {
return;
}
showProgressDialog();
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Login realizado, atualiza UI com informações do usuário
Log.d(TAG, "signInWithEmail:success");
FirebaseUser patient = mAuth.getCurrentUser();
updateUI(patient);
showMainActivity();
} else {
// Se o login falhar, mostra uma mensagem de falha
Log.w(TAG, "signInWithEmail:failure", task.getException());
Toast.makeText(LoginActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
hideProgressDialog();
}
});
59
}
// Função para validação dos campos de login
private boolean validateForm() {
boolean valid = true;
String email = _emailText.getText().toString();
if (TextUtils.isEmpty(email)) {
_emailText.setError("Requerido.");
valid = false;
} else {
_emailText.setError(null);
}
String password = _passwordText.getText().toString();
if (TextUtils.isEmpty(password)) {
_passwordText.setError("Requerido.");
valid = false;
} else {
_passwordText.setError(null);
}
return valid;
}
// Função para atualizar UI
private void updateUI(FirebaseUser user) {
hideProgressDialog();
if (user != null) {
finish();
showMainActivity();
} else {
_emailText.setText("");
60
_passwordText.setText("");
}
}
private void showMainActivity() {
Intent intent = new Intent(
getApplicationContext(), MainActivity.class
);
startActivity(intent);
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.link_signup) {
Intent intent = new Intent(getApplicationContext(), SignupActivity.class);
startActivity(intent);
} else if (i == R.id.btn_login) {
signIn(_emailText.getText().toString(), _passwordText.getText().toString());
}
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
61
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="56dp"
android:paddingLeft="24dp"
android:paddingRight="24dp">
<ImageView android:src="@drawable/logo"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginBottom="24dp"
android:layout_gravity="center_horizontal" />
<!-- Email Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="Email" />
</android.support.design.widget.TextInputLayout>
<!-- Password Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
62
<EditText android:id="@+id/input_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Senha"/>
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="Login"/>
<TextView android:id="@+id/link_signup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:text="Não possui uma conta ainda? Registre-se"
android:gravity="center"
android:textSize="16dip"/>
</LinearLayout>
</ScrollView>
SignupActivity.java
package com.example.pedro.myheart;
import android.content.Intent;
import android.support.annotation.NonNull;
63
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.Map;
public class SignupActivity extends BaseActivity implements
View.OnClickListener {
private static final String TAG = "SignupActivity";
private EditText _nameText;
private EditText _emailText;
private EditText _passwordText;;
private EditText _telefoneText;
private Button _signupButtom;
private TextView _loginLink;
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
64
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup);
mDatabase = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
// Botões
_signupButtom = (Button) findViewById(R.id.btn_signup);
_signupButtom.setOnClickListener(this);
_loginLink = (TextView) findViewById(R.id.link_login);
_loginLink.setOnClickListener(this);
_nameText = (EditText) findViewById(R.id.input_name);
_emailText = (EditText) findViewById(R.id.input_email);
_passwordText = (EditText) findViewById(R.id.input_password);
_telefoneText = (EditText) findViewById(R.id.input_telefone);
}
private void createAccount(final String name, final String email, final String telefone,
String password) {
Log.d(TAG, "createAccount:" + email);
if (!validateForm()) {
return;
}
showProgressDialog();
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
65
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Login realizado, atualiza UI com informações do usuário
Log.d(TAG, "createUserWithEmail:success");
FirebaseUser patient = mAuth.getCurrentUser();
//Salva em banco
writeNewPatient(name, email, telefone);
updateUI(patient);
} else {
// Se o login falhar, mostra uma mensagem de falha
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(SignupActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
hideProgressDialog();
}
});
}
// Função para validação dos campos de login
private boolean validateForm() {
boolean valid = true;
String name = _nameText.getText().toString();
if (name.isEmpty() || name.length() < 3) {
_nameText.setError("Mínimo 3 caracteres");
valid = false;
} else {
_nameText.setError(null);
66
}
String email = _emailText.getText().toString();
if (TextUtils.isEmpty(email)) {
_emailText.setError("Requerido.");
valid = false;
} else {
_emailText.setError(null);
}
String password = _passwordText.getText().toString();
if (TextUtils.isEmpty(password)) {
_passwordText.setError("Requerido.");
valid = false;
} else {
_passwordText.setError(null);
}
String telefone = _telefoneText.getText().toString();
if (TextUtils.isEmpty(telefone)){
_passwordText.setError("Requerido.");
valid = false;
} else {
_telefoneText.setError(null);
}
return valid;
}
// Função para atualizar UI
private void updateUI(FirebaseUser user) {
hideProgressDialog();
if (user != null) {
67
finish();
showLoginActivity();
} else {
_nameText.setText("");
_emailText.setText("");
_passwordText.setText("");
_telefoneText.setText("");
}
}
private void showLoginActivity() {
Intent intent = new Intent(
getApplicationContext(), LoginActivity.class
);
startActivity(intent);
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.link_login) {
finish();
} else if (i == R.id.btn_signup) {
createAccount(_nameText.getText().toString(), _emailText.getText().toString(),
_telefoneText.getText().toString(),_passwordText.getText().toString());
}
}
// Função para salvar informações do paciente em banco. Child: "info".
private void writeNewPatient(String name, String email, String telefone) {
Patient patient = new Patient(name, email, telefone);
Map<String,Object> patientValues = patient.toMapInfo();
68
mDatabase.child("info").setValue(patientValues);
}
}
activity_signup.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="56dp"
android:paddingLeft="24dp"
android:paddingRight="24dp">
<ImageView android:src="@drawable/logo"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginBottom="24dp"
android:layout_gravity="center_horizontal" />
<!-- Name Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_name"
69
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords"
android:hint="Nome" />
</android.support.design.widget.TextInputLayout>
<!-- Email Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="Email" />
</android.support.design.widget.TextInputLayout>
<!-- Telefone Label -->
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_telefone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPhonetic"
android:hint="Telefone" />
</android.support.design.widget.TextInputLayout>
<!-- Password Label -->
70
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText android:id="@+id/input_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Senha"/>
</android.support.design.widget.TextInputLayout>
<!-- Signup Button -->
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_signup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="Criar conta"/>
<TextView android:id="@+id/link_login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:text="Já é um membro? Clique aqui"
android:gravity="center"
android:textSize="16dip"/>
</LinearLayout>
</ScrollView>
71
APÊNDICE D – Código das Classes Bluetooth e Main do Aplicativo Android
BluetoothConnection.java
package com.example.pedro.myheart;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
public class BluetoothConnection extends Thread {
// Log
private static final String TAG = "BluetoothConnection";
// Delimitador usado para separar os batimentos
private static final char DELIMITER = '\n';
// UUID para comunicação serial bluetooth genérica
private static final UUID uuid = UUID.fromString("00001101-0000-1000-8000-
00805F9B34FB");
// Endereço MAC do módulo HC-05
private final String address;
// Socket da comunicação bluetooth
private BluetoothSocket socket;
72
// Fluxo de entrada e saída da conexão bluetooth
private OutputStream outStream;
private InputStream inStream;
// Handlers usados para transmitir dados entre as threads
private final Handler readHandler;
//private final Handler writeHandler;
// Buffer utilizado para parsear mensagens
private String rx_buffer = "";
// Construtor com o mac address do HC-05 e um handler para mensagens recebidas
public BluetoothConnection(String address, Handler handler) {
this.address = address.toUpperCase();
this.readHandler = handler;
}
// Conexão ao socket bluetooth do HC-05. Se falhar lançará uma exceção
private void connect() throws Exception {
Log.i(TAG, "Tentativa de conexão para " + address + "...");
// Obtém o adapatador bluetooth
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if ((adapter == null) || (!adapter.isEnabled())){
throw new Exception("Bluetooth não foi encontrado ou não está habilitado!");
}
// Encontra o HC-05
BluetoothDevice remoteDevice = adapter.getRemoteDevice(address);
73
// Cria um socket de comunicação com o HC-05 passando o UUID
socket = remoteDevice.createRfcommSocketToServiceRecord(uuid);
// Certifica que o adptador bluetooth não está em modo de descoberta
adapter.cancelDiscovery();
// Conecta o socket
socket.connect();
// Obtém os fluxos de entrada e saída do socket criado
outStream = socket.getOutputStream();
inStream = socket.getInputStream();
Log.i(TAG, "Conexão feita para " + address + ".");
}
// Desconecta os fluxos e socket
private void disconnect() {
if (inStream != null) {
try {inStream.close();} catch (Exception e) { e.printStackTrace(); }
}
if (outStream != null) {
try {outStream.close();} catch (Exception e) { e.printStackTrace(); }
}
if (socket != null) {
try {socket.close();} catch (Exception e) { e.printStackTrace(); }
}
}
74
// Retorna os dados lidos pelo socket ou uma string em branco
private String read() {
String s = "";
try {
// Checa se existem dados
if (inStream.available() > 0) {
// Lê os dados no buffer
byte[] inBuffer = new byte[1024];
int bytesRead = inStream.read(inBuffer);
// Transforma os dados (bytes) lidos em string
s = new String(inBuffer, "ASCII");
s = s.substring(0, bytesRead);
}
} catch (Exception e) {
Log.e(TAG, "Leitura falhou!", e);
}
return s;
}
//Envia mensagem para um handler de leitura
private void sendToReadHandler(String s) {
Message msg = Message.obtain();
msg.obj = s;
readHandler.sendMessage(msg);
Log.i(TAG, "[RECV] " + s);
}
75
// Envia mensagens do rx_buffer para o handler de leitura
private void parseMessages() {
// Encontra o primeiro delimitador no buffer
int inx = rx_buffer.indexOf(DELIMITER);
// Sai caso não tenha dado (no ca não encontre um delimitador)
if (inx == -1)
return;
// Obtém o dado
String s = rx_buffer.substring(0, inx);
// Remove a mensagem do buffer
rx_buffer = rx_buffer.substring(inx + 1);
// Envia para o handler de leitura
sendToReadHandler(s);
// Verifica se há mais mensagens
parseMessages();
}
// Ponto de entrada quando a thread.start() é chamada
public void run() {
// Tentativa para conectar. Caso falhe é gerado um exception
try {
connect();
sendToReadHandler("Conectado");
} catch (Exception e) {
Log.e(TAG, "Falhou a conexão!", e);
76
sendToReadHandler("Falha na conexão");
disconnect();
return;
}
// Enquanto thread.interrupt() não for chamada, loop continua
while (!this.isInterrupted()) {
if ((inStream == null) || (outStream == null)) {
Log.e(TAG, "Conexão blutooth perdida!");
break;
}
// Lê dados e adiciona no buffer
String s = read();
if (s.length() > 0)
rx_buffer += s;
// Procura por mais mensagens
parseMessages();
}
// Se a thread for interrompida, destroi a conexão
disconnect();
sendToReadHandler("Desconectado");
}
}
77
MainActivity.java
package com.example.pedro.myheart;
import android.annotation.SuppressLint;
import android.content.Intent;
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.util.Log;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.Map;
import java.util.concurrent.TimeUnit;
78
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private Patient patient;
private FirebaseAuth mAuth;
private FirebaseUser firebaseUser;
private FirebaseDatabase firebaseDatabase;
private DatabaseReference mDatabase;
// Log
private static final String TAG = "MainActivity";
// Mac Address do HC-05
private final String address = "00:21:13:00:20:02";
// Thread bluetooth
BluetoothConnection bluetoothConnection;
@SuppressLint("ResourceType")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
79
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// Instância do database
mDatabase = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
//Usuário
firebaseUser = mAuth.getCurrentUser();
//Visualizar email
View headerView = navigationView.getHeaderView(0);
TextView navUserEmail = (TextView) headerView.findViewById(R.id.email);
navUserEmail.setText(firebaseUser.getEmail());
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Itens da view de navegação
80
int id = item.getItemId();
if (id == R.id.nav_bluetooth_disconnect) {
disconnectButtonPressed();
} else if (id == R.id.nav_bluetooth_connect) {
connectButtonPressed();
} else if (id == R.id.nav_sign_out) {
signOut(mAuth);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
// Deslogar
private void signOut(FirebaseAuth mAuth) {
mAuth.signOut();
Intent intent = new Intent(getApplicationContext(),LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
MainActivity.this.finish();
}
// Inicia a thread bluetooth quando clicado o botão Conectar
public void connectButtonPressed() {
Log.v(TAG, "Botão conectar clicado.");
// Restringe apenas uma thread por vez
if (bluetoothConnection != null) {
Log.w(TAG, "Já conectado!");
return;
}
81
// Inicializa a thread bluetooth, passando o Mac Address do HC-05
// e um handler para as mensagens recebidas
bluetoothConnection = new BluetoothConnection(address, new Handler() {
@Override
public void handleMessage(Message message) {
String s = (String) message.obj;
if (s.equals("Conectado")) {
Toast.makeText(MainActivity.this, "Conectado",
Toast.LENGTH_LONG).show();
} else if (s.equals("Desconectado")) {
TextView bpm = (TextView) findViewById(R.id.bpm);
bpm.setText("-");
Toast.makeText(MainActivity.this, "Desconectado",
Toast.LENGTH_LONG).show();
} else if (s.equals("Falha na conexão")) {
bluetoothConnection = null;
Toast.makeText(MainActivity.this, "Falha na conexão",
Toast.LENGTH_LONG).show();
} else {
TextView bpm = (TextView) findViewById(R.id.bpm);
bpm.setText(s);
//Envia os batimentos e timestamp para o realtime database
patient = new Patient();
patient.heatbeat = s;
mAuth = FirebaseAuth.getInstance();
firebaseUser = mAuth.getCurrentUser();
82
firebaseDatabase = FirebaseDatabase.getInstance();
mDatabase = firebaseDatabase.getReference("/");
Map<String,Object> patientHeatbeatValues = patient.toMapHeatbeat();
mDatabase.child("heartbeat").push().setValue(patientHeatbeatValues);
ToggleButton help = (ToggleButton) findViewById(R.id.help);
help.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean
isChecked) {
if (isChecked) {
mDatabase.child("help").setValue(1);
} else {
mDatabase.child("help").setValue(0);
}
}
});
}
}
});
// Thread executada
bluetoothConnection.start();
Toast.makeText(MainActivity.this, "Conectando...", Toast.LENGTH_LONG).show();
}
//Destroi a thread bluetooth
public void disconnectButtonPressed() {
Log.v(TAG, "Botão para desconectar pressionado.");
83
if(bluetoothConnection != null) {
bluetoothConnection.interrupt();
bluetoothConnection = null;
}
}
// Ao fechar o aplicativo a thread bluetooth é destruída
@Override
protected void onDestroy() {
super.onDestroy();
if(bluetoothConnection != null) {
bluetoothConnection.interrupt();
bluetoothConnection = null;
}
}
}
84
APÊNDICE E – Código da Classe Patient e Persistência do Aplicativo Android
Patient.java
package com.example.pedro.myheart;
import android.util.Log;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.Exclude;
import com.google.firebase.database.IgnoreExtraProperties;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
@IgnoreExtraProperties
public class Patient {
public String name;
public String email;
public String telefone;
public String heatbeat;
public Patient() {
}
85
public Patient(String name, String email, String telefone) {
this.email = email;
this.name = name;
this.telefone = telefone;
}
public long getTimestamp() {
Date date = new Date();
long time = date.getTime();
return time;
}
@Exclude
public Map<String, Object> toMapInfo() {
HashMap<String, Object> result = new HashMap<>();
result.put("email", email);
result.put("name", name);
result.put("telefone", telefone);
return result;
}
@Exclude
public Map<String, Object> toMapHeatbeat() {
HashMap<String, Object> result = new HashMap<>();
result.put("Timestamp", getTimestamp());
result.put("beat", heatbeat);
return result;
}
}
86
Persistência das informações pessoais do paciente
// Função para salvar informações do pacient em banco. Child: "info".
private void writeNewPatient(String name, String email, String telefone) {
Patient patient = new Patient(name, email, telefone);
Map<String,Object> patientValues = patient.toMapInfo();
mDatabase.child("info").setValue(patientValues);
}
Persistência do horário e frequência cardíaca do paciente
Map<String,Object> patientHeatbeatValues = patient.toMapHeatbeat();
mDatabase.child("heartbeat").push().setValue(patientHeatbeatValues);
Map<String,Object> patientHeatbeatValues = patient.toMapHeatbeat();
mDatabase.child("heartbeat").push().setValue(patientHeatbeatValues);
Persistência do status do paciente de acordo com o botão de ajuda
ToggleButton help = (ToggleButton) findViewById(R.id.help);
help.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mDatabase.child("help").setValue(1);
} else {
mDatabase.child("help").setValue(0);
}
}
});
87
APÊNDICE F – Código da Aplicação Web
app.js
(function(){
//Snippet de configuração do Firebase
var config = {
apiKey: "AIzaSyApM5xWvpGiJsjwXcpoLwnA6jLot1Pubr0",
authDomain: "myheart-7117f.firebaseapp.com",
databaseURL: "https://myheart-7117f.firebaseio.com",
projectId: "myheart-7117f",
storageBucket: "myheart-7117f.appspot.com",
messagingSenderId: "883615834331"
};
firebase.initializeApp(config);
// Realtime Database
var db = firebase.database();
// Refêrencia ao índices
var infoRef = firebase.database().ref('info');
var heartbeatRef = firebase.database().ref('heartbeat');
var helpRef = firebase.database().ref('help');
// Registra as funções que atualizam os dados atuais e gráfico
heartbeatRef.orderByChild("beat").limitToLast(1).on('value',
onNewMaxData('heartbeatMaxValue', 'timestampMaxValue'));
heartbeatRef.orderByChild("beat").limitToFirst(1).on('value',
onNewMinData('heartbeatMinValue', 'timestampMinValue'));
heartbeatRef.limitToLast(100).on('value', onNewData('heartbeatCurrentValue',
'timestampCurrentValue', 'tempLineChart' , 'Batimentos', ''));
88
helpRef.on('value', onNewDataHelp('helpCurrentValue'));
//Registra nome, telefone e email do paciente
infoRef.on('value', function (snapshot) {
var email = snapshot.val().email;
var nome = snapshot.val().name;
var telefone = snapshot.val().telefone;
document.getElementById("patientInfo").innerText = "Nome: "+nome+" | Telefone:
"+telefone+" | Email: "+email;
});
})();
// Função que altera o status do paciente
function onNewDataHelp(helpCurrentValueEl) {
return function(snapshot) {
var helpCurrentValue;
helpCurrentValue = snapshot.val();
if (helpCurrentValue == 0) {
document.getElementById(helpCurrentValueEl).innerText = "Bem";
var elements = document.getElementsByClassName("help-color");
for (var i=0; i< elements.length; i++) {
elements[i].style.backgroundColor = '#b3d9ff';
}
} else if (helpCurrentValue == 1) {
document.getElementById(helpCurrentValueEl).innerText = "Mal";
var elements = document.getElementsByClassName("help-color");
for (var i=0; i< elements.length; i++) {
elements[i].style.backgroundColor = 'red';
}
}
89
}
}
// Retorna uma função que de acordo com mudança em banco, atualiza o maior batimento
function onNewMaxData(heartbeatMaxValueEl, timestampMaxValueEl) {
return function(snapshot) {
var heartbeatMaxValue;
var heartbeatData = [];
var timestampMaxValue;
snapshot.forEach(function(item){
heartbeatMaxValue = item.val().beat;
timestampMaxValue = timeConverter(item.val().Timestamp);
heartbeatData.push(heartbeatMaxValue);
});
document.getElementById(heartbeatMaxValueEl).innerText = heartbeatMaxValue;
document.getElementById(timestampMaxValueEl).innerText = timestampMaxValue;
}
}
// Retorna uma função que de acordo com mudança em banco, atualiza o menor batimento
function onNewMinData(heartbeatMinValueEl, timestampMinValueEl) {
return function(snapshot) {
var heartbeatMinValue;
var timestampMinValue;
snapshot.forEach(function(item){
heartbeatMinValue = item.val().beat;
timestampMinValue = timeConverter(item.val().Timestamp);
});
document.getElementById(heartbeatMinValueEl).innerText = heartbeatMinValue;
document.getElementById(timestampMinValueEl).innerText = timestampMinValue;
90
}
}
// Retorna uma função que de acordo com mudança em banco atualiza o batimento atual e
gráfico
function onNewData(heartbeatcurrentValueEl, timestampcurrentValueEl, chartEl, label,
metric){
return function(snapshot){
var heartbeatCurrentValue;
var timestampCurrentValue;
var timestampData = [];
var heartbeatData = [];
snapshot.forEach(function(item){
heartbeatCurrentValue = item.val().beat;
timestampCurrentValue = timeConverter(item.val().Timestamp);
heartbeatData.push(heartbeatCurrentValue);
timestampData.push(timestampCurrentValue);
});
document.getElementById(heartbeatcurrentValueEl).innerText = heartbeatCurrentValue;
document.getElementById(timestampcurrentValueEl).innerText = timestampCurrentValue;
buildLineChart(chartEl, label, heartbeatData, timestampData);
}
}
// Função que realiza a criação do gráfico
function buildLineChart(el, label, heartbeatData, timestampData){
var elNode = document.getElementById(el);
new Chart(elNode, {
type: 'bar',
91
data: {
labels: timestampData,
datasets: [{
label: label,
data: heartbeatData,
borderWidth: 1,
fill: false,
spanGaps: false,
lineTension: 0.1,
backgroundColor: "#C3533A",
borderColor: "#C3533A",
borderWidth: 5,
options: {
}
}]
}
});
}
function addData(chart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
// Converte timestamp em horário seguindo o padrão [dd mm yy hh:mm:ss]
function timeConverter(timestamp){
var a = new Date(timestamp);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
92
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes();
var sec = a.getSeconds();
var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
return time;
}
index.html
<html>
<head>
<title>My Heart</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-
scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-
awesome/4.6.3/css/font-awesome.css">
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-
MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous">
<link rel="stylesheet" href="css/styles.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css">
</head>
<body>
<div class="navbar-fixed">
93
<nav class="nav-extended">
<div class="nav-wrapper">
<a href="#" class="brand-logo center">My Heart</a>
</div>
<div class="nav-content center">
<h6> <span id="patientInfo">-</span>
</h6>
</div>
</nav>
</div>
<div class="container content">
<br/><br/>
<div class="row">
<div class="col s12 m6">
<div class="card">
<span class="card-title activator grey-text center">Batimento atual</span>
<div class="card-image center">
<span id="heartbeatCurrentValue" class="statistic">-</span>
</div>
<span id="timestampCurrentValue" class="card-title activator grey-text center">-
</span>
</div>
</div>
<div class="col s12 m6">
<div class="card">
<span class="card-title activator grey-text center">Maior batimento</span>
<div class="card-image center">
<span id="heartbeatMaxValue" class="statistic">-</span>
</div>
<span id="timestampMaxValue" class="card-title activator grey-text center">-
</span>
</div>
</div>
94
<div class="col s12 m6">
<div class="card">
<span class="card-title activator grey-text center">Menor batimento</span>
<div class="card-image center">
<span id="heartbeatMinValue" class="statistic">-</span>
</div>
<span id="timestampMinValue" class="card-title activator grey-text center">-
</span>
</div>
</div>
<div class="col s12 m6">
<div class="card">
<span class="card-title activator grey-text center">Status</span>
<div class="help-color card-image center">
<span id="helpCurrentValue" class="statistic2">-</span>
</div>
<span class="help-color card-title activator grey-text center">-</span>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col s12 m6">
<canvas id="tempLineChart"></canvas>
</div>
</div>
</div>
</div>
</body>
95
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-
q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-
ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
integrity="sha384-
ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
crossorigin="anonymous"></script>
<script src="https://www.gstatic.com/firebasejs/3.3.0/firebase.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<script src="js/app.js"></script>
</html>
styles.css
body{
background-color: #E0E0E0;
}
.content {
margin-top: 40px;
}
nav {
background-color: #C3533A;
}
.statistic {
font-size: 8em;
margin-top: 15px !important;
}
.statistic2 {
96
font-size: 8em;
margin-top: 15px !important;
}
.card {
min-height: 250px;
}
.activator {
cursor: pointer;
}
@media screen and (max-width: 600px){
.statistic {
font-size: 5em;
}
}
.help-color {
background-color: #ffffff;
}