UNIVERSIDAD A U T ~ N O M A METROPOLITANA

Anuncio
UNIVERSIDADA U T ~ N O M A
METROPOLITANA
-
I
v’
CIENCIAS BASICAS E INGENIERIA
ING. ELECTRONICA
PROYECTO DE INGENIERIA ELECTRONICA
ELECTROCARDIOGRAFO
/
Trimestre 99-I
Proyecto de inzeniería electrónica
INTRODUCCI~N:
Uno de las principales técnicas para el diagnostico de enfermedades cardiacas esta
basado en el electrocardiograma (ECG). El electrocardiógrafo o máquina de ECG permite
la deducción de muchos defectos eléctricos o mecánicos de el corazón mediante la
medición de los ECGs, las cuales son medidas potenciales en la superficie del cuerpo. Con
un electrocardiógrafo se puede determinar el ritmo cardiaco y otros parámetros cardiacos.
Existen tres técnicas básicas utilizadas en la electrocardiografia clínica. El más
común es el electrocardiograma clínico estándar. Este examen es aplicado en una clínica
física, en donde se toman 12 diferencias de potencial distintas, llamadas muestras ECG, las
cuales son tomadas de la superficie del cuerpo de un paciente descansando. Una segunda
aproximación utiliza otro conjunto de potenciales de la superficie del cuerpo, como
entradas a un modelo vectorial tridimensional de excitación cardiaca. Esto produce una
vista gráfica de la excitación del corazón, llamada vectocardiograma (VCG). Finalmente,
durante un lapso de tiempo se monitorea a los pacientes de cuidado intensivo o
ambulatorios, a quienes se les toma uno o dos ECGs, estos son observados para ver las
alteraciones del ritmo cardiaco. Esta aproximación se denomina Análisis de la Arritmia.
En conclusión, las tres técnicas básicas utilizadas en la electrocardiografia son:
1. El ECG clínico estándar (12 muestras)
2. VCG (3 muestras ortogonales)
3. ECG monitoreado (1 o 2 muestras).
Tan solo con la observación de las señales eléctricas de la superficie del cuerpo, los
cardiólogos pueden determinar el estado funcional del corazón. Pensando en el ECG
como una señal eléctrica, este varia conforme cambia el estado mecánico del corazón. El
estudio de la cardiología esta basado en la grabación de los ECGs de cientos de pacientes a
lo largo de los años y la observación de las relaciones entre varias formas de onda en la
señal y las diferentes anormalidades. De esta forma, la electrocardiografia es muy
empírica, basada en su mayoría en conocimiento experimental.
Una parte importante para la medición de los ECGs son los electrodos. Desde hace
tiempo, los electrodos metálicos fueron desarrollados para conectar eléctricamente al
cuerpo. Un electrolito, usualmente compuesto de una solución salina en un gel, forma la
interface eléctrica entre el electrodo metálico y la piel. En el cuerpo, las corrientes son
producidas por el movimiento de iones por donde esta un alambre, las corrientes dadas
por el movimiento de los electrones. Los sistemas de electrodos hacen la conversión de
corrientes ionicas a corrientes electrónicas. Los metales conductivos tales como la mezcla
de niquel-plata son utilizados como electrodos del ECG, pero estos tienen un problema.
Los dos electrodos necesarios para adquirir un ECG, junto con el electrolito y la parte
salada del torso, actúan como una batería. Un offset de dc ocurre a lo largo de los
electrodos, el cual puede ser tan grande o mayor que el pico de una señal ECG. Una capa
de doble carga (iones positivos y negativos separados por una distancia) ocurre en el
electrolito. El movimiento de el electrodo tal como el provocado por el movimiento del
paciente, altera esta doble capa y los cambios en el dc offset. Por lo que este potencial
offset es amplificado alrededor de 1000 veces a lo largo del ECG, pequeños cambios dan
un incremento a lo largo de la solución salina en la señal de salida. Un electrodo que se
Seminario de proyectos
Proyecto de ingeniería electrónica
comporta de esta manera es llamada electrodo polarizable y solamente se utiliza en
pacientes descansando.
El material más usado para los electrodos en estos días son de plata-plata clorado
(Ag-AgCl), de aquí se aproxima a un electrodo no polarizado. Este electrodo tiene un
potencial de offset muy pequeño. Tiene una capa de AgCl depositado en un plato de Ag.
Los iones del clorato se mueven en el cuerpo, en el electrolito y la capa de AgCl, donde
ellos los convierten en un flujo de electrones en el plato de Ag y en el alambre conectado.
Esta aproximación reduce el potencial offset de dc a un valor muy pequeño comparado
con el del pico de la señal del ECG. Así el movimiento del electrodo provoca un cambio
más pequeño en la amplificación del ECG que el del electrodo polarizable.
C~ndiciopdel
Generador cardiaco
equivalente
+ Potenciaks de la supedicie
del cuerpo
(Electmcardiogramas)
Dipolo
(Vector)
Figura 1.
La Figura 1 muestra como un modelo físico, llamado generador equivalente
cardiaco, puede se utilizado para representar la actividad eléctrica cardiaca. El modelo
físico popular es un dipolo de corriente que es representado matemáticamente como un
vector de variación en el tiempo el cual da el incremento para el vectocardiograma clínico
(VCG). Einthoven postuló que la excitación cardiaca puede ser modelada como un vector.
El también afirmó que los miembros son como conexiones directas a puntos en el torso tal
como el conjunto de flujos de corriente dentro del cuerpo como por el flujo del dipolo
fuente dentro de tórax y no fluye significantemente dentro dichos miembros. De esta
manera el visualizó una situación donde los electrodos podrían estar conectados a los
hombros y para un punto cercano al ombligo él no había restringido el uso de tinas de
solución salina. Einthoven dibujo un triángulo usando como vértices los hombros y el
ombligo; observó que los lados del triángulo tenían el mismo largo. Este triángulo, como
se muestra en la Figura 2, se conoce como el triángulo equilátero de Einthoven. Si el vector
representando la diferencia de la excitación cardiaca es conocido, entonces la diferencia de
potencial medida entre las dos hombros (es decir, dos vértices del triángulo) es
proporcional a la proyección de el vector en el lado de el triángulo el cual conecta los
hombros.
Seminario de proyectos
Proyecto de ingeniería electrónica
La Figura 2 muestra la relación entre el vector de Einthoven y cada uno de los tres
muestras de las derivaciones frontales (muestra I, I1 y 111). Los signos positivos muestran
cuales conexiones van a la entrada positiva del amplificador para cada muestra.
I
+
LL
Figura 2.
Una corriente dipolar es una fuente de corriente y un corriente invertida separado
por una distancia. Tal que cada dipolo tiene una magnitud y una dirección la cual cambia
a través de un pulso cardiaco, como las celdas en un corazón depolarizado, estas muestras
tienen la representación vectorial
donde p(t) es el vector cardiaco de variación en el tiempo, pi(t) son los componentes
ortogonales del vector también llamados muestras escalares; x, y, z son los vectores
unitarios en las direcciones x, y, z, respectivamente.
Un reconocido investigador del VCG en los ~ O ' S , llamado Frank, trazo un molde de
yeso del cuerpo de un sujeto como el que se muestra en la Figura 3, probado en agua, y
lleno de agua salada. El colocó una fuente dipolar compuesta de dos electrodos en una
barra, puesto en el torso del modelo a la altura del corazón. Una fuente de corriente
sustituía la corriente de los electrodos, los cuales entonces producían fluidos de corriente
en el conductor. Desde los electrodos empotrados en el yeso, Frank media la distribución
del potencial en la superficie del cuerpo como muchos puntos torácicos, de la fuente de
corriente. De las mediciones en cada estudio, encontró los coeficientes de transferencia
geométrica que relaciona la fuente dipolar con cada uno de los potenciales de la superficie
del cuerpo.
del torso
Figura 3.
Seminario de proyectos
Electrodo
rabado de la
Proyecto de ingeniería electrónica
Una vez que los coeficientes de transferencia son conocidos, el problema de avance
de la electrocardiografía puede ser resuelto por cualquier fuente de dipolo. La solución de
avance proporciona el potencial para cualquier punto arbitrario en la superficie del cuerpo
para dado dipolo cardiaco.
Vn=
tnx
px(t) + tny py(t) + f n z pz(t)
Esta solución para el avance muestra que el potencial Vn (t) (el ECG) para
cualquier punto n en la superficie del cuerpo esta dada por la suma linear de los
productos del conjunto de coeficientes de transferencia [hi]único para ese punto y los
correspondientes componentes del vector del dipolo ortogonal [pi(t)]. Los ECGs están
variando en el tiempo como sus componentes del dipolo, mientras los coeficientes de
transferencia solamente dependen de la geometría torácica y los homogéneos. Así para un
conjunto de k potenciales de la superficie (muestras), existe un conjunto de k ecuaciones
que pueden ser expresadas en un a matriz de la forma
V=TxP
donde V es un vector k x 1 que representa los potenciales variantes en el tiempo, T es una
matriz de coeficientes de transferencia de k x 3, los cuales están acotados y P es el vector
cardiaco de variación en el tiempo de 3 x 1.
Por supuesto que el vector cardiaco y los coeficientes de transferencia son
desconocidos para un caso particular. Por lo regular si tenemos una forma de calcular este
vector cardiaco, podremos usarlo en la solución del problema de avance y obtener el ECG
para cualquier lugar de la superficie del cuerpo. La aproximación para la solución de este
problema esta basado en un modelo físico del torso humano. El modelo proporciona los
coeficientes de transferencia, que relaciona los potenciales con muchos puntos de la
superficie del cuerpo, para el vector cardiaco. Con esta información, escogemos tres
muestras del ECG que suma las características intrínsecas del ECG anormal deseado para
simularlo. Entonces resolvemos el problema inverso para encontrar el vector del dipolo
cardiaco
P=BxV
donde B es una matriz de 3 x k de coeficientes de muestras que es directamente derivado
de invertir la matriz T de coeficientes de transferencia. Así, para los tres componentes del
vector cardiaco, hay tres ecuaciones lineales de la forma
Si escogemos k muestras de ECG de la superficie del cuerpo { vl(t), u2(t), ..., m(t) } para los
cuales los coeficientes de las muestras son conocidos del modelo físico del torso humano,
podemos resolver el problema inverso y calcular el vector cardiaco de la variación en el
tiempo. Una vez que tenemos estos componentes del dipolo, podemos solucionar el
problema de avance para calcular el ECG para cualquier punto de la superficie del cuerpo.
La Figura 4 muestra como un ECG es medido utilizando electrodos colocados
sobre la superficie del cuerpo y conectados a un instrumento amplificador (ECG). Para los
Seminario de proyectos
Provecto de ingeniería electrónica
puntos en el tiempo, que apuntan en la dirección del vector, que están hacía la parte
positiva del amplificador del electrodo conectado, la salida de la señal del ECG será
positiva. Si los puntos están hacía el electrodo negativo, el ECG será negativo. El
movimiento variante en el tiempo del vector cardiaco produce el ECG de la superficie del
cuerpo para un pulso cardiaco, con sus ondas características P y T, y su complejo QRS. En
la Figura 4 se muestra como podemos observar las diferencias de potencial entre los
miembros, como fuentes de voltaje ideal, donde se hace cada voltaje medible, utilizando
un instrumento amplificador con una impedancia muy alta. Es claro que estos tres voltajes
forman un ciclo cerrado medible. De la ley de voltajes de Kirchhoff, la suma de los voltajes
alrededor del ciclo es igual a cero. De esta forma
I1 - I - I11 = o
donde podemos reescribir esta ecuación para expresar cualquiera de los muestras en
términos de las otras dos.
I1 = I - I11
I = I1 - I11
I11 = I1 - I
Así es claro que uno de esos voltajes es completamente redundante; es posible medir
cualquiera de los otros dos y calcular el tercero. En efecto, eso es lo que las maquinas de
ECG hacen. Muchas maquinas miden las muestras I y 11, y calculan la muestra 111.
Figura 4.
Seminario de provectos
Proyecto de ingeniería electrónica
La primera instrumentación tuvo una ganancia inadecuada para la producción de
suficientes trazos de ECG para todos los sujetos, de esta manera la Figura 5 muestra la
manera de producir una mayor amplitud de las señales. En este caso, la señal del brazo
izquierdo, llamado derivacion aumentada aVL, es medido utilizando el promedio de los
potenciales de los otros dos miembros como una referencia.
Se puede analizar esta configuración utilizando teoría de circuitos común. Donde
el ciclo del fondo de la izquierda esta dado por
i x R + i x R - 11= O
O
i x R= II/2
(Ec. 1)
y para el ciclo del fondo de la derecha esta dado por
-i x R + I11 + aVL= O
aVL= i x R - I11
(Ec. 2)
sustituyendo el valor de la Ec. 1 en la Ec. 2 se obtiene
aVL= II/2 - III= (I1 - 2 x III)/2
I
RA
aVL
R
Figura 5.
Seminario de proyectos
Proyecto de ingeniería electrónica
Del ciclo de arriba al centro
11= I11 + I
sustituyendo se obtiene
aVL= (I11 + I - 2 x iii)/2= (I - 111)/2
Este es el voltaje equivalente de Thévenin para el muestra aumentada del aVL como un
promedio de los potenciales de las dos muestras frontales como una referencia. Es claro
que un aVL es una muestra redundante dado que puede ser expresado en términos de las
otras dos muestras. Las otras dos muestras aumentadas, un aVR y un aVF, similarmente
ambas pueden ser expresadas como funciones de las muestras I y 111. Así encontramos tres
muestras adicionales, las cuales pueden ser calculadas a partir de las muestras frontales y
así todas son redundantes sin nueva información real. De esta forma, dada la naturaleza
empírica de la electrocardiologia, sin embargo el físico necesita ver la apariencia de estas
muestras para facilitar el diagnóstico.
Este problema se resuelve vectorialmente mediante una muestra de derivación
aumentada en términos de dos de las derivaciones standard. Las derivaciones están
representadas por vectores orientados en las direcciones de los lados correspondientes al
triángulo, pero centrados al origen común. Para encontrar un aVL, como en este ejemplo,
se utilizan los vectores de los dos derivaciones para encontrar el vector resultante, en este
caso, el del lado brazo izquierdo. Se utiliza la muestra I como uno de los vectores para
sumar, dado que su sentido positivo esta conectado con el brazo izquierdo. El vector de la
muestra I11 se desprecia dado que su sentido es negativo en relación con el brazo
izquierdo. La muestra aVL es la mitad del valor de la suma de los vectores de las muestras
I y -111.
Se puede representar el conjunto completo de vectores representando las
derivaciones frontales. De esta descripción, se pueden encontrar rápidamente los tres
derivaciones aumentadas como funciones de las muestras frontales.
De esta forma tenemos el sistema básico de tres muestras utilizado en la
cardiología. El más popular es el que utiliza una aproximación de 1 2 muestras, el cual
define un conjunto de 12 diferencias de potencial que componen el ECG clínico estándar.
Un segundo conjunto de muestras designa las posiciones de los electrodos para las
grabación del VCG. Los sistemas de monitoreo, comúnmente analiza uno o los dos.
Se tienen 1 2 muestras del ECG clínico estándar que se monitorean. El amplificador
para esta instrumentación tiene un diseño especial para la electrocardiografia. En un
moderno microprocesador que hay en las máquinas para ECG, hay ocho amplificadores
similares, los cuales graban simultáneamente las muestras I, I1 y V1-V6; entonces calculan
las muestras las muestras 111, aVL, aVR y aVF para el reporte final.
El posicionamiento de los electrodos, para un sistema de muestras VCG Frank, es
el más popular, mundialmente, sistema de muestras de VCG.
Las aplicaciones de monitoreo no usan un estándar de las posiciones de los
electrodos, pero usualmente utiliza dos muestras. Dado que el principal acierto de estos
sistemas es el del reconocimiento de los pulsos cardiacos y el análisis del ritmo; los
electrodos son colocados donde la señal primaria del ECG tiene una amplitud de onda R
grande. Dado que la muestra I1 tiene una amplitud pico muy grande para muchos
pacientes, ésta muestra es recomendada frecuentemente como la primer opción de
Seminario de proyectos
Provecto de ingeniería electrónica
muestra primaria para muchos fabricantes. Una segunda muestra con diferentes
posiciones de los electrodos sirve como un respaldo, en el caso que la primer muestra
tenga problemas.
La regularmente se manejan tres anchos de banda utilizados en las distintas
aplicaciones en la electrocardiografia. El ancho de banda clínico utilizado para la
grabación de ECG estándar de 12 muestras es entre 0.05-100 Hz. Para aplicaciones de
monitoreo, tales como para los paciente de cuidado intensivo y para los pacientes
ambulatorios, el ancho de banda Es restringido a 0.5-50 Hz. En estos ambientes, las
perturbaciones del ritmo (las arritmias), son más importantes que los cambios
morfológicos en las formas de onda. De esta forma, el ancho de banda restringido, atenúa
el ruido de alta frecuencia provocado por las contracciones musculares (ruido EMG) y el
ruido de baja frecuencia provocado por el movimiento de los electrodos. Un tercer ancho
de banda utilizado para medir el ritmo cardiac0 (cardiotacometro) maximiza el radio de
señal de ruido para detectar el complejo QRS. El filtro permite el paso de las frecuencias
del complejo QRS, mientras rechaza el ruido, incluyendo las ondas que no son QRS, tales
como las ondas P y T. Este filtro ayuda a detectar los complejos QRS, pero distorsiona el
ECG, tanto que la apariencia de la señal filtrada no es clínicamente aceptable. Alguna otra
aplicación no muestra ampliamente el ancho de banda superior a los 500 Hz. Hay
pequeños eventos de frecuencia muy alta que pasen en ECG siguiendo al complejo QRS.
El pico de amplitud de una señal de ECG esta en el rango de 1 mV, y un
amplificador de ECG, comúnmente, tiene una ganancia de alrededor de 1,000, para dar
una señal pico del rango de 1 V.
Seminario de proyectos
Prwecto de inneniería
electrónica
J
O 0 0 0
0
0
0
0
-t
í;
- El ALGORITMO.
Dadas las características de la tarjeta de prueba, es necesario
implementar un programa que al adquirir el dato lo filtre, puesto que esta
tarjeta carece de un filtro que cumpla con tal fin.Esta ííltración nos permitirá
obtener datos más aproximados a los reales, ya que existen muchos factores
eléctricos que pueden alterar la señal original, éstos pueden ser tales como, la
tensión muscular, el tipo de eléctrodos, etc.
El algoritmo utilizado es el de detección del complejo QRS a tiempo real
de la señal de ECG. Éste realizará una detección basándose en análisis dígital
de pendientes, amplitud y ancho. En forma general, el algoritmo esta
compuesto de tres etapas principales: pasabandas, derivación e integración, las
cuales serán descritas a continuación.
Filtro pasa banda
El filtro pasa banda reducirá una detección falsa causada por las
interferencias diversas presentadas en una sena1 de ECG. Este filtrado permite
usar umbrales bajos, de ese modo se incrementara la sencitividad de la
deteccion. El algoritmo automáticamente ajustará umbrales y parametros para
adaptar a los cambios del ECG como la morfologia del QRS.
La primera etapa del pasa banda es el pasa bajas, que esta representado
por la ecuación
y(nT)=2y(nT-T)-y(nT-2T)+x(nT)-2x(nT-6T)+x(nT-l2T)
Ec. 1
donde la frecuencia de corte es aproximadamente 11 Hz y una ganancia de 36.
La implementación dentro del algoritmo real esta dada por la siguiente
función:
float P-Bajas(float dat)
{
int i;
float aux;
fx[l2]=dat;
aux=2*fy[l]-fy[O]+dat-2*fx[6]+fx[O];
for(i=O;i<l2;i++) fx[i]=fx[i+l];
fyP1 =fy[ll;
fy[l]=aux;
return(aux);
1
En el arreglo fx se representa a x(n) que es de tamaño 12 y que se va
actualizando conforme llega un dato, haciendo un recorrido de los valores que
ya se encontraban con anterioridad, para de esta manera aplicar la Ec. 1. Para el
caso de y(@, es representada por el arreglo fy, que es de tamaño 2, esto debido
a que en realidad siempre se utilizan dos celdas; una que trae el valor anterior
y otra que almacena el valor de la evaluación actual.
La segunda etapa es el filtro pasa altas que utiliza la siguiente ecuacion
de diferencias
y(nT)=32x(nT-16T)-[y(nT-T)+x(nT)-X(nT-32 T)]
Ec. 2
cuya frecuencia de corte es de 5Hz y una ganencia de 32.
La función que realiza esta ecuación dentro del algoritmo es la
siguiente:
float P-Altas(float datl)
{
float aux;
int t;
fxl[32] =datl;
aux=(32*fxl[16])-(yant+ datl-fxl[O]);
for(t=0$<32$++) fxl[t]=fxl[t+l];
yant=aux;
return( aux);
I
ésta recibe el valor generado por el pasa bajas y le aplica un análisis parecido a
la función que lo antecede. En este caso los arreglos que representan a x(n) y a
y(n), respectivamente son fxl y yant, para el arreglos de y(n) solo requiere de
una variable que almacene el resultado anterior. El resultado final es elevado al
cuadrado, para posteriormente ser el valor de entrada de la derivación.
Derivada
Despues del filtrado se obtiene inforrnacion de la pendiente, utilizando la
siguiente ecuación de diferencias:
y(nT)=(í/¿?T)[-x(nT-2 T)-2x(nT-T)+2x(nT+T)+x(nT+2T)]
Ec. 3
La función que representa este paso es la siguiente:
float Deriva(float dt)
{
float temp;
int i;
DRV[4] =dt;
temp=( (2*DRV[3])+DRV[4]-DRV[O]-(2*DRV[1]))*0.125;
for(i=O;i<4;i++) DRV[i]=DRV[i+l];
return(temp);
1
en este caso, cada punto que es derivado, es almacenado en el arreglo DRV,
que en la Ec. 3 es x(n), y que cada entrada a esta función va recorriendo los
valores, quedando en la posición 3 el último obtenido, el resultado final del
punto queda en temp.
Elevación al cuadrado
En este paso, la señal es elevada al cuadrado punto a punto; donde la
esta operacion esta representada por:
esto hace a todos los puntos positivos, una amplificación no lineal de la salida
y la derivada enfatiza frecuencias mas altas.
Integración
Este último paso es para la obtención de la característica de la forma de
onda en relacion con la pendiente de la onda, y se utilizará la siguiente
ecuacion de diferencias:
y(nT)=(I/N) [x(nT-(N- I ) T)+x(nT-(N-2)T)+...+x(nT)]
Ec. 5
donde N es el numero de muestras en el ancho de la ventana de integracion. La
funcion que realiza este calculo es la siguiente:
float Integra(float dt)
{
int i;
float al;
INTGINI =dt;
itg=itg-INTG[O]+dt;
a l =it@;
for(i=O;i<N;i++) INTG[i]=INTG[i+l];
return(a1);
1
en este caso el arreglo x(n) este representado por INT y el valor del resultado
queda en itg, que seria el resultado de la Ec. 5, y(n) .
El resto de las funciones agregadas, son para adecuar y graficar los
valores de los puntos obtenidos; posteriormente se realiza la descripición de
cada una de las funciones.
-LA TARJETA.
La tarjeta que se utilizó para la pruebas preliminares del software fue la
PCL-812PG, posteriormente se utilizará una de diseño propio, y que esta
descrita en la primer parte del reporte este proyecto.
Se utilizara la tarjeta PCL 812PG (Enhanced Multi-lab card) para hacer la
adquisicion y conversion A/D y D/A, mediante software se implementa el
filtro, consistente en un pasa banda, derivacion e integracion.
Desmipción de la tarjeta
La PCL-812PG es una tarjeta de adquisición de datos de alto
desempeño, velocidad y multi-funciones para IBM PC/XT/AT y
computadoras compatibles. las aplicaciones incluyen adquisición de datos,
procesos de control, evaluación automática y automatización. Como
características generales se pueden establecer las siguientes:
- 16 canales de entrada analógica.
- Un convertidor de aproximaciones sucesivas para convertir
entradas
analógicas. El máximo rango de muestre0 A/D es de 30KHZ en modo
DMA.
- Rangos de entrada analógica programable por software
Bipolar: +/ -5V,. +/ -2.5V,+/ -1.25V,+/-0.625V,+/-0.3125V.
La habilidad para transferir datos convertidos de A/D por un
programa de control, rutina de atención a interrupción o transferencia
por DMA.
- Un Timer/Counter programable INTEL 8253-5 que nos da pulsos a
un rango e 0.5 MHz a 35 minutos /pulso. La base de tiempo del timer
es de 2 MHz. Un canal contador de 16 bits es reservado para
aplicaciones de configuración.
-
Mapa
de direcciones del puerto de entrada/salida
La siguiente descripción proporciona la ubicación de cada registro y los
controladores relacionados a la dirección base:
Ubicación
I
I
I
I
Base + O
Base + 1
Base + 2
Base + 3
Base + 4
Base + 5
Base + 6
Base + 7
Base + 8
Base + 9
Base + 10
Base + 11
Base + 12
Base + 13
Base + 14
Base + 15
Lee
I
I
I
I
Contador O
Contador 1
Contador 2
No se utiliza
A/D Byte bajo
A/D Byte alto
D/I byte bajo
D/I bvte alto
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
Escribe
I
I
I
I
I
Contador O
Contador 1
Contador 2
Control del contador
CH1 byte bajo D/A
CH1 byte alto D/A
CH2 byte bajo D/A
CH2 bvte alto D/A
Limpia la solicitud de
interrupción
Control de la ganancia
MUX Control
Control de modo
Disparo del software A/D
Bvtebaio D/O
Bvtealto D/O
No se usa
/* Adquiere.c f
i
\
I * Proyecto de ingeniería electrónica I1
I* Prof. Donaciano Jiménez
I* Alumno: Adrián González Contreras
I* Matricula: 89227081
i * Programa de adquisición de una señal cardiaca, mediante el uso de
I * la tarjeta PCL-812PG
- -
\
*I
/
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#include <float.h>
#include <string.h>
/* Tipo de señal "/
#define cuadrada
#define seno
#define pulso
2
3
#define otra
#define adquirida
/* Tipos de impresión "/
#define normal
#define pasa-bandas
#define derivada
#define integral
#define FRECUEN
-- /
*I
*I
*I
*I
6
10
\
Indica en que momento grafica las frecuencias
/
*\
#define antes
#define despues
#define verdadero
#define falso
const base=Ox300;
const N=26;
3
4
8
9
*I
-/
\
Variables globales
-\
/
int xl, yl, y2, lugar, cont, ya= O, MAX, MIN, estuvo,frec[20];
int alto= O, frecuencia, tipo, imprime, segunda= 1, graficacion= O;
char buffer [50];
char el-archivo [30];
float fx[13],fy[2],fxl[33],DRV[6];
float itg,yant,vall;
float INTG[27];
double maximos[4];
FILE *paradeer;
-/
\
Definición de funciones
-\
double factor();
float senalo;
void detecta-max();
void mas-grande();
void MIN-MAX();
void portada();
void grafica();
void inic-var();
void h-proc();
void frecuencias();
void pinta-punto();
void grafica-frec();
int espera();
int IniciaGraficos();
/
/\
\
Función, que mediante POLLING, espera la llegada de
un dato.
int espera()
I
int msb,z;
msb= 1;
z= o;
while(8) {
msb =inportb(base+5);
z++;
iymsb<= 15 && z> 15)break;
1
return(msb);
I
/
.......................
\
. . . . . . . . . . . . . . . . . . . . . .
/
Función responsable de configurar los controladores de la
tarjeta de adquisición (PC Lab en este caso).
void activ-card()
{
int cntl,cnt2;
int lsb,msb;
cntl=Ox74; cnt2=OxB4;
outportb(base+lO,l); /* Establece el canal de comunicación
”/
outportb(base+9 ,O); /* Establece la ganancia
”/
outportb(base+ll,6); /* Establece el modo de operacitn (POLLING)”/
lsb=OxDO; msb=Ox7;
outportb(base+3,cnt2);/* Inicializa cuenta de contador 2
outportb(base+2,lsb); /* Parte baja del contador 2
outportb(base+2,msb); /* Parte alta del contador 2
”/
”/
”/
lsb=Ox2; msb=O;
outportb(base+3,cntl);/* Inicializa cuenta de contador 1
“/
outportb(base+l,lsb); /* Parte baja del contador 1
”/
outportb(base+l,msb); /* Parte alta del contador 1
”/
inportb(base+S); /* Esta ljnea despeja de “basura”el canal “/
1
\
/
I
F
Esta función es la primer proceso que se le aplica
al pasa banda, que es el filtro pasa bajas.
\
/
float P-Bajas(float dat)
I
int i;
float aux;
fx[l2]=dat;
aux=2*fy[l]-fy[O]+dat-2*fx[6]+fx[O];
for(i=O;i42;i++) fx[i]=fx[i+l];
fYto1=fY[lI;
fy[l]=aux;
return(aux);
1
/"""""""""""""""""""""""*
\
La función del filtro pasa altas, recibe el valor generado por
el filtro pasa bajas, con lo que se complementael filtro pasa
bandas.
\"""""""""""""""""""""""""*
float P-Altas(fl0at datl)
{
float aux;
int t;
/
fx1[32]=datl;
aux=(32*fxl[16])-(yant+datl-fxl [O]);
for(t=O;t<32;t++)fxl[t]=fxl[t+l];
yant=aux;
return(aux);
1
/""""""""""""""""""""""*
\
\""""""""""""""""""""""*
/
Esta función obtiene la derivada del dato adquirido, con lo que
se van "limando" los valores de la sedal.
float Deriva(float dt)
{
float temp;
int k
DRV [4]=dt;
temp=((2*DRV[3])+DRV[4]-DRV[O]-(2*DRV[l]))r).125;
for(i=O;i<4;i++) DRV[i]=DRV[i+l];
retum(temp);
1
/""""""""""""""""""""""""*
\
\"""""""""""""""""""""""""*
/
Esta función integra el valor del dato, recibe el valor generado
por la función deriva.
float Integra(float dt)
I
int i;
float al;
INTG[N]=dt;
itg=itg-INTG[O] +dt;
al=itg/N;
for(i=O;iCN;i++) INTG[i]=INTG[i+l];
retum(a1);
1
/””””””””””””””””*
\
\””””””””””””””””*
/
Esta función grafica los datos adquiridos.
void grafica(void)
{
float dato,aux,drv,integ;
int x,y,i,MSB,LSB,linea=500;
xl= getmaxx0-8;
yl=(getmaxyO/3);
y2= getmaxy()-100;
x=i= O;
lugar= o;
estuvo= faiso;
frecuencia= O;
do{
if(imprime== adquirida) {
MSB= espera();
LSB= inportb(base+4);
dato= (MSB*256+(LSB-2048))*(0.002441);
1
else dato=senal(x,tipo);
pinta-punto(normal,tipo,x,dato);
/* Es esta parte se le aplica un pasabandas ”/
aux= P-Altas(P-Bajas(dat0));
drv= Deriva(aux);
if(graficacion== despues) pintapunto( derivada,tipo,x,drv);
drv= pow(drv,2);
integ= Integra(drv)”factor(tipo);
pinta-punto(integral,tipo,x,integ);
if(estuvo== falso) detecta-max(integ,x);
else {
if(segunda== 2) frecuencia++;
d(integ> MAX-20) {
if(gr&cacion== antes) pinta-punto(FRECUEN,tipo, x, frecuencia);
if(graficacion== despues) &&o<= 20) frecuencias();
/”/
nosound();
/”/
sound(800); delay(l0);
nosound();
segunda= 2;
sound@nea+=lO);
1
1
x+=l;
if(x>= xl){
sound(linea);
x=o;
clearviewport();
1
if(kbhit()) i= 1;
delay(2);
}while(+= O);
nosound();
if(graficacion== despues) grafica-fret();
if(tipo== pulso) fclose(para-leer);
getch0;
fin_procO;
void frecuencias()
{
if(frecuencia<= 100) return;
frec[alto]= frecuencia;
frecuencia= O;
segunda= 1;
alto+= 1;
I
/"""""""""""""""""""""""*
\
\"""""""""""""""""""""""*
/
Función que permite ajustar los valores de los puntos obtenidos,
para poderlos desplegar en la pantalla.
double fador(tipo-sed)
I
switch(tipo-sed) {
case pulso: return(O.00000006);
default return(1);
1
I
/"""""""""""""""""""""""*
\
\""""""""""""""""""""""*
/
En esta función se pueden ir seleccionando cada que determinada
cantidad de muestras se escoge un máximo, por ejemplo: cada dos
muestras se escoge uno y se almacena en la función "mas_grande".
void detecta-max(max-loc,cont)
double max-loc;
int cont;
I
if(cont%2== O) {
if(ya== O) {
maximos[lugar]= max-loc;
lugar++;
if(lugar== 4) ya= 1;
I
I
else
mas_grande(max-loc);
if(cont== 630) MIN-MAX();
1
.......................
\
Aquí se selecciona el rango donde puede caer un máximo,
quedando los valores entre MIN y MAX, que son los valores
finales.
.......................
void MINMAXO
/
int q;
MIN= maximos[3];
MAX= maximos[3];
for(q= O; q< 4; q++) [
iymaximos[q]> MAX) MAX- maximos[q];
if(maximos[q]< MIN) MIN= maximos[ql;
1
estuvo= verdadero;
1
\
. . . . . . . . . . . . . . . . . . . . . . . . .
Esta función recibe los datos y almacena los que son máximos de
la primera pantalla de muestras; posteriormente con estos máximos
locales se puede establecer donde estar n, aproximadamente los
máximos.
- - \
“*/
void mas-grande(e1em)
double elem;
I
int i; double temp;
for(+ 3; i>= O; i--) [
iymaximos[i]< elem) {
temp= maximos[i];
maximos[i]= elem;
elem= temp;
1
1
1
/”””””””””””””””*
\
\””””””””””””””*
/
Función que inicializa el modo gráfico.
int IniciaGraficos()
int gdriver=DETECT,gmode,errorcode;
detectgraph(&gdriver,&gmode);
initgraph(&gdriver,&gmode,””);
errorcode=graphresult();
if(errorcode!= @k)
{
printf(”\nErroren inicializacion de gr ficos”);
printf(n\n%s”,grapherrormsg(emorcode));
getch0;
~tulTl(0);
1
else return(1);
1
/"""""""""""""."
\
\"""""""""""""""
/
Aquí se despliega la pantalla inicial.
void portada()
{
cleardevice();
setcolor(L1GHTCYAN);
rectangle(0,32,getmaxx(),getmaxy()-32);
rectangle(420,4,getmaxx()-ó5,28);
rectangle(l0,getmaxy( )-28,getmaxx()-389,getmaxy()-5);
setfillssrle(l,4);
floodfill(l,l,LIGHTCYAN);
floodfill(1,getmaxy(),LIGHTCYAN);
settextstyle(SMALL-FONT,HORIZ-DIR,5);
outtextxy(20,getmaxy()-2O,"PULSE UNA TECLA PARA DETENERu);
setcolor(2);
outtextxy(430,12,"ADQUIRIENDODATOS");
setviewport(0,33,getmaxx(),getmaxy()-33,1);
clearviewport();
setcolor(WH1TE);
1
\
Despliega el final del proceso de adquisición e impresión de
resultados.
\""""""""""""""""""""""""*
void fin-proc()
{
settextstyle(l,O,l );
setcolor(WHlTE);
rectangle(getmaxx()-410,35,getmaxx()-ZS3,19);
/
settextstyle(SMALL-FONT,HORIZ-DIR,5);
outtextxy(getmaxx()-398,22, "PROCESO TERMINADO");
outtextxy(getmaxx()-305,40,
getchar();
I
"Pulse una tecla");
/""""""""""""""""""""""""*
\
\""""""""""""""""""""""m"""
/
Procedimiento donde, en función del tipo de señal que se va a simular,
se multiplica el dato adquirido por un factor que permita desplegarlo
en la pantalla.
Aquí se imprimen los tres distintos "procesos" a los que se someten
los datos.
void pinta-punto(func,clase,laX,laY)
int func,clase,laX;
float lay;
1
char buffy[6];
switch(func) {
case normal:
if(clase== pulso) putpixel(laX,5O-laY*O.O5,YELLOW);
if(clase== seno) putpixel(laX,6O-laY~O,YELLOW);
if(Clase== cuadrada) putpixel(laX,óO-laYY0,YELLOW);
break;
case pasabandas:
if(clase== pulso) putpixel(laX,120-IaY*O.~l,WHITE);
if(clase== seno) putpixel(laX,120-laY*O.O3,WHITE);
lyclase== cuadrada) putpixel(laX,12O-laY*O.O2,WHITE);
break;
case derivada:
if(clase== pulso) putpixel(laX,yl-laY*0.0008,RED);
if(clase== seno) putpixel(laX,200-laY*o.28,FED);
if(clase== cuadrada) putpixel(laX,200-1aY*O.O8,ñED);
break;
case integral:
@clase== pulso) putpixel(laX,y2-laY,GREEN);
if(cl&se==seno) putpixel(laX,390-iaY*O.007,GñEEN);
@clase== cuadrada) putpixel(laX,390-laY*0.0007,GREEN);
break;
case FRECUEN :
if(frecuencia<= 100) break;
memset(buffy, '\O', sizeof(buffy));
buffy[O]= I*';
itoa(frecuencia, &buffy[l], 10);
outtextxy(laX, y1,buffy);
frecuencia= O;
break;
/""""""""""""""""""""
SIMULA SEWALES
\
\"""""""""""""""""""*
/
Esta función permite simular las tres señales básicas:
cuadrada, seno y un pulso cardiac0 obtenido de un
archivo de texto.
float senal(punto,tipo-send)
int punto, tipo-senal;
{
double bien;
switch(tiposenal) {
case cuadrada:
II
if(punto<= 40
(punto> 80 && punt0<=120) I I
(punto>lóO && punt0<=200) I I
(punto>240 && punto<=280) I I
(punto>320 && punto<=360) I I
(punto>400 && punto<*o)
II
(punto>480 && punto<=520) I I
&& punto<=rn) I I
(punto~560
(punto>640 && punto<=óóO)) retum(5);
else return(-5);
case seno: retum(sin(punto*O.O)*5);
case pulso: retum(hart(punt0));
default: return(punt0);
I
1
/""""""""""""""""""""""*
\
\"""""""""""""""""""""""
/
Esta función lee un archivo donde se tiene almacenadauna seaal
cardiaca, y permitiendo asi simular una adquisición real.
int hart()
{
int bien, resultado;
if(ya== O)
bien= abre-arch();
if(bien) {
cleardevice();
exit(0);
1
1
fscanf(para-leer, "% i", &resultado);
return(resultado);
1
-/
\
-\
/
Función que abre la señal cardiaca.
int abredar&()
{
if((para-leer= fopen(e1-archivo, "rt"))== NULL) {
clearviewport();
memset(buffer, '\O',sizeoybuffer));
sprintf(buffer,"Err: no se encuentra el archivo % s para ledura",el-archivo);
outtextxy(15,200,buffer);
outtextxy(l5,210,"E1 archivo va a ser generado");
system("a:cambia.bat");
memset(buffer, '\O', sizeof(buffer));
sprintf(buffer,"Proceso terminado, intente de nuevo",el-archivo);
outtextxy(15,22O,buffer);
return(-1);
1
ya= 1;
\
Función donde se inicilizán los arreglos que contendrá n los
resultados de cada análisis.
\"""""""""""""""""""""""
void inic-varo
/
I
int i;
ya= O;
if(tipo== pulso) (
el-archivo[O]= '\O';
strncpy(el-archivo, "c:\\tc\\ecg.txt", 25);
1
for (i=O;i==13;i++) fx[i]=O;
for (i=O;i==2 ;i+fy[i]=O;
+)
for (i=O;i==33 ;i++) fxl[i]=O;
for(i=O;i==6 ;i++) DRV[i]=O;
for (i=O;i==N+l;i++)INTG[i]=O;
yant=itg=O.O;
cont=O;
vall=O;
1
/""""""""""""""""""""""
\
\"""""""""""""""""""""
/
Imprime una relación global de los datos adquiridos con sus
respectivas frecuencias.
void grafica_frec()
{
int ,i j, ana, antY, lax;
char *cadena, buff[4];
lf(alto< 1) retllm;
clearviewport();
setfiilstyle(1,DARKGRAY);
floodfiU(l,l,LIGHTCYAN);
line(35,30,35,350);
line(15,350,630,350);
for(i= 30; i>= O; i--) {
j= i % 5;
lf(J=- O) {
line(27,(i~0)+50,35,(i~O)+50);
/*
iyx<fjoo)
I
itoa(x+=lOO,cadena,lO);
"/
1
1
outtextxy(5,iq0-5,cadena);
else line(32,(iYO)+50,35,(ir0)+50);
for(i= O; i< 60;i++) {
j= i 99 5;
if(j== O) {
line((i90)+35,350,(i~O)+35,358);
/"/
itoa(i*5,cadena,lQ);
outtextxy((i~0)+35,3,cadena);
/"/
1
1
else line((iqO)+35,35O,(iqO)+35,353);
j= 83;
ana=antY= o;
for(+ O; i<= alto I I alto<= 20; i++) {
memset(buff, '\O',sizeoybuff));
iyi== alto) break;
laX=irO+j;
setcolor(GREEN);
itoa(frec[i], buff, 10);
outtextxy(laX,getmaxy()-free[i]+50, buff);
outtextxy(laX,getmaxy()-frec[i]+60,"*");
if(i> O && i<= alto) {
setcolor(RED);
line(antX,antY,laX+2,getmaxy()-frec[i] +óó);
1
antx= lax+2;
antY= getmaxy()-frec[i]+óó;
I
1
j+= 40;
.......................................
1*+*+ P R I N C I P A L +*+*+*+*+*+*+*+*I
.......................................
void main()
{
if(IniciaGraficos()) {
imprime= otra;
tipo= cuadrada;
graficacion= despues;
if(imprime== adquirida) adiv-card();
inic-varo;
portada0;
graficao;
closegraph();
I
Descargar