UNIVERSIDAD AUTONOMA METROPOLITANA irtapalapa L- SEMINARIO DE PROYECTOS 11 -Continuacióndel Software PC-LAB 818- GRUPO: CL74 CLAVE: 212443 -ALUMNO: ALEJANDRO VILLASEÑOR HERRERA ASESOR: M. en I. JESUS ALFONSO MARTINEZ ORTlZ México,D.F., a 18 de Octubre de 1996. 4 CONTENIDO introduccidn ................................................................................................................................. CAPITULO 1: Programa principal Variables globules Archivas utilizados de la bobliotec de Turbo C Archivos creados Función principal(main) 3 ......................................................................................................................... .......................................................................... ........................................................................................................................... ................................................................................................................ CAPITULO 2: Complementación al programa original Ventanas de Ayuda Ventana de Directorio ................................................................................. ................................................................................................................ .................................................................................................................. MANUAL DE USUARIO ................................................................................................................ ............................................................................................................................ Hemerografh ............................................................................................................................. 5lbliogrufiu .................................................................................................................................. Conclusiones 6 7 7 .8 10 13 18 21 227 28 29 1 I NT RODUCCION Indudablemente, para un Ingeniero la programación en un lenguaje de alto nivel es fundamental tanto en su formación como en su desarrollo a nivel profesional. Es por ello que decidí retomar este software(PC-LAB818) que como bien Io explica el "Manual de Usuario" realzado por el alumno Norbert0 Mendoza quien es el autor de dicho software; éste fue pensado originalmente para la captura y procesamiento de una señal fisiológica en particular; los potenciales evocados; esto con la ayuda de una tarjeta PCLAB Card Modelo PCL-818 CAD de 16 canales. A manera de ubicar el presente software como un sistema de instrumentación; vale la pena mencionar que todo sistema de instrumentación tiene al menos algunos de los componentes funcionales que se muestran en el esquema. En donde el flujo de Infonnaclón va de kquierda a derecha, y los elementos relacionados con lineas punteadas no son esenciales. La mayor diferencia que existe entre este tipo de sistema de instrumentacióny los sistemas de instrumentación convencionales, es que, la 'Tuente de señales" es tejldo VIVOd energfa apllcada a tejido vivo. ~ . . ~ . ' ~ ' ~ ~ " ~ " ~ .Control ' ~ ' . ~ . ' ~ . . ~ _.._.__.._..-.."~''~'~~ I : ! U ____._ Fuente de poder __+ Elementode conversión variable I I Procesarnlento . de la señal Despliegue perceptible L - 1) Señal de Radiación, corriente eléctrica, o alguna otra SlST EMA DE I NSTRUME NTAClON 6ENE RALliA D O 2 MESURANDO La cantidad fbica, propiedad G condicihn que el sistema rtiide M llart-tach "mesurando". La accesibilidad del mesurando es importante; ya que este puede ser interno (presión sanguínea), o puede estar tamblén en la superñcle corporal (pOtenCla1 de elctrocardiograma),o bien puede emanar del interior del cuerpo (radiación infraroja), o puede ser derivado de una muestra de tejido (como la sangre 6 una biopsia) que es tomada del cuerpo. La mayoría de los mesuranda medicamente importantes pueden ser agrupados en las siguientes categorías: blopotenciales, presión, flujo, dimensiones (imagenes], desplazamiento (velocidad, aceleración y fuerza), impedancia, temperatura y concentraciones químicus. Como se observa, el mesurando que nos ocupa aqul (potenciales evocados] entra en la categoría de biopotenciales. POTENCIAL ES EV OCA DOS La respuesta eléctrica del cerebro a un estímulo especmco es referida como potencial evocado. Por su pequeña amplitud, especialmente en relación con el EEG (Electroencefalograma), los potenciales evocados usualmente no pueden ser identificados en un registro de rutina de EEG; sin embargo con la ayuda de técnicas de promediación-señal con la computadora (como es el caso del software PCLAB818) es posible incrementar la amplitud de la señal para que asícea claramente delineada. Los estudios de potenciales evocados proporcionan un medio muy Útil para la evaluación de la integridad funcional de nervios censoriales. Dichos estudios permiten la detección y localización de lesiones de estos nervios sensoriales; adem& de ayudar al establecimiento o soporte de un diagnóstico neurológico; o bien de ayudar en el seguimiento del curso de ciertos desórdenes (neurológicos); y también ayudar en la evaluación de funciones sensoriales (visiÓn,oído) cuando no es posible aplicar pruebas subjetivas o de comportamiento al paciente, como puede ser el caso de niños. Así tenemos por ejemplo que, las técnicas de potenciales evocados han incrementado su importancia en la evaluación funcional de los sistemas de conducción visual. El método preferido de estimulación del sistema visual, es mediante un "tablero de damas" en el cual, se van alternando un cuadro oscuro y un cuadro iluminado sin ningún cambio en la luminiscencia total. El sujeto (paciente)es sentado a 1m de este tablero y mantiene su vista fija en un foco, en su centro. En respuesta a la estimulación visual, un potencial es generado en la corteza occipital, el cual es registrado por un electrodo situado en el cuero cabelludo en la parte media-occipital y referenciado (tierra)a otro electrodo en la región 'inastoides" 6 'inedia frontal". El tablero esta hecho para cambiar (oscuro-luz)aproximadamente 2 veces por segundo, y l a respuesta a 100 cambios e s amplificada, promediada en la computadora para después ser desplegada. 3 Generalmente, el témino transductor es definido como un dapositivo que convierte una forma de energía en otra. Un sonsor convierte el mesurando físico a una salida eléctrica. El sensor debe de responder solamente a la forma de energía presente en el mesurando, excluyendo las demás. El sensor debe de interfasar con el 'bistema vivo" de tal manera que minimice la energía extraida, mientras se ha invadido también de manera mínima. Muchos sensores tienen un elemento sensor primario como un diafragma, el cual convierte presión en desplazamiento. A continuación un elemento de conversión variable, convierte el desplazamiento en voltaje, Algunas veces la sensibilidad del sensor puede ser ajustada en un amplio rango a través del elemento sensor primario. ACONDICIONAMIENTO DE LA SERAL Usualmente el sensor de salida no puede ser directamente acoplada al despliegue en el dbpositivo. L o s acondicionadores de señal simples sólo amplifican y filtran la señal Ó acoplan la impedancia del sensor con la del despliegue. Frecuentemente las salidas de los sensores son convertidas a una forma digital y luego procesadas por algun circuito digital Ó un microprocesador, en donde es posible transformar la señal, del "dominio del tiempo" al "dominio de la frecuencia". DESPLIEGUE DE LA SALIDA Los resultados del proceso de medición deben de ser desplegados de tal forma que el operador (humano)del instrumento pueda entender fácilmente. Tal vez la mejor forma de despliegue sea la num6rica 6 la gráfica, dacreta o continua, permanente o temporal- dependiendo del mesurando en particular y cómo el operador usará la información. Si bien la mayoda de los despliegues dependen de nuestro sentido visual, alguna información (señales ultrasónicas Doppler, por ejemplo) es mejor percibida por otro sentidos (aquf, el sentido auditivo). ELEMENTOS A U N LiAR ES Una señal calibrada con las propiedades del mesurando debe ser aplicada al sensor de entrada Ó a la línea de procesamiento de la señal tan pronto sea posible. Muchas farmas de control y de retroalimentación pueden ser requerida para lograr obtener el mesurando, purrs ajustar ei semor y acondicionar la señal, y para el flujo directo de la 4 salida hada el despliegue, almacenanilento 6 trammtsión. El control y la retroalimentación pueden ser automáticos Ó manuales. Los datos pueden ser almacenados momentaneamente para encontrar los requerimentos del acondicionamiento de la señal o bien para prevenir al operador para que examine los datos que preceden condiciones de alarma. O también los datos pueden ser almacenados antes del acondicionamiento de la señal, para que cal diferentes esquemas de acondicionamiento puedan ser utilizados. Principios convencionales de comunicación pueden ser frecuentemente usados para transmitir datos a distancia, como pueden ser estaciones de enfermería, centra medica,etc. Y para finalbar esta rápida introducción a los sistemas de instrumentación, vale la pena mencionar la siguiente: CLASiFlCACiON DE INSTRUMENTOS BiOMEDiCOS El estudio de instrumentos biomédicos puede ser aproximado en al menos 4 puntos de vista. Técnicas de medlclón blomédicas pueden ser agrupadas de acuerdo a la cantldad quo es sensada, como la presión, flujo o temperatura. Una ventaja de esta clasificación es que la hacen diferentes métodos para la medición de cualquier cantidad fácil de comparar. Un segundo esquema de clasificación usa el principio de transducclón, como puede ser resistiva, inductiva, capacitiva, ultrasónica Ó electroquímica. Las técnicas de medición pueden ser estudiadas por separado por cada sistema fbioiógico, como los sistemas cardiovascular, pulmonar, nervioso y endocrino. Esta aproximación aisla todas las mediciones importantes para especialistas que necesitan saber algo sobre una área especifica, pero tal vez coincide de manera considerable con las dos clasificaciones anteriores. Finalmente los instrumentos biomédicos pueden ser clasificados, de acuerdo a la especialidad mddica clínica, como puede ser pediatría, obstetricia, cardiología, radiología,etc. Esta clasificación resulta valiosa para personal medico que esta interesado en instrumentos especializados. No pretendo en esta exposición escrita repetir, a menos que sea necesario,lo que ya se explica en el manual mencionado; sino aportar elementos que sumados a dicho "Manual", ayuden lo mejor poslble a qulen retorne este proyecto, que por sus caracterífticas tiene posibilidades muy variadas, como se podrá ver mas adelante. Así, espero contribuir con esta 'pequeñisima parte" tanto al enriquecimiento del software como de quien retome esta idea. 5 CAPITULO I Es conveniente abordar el problema de manera general, en nuestro caso el problema es familiarizarse con un programa realizado en lenguaje C, con el compilador TURBO C 3.1 ,que cuenta con un código de mas de 2ooo líneas. Para ello es necesario describir el programa principal; el cual cuenta con lo siguiente: Macros # define NUMV 20 define NUMM 20 define NMOPC 16 define BASE 0x333 define desp 70 ## define n-datos 1024 # define REG struct reg # # # # en donde los identificadores son: NUMV número máximo de ventana que se utiiizan NUMM número máximo de men& que se utilizan NMOPC número mMmo de opciones que contiene un menú BASE dirección base de la tarjeta PC-LAB818 desp desplazamiento de la primera gráfica n-datos número m&mo de datos que se pueden capturar por canal REG estructura de arreglos tipo char que guarda los datos del paciente Variables Clobales Cuenta con el siguiente arreglo bidimensional: int dato [ 161[n-datos] en donde se guardan los datos capturados por la tarjeta, en donde observamos que se tiene una capacidad máxima de 16 canales y 1024 datos por canal. 6 Archlvw utlikadw de la Blblldeca de Turbo C # include cmath.h> # include <stdiib.h> ## include <ctype.h> # include <io.hr # include cconio.h> # include <alloc.h> # include <string.h> # include <stdio.h> # include <dos.h> # Include <blos.h> # include <dir.h> # include <graphics.h> ## include <proceSS.h> Archivos crsados (que n o se wncuwntran @n la bibildwca de Turbo C) include "ventanas.h" include "menus.h" include "princa.h" (antes llamado princ.h) include '%onf.h" include "grafJft.h" # include 'pot-ev0.h' # include 'Sa1var.h" # include "fi1tros.h" # include 'Wt .h" # ## # # # Estos archivos creados, son en realidad como se podrá intuir, el cuerpo cornpieto del programa, dividiendolo así en modula diferentes de acuerdo a sus funciones. Sin embargo el precio de esta modulandad se paga con la memoria utilizada, ya que como se describe posteriormente, esto conduce a problemas al compilar e intentar correr el programa. 7 Contamos con sus variables globules, y funciones de inicialización como son: inic-r(&p, nombrea); -Aquíse inicializa en blanco el registro de datos del paciente y el nombre del archivo a cargar o salvar. conf-Ink (vol-max, canales, num-can, longitud, amp, off-y, Ernum-adq); -En donde se inicializan todos los canales y parametros de las gráficas con los valores por default. A continuación contamos con las funclones que inicializan el modo gráfico y crean las ventanas correspondientes al menú principal: vengrinc(); ven-menugrin(&opc) Donde la variable "opc" guarda el valor de la opción seleccionada. El uso de esta variable que se encuentra en el archivo 7nenus.h' es fundamental en la creación de men& y ventanas aquí utilizados. Posteriormente tenemos la estructura b&ica del programa principal, en una sentencia -switch()- , contenida en una estructura -do/while-, cuyas opciones representan las diferentes funciones que realiza el programa: Así tenemos los casos: case O: cargar(); en donde es posible realizar la lectura de archivos, ya sea capturados por este programa o bien archivos con la extensión .DAT. case 1 :config(); en donde se realizan los cambios que se requieran para la configuración de la tutjetu. 8 en donde se procesa ¡asefial captnirada con el calculo de la FFT y es posible graficatla. cam 3: llltlw(]; aquí se realiza el filtrado digital(filtros:pasa-bajas, pasa-altas y rechaza-banda)y la gráfica correspondiente de la señal previamente capturada. case 4: pot-evoc(): aquíes donde se realiza la captura de la señal fisiológica. case 5: salvar(): como su nombre lo dice, salva o escribe el archivo en disco, de la señal capturada. case 6:spawn[ P W AIT, " direc.exen,NULL); en donde es posible con esta funclón de 'C',ejecutar otro programa; en este caso se ejecuta el programa denominado direcexe en donde se visualizan los archivos contenidos en el directorio actual. case 7salida(): en donde es posible seleccionar la opción de "salir"o "no" del programa. 9 CAPlTULd 11 Complemontaclón al programa original Inicialmente al retomar este proyecto se plantearon vanas ideas para su enriquecimiento; como son: - La posibilidadde poder capturar y procesar otro tipo de señal fisiológica, como puede ser el ECG o el EEG. - De desplegar mensajes de ayuda para mayor facilidad del usuario. - De vkualizar el directorio de archivos existentes, sin tener que salir al control del sistema operativo. Asíme di a la tarea de adentrarme en la programación en C, para poder cumplir con las espectativas planteadas. Es oportuno ahora mencionar que, en base a ml experiencla, y en primera instancia para poder compilar el codigo fuente PCLAB818.C, y por consiguiente correrlo hay que tomar en cuenta los siguientes puntos: 1) Hay que trabajar en una computadora cuya memoria RAM sea al menos de 4 MB. 2) Dicha computadora debe de estar controlada por el sistema operativo versión 6.2 . 3) El modelo de memoria del cornpilador debe ser "HUGE". 4) Es recomendable utilizar el compilador de Turbo C versión 3.1, que es donde fué creado el programa. Y ahora viene la pregunta de porque son necesarios estos puntos?, quien sea experto programador muy probablemente tenga la respuesta; pero por ahora va la opinión de un principiante que espera responder un poco a esta pregunta. Estos puntos contemplados evidentemente nos dicen que hay problemas con el manejo de memoria del programa, y esto a simple vista puede suponerse al ver en el programa principal tantas librerias incluidas(lasde biblioteca de Turbo C y las creada). Por lo que toca al primer punto; es lógico pensar que debido al tamaño del programa se requiera una cantidad mhima de Megabytes en RAM(4en este caso). En cuanto al tercer punto, el hecho de utilizar el modelo de memoria "HUGE'(enorme) significa en simples palabras que se tiene aquí una gran cantidad de código y datos, en donde las estructuras d e datos pueden superar los 64 K(para myor IntormaclÓn: CAP.10 -Modelos de memoria-Llbro TURBO C/C++ 3.1 -Manualde Referencia-). 10 El cuarto punto es conveniente, pero ciaro no necesario, ya que cualquier versi6ri posetnor a la versión utilizada de Turbo C, debe ser compatible; sin embargo hay que considerar que necesariamente habrá que actualizar parte de la sint& y probablemente de la semántica, debido a las diferencias de los compiladores; de no tomarse en cuenta esto, seguramente aparecerun una gran cantidad de mensajes de advertencia(Warnings)incluso hasta de errores al momento de compilar el programa. El segundo punto es crucial, ya que, en mi caso me llevó semanas decubnrlo, incluso el creador del programa, ignoraba esta dificultad. Y como ya se mencionó, con el sistema operativo 62, no hay dificultades para poder compilar el programa; pero al intentar trabajar en una máquina controlada por un sistema operativo diferente, aparecerán errores tales como: Out of memory - tinker error:Group overflowed maximum size:DGROUP Este Último mensaje como se podrá ver en la ayuda del compllador ocurre cuando demasiados datos fueron definidos en un segmento, o bien cuando segmentos de mismo nombre en diferentes archivos fuente fueron combinados; o también cuando al combinar los segmentos del grupo de datos excede los 64K , como ya se había advertido al momento de utilizar el modelo de memoria "HUGE". Con esta informaclón puedo decir que, el sistema operativo 6 2 configura la memoria de la máquina(computadora) de tal modo, que se adapta a las necesidades del programa. Una probable respuesta está en la manera en que el CONFIG.SYS(MS DOS 6.2) configura el sistema. En donde a dicho archivo se le indicarán los comandos, ilamados comandos de configuracón. que realizarán dicha función en el sistema en un inicio(para mayor lnf:-LibroM9 DOS 6.2 Edición ospeciai CAP 11) - Por ejemplo el CONFIGSYS del MS DOS 6.2 que yo siempre us6 esta de la siguiente manera: [COMMONI BUFFERS=X) F ILES=x) BREAK ON [4J361 DOS=HIGH DEVICEH IGH =A:\H Y MEMSYS DEVICEHIGH=A:\RAMDRIVESYS4096 5 1 2 1024/E REM DEViCEHIGH=A:\EMM386.EXE NOEMS En donde se definen un total de 20 buffers de archivo que el DOS reserva para la transferencia de infomacibn de y hacia el dbco. Un número total de 20 archivos que pueden estar abiertos en cualquier momento. 11 El 50s est6 cargado en e1 Brea de rrierrtoria alta. Los controladores dispositivo HYMEMSYS, RAMDRIVESYS, y EMM386.B(E8son cargados en un bloque de memoria superior, también conocida como memoria reservada. El HIMEMSYS administra la memoria extendida, el RAMDRIVESYS utiliza una porción de la RAM para simular un dico duro y finalmente el EMM386.EXE utiliza memoria XMS, con el objeto de emular memoria E M S y proporcionar bloques de memoria superior. Por consiguiente, de querer trabajar con otro sistema operativo sugiero, salvo una mejor opinión, ver que pasa con el CONFIGSYS del cisterna elegido. Va aquípues, la primera propuesta a quien retome este proyecto, en cuanto a la optimización del manejo de memoria por parte del programa. Una manera es, tratar de introducir lo menos posible , nuevos cambios al código ya existente: trabajando por separado la función que se quiera implementar haciendola un programa ejecutable aparte; para después desde el programa principal llamaria en el momento en que se requiera. 12 VENTANAS DE AYUDA Para la elaboración de dichas ventanas fué fundamental la utii&acónde ius librerías que fueron creadas para su propósito, y me refiero u las librerías: ventanas.h menvs.h Y como ya se mencionó anteriormente, debido a los problemas ocasionados por el 'ho óptimo manejo de memoria", decidí hacer estas ventanas de ayuda aparte, es decir con la ayuda de las librerías mencionadas se hizo el programa y se creo el ejecutable para despues llamarlo desde el programa principal cuando fuera requerido, de esta manera la memoria no es utillzada a menos que se llame ai programa. Para ello creo que vale la pena mencionar nuevamente y de manera general como se utiliza la libreria de -ventanas.h. Esta librería depende de 5 archlvos de biblioteca de Turbo C, los cuales deben de ser declarados antes: coni0.h - al1oc.h string.h st dio.h dos.h !bentanas.h" Una vez hechas estas declaraciones previas, se procede a deíinlr el número de ventanas a utilizar con el siguiente macro: # define NUMV ntv donde 'htv" es el número total de ventanas. Hecho lo anterior procedemos a utillzar lac funciones: 1) iniclzvent 2) caractvent 3) crear-v 4) activa-v 5) cierra-v Para la función 1) lnicizvemn-vent, xl, y 1, a,y2, sombra, f-despllegue) Esta funcon se encarga de reservar memoria para el área de la ventana. En donde los parámetros: n-vent = Indica el número de ventana declarada. (Entero) xl,y 1,A?,@, = Indican las coordenadas de la ventana. (Entero) sombra = Indicasi la ventana tiene efecto de sombra. (Entero) 13 !-despliegue = Este pardmetro sehala la forrricl en que la ventaria hard su apar¡c¡dn. ‘Ii= Forma instantánea L Forma lateral ‘Pi= Tipo persiana (Caracter] I - I, Para la función 2) caradvent(n-vent, c-f, c-m, c-titulo, c-texto, -t,titulo) Esta función se encarga de guardar en la memoria las caracterkticas de presentación de la ventana. En donde los parámetros: n-vent = Indica el número de ventana. (Entero] = Indica el color de fondo. c-f (Entero) = Indica el color de margen de la ventana. c-m (Entero) c-titulo = Indica el color del título de la ventana (Entero) c-texto (Entero) = Indica el color del texto de la ventana. t-mp-t = Se refiere al tipo de margen. (Cadena) Para la función 3) crear-d n-vent) Esta función coloca la ventana en la pantalla, de acuerdo a la caracteristicas especificadas en las doc funciones anteriores. Para la función 4) adlw-v(n-vent) Con esta función se determina el área real de trabajo, y coloca al cursor en las coordenadas (1 , I ) de la ventana. Para la funclón 5) clena-v( n-vent) Esta funcidn se encarga de borrar de la pantalla la ventana indicada y recuperar en pantalla la ventana sobre la cual estaba sobrepuesta dicha ventana . 14 f i r con la ayuda de dicha funciones fue prssible crew l a ventaria de ayuda, que finalmente se decidió repito, hacerlas en un programa aparte(AYUDA.EXE)debido a los problemas con la memoria ya mencionados. Como se podrá ver en el listado que se presenta al final del reporte, si se decide retomar esta idea, es posible agregar o modificar las ventanas necesarias de acuerdo al criterio del progrumudor. Un vez hecho este programa ejecutable de nombre "AYUDA.EXE", para su incorporaci6n al programa PCLA8818, se aprovechd la librería de 'tnenus.h': para la cual como ya se explica en la sección de "Rutinas para la creación de menus y ventanas", las caracte6ticas ya mencionadas de las ventanas creadas. Y al igual que con las ventanas, tanto el número de menús como el número de opciones se deben de indicar con macros de la siguiente manera: # define NUMM n-menus # define NMOPC nm-opc donde n-menus, es la cantidad total de menús que se van a utilizar y nm-opc es el número máximo de opciones que se van a manejar. En dicha librería, se cuenta con tres funciones básicas para la creación de menús: 1. inichenu 2. llenamenu 3. creaopcvnt Para Inichnu(n-menu, t-opc, c-t, cf) tenemos que esta función se encarga de declarar el número de menú, y guardar en memoria sus caractemticas mas importantes. donde: n-menu = Indica que número de menú se esta declarando. (Entero) t-opc = Indica cuantas opciones tiene este menú en particular. (Entero) c-t = Indica cual va a ser el color de texto que va a estar indicando la opción en (Entero] turno. = Aquíse indica cual va a ser el color de fondo de la opción en turno. c-f (Entero) Para Ilenamnu(n-mnu, n-opc, x, y, todo) tenemos que esta función se usa para la numeración y colocación de las diferentes opciones del menú n-menu. donde: nopc = Indica el número de opcidn con el que se va a trabajar. (Entero] 15 %.,y = (Entero] indican Ius coordenadas en que se ponelre el texlo. texto = Es el texto que se escribirá en pantalla, y que identificará a la opción (cadena) nppc. Para creaopcmt(n-menu, n-veni) cuyos parámetros ya se explicaron, tenemos que esta función cuenta con dos usos. El primero es que, pone el menú en la ventana indicada, para que se elija la opción deseada; y el segundo es que, después de elegir dicha opción, devuelve un entero que es el valor de la opción que se eligió. En esta Última función está el enlace con el programa de "AYUDA.EXE", ya que el valor de la opción elegida se guarda en una variable llamada: opc. Y como se puede observar en el listado de ?nenusa.h", que se anexa al final del trabajo, las opciones pueden ser: -La tecla de ESCAPE -La tecla de ENTER -Las teclas del CURSOR Y además las teclas de las letras "A" y "a" para indicar la palabra ayuda. Es por esta pequeña diferencia que decidí renombrar el archivo "menus.h" como "menusa.h", los cuales difieren únicamente(comose puede ver en el listado), en la sentencia switch que se muestra a continuación: swltcyc) { caso 65: opcespawnY P-W AIT,'ayuda.exo",NULL); Iyopc===1) { perror('Error from spawn"); *xly 1); 1 broak case 97: opc=spawnYP-W Alt,' ayuda.exe' ,NULL); n(opc===1) { penor("Error from spawn"); e m1); 1 break: 1 Como se puede observar en el código al seleccionar la letra "A"(65) o bien "a"(97), esta vez no se guarda un valor, sino que se invoca a la ejecución del programa 16 "AYUDA".Esto u través de la función de control de procesos spawni(),cuyo prototipo se encuentra en la librería pr0cess.h (para mayor información en CAP 22-Funciones de . control de Procesos- de Turbo C/C++ 3.1 "Manualde Referencia') Dicha función lo que hace es ejecutar otro programa, en nuestro caso , el programa "ayuda"[denominado proceso hijo], dejando suspendida la ejecucibn del programa que conti8m la llamada spuwnl()(denominado proceso padre) hasta que el proceso hijo termine. Cuando las funciones spawn tienen éxito no devuelven ningún valor. En caso contrario, devuelven -1 y la función psrrofo se encargará de el error detectado, que puede ser: -Argumento err9neo -Demasiados argumentos -Archivo no encontrado -Error de forrnato de spawn -Insuficiente memoria libre 17 VENTANA DE DIRECTORIO Para la creación de dicha ventana, al igual que en las ventanas de ayuda, se utilizaron las libredas ya comentadas: -"ventanas.h" -'henus.h' Cabe aclarar que esta Última librería, se utilizó tal cual, sin la modificaci6n hecha para las ventanas de ayuda, ya que éstas no son utilizadas aquí. Y se continúa aquí con la propuesta de trabajar con un programa aparte para después hacerlo ejecutable, y mandarlo llamar desde donde se requiera mediante las función spawn. En nuestro caso como podemos observar en el programa principal (cuyo listado se encuentra al final 1. tenemos que éste difiere del original en que cuenta con un caso mas: 8 case 6: resuitwpawnqP-WAIT, 'dlrec.exe', NULL): ii(resuit==-l) c penor(' Error from spam'); exiy 11: 3 break; En donde como ya se explicó anteriormente, mediante la función spawn1 llamamos al programa ejecutable, esta vez de nombre direc.exe , cuyos principales punta del código mencionaremos a continuación. Para visuaiizar los archivos existentes del directorio actual de trabajo, es decir donde se encuentre corriendo el programa PCLAB818.EXE , consideré oportuno utilizar la ESTRUCTURA DE DATOS conocida como LISTA LlGADA(doblemente].En donde como es sabido cada elemento de la lista se conoce como NODO, y contiene varios campos, en nuestro caso 3: -Información -Direcci6nsiguiente -Dirección anterior El campo de información contiene el elemento real de la lista, el de dirección siguiente contiene la dirección del siguiente NODO de la Ma, y el de dirección anterior contiene la dirección del NODO anterior de la lista. 18 I ~ información *anterior información 4 *siguiente *anterior *siguiente b - Esquema de la lista utlilzada Esta lista(Estructura de Datos Dinámica) puede variar en tamaño(n6mero de nodos) al insertar o eliminar elementos, es decir de acuerdo a la capacidad de memoria RAM disponible de la computadora donde se esté trabajando. Así tenemos que, para la creación de la lista, en el código de D1rec.C contamos con las tres funciones encargadas de ello: -crea-ibta() -creanodo() -Insertar() Para lo cuál primero, hubo que definir la estructura "NODO", que como ya se mencionó cuenta con tres campos: -El de informacibn, en donde guardamos las caracterktlcas del archivo, a través de la estructura: druci ff bik{ char ff-resewd[q: /*usado por el DOS*/ char ff-aitrlb /*atributo del archivo*/ int ff-ftlme: /*hora de creación*/ ini ff-fdaíe: /* fecha de creación*/ long ff-fsis.; /* tamaño en bytes */ chew ff-name[ 131; /* nombre del archivo; */ x Esto con la ayuda de las funciones de directorio: -flndfirst(consichar %ombre,struci ffbikptr,lni atrib) -findnexí(druciffbik) En donde fndfirst() buscará el primer nombre del archivo que coincida con el apuntado por nombre, y la estructura(ffb1k) a la que apunta "ptr" se llenará con la información sobre el archivo, que para este caso en particular Únicamente se rescató el nombre del archivo y su tamaño en bytes. La funci6n findnext() continúa con la búsqueda iniciada por iindfirst(). 19 En tu función crecilMa(), corno se oherva en e¡listado, a tratr& de ¡ados funciones de directorio mencionadas, se dá la búsqueda de tos archivos con extensión 'w.*"(todos los archivos) que se encuentren en el directorio actual de trabajo. Para después mediante la función creanodo(),crear la estructura tipo NODO y almacenar en ella las caracterkticas del archivo(n0mbre y tamaño en bytes) contenidas en la estructura ffbk(denominada"a") , e inmediatamente después Irrrrrrtcir() este nuevo NODO creado en la lista. Como se puede observar en la lunclón prlnclpal de DIREC.C, una vez creada la lista a traves de la función crea-lbta(), lo que se hace es mostrar en pantalla los archivos almacenados (nombre y tamaño en bytes] mediante las funciones: -pagoone pagqdown Y como su nombre lo indica, con la primera función se recorre la lista y se muestra en - pantalla los primeros elementos(l0 como mibdmo) contenldos en la 'IXaglna-uno': para después con la detección de la tecla "enter"("return")mostrar la "página-abajo"(página siguiente). Existe también la función : -PaQe-uP y como su nombre lo dice lo que hace es mostrar la 'Página anterior"(paginaarriba], sin embargo ésta se omitió, para Únicamente recorrer la lista de 'inicio" a "fin", es decir algo parecido al comando dir del sistema operativo, es decir a través de la opción de "Directorio" , en una ventana se mostrarán los archivos contenidos en la ruta actual de trabajo. La función omitida se anexa también al final del reporte, por si se decide retomar la opción de recorrer la lista de: "fln"a 'inlclo"(6en sentldo contrario); de ser asf dlcha opcldn es posible adlclonarla al programa d1rec.c ,y llamarla en la función principal de manera similar a como se hace con la hnciÓn page-down ,es decir después de llamar a ésta, habría que agregar: 8 do( page-up(6opc. &nodogdual,&bander) )wtill* (((nodqactual)->ani)l=origen); La Idea original que tenía respecto a estas tres funciones (page-~ne~page-down~page-up) era para que el usuario al consultar la opción de "Directorio': tuviera a su vez las opciones de visualizar en pantalla los archivos de la página anterior o sigulente, si así lo deseaba; sin embargo por falta de tiempo esta Idea ya no se completó; por lo que aquí podría plantearse la propuesta de optimizar con estas y otras ideas, la opción de "Directorio", En la parte final de la función prlncipal, encontramos la función: -Ilbera-lkta La cual se encarga de borrar la tata, Ó dicho de otra forma, de liberar memoria que ya no será utilizada ,una vez visualizados los archivos en pantalla. 20 MANUAL DE USUARIO Este manual, como el lector se podrá dar cuenta, es practicamente igual, al ya reulizado por Norberto Mendoza, sin emburgo creo que vule la pena mencionarlo nuevamente, recalcundo ai mbmo tiempo Ius pequehas diferencias udicionudas ul programa original. El programa ejecutable es posible llamarlo por PCLAB818 o bien por PROY ECDI, ambos son exctamente el mismo programa, solo que con el segundo nombre se pretendió áitinguirio del original. Un vez cargado ei programa aparecerá en pantalla la ventana del menú principal: Cargar archlvo Conflgurar PC-LAB FFT Filtros Potenciales evocados Salvar Archivo Directorio Salir del S M e m a Y en la parte inferior, aparecerá también una ventana con lo siguiente: b c Ventana Anterior TArriba - &Abajo J Aceptar opción A Ayuda - En donde se trata de indicar con las letras remarcadas(blancas), las teclas correspondientes al teclado, que realiardn las funciónes que se indican con las letras no remarcadas(negras).Dichas funciones son generales para todo el programa. Así tenemos que con la tecla: Esc Se regresará a la ventana anterior, borrandose la ventana que estaba sobrepuesta. t y &- (Cursor] Será posible moverse de opción, la cuál se mostrará de color dlferente(fond0negro, letras blancas)a los demás renglones de la ventana. s(Enter) Se aceptará la opción de acuerdo al texto remarcado(fondo negro, letras blanca). A Aparecerá en pantalla una ventana de ayuda, en donde en algunas líneas se describirá cada opción. Es importante remarcar aquí, que para que dicha ventana 21 aparezca, debe de estar contenido en la ruta actual de trabajo de el progarria PROY ECDI(PCLABBlB), el programa AYUDA.EXE. Regresando al menú principal tenemos que al seleccionar: Cargar Archlva Aparecerá una ventana esperando el nombre del archivo que se desea cargar. Si el archivo no existe o se presiona la tecla de Enter , estando la ventana en blanco aparecerá un pequeño mensaje: No exbte archlvo", y se regresará al menú principal. SI el archivo existe, aparecerá el mensajelCargando archivo'. Para esta opción hay que considerar el formato del archivo a cargar, este puede ser nombre.DA1, o bien los archivos capturados por el programa, los cuales no tienen extensión. Configurar PC-LAB Aparecerá una ventana con el siguiente menú: Frecuencla de muestre0 100 Hz Seleccionar canales VoiiqJek l m de entrado Frecuencia de mudreo AI selccionar esta opción, aparecerá otra ventana que contendrá la posibles frecuencias de muestreo a elegir. 100 tu 5mhz lo00 hz 5ooo hz loo00 hz 20000hz 30000 hz El rango de frecuencias depende del número de canales activos de la opci6n Seleccionar canales. Es Importante que como la frecuencia de muestreo depende del número de canales activos, es importante que seleccione únicamente los canales necesarios y que estos sean consecutivos; ya que la frecuencia de muestreo máxima pura un canal es de 30 khz y esta se divide por ((can-ma can-min) + 1); en donde: can-max es el canal mayor activo can-min es el canal menor activo - 22 Seleccionar canales Aparecerá en pantalla la ventana con el menú: Canal O on Canal 1 on Canal 20ll Canal 3off Canal 4off Canal 5oii Canal bofi Canal 7011 Canal 8cM Canal ?off Canal 10 oii Canal 11 off Canal 12 otl Canal 13 011 Canal 14 off Canal 15 off -on- indica canal activo off lndlca canal lnactlw VoH4e máximo de entrada Aparecerá en pantalla un menú similar al anterior, con la diferencia de que, on y off no aparecerán, en su lugar aparecerá una cantidad con unidades de voltaje: +/- 5.0 V por ejemplo. Si es seleccionado algun canal[ mediante la tecla enter), aparecerá el menú de los posibles voltajes: +I*1o.ov +/ 5.0 V 9 +J- 2.5 V +/- 1.ov +J- 0.5 V FFT Aparecerá el menú: Grdlcar Calcular AI seleccionar la primera opción aparecerán las gráficas correspondientes a la Transformada de Fourier del archivo cargado. con la segunda opción se realizarán los cálculos de la Transformada Rápida de Fourier (FFT). Es importante mencionar que para 23 que aparezcan en pantalia ta grbfica, es necesario inciuir en la ruta actual de trabajo(directono actual) , los archivos BGI, los cuales contienen los controladores gráficos. Fiiiros Aperecerá en pantalla el siguiente menú: Filtrar Posa-anas off Pam-bajas off Rechaza-bandaoff AI seleccionar "Fiiirar"se realizarán los cálculos respectivos para los filtros activos y a continuación se graficará la señal filtrada. Se se selecciona cualquiera de las otras opciones se activará o desactivcará el filtro correspondiente. Potenciales evocados Aparecerú el siguiente menú: Adquisición Disparo por coros GrÚílca Número de daíos 256 Reset Adqubiclh En esta opción aparecerá el mensaje 'Espera disparo digiiar indicando que espera el disparo para comenzar la captura de datos. Una vez dado el daparo aparecerá el mensaje 'Adquiríendo datos" y se realizará la captura de datos. Una vez terminada la captura 5e regresará al menú de Pdenciales evocados. En el menú aparece el número de adquisiciones realizadas. Disparo por Aparecerá el menú: Ceros Unos El disparo indica el nivel de la entrada digital del puerto BASE comenzará la captura de datos. + O3 con que se 24 Crailca Aparecerá la gráfica de la señal adquirida con el menú: ESC Salk (C)rallca (A)mplitud (C)anal (Wmpo (N)Úmero de gróflcar (I)nicio ( R)otrocodor (S)eguir En donde será posible variar los parámetros indicados. En la opción de (I)nicio, las gráficas comenzarán desde el origen. En la opción (R)etroceder,todas las gráficas retrocederán una pantalla, en caso de que se ocupe mas de una, de lo contrario no pasa nada. En la opción (Sleguir, pasa algo similar solo que las gráficas uvanzuránuna pantalla Número de datos(Númerode datos que serán capturados) Aparecerá el siguiente menú: 256 512 1024 Por otro lado al seleccionar Reset se inicialia con cero el buffer de datos de todos los canales. Vale la pena mencionar, que en este menú de Potenciales Evocados es posible capturar también otro tipo de sefíales, como es el caso del ECG, muestra de ello esta presente en tres archivos capturados, que se unexan en el diskette, y se Ilumcrn: UNO, DOS y TRES. Salvar archivo Aparecerá el sigulente menú: Datos del paclenfe Nombre del archivo 25 Aiseleccionar la primera opci6n aparecer4 el siguiente menu: Nombre Apellido paterno Apellida materno Dlracción Teléfono Número de fliiaclÓn Fecha En donde como se observa será posible archivar los datos del paciente. En la segunda opción será posible darle nombre a la señal capturada. Directorio AI seleccionar esta opción aparecerá en pantalla una ventana con el nombre y tamaño en bytes de los archivos contenidos en el directorio actual de trabajo; es decir algo parecldo al comando dir del sistema operativo. Y al igual que para la opción de ayuda, debe ser incluido en el directorio actual de trabajo el programa direc.exe, de lo contrario no ser6 posible visualizar la lista de archivos. Salir del sistema Como su nombre lo indica, esta opción da la posibilidad al usuario de dar por terminado el programa seleccionando cualquiera de las dos opciones que aparecerán en pantalla: No si 26 CONCLWIONES El trabajo hasta aquí descrito, ha intentado ser enriquecedor, tanto para el inexperto programador que escribe estas líneas, como para el lector y el mismo software PC-LAB 818. Para el cuúl como ya se descnbi6 a lo largo de este reporte, tal vez las aportaciones reales sean en cuanto al manejo de las librerías: "ventanas.ha'y henus.h", para la realización tanto de las ventanas de ayuda como la de directorio. Asícomo también las observaciones y sugerencias en cuanto al manejo de memoria, como puede serio la aplicación de la estructura de datos dinámica conocida como 'lista doblemente ligada", para la opción de "Directorio" .Y tengo que ser aquí reiterativo írepresentó "especial" trabajo. en cuanto al punto del manejo de memoria que para m Es decir, en el sentido de que no obstante ser un programa grande(más de xxxl líneas], pienso que no es "adecuado" que se requieran más de 4 MB en RAM y que se presenten los problemas mencionados con el sistema operativo; ya que con esto se dkminuye la portabllldad del programa, punto fundamental en el buen desarrollo de la programación. Las sugerencias para la continuaciCIn de este proyecto, pienso que son ilimitadas, por io que quedan abiertas al criterio de quien retome el trabajo. . 27 HEMEROORAFlA MENDOZA, Pérez Norbert0 Seminario de Proyector ii Clam 212443 Grupo CL65 -Software PC-LAB 818México,D.F., 1995. 28 turbo C)C++ 8.1 Manual de referencia Ed.McGraw-Hili España, 1994. KAMIN, Jonathan. BATZ, Eric. HARRIS, Mattew. SHULMAN, Mark. MS-DOS 63: Edlción bpecialEd. Prentice-Hall, Hispano-Amencana$.A. - SANCHEZ, García G. -traduccióm MéX¡CO, 1993. MiCROS0FT, Corporation. MS-DOS6 Operailng System Plvs Enhanced Tools Ed. Microsoft Corporation U.S.A. 19?3. WEBSTER, John G. ENCYCLOPEDIA OF MEDICAL DEVICES AND INSTRUMENTATION Volume 2 Ed. Wiley Interscience U3.A. 1988 WEBSTER, John G. MEDICAL INSTRUMENTATION Applicatlon and Design Second Edition Ed. Houghton Miffiin Company U.S.A. 1992 29 ANEXO PROGRAMAS FUENTE PROY ECD1.C (PCLAB818.C) A4ENUSA.H DIREC.C AYUDA.C I PROY ECbl .C f Programa prlncipal */ # denne NUMV $39 # define NUMM20 # deflne FlMOPC 16 # define BASE( h ~ o o # deflne desp 70 # deflne n-datos 1024 # define REG slruct reg REG { 1; char nombre [25]: char paterno [2ü]; char materno [XI]; char direc [a]; chartel [2ü]: char num-lMSS [a]; char fecha [25]; int dato [16][n-datos]: # include <rnath.h> # include <stdlib.hz # Include <ctype.h> Include <lo.h> Include <conlo.hr include <alloc.h> include <string.hi include Qtdio.h> include <dos.h> include <bios.hz Include <dlr.h> Include <graphics.h> # Include qxOCBss.h2 # # # # # # # # # # Include‘Ventanos.h” # include “menusa.h” # Include”prlnca.h” # Include“c0nf.h” # include“graf-fft.h“ # Include“pot-ev0.h” # include ‘5aivar.h” # Include“fl1tros.h” # Include “m.W Int opc; Int sal = O; \ni num-dat = 256; Int irec-m =O; int num-graf = O: Int cantsraf = 3 lnt num-ad = O; lnt dkp =O; REG'p = NULL; lnt numcan [4]; Int nombre-a (441: Int longltud 1.41: Int v o l m w (161; Int canales [ 16); int amp [4]; lnt off-y 141; int pas-baj = O; Int pas-alt =O; int rech60 = O; Int result: harderr (error-hard): inlc-r (&p,nombre-a); conf-lnlc &ol-max, canales, num-can, longltud, amp, off-y, hnum-ad); ven-prln ( ); ven-ayuda( 1; do { ven-menu-prin (&opc): switch (opc) { case O: cargar [&p, nombre-a, vol-max, canales, num-can, longitud, amp, hum-ad, Bfrec-m, hum-dat, hnurngraf, gcantgraf, hdkp, &pas-ba), &pas-alt, &rech60):break: case 1: Conflg (vol-max, canales, &frecm, num-can); break; case 2: menu-FiT [canales, frec-m, num-can, amp, longltud, &num_graf,vol-ma, tkantgraf, off-y): break: c a e 3: flltros [&pas-baj, &pas-ait, brechM), canales, frec-m, num-can, amp, longltud, &num_graf,vol-max, &cant_graf,off-y, num-dat): break: case 4: pot-evoc (anum-dat, canales, frec-m, num-can, amp, iongltud, hnum-graf, vol-ma, &cant_graf, off-y, &num-ad, &disp);break; case 5: sabar (kp,nornbre-a, vol-max, canales, num-can, longltud, amp, Bnum-ad, &frec-m, bnum-dat, gnumgraf, hcant-graf, &dkp, Lpas-bal, &pas-alt, Brecha); break; m case 6: result=spawni[P_WAiT;'dlrec.exe",N u LL); lf(resuit==l) I P LLAMADA AL "/ penorrEnor from spawn"); PPROGRAMA*/ dt(1); /"DIREC.EXE./ 1 break: case 7: salida [&sal): break: clerra-v (1 ); 1 while [salI= 1): cierra-v ( 1 8); cierra-v (o); window ( 1 , 1 , 80,25): clrscr [ ); 1 MENWA. H Piibreria menusa.h cuya Únlca diferencia con menus.h se encuentra en la función crea-opcvnt(j*/ siruct menu { char n, color-t, color-f; } paraml [NUMM]; struct dato{ char x, y, iexto[78),dlrec[4];} textol [ N UMM][ NMOPC]; asgn-drc( nrn, ttiopc) char nm. ttlopc: { char 1,j; texto1[nml[Ol.direc[O] = ttiopc-1; textol [nrn][ttlopc- l].dlrec[l J = O; for [ i=1; i<ftiopc; I++) texto1[nrn][i].dlrec[O]= i-1; for ( 14;i4tiopc-1; I++ ] textol [nrn][i].dlrec[l]= 1+1; for [ 14;Kttiopc; I++ ) for ( ]=i+l:j<ttiopc: I++] { it [ textol [nrn][l].y== textol [nm]fl].y] texto1[nrnl[i].dlrec[3]= j; break: ] { elre textol Inrn][l].dlrec[3]= I; 1 for ( i=ttlopc-1; ¡>=O; --I ] for ( J=Ci; ]>=O; -1 ] { if ( texto1[nm][i].y== textol [nrn][l].y] { textol [nm][I].direc[2]= j; break: ) else textol [nm)[i].dlrec{2j= I; 1 I crea-opcvnt (nm,nv) char nm, nv; { char I,c, opc; struct ventana *dit dlr = &vent[nv]; opc = o; trn-cnrl-1,- 1); textbackground[ dir->color-f ); textcolor(dir-xolor-te ); for ( 14;icpararnlInm1.n; ++I ] gotoxy ( textol [nm][i].x, textol [nm][i].y); cputs( textol [nmllll-texto): 1 textbackground[ paran1[nrnj.color-f 1; textcolorj paraml InmJ.color-t 1; gotoxy( texto1[nrn][opc].x,textol [nrn][opc].y1: cputs( textol [nm][opc].texto1; Y whlle [. &=getcho)I= 27 ) 4 swiich(c) /%qui es donde se encuentra la fnlca dflerencla*f /* con respecto a la llbreqa menus.h*/ i case 65: opc=spawni[P-WAiT: ayuda.exe",NlJLL); /* LLAMADA AL*/ it(opc==-l) 4 perrorferror from spawn'); exIt(1); I* PROGRAMA */ i break; /+WECUTABLE*/ caso 97: opcspawnl(P,WAiT,"ayuda.exo',NULL); n(0pc==-l) f *DE*/ 4 perror Error born spawrr'); emi); 1 break; /*AYüDA*/ 1 If ( c = = O ) switch( c=getch() ] { case 72: opc = cambia(dlr, nm, opc, O 1; case 80: opc = cambia(dir, nm, opc, 1 1; cose 7 5 opc = cambia(dlr, nm, opc, 2 ); case 77: opc = cambial dlr, nm, opc, 3 1; break; break; break: break: 1 else if ( c == 13) tm-cnr( 6,7 I; return( opc ): 1 1 I trn-crsrt 6,7 return(-1 ); 1; cambla( dlr, nm, opc, seiec I stmct ventana *dit char nm,opc, selec; { textbackground( dlr->color-f ); textcolor(dlr->color,te 1; gotoxy[ texto1[nm][opclx.textol [nml[opcl.y I: cputs( texto1[nml[opc].texto ); opc = textol [nm][opc].direc[selec]; textbackground(paraml [nmj.color-f 1; textcolor[ paraml (nm].color-t ): gotoxy( textol [nm][opcl~ textol [nml[opcl.y 1; cputst textoi [nm][opc).texto): return(opc); 1 VI lrtlclzmenii(nm,itlope, clrt, elrrj char tttopc, ctrt, clrf, nm; I paraml[nml.n = ttiopc; paraml [nm].color-t = cirt; paraml [nml.color-f = clrf; 1 Ilenamenu(nm, nopc, x, y, texto) char nm, nopc, x, y, *texto: { texto1~nm][nopc]x = x; texto1 [nm][nopc].y= y; strcpyt texto1[nm][nopc].texto,texto 1; if( nopc == paraml (nm1.n- 1) asgn-drc( nm, paraml [nm].n); 1 DIRECC f COülGO DEL PROGRAMA DE DIRECTORIO'/ P DIREC.C*/ # define NUMV 2 # define N U M M 2 P üefinlciéndel rifmero de:'/ pventanos,menzsy opciones=/ # define NMOPC 10 # Include <dos.h> PUbrerlas del cornplladoP/ # include <dlr.hz # Include <graphlcs.h> # inciude <stdilb.h> # Include <process.hr # Include'i/entanas.h" fUbrevas creadas para la creaclgn"/ # tnctude "rnenush" /'de ventanas y men€?/ ,f' VARIABLES GLOBALE?/ typedef struct nodlto( struct ffblk a; struct nodlto %lg,*ant; } NODO; NODO *origen=NULL, *nuevo=NULL *ultimo=NULL*nodo,actuai=NULL; int dato4; lnt dat=O,bander=l; P FUNCIONES PARA LA CREACION DE LA LISTA */ /" DOBLEMENTE LIGADA*/ NODO *creanodo(structffblk *a) 1 NODO *p=NULL; p=(NODO')rnalloc(skeof(NODO)); E.Aslgnacl#ndin rnlca d e / ifllP1 f*rnernorla+/ prlntfrln Error en la aslgnaclgn de rnemorld'); else { strcpy(Ip>aj.ff-name,a->ff-narne); /+Copiadel nombre y */ (p->a).ff-fske=a-~ff-fske; PnSmero de byes der/ p>ant=p; Parchivo, a la estructura*/ p-xig=NULL; P NODO*/ 1 1 returnlp); f FIiNCIC" PARA LA CR€ACIQNP€ LA LISTA "f P DOBLEMENTE LIGADA*/ NODO *lnsertar[NODO *nuevo, NODO "origen, NODO *yultimo)) t if (If*uitimo]] { *uitimo=nuevo; return(nuevo); p Primer NODO de la lista*/ 1 eke rult1mo)-rslg=nuevo; PConexign del ULTIMO NODO*/ (~ultlmo)->slg)-~ant=~ultimo]: Pde la lista, con el NUEVO*/ *u1tlmo=nuevo; returntorigen): f NODO creado */ crea-Its ta () ( struct mlk a; register Int fln; fin=findflrst~".*', &a, O);fBúsqueda del primer archivo*/ Pcon la exienslgn *.* */ P Es declr busca todos los+/ do P Archivos del dlrectorlo*/ {dot++; factual"/ nuevo=creanodo(&a): If(nuev0) orlgen=inseriar(nuevo,origen,&ultimo]: else returnO; Rn=flndnext(&a];PContlMa la busqueda iniciada por/ 1 1 whlle(1fln); P findflrsP/ P FUNCIONES PARA LEER LA LISTA"! P Y MOSTRARLA EN PANTALLA*/ page-down(1nt *opc,NODO 'pnodo-actual)) { char temp[í!ü],ternpy[3],tempt [So]; int i=O,ref: res=daWlO; if( (resi=ü)&&(dato=-dat-res)) I inickvent(0.10,10,40,res+ 11,I ,'I1); caractvent(0,LiGHTGRAY,BLACK,BLACK,BLACK,"CD",'"'): crear-v [O); activ a-v (o); Inickrnenu(O,res,WHITE,BLACK); 1 else { InicWent(0,10,10,40,21 ,l ,'It]; caractvent(O,LIGHTGRAY,BLACK,BLACK,BLACK,"CD",'"'): crear-v [O); actka-up); inlclzmenup,iO,WH ITE,BLACK); 1 do( Itoa(dato+1,tempy, lo]; strcpy(temp, tempy); dato++: strcat(temp," "); strcat [temp, [ pnodo-oc tual)->a).ff-name); itoa([~nodo,actual)->a).tt-ísize,tempt,10]; strcat (temp," "I: strcat (temp,tempt): llenamenu (O,l,l ,i+l ,temp); I++; if (((%odo-actual)-)sig)==NULL) break: else [*nodo-actual)=f+nodo-actual)->sig; if(l==lO) break; } while((pnodo-actual)->sig)l=N ULL); if( (dato==dat-l)&&(resi=l)) { Itoa(dato+l,tempy,lO); strcpy(temp,ternpyj: strcat(temp," strcat (temp,(~nodo-actual]-~a).rf.-name]; ¡toa(( pnodo-ac tual)->a).ff-fsize,tempt, 10): 'I): strcat(temp:' "); s trcat (temp,temp t); lienamenu p,res-l,l ,res,temp); 1 *opc =crea-opcvnt (0.0): cIerra-v(O); x P C:ONTIt.lliA LA FIJNCION PAGE-DOWN"/ if[ [res==l)&&[dato+lO~=dat-res+lO~ ] I Inlckvent(0,10,10AO,res+ll,i,'l'); caractvent (0,LI GHTGRA Y, B LACK,B LACK,BLACK,"CCY',"'); crear-v (O]; activa-v p]; inlckmenu(ü,res,W H ITE,BLACK); itoa(datot1,tempy,lü]: strcpy(temp,tempy); strcat [temp," "1; strcat (temp,(?nodo-ac tual)->a).ff-name); ltoa(((.nodo~actualJ-~a).ff~Fske,tempt,10); strcat(temp," "); s trcat [t emp,t empt]; lienamenu (0,res-l,1 ,res,temp); *opc =crea-opcvnt (ü.0): clerra-v (O); I 1 page-up(lnt *opc,NODO *rnodo-actual), int *bander) { char temp [a] ,tempy[3],tempt (SO]; Int i=O,Ind,res; res=daPJ610; lfrbander==1] {If (resi=O) { for(ind=l;ind<=rest9;ind++) { If ( rnodo-oc tual)==orlaen) return; ?nodo-ac tual]=rnodo-ac tuapant ; 1 itoa(dat-lnd,tempy, 10); s trcpy(temp,tempy); dato=dat-lnd; *bander&: I 1 eke I for(lnd=l;lnd.c=2O;lnd++] i I if(pnodo,actual)==origen) return: rnodo-ac tual)=rnodo-ac tual)-rant; Itoa(dato-20,tempy, 10); s trcpyttemp,tempy]: dot o=dato-X): 1 in¡c~ent~,10,10,40,21,1,'¡'~: caractvent (0,LIGHTGRAY,BLACK, BLACK, BLACK,"C D":"); crear-vp); activa-vp); inlchmenup, 10,W ii iTE,BLACK): do{ itoa(dato+1,tempy,10); strcpy(temp,tempy); dato++; strcat(temp," s trcat(temp.(rnodo-ac tual)->a) .ff-name); Itoat[ pnodo-actual)->a).ff-fsize,!empi,lO); strcat (temp," "); strcat (temp.tempt): lienamenu p,i,l,l+l,ternp); 'I): I++; If ((ynod0,actuai)->sig)==NULL) break: else modo-actual)=rnodo-ac tual)-Xig; If(¡== 10) break; 1 whlle([~nodo-actual)->slg)!=N ULL): *opc =crea-opcvnt (0,O); cierra-v p]: page-one(lnt 'opc, NODO '~nodogctual)) { Inty: char temp(201,tempy[3],tempt [80); *nodo,actual=orlgen; If(dat40) { inickent (0,10,10,40,dat+ll,1 ,'I1); 1 caractvent(0,LIGHTG RAY,BLACK,BLACK, BLACK,"Cü,"'); crear-v (O); act b a y (O); lnlctnnenu(O,dat,WH ITE,BLACK); eke { 1n1ckent(0,10,10,40,21,1,'la); caractvent(0,LIGHTGRAY,BLACK,BLACK,BLACK,"C[T',"'): crear-v(O); actIva-v (O); Inlctnnenu(O,IO,WHlTE,BLACK); I do{ Itoa(dato+l,tempy,lO); st rcpy(t emp,t empy]; dato++; strcatttemp," strcat (temp,Irnodo-ac tual)->a).ff-name); Itoa(( rnodo-ac t ual)->a].ff-fslze,t empt,1O); strcat(temp," strcat (temp.1empt): llenamenu (O,dato-l,l ,dato,temp); 'I); 'I); if((~nodo-actual)-xlg)I=N U LL) pnodo-actual) =rnodo-actuot)->slg; if(dato==10) break: ) whlle((~nodo~actual]-)sig)l=N U LL); lioa(dato+l,tempy,lO); strcpy(temp,tempy); strcat(temp," strcat [temp,(j*nodo-actual)-~a].ff-name); Itoa((~nodo~actual)-)al.tthlze,tempt,10); st rcat(temp." "1: strcat(temp,tempt): llenamenu (0,dato.l ,dato+l,temp); 'I): 'opt =crea-opcvnt @,O); clerra-v(O); I P FUNCION PARA LIBERAR MEMORIA "f libera-lkta() 1 /*libera la memoria asignada*/ NODO *borra=NULLlmove=NULL; move=origen; /Se mueve+/ borra=origen:Ppara borraf/ do I move=move-ag; free (borra); borra=NU LL; borra=move; )whlie(movel=NU LL); origen=NULL; Ppara lnlciallzar nuevamente los nodos*/ uliimo=NULL: 1 P FUNCION PRINCIPAL'/ malno { struct ffbik a; register int fln; int opc; crea-lista(); page-one(&opc,&nodo-actual): if(((nodo-actual)->slg)l=NU LL] do( page-down(&opc,&nodo-actual); 1 while ([(nodo-actual)-%lg)l=NULL); Ilbera-ilsta(): PAGEUP.C page-up(int *opc,NODO *f*nodo-actuai),int *bander) { char temp[20],tempy[3],ternpt[80); int I=O,ind,res; res==dot%lO ifpbander==l) {if(resl=O) { for(ind=1;Ind<=res+?:ind++) { it(~nodo-actual]==orlgen) return; rnodo-ac tual)=rnodogc tual)->an1; 1 Itoa(dat-lnd,tempy, 10); strcpyItemp,tempyl: dato=dat-ind: *bander=O; 1 1 eke I I 1 for(ind=1;ind<=X);ind++) If((%odo-ac tual)==origen) return; rnodo,actual)=rnodo-ac tual)->ant; ItOa(datO-20,tempy,10); strcpy(temp,tempy): dato=dato-20: inicizvent(0,10,10,4021,l,'I1); caractvent(ü,LIGHTGRAY,BLACK,BLACK,BLACK,"CD",.'"'); crear-v (0); act iva-v (O); inlcimenu(O,lO,WHiTE,BLACK): do( ltoa(datot1,tempy,lü]; strcpy(temp,tempy); dato++; strcat (temp," "); of rcat(t emp,(rnoda,aetual)-sci) .tt-name): Itoa[[ modo-actual)->a).ff,fslze, tempt,lü); strcat(temp," "1: strcat [temp,temp1); llenamenu (ü,l,l ,It1,temp]; I++; If ((pnodo-actual)->slg)==NULL) break: eke ("nodo-ac tual)=enodo-ac tualpsig; if(i==10) break: } whlle((("nodo,actual)->slg)I=NULL]; *opc =crea,opcvnt p,O); clerra-v (O]; AY U0A.C P PROGRAMA D E AYUDA.C*/ # define NUMV 3 # include <conlo.h> # include <alloc.hr # include <strlng.h> # Include <stdio.hr # Include <dm.h> # include <graphlcs.h> # Include "ventanas.h" vold AY UDA 1 (void) lnlchvent (1,23,!2,62,10,1,'I1]: caractvent (1,LIGHTGRAY,BLAC K,BLAC K,BLAC K,"C D",'"); crear-v (1): activa-v (1); 1 textcolor(WHITE); gotoxyll ,l): cprintf("1"); textcolor(BLACK); cprlntq" Ser posible en esta opclEn darer'); cprintfr nombre del archivo de la s e a a l que hd'); cprintf("sidocapturada, o bien un archivo con "1: cprinttrla extenslftn -.DAT-, para realtzar "j; cprintff'un procesamiento de la seoal como "1; cprlntfr'puede ser el clculo de la FFT,"); cprintff't! el filtrado dlgltal."); void AYUDA'L(void) I lnlctzvent (1,23,4,72,15,1,'1'): caractvent (1, LIG HTGRAY,6 LACK,BLACK, BLACK,"CCY',"'); crear-v (1); activa-v (1); t exicolor[WH ITE); gotoxY(1,11: cprinttp']; textcolor(BLAC K); cprlntff' Esto opclgn le pemltlr una vez dando"); cprlntfc' instalada la tarjeta PC-LAB 818,configurarla,"); cprlntfr' en cuanto a la frecuencia de muestreo, cprlntff' los canales a selecclonar y el voltaje rn xlrno"); cprlntf? de entrada. Recuerde que una vez que se cprlntff' ha selecclonado cualquiera de las opciones de"); cprlntf(" conflgurar, si la tarjeta no se encuentrd'j; cprintfr Instalada el programa se perder, es decirse quedar cprlntfv buscando la tarjeta Instalada."); 'I); 'I); 'I); vold AYUDA3[voldj I inlclzvent (1,23,7,42,12,1,'1'); caractvent (1,LIGHTGRAY,BLACK,BLACK,BLACK,"Cü~']; crear-v (1); actlva-v (1): textcoior[WH¡TE): gotoxy(1,l); cprinttrq; textcolor(BLACK); cprlntfi' Con a t a opciCn a poslbie graficat'); cprintfr'laTransformada de Fourier de la seaar']; cprlntfro blen hacer el calculo de la FR para"]: cprlnttrdespuestambien grancatIa."j; 1 vold AYUDA4(vold) { inlchvent f1,23,8,62,15,1,'1'); caractvent 1,LIGHTGRAY, BLACKJLACK, BLACK,"Cü,'"'); crear-v (1); acttva-v (1); textcolorIWH ITE); gotoxy(~,1); cprlnt f ("4"); textcoior(BLACK); cprintfr La opcien de flltros, reailza un "1; cprinifi'filtrado dlgltal con cualquiera de "1: cprlntfr los slgulentes flltros: "I; Flltro pasa-bajas "1; cprintt ("Filtropasa-alt as cprintfr Filtro rechaza banda"): vold AY UDAS(vold) { inlctzvent [ i,23,9,62,16,1 ,'I1]; caractvent (l,LIGHTGRAY,BLACK,BLACK,BLACK:":"): crear-v (1); acthm-v (11; textcolor(WHITE); gotoxy(l.1): cprintf f'"']; textcolor[BLACK); cprtntfr A traves de esta opcUn es posible"); cprlntfr realhar la captura de la seoar'); cprlntfc' que no solo pueden ser potenclales"); cprlntfr' evocadas, slno cualquler tlpo de"); cpnntry' seaal, como un ECGpor ejempio:'); vold AYUDAdwold) { Iniciwent 1123,10,62,17,1 ,'l']: caractvent (1,LIGHTGRAY,BLACK,BLACK,B~CK,"CLT':"); crear-v (11; actway (1); textcoior(WHITE); gotoxy(1,1 I : cprintf("4"); textcolor(BLACK); cprlntfr Aqui es poslble salvar en un archlvo"); cprintfr'la seoal capturada, en donde se "1; cprlntfrcontempian tamb1.n los datos del "1; cprintfrpaclente (Nombre. tel.fono,etc.) de "): cprlntfrquiense obtuvo la seuai."); void AYUDA7(voldj { Inlctzvent (1,23,12,62,18,1,'1'); caracivent (1, LIGHTGRAY, BLACK, BLACK,BLAC K,"Cü":']; crear-v (1); activa-v ti); lextcolor(WHITE); gotoxy(1,1); cprintfy'"'): text color[BLACK) : cprlnttr Con la opcilzn de Directorioes poslble"); cprintfr vlsualkar en una ventana los archivos"); cprlntfr que se encuentran en eldirectorlo actuar); cprintfr' de trabajo."); vold AY UDAB(vold) { inlclrvent (123,14,62,19,1 ,'I1]; caractvent (l,LIGHTGRAY,BLACK,BLACK,BLACK;'Cüi,'mi); crear-v (1); actha-v (1); texfcoior(WHITE): gotoxy(1,l); cprintfp'"; textcolor(6LACK); Cprlntfr' Esta opclgn da por temilnado el '7; cprintfr programa SI el usuario as(lo "1; cprintfr desea, mediante la opcign de:"); cprlntfr' SI 8 NO"); t Int sallda=l; char opcion=ü'; inlctzvent (220,4,6923,1,T): caractvent p,LIGHTGRAY, BLACK,BLAC K,BLAC K,"C ü,'"'); crear-v (2); activa-v (2); textcoior(WHITE): gotoxy[l,l I: cprlntf f'l"); textcolor(BLACK); cprlntfi' La opciln cargar archivo....."); textcolor[WHITE); gotoxYll,3); cprint t r q ; textcolor(BLACK); cprintfr' La opciln configurar PC-LAB..:'); textcolor(WHITE); gotoxy(1,S); cprintf (9'); textcolor(BLACK); cprintfl' La opclpn FFT ........'I): textcolor(WHiTE); gOtOXy[1,7); cprintf f'4"); textcolor(BLACK); cprlntfr' La opciZn Filtros........ 'I); textcoior(WHITE); gOtOXy(13); cprintf("5'); textcolor(BLACK); cprlntfi' La opciitn Potenclalesevocados......"]; textcolor(WHITEJ; gotoxy[l.ll); cprlntf ("4'); textcolor(BLACK); cprintff' La opciOn salvar archivo........."); ielctcolorpLACK)j cprlnttr La opclen Directorio........"): textcolor(W H ITE); gOtOXy(1J5); cprlntf ('al]: textcolor(BLACK): cprlntfr La opclm Salir al sbtema...:'I; do{ opclon=getch[); swltch(opclon)( case '1': AYUDAl(]: break: case 2':AVUDA2[);break: case 3': AVUDA3t); break; case '4': AVUDAd(];break; case'S:AYUDAS();break; case '6':AYUDA6[);break; case'7':AVUDA7();break: case '8:AYUDA8(J:break; case 27: sallda=0; cierra,v(i); }while(sallda==l); clerra-v p); 1 return (55):