universidad autonoma metropolitana unidad iztapalapa

Anuncio
UNIVERSIDAD AUTONOMAMETROPOLITANA
UNIDAD IZTAPALAPA
'DIVISION
DE CIENCIAS
BASICAS
'LICENCIATURA
E INGENIERIA
EN INGENIERIA
BIOMEDICA
INSTRUMENTACION MEDICA ELECTRONICA
'PROCESAMIENTO DE UNA SEÑAL DE
FONOCARDIOGRAFIA EN TIEMPO REAL ASESOR :
Ing. Miguel Angel Peña Castillo
ALUMNO:
/
Juan Hernández Cervantes
México, D.F. , 1996.
..
i
UNIVERSID
AUTONOMA
ME ROPOLITANA
h
- PROCESAMIENTO DE UNA SEÑAL DE
FONOCARDIOGRAFIA EN TIEMPO REAL-
Vo. Bo.
f\
INTRODUCCION
Es común en la actualidad observar en los equipos médicos, va sea de diagnóstico
o de terapia, lapresencia de dispositivos electrónicos y dispositivos de potencia
que permiten ser integrados para lograr métodos de control de procesos, tanto
más precisos como más eficientes, los cuales hoy endía,con los avances enla
tecnología de dispositivos integrados, logran grandes velocidades de
procesamiento de información. Lo anterior permite hacer el control de todo un
proceso en diferentes faces, en muchos casos estos procesos se llevan a cabo en los
que conocemos como tiempo real. Con la ayuda de estas herramientas el desarrollo
del procesamiento digital de sefialese imágenes, hoy en día, existe unamplio
campo de aplicación en el área médica e industrial.
Como se menciona anteriormente, hoy podemos observar
equipos
como:
imágenes ultrasónicas en tiempo real , detección de frecuencia cardiaca por
ultrasonido, medición de parámetros de oximetría y, en general, aquellos equipos
que se relacionan con la medición de yarámetros en forma instantánea que son de
gran utilidad, ya que se puede determinar el diagnóstico o la terapia adecuada casi
en el momento, por lo tanto, el diagnóstico y/o terapia serán más precisos.
Dentro de la tecnología médica, la implementación de dispositivos que permitan al
usuario un mejor análisis de la información obtenida es de gran importancia. Sin
embargo, el diseño yeltipo de tecnología que se utilizará debe ser considerada;
puesto que, de esto depende una mejor obtención de resultados en condiciones
más confortables para el paciente y que a la vez el dispositivo cuente con todos los
medios necesario para su buen desempeiio.
La utilidad de las herramientas matemáticas para el procesamiento de señales es
importante, ya que permite que la información oculta en las señales fisiológicas,
como el electrocardiograma o fonocardiografía, sea posible
observarla
gráficamente o en forma numérica.
Aún existen aplicaciones en las cuales la utilidad de las herramientas matemáticas
del procesamiento de señales y surelación
con la tecnología de dispositivos
electrónicos, son de gran importancia, que, aplicadas al desarrollo de nuevas
técnicas de detección de parámetros médicos, siguen en desarrollo o estána
prueba. En al algunos casos de estos algoritmos, donde esta involucrado el ciclo
cardiaco, utilizan principalmentela detección del complejo QRS. Sin embargo,
como es de esperar se requiere la aplicación de electrodos para su detección.
En el presente trabajo se muestra un algoritmo de detección del ciclo cardiaco en
basealadetección
de picos generados por la presencia de ruidos cardiacos.
Cuando escuchamos con u n estetoscopio el coratdn
que
late,
se perciben
normalmente dos ruidos que podrían describirse con las sílabas "lub,dub; lub,dub;
lub,dub". El "Lub" es el primerruido cardiaco, y el "dub" esel segundo ruido
cardiaco. El primer ruido cardiaco es producido es producido por el cierre de las
válvulas AV (aurículo-ventriculares) cuando se contraen los ventrículos, v el
segundo ruido lo causa el cierre de la válvula aórtica y pulmonar alfinal de la
contracción. Entonces, la representación gráfica de estos ruidos se conoce como
fonocardiograma. La detención súbita del flujo retrógrado desde los ventrículos
hacialas auriculas crea vibración de la sangre y de las paredes cardiacas; estas
vibraciones se transmiten hacia la pared torácica y se escuchan como primer ruido.
Inmediatamente después que los ventrículos han descargado su sangre en el
sistema arterial, la relajación ventricular subsecuente permite que empiece a fluir
sangre de nuevo desde las arterias hacia los ventrículos, por lo tanto hace que se
y pulmonar. Estodesencadena también
cierren súbitamente lasválvulasaórtica
vibraciones, esta vez en la sangre v en las paredes de las arterias aorta y pulmonar
lo mismo que en los ventrículos. Esta vibraciones se transmiten hacialapared
torácica y se producen los ruidos que escuchamos.
Es importante mencionar que encada evento, relacionado con el ciclo cardiaco,
están involucrados otros eventos como: el ruido respiratorio, el movimiento
muscular y ruido exterior. Por lo tanto, el procesamiento de estas señales; implica
la eliminación de elementos indeseables, de tal forma que se logre lo mejor posible
el registro del evento deseado (En este caso el latido del corazón).
Entonces como primer paso es la detección de estos ruidos, el método que todos
conocemos es mediante un transductor de sonido (micrófono o bocina) y un
amplificador de instrumentación. Esto en principio no esta tan complicado y no es
la parte importante del trabajo (Esta parte será complementada con los dispositivos
existentes en el laboratorio). La tarea principal, es la conversión A/D de la señal de
ruido y la necesaria separación de los componentes presentes no deseados enla
misma; utilizando las herramientas antes mencionadas.
Todo el proceso que más adelante se describe, contiene la información acerca del
los dispositivos utilizados, una relación de las consideraciones del laspartes
principales configuradas, los procesos matemáticos utilizados y la importancia en
la partedel
proceso y, además la parte más importante, a juicio propio, la
detección de los picos que durante el proceso se manejan con dos criterios
importantes: la amplitud del pico y la distancia pico a pico. Todo esto se espera nos
de corno resultado el objetivo principal, el ciclo cardiaco.
la automatización
del
método
de
Con
el
presente
trabajo
se
busca
a registrosde
medicióndelciclocardiacofetalentiemporeal,enbase
fonocardiografía.
Esto
presenta
una
idea
que
pueda
sugerir
una
implementación
del
algoritmo
más
eficiente
para
esta
aplicación.
Anteriormente,cuandosedesarrollo
el método,fueaplicado
a registros
presentes en archivos, en base a las referencias se obtuvieron muy buenos
los datos
resultados. Sin embargo, la forma en como fueron manipulados
en ese caso fue utilizando estructuras
de listas. Respecto a este punto se
menciona la justificación del porque no se utilizó estemismométodode
la relaciónqueexisteentre
el
manejo de datosenestetrabajo.Además
y eldispositivo
que provee la
procesodedetección
del ciclocardiac0
información.
CONTENIDO
Sección I
I. 1.- Especificaciones de la tarjeta PC-LAB 812.
I. l . 1.- Convertidor A/D.
I. 1.2.- Contador/Temporizador Programable.
I. 1.3.- Canales de interrupción .
I. 1.4.- Especificaciones Generales.
I. 1.5.- Diagrama a Bloques de la Tarjeta.
I. 1.6.- Selección de la B a s e de direcciones.
I. 1.7.- Selección del con tador.
I. 1.8.- Selección de línea de interrupción(1RQ).
I. 1.9.- Estructura de Registros y Formato.
I. 1.9.1.- Mapeo de los puertos de entrada/salida (I/O).
1.1.9.2.-Registro de Datos en el modo A/D.
1.1.9.3.- Registro de selección del Canal de Conversión.
1.1.9.4.- Registro de Control de PCL-812.
I. 1.10.-El Intel 8253.
I. 1.10.1.- Escritura/Lectura al Contador y Registros de
Control.
1- 1
1-1
1-2
1-2
1-2
1-3
1-4
1-4
1-5
1-5
1-5
1-6
1-7
1-7
1-7
1-8
Sección I1
11.1.- Desarrollo de la interface PC-PCLAB.
11. l . 1.- Programación"de los Contadores (timer-S).
11.1.1.1.- Listado del programa que Configura la
Frecuencia de Muestreo.
11.1.2.- Habilitación del vector de interrupción.
11.1.3.- Transferencia de datos a la memoria.
2- 1
2-2
2-2
2-4
2-1 1
Sección I11
111.1.- Diagrama a Bloques del Algoritmo.
3- 1
Sección IV
IV. 1.- Desarrollo del sofware.
IV. l . 1.- Módulos del Algoritmo.
IV. l . 1 .-1Búsqueda por Amplitud.
IV. l . 1.2- Búsqueda por Distancia entre Picos.
4- 1
4-29
4-29
4-34
Sección V
V.1.- Gráficas de Respuesta de los Filtros.
5-1
Sección VI
V.1.- Manual de usuario.
6- 1
Sección VI1
OBSERVACIONES.
COMENTARIOS.
CONCLUSIONES.
Anexo
Bibliografia
7-1
7-2
7-3
1 - 1
I. 1.- Especificaciones de la Tarjeta PC-LAB
812
La tarjeta PCL-812 es de alto desempeño, alta
velocidad y con múltiples
las
funcionesdeadquisicióndedatosparaIBMPC/XT/AT.Dentrode
aplicacionesmáscomunesincluye
la adquisicióndedatos,procesos
de
control, pruebas automáticas y automatización por factores.
Especificaciones importantes:
I.1.1.- Convertidor A/D
Canales :
bits.
16 canales.
12
Resolución:
RangodeVoltaje:
+ / - lOV, + / - 5 v , + / - 2 v , + / - 1v.
Todos los rangos de entrada son seleccionables por
interruptores.
Protección contra sobre
voltaje:
Rango
continuo
de
+/ - 3 0 V máximo.
Tipo
de
conversión:
Aproximaciones
sucesivas.
i
Modelo del convertidor: HADC574Z
Velocidad de
conversión:
30KHz máximo.
Precisión:
0.015 Yo de la lectura + / - 1 bit.
Linealidad:
+ / - 1 bit.
Modo de
disparo:
Disparo
por
software,
contador
programable
incluido en la tarjeta o disparador externo
(pulso externo).
Transferencia de datos: Controlado por programa (poleo), controlado por
interrupción o transferencia por DMA.
Disparo
externo:
Compatible
con
TTL.
1-2
I. 1.2.- Contador/Temporizador Programable
Dispositivo:
INTEL 8 2 5 3 - 5 .
Contadores:
3 canales, 16 canales
bits.
2 permanentemente
conectados a u n reloj de 2MHz como contador
programable, 1 canal libre para aplicación del
usuario.
Compuerta de entrada: Compatible con TTL/DTL/CMOS.
B a s e de tiempo:
2MHz.
Rango de frecuencia
programable:
35 minutos/pulso
hasta
0.5MHz.
I. 1.3.- Canales de interrupción
Nivel:
IRQ 2 a 7 , seleccionable
puentes
por
%
Habilitación:
Vía
de
registro
de
control
(jumper's).
SO, S 1 y S 2 .
I. 1.4.- Especificaciones Generales
Consumodeenergía:
+ 5V @ 500mA, 1A máximo.
+ 12V @ 50mA, 1 O O r n A máximo.
-12V @ 1 4 d , 20rnA máximo.
Conector Entrada/Salida
( W ) :
entrada
puerto
Analógica/Digital.
20pin
para
de
B a s e de Direcciones
(I/ 0):
Requiere 16 direcciones
memoria
deconsecutivas.
La base de direcciones esta definida por
1-3
interruptores
tipo
DIP,
líneas
para
direccionamiento son: A8-A4.
de
Temperatura de Operación: O a +50 “C.
Temperatura de Almacenamiento: -20 a +65 “C.
Peso:
8.6 oz (242.89 gm).
1.1.5.- Diagrama a Bloques de la tarjeta
nnnnn ww
111SSY
2L(
ANA
“<CH
16 CHANNEL
SDIGLB END “<CH
O ANALOG
INPUT
1-4
I. 1.6- Selección de la Base de Direcciones
Nombre
del
interruptor :
sw1.
Muchos
dispositivos
periféricos
de
PC
y tarjetas
de
interface
son
Estos puertos utilizan
controladas a través de puertos de entrada salida.
un espacio de direcciones.
Labasededireccionesdelpuertodeentradasalidapara
la tarjeta PCL812 esseleccionableconinterruptorestipo
DIP. La PCL-812 requiere 16
direcciones
consecutivas.
Las
direcciones
validas
están
en
el rango
200 a 3F0, sinembargopuedenserutilizadasestas
Hexadecimalde
direcciones para otro dispositivo. A continuación se proporciona una tabla
de direcciones seleccionables.
Direcciones I / O
Posiciones de los Interruptores
Rango en
Hexadecimal
A9
1
2
A8
A6
A7
3
4
5
A5
A4
O
O
O
1
1
O
1
O
(fijo)
200-20F
2 10-2 1F
220-22F'
300-30F3
3FO-3FF
1
O
1
O
1 %
O
1 220-23FO
1
1
1
1
I. 1.7.- Selección del contador
Puente selector( Jumper ) : JP2
I NT
El
EXT
O .
CLK
Especificada por fabricante.
' Base de direcciones utilizada .
O
O
O
O
O
O
O
O
O
1
1
O
1
1
O
1
1-5
1.1.8.- Selección de Línea de Interrupción (IRQ)
Puente selector : JP4
2
3
4
5
6
O
O
O
O
O
O
O
O
O
O
7
O
**
X
[
*
* Determina.da por fabricante.
** Seleccionada por usuario.
1.1.9.- Estructuras de Registros y Formato
1.1.9.1.- Mapeo de los puertos de entrada /salida (I/O)
La siguiente tabla muestra la localización de cada registro y el control de la
base de direcciones, y el uso de esta.
c
Localización
Lectura
Escritura
B a s e +O
Contador O
Contador O
B a s e +1
Contador 1
Contador 1
Base +2
Contador 2
Contador 2
B a s e +3
N/U
Control de contador
B a s e +4
A/D byte bajo
CH1 D/A byte bajo
B a s e +5
A/D byte alto
CH 1 D/A byte alto
B a s e +6
D/I byte bajo
CH2 D / A byte bajo
B a s e +7
D / I byte alto
CH2 D/A byte alto
1 - 6
Base +8
N/U
B a s e +9
N/U
B a s e +10
N/U
B a s e +11
N/U
B a s e +12
N/U
Base +13
N/U
B a s e +14
N/U
B a s e + 15
N/U
deAviso
atención
de
interrupción
(Clear interrupt request)
N/U
MUX
(selección del canal de
conversión)
PCL-8
Control
de
12
(habilitación de línea de
interrupción)
modo Selección
de
transferencia de transferencia
de datos.
D/O byte bajo.
alto.
D / O byte
1.1.9.2.-Registros de Datos en el m o d o A / D
Los registro de datos usados por las direcciones Base +4 y Base +5.
Formato de datos:
l . A/D Byte bajo.
Base +4
D7
D6
D5
D4
D3
D2
Dl
A
AD
D7654321
ADO
2. A/D Byte alto.
Base +5
D7
D6
D5
D4
O
DO
D3
O
O
DRDY
AD11
AD10
AD9
D2
Dl
DO
AD8
AD 11 a ADO - Analógico a dato digital. ADO-AD7 e s el byte menos
significativo (LSB) y AD8-AD 11 e s el byte m á s significativo (MSB) de el dato convertido. Como se había mencionado anteriormente la resolución del convertido e s
de 12 bits distribuidos en dos registros.
DRDY
- Señaldedatoconvertido.
O: Datoleído, 1 : Datono
leído. Al momento de leer el registro (Base +5) este
bit debe ser puesto a cero o limpiado.
1 - 7
Al unir el resultado de ambos registros, además de limpiar el bit
dato final es el valor de conversión A/D.
DRDY, el
1.1.9.3.-Registro de selección de Canal de Conversión
Este registro e s solo de escritura usando
la base de direcciones Base+lO.
El multiplexor (MUX)cambia a un nuevo canal de conversión cuando se
escribe sobre este registro.
Formato:
Base +10
D 7 D2
D3
D4
D5
D6
X
x
DI
x
x
CL3
- Númerode canal de conversión
CLO - CL3
CL2
CL1
DO
CLO
A/D.
1.1.9.4.-Registro de Control de PCL-812
El registro de control de PCL-812; es un registro de solo escritura y usa la
dirección
Base
“-1l . Este
registro
provee información
del
modo
de
operación de la PCL-8 12.
Formato:
Base + 1 1
D4
D3
D6
D5
D7
PCL-8 12 CNTL
status
X
x
x
x
X
D2
Dl
DO
S2
S1
so
Bajo las siguientes condiciones internas de disparo:
S2 S1
so
o
O
O
0
0
0
1
0
1
1
1
1
: Software
deshabilitado.
: Habilitación
de
disparo
solo
por
software.
: Habilitación
de
disparo
usando
transferencia
por DMA solamente.
: Habilitación
de
disparo
usando
transferencia
por
programa o transferencia por interrupción. Si es
transferencia por programa, el puente (jumper)
JP4 debe estar en la posición “X”, como se
menciona anteriormente.
1 - 8
I. 1.10.- El Intel 8253
La PCL-812 usa el INTEL 8 2 5 3 como un contador de intervalo programable
un
temporizador/contador
muy
común,
este
versión 5. El 8253 es
16 bits.Cada
dispositivoconsistedetrescontadoresindependientesde
contador tiene un reloj
de entrada, la compuerta de control y una salida.
Estos pueden ser programados con cuentas desde 2 hasta 65535.
La máxima frecuencia del reloj de entrada es de 4MHz para la versión 5 del
8 2 5 3 . La PCL-812 contiene un oscilador de 2MHz de frecuencia
a través
de un cristal oscilador.
Los contadores 1 y 2 estan conectados en cascada y operan como divisores
defrecuencia(configuracióndivisor
fijo). La entradadelcontador 2 esta
conectada al reloj de frecuencia de 2 M H z y la salida de este esta conectada
a laentradadelcontador
1 . Lasalidadelcontador
1 estaconfigurada
internamente como el pulso de disparo del convertidor A/D.El contador O
no esta reservado para
la PCL-812 en cualquier uso interno,
y su acceso
e s a través de conector 5.
I. 1.10.1.-Escritura/Lecturaal Contador y Registros de
El 8253 usa cuatro registros de control con direcciones Base
Base +2 y B a s e +3. La función de cada registro es:
Control
+O, Base + 1 ,
Base +O
Contador O
Lectura/Escritura
Base +1
Contador 1
Lectura/Escritura
B a s e +2
Contador 2
Lectura/
Escritura
Base+3Palabradecontroldelcontador
Desde que se empezó el
uso de una estructura de 16 bits en el contador
8253, cada lectura/escritura de un dato debe hacerse en dos partes en un
byte menos significativo y u n byte m á s significativo. Esto e s importante ya
que la operacióndelectura/escrituradependedeun
par dedatos y el
orden en que estos bytes son utilizados.
1-9
Formato de los Datos y el registro de control:
Base +3
D7 D6 D5 D4 D3 D2 D l
sc 1
SC 1& SCO
SCO
RW 1
RWO
M2
M1
M.O
DO
BUD
O
1
1
1
Y
1
1
O
1
O
1
1
x
1
1
O
-
VALORES
UTILIZADOS
76H
B6H
Bits de selección de contador.
sc 1
SCO
Contador
O
O
O
1
O
1
O
1
2
No existe
1
1
RW1 & RWO - Bits de selección de modo Lectura/Escritura.
RW 1
RWO
Operación
O
O
1
1
O
1:
O
1
Counter Latch
Lectura/Escritura LSB.
Lectura/Escritura MSB.
Lectura/Escritura primero LSB,
después MSB.
M2,M 1 y M 0
M1
M2
O
O
X
X
1
1
O
O
1
1
O
O
-
Selecciona el modo de operación.
M0
Modo
O
1
O
1
O
1
O123 4 5-
Interrupt
terminal
on
count.
Programable
one
shot.
Rate generator .
Square wave rate
generator.
Software
triggered
strobe.
Hardware triggered strobe.
I
1
BUD
-
- 10
Modo deconteo.
BUD
Tipo
O
1
Contador
binario
de
16 bits.
Contador
en
código
decimal
(BUD), contador
en
décadas.
4
2-1
PI. 1.- Desarrollo de la interface
PC-PCLAB
El hechodehaberimplementadomódulosenensambladoresdebido
a
que; es más sencillo de controlar la escritura en los registros de control.
la interface(ensamblador)una
vez implementadosson
Losmódulosde
ligadosalprogramaprincipaldeC,estosmódulosdeensambladorson
al programaprincipal y parahacerusode
consideradoscomoexternos
ellos
se definen
con
el
prefijo
EXTERN,
lo cual
permite
que
sean
importadosestosmódulosdeensambladoralprogramaprincipalenC
como se muestra en el siguiente bloque del listado.
extern void DIVIDE-FREC(void);
extern void ADQUISICION(void);
extern void REESTABLECE(void);
extern int indicador-coloca-ind;
Lasvariablesutilizadasenensambladorquepermitenelcontroldela
dependen
del
valor
que
se
les
asigne
en
el
programa
tarjeta y que
principal, estan definidas como variables globales en C, como se puede ver
en el parrafo del listado,
int
int
int
int
DIVISOR;
NUM-CANAL;
Muestras-Tot;
*BLOQUE-AUX-NULL;
a estasvariablesnoes
comosepuedeobservarenelpárrafoanterior,
necesario agregarles el prefijo EXTERN.
Paradefinir
las variablesenensambladorcuyosvalorseextraen
del
programa principal(implementaci6n en
C)
se
definen
con
el
prefijo
EXTERN, mientras que las variables y procedimientos que son utilizados
en módulos implementados en C se definen con el prefijo PUBLIC.
DATASEG
EXTRN
EXTRN
public
-BLOQUE-AUX:WORD
-Muestras-Tot:WORD
-indicador-coloca-ind
CODESEG
public -ADQUISICION
public"REESTABLECE
2-2
el párrafo anterior muestra un ejemplo de transferencia de parámetros
C a ensamblador y viceversa.
de
11.1.1.- Programación de los Contadores ( timer’s)
Es preciso
mencionar
que
la frecuencia
de
muestreo
elegida
sea
la
frecuencia de la señal que se obtenga
a la salida de los contadores, esta
puedesermedidaenel
pin 7 del timer;yaquedeestodependela
v a directamenterelacionada
precisióndelafrecuenciademuestreo,que
con el resultado de los datos capturados y de los cálculos.
La base de direcciones donde quedó instalada la tarjeta es la 300h.
11.1.1.1.- Listado del Programa que Configura la Frecuencia de
Muestre0
El siguientes segmento de programa define
:
una dirección hacia el puerto
SEL-C 1
SEL-C2
CONTl
CONT2
PAL-CONT
EQU
EQU
EQU
EQU
EQU
076h
Ob6h
0301h
0302h
0303h
C-GAN
MODO-TRANS
EQU
EQU
0309h
EXTRN
-DIVISOR:
WORD
030Bh
a las constantes que contiene
;Selecciona contador 1
;Selecciona contador 2
;Dirección del contador 1
;Dirección del contador 2
;Dirección de palabra de control
de 8 2 5 3
;Control de ganancia
;Controla el modo de
transferencia de datos.
;Variable
importada
desde
C , la cual
;tiene el valor del
;divisor de frecuencia que se utilizara
;para programar el timer.
CODESEG
public-DIVIDE-FREC
;Nombre de el procedimiento que
;será exportado a C.
2-3
PROC
SI push
push
push
push
push
DS push
-DIVIDE-FREC
DI
SS
cx
BX
sub
push
push
A
x
,
=
mov
mov
AX,@data
DS,AX
mov
ES , A X
mov
NEAR
;Guarda el ambiente
Ax
ES
AL,SEL-C 1
mov
DX,PAL-CONT
out
mov
DX,AL
AX,[-DIVISOR]
mov
DX,CONTl
;Localiza dirección del segmento de datos.
;Carga en DS la dirección del segmento
;de datos.
; Ahora la dirección del segmento de
; datos en ES.
;Recibe la palabra de control para
;contador # 1 en AL.
;Dirección del puerto a donde se envía
;la palabra de control.
;Envia palabra de control al registro.
;Toma el valor de divisor (valor calculado
;en C).
;Recibe dirección del contador ##l.
; Escribiendo en el puerto (programa frecuencia de muestre0 en
; contador # 1).
out
xchg
out
DX,AL
AL,AH
DX,AL
mov
AL,SEL-C2
mov
DX,PAL-CONT'
DX,AL
out
;Envía
palabra
puerto.
control
de
al
mov
mov
AX,[-DIVISOR]
DX,CONT2
;Envia byte más bajo de la palabra.
;Envía byte mas alto.
;Selecciona al contador numero#2.
;Toma la palabra de control.
;Toma el valor de divisor.
;Toma la dirección del contador2
2 - 4
out
xchg
out
mov
mov
out
mov
mov
out
mov
mov
out
DX,AL
;Envía el byte más bajopuerto.
al
AL,AH
DX,AL
; Envía el byte más
alto
DX,MODO-TRANS ; Avisa a la tarjeta cual es el modo de
; transferencia de
AL,OGh
; datos vía interrupción .
DX,AL
DX, C-GAN
; Selecciona el modo
de
ganancia
unitaria.
AL,OOh
DX,AL
DX,CAN-MUX
; Indica el canaldeconversión
inicial.
; Canal
de
cero
inicio
AL,OOh
DX,AL
POP
POP
POP
POP
POP
POP
POP
POP
POP
ES
Ax
DS
BP
BX
; restaura AMBIENTE
cx
SS
DI
SI
; Termina procedimiento
RET
a
ENDP -DIVIDE-FREC
; Fin de procedimiento.
END
11.1.2.- Habilitación del vector
;/ /Definición de la constates
0304h
EQU
BYTE-BAJO
BYTE-ALTO
C-GAN
EQU
CAN-MUX
MODO-TRANS
EQU
EQU
0305h
EQU
0309h
030Ah
030Bh
de interrupción
; Byte menos significativo del dato
; convertido
; Byte mas significativo del dato
; convertido
; Control de ganancia
; Controldelmultiplexor
para
; los canales
; Registrodel controldetransferencia
2-5
; de datos
Bandera-Int
Limp-Peticion
SERV-251
0308h
OFFh
250Bh
EQU
EQU
EQU
SERV-351
EQU
HABILITA-IRQ
DESHAB-IRQ
FIN-INTERRUP
;Registro para limpiar interrupción
; Aviso de interrupción atendida.
;Servicio de int2 1, para obtener
; vector
; Servicio
int2
de
1 , para
poner
; vector
; Habilita interrupción para IRQ3
; Deshabilita IRQ3
; Para indicar al 8 2 5 9 q u e y a s e
; atendió la interrupción
350Bh
EQU
EQU
EQU
OF7h
08h
20h
; / / Inicio del segmento de datos:
DATASEG
EXTRN
-BLOQUE-AUX:WORD
; Apuntador al inicio
del
bloque
; de direcciones donde
; se guardarán los datos.
EXTRN
-Muestras-Tot:WORD
; Contiene el numero
de
muestras
; que
se
están
capturando
por
bloque
public
-indicador-coloca-ind
-indicador-coloca-ind
-indicador-coloca
DW
DW
O
O
Old-HandSeg
DW
O
Old-HandOfs
Dato-Actual
DW
DW
O
O
Canal-Actual
DW
O
; Indice
para
el
control
de
los
; apuntadores que accesan
; al arreglo donde se guardan los
; datos.
; Inicializa
índice
el
; Contiene la dirección del
; bloque
; Segmento del vector
; original
; Offset del vector antiguo
; Apuntador de numero de
; datos adquiridos
; Apuntador a canales
; Inicia el segmento de código:
CODESEG
; Nombres de los procedimientos que serán exportados al modulo de "C".
I
2-6
public -ADQUISICION
public-REESTABLECE
; Inicia procedimientos:
PROC
push
push
push
push
push
push
push
mov
mov
mov
rnov
mov
mov
mov
-ADQUISICION
NEAR
SI
DI
SS
cx
; Guarda el ambiente
BX
Ax
ES
AX,@data
DS,AX
; Localiza
dirección
del
segmento
de
datos
; y carga
dicha
direccion
DS
en
i
y ES
ES,AX
AX,[-Muestras-Tot]
[Dato-Actual],AX
AX ,[-BLOQUE-AUX]
[indicador-coloca] , AX
; Obtiene el tamañodelbufer
y
; lo guarda
en la variable
; Obtiene la direcciondememoria
; donde
; seránguardadoslosdatos
; / / Colocación del nuevo vector de interrupción
push
mov
ES
AX,SERV_351
in t
21h
mov
[Old-HandSeg],ES
mov
[Old-HandOfs],BX
POP
push
mov
ES
DS
AX,SERV-251
; Salva registro
; Coloca en AH=35 que es el
; servicio de interrupción
; para obtener el vector de
; interrupción del COM2
; con dirección OBH y cuyo valor
; de dirección se coloca en
AL.
; Llamada a la interrupción 2l h del
; bios para obtener el vector.
; Salva el valor del segmento del
; vector antiguo
; Salva el offset del vector antiguo
; Guarda el registro
; Coloca en AH=25 que corresponde
; al servicio de interrupción
; para colocar un nuevo vector y en
2-7
; AL se coloca OBH que corresponde
; a la dirección de puerto COM2
; que es donde esta el dispositivo
; que generará la interrupción.
push
CS
POP
mov
DS
DX,offset -1SRQ
int
21h
POP
DS
hace
; Se
CS=DS que la dirección a
; donde v a a saltar cuando
; El dispositivo
interrumpa.
; Obtiene la dirección de la rutina
; de interrupción .
; Llamada a la interrupción 2 1 h
; para colocar al fin el nuevo
; vector de interrupción.
ds.; Restaura
; Programación del controlador de interrupciones 8259 y
; habilitación del IRQ3(línea de requerimiento de interrupción).
mov
in
and
DX,AL
out
sti
DX,02 1 h
AL,DX
AL,HABILITA-IRQ
mov
DX,MODO-TRANS
mov
DX,AL
out
AL,OGh
; Habilita la IRQ3
; Habilita la tarjeta
para
el
modo
; de transferencia de
datos
; los
(por interrupción ).
; Restaura ambiente
RET
ENDP -ADQUISICION
;/ / Procedimiento que reestablece el vector de interrupción original.
I
2 - 8
PROC -REESTABLECE NEAR
cli
push
push
push
push
push
push
ES
push
SI
DI
SS
CX
BX
AX
mov
AX,@data
mov
mov
DS , A X
ES ,AX
; Guarda el ambiente
; Localiza dirección del segmento
; de datos
; y carga dicha dirección enDS y ES
; / / REGRESAESTADOANTERIORDEL IRQ3
push DS
mov
AX,SERV-251
mov
DX,[Old-HandOfs]
mov
DS,[Old-HandSeg]
21h
int
POP
DS
mov
DX,02 1h
AL,DX
in
or
AL,DESHAB-IRQ
mov
DX,02 1h
DX,AL
out
; salva DS
; Pone el vectorinterrupción
de
; Toma
el
valor
del
offset
guardado
; Obtiene el valor
del
segmento
;. Deshabilita
IRQ3
; Restaura ambiente
sti
RET
ENDP "REESTABLECE
2-9
;/ /Inicio de rutina de atención
a interrupción
(servicio de interrupción)
PROC -1SRQ NEAR
cLI
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSH SI
PUSH DI
PUSHDS
PUSH ES
PUSHBP
PUSHF
mov AX,@data
mov DS,AX
mov ES,AX
; Guarda ambiente
; Localiza dirección del segmento dseg
; Carga en D S la dirección del
; segmento
; de datos al igual que en ES.
;Lee el registro donde se encuentrael
;dato convertido, que corresponde al
;byte mas significativo
;Lee el registro donde se encuentra el
;dato convertido, que correspondeal
;byte menos significativo
;Ajuste del valor leído,
and A X , O f f f h
;limpia bit DRDY.
;Autoincremento de DI al utilizar
cld
mov DI, [-indicador-coloca] ;Carga la dirección de apuntador a
; memoria en DI
stosw
;Guarda el dato leído en la dirección
;apuntada por DI
mov [~indicador~coloca],DI
inc
[-indicador-coloca-ind]
dec [Dato-Actual]
;Actualiza
numero
datos
de
jne TERMINA
mov DX,BYTE-ALTO
AL,DX
in
xchg AH,AL
mov
DX,BYTE-BAJO
AL,DX
in
mov ax,[-Muestras-Tot]
mov [Dato-Actual],ax
2-11
11.1.3.- Transferencia de datos a la memoria
Otra parte importante de la interface e s la transferencia de los datos
convertidos para completar el ciclo.
Para decidir que arreglo de memoria o el tipo de memoria que se v a a
utilizar,
se
consideran
los
siguientes
puntos:
1 ) Se
requiere
para
la
aplicaciónuntipodememoriaquepermitaunaccesomásrápido
a los
El tamañodememoria
datoscontansolomoverundesplazamiento;2)
debeservariable;
y 3) Debido a que
essonutilizadosmódulosen
ensamblador,serequiereun
tipodememoriaquepermitamanejarun
menor numero de variables en ensamblador. De manera que, el periodo en
que son almacenados los datos (en el servicio de interrupción) sea lo más
pequeñoposible.Estopermitereducireltiempodeacceso
a memoria.
Comparandocon unaestructuradedatos,
el acceso es más lento
a los
datosenmemoria
y al pasar unadireccióndememoria
al moduloen
ensamblador es más lento;
debido al procesodeconexiónenlosnodos,
en el caso de listas ligadas. De acuerdo a las consideraciones anteriores, se
utiliza u n arreglodememoriasecuencial
y de tamañovariable.Este
arreglosecuencialpermiteserutilizadocomo
un arreglo circular, lo cual
da como ventaja el que no es requerido solicitar más memoria cuando se
hallallenado el arregloenlaultimaposición,
el desplazamientoquees
a unadeterminadaposiciónsolose
utilizado paramoverelapuntador
inicializa para seguir capturando nuevos datos.
Este bloque de programa Irnuestra la forma de como es definido el espacio
de memoria ó arreglo:
void Aparta-Bloque(int MTOTAL)
BLOQUE-ASIG=(int *)malloc(2*MTOTAL);/ /Tamaño total de memoria.
if(BL0QUE-ASIG==NULL){printf("No
hay memoria");
getch();exit(1 ) ; }
apuntador-auxiliar=BLOQUE_AUX=BLOQUE_ASIG;
1
I
el modulomostradoanteriormentedevuelveunapuntador
al inicio del
al modulo de ensamblador,
y pormediode
la
bloque, el cual es enviado
suma de un índice es desplazado el apuntador a los diferentes espacios de
memoria que ha sido reservada previamente, cada
vez que es capturado
u n nuevo dato.
Es precisomencionarqueseutilizandosapuntadores,unopara
y otro
paraleerlos,entonces;unoesmanipuladoen
guardar
datos
ensambladorcuandosepresentaunainterrupciónyelotrocuandoes
leído un dato. Por lo tanto, podemos tratar con dos apuntadores uno de
.
. .,
.
. . .. - .
.
2
-
12
escritura y uno de lectura, que necesariamente deben ser controlados para
evitar
que
la
escritura
y lectura
sean
simultáneas.
Para
evitar
esto
podemos mostrar las siguiente líneas de un modulo en C ,
Real GraficaDatoNoPrc(int VERT-MAX,int cuenta-bufer)
Real escalador1 ,nuevoDato;
escalador 1 =4095/(Real)VERT-MAX;
/ /Factor de escalamiento
/ / Si esta activa la tarjeta espera que el apuntador de escritura sea mayor
/ / que el apuntador de lectura.
if(archiv0Tarjeta)
while(indicador-coloca-ind==cuel1ta_bufer);
nuevoDato=apuntador~auxiliar[cuenta~bufer];
/ /Lee el nuevo valor.
return(nuevoDato/escalador1 ) ; / /Retorna valor normalizado
\
con las variables
“indicador-coloca-ind”
y
“checa-mem”,
que
son
los
desplazamientosenelarreglo,esposibleevitarquelosapuntadoresse
traslapen y solo es necesario verificar que la varible “indicador-coloca-ind”
sea siempre mayor que “checa-mem” ; esto garantiza que el apuntador de
escritura siempre irá adelante del apuntador de lectura.
3-1
111.1 .-Diagrama a Bloques del Algoritmo
DERI\'ACION
__
PASA BANDA
20 A 30Mz
4
100 A 110Hz
B'llSCA
-PICOS
I
-
PROhlEDlA
-PICOS
I
ENCC'ENTRA
EN E L
PROhlEDlO I
4PICOS
PROhlEDIA
'PICOS I I Y
DESVIACIOS
I
m
INTERVALO
ENTRE
PICOS
I
L EXISTE INTERVALO
DE REFERENCIA?
Ti=r*IIVTERVALO
+b
'
MIDE E L
INTERVALO COK
hllNlXlA
DIFERENCIA
TlEhíPO
L EL
MEDIDO > Ti?
'
PICOS
DESTRO
DEL RANGO
I
IKTERVALO
ENTRE
PICOS
1SELECC;ONA E L
MEJOR
INTERVALO DE
ACUERDO A LA
REFERENCIA
I
I
Durante la ejecución del programa, la adquisición de los datos se presenta
con cada interrupción de la tarjeta cuando el convertidor tiene un nuevo
dato,bloqueandoelprocesoenelqueseencuentreactualmenteenla
ejecución del programa principal.
4- 1
IV. 1
.-Desarrollo del software
Enunaseñalderuidoobservamosunaseriedepicosaleatorios.En
el
caso deruidocardiaco,aunquelossonidoscardiacossepresentende
maneraregular,esdecircuandosepresentaunlatido;lospicosque
conformanelruidonosonregulares.Por
lo tanto,esnecesarioaplicar
algunos procesos para lograr remarcar los picos importantes del ruido del
picoÚnicoporlatido.
Enestesentido,
la
latido y procurarobtenerun
primera
etapa
del
algoritmo
se
busca
remarcar
los
ruidos,
con
las
siguientes consideraciones: filtrar la señal en el rango de frecuencias en el
la
cualseencuentrancadauno
delosruidos,estopermitetambién
posibilidadde
remarcarmas elprimero
o segundoruido,eliminarlas
componentes de frecuencia
indeseables,
en
el
monitoreo
de
sefiales
, como
ruido
de
línea,
fisiológicas
se
presentan
varias
interferencias
la segunda parte se
artefactos de movimiento, ruido respiratorio, etc.; en
registranloscambiosdeamplitud,con
lo cual sedeseadespreciarlos
picosqueesténdebajodeundeterminadoumbral,conundeterminado
numerodemuestraspodemoscalcularunrangodeamplitudesqueno
solo desprecian los picos por abajo del umbral, sino también los que sobre
pasan elnivel
superior;una
vez detectadoslospicosporun
nivelde
la deteccióndeposibleslatidos,
amplitud,secontinua
elprocesocon
midiendo la distancia entre picos.
Ahora se muestra el listado del programa principal en “C”:
Librerías utilizadas, estos archivos contienen el paquete de instrucciones
utilizadas en cada parte o modulo del programa principal, por ejemplo:
#include<stdio.h>
#include<conio.h>
#includecctype.h>
#include<string.h>
#include<dir. h>
#include<io.h>
#include<bios.h>
//Contiene
#include<dos.h>
#include<math.h>
#include<graphics.h>
., ..
: bioskeyo
/ /Contiene : sqrt()
/ /Contiene : outtextxyo,
setcolor(),
/ / line(), etc.. Toda instrucción que
/ / utiliza el modo gráfico.
4 - 2
Constantes que no se modifican durante
el programa, esta corresponden
de
principalmente a teclas especiales, las cuales se utilizan como medios
ejecucióndetareas,porejemplo:Llamada
a filtros,reinicializaciónde
variables,ademássedefineunalíneadeun
tipode
datos.Líneas del
programa
principal
donde
se
definen
como
macros(en
este
caso
son
constantes):
#define PINTA
#define F2
#define F3
#defineARRIBA
#define ABAJO
Ox3B00
Ox3COO
Ox3D00
0x4800
0x5000
#define Real
#define taps
#define memTotal
#define NUMPICOS
#define MUESTRAS
#define TOTCOMPARA
float
//Define
u n tipo
de
datos.
15
//Número
coeficientes
de
del
filtro.
20000
//Total
de
memoria
utilizada
para
/ /guardar los datos adquiridos.
3
/ /Número
picos
de
a detectar
/ /para comparar distancias.
15
/ /Número
de
picos
a detectar
antes
//de obtener promedios.
15
//Total
picos
depara
calcular
/ /el
primer
promedio
por
/ /amplitud.
i
MóduEos implementados en ensamblador:
extern void DIVIDE-FREC(void);
extern void ADQUISICION(void);
extern void REESTABLECE(void);
indicador-coloca-ind;
int
extern
(única
variable controlada
exclusivamente en ensamblador y que cambia con cada interrupción, es utilizada
principalmente para evitar que 'losapuntadores
de escritura y lecturase
traslapen, por lo tanto; en el programa principal solo se utiliza como un
indicador).
4-3
VariabZes que importantes para cargar los datos capturados en
y quesonutilizadastantoenensambladorcomoenprogramaprincipal
la memoria
“C”.
int DIVISOR,NUM-CANAL,Muestras-Tot,*BLOQUE-AUX=NULL;
Variables globales:
int checa-mem;
int contadorAmplitUno=O,contadorPicos=O,
contadorPosiciones=0,posicionesDetec[NUMPICOS],
distanciasDetec[MUESTRAS],contadorIntervalos=O;
int *BLOQUE-ASIG=NULL,*apuntador-auxiliar=NULL;
int frecuenciacanal=1 ,frecuenciaMuestreo= 1 ,canalGraficar= 1 ;
Real distanciaMaxima=O,distanciaMinima=O,datoProcesado=O;
Real primerRegistro=O,segundoRegistro=O;
Real umbralNivel=O,SDamplitud=O,amplitudPromedio
1 =O,
PrimAmplitud[TOTCOMPAP~],amplitudesDetec[MUESTRAS],
intervaloPromedio= 1 ,frecuenciaAprox=O,
variabilidadMuestras,SDintervalo,variabilidadHer~=O;
Arreglos donde son guardados los coeficientes de los filtros:
[taps];
Real taps1 [taps], taps2
Real arreglo1 [taps],arreglo2[taps],arreglo-fin[taps];
VariabZes quesonutilizadascomobanderasdeestadoqueindicanal
programa los proceso que son o no realizables:
int archivoTarjeta=O,corrimiento=O,existeReferencia;
Definición de los módulos “Prototipos de Procedimientos”, en los cuales se
aprecia el tipo de dato que devuelve y los parámetros que recibe:
int PresentaMensaje(int cual);
void CorregirCadena(char *cadena-a-mandar,int “bad-cad);
void ReservaMemoria(int MTOTAL);
void LiberaMemoria(v0id);
int CargaDatos(void);
void CargarBuffer(void);
void Canal(void);
. . . .
.
4 - 4
int CargaTaps(int cualFiltro);
int IniciaGraficos(void);
void MuestraMensaje(int bandera,int xx1 ,int yyl ,int xx2,int yy2,char
*mensaje,Real valor);
void AmbienteDeGraficacion(int XXMAX,int YYMAX);
void PresentaGrafica(v0id);
Real ProcesaDatos(void);
Real PrimerFiltro(int verifica-bufer);
Real FuncionDerivada(Rea1 *conjunto);
Real SegundoFiltro(Rea1 *arreglo-final);
Real BuscaPicos(Rea1 muestra-act);
Real PromedioPicos 1 (Real valor-pico-act);
intCorrimiento(Rea1muestra-anterior);
int SeleccionaIntervalo(int posicionActua1);
int GuardaDistancia(Rea1 intervActua1);
Real BuscaReferencia(int NuevaPosicion);
int CompruebaDistancia(int distanciaAnterior,int disTancia);
Real PromediaIntervalos(void);
Real CalculaFrecuencia(int distanciaEntrePicos);
Real VariabilidadDeFrec(Rea1 frecuencia);
Implementación de los módulos:
Módulo principal:
int main(void)
/ /Inicio de programa.. .
c h a r f;
PresentaMensaje(0);
do(
PresentaMensaje( 1 ) ;
f=getch();
switch(f){
case 'O':
PresentaMensaje(2);
LiberaMemoriaO;
Muestras-Tot=memTotal;
ReservaMemoria(memTotal+ 1 ) ;
archivoTarjeta=CargaDatos(); //Opción de adquisición de datos
break;
case ' 1 ':
{
' I
4-5
LimitesDeFrecuenciaO;
break;
case 2':
Canal();
IniciaGraficos();
PresentaGraficaO;
if(archivoTarjeta)REESTABLECE();
clrscr();
break;
case '3l:
LiberaMemoriaO;
PresentaMensaje(6);
delay( 1000);
break;
}while(fl='3');
return O;
/ /Fin
programa.
de
I
Módulo de menús y mensajes:
int PresentaMensaje(int cual)
c
clrscr();
textbackground(L1GHTBLUE);
textcolor(WH1TE);
switch (cual)
{
case O:
gotoxy( 13,2);cprintf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ~,");
gotoxy( 13,3); cprintf("O
"'7;
cprintf(""
gotoxy( 13,4);
O");
gotow( 13
>5);
cprintf("UNIVERS1DADAUTONOMA METROPOLITANA");
cprintf(""
gotoxy(13,6);
gotoxy(13,7);cprintf("O
IZTAPALAPA
cprintf(""
gotoxy(13,8);
"'7;
gotoxy( 13,9);cprintf("O
C. B. I.
""1;
gotoxy( 13,1O);cprintf(""
"7;
gotoxy( 13,ll);cprintf(" SEMINARIODEPROYECTOS
I1
");
gotoxy(13,12);cprintf(""
"");
go t o w;cprintf(""
( 13,13)
Titulo:
O");
gotoxy( 13,14);cprintf("PROCESAMIENTODESEYAL DE O " ) ;
O");
" ' l b
4 - 6
gotoxy( 13,15);cprintf("" -FCG- TIEMPO
EN REAL.
"'I;
gotoxy( 13,23);cprintf(""
""1;
gotoxy( 1 3 , 2 4 ) ; c p r i n t f ( " E : i Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í ~ " ) ;
textcolor(L1GHTGREEN);
.");
gotoxy(18,25);cprintf("Esperar..
delay(2000);
break;
case 1:
gotoxy(18,5);cprintf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ))");
cprintf(""
gotoxy(18,6);
""1;
cprintf(""
gotoxy(18,7);
"'7;
gotoxy(18,8);
cprintf(""
MENU
PRINCIPAL
""1;
gotoxy( 18,9);cprintf(""
""1;
gotoxy(1 8 , lO);cprintf(""
<O> CARGAR
DATOS
""1;
gotoxy(18,ll);cprintf(""
< 1> LIMITESDEFRECUENCIA
gotoxy(18,12);cprintf(""
<2>
MUESTRA
GRAFICA
O");
gotoxy( 18,13);cprintf(""
<3> TERMINAR
O");
gotoxy(18,14);cprintf(""
O");
gotoxy(18,15);cprintf(""
O");
gotoxy(18,16);cprintf(""
gotoxy( 18,17);cprintf("EÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'/4");
gotoxy(23,19);cprintf("Elija opcicn ");
break;
case 2:
gotoxy(18,6);cprintf("0ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ~)");
gotoxy(l8,7);
cprintf(""
CARGAR
LOS
DATOS
DE:
"") ;
cprintf(""
gotoxy( 18,8);
"'7;
gotoxy(cprintf(""
18,9);
l . ARCHIVO
""1;
gotoxy(18,10);cprintf(""
O");
gotoxy(
l);cprintf(""
18,l2.
TARJETA
O");
gotoxy( 18,12);cprintf(""
""1;
gotoxy(18,13);cprintf(""
""1;
gotoxy(1 8 , 1 4 ) ; c p r i n t f ( " E Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í ~ " ) ;
textcolor(L1GHTGREEN);
gotoxy(23,18);cprintf(" Elija opcicn : ");
break;
case 3:
gotoxy(14, 5);cprintf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ~~t');
gotoxy(14, 6); cprintf(""
"'7;
gotoxy(14, 7); cprintf("O
O");
gotoxy(14, 8);cprintf("RANGODE FRECUENCIA A DETECTAR");
( latidos/minuto )
O");
gotoxy(14, 9); cprintf(""
lO);cprintf(""
gotoxy(14,
"'7;
gotoxy( 14, 1l);cprintf(""
<A> 70 - 90.
"");
O");
O");
4 - 7
gotoxy( 14, 12);cprintf(""
<B> 1 2 0 - 1 8 0
"'7;
gotoxy( 14, 13);cprintf(""
DEFAULT
100-200.
"'7;
gotoxy( 14, 14);cprintf(""
"'7;
15);cprintf(""
gotoxy( 14,
""1;
g o t o y ( 14, 1 6 ) ; c p r i n t f ( " E Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í Í ~ ~ " ) ;
textcolor(L1GHTGREEN);
gotoxy(18,20);cprintf(" << OPCION >> ");
break;
case 4:
. ");
gotoxy( 18,1O);printf("Tarjeta Inicializada..
gotoxy( 18,12);printf("Interrupcion
habilitada.. .
Cargando datos...");
gotoxy( 18,16);printf("Oprima cualquier teclapara continuar.");
getche();
break;
case 6:
textbackground(BLACK);
textcolor(WH1TE);
cprintf("Termin0...");
delay(800);
clrscr();
break;
f
return O ;
1
J
Corregircadena,este módulocompruebacadaelementode
verifica si todos
son
números,
en
caso
de
que
la
cadena
contenga
elementos alfanuméricos regresa un cero en el apuntador bad-cad
uno si la cadena cumple solo con elementos numéricos.
la cadena y
y un
void CorregirCadena(char *cadena-a-mandar,int *bad-cad)
{
char recibe_caracter[20];
int i=O;
do
{
*badPCad= 1 ;
recibe-caracter[i]=cadena_a_mandar[i];
*bad-cad=(isdigit(cadena-a-mandar[i]));
if(*bad-cad==O )break;
' i
4-8
i++;
1
1
while(cadena-a-mandar[i]!='\xO');//Verifica hasta el elemento nulo.
de
es //que
final
el
la cadena.
PideFrecuencia, captura el valor de frecuencia de muestre0 deseado en
rango predefinido.
el
int PideFrecuencia(v0id)
{
char cadena-a-mandar[20],cadena-a-validar[20];
int bad-cad= 1 ;
clrscro;
do{
do{
gotoxy( 18,14);cprintf("Seleccionela frecuencia en Hz< 1-3000>:");
bad-cad= 1;
gotoxy( l8,70);
clreol();
gotoxy( 18,70);
gets(cadena-a-validar);
strcpy(cadena-a-mandar,cadena--a-validar);
CorregirCadena(cadena-a-mandar,&bad-cad);
}while(bad-cad==O);
frecuenciaCanal=(atoi(cadena-a-validar));
)while((frecuenciaCanal<=O,O)
I I (frecuenciaCana1>3000));
return(frecuenciaCana1);
}
RaizFrec,recibecomoparámetro
la frecuenciaporcanalseleccionada
previamente,
y regresa
valor
eldel
divisor
que
será
utilizado
posteriormente
registros
cada
los
uno
del
encontador
del
el fin dedividirlafrecuencia
programable(timer)correspondiente,con
máxima de 2MHz a la frecuencia seleccionada, tomando en cuenta que se
la justificaciónde
la raíz
tratadedoscontadoresencascada;estaes
la función. Cuando se menciona contador
cuadrada que se encuentra en
programable, se refiere a los contadores de la tarjeta PC-LAB.
I
.
4 - 9
int KaizFrec(int frecuenciacanal)
I
1
double Conversion;
int resultado;
frecuenciacanal = frecuenciacanal;
Conversion = (doub1e)frecuenciaCanal;
Conversion = 2000000/Conversion;//Frecuenciamáxima
2MHz
/ / Raíz
cuadrada.
Conversion = sqrt(Conversi0n);
Conversion = (int)Conversion;
/ / Conversión
de
resultado
en
//entero.
resultado = (int)Conversion;
return(resu1tado);
i
El hecho de convertir el resultado en un valor entero, es debido
a que no
se puede escribir en el registro de ocho bits del contador programable un
valor fraccionario, en el caso de que este error se presentara ocasionaría
el
un problema en la ejecución del programa que bloquearía el proceso, en
mejor de los casos.
LimitesDeFrecuencia, en relación a el número de muestras existentes en
entre cada latido; es necesario relacionar el numero de muestras máxima y
numerodemuestrasmínimasparaunrangodefrecuenciadelatidos
cardiacos definido; esto v a directamente relacionado, desde luego, con
la
frecuencia de muestreo.
int I.,imitesDeFrecuencia(void)
I
char c;
PresentaMensaje(3);
c =toupper(getch());
CalculaLimitesDeFrec(c);
return O ;
3
CalculaLimiteDeFrec,
hace
los cálculos
necesario
para
determinar
el
número de muestras limite que debe haber entre cada pico detectado. Esto
es necesario para determinar si el pico detectado e s o no un latido.
int CalculaLimitesDeFrec(charc)
{
4 - 10
Real maxima,minima;
switch(c)(
case 'A':/
/para adulto 70-90
minima=50;
maxima= 1 1 O ;
break;
/para feto 120- 180
case 'B':/
minima= 100;
maxima= 190;
break;
default :
minima= 100;
maxima=200;
break;
minima=(Real)minima/60.000;
//frecuencia
en
Hertz
/ /frecuenciaen
Hertz
minima= 1 / (Rea1)minima;
//En
segundos
minima=(Real)minima*frecuenciaMuestreo;
/ / [s]*[MUESTRAS/s]=[MUESTRAS]
maxima=(Real)maxima/60.000;
maxima= 1 /maxima;
segundos
//En
maxima=maxima*frecuenciaMuestreo;
/ / [s]*[MUESTRAS]=(MUESTRAS]
e
distanciaMaxima=minima;
distanciaMinima=maxima;
1
/ /Guarda los resultados en variables
/ /globales.
return O ;
Canal, captura el número de canal por el que van ha ser adquiridos los
de 16 canales),
datos. Una vez capturado el número de canal (de un total
es seleccionado directamente escribiendoal registro que se encuentra en la
dirección del puerto Ox030A, donde se encuentra el multiplexor.
void Canal(void)
if(archiv0Tarjeta)
4 - 11
canalGraficar=PideCanalGraficar();
outportb(0x030A,(unsignedchar)canalGraficar); / /Escribe en el. puerto
int PideCanalGraficar(v0id)
\
int NUMERO-CANAL,bad-cad=l;
char cadena-a-mandar[20],cadena-a-validar[20];
do(
do{
clrscr();
gotoy( 1,2);printf("Indique canal
a graficaw 1 - 16>:");
bad-cad= 1 ;
gotoxy(25,35);
clreol();
gotoxy(25,35);
gets(cadena-a-validar);
strcpy(cadena-a-mandar,cadena-a-validar);
CorregirCadena(cadena-a-mandar,&bad-cad);
)while(bad-cad==O);
NUMERO-CANAL=(atoi(cadena-a-validar)); //Convierte cadena a
1
/ / número.
)while(NUMERO-CANAL< 1 I I NUMERO-CANAL> 16);
return(NUMER0-CANAL- 1 ) ;
LiberaMemoria,
verifica
si existe u n bloque
de
memoria
ocupado
previamente, si e s así es liberado el espacio e inicializados los apuntadores
a nulo.
void LiberaMemoria(v0id)
{
if(BL0QUE-ASIG!=NULL)
free(BL0QUE-ASIG);
BLOQUE-AUX=apuntador-auxiliar=BLOQUE-ASIG=NULL;
1
1
4
- 12
ReservaMemoria,devuelveunapuntador
al iniciodelbloquedememoria
de tamaño MTOTAL, asignado para valores enteros. El valor de la dirección
de inicio es asignado
void ReservaMemoria(int MTOTAL)
BLOQUE-ASIG=(int *)malloc(2*MTOTAL);
if(BL0QUE-ASIG==NULL){printf("No
hay memoria");
getch();exit(1);)
apuntador-auxiliar=BLOQUE-AUX=BLOQUE-ASIG;
1
J
CargaDatos,estemódulopermiteque
el programatengadosfuentes
de
y la otra opción es
acceso a datos; una es por medio de datos en archivo
obtener datos habilitando la interrupción de la tarjeta.
int CargaDatos(void)
{ int entero,cambia=O;
char c;
PresentaMensaje(2);
c=getch();
switch(c){
case ' 1 ':
CargarBufferO;
break;
case '2':
entero=PideFrecuencia();
DIVISOR=RaizFrec(entero);
DIVID E-FREC () ;
ADQUISICION();
PresentaMensaje(4);
cambia= 1 ;
break;
1
frecuenciaMuestreo=frecuenciaCanal;
if(cambia== 1)return 1 ;
return O ;
1
ontador.
4 - 13
El módulodevuelvevalor
uno si losdatossonadquiridosmediante
la
tarjetaPC-LAB.
E n otrocaso,
si losdatossoncargadosmedianteun
archivo, la función regresa como resultado
un cero. Esta función además
de permitir
acceso
el
a los datos,
también
modifica
variable
la
"archivoTarjeta" , con la cualseejecutan
o dejandeejecutarsealgunas
instrucciones durante el proceso.
CargarBuffer, por medio de este módulo es posible el acceso
archivo.
a 10s datos en
void CargarBuffer(v0id)
i
int dato=O,auxIliar=O,Num-dat=O,Contador=O;
char archivo[70];
FILE *fp;
clrscr();
printf("\,n Nombre y ruta de acceso al archivo:\n ");
scanf("O/s",&archivo);
if(!(fp = fopen(archivo,"rb")))
c
printf(" \n\nNo se abrio el archivo...");
delay(800);
goto salir;
1
fseek(fp,OL,SEEK-SET);//Coloca
el apuntadoralinicio delarchivo.
frecuenciaCanal=getw(fp);//Lee la frecuencia de muestreo con que
//fueron capturados los datos.
Num-dat=getw(fp);
/ /Leeelnúmerototaldedatosdelarchivo.
fseek(fp,S,SEEK-SET);//Coloca
el apuntadorenlaposicióndonde
//comienza el bloque de datos.
Contador=auxIliar=O;
/ / Inicializa los contadores.
while(auxIliar<Num-dat-2)/ /Comienza carga de los datos
y verifica
//el final del archivo.
dato=getw(fp);
/ /Lecturadato.
del
apuntador-auxiliar[auxIliar]=dato;/ /Lo guarda en memoria.
el //Actualiza
++Contador;
4 - 14
if(Contador=-memTota1)goto termina; //Verifica si esta al final del
/ /arreglo de memoria.
++-auxiliar;
//Actualiza
contador.
1
termina:
//Etiqueta
de
final
de
carga
directa
de
archivo.
fseek(fp,OL,SEEK-END); //Coloca el apuntador de archivo al final de
//este.
fclose(fp);
archivo.
/ /Cierra
el
//Llenalosespacioslibresdelbloquedememoria,
si esqueexisten,es
//decir,quedanespacioslibres
si el nilmerodedatosesmenorque
el
/ /espacio de memoria asignado.
if(Num-dat-2<memTotal- 1)
c
for(auxIliar=0,Contador=Num~dat-3;
Contador<memTotal;Contador++,auxIliar++)
I
{
apuntador~auxiliar[Contador]=apuntador~auxiliar[auxIliar];
if(auxIliar==Num~dat-2)auxIliar=O;
i
1
printf("\n\n\nLos datos ya fueron cargados en el bufer ... \I"');
printf("\n\n\n Oprima cuaquier tecla para continuar. \r");
salir:
getch(); / /Espera se oprimida cualquier tecla.
1
CargaTaps,estemódulocontieneloscoeficientesdelosfiltros.Cada
que es llamado, son cargados los valores en arreglos globales.
vez
int CargaTaps(int queFiltro)
i'
int guardaTaps;
Real tapsFiltro 1 [taps]=
{-2.108063075E-2,-3.9151573873-2,-6.97967747E-2,
-7.0825699043-2,7.662132192E-13,1.367956549E-1,
2.7502143323-1,3.3333333E-1,2.7502143323-1,
1.3679565493-1,7.662132 192E-13,"7.0825699043-2,
-6.979677473-2,-3.915157387E-2,-2.1080630753-2},
4 - 15
tapsFiltro2[taps]=
C2.315044242E-2,3.167428862E-2,-8.796018663E-13,
-1.14598374531 ,-2.003068499E1 ,-8.45443642
1E-2,
1.866614325E1,3.333333331,1.866614325E1,
-8.45443642
1E-2,-2.00306849931 ,-l.145983745E-1,
-8.796018663E-13,3.167428862E-2,2.315044242E-2),
tapsFiltro3(taps]=
(-2.4208468663-2,1.209850168E-2,6.97967747E-2,
9.4783274443-2,1.2379644
143-1,-2.499380982E1,
-6.602597445E-2,3.3333333E-1,-6.6025974453-2,
-2.49938098231 ,-1.2379644
14E1,9.478327444E-2,
6.97967747E-2,-1.209850168E-2,-2.420846866E-2),
tapsFiltro4[taps]=
(2.4208463663-2,-1.209850168E-2,-6.97967747E-2,
9.478327444E-2,1.237964414E-1 ,-2.499380982E1,
-6.602597444E-2,3.3333333E-1,-6.602597444E-2,
-2.499380982E1,1.2379644
1431,9.478327444E-2,
-6.979677473-2,-1.209850
168E-2,2.420846366E-2},
tapsFiltro5[taps]=
(-2.315044242E-2,3.167428862E-2,-1.466003111E-12,
- 1.1459837453-1,2.003068499E-1 ,-8.454436422E-2,
-1.866614325E-1,3.3333333E-l,-1.866614325E-l,
-8.454436422E-2,2.003068499E1,-1.14598374531,
- 1.4660031llE-l2,3.167428862E-2,-2.3150442423-2),
tapsFiltro6[taps]=
(9.3670739573-3,1
.go743
1079E-2,4.635808739E-2,
9.181312086E-2,1.485844147E-1,2.043135351E-1,
2.45060350531,2.6E1,2.45060350531,
2.043135351E-1,1.485844147E-1,9.181312086E-2,
4.635808739E-2,1
switch(queFi1tro)
1079E-2,9.367073957E-3;;
.go743
case O: //20-30Hz
con Frec. Muestreo de 300Hz
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps 1[guardaTaps]=tapsFiltr1o[guardaTaps];
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps2[guardaTaps]=tapsFiltro1 [guardaTaps];
break;
case 1: / /40-60Hzcon Frec. Muestreo de 300Hz
for(gua?daTaps=O;guardaTaps<taps;guardaTaps++)
taps1[guardaTaps]=tapsFiltro2[guardaTaps];
break;
I
4
-
16
case 2 : / /80-90Hzcon Frec. Muestreo de 300Hz
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps 1 [guardaTaps]=tapsFiltro3[guardaTaps];
break;
case 3: / / 100- 1 lOHz con Frec. Muestreo de 300Hz
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps1 [guardaTaps]=tapsFiltro4[guardaTaps];
break;
case 4: //20-30Hz
con Frec. Muestreo de 300Hz
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps 1 [guardaTaps]=tapsFiltro5[guardaTaps];
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps2[guardaTaps]=tapsFiltro5[guardaTaps];
break;
default: / /20-30Hz con Frec. Muestreo de 1OOOHz
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
taps 1 [guardaTaps]=tapsFiltro6[guardaTaps];
for(guardaTaps=O;guardaTaps<taps;guardaTaps++)
1
tapsZ[guardaTaps]=tapsFiltro6[guardaTaps];
break;
return O ;
Cada filtro fue diseñado para una determinada frecuencia de muestreo, en
base a losalgoritmosdeventanasdeHamming.
Sus coeficientesfueron
calculados
con
la
ayuda
del paquete DSPLAY, posteriormente
serán
mostradas sus curvasderespuestaenfrecuencia
y las diferenciascon
respecto a la frecuencia de muestreo.
MuestraMensaje, el siguiente módulo genera un mensaje en la pantalla de
gráficos, con el que se muestran principalmente resultados de los cálculos
realizados durante el proceso
y cada vez que es detectado un nuevo pico.
Recibe como parámetro una variable “bandera”, que indica si el mensaje v a
ha ser borrado o restablecido, con tan solo cambiar
el color de la fuente,
recibe las coordenadas donde v a ha ser colocado el mensaje “ x x l ,yy 1 ,xx2
& yy2”; obtienelacadena
que contieneelmensaje“mensaje”
y esta
definida como un apuntador “mensaje”; y por último el valor
o resultado
que v a a desplegar.
void MuestraMensaje(int bandera,intxxl ,int yy1,int xx2,int yy2,char
4 - 17
*mensaje,Real
i
char
valor)
*numero-calculado=NULL;
settextjustify(T0P-TEXT,LEFT-TEXT);
settextstyle(SMALL~~FONT,HORIZ~DIR,4);
gcvt(va~or,5,numero-~alculado);
/ /Cambia número
flotante o Real una
//cadena.
setcolor(L1GHTGREEN);
outtextxy(xx1+15O,yy1+2O,mensaje);
if(bandera==,O)setcolor(LIGHTBLUE);
if(bandera==
l)setcolor(YELLOW);
outtextxy(xx2+150,yy2+20,numero~calculado);
i
J
MenuFiltro,
void
muestra la enpantalla
MenuFiltros(int
de
gráficos
la
opciones
de
filtrado.
xx,int
yy)
I
int
ajustex=xx-
160,ajustey=yy105;
setcolor(L1GHTGREEN);
outtextxy(ajustex,ajuste$," FILTROS PASA BANDA ");
setcolor(YELL0W);
outtextxy(ajustex,ajustey+16,"O> 20-30I-Iz");
outtextxy(ajustex,ajustey+30,"1> 40-50 Hz");
outtextxy(ajustex,ajustey+43,"2> 60-70Hz");
outtextxy(ajustex,ajustey+54,"3> 80-90Hz");
outtextxy(ajustex,ajustey+66,"4> 100-110Hz");
CargaTaps(getch0);
setcolor(L1GHTBLUE);
outtextxy(ajustex,ajustey,"FILTROS PASA BANDA ");
outtextxy(ajustex,ajustey+16," O> 20-30Hz");
outtextxy(ajustex,ajustey+30,"1> 40-50Hz");
outtextxy(ajustex,ajustey+43,"2> 60-70Hz");
outtextxy(ajustex,ajustey+54,"3> 80-90Hz");
outtextxy(ajustex,ajustey+66,"4> 100-1 1OHz");
,
GraficaDatoNoPrc, esta función realizaun calculo de normalizaciónde
datos, ya que los valores leídos
de un archivo, asícomo los valores que
4
-
18
entrega la tarjeta,estánenelrangode
O a 4095, y para poder ser
graficados es necesario normalizarlos a la resolución de la pantalla actual
en el plano vertical.
En este caso, es módulo es
utilizado paragráficarlosdatosqueaúnno
son procesados.
Real GraficaDatoNoPrc(int VERT-MAX,int cuenta-bufer)
i
Real escalador1 ,nuevoDato;
escalador 1 =4095/(Rea1)VERT”AX;
/ /Factor de escalamiento
/ / Si esta activa la tarjeta espera que el apuntador de escritura sea mayor
/ / que el apuntador de lectura.
if(archiv0Tarjeta)
while(indicador-coloca-ind==cuenta-bufer);
nuevoDato=apuntador~auxiliar[cuenta~bufer];
/ / Lee el nuevo valor
/ /convertido.
return(nuevoDato/escaladorl);//Retorna valor normalizado
Marcapicos,estafunciónes
el mismocasoque
la funciónanterior
la
diferenciaconsisteenquelosdatos
a gráficaryahansidoprocesados.
Estos datos son registrados en la variable “datoProcesado”.
Adem’ás, la función regresa u n valor uno si durante el proceso es detectado
un latido o un pico. En caso contrario regresa un cero.
Esta función recibe como parámetro el tamaño en altura de la pantalla de
graficación
actual
y apartir
de
este
valor
calcular el
valor
del
dato
normalizado.
Real MarcaPicos(int VERT-MAX)
{
int nuevaventana;
Real nuevoDato; / /Es utilizada como variable auxiliar.. .
//Actualiza los datos de los filtros durante un salto de pantalla
if(saltoDePantalla== 1 )
{//Conecta las pantallas
for(nuevaVentana=O;nuevaVentana<29;nuevaVentana++)
datoProcesado=ProcesaDatos();
4
-
19
saltoDePantalla=O; / /Fin de salto
datoProcesado=ProcesaDatos();
nuevoDato=datoProcesado;
//Llama a las funcionesde
/ /procesamiento; filtrado y derivada.
//Comprueba si esta en el rango.
if(datoProcesado>4096) datoProcesado=4096;
if(datoProcesado<O) datoProcesado=O;
//Normaliza el dato para el tamaño de pantalla.
datoProcesado=datoProcesado/(4095/(Real)VERT_MAX);
nuevoDato=BuscaPicos(nuevoDato);//Llama a las funciones de
/ /detección de picos.
/ /Empieza la detección de picos en base al criterio de
//distancia entre picos...
if(nuevoDato== 1 ) nuevoDato = SeleccionaIntervalo(checa-mem);
if(nuevoDato== 1 ) return 1 ;
return O ;
ProcesaDatos,
filtra
y deriva los datos
capturados
regresando
como
resultado el valorprocesado.Considerandoque
las características de los
filtros y la derivadas dependen de valores anteriores o mejor dicho utilizan
valores
anteriores,
es
posible
que
guardando
los
datos
anteriores
y
haciendouncorrimiento,paraagregar
el datoactual y desechandoun
Único dato,
lograr
mayor
velocidad
de
procesamiento.
Para
esto
es
ya fueron
necesarioutilizarunbanderaquenospermitasabercuando
calculados algunos datos que son reutilizables; esta variable que cambia
solo corrimientoses“corrimiento”,escero
cuandoesnecesariohacer
cuando no hay datos anteriores y uno en el caso contrario.
Real ProcesaDatos(void)
{
int checa-buf,bufer,d,f,g;
int tamano=memTotal;
bufer=checa-mem;
if(corrimiento==O) / /Bandera en el inicio.. .
4
- 20
I
for(f=taps- l;f>=O;f--,bufer--)
if(bufer<O)bufer=tamano-2;//Si esta en el limite inferior de bufer
checa-buf=bufer;
/ /tomaelvalorsuperior(bufer
circular).
for(g=3;g>=O;g--)
{
for(d=3;d>=O;d--,checa-buf--)
{if(checa~buf~O)checa~buf=tamano-2;
arreglo 1 [d]=PrimerFiltro(checa.-buf);)/
/Llamo 4 veces al filtro
arreglo2[g]=FuncionDerivada(arreglo1 ) ; //Derivada
1
arreglo-fin[f)=FuncionDerivada(arreglo2);/
/ Derivo por segunda
/
/ ocasión.
1
corrimiento= 1 ; //Cambia la bandera, pues ya existen datos anteriores.
1
)
else {
/ /Corrimientos.
for(f=O;f<taps;f++)
arreglo-fin[q=arreglo-fin[f+ 1 I ;
for(d=O;d<3;d++)
arreglo 1 [d]=arreglo1[d+ 11;
for(g=O;d<3;g++)
arreglo2[g]=arreglo2[g+l];
//Calcula los nuevos datos..
arreglo 1 [3]=PrimerFiltro(bufer);//Filtra dato actual
arreglo2 [3]=FuncionDerivada(arreglo
1 ) ; / /Derivada
/ Derivo por segunda
arreglo-fin[taps- l]=FuncionDerivada(arreglo2);/
/ /vez.
1
return(fabs(SegundoFiltro(arreg1o-fin)));/
/Filtro por segundavez
1
PrimerFiltro, la idea de utilizar dos funciones diferentes para
el filtrado e s
debido a que es posible la utilización de dos filtros distintos en cada una
de las etapas del proceso.
Real PrimerFiltro(int verifica-bufer)
{
4
- 21
mt y;
int tamano=memTotal;
Real arregloFiltrar[taps);
Real datoProcesado=O;
for(y=taps- 1 ;y>=O;y--,verifica-bufer--)
/ /Para lograr la idea de recorrer el búfer de manera circulary en
//sentido descendente, enel caso de que el apuntador haya leído la
//primera posición es necesario que la siguiente lectura la haga
/ /en la última posición del arreglo.
if(verifica_bufer<O) verifica-bufer=tamano-2;
/ /Lectura de un nuevo dato.
arregloFiltrar[yJ=apuntador~auxiliar[verifica_bufer];
1
/ /Realiza el filtrado . ..
for(y=O;y.=taps;y++)
datoProcesado=taps 1 [y]*(arregloFiltrar[taps-yl])+datoProcesado;
//Regresa el dato procesado.
return (datoProcesado);
t
J
<
FuncionDerivada, ca1cul.a la tercera derivada por método de aproximación
de derivadas. Recibe como para metro un apuntador al arreglo donde se
encuentran los datos previamente filtrados.
Real FuncionDerivada(Rea1 *conjunto)
{
int D;
D=(- l*conjunto[O]
+3*conjunto[1 J
-3*conjunto[2]
+ l*conjunto[3] );
return (4*fabs(D)); //Amplifica el resultado
I
4
SegundoFiltro,efectúa elfiltrado parasuavizar la curvaresultante
los picos.Recibecomoparámetroun
estamaneraremarcaraúnmás
arreglo de datos previamente derivados.
-
22
y de
Real SegundoFiltro(Rea1 "arreglo-final)
f
I
m t y;
Real datoFinal=O;
//Calcula la sumatoria del filtro.
for(y=O;y<taps;y++)
datoFinal=taps 1 [y]*(arreglo-final[taps-yl])+datoFinal;
//Regresa un datoya procesado.
return (datoFinal);
IniciaGraficos,
activa
monitor
el
en
modo
el de
gráficos.
Además
inspecciona si es posible utilizar un controlador o si existe una tarjeta que
permita la utilización de gráficos.
L
int IniciaGraficos(void)
{
int chances=O,modo,Error,controlador=O;
c h a r BGIs[GO]="c:\ yuan\ \tc"; //Localiza los controladores en esta
/ /dirección como primera opción.
clrscr();
do{
initgraph(&controlador,&modo,BGIs);
Error=graphresult();
/ /Si después de la búsqueda genera uno de los siguientes errores
//regresa un mensaje de error no reparable o sin solución.
switch(Error)(
case grNotDetected:
case grInvalidDriver:
case grNoScanMem:
case grInvalidMode:
case grIOerror:
4
-
23
case grInvalidVersion:
case grNoLoadMem:
case grInvalidFont:
puts ("Error tragico");
exit( 1 ) ;
break;
case grOk: //Este caso es en el que ha sido posible
break; / /la inicialización de los gráficos.
default:
/ / E n c a s o de que la ruta de acceso a los controla/ /dores de video no sea la correcta...
printf("La ruta de acceso de los bgi: ");
gets(BG1s);
/ /espera
nueva
ruta
. ..
controlador=O;
chances++; / /Oportunidades de inicialización de
/ /gráficos.
if(chances==3)
{ clrscr();
printf("\n\n\n Se acabaronlos chances. ");
LiberaMemoriaO;
exit(0);
;
1
break;
)while(Error!=grOk);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,4);
setcolor(L1GHTBLUE);
outtextxy( 100,170," Prepara Ambiente grafico... ");
delay(800);
return O ;
1
AmbienteDeGraficacion,muestraunaventanadondeseaprecianbarras
y otras
dedatoscomo:frecuenciademuestreo,canaldeadquisición
funciones; como la llamada de los filtros y opción de salida.
void AmbienteDeGraficacion(int XXMAX,int YYMAX)
{
char numero[20];
setviewport(O,O,XXMAX,YYMAX,1); //Define una ventana...
setbkcolor(BLUE);
fondo..
/ /Color
de
.
setfillstyle(SOL1D-FILL,LIGHTBLUE);
4
bar(O,O,XXMAX,YYMAX);
- 24
//Coloca una barra de color azul claro
/ / e n la parte superior dela pantalla.
settextjustify(LEF3-TEXT,TOP-TEXT);
setfillstyle(SOL1D-FILL,BLUE);
bar(O7YYMAX-20,XXMAX,YYMAX+25);/
/Coloca una barra decolor azul
/ / e n la pare inferior de la pantalla.
settextstyle(SMALL-FONT,HORIZ_DIR,5);
itoa(canalGraficar,numero,
10); / /Convierte un número en cadena
settextjustify(LEFT-TEXT,TOP-TEXT);
setcolor(WH1TE);
outtextxyj50,YYMAX- 15,numero); / /Pinta el valor del canal a graficar
settextjustify(LEF3-TEXT,TOP-TEXT);
setcolor(YELL0W);
outtextxy(8,YYMAX-15,"CANAL "); //Pinta la leyenda "CANAL"
itoa(frecuenciaMuestreo,numero,10);/ /Ahora frecuencia de muestreo..
.
settextjustify(CENTER-TEXT,TOP-TEXT);
setcolor(WH1TE);
outtextxy(XXMAX-30,YYMAX1 5,numero);/ /Pinta
valor de la frecuencia
//de muestreo.
settextjustify(CENTER-TEXT,TOP-TEXT);
I
setcolor(YELL0W);
outtextxy(XXMAX-80,YYMAX15,"FM"); //Pinta leyenda "FM"
setfillstyle(CL0SE-DOT-FILL,BLUE);
bar(O,O,XXMAX,18); //Define área de graficación.
setcolor(WH1TE);
settextstyle(SMALL~FONT,HORIZ~DIR,5);
/ /Pinta leyendas de funciones
outtextxy(XXMAX-120,4,"CUALQUIERTECLA PARA SALIR");
outtextxy( 110,4,"F2:
REINICIA DETECCION");
outtextxy(XXMAX/2,4,"F3:
FILTROS");
setfillstyle(SOL1D-FILL,WHITE);
bar(81,20,XXMAX- 19,YYMAX1 10); //Marca el área de graficación
/ / en blanco.
setcolor(RED);
rectangle(79,18,XXMAX-18,YYMAX-109);
rectangle(80,19,XXMAX-l7,YYMAX108);
IresentaGrafica, muestra los resultados de los datos obtenidos.
I
4
-
25
void PresentaGrafica(v0id)
I
int j,key,exitenDatos,YYMAX,XMAX,altura-ventana,
longitud-ventana,altura-ven-real;
int dif,aux,posYant,posYact,checa-bufer,tam-buf,
ventana,indicador-frecc=O;
int YYant,YYact,aux2;
Real borra~ant=O.O,estandar~old=O.O,variabilidad~ant=O.O;
YYMAX=getmaxy(); //Captura la resolución del monitor actual en
XXMAX=getmaxx(); / /horizontal y vertical.
//Ajusta el área de la pantalla donde serán graficados los datos.
longitud-ventana=XXMAX- 19;
altura-ventana=YYMAX- 130;
altura~ven~real=altura~ventana+20;
//Inicializa el valor del total de datos presentes en memoria.
tam-buf=memTotal;
/ /Inicializa el índice a la primera poción del arreglo.
checa-bufer=O;
AmbienteDeGraficacion(XXMAX,YYMAX);
key =PINTA;
CargaTaps(6); //Carga un
valor cualquiera para los filtros ...
do{
switch(key)(
case PINTA: / /Primera opción...
ventana=O; / /Inicializa el número de ventanas graficadas
exitenDatos=O; //Bandera que indica si ya existen tienen datos
//procesados suficientes para comenzarla
/ /detección de los picos.,
.
j=aux=O;
/ /Inicio
de
la pantalla
while(bioskey(1)==0) //Realizala graficación mientras no se oprima
/ / u n a tecla...
{
//Verifica si final de arreglo de datos capturados.
if((checa_bufer+2)==tam_buf)
checa-buf=O;
//Verifica si final de ventana
ifCj>longitud-ventana I I j==O) / / E n el caso del final de ventana...
{ //Torna una nuevaposición en la pantalla, en especifico al
//inicio de esta para continuar con
la gráfica.
j=aux=81;
i
4
- 26
//Toma unnuevo dato como primera coordenada ....
posYant=(int)(altura_ventana+20GraficaDatoNoPrc(a1tura-ventana,checa-bufer));
if(ventana<2)++ventana;/ /Incrementa número de ventanas
exitenDatos=O;
saltoDePantalla= 1 ;>
setcolor(MAGENTA);
lineCj ,70,j,altura-ven-real-50); / /Línea indicadora del punto
/ /actual de graficación.
setcolor(WH1TE);
,altura-ven-real);
/ /Línea de borrado del dato
lineu ,20,j
//del punto anterior.
setcolor(BLUE);
/ /Calcula la posición del nuevo datoa gráficar(dat0 actual).
posYact=(int )(altura_ventana+20GraficaDatoNoPrc(a1tura-ventana,checa-bufer));
line(aux,posYantj,posYact);/
/Pinta curva de datos no procesados.
posYant=posYact; / /Actualiza coordenadas.. .
aux=j ;
//Verifica si ya fueron graficadas al menos dos pantallas
/ / y entonces cambia la bandera, para que posteriormente
//empiece la detección de los picos.. . Además espera a que,
//en cada pantalla, sean graficados al menos doce datos.
if(ventana> 1 &&j==8 1 + 12) exitenDatos=1 ;
/ /Comienza graficación de rasultados.. .
if(exitenDatos)
checa-mem=checa-bufer; //Pone el índice del apuntador en el
/ /dato actual...
if(MarcaPicos(a1tura-ventana)) //Sipico detectado e s latido.. .
{setcolor(GREEN);
/ /pinta líneaverde vertical y cambia la bandera
/ / “indicador-frecc”.
line~-12,20,j-12,altura~ven~real);indicador~frecc=l;}
/ / S i final de pantalla...
if(j==81+12)
{ / /Actualiza variables...
YYant=(int )(altura~ventana+20-datoProcesado);
//primera
//coordenada en ejeY . . .
aux2=j- 12;/ /coordenada en X, al inicio.}
4
- 27
/ /Calcula nuevo valor a gráficar para la nueva pantalla.
YYact=(int )(altura~ventana+20-datoProcesado);
/ /Verifica si esta dentro delos límites del área de graficación...
if(YYact>=20&&YYact<=altura-ven-real)
{setcolor(LIGHTRED);
line(aux2,YYantj-12,YYact); //Pinta curva del gráfica
/ /procesada.. .
/ /Actualiza coordenadas.
aux2=j- 12;
YYant=YYact;}
/ /Si indicador-frecc es uno, muestra los valores actuales
/ /calculados; tanto de frecuencia como desviaciones estándar.
if(indicador-frecc)
{MuestraMensaje(0,35,YYMAX100,100,YYMAX-100,
"FRECUENCIA <Hz> :",borra-ant);//Borra
MuestraMensaje(O,170,YYMAX100,240,YYMAX-100,
"SD :",estandar-old);
/ /Borra
MuestraMensaje(0,35,YYMAX-80,100,YYMAX-80,
"VARIABILIDAD :",variabilidad-ant);// borra
MuestraMensaje(1,35,YYMAX-100,100,YYMAX-100,
"FRECUENCIA <Hz> :",frecuenciaAprox);/ /Pinta
100,
MuestraMensaje(1,170,YYMAX- 100,240,YYMA.XSD :",SDintervalo);
/ / Pinta
MuestraMensaje(1,35,YYMAX-80,100,YYMAX-80,
"VARIABILIDAD :",variabilidadHertz);//Pinta
/ /Guarda los valores actuales...
estandar-old=SDintervalo; //Desviación estándar por ancho
/ /de intervalo.
borra-ant=frecuenciaAprox;
variabilidad-ant=variabilidadHertz; / /Variabilidad calculada
/ /de la frecuencia.
indicador-frecc=O; / /Inicializa la bandera.. .>
q.
1
"
++theca-bufer; //Incrementa el índice para lectura de unnuevo
//dato.
++j;
//Incrementa posición en el eje X
}/ / fin del ciclo while...
key=bioskey(O); //Toma el valor de la tecla presionada.
break;
4
-
28
case F2:
//La tecla “F2”,
permite inicializar todas la variables que se utili//zan durante la detección.
ventana=O;
corrimiento=O;
umbralNivel=O;
SDamplitud=O;
SDintervalo=O;
contadorPicos=O;
contadorAmplitUno=O;
contadorPosiciones=O;
contadorIntervalos=O,
existeReferencia=O;
key=PINTA; / /Continúa graficando.
break;
case F3:
/ /La tecla “F3”,permite la visualización y selección de los filtros.
MenuFiltros(XXMAX,YYMAX);
key=PINTA; //Continúa graficando.
break;
}
}while(key==F3 I I key==ABAJO I I key==PINTA 1 I key==F2);
REGRESA:
closegraph(); //Restaura el modo textodel monitor.
restorecrtmode();
1
4
- 29
IV. 1.1.- Módulos del Algoritmo
Lasiguientepartedellistadomuestra
la implementacióndelalgoritmo
para la detección de posibles picos que correspondan a u n latido o sonido
cardiaco.
IV.l.l . 1 .- Búsqueda por Amplitud
BuscaPicos, la primerapartedelalgoritmoesdetectarpicosenbase
al
criterio de amplitud. Primero es necesario determinar si el dato presente es
unmáximo,
si estosucedecabelaposibilidaddequeseaunposible
sonido
cardiaco.
Esto
es
posible
entre
las variables
“primerRegistro”,
solo seaceptacomoposible
”segundoRegistro” y “muestra-act”,donde
pico el caso en que el valor de la variable “segundoRegistro” e s mayor.
Real BuscaPicos(Rea1 muestra-act)
Real limite~sup=0,1imite~inf=07Umbral=0;
int num.-muestra;
/ / Verifica si es un máximo el dato inmediato anterior “segundoRegistro”.
if(segundoRegistro>primerRegistro&& segundoRegistro>muestra-act)
{
%
//Toma los valores actualesdel segundo promedio y desviación estándar,
/ /si los valores son cero solo se considera el umbral determinado por
/ /el primer promedio. La variable “umbralNive1” corresponde al segundo
/ / promedio.
limite-inf=umbralNivel-SDamplitud;
limite-sup=umbralNivel+SDamplitud;
/ /Llamada a la función de primer promedio y actualización del umbral
//con el nuevo pico detectado.
Umbral=PromedioPicos 1 (segundoRegistro);
/ /Prueba si los limites dados por el segundo promedio y desviación
/ /estándar son distintos de cero, si esto no sucede estos limites
//toman los valores del primer promedio como el limite inferior
/ / yel limite superior como el máximo valor que puede tener una
//muestra capturada. Además, verifica si el valor de “Umbral”( que
//contiene el primer promedio ) e s distinto de cero.
if(Umbral>limite-inf I I limite-inf>=limite-sup&&Umbral!=O)
4
-
30
limite-inf=Umbral;
limite_sup=4096;
/ /La variable “contadorAmpli.tuno” lleva la cuenta de un arreglo don(
~
//están guardados los datos de los valores a promediar, con esta
//variable comprueba si ya se ca1cul.o el primer promedio, cuando
/ /es igual al valor“TOTCOMPARA”.
if(segundoRegistro>=limite_inf&&segundoRegistro<=limite_sup&&
contadorAmplitUno>=TOTCOMPARA)
i
PromedioPicos2(); / / Calcula el segundo promedio si
/ /tiene el total de datos en el arreglo...
Corrimiento(segundoRegistro);/ /Guarda el nuevo valor del amplitud
/ /idel pico actual.
primerRegistro=segundoRegistro;/ /Actualizo variables
segundoRegistro=muestra-act;
return 1 ; //Regresa un uno si el máximo detectado pasó el limite
I
amplitud.
//de
else ;
I
else ;
primerRegistro=segundoRegistro;/ /Actualiza las variables.
segundoRegistro=muestra-act;
return O ; //Regresa un cero si el valor de amplitud no es un máximo o
1
//el
valor
del
pico
no
esta
en
el
rango
de
amplitud.
PromedioPicosl, calcula elprimerpromedioporamplitudde
un número
“TOTCOMPARA” demuestras,
y seactualizaestepromedioconcada
nuevo pico detectado.
Real PromedioPicos 1 (Real valor-pico-act)
i
int jj,poblacion=TOTCOMPARA;
Real prom;
//Verifica si el contador “contadorAmplitudUno” indica si no
se ha
/ /llenado el arreglo con las’muestras necesarias para calcular el
/ /promedio. Además, comprueba si “valor-pico-act” esta dentro del
/ /rango de amplitud.
if(contadorAmplitUno~poblacion&&valorpic
valor-pico_act>=O)
.
... .
.
,
4
-
31
/ /Guarda el valor de pico actual.. .
{
PrimA~nplitud[contadorAmplitUno]=valor~pico~act;
++contadorAmplitUno; //Actualiza el contador..
return O;). //Termina ...
.
/ /Si el arreglo esta lleno...
if(contadorAmplitUno~=poblacion&&valor~pico~act~=4096&&
valor-pico-act>=amplitudPromedio 1)
//Hace un corrimiento...
forCjj=O;jj<poblacion- l;jj++)PrimAmplitudIjj]=PrimAmplitudIjj+
11;
PrimAmpli tud[poblacion- l]=valor-pico-act; //Guarda el nuevo valor
/ /Calcula
el promedio... actualiza.
forCjj=O,amplitudPromedio1 =O;jj<poblacion;jj++)
amplitudPromedio 1 +=PrimAmplitudljj];
amplitudPromedio 1 =amplitudPromedio 1 /poblacion;
//Valor relativo del promedio reduciendo a u n 45% el umbral
/ /del valor original.
amplitudPromedio 1 =amplitudPromedio 1 -(0.45*amplitudPromedio 1 ) ;
I
return amplitudPromedio 1 ; / /Regresa el valor del promedio.
los picosporamplitud
PromedioPicos2, calcula elsegundopromediode
cuando tiene un total de “MUESTRAS” en el arreglo “amplitudesDetec”,
y
guarda
valor
el en
la variable “umbralNive1”.
También
calcula
la
desviación estándar de amplitudes.
int PromedioPicos2(void)
{
int pico,poblacion=MUESTRAS;
//El contador “contadorPicos ” indica si el arreglo esta lleno, es decir,
/ /si e s igual a “MUESTRAS”.
if(contadorPicos>=poblacion)
{ / /Calcula el promedio
for(pico=O,umbralNivel=O;pico<poblacion;pico++)
umbralNivel+=amplitudesDetec[pico];/ / Sumatoria.. .
umbralNivel=umbralNivel/poblacion;/ /Calcula promedio.. .
4
DesviacionEstandar 1 ();
/ /Calcula
- 32
desviación estándar.
\
J
else ;
return O ;
/ /Termina calculo.
Corrimiento, guarda el valor del pico actual ...
int Corrimiento(Rea1 muestra-anterior)
I
int recorre,poblacion=MUESTRAS;
//Verifica si “contadorPicos‘‘ indica que esta lleno el arreglo
if(contadorPicos>=poblacion)
{amplitudesDetec[O]=O; //Libera la primera posición
for(recorre=O;recorre<poblacion1 ;recorre++) / /Hace el corrimiento.. .
amplitudesDetec[recorre]=amplitudesDetec[recorre+11;
/ /Guarda el nuevo dato.
amplitudesDetec[poblacion-l]=muestra-anterior;
return O ; //Termina.
1
/ /Si no esta llenoel arreglo.. .
amplitudesDetec[contadorPicos]=muestra~anterior;
/ /Guarda elnuevo
i
/ /dato.
++contadorPicos;//Actualizacontador.
return O ; / /Termina.
I
DesviacionEstandarl,calculaladesviaciónestándardeamplitudde
muestras presentes en el arreglo “amplitudesDetec”, con número total de
muestras igual a “MUESTRAS”.
las
int DesviacionEstandarl(void)
{
int standar,poblacion=MUESTRAS;
/ /Suma del cuadrado de la diferencia del promedio y la muestra.
for(standar=O,SDamplitud=O;standar<poblacion;standar++)
SDamplitud+=pow((double)(umbralNivel-amplitudesDetec[standar]),2.0);
//División entre el número de muestras.
I
4
- 33
SDanlplitud=SDamplitud/poblacion;
if(SDamplitud<O)SDamplitud=O;
SDamplitud=sqrt(SDamplitud);/ /Raíz cuadrada...
SDamplitud=3*SDamplitud;//Esto nos provee el 99 YOde probabilidad
return O ; //Termina.
t
4
- 34
IV. 1.1.2.- Búsqueda por Distancia entre Picos
Lasegundapartedelalgoritmoes
l a búsquedadeposibleslatidopor
el
criteriodedistanciaentrepicos.Enestapartesemenciona
la palabra
“posición” y se refiere a la posición (valor en el índice del apuntador) en
el
arreglodememoria,querelacionandocon
la frecuenciademuestreo;se
refiere al número de muestras que debe haber entre cada pico, esto para
que se puedan seleccionar los picos que si cumplen con este criterio.
GuardaPosicion, guarda el valor del índice (posición en el arreglo).
int GuardaPosicion(int posicion)
I
int contador;
/ /El contador que lleva el control de el arreglo “posicionesDetec” e s
/ /”contadorPosiciones”, este determina en que lugar del arreglova
//aser guardado un nuevo dato o una nueva posición.
if(contadorPosiciones<NUMPICOS) //Verifica si no esta lleno el arreglo.
{ / /Guarda la nueva posición.. .
posicionesDetec[contadorPosiciones]=posicion;
++contadorPosiciones; / /Actualiza el contador.
return O;>
//Siesta lleno el arreglo...
posicionesDetec[0]=0; / /limpia la primera posición.. .
/ /hace un corrimiento...
for(contador=O;contador<NUMPICOSl;contador++)
posicionesDetec[contador]=posicionesDetec[contador+
11;
/ /guarda la nueva posicion...
posicionesDetec[NUMPICOS- l]=posicion;
return O ; //Termina.
1
I
MideDistancia, calcula la distancia que existe entre dos picos.
Considerando que se trata de u n arreglo que se maneja como circular, es
necesarioverificardoscasosparalograrlamedicióncorrecta
de la
distancia. El primero, el más sencillo, donde la posición actual (hablando
de indices) es mayor que la posición anterior, donde con una simple resta
4
- 35
e s posiblecalcular
la distancia. El segundocaso,cuando
la posición
actualesmenorque
la posiciónanterior, esnecesariohacerunajuste
para obtener la posición real ...
int MideDistancia(int posicion-actua1,int posicion-anterior)
int tamano=memTotal;
//Comprueba si es necesario el ajuste ...
if(posicion-actual<posicion-anterior)
//Regresa un valor real dela distancia entre los picos actuales,
//donde “tamano” es el tamañodel arreglo.
return (tamano-posicion-anterior+posicion-actual);
else return (posicion-actual-posicion-anterior);
1
El ajuste se realiza, primero calculando la distancia que hay de la posición
la distanciaque
anterior al finaldelarreglo;posteriormentesesuma
existe del inicio del arreglo a la posición actual.
promedio
de
distanciaentrepicos,los
PromediaIntervalos, calcula el
valoresdeestasdistanciassonguardadospreviamenteen
el arreglo
del
“distanciasDetec” y el “contadorhtervalos ” lleva el control del llenado
arreglo. También calcula la desviación estándar.
int PromediaIntervalos(void)
{
int cuenta,poblacion=MUESTRAS;
!
//Comprueba si esta lleno el arreglo ...
if(contadorIntervalos>=poblacion)
c
for(cuenta=O,intervaloPromedio=O;cuenta<poblacion;cuenta++)
intervaloPromedio+=distanciasDetec[cuenta];/ /Sumatoria de los datos.
/ /Calcula el promedio.
IntervaloPromedio = intervaloPromedio/ poblacion;
/ /Calcual desviación estándar de intervalos.
DesviacionEstandara();
else ;
return O ; //Termina.
1
4
-
36
DesviacionEstandar2, desviación estándar de la distancia entre picos con
un número total de “MUESTRAS”...
int DesviacionEstandar2(void)
int standar,poblacion=MUESTRAS;
/ /Sumatoria del cuadrado de la diferencias entre el “intervaloPromedio” y
/ /la muestra .
for(standar=O,SDintervalo=O;standar<poblacion;standar++)
SDintenralo+=pow((double)(intervaloPromediodistanciasDetec[standar]),2.0);
//División entre el numero total de muestras...
SDintervalo=SDintervalo/poblacion;
if(SDintervalo<O)SDintervalo=O;
SDintervalo=sqrt(SDintervalo); //raíz cuadrada.. .
SDintervalo=3*SDintervalo; //el 99 YOde probabilidad.. .
return O ; //termina.
1
SeleccionaIntervalo,determina si la distanciaentrepicosdetectadacae
dentrodelrangodefrecuenciacardiacacorrespondiente,comparando
entre los picos encontrados sus respectivas distancias.
int SeleccionaIntervalo(int posicionActua1)
i
Real distanciaActual=O;
distanciaActual=BuscaReferencia(posicionActual);
if(distanciaActual!=O&&existeReferencia== 1)
{ //Sicumple es un posible pico y guarda la distancia actual y
//hace los calculos correspondientesa pico detectado actualmente.
GuardaDistancia(distanciaActua1);
//Variabilidad en base a promedio de intervalos
VariabilidadDeFrec(CalculaFrecuencia(PromediaIntervalos()));
/ /frecuencia
actual
I
4
frecuencidprox
=
- 37
CalculaFrecuencia(distanciaActua1);
/ / T o m a el mejor intervalo.
if(CompruebaDistancia(distanciaActua1,variabilidadMuestras))
I
return 1 ;
return 1;
return O ;
1
1
BuscaReferencia,detecta si existenreferencias;
si estasnoexisten
las
busca y guarda en un arreglo las posiciones de los picos detectados, en
otro caso compara estas distancias con la actual y verifica si corresponden
o no a u n posiblepico.
Estafunción
devuelve uncerosinoexisten
referencias o si el pico detectado no corresponde a un posible pico, en otro
caso devuelve un uno.
Real BuscaReferencia(int NuevaPosicion)
{
Real disTancia1=O,disTancia2=O,distanciaActual=0,
limiteInf=O,limiteSup=O;
//Toma los limites calculados para el rango de distancias entre picos
//para un rango determinado de muestras entre picos que equivale
/ /al rango de ciclo cardiac0 seleccionado.
1imiteInf = distanciaMinima;
limiteSup = distanciaMaxima;
//Pregunta si existen datos para comparar...
if(contadorPosiciones<NUMPICOS)
GuardaPosicion(NuevaPosicion);//guarda nuevos datos.
return O ;
)
//Mide las distancias entre dos intervalos subsecuentes y el actual
disTancia1 = MideDistancia(posicionesDetec[l],posicionesDetec[O]);
disTancia2 = MideDistancia(posicionesDetec[2],posicionesDetec[
11);
distanciaActua1 = MideDistancia(NuevaPosicion,posicionesDetec[2]);
//Comprueba si se ha perdido un latido con respecto al limite superior
if(disTancia1 >limiteSupI I disTancia=!>limiteSupI I
distanciaActual>limiteSup)
4
f
existeReferencia = O ; / / reinicia busqueda de referencia,
contadorPosiciones = O ;
return O ;
1
//Compara contra el limite inferior.
if(disTancia1 <limiteInfI I disTancia2<limiteInfI
distanciaActual<limiteInQreturn O ;
I
//Buscamínima diferencia de distancia entre picos
//anteriores.
if(CompruebaDistancia(disTancia1,disTancia2)==0)
return O ; //termina si no cumple ...
//busca mínima diferencia con la referencia actual.
if(CompruebaDistancia(disTancia2,distancidctual)==
1)
{
1
GuardaPosicion(NuevaPosicion);
existeReferencia = 1 ;
return distanciaActua1;
I
return O ;
t
int CompruebaDistancia(int distanciat\nterior,int distancidctual)
Real diferencia,limiteInf,limiteSup;
/ /Calcula la diferencia
entre distancias...
diferencia = 0.03*frecuenciaMuestreo+20;
//obtiene un rango de diferencia
...
limitelnf = distancidnterior-diferencia;
IimiteSup = distanciaAnterior+diferencia;
/ /compara.
if(distancidctual>=limiteInf&&
-
38
4
- 39
distanciaActual<=limiteSup)return 1 ;
return O ;
\
J
CalculaFrecuencia,una vez que el programahadetectadointervalos
de
referencia es posible calcular una aproximación dela frecuencia cardiaca.
Real CalculaFrecuencia(int distanciaEntrePicos)
{
Real frecuencia,Periodo-muestreo;
Periodo-muestreo= 1 /(Real )frecuenciaMuestreo;/ / [sJMUESTRAS]
frecuencia= 1 / (distanciaEntrePicos*?eriodo-muestreo);
/ / [s/MUESTRAS]"[MUESTRAS]=
1/ [ S ]
return (frecuencia);
VariabilidadDeFrec, calcula la variabilidad
de
la frecuencia
tanto
en
unidades de Hertz como por número de muestras.
<.
Real VariabilidadDeFrec(Rea1 frecuencia)
{
Real intervalo,a=O,b=O,Ti;
if(frecuencia<=O)frecuencia=1 ;
intervalo= 1 / (Rea1ffrecuencia;j/ [ 1 / 1/ s ] = [ s ]
if(intervalo<0.023&&intervalo~O.O1)
{a=0.9;b=0.002 l;}
/ /Criteriospara elindice de
else(a-1 . O 0 0 l;b=0.0001;}/ /variabilidad(pendiente y cons/ /tante de la recta
Ti=a*intervalo+b;
/ / [SI
if(Ti<=O)Ti=1 ;
variabilidadHertz= 1 /Ti;
/ /Hz
variabilidadMuestras=frecuenciaMuestreo*Ti;
/ / [MUESTRAS/s]*[s]=[MUESTRAS]
return (VariabilidadMuestras);
}
5-1
V.l.- Gráficas de Respuesta de los Filtros
Las siguiente gráficas de respuesta corresponden a filtros cuya frecuencia de
muestre0 es de 330 Hz.
Filtro pasa banda con rango de frecuencias 2 0 a 30 Hz.
l.ook
Y
5.00
o. o
1
,
Frecuencia Central :24.609Hz
:
4.
Filtro pasa banda con rango de frecuencias entre 40 a 50 Hz.
Frecuencia Central : 44. 531 Hz.
0.0 -
1
o .o
I
1
I
I
I
I
I
I
,
1
I
I
I
I
I
1
18.750 H z / D i v
5 - 2
Filtro pasa banda con rango de frecuencias entre 60-70 H z
1
I
I
I
o .o
Frecuencia Central : 64.453 Hz.
I
I
I
I
,
I
18.750 Hz/Div.
I
Filtro pasa banda con rango de frecuencias entre 80 a 90 HZ.
1.000 4
5.000
1
o .o
I
I
I
I
1.8.750 Hz/Div.
1
I
I
I
5-3
Filtro pasa banda con rango de frecuencias entre 100 a 1 10 Hz.
1.000 -
Frecuencia Central : 104.SS3 Hz.
0.0
1
5 .O00
I
I
1
0.0
I
I
0
r
I
I
13.750 Hx/Div.
Filtro con rango de frecuencia entre 20 a 30 Hz,con frecuencia de
muestre0 de 1000 Hz.!.
l*Oool
I
0.0
I
I
I
62.500 Hz/Div.
,
I
I
5 - 4
Los filtros fueron diseñados en base
a las ventanas de Hamming, es decir, se
tratadefiltrostipos
FIR. Existendiferenciasrespecto a la selectividadde los
filtros, esta diferencia es notoria modificando la frecuencia de muestreo.
Respecto a la selectividad, esta sería aún mayor si fueran disenados
los filtros
con un mayor número de coeficientes. Sin embargo, esto influiría en gran parte
en la velocidad de procesamiento.
La respuesta en fase, en el caso de los filtros digitales, siempre tendremos una
respuesta lineal al menos en la banda de paso.
En la frecuencia de muestreo seleccionada para el diseño según el teorema
Nyquist, estafrecuenciaesaproximada
ya quetenemosunampliorango
frecuencias en las que va ha estar oscilando el ciclo cardiaco.
de
de
Como esdeobservarseen
elúltimocaso,
elfiltro diseñadocon 1000 Hz de
frecuencia de muestreo, la selectividad disminuye considerablemente.
En base a lo anterior es necesario considerar para la captura de los datos; una
frecuencia de muestreo lo suficientemente grande, para que de esta manera se
obtengaunarespuestaoptima
delfiltro y ademásseaposibledistinguirlos
picos que resultan de los ruidos cardiacos, cuando estos se presenten.
c
6-1
VI. 1
.-Manual de Usuario
El ordendecomosemuestran
alguno
de
los pasos
se
omite
procesamiento.
las opcionesesindispensable,
el
programa
generará
errores
en
ya que si
el
1 .- La primer pantalla muestra una presentación del programa; no se debe
oprimir tecla alguna, debe esperar unos segundos(siguiente ventana).
UNIVERSIDAD AUTONOMA METROPOLITANA
IZTAPALAPA
C. B . I .
SEMINARIO DE PROYECTOS I 1
PROCESAMIENTO DE S E Ñ A L DE
-FCG- EN TIEMPO REAL.
2.- Unasegundapantallamuestralasopcionesquetiene
elprograma
(menú principal). Debe seleccionar con número la opción, cualquier error
tecleado solo genera la espera del número correcto.
MENU PRINCIPAL
< O > CARGAR DATOS
< 1 > LIMITES DE FRECUENCIA
<2> MUESTRA GRAFICA
<3> TERMINAR
6-2
3.- E n la opcióndecargardatos,muestraunsubmenúquemuestra
el
origen deseado de los datos, debe ser seleccionado oprimiendo un número.
Los casos se muestran en la siguiente ventana,
C A R G A R LOS D A T O SD E :
l . ARCHIVO
2 . TARJETA
El origen de los datos incluye la frecuencia de muestreo. Si existe un error
en la lectura del archivo muestra un mensaje “no se abrió
el archivo”, y
regresa al menú principal; este error se puede presentar debido
a que este
mal la ruta de acceso del archivo o por un error de tecleo de la ruta de
acceso. Si el acceso fue correcto el programa regresa el mensaje “ya fueron
cargados los datos”.
E n el caso de unarchivo,lafrecuenciademuestreonotienequeser
seleccionada;
este
dato
encuentra
se
al principio
archivo,
del
Posteriormente lee el número de datos.
Para el caso de la habilitación de la tarjeta, la frecuencia de muestreo se
selecciona, muestra un mensaje al teclear la opción “2”; pide la frecuencia
de muestreodeseada y envía el datonecesarioalcontadorprogramable
(8253-5).
Después
de
ejecutarse
cualquiera
de
las
opciones
regresa
al
menú
principal.
6-3
4.- Para seleccionar el rango de detección del ciclo cardiaco, debe oprimir
con letra la opción mostrada en el submenú.
la opción
el
programa
toma
por
default
valores
distintos
primeras; como se muestra a continuación.
Si ocurre un error
al teclear
a las dos
RANGO DE FRECUENCIA A DETECTAR
( latidowminuto 1
70 - 90.
120-180
DEFAULT 100-200.
A.
B.
E s importante, que antes de iniciar el procesamiento, debe seleccionar
el
los que
seguramente
estará
la
señal
rango
de
ciclos
cardiacos
en
capturada. De ahíelhechodetenerprimerolosdatos
o seleccionar la
frecuencia de muestreo, ya que el rango depende de este parámetro
para
calcular elnúmerodemuestras
máximo y mínimoentrecadaciclo
cardiaco.
6 - 4
5.- Al hacer la llamada a la opcióndemostrargráfica,cambiaal
modo
gráfico el monitor y muestra un mensaje de espera. Si existe un error
al
inicializar los gráficos muestra
el mensaje correspondiente. En otro caso,
muestra el mensaje “preparando gráficos”, y muestra la siguiente pantalla
de gráficos. E s muycomúnque,
si no se encuentrauncontrolador
de
gráficos (archivos *.BGI) el programa pedirá la dirección correcta de dicho
controladorhastaqueobtengalarutacorrecta,
solotienetresopciones
para lograr esto o el programa terminará.
En la pantalla de gráficos .muestra dos funciones de teclas. Para la tecla
“F2” su función
inicializar
es
las variables
que
se utilizan
en
procesamiento.Latecla
“F3” muestraunmenú
defiltros, los cualesse
pueden seleccionar oprimiendo el
filtro requerido, al ancho de banda que
se desee filtrar (ver la siguiente gráfica).
6-5
I
I
I
I
I
/,
.”
”.
E n las pantallas mostradas anteriormente se puede apreciar las funciones
en la barra superior, así como el modo de salida del programa; desde luego
que para salir delprograma,debeseroprimida
una tecla diferente de
la
función “F2”y ”F3”.E n la barra inferior, se muestra el valor del número de
canal que se observa en la pantalla (Solo cuando esta activa la tarjeta, en
la opción de datos de archivo puede tomar cualquier valor; puesto que no
se incluyó como parámetro al guardar los registros). Además se aprecia en
la esquina inferior derecha el valor de la frecuencia de muestreo.
Lafrecuenciaqueseindicacomoresultado“FRECUENCIA
<HZ>”, e s el
valor aproximado de la frecuencia instantánea. La “VARIABILIDAD” es un
para ser calculada.
datos no real, puesto que, no tiene los datos correctos
El valor “SD”e s la desviaciónestándar
del númerodemuestrasentre
intervalos.
Al momento de oprimir cualquier tecla, distinta de las funciones, regresa al
menú principal cambiando del modo gráfico al modo texto de la pantalla.
6-6
6.- E n el momento de que en la pantalla se muestra
la curva procesada
o la
(parte inferior en el área de gráficas); se muestra un desplazamiento
forma de los picos de
la curva no son los adecuados, es necesario oprimir
la tecla ‘‘€72’para
’
reinicializarelprocesohastaobtenerlaformade
los
picos más adecuada para la
detección;
ejemplo:
(ver
las siguientes
gráficas).
dos curvas. La curva superior
En
todas
las
gráficas
se
aprecian
corresponde a la señal original. Mientras que la curva inferior corresponde
a la señal procesada.
Gráfica 1 :
6 - 7
Gráfica 2 :
7 - 1
OBSERVACIONEStf
electrocardiografiaera
unaseñalde
Estealgoritmoalserprobadocon
bastante eficiente, de tal forma que (la la posibilidaci de medir la frecuencia
instantánea. Esto se debe a que la presencia del complejo QRS está más
definido, es el caso contrario que se presenta en la fonocardiografia.
El criteriodeamplitudsiemprefue
dificilde definiradecuadamente,ya
que al presentarse un pico de amplitud muy grande, el umbral (promedio)
se disparaba a valoresmuyporarriba
delpromediodeamplituddelos
picos
correspondientes
a un latido, lo que
originaba
que
los
picos
la presencia
subsiguientesnofuerandetectados.Estogeneralmentepor
de un artefacto. Considerando que en aplicación normal (detección directa
defonocardiograma)siempreexistenartefactosdemovimiento
o ruido
respiratorio.
Es necesarioconsiderarque
en elmonitoreode
la señalderuido,los
cambios
de
la distancia del micrófono(transductor
de
sonido)
por
movimientosrespiratorios,provocanque
la amplituddelruidocambie
debidoalalejamiento
o acercamiento del transductor.Estoscambios
de
y
amplitud provocan que el pico que se presenta sea de menor amplitud,
ocasiona que el pico no rebase el umbral, por lo tanto no es detectado y se
pierde la referencia.
se pudoverque
al presentarse ruidos
En elmismosentido,también
respiratorios o artefactos elfiltradono
logró eliminarestasfrecuencias,
después
haber
de
procesado
señal,
observaron
la
se
picos
correspondientes a la presencia delruido en cuestión. En algunos casos,
los artefactosquesepresentabanestabantraslapadosuocultabanun
ruidocardiaco, lo queocasionabaque
elpico obtenidoeramuygrande,
por lo tanto, al pasar por la etapa
de discriminación por amplitud
el pico
resultante no eradesuficienteamplitudparaserdetectado.
Es sucede
m á s a menudo cuando se muestrea la señal a m á s de 500Hz. Sin embargo,
al muestrear a 300 o 330Hz, la señal se observó limpia de ruido, aunque
se seguía presentando el problema de el filtrado antes mencionado.
tt
En el caso de observaciones y comentarios, para mayor referencia se muestran gráficos en anexo.
7-2
COMENTARIOS
Para hacer uso de este programa, debido al alto número de operaciones, es
indispensable una PC que cuente con coprocesador matemático, sin este la
velocidad de proceso es extremadamente lenta.
Es importante mencionar la frecuencia de muestreo que se esta utilizando,
al programar el 8253 con frecuencias de muestreo mayores a lOOOHz se
debe verificar que sea la indicada, ya que el calculo de divisor es por medio
de raíz cuadrada y un redondeo, que produce un cierto margen de error. El
rangodeprecisióndelafrecuenciademuestreo,esposiblemedirlo
observando la salidadelaseñal
del 8253 en elpin
7 , medianteun
osciloscopio y hacer los ajustes necesarios.
El objetivo principal de tener teclas especiales durante el proceso es el de
poder observar los cambios instantaneos que ocurren en
el mismo. E n el
caso de “FY,en ocasiones sucede que el umbral de amplitud este muy alto
debido a la señal actual; pero al presentarse un cambio de amplitud o al
mover la amplitudde la señal a u n a demenor,esnecesariocomenzar
nuevamente el registro, inicializando la variables.
De igual manera la tecla “F3”,permite visualizar los cambios de la curva o
señal procesada al mover el tipo de filtro.
Al momento de iniciar el proceso, el filtro debe ser inicializado, ya que
en
la curva de la señal procesada en forma aleatoria se presenta un offset en
la curva, se debe oprimir
la tecla F2, para reinicializar el proceso o h a s t a
ver que este offset halla desaparecido.
La frecuencia de muestreo a 300 o 330Hz,se observó suficiente para lograr
apreciar los picos debidos al ruido producido por un latido. E n el caso de
que no se llegaran a apreciar los picos; después del procesamiento, basta
conquesemultiplique
por, unaconstantedichoresultadodespués
de
haber derivado, para lograr la amplificación de la señal procesada .
7 - 3
CONCLUSIONES
La
solución
dada
a este
algoritmo
es
un
preliminar,
los resultados
obtenidosdanideadelospuntosimportantesdelmismo.Unasolución
la utilización del modelo
alternativa para un mejor control del proceso es
deobjetos.Conestoseobtendráunmejorcontroldelasvariables
y
procedimientos.
Es de observar que en muchos equipos el monitoreo de señales fisiológicas
este
acompañado
de otras
curvas
monitoreo.
de
Haciendo
las
modificacionesnecesarias a la interfacedecapturadedatos,esposible
rastrear
canales
simultáneos.
Además,
es
necesario
incrementar
la
frecuencia de muestreo en forma proporcional a número de canales; dada
por FM*N(FM: frecuencia de muestreo por canal, y N: número de canales).
Relacionando lo anterior, existe un tipo de algoritmos de filtrado que son
mucho más eficientes que el que se utiliza en este trabajo, dichos filtros
sonconocidoscomo“filtrosadaptivos”.Estaaplicaciónrequieredelas
diferentesserialesinvolucradas,lascualesson:ruidocardiaco,ruido
la ayuda
muscular, ruido respiratorio, artefactos de movimiento, etc.. Con
de este método se correlacionan las señales y se filtra la señal deseada. Se
ha observado que esta herramienta de procesamiento es bastante eficiente.
En general, durante el desarrollo del trabajo se puede observar los puntos
clavesenlosqueelprogramadebediseñarseparalograrunamayor
eficiencia. Los resultados
obtenidos
muestran
un
buen
avance
y
proporcionan
ideas
importantes,
para
un
posterior
mejoramiento
del
mismo. La utilidad de este algoritmo es interesante y de amplia aplicación,
sobre todo lo que se refiere a la medición de la frecuencia instantánea, en
especifico, la medición de la variabilidad de la frecuencia cardiaca latido a
latido, lo cual, nos da la posibilidad de obtener
la curvadevariabilidad,
como objetivo al cual deberá ser enfocado el mejoramiento del algoritmo.
El algoritmodedetección
e s eficiente,lapruebahechaconunECG
(Electrocardiograma) lo muestra. La precisión con que realiza la detección
es bastante buena. Sin embargo, la etapa de filtrado no e s la adecuada. El
tipo de filtros utilizados; solo obtiene el área bajo la curva de las muestras
presentes, lo que provoca es que no sean eliminados los artefactos, por
lo
tanto, ocasiona los errores antes mencionados.
Fue posible medir el ciclo cardiaco, sin embargo, no
instantánea.
fue posible de manera
ANEXO
G r h f i c a No. 1
A- 1
ANEXO
G r a f i c a No. 2
A-2
ANEXO
Grafica No.3
A-3
ANEXO
G r a f i c a No. 4
A - 4
ANEXO
A - 5
G r a f i c a No. 5
P
'I,
1,".
ANEXO
A - 6
G r h f i c a No. 6
111
ANEXO
Grafica No. 7
A-7
BIBLIOGRAFIA
Peña, M., 1994,
Método Automatizado para la Medición del Ciclo
Cardiac0 Fetal por FCG, Ing. Biomedica, vol. XV,
NO.2, pigs. 64-74.
Peña, M, 1994,
Comparation of Abdominal ECG and phonocardiography for instantaneus fetal heart rate detection,
World Congress on Medical Physics and
Bionledical Enginering, Brasil.
Guyton, A.,
Fisiología Humana, Edit. Interamericana, 6”
Edición, pag‘s [268-2711.
Kamas, A.,
Digital Signal Processing Experiments (User’s
Manual). la Edición, Edit. Prentice-Hall,
pag’s 57 -6 1.
Brey, B.,
The Intel Microprocessors. 8086/8088, 80186,
80286. 80386, and 80486 (Architecture,
Programing, and Interfacing). 1” Edición,
Edit. Macmillan Publishing Company.
Goofrey, J.,
LenguajeEnsamblador para Microcornputadoras,
1” Edicion, Edit. Prentice-Hall, Cap’s. 2, 5.
PCL-812 ENHACED MULTILAB-CARD,USER‘S MANUAL.
Aljama , T.,1992,
Procesamiento Digital de Señales. 1”Edicion,
Edit. UAM.
Schildt, H., 1994,
Turbo C/C++ 3.1 (Manual de Referencia),
1” Edicion, Edit. Osborne McGraw-Hill.
7
Descargar