Prototipo Señales Cardiacas
Prototipo Señales Cardiacas
Prototipo Señales Cardiacas
PROYECTO DE TITULACIÓN.
INGENIERO EN NETWORKING Y
TELECOMUNICACIONES.
GUAYAQUIL – ECUADOR
2020
REPOSITORIO NACIONAL EN CIENCIAS Y TECNOLOGÍA
FICHA DE REGISTRO DE TESIS
TÍTULO “DISEÑO E IMPLEMENTACIÓN DE UN PROTOTIPO PARA SIMULACIÓN DE
SEÑALES ELÉCTRICAS CARDÍACAS PARA LA FACULTAD DE MEDICINA DE LA
UNIVERSIDAD DE GUAYAQUIL.”
REVISORES: ING. MANUEL EDUARDO
FLORES MORAN MSC.
INSTITUCIÓN: Universidad de Guayaquil. FACULTAD: Ciencias Matemáticas y Físicas.
CARRERA: Ingeniería en Networking y Telecomunicaciones.
FECHA DE PUBLICACIÓN: N° DE PÁGS.: 65
ÁREA TEMÁTICA: Networking, Telecomunicaciones.
PALABRAS CLAVES: Simulador, Raspberry pi, Simulador Cardíaco.
RESUMEN: Hoy en día no todos los estudiantes de medicina tienen la facilidad de conocer simuladores que les ayuden
a observar con más profundidad y de manera casi real los fallos del corazón y si los tienen, son simuladores muy
costosos. Los cuales no están al alcance de todos, por lo tanto, solo se localizan en universidades con un alto
presupuesto económico. En la actualidad se pueden desarrollar simuladores de bajo costo y que realicen una buena
presentación con un alto grado de robustez para que los estudiantes logren aprender, captar, registrar la actividad
eléctrica del corazón, logren identificar cuando un paciente ha sufrido un infarto, arritmias o identificar una serie de
trastornos que son de utilidad para el control del paciente.
Para el presente proyecto integrador se diseñó y construyó un simulador que pueda dar impulsos eléctricos de gran
similitud a la de un corazón por medio de un hardware denominado Raspberry Pi 4, el cual generará las señales de
pulsos cardíacos y también se podrá visualizar y seleccionar por medio de un menú gráfico desarrollado por medio del
lenguaje de programación Python, el mismo que desplegará diferentes opciones y así alumnos puedan interactuar de
forma amigable con el simulador.
Nombre:
CONTACTO DE LA INSTITUCIÓN
Teléfono:
II
APROBACIÓN DEL TUTOR
Atentamente.
III
DEDICATORIA
Gracias, madre.
IV
AGRADECIMIENTO
La prioridad de mi
agradecimiento es para Dios,
gracias a su bondad,
misericordia y fortaleza he
logrado cumplir unas de mis
metas en mi vida. Gracias a
mi esposa Ingrid Izurieta
Piedrahita y mi madre Gladys
Valero Martillo que son
pilares en todo las decisiones
y proyectos en mi vida;
también debo agradecer a mi
amigo David Manzo Vera ya
que gracias a él retomé la
decisión de culminar esta
meta.
V
TRIBUNAL PROYECTO DE TITULACIÓN.
Ing. Eduardo Flores Moran, M.Sc. Ing. Wilber Ortiz Aguilar, M.Sc.
PROFESOR REVISOR PROFESOR DEL ÁREA
TRIBUNAL. TRIBUNAL.
VI
DECLARACIÓN EXPRESA.
Proyecto de Titulación que se presenta como requisito para optar por el título
C.I.:0919099937.
ii
CERTIFICADO DE ACEPTACIÓN DEL TUTOR.
CERTIFICO:
Presentado por:
iii
UNIVERSIDAD DE GUAYAQUIL
FACULTAD DE CIENCIAS MATEMÁTICAS Y FÍSICAS
CARRERA DE INGENIERÍA EN NETWORKING Y
TELECOMUNICACIONES.
iv
Publicación electrónica:
Firma Alumno:
3. Forma de envío:
El texto del proyecto de titulación debe ser enviado en formato Word, como
archivo .Doc. O .RTF y. Puf para PC. Las imágenes que la acompañen pueden
ser: .gif, .jpg o .TIFF.
DVDROM X CDROM
v
ÍNDICE
TRIBUNAL PROYECTO DE TITULACIÓN .......................................................... VI
ABSTRACT ................................................................................................................... ix
ABREVIATURAS .......................................................................................................... x
SIMBOLOGÍA............................................................................................................... xi
INTRODUCCIÓN .......................................................................................................... 1
CAPÍTULO I................................................................................................................... 3
EL PROBLEMA ............................................................................................................. 3
OBJETIVOS ................................................................................................................... 9
OBJETIVOS ESPECÍFICOS........................................................................................ 9
CAPÍTULO II ............................................................................................................... 13
vi
FUNDAMENTACIÓN TEÓRICA / DEFINICIONES CONCEPTUALES ........... 14
FUNDAMENTACIÓN LEGAL .................................................................................. 18
PREGUNTA CIENTÍFICA PARA CONTESTARSE .............................................. 21
PROPUESTA TECNOLÓGICA................................................................................. 22
ANÁLISIS DE FACTIBILIDAD ................................................................................ 22
FACTIBILIDAD TÉCNICA ....................................................................................... 22
FACTIBILIDAD ECONÓMICA ................................................................................ 23
ETAPAS DE LA METODOLOGÍA ........................................................................... 23
ENTREGABLES DEL PROYECTO ......................................................................... 25
CRITERIO DE LA VALIDACIÓN PROPUESTA .................................................. 25
PROCESAMIENTO Y ANÁLISIS ............................................................................. 25
FUNCIONAMIENTO Y PARÁMETROS DEL ....................................................... 26
SIMULADOR DE RITMO CARDIACO ................................................................... 26
CAPÍTULO IV – ........................................................................................................... 29
RESULTADOS ............................................................................................................. 31
CONCLUSIONES ........................................................................................................ 32
RECOMENDACIONES .............................................................................................. 33
BIBLIOGRAFÍA .......................................................................................................... 34
ANEXOS........................................................................................................................ 36
vii
RESUMEN.
viii
ABSTRACT.
Nowadays, not all medical students have the facility to know simulators
that help them to observe in more depth and in an almost real way heart
failures and if they do, they are very expensive simulators. Which are not
available to everyone, therefore, they are only located in universities with
a high economic budget. At present, low-cost simulators can be developed
that make a good presentation with a high degree of robustness so that
students can learn, capture, record the electrical activity of the heart,
identify when a patient has suffered a heart attack, arrhythmias or identify
a series of disorders that are useful for patient management.
For the present integrating project, a simulator was designed and built that
can give electrical impulses very similar to that of a heart by means of a
hardware called Raspberry Pi 4, which will generate the cardiac pulse
signals and can also be viewed and selected by through a graphical menu
developed through the Python programming language, which will display
different options and thus students will be able to interact in a friendly way
with the simulator
ix
ABREVIATURAS.
UG Universidad de Guayaquil.
Ing. Ingeniero.
Msc. Máster.
PhD. Doctor.
Sr. Señor.
Ab. Abogado.
Esp. Especialista.
Covid-19 Coronavirus 2019-nCoV.
ECG o EKG Electrocardiograma.
LPM Latidos por minuto.
x
SIMBOLOGÍA
N°. Número.
P Despolarización de las aurículas en el ciclo cardiaco.
QRS Representa la despolarización y contracción
ventricular.
Q Señal cardiaca precedida de la señal P.
R Señal cardiaca precedida de la señal Q.
S Señal cardiaca precedida de la R.
T Representa la repolarización de los ventrículos.
xi
ÍNDICE DE CUADROS
INDICE ..................................................................................................................... VI
TABLA 1: CAUSAS Y CONSECUENCIAS ...........................................................................6
TABLA 2: DELIMITACIÓN ..............................................................................................7
TABLA 3: FUNDAMENTOS LEGALES. ............................................................................ 18
xii
ÍNDICE DE GRÁFICOS.
xiii
INTRODUCCIÓN.
1
caso de los estudiantes de medicina de la Universidad de Guayaquil y a
los internos de los hospitales. Dada esta problemática en la actualidad el
estudiante pierde práctica, existen varias soluciones para este problema;
Implementación de zonas de revisión de pacientes en facultades de
medicina, telemedicina, videos donde se explique procedimientos
quirúrgicos, uso de simuladores, entre otros.
2
CAPÍTULO I.
EL PROBLEMA.
3
Existen varias formas de diseñar un simulador del sistema cardiovascular,
por ejemplo:
4
Situación Conflicto Nudos Críticos.
5
Causas y Consecuencias del Problema.
6
Delimitación del Problema.
Tabla 2: Delimitación
Tecnología de la información,
Campo
Ciencias Médicas, Ingeniería.
Recursos académicos en la
Aspecto
asignatura de cardiología.
Diseño e implementación de un
sistema para simular arritmias
cardíacas en el cual se emplearán
diferentes herramientas
Tema electrónicas para su
implementación, tales como
Raspberry, Arduino,
Microprocesadores, Convertidores,
entre otros.
7
Evaluación del Problema.
8
necesitará un paciente en físico, pues el paciente será un maniquí el cual
tendrá un gel especial y unos componentes electrónicos para emitir
pulsaciones y de esta forma conectar los electrodos para el
electrocardiograma.
OBJETIVOS.
OBJETIVO GENERAL.
OBJETIVOS ESPECÍFICOS.
• Recrear los diferentes tipos de señales del latido del corazón de forma
digital y la creación de un menú para la elección de las diferentes
simulaciones cardiológicas que se pudieran dar cuando una persona
experimenta arritmia cardíaca.
• Diseño y programación del simulador mediante la tarjeta de desarrollo
Raspberry Pi 4.
• Realizar pruebas con personal docente en el área de medicina y con
estudiantes de ciencias médicas para validar aprobación del prototipo.
9
ALCANCES DEL PROBLEMA.
10
Este listado de simuladores gratuitos los podemos encontrar en internet y en la
página anexos estará el link de cada uno de ellos.
JUSTIFICACIÓN E IMPORTANCIA.
11
METODOLOGÍA DEL PROYECTO:
METODOLOGÍA DE DESARROLLO.
Supuesto.
Restricciones.
12
Plan de calidad.
CAPÍTULO II.
MARCO TEÓRICO.
13
y el uso de simuladores ayuda a los futuros profesionales a tener una mayor
experiencia. (Macaya, 2018)
Arritmias cardíacas.
Las arritmias cardíacas son alteraciones de la secuencia de contracciones
y relajaciones del corazón. Sus causas pueden ser diversas, al igual que
su gravedad y consecuencias clínicas: algunas modificaciones del ritmo
cardíaco remiten de forma espontánea o eliminando la causa que las ha
producido, mientras que en otros casos se afecta de forma importante a la
función cardíaca. Los síntomas de una arritmia pueden incluir palpitaciones,
falta de aire, mareos o desmayos; causas comunes de arritmias.
(Manchego, 2019)
• La vía normal de conducción cardiovascular se interrumpe.
• Otra parte del corazón asume el control como marcapasos.
• El marcapasos natural del corazón (el nódulo sinusal) produce una
• frecuencia o ritmo anormales.
14
Electrocardiógrafo o electrocardiograma.
Es un procedimiento que mide las señales eléctricas del corazón y las
muestra en una pantalla para su interpretación, el procedimiento es indoloro
y tiene dos siglas correctas y de uso común que son: EKG o ECG.
Tarjetas de desarrollo.
El uso de tarjetas de desarrollo en el campo de la electrónica tiene como
fin la reducción de los circuitos con la implementación de una placa
programable en la cual se pueden hacer modificaciones de su operación
según la programación establecida en la misma. Es importante la
implementación de este tipo de electrónica pues es un esquema en el cual
se pueden hacer mejoras con tan solo modificar bloques de programación,
mientras que en la electrónica antigua si se tenía que hacer cambios en
todo el circuito básicamente. Una tarjeta de desarrollo en el área de la
ingeniería es una herramienta de diseño para prototipos y diseños rápidos
en sistemas digitales y analógicos. (Felipe, 2013)
Software libre.
El uso de software libre a crecido en el uso de proyectos de cualquier índole
en las ciencias actuales, pues estos, no se ven limitados en funciones que
los da un proveedor de software de paga. El software libre goza de una
amplia documentación donde el código puede ser modificado según los
15
requerimientos del diseñador. Un problema del uso de este software es que
en muchos casos no tienen una interfaz gráfica para su uso, por lo que
sería un gran reto para una persona sin conocimiento en programación.
La ventaja del uso del software libre en las implementaciones de proyectos
es el abaratamiento de costos y la “libertad” al momento del uso, del diseño,
del esquema, entre otros. (Alarcón, 2019)
Microcontrolador.
Componente electrónico con circuitos aritméticos, lógicos que son
programados para cumplir especificaciones dadas por el diseñador. Un
microcontrolador tiene una unidad de procesamiento y una memoria donde
se almacena mediante código las funciones que ejercerá, este
microcontrolador podrá enviar y recibir señales eléctricas que por lo general
son de voltajes de 5 voltios. (E-Marmolejo., 2017)
Proyectos Similares:
16
Simulador con graficas creadas por computador HoloLens.
17
Figura 3.- Menú de opciones.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
FUNDAMENTACIÓN LEGAL.
18
“El sistema nacional de ciencia, tecnología, innovación y
saberes ancestrales, en el marco del respeto al
CONSTITUCIÓN DEL ambiente, la naturaleza, la vida, las culturas y la
ECUADOR soberanía, tendrá como finalidad:
ARTÍCULO 385 Desarrollar tecnologías e innovaciones que impulsen la
LITERAL 3.- producción nacional, eleven la eficiencia y productividad,
mejoren la calidad de vida y contribuyan a la realización
del buen vivir.”
DECRETO 1014 “En Ecuador, se emitió el Decreto No. 1014 en abril del
2008, basado en los siguientes ejes centrales:
19
1. Cumplimiento de recomendaciones Internacionales:
La Carta Iberoamericana de Gobierno Electrónico
aprobada por la “IX Conferencia Iberoamericana de
Ministros de Administración Pública y Reforma del
Estado “, que recomienda el uso de estándares abiertos
y software libre como herramientas informáticas.
2. Con los objetivos fundamentales de:
Alcanzar la soberanía y autonomía tecnológica.
Alcanzar un ahorro significativo de recursos públicos.
Se decretó establecer como política pública la utilización
de software libre en los sistemas y equipamientos
informáticos de las Entidades de la Administración
Pública Central, tomando como definición de Software
Libre las cuatro libertades promulgadas por Richard
Stallman.
Indica, que se debe evaluar periódicamente los sistemas
informáticos que utilizan software propietario con el fin
de migrarlos a software libre.”
20
“Objetivo 10: Impulsar la transformación de la matriz
productiva.
21
CAPÍTULO III.
PROPUESTA TECNOLÓGICA.
ANÁLISIS DE FACTIBILIDAD.
FACTIBILIDAD TÉCNICA.
22
FACTIBILIDAD ECONÓMICA.
ETAPAS DE LA METODOLOGÍA.
• Bajo costo.
• Interfaz gráfica, para un entorno amigable.
• Fácil acceso al menú.
• Diversidad en simulaciones de pulsos cardiacos.
23
Fase II: Diseño y Desarrollo.
24
ENTREGABLES DEL PROYECTO.
A través de los criterios del tutor de Tesis y del Tutor revisor, se procedió a
validar de que cada uno de los requerimientos planteados en la propuesta
tecnológica, sean llevados a cabo en el simulador. A continuación, se
indican las pruebas realizadas:
PROCESAMIENTO Y ANÁLISIS.
25
FUNCIONAMIENTO Y PARÁMETROS DEL
26
El simulador de ritmo cardiaco cuenta con las siguientes 7 patologías de
arritmias:
27
Configuración de señal cardiaca: En esta opción del menú, el estudiante
deberá ingresar los parámetros de amplitud e invertir los diferentes tipos de
ondas que conforman la señal cardiaca (Figura 7), de esta forma se podrá
verificar gráficamente la señal generada con variaciones.
28
CAPÍTULO IV –
29
Figura 9.- Deficiencia en equipos electrónicos.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
30
Figura 11.- Viabilidad del simulador.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
RESULTADOS.
31
Se creo un menú donde el practicante pueda verificar las diferentes
arritmias cardíacas a través de un entorno gráfico donde se aprecian las
pulsaciones por minuto y se pueden observar las diferentes amplitudes que
se encuentran en un pulso cardiaco.
CONCLUSIONES.
32
tales como la librería Matplotlib y NumPy que se implementaron en el
código y se usaron con el fin de agilizarlo para la gráfica de señales.
RECOMENDACIONES.
Una mejora al simulador podría ser agregar una etapa de testeo dónde el
usuario se conecta los electrodos y el equipo almacena en memoria la señal
cardíaca, luego de esto, compara la señal almacenada con alguna
patología de arritmia cardíaca.
33
BIBLIOGRAFÍA
34
Argullós JL, Palés C, Gomar S. El uso de las simulaciones en educación médica.
Teoría de la Educación. Educación y Cultura en la Sociedad de la
Información 2010; 11 (2): 147-70.
Bonilla Trujillo, D., Villamil Reyes, V. V., & Montes Mora, J. F. (2019). Uso de
simuladores 3D como estrategia tecno pedagógica para la transferencia
de conocimiento en el aprendizaje de la anatomía animal. Documentos
De Trabajo ECAPMA, (1). https://doi.org/10.22490/ECAPMA.3414
35
ANEXOS
36
Figura 14.- Taquicardia auricular.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
37
Figura 16.- Ritmo sinusal.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
38
Figura 18.- Arritmia sinusal.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
39
Figura 20.- Valor Pulsaciones por minuto incorrecto.
Fuente: Trabajo de Investigación.
Autor: Gatsby Gabino Bueno Valero.
Código Fuente.
EjecutableSimulador.sh
#!/bin/sh
# launcher.sh
# navigate to home directory, then to this directory, then execute
python script, then back home
cd /
cd home/pi/SimuladorCardiaco #where the script is
sudo python3 SimuladorCardiaco.py #a commnad to run the script
cd /
40
Librería.py
arreglo=[952 , 952 , 954 , 956 , 961 , 966 , 971 , 977 , 983 , 990 ,
996 , 1003 , 1011 , 1018 , 1026 , 1033 , 1040 , 1048 , 1059 , 1069 ,
1079 , 1089 , 1099 , 1107 , 1113 , 1120 , 1126 , 1132 , 1139 , 1145 ,
1151 , 1158 , 1164 , 1170 , 1177 , 1183 , 1189 , 1196 , 1202 , 1208 ,
1215 , 1222 , 1230 , 1238 , 1246 , 1252 , 1253 , 1254 , 1255 , 1256 ,
1257 , 1258 , 1258 , 1259 , 1259 , 1259 , 1259 , 1259 , 1259 , 1259 ,
1259 , 1259 , 1258 , 1258 , 1257 , 1256 , 1255 , 1254 , 1253 , 1253 ,
1252 , 1248 , 1241 , 1235 , 1228 , 1222 , 1215 , 1209 , 1203 , 1198 ,
1193 , 1188 , 1183 , 1178 , 1173 , 1169 , 1164 , 1159 , 1153 , 1148 ,
1142 , 1136 , 1130 , 1125 , 1119 , 1113 , 1107 , 1102 , 1094 , 1086 ,
1078 , 1070 , 1062 , 1055 , 1047 , 1040 , 1032 , 1025 , 1017 , 1012 ,
1007 , 1002 , 997 , 992 , 987 , 982 , 977 , 972 , 967 , 964 ,
963 , 961 , 959 , 957 , 955 , 953 , 952 , 952 , 952 , 952 ,
952 , 952 , 952 , 952 , 952 , 952 , 952 , 952 , 952 , 951 ,
951 , 951 , 951 , 951 , 951 , 951 , 951 , 951 , 951 , 951 ,
951 , 951 , 953 , 957 , 962 , 965 , 963 , 960 , 957 , 955 ,
952 , 945 , 935 , 925 , 915 , 904 , 894 , 886 , 879 , 871 ,
863 , 855 , 840 , 817 , 793 , 769 , 741 , 713 , 686 , 658 ,
991 , 1307 , 1332 , 1358 , 1401 , 1493 , 1591 , 1670 , 1766 , 1910 ,
1954 , 2187 , 2532 , 2548 , 2782 , 2923 , 3247 , 3263 , 3746 , 3899 ,
3909 , 4021 , 4080 , 4058 , 4037 , 3974 , 3859 , 3870 , 3533 , 3468 ,
3404 , 3329 , 3251 , 3095 , 2715 , 2625 , 2513 , 2486 , 2198 , 1690 ,
1268 , 832 , 572 , 306 , 346 , 72 , 67 , 62 , 57 , 52 ,
47 , 115 , 226 , 259 , 272 , 288 , 313 , 338 , 363 , 467 ,
532 , 561 , 577 , 594 , 618 , 673 , 687 , 702 , 717 , 824 ,
922 , 941 , 960 , 978 , 988 , 997 , 1007 , 1016 , 1022 , 1025 ,
1028 , 1031 , 1033 , 1036 , 1039 , 1042 , 1045 , 1047 , 1048 , 1048 ,
1047 , 1046 , 1046 , 1045 , 1044 , 1044 , 1043 , 1042 , 1042 , 1040 ,
1037 , 1034 , 1032 , 1029 , 1026 , 1023 , 1020 , 1017 , 1014 , 1011 ,
1008 , 1005 , 1001 , 998 , 994 , 990 , 987 , 983 , 979 , 977 ,
977 , 977 , 977 , 977 , 977 , 977 , 977 , 977 , 977 , 977 ,
977 , 977 , 977 , 977 , 977 , 977 , 977 , 977 , 977 , 977 ,
977 , 977 , 977 , 977 , 978 , 979 , 979 , 980 , 981 , 981 ,
982 , 983 , 984 , 984 , 984 , 984 , 984 , 984 , 983 , 983 ,
984 , 986 , 988 , 990 , 992 , 994 , 996 , 999 , 1001 , 1003 ,
1005 , 1012 , 1018 , 1024 , 1031 , 1037 , 1043 , 1050 , 1055 , 1059 ,
1063 , 1067 , 1071 , 1074 , 1078 , 1082 , 1086 , 1090 , 1093 , 1098 ,
1107 , 1115 , 1124 , 1133 , 1142 , 1149 , 1154 , 1159 , 1165 , 1170 ,
1175 , 1180 , 1185 , 1191 , 1196 , 1201 , 1206 , 1211 , 1216 , 1221 ,
1226 , 1231 , 1236 , 1241 , 1246 , 1251 , 1256 , 1261 , 1266 , 1272 ,
1277 , 1283 , 1289 , 1294 , 1300 , 1305 , 1310 , 1313 , 1315 , 1318 ,
1320 , 1323 , 1325 , 1328 , 1330 , 1333 , 1335 , 1338 , 1338 , 1338 ,
1338 , 1338 , 1338 , 1338 , 1338 , 1338 , 1338 , 1338 , 1338 , 1334 ,
1330 , 1326 , 1323 , 1319 , 1315 , 1311 , 1307 , 1303 , 1299 , 1296 ,
1292 , 1288 , 1285 , 1281 , 1278 , 1274 , 1271 , 1267 , 1263 , 1260 ,
1255 , 1250 , 1246 , 1241 , 1236 , 1230 , 1224 , 1219 , 1213 , 1208 ,
41
1202 , 1196 , 1191 , 1184 , 1177 , 1170 , 1162 , 1155 , 1147 , 1140 ,
1133 , 1125 , 1117 , 1109 , 1101 , 1093 , 1088 , 1082 , 1076 , 1071 ,
1065 , 1059 , 1053 , 1048 , 1042 , 1037 , 1034 , 1032 , 1029 , 1026 ,
1023 , 1021 , 1018 , 1015 , 1013 , 1010 , 1007 , 1005 , 1002 , 1001 ,
1000 , 999 , 998 , 997 , 997 , 996 , 995 , 990 , 989 , 985 ,
983 , 980 , 976 , 974 , 972 , 970 , 968 , 965 , 961 , 958 ,
955 , 952 , 952, 952]
amplitudP=54
amplitudQ=179
amplitudR=202
amplitudS=230
amplitudT=408
eje=952
def modularSeñal(Señal):
j=0
for i in Señal:
Señal[j]=i/47
j=j+1
return Señal
def invertirSeñal(Onda,eje):
j=0
for i in Onda:
Onda[j]=(2*eje-i)
j=j+1
def ampliarSeñal(Onda,value):
j=0
if(detectarConcava(Onda)==1):
42
for i in Onda:
Onda[j]=i*(value*0.01+1)
j=j+1
if(detectarConcava(Onda)==0):
for i in Onda:
Onda[j]=i*(1-value*0.01)
j=j+1
def detectarConcava(Onda):
j=0
value=Onda[0]
count=0
count2=0
for i in Onda:
if(i>value):
count2=0
count=count+1
if(count>10):
return 1 #concava hacia arriba
else:
count=0
count2=count2+1
if(count2>10):
return 0 #concava hacia abajo
def obtenerSeñal(Onda,Señal,inter1):
j=inter1
k=0
for i in Onda:
Onda[k]=Señal[j]
j=j+1
k=k+1
def concatenarSeñal(Onda,Señal,inter1):
j=inter1
for i in Onda:
Señal[j]=i
j=j+1
def frecuencia(lpm):
#lpm=lpm*0.01578947368/60
lpm=lpm*0.05/49
return lpm
def animate(i):
global Señal
x = np.linspace(0,8,len(Señal))
ax = plt.axes(xlim=(0,5), ylim=(-1000,5000))
line, = ax.plot([], [], lw=2,c="b")
line.set_data([], [])
ax.grid(True)
line.set_data(x-frecuencia(frecuenciaValor)*i, Señal)
return line,
def ritmoCardiaco(frecu,texto,Invertir,Amplitud,VarLPM):
global
frecuenciaValor,Señal,OndaP,OndaQ,OndaR,OndaS,OndaT,Onda_ST,arreglo
global interP1,interQ1,interR1,interS1,interT1,interST1,eje
root = tk.Tk()
root.wm_title(texto)
root.geometry("1360x700")
frecuenciaValor=frecu
43
Señal= [952 for i in range(524)]
obtenerSeñal(OndaP,arreglo,interP1)
obtenerSeñal(OndaQ,arreglo,interQ1)
obtenerSeñal(OndaR,arreglo,interR1)
obtenerSeñal(OndaS,arreglo,interS1)
obtenerSeñal(OndaT,arreglo,interT1)
obtenerSeñal(Onda_ST,arreglo,interST1)
if Invertir[0]==1:
invertirSeñal(OndaP,eje)
if Invertir[1]==1:
invertirSeñal(OndaQ,eje)
if Invertir[2]==1:
invertirSeñal(OndaS,eje)
if Invertir[3]==1:
invertirSeñal(OndaT,eje)
ampliarSeñal(OndaP,Amplitud[0])
ampliarSeñal(OndaQ,Amplitud[1])
ampliarSeñal(OndaR,Amplitud[2])
ampliarSeñal(OndaS,Amplitud[3])
ampliarSeñal(OndaT,Amplitud[4])
concatenarSeñal(OndaP,Señal,interP1)
concatenarSeñal(OndaQ,Señal,interQ1)
concatenarSeñal(OndaR,Señal,interR1)
concatenarSeñal(OndaS,Señal,interS1)
concatenarSeñal(OndaT,Señal,interT1)
concatenarSeñal(Onda_ST,Señal,interST1)
for i in range(3):
Señal=np.concatenate((Señal,arreglo3,Señal))
print(len(Señal))
pulsos=int(2/frecuencia(frecuenciaValor))
fig = plt.figure()
# call the animator. blit=True means only re-draw the parts that
have changed.
anim = animation.FuncAnimation(fig, animate ,frames=pulsos,
interval=20, blit=True)
#anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec',
'libx264'])
label=tk.Label(root, text=str(frecu)+"
LPM",font=("Verdana",20,"bold")).place(x=1190,y=20)
tk.Button(root, text="cerrar", command=lambda:
root.destroy()).place(x=1250,y=620)
plt.show()
44
#ritmoCardiaco(60,"prueba","P")
Simuladorcardiaco.py
###!/usr/bin/env python
### -*- coding: utf-8 -*-
import time
import os, sys
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import tkinter as tk
import random
from PIL import ImageTk, Image
from IPython.display import display
from IPython.core.pylabtools import figsize, getfigs
from matplotlib.backends.backend_tkagg import *
from matplotlib.figure import *
from pylab import *
from numpy import *
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from lib import *
direccion="/home/pi/SimuladorCardiaco/imagenes/"
w=1360
h=700
tamaño=str(w)+'x'+str(h)
VarCambio=0
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Intro(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.cont1=Frame(Page.__init__(self, *args, **kwargs))
can=tk.Canvas(self ,w=w,height=h,bg='yellow')
can.grid(column=0,row=0)
can.pack(fill=BOTH)
can.create_text(w-700,h-650,text="SIMULADOR RITMO
CARDIACO",font=("Verdana",40,"bold"))
#root.delete("all")
can.create_image(0,0,anchor=NW, image=primeraImagen)
can.pack()
45
class PosicionElectrodos(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.cont1=Frame(Page.__init__(self, *args, **kwargs))
class OpcionesArritmias(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.VarText=tk.StringVar()
estructura = tk.Frame(self)
estructura.pack(side="top", fill="both", expand=True)
can=tk.Canvas(self ,w=w,height=h,bg='steelblue1')
can.pack(fill=BOTH)
can.create_text(w-700,h-670,text="Seleccione la patología
que desee simular",font=("Verdana",25,"bold"))
can.create_text(w-1200,h-
620,text="Mostrando:",font=("Verdana",20,"bold"))
can.create_rectangle(150,110,600,180, fill="white")
muestra_var=tk.Label(self,
textvariable=self.VarText,font=("Verdana",20,"bold"),bg="white").place
(x=w-1150,y=h-575)
#Entry(self,font=('arial',20,'bold'),width=22,textvariable=VarText,bd=
20,insertwidth=4,bg="powder blue",justify="right").place(x=w-1000,y=h-
550)
can.create_image(20,h-500,anchor=NW,
image=arritmiaCorazon)
can.pack()
b1 = tk.Button(self, text="Bradicardia
Sinusal",font=("Verdana",15,"bold"),fg="black",
bg="steelblue1",image=botonArritmia,compound="center",command= lambda:
self.Insertar("Bradicardia Sinusal",56,"")).place(x=650,y=80)
b2 = tk.Button(self, text="Ritmo
Sinusal",font=("Verdana",15,"bold"),fg="black", bg="steelblue1",
image=botonArritmia,compound="center",command= lambda:
self.Insertar("Ritmo Sinusal ",80,"")).place(x=1000,y=80)
b3 = tk.Button(self, text="Taquicardia
Sinusal",font=("Verdana",15,"bold"),fg="black", bg="steelblue1",
46
image=botonArritmia,compound="center",command= lambda:
self.Insertar("Taquicardia Sinusal",140,"")).place(x=650,y=215)
b4 = tk.Button(self, text="Fibrilación
Auricular",font=("Verdana",15,"bold"),fg="black", bg="steelblue1",
image=botonArritmia,compound="center",command= lambda:
self.Insertar("Fibrilación Auricular",90,"")).place(x=1000,y=215)
b5 = tk.Button(self,
text="Taquicardia\nAuricular",font=("Verdana",15,"bold"),fg="black",
bg="steelblue1", image=botonArritmia,compound="center",command=
lambda: self.Insertar("Taquicardia
Auricular",230,"")).place(x=650,y=350)
b6 = tk.Button(self, text="Arritmia
Sinusal",font=("Verdana",15,"bold"),fg="black", bg="steelblue1",
image=botonArritmia,compound="center",command= lambda:
self.Insertar("Arritmia Sinusal",70,"")).place(x=1000,y=350)
b7 = tk.Button(self,
text="Taquicardia\nNodal",font=("Verdana",15,"bold"),fg="black",
bg="steelblue1", image=botonArritmia,compound="center",command=
lambda: self.Insertar("Taquicardia Nodal",118,"P")).place(x=825,y=485)
print(self.VarText)
#can.place(x=0,y=0)
#self.after(1,OpcionesArritmias)
def Insertar(self,texto,frecuencia,Invert):
Invertir=[0 for i in range(4)]
Amplitud=[0 for i in range(5)]
self.VarText.set(texto)
if Invert=="P":
Invertir.pop(0)
Invertir.insert(0,1)
ritmoCardiaco(frecuencia,texto,Invertir,Amplitud)
class Evaluacion(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
global VarCambio
self.VarText=tk.StringVar()
VarSelect=0
estructura = tk.Frame(self)
estructura.pack(side="top", fill="both", expand=True)
can=tk.Canvas(self ,w=w,height=h,bg='azure2')
can.pack(fill=BOTH)
can.create_rectangle(100,300,400,600, fill="white")
can.create_text(w-1110,h-
420,text="Validación",font=("Verdana",20,"bold"))
can.create_text(w-1100,h-650,text="1) Presione
GENERAR.\n2) Seleccione la opción que corresponde\n a la Arritmia que
se muestra en el ECG.",font=("Verdana",15,"bold"))
can.create_text(w-400,h-670,text="Modo de
Evaluación",font=("Verdana",35,"bold"))
#can.create_text(w-700,h-
670,text=VarText,font=("Verdana",35,"bold"))
#can.create_image(0,h-620,anchor=NW,
image=arritmiaCorazon)
can.pack()
inicio = tk.Button(self,
text="GENERAR",font=("Verdana",15,"bold"),fg="black", bg="azure2",
47
image=botonEvaluacion,compound="center",command= lambda:
self.Aleatorio()).place(x=110,y=150)
b1 = tk.Button(self, text="Bradicardia
Sinusal",font=("Verdana",15,"bold"),fg="black",
bg="azure2",image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(1)).place(x=650,y=80)
b2 = tk.Button(self, text="Ritmo Sinusal
",font=("Verdana",15,"bold"),fg="black", bg="azure2",
image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(2)).place(x=1000,y=80)
b3 = tk.Button(self,
text="Taquicardia\nSinusal",font=("Verdana",15,"bold"),fg="black",
bg="azure2", image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(3)).place(x=650,y=215)
b4 = tk.Button(self,
text="Fibrilación\nAuricular",font=("Verdana",15,"bold"),fg="black",
bg="azure2", image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(4)).place(x=1000,y=215)
b5 = tk.Button(self,
text="Taquicardia\nAuricular",font=("Verdana",15,"bold"),fg="black",
bg="azure2", image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(5)).place(x=650,y=350)
b6 = tk.Button(self,
text="Arritmia\nSinusal",font=("Verdana",15,"bold"),fg="black",
bg="azure2", image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(6)).place(x=1000,y=350)
b7 = tk.Button(self,
text="Taquicardia\nNodal",font=("Verdana",15,"bold"),fg="black",
bg="azure2", image=botonEvaluacion,compound="center",command= lambda:
self.Seleccionar(7)).place(x=825,y=485)
def Seleccionar(self,value):
global VarCambio
VarSelect=value
print(VarSelect)
muestra=tk.Label(self,
textvariable=self.VarText,font=("Verdana",100,"bold"),bg="white")
if VarSelect==VarCambio:
muestra.config(fg="green")
muestra.place(x=w-1250,y=h-350)
self.VarText.set("OK!")
else :
muestra.config(fg="red")
muestra.place(x=w-1250,y=h-350)
self.VarText.set(" X ")
def Aleatorio(self):
global VarCambio
VarCambio=random.randint(1,7)
print(VarCambio)
self.VarText.set(" ")
self.SeleccionSeñal(VarCambio)
def SeleccionSeñal(self,value):
Invertir=[0 for i in range(4)]
48
Amplitud=[0 for i in range(5)]
if value==1:
ritmoCardiaco(56,"Evaluación",Invertir,Amplitud)
if value==2:
ritmoCardiaco(80,"Evaluación",Invertir,Amplitud)
if value==3:
ritmoCardiaco(140,"Evaluación",Invertir,Amplitud)
if value==4:
ritmoCardiaco(90,"Evaluación",Invertir,Amplitud)
if value==5:
ritmoCardiaco(230,"Evaluación",Invertir,Amplitud)
if value==6:
ritmoCardiaco(70,"Evaluación",Invertir,Amplitud)
if value==7:
Invertir.pop(0)
Invertir.insert(0,1)
ritmoCardiaco(118,"Evaluación",Invertir,Amplitud)
class CalibracionSeñal(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
AmplitudP=IntVar(value=0)
AmplitudT=IntVar(value=0)
AmplitudQ=IntVar(value=0)
AmplitudR=IntVar(value=0)
AmplitudS=IntVar(value=0)
InvertirP=IntVar(value=0)
InvertirT=IntVar(value=0)
InvertirQ=IntVar(value=0)
InvertirR=IntVar(value=0)
InvertirS=IntVar(value=0)
VarLPM=IntVar(value=0)
VarST=IntVar(value=0)
IntervaloQ_T=IntVar(value=0)
AmplitudT=IntVar(value=0)
can=tk.Canvas(self ,w=w,height=h,bg='AntiqueWhite1')
can.grid(column=0,row=0)
can.pack(fill=BOTH)
can.create_rectangle(50,70,500,130, fill="white")
can.create_text(w-1110,h-600,text="Mostrando
Señal",font=("Verdana",20,"bold"))
can.create_text(w-700,h-670,text="Configuración de Señal
Cardiaca",font=("Verdana",35,"bold"))
can.create_image(20,h-550,anchor=NW, image=configOnda)
can.create_text(w-150,h-
600,text="%",font=("Verdana",20,"bold"))
can.create_text(w-150,h-
560,text="%",font=("Verdana",20,"bold"))
can.create_text(w-150,h-
520,text="%",font=("Verdana",20,"bold"))
49
can.create_text(w-150,h-
480,text="%",font=("Verdana",20,"bold"))
can.create_text(w-150,h-
440,text="%",font=("Verdana",20,"bold"))
can.create_text(w-130,h-240,text="
LPM",font=("Verdana",20,"bold"))
can.create_text(w-400,h-600,text="Amplitud
P:",font=("Verdana",20,"bold"))
amplitudP = tk.Entry(self,
textvariable=AmplitudP,width=5).place(x=1150,y=90)
can.create_text(w-400,h-560,text="Amplitud
Q:",font=("Verdana",20,"bold"))
amplitudQ= tk.Entry(self,
textvariable=AmplitudQ,width=5).place(x=1150,y=130)
can.create_text(w-400,h-520,text="Amplitud
R:",font=("Verdana",20,"bold"))
amplitudR= tk.Entry(self,
textvariable=AmplitudR,width=5).place(x=1150,y=170)
can.create_text(w-400,h-480,text="Amplitud
S:",font=("Verdana",20,"bold"))
amplitudS= tk.Entry(self,
textvariable=AmplitudS,width=5).place(x=1150,y=210)
can.create_text(w-400,h-440,text="Amplitud
T:",font=("Verdana",20,"bold"))
amplitudT= tk.Entry(self,
textvariable=AmplitudT,width=5).place(x=1150,y=250)
can.create_text(w-400,h-400,text="Invertir
P:",font=("Verdana",20,"bold"))
invertirP= tk.Checkbutton(self, variable=InvertirP,
onvalue=True, offvalue=False,bg='AntiqueWhite1').place(x=1150,y=290)
#invertirP= tk.Radiobutton(self,variable=InvertirP,
value='On',bg='AntiqueWhite1').place(x=1150,y=290)
#invertirP= tk.Entry(self,
textvariable=InvertirP,width=5).place(x=1150,y=290)
can.create_text(w-400,h-360,text="Invertir
Q:",font=("Verdana",20,"bold"))
invertirQ= tk.Checkbutton(self, variable=InvertirQ,
onvalue=True, offvalue=False,bg='AntiqueWhite1').place(x=1150,y=330)
can.create_text(w-400,h-320,text="Invertir
S:",font=("Verdana",20,"bold"))
invertirS= tk.Checkbutton(self, variable=InvertirS,
onvalue=True, offvalue=False,bg='AntiqueWhite1').place(x=1150,y=370)
can.create_text(w-400,h-280,text="Invertir
T:",font=("Verdana",20,"bold"))
invertirT= tk.Checkbutton(self, variable=InvertirT,
onvalue=True, offvalue=False,bg='AntiqueWhite1').place(x=1150,y=410)
can.create_text(w-400,h-240,text="Latidos por
Minuto:",font=("Verdana",20,"bold"))
varlpm = tk.Entry(self,
textvariable=VarLPM,width=5).place(x=1150,y=450)
50
b1 = tk.Button(self,
text="Iniciar",font=("Verdana",15,"bold"),fg="black",
bg="AntiqueWhite1",image=botonArritmia,compound="center",
command= lambda:
self.MostrarGrafica(AmplitudP,AmplitudQ,AmplitudR,AmplitudS,AmplitudT,
InvertirP,InvertirQ,InvertirS,InvertirT,VarLPM)).place(x=1000,y=500)
can.pack()
def
MostrarGrafica(self,AmplitudP,AmplitudQ,AmplitudR,AmplitudS,AmplitudT,
InvertirP,InvertirQ,InvertirS,InvertirT,VarLPM):
Invertir=[]
Amplitud=[]
imprimir=1
Invertir.insert(0,InvertirP.get())
Invertir.insert(1,InvertirQ.get())
Invertir.insert(2,InvertirS.get())
Invertir.insert(3,InvertirT.get())
Amplitud.insert(0,AmplitudP.get())
Amplitud.insert(1,AmplitudQ.get())
Amplitud.insert(2,AmplitudR.get())
Amplitud.insert(3,AmplitudS.get())
Amplitud.insert(4,AmplitudT.get())
if(AmplitudP.get()<0 or AmplitudP.get()>100):
messagebox.showerror("ERROR","VALOR Amplitud
P="+str(AmplitudP.get())+"% FUERA DE RANGO")
imprimir=0
if(AmplitudQ.get()<0 or AmplitudQ.get()>100):
messagebox.showerror("ERROR","VALOR Amplitud
Q="+str(AmplitudQ.get())+"% FUERA DE RANGO")
imprimir=0
if(AmplitudR.get()<0 or AmplitudR.get()>100):
messagebox.showerror("ERROR","VALOR Amplitud
R="+str(AmplitudR.get())+"% FUERA DE RANGO")
imprimir=0
if(AmplitudS.get()<0 or AmplitudS.get()>100):
messagebox.showerror("ERROR","VALOR Amplitud
S="+str(AmplitudS.get())+"% FUERA DE RANGO")
imprimir=0
if(AmplitudT.get()<0 or AmplitudT.get()>100):
messagebox.showerror("ERROR","VALOR Amplitud
T="+str(AmplitudT.get())+"% FUERA DE RANGO")
imprimir=0
if(VarLPM.get()<1):
messagebox.showerror("ERROR","VALOR
"+str(VarLPM.get())+" LPM INCORRECTO")
imprimir=0
if(imprimir==1):
ritmoCardiaco(VarLPM.get(),"Grafica
Nueva",Invertir,Amplitud)
return
class MainView(tk.Frame):
51
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
P_Intro = Intro(self)
P_posicionElectrodos = PosicionElectrodos(self)
P_opcionesArritmias = OpcionesArritmias(self)
P_calibracionSeñal = CalibracionSeñal(self)
P_evaluacion=Evaluacion(self)
estructuraBoton = tk.Frame(self)
estructura = tk.Frame(self)
estructuraBoton.pack(side="top", fill="x", expand=False)
estructura.pack(side="top", fill="both", expand=True)
b1 = tk.Button(estructuraBoton, text="Posición de
Eléctrodos",font=("Verdana",10,"bold"),fg="white",
bg="white",image=botonSeleccion,compound="center",
command=P_posicionElectrodos.lift)
b2 = tk.Button(estructuraBoton, text="Opciones de
Patologías",font=("Verdana",10,"bold"),fg="white", bg="white",
image=botonSeleccion,compound="center",
command=P_opcionesArritmias.lift)
b3 = tk.Button(estructuraBoton, text="Evaluación de
Patologías",font=("Verdana",10,"bold"),fg="white", bg="white",
image=botonSeleccion,compound="center", command=P_evaluacion.lift)
b4 = tk.Button(estructuraBoton, text="Crear
Patología",font=("Verdana",10,"bold"),fg="white", bg="white",
image=botonSeleccion,compound="center",
command=P_calibracionSeñal.lift)
b1.pack(side="left")
b2.pack(side="left")
b3.pack(side="left")
b4.pack(side="left")
P_Intro.show()
if __name__ == "__main__":
root = tk.Tk()
#root.wm_geometry("1360x700")
root.title("Simulador ritmo cardiaco")
root.geometry(tamaño)
botonSeleccion=PhotoImage(file=direccion+"boton.png")
botonArritmia=PhotoImage(file=direccion+"botonArritmia.png")
botonEvaluacion=PhotoImage(file=direccion+"botonEvaluacion.png")
botonSalir=PhotoImage(file=direccion+"botonSalir.png")
52
visto=PhotoImage(file=direccion+"visto.png")
error=PhotoImage(file=direccion+"error.png")
fondo=PhotoImage(file=direccion+"fondo.png")
primeraImagen=PhotoImage(file=direccion+"primeraImagen.png")
posicionElectrodos=PhotoImage(file=direccion+"posicionElectrodos.png")
arritmiaCorazon=PhotoImage(file=direccion+"arritmiaCorazon.png")
configOnda=PhotoImage(file=direccion+"configOnda.png")
main = MainView(root)
main.pack()
53