Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
IEL2-II-04-15 IEL2-II-04-21 DESARROLLO E IMPLEMENTACION DE UN SISTEMA DE ELECTROMIOGRAFIA (EMG), PARA CONTROL DE UN MODELO SIMPLE DE PROTESIS MIOELECTRICA DE RODILLA. JAIME ANDRES MORALES PEDRAZA ROQUE ANDRES GOMEZ PEREZ UNIVERSIDAD DE LOS ANDES FACULTAD DE INGENIERIA DEPARTAMENTO DE INGENIERIA ELECTRONICA BOGOTA, ENERO DE 2005 IEL2-II-04-15 IEL2-II-04-21 TABLA DE CONTENIDO 1. INTRODUCCION…………………………………………………………………... 3 2. MARCO TEORICO………………………………………………………………… 5 3. OBJETIVOS………………………………………………………………………… 7 3.1 Objetivo General..…….…………………………………………………... 7 3.2 Objetivos Específicos…………………………………………………….. 7 4. Definición del Problema…………………………………………………………. 9 5. Aspectos Biológicos……………………………………………………………… 10 5.1 Potenciales Bioeléctricos….……………………………………………... 10 5.2 Propagación de los Potenciales de Acción……………..……............ 11 5.3 Músculos de Medición……………………………………………………. 11 6. Señales Mioeléctricas……………………………………………………………. 12 7. Descripción del Sistema…………………………………………………………. 13 7.1 Entradas……………………………………………………………………. 13 7.2 Procesamiento Análogo…………………………………………….......... 13 7.3 Procesamiento Digital……………………………………………………… 14 7.4 Interfaz con el Usuario………………………………………………….. 14 7.5 Modelo…………………………………………………………………….... 14 7.6 Diagrama de Bloques……………………………………………………... 15 8. Electrodos………………………………………………………………………….. 16 8.1 Características……………………………………………………………... 16 8.2 Ubicación…………………………………………………………………… 17 9. Diseño de la Etapa Análoga ……………………………………………………... 18 9.1 Descripción del Sistema de Adquisición (EMG)……………………….. 18 9.2 Primera Etapa de Amplificación y Guarda ……………………………… 18 9.3 Acondicionamiento de la Señal………………………………………….. 19 9.3.1 Filtro Pasa Altas ………………………………………………… 19 1 IEL2-II-04-15 IEL2-II-04-21 9.3.2 Filtro Notch ………………………………………………………. 21 9.3.3 Filtro Pasa Bajas ………………………………………………... 22 9.4 Segunda Etapa de Amplificación………………………………………... 23 9.5 Nivel Offset………………………………………………………………... 23 10. Diseño de la Etapa Digital……………………………………………………… 25 10.1 Microcontrolador…………………………………………………………. 25 11. Visualización……………………………………………………………………… 26 12. Control Bidireccional PWM……………………………………………………. 28 13. Modelo de Prótesis……………………………………………………………… 30 13.1 Potencia…………………………………………………………………… 30 13.1 Diseño del Modelo ……………………………………………………….. 30 14. Resultados………………………………………………………………………… 32 15. Inconvenientes…………………………………………………………………… 34 16. Conclusiones……………………………………………………………………... 35 17. Referencias……………………………………………………………................. 36 2 IEL2-II-04-15 IEL2-II-04-21 1. INTRODUCCION La constante preocupación por encontrar alternativas que mejoren nuestra calidad de vida, especialmente en situaciones adversas, nos lleva a explorar nuevos horizontes, haciendo uso de las distintas ramas del conocimiento. La ciencia Biomédica es un ejemplo interesante del avance conjunto de la Medicina con el desarrollo tecnológico de la Ingeniería en busca de beneficios para el hombre. La electromiografia ha logrado caracterizar las señales del sistema neuromuscular que generan el movimiento, sirviendo como herramienta terapéutica para personas con problemas motores o que han perdido alguna extremidad. La técnica de Biofeedback permite al paciente educar su mente mediante estímulos visuales para aprender a controlar el movimiento de los miembros afectados o de prótesis dado el caso [1]. En respuesta a la necesidad de reemplazar extremidades perdidas, hace ya varios años se han desarrollado una serie de prótesis mecánicas capaces de simular algunos de los movimientos de los miembros sustituidos. Estas son controladas por la fuerza generada directamente por la articulación más cercana correspondiente al órgano afectado. Sin embargo para este tipo de prótesis el paciente debe tener cierto tipo de características, como un miembro residual lo suficientemente largo [2]. Estas prótesis tienen la propiedad propioceptiva, referente al control de la fuerza aplicada por el usuario al realizar cierta actividad. Sin embargo se encuentran limitadas a cierto tipo de pacientes, y al movimiento que esta puede ofrecer. Una nueva aplicación de la electromiografia se enfoca en el desarrollo de prótesis de reemplazo, funcionales en términos de movilidad además del aspecto más agradable para el usuario. Este tipo de prótesis (mioeléctricas) son controladas directamente con las señales provenientes de los músculos. Para mejorar su 3 IEL2-II-04-15 IEL2-II-04-21 desempeño la persona debe aprender a coordinar el movimiento de los músculos a los cuales se conectan los electrodos que captan los impulsos del sistema neuromuscular. La cantidad de personas que sufren desmembramiento de extremidad inferior en Colombia debido a las minas antipersona (una de las principales razones), hace que la producción de prótesis sea altamente necesaria. Esto se convierte en una gran necesidad que demanda el desarrollo de soluciones cada vez mejores, que reestablezcan la vida de estas personas. Es por esta razón que nuestras expectativas estuvieron siempre enmarcadas en desarrollar o servir como instrumento para el desarrollo de prótesis que en algún momento puedan llegar a ser útiles a nuestra sociedad, por medio de la aplicación de los resultados de este trabajo en futuros proyectos con mejoras que lo complementen. 4 IEL2-II-04-15 IEL2-II-04-21 2. MARCO TEÓRICO Desde hace varios años se ha venido desarrollando el estudio de las características eléctricas del cuerpo humano, debido a la gran fascinación que representa conocer su funcionamiento y el interés de poderlo usar para el beneficio de la humanidad. La gran variedad de procesos que maneja nuestro organismo y la complejidad de los mismos, requieren de un estudio diferenciado para cada tipo de señal que interviene en tales procesos. Gracias a dichas características eléctricas del cuerpo humano, uno de los principales campos de aplicación de la Ingeniería Electrónica en la actualidad es la Medicina. Esta sinergia marca la pauta de grandes adelantos tecnológicos como la sustitución de órganos y miembros, sintetizando su funcionamiento en dispositivos capaces de llevar a cabo en gran medida y sin necesidad de señales artificiales, las funciones realizadas anteriormente por los órganos reemplazados, esto por medio de la adquisición e interpretación previa de las mismas señales, encargadas de llevar la información del cerebro a cada parte del resto del cuerpo. Específicamente la Ingeniería Electrónica tiene un gran campo de acción en el desarrollo de equipos de medición y tratamiento de las señales del sistema nervioso encargadas de mantener enlazadas las distintas funciones de nuestro organismo. Tales equipos pueden servir para diagnosticar enfermedades y monitorear el correcto funcionamiento de determinado órgano. Como un claro ejemplo se pueden nombrar las señales mioeléctricas, que corresponden a aquellas que permiten la actividad muscular. Los proyectos relacionados con este tipo de señales exigen la aplicación de conocimientos tanto análogos como digitales simultáneamente, que definen los patrones para su interpretación y manejo. Es así como se ha llegado a desarrollar prótesis mioeléctricas, capaces 5 IEL2-II-04-15 IEL2-II-04-21 de realizar en gran medida las funciones de los miembros en cuestión, llevando de esta manera a su sustitución física funcional. Como solución a este tipo de necesidades se han desarrollado prótesis que pueden llegar a ser controladas por medio de Biofeedback, mecanismo que sirve para educar a la persona que la porte, las cuales le dan al usuario información del monitoreo de los sistemas de adquisición de señales, aproximándose en estesentido cada vez más a la forma en que el cuerpo humano controla cada uno de sus miembros, que según la literatura esta muy relacionado con la forma en la cual funciona el control difuso. 6 IEL2-II-04-15 IEL2-II-04-21 3. OBJETIVOS 3.1 Objetivo General Desarrollar e implementar un sistema de medición y tratamiento de señales mioeléctricas de 2 canales, que permita controlar un modelo simple de prótesis a nivel de la rodilla. 3.2 Objetivos Específicos • Determinar el comportamiento del sistema neuromuscular y conocer las principales características de las señales mioeléctricas que permiten el movimiento. • Capturar las señales que generan los movimientos de las piernas, usando electrodos superficiales de piel, ubicados en los grupos musculares que intervienen en la flexión y estiramiento de la rodilla. • Acondicionar las señales adquiridas a un nivel de ganancia que permita diferenciar cambios importantes de amplitud y/o frecuencia para un mejor análisis de la actividad neuromuscular. • Desarrollar físicamente un modelo simple de prótesis mioeléctrica capaz de representar el comportamiento real del movimiento de la rodilla, por medio de la respuesta controlada correspondiente a los estímulos provenientes de los grupos musculares trabajados. 7 IEL2-II-04-15 IEL2-II-04-21 • Digitalizar las señales con buen nivel de resolución y tiempo de muestreo, para la visualización de las mismas en tiempo real y su manejo en la parte de control del modelo mioeléctrico. • Promover la investigación biomédica llevada a la práctica en el área de electromiografía para desarrollo de nuevos y mejores modelos de prótesis mioeléctricas. • Aportar con los resultados obtenidos en este trabajo a futuros proyectos que profundicen más en el tema. 8 IEL2-II-04-15 IEL2-II-04-21 4. Definición del Problema Debido a la situación actual de Colombia, muchas personas son victimas de amputaciones, que de cierta manera los margina de una vida normal, ya que los efectos de la pérdida de un miembro descompensan el equilibrio del organismo, deteriorando los grupos musculares asociados. Sin embargo además de tener efectos fisiológicos, también existen los efectos psicológicos y sociológicos que limitan al individuo e inciden de forma negativa en su desenvolvimiento como persona capaz aun de servir de forma productiva a la sociedad. Los costos de prótesis ya existentes pero que son desarrolladas con tecnología extranjera, son bastante elevados, y aun así no todo tipo de persona puede usarlas, están restringidas según la altura a la cual se haya hecho la amputación, de esta manera se busca llevar a cabo el desarrollo de prótesis con diseños propios, que reduzcan los costos y que puedan llegar a cumplir con las expectativas que los usuarios puedan tener. 9 IEL2-II-04-15 IEL2-II-04-21 5. Aspectos Biológicos 5.1 Potenciales Bioeléctricos Las células del organismo contienen una solución conductora (líquido orgánico), compuesta por átomos cargados (iones, , +Na +K ). Los potenciales bioeléctricos hacen referencia a la conformación de cargas repartidas al interior y exterior de la membrana celular. Los potenciales de reposo corresponden a una concentración de mucho menor al interior de la célula que en el líquido orgánico externo. En un intento de equilibrio de carga eléctrica se produce una concentración de −Cl +Na +K más alta al interior de la célula con respecto al exterior. Los potenciales de acción se presentan con la situación contraria como se muestra en la figura 1. Cuando se pasa del estado de reposo de la célula a uno de excitación se conoce como despolarización. Por el contrario cuando se pasa del potencial de acción al potencial de reposo se conoce como repolarización. Figura 1. Concentración de cargas de la célula en reposo y excitación. 10 IEL2-II-04-15 IEL2-II-04-21 5.2 Propagación de los Potenciales de Acción La excitación de las células se propaga desplazándose con tiempos determinados para cada tipo de tejido, produciéndose una corriente iónica. Esta propagación de potenciales actúa sobre los tejidos musculares en forma de contracción y relajación de los mismos permitiendo el movimiento, generado por la señales denominadas mioeléctricas. Figura 2. Despolarización y repolariación de una célula. 5.3 Músculos de Medición Para el caso de la rodilla los grupos musculares más importantes que intervienen en el movimiento de estiramiento y flexión se refieren a Rectus Femoris y al Biceps Femoris correspondientemente. Ambos se encuentran en rodeando al fémur por encima de la rodilla, ubicándose los primeros (Quadriceps), hacia la parte frontal y los segundos (Hamstrings) hacia la parte posterior de la pierna [3]. 11 IEL2-II-04-15 IEL2-II-04-21 6. Señales Mioeléctricas Las señales mioeléctricas se asemejan a una señal de ruido blanco, sin embargo tienen un ancho de banda bien definido (0Hz a 500Hz) y un espectro que concentra la mayor cantidad de energía en el rango de 50Hz a 150Hz. La amplitud está alrededor de 0 a 10mV con cierta simetría repartida en 0V. Cuando se presenta movimiento (contracción de un músculo), las señales que generan este estímulo sobre los tejidos tiene un aumento representativo de frecuencia y amplitud, con respecto al estado de reposo. Figura 3. Espectro de frecuencia de una señal mioeléctrica [4]. 12 IEL2-II-04-15 IEL2-II-04-21 7. Descripción del Sistema Figura 4. Modelo general del diseño 7.1 Entradas Son las señales que se generan al nivel de los músculos, estas pueden ser tomadas por medio de electrodos superficiales o invasivos. Su principal característica es que guardan una estrecha relación con el nivel de contracción de los músculos ofreciendo información acerca de los movimientos y la fuerza ejercida por estos. 7.2 Procesamiento Análogo Una vez se recogen las señales de los músculos requeridos se hace una amplificación diferencial con rechazo de modo común. Después se realiza el 13 IEL2-II-04-15 IEL2-II-04-21 acondicionamiento de la señal referente a toda operación con la señal procedente del amplificador, abarcando en este caso el filtraje, una nueva etapa de amplificación y la suma de un voltaje de offset. 7.3 Procesamiento Digital Para este caso en particular y según las necesidades de este proyecto, se realiza la digitalización de la señal por medio de un conversor análogo digital (ADC). En la transmisión serial de datos para la visualización, se hace una multiplexación para controlar el orden de envio de las señales debido a que solo se tiene un canal destinado a la transmisión de dos señales independientes. Una vez se tiene digitalizada la señal se hace una serie de operaciones matemáticas por medio de las cuales se generan las señales encargadas del control de movimiento del modelo de prótesis. 7.4 Interfaz con el Usuario Usando un computador se grafican las señales previamente tratadas para que el usuario pueda ver el comportamiento de los músculos monitoreados interpretando los cambios de las señales. 7.5 Modelo El modelo simple de prótesis es un dispositivo físico diseñado para la simulación de los movimientos de estiramiento y flexión de la rodilla. 14 IEL2-II-04-15 IEL2-II-04-21 7.6 Diagrama de Bloques Figura 5. Diagrama de bloques del sistema de EMG para control de prótesis mioeléctrica. 15 IEL2-II-04-15 IEL2-II-04-21 8. Electrodos 8.1 Características Para la transducción de los potenciales bioeléctricos (iónicos) en potenciales netamente eléctricos (voltaje), es necesario usar un electrolito entre la piel y los contactos metálicos del electrodo. Dicho electrolitoes una solución acuosa que contiene cationes del metal del electrodo y aniones . +C −A Si los electrodos son del mismo tipo, la diferencia de potencial eléctrica es relativamente pequeña y va a depender de la diferencia de potencial iónica real entre los puntos de media del cuerpo. A medida que aumenta el tamaño del electrodo aumenta el paso de corriente, disminuyendo la impedancia. Figura 6. Circuito equivalente de medida de biopotencial con dos electrodos. 16 IEL2-II-04-15 IEL2-II-04-21 Se utilizaron electrodos superficiales de Nicolet Biomedical®, con recubrimiento en oro tipo cóncavo de radio 10mm y longitud 152cm (60’’). Se ubicaron dos pares de electrodos por grupo muscular a una distancia de 1.5cms como se muestra en la figura 2, para obtener las señales diferenciales que actúan en los movimientos de flexión y estiramiento de la rodilla. Como referencia se ubicó un electrodo más en la cadera, común para ambos canales de medición [5]. 8.2 Ubicación Este es un aspecto de suma importancia para una medición de señales mioeléctricas confiable. Es necesario ubicar los electrodos entre dos puntos motores o de la parte media del músculo de forma longitudinal [4]. Para los músculos trabajados en este proyecto, la ubicación realizada se puede apreciar en la figura 7. Figura 7. Ubicación de los electrodos superficiales [5]. 17 IEL2-II-04-15 IEL2-II-04-21 9. Diseño de la Etapa Análoga 9.1 Descripción del Sistema de Adquisición (EMG) La etapa de tratamiento de la señal análoga proveniente de los electrodos superficiales, consta de dos partes generales que corresponden a la amplificación diferencial y el acondicionamiento. Con esto podemos obtener una señal libre de ruido con una amplitud adecuada para el proceso digital (entre 0V y 5V). 9.2 Primera Etapa de Amplificación y Guarda Para la etapa de amplificación se usaron amplificadores de instrumentación (AI) INA129 (CMRR 120db), buscando una ganancia superior a 30, para obtener una señal alrededor de mV de amplitud con un nivel bajo de modo común. Tomando la ecuación de ganancia del AI, con una Ω= kRg 64.1 , obtenemos el valor de ganancia adecuado: 12.31 64.1 4.491 = Ω Ω += k kG A pesar de las características de ganancia que ofrece este AI, decidimos dejar una amplificación inicial relativamente baja, dado que experimentalmente fue para este valor de (en conjunto con la segunda etapa de amplificación), que se presentó la señal más libre de ruido. gR 18 IEL2-II-04-15 IEL2-II-04-21 El circuito de guarda (realimentación activa), diseñado con amplificadores operacionales (AO) LM741, resistencias de 390kΩ y 10kΩ y cable blindado; cumple la función de reducir el voltaje de modo común (Vmc). Figura 8. Diagrama circuital para la primera etapa de amplificación y el circuito de guarda. 9.3 Acondicionamiento de la Señal Esta parte consta de tres filtros que se encargan de tres frecuencias diferentes. Un pasa altas a 2Hz, un Notch a 60Hz y un pasa bajas a 250Hz. Se diseñaron para esto, filtros activos Butterworth, implementados con AO LM324 [6]. 19 IEL2-II-04-15 IEL2-II-04-21 9.3.1 Filtro Pasa Altas Tomando una atenuación de 45db para 0.6Hz y una de 3db para 2Hz, se obtiene un factor de escarpamiento de 3.5, equivalente a un filtro activo de orden 4, con resistencias normalizadas (1Ω), cuyos valores respectivos de capacitancia son: 3825.0 613.2 9241.0 082.1 4 3 2 1 = = = = C C C C norm norm C R 1= FSFC Z * 1 = ZRR norm *= Con un factor de impedancia 47.79577=Z , resistencias normalizadas , 646.735461 =normR 485.861132 =normR , 447.304543 =normR , y un factor de cambio de escala en la frecuencia 677.2080454 =normR 57.1222 == πFSF , obtenemos finalmente (ajustado a valores comerciales): FCCCC µ14321 ==== Ω= Ω= Ω= Ω= kR kR R kR 200 27 82 68 4 3 2 1 20 IEL2-II-04-15 IEL2-II-04-21 Figura 9. Diagrama circuital para el filtro pasaaltas a 2Hz. 9.3.2 Filtro Notch Para el diseño de este filtro se tuvo en cuenta la frecuencia a rechazar (60Hz) y un ancho de banda repartido simétricamente a esta frecuencia (20Hz). Con esto hallamos el factor de calidad: 3 Hz20 Hz60Q == Escogiendo y F1C µ= Ω= k10R , remplazamos en FC2 1R1 π = y Q4 1Q4K −= obteniendo los demás elementos (ajustado a valores comerciales): Ω= Ω=− = Ω= Ω= kKR RK K kR kR 10 800)1( 92.0 35.1 2 7.2 1 1 21 IEL2-II-04-15 IEL2-II-04-21 Figura 10. Diagrama circuital para el filtro Notch a 60Hz. 9.3.3 Filtro Pasa Bajas Tomando una atenuación de 45db para 875Hz y una de 3db para 250Hz, se obtiene un factor de escarpamiento de 3.5, equivalente a un filtro activo de orden 4, con resistencias normalizadas (1Ω), cuyos valores respectivos de capacitancia son: 3825.0 613.2 9241.0 082.1 4 3 2 1 = = = = C C C C FSFC Z * 1 = ZR = Con factores de impedancia 822.6881 =Z , 300.5882 =Z , 487.16633 =Z , y un factor de cambio de escala en la frecuencia 507.2434 =Z 59.31415002 == πFSF obtenemos finalmente (ajustado a valores comerciales): 22 IEL2-II-04-15 IEL2-II-04-21 FCCCC µ14321 ==== Ω= Ω= Ω= Ω= 240 8.1 560 680 4 3 2 1 R kR R R Figura 11. Diagrama circuital para el filtro pasabajas a 250Hz. 23 IEL2-II-04-15 IEL2-II-04-21 9.4 Segunda Etapa de Amplificación La finalidad de esta nueva amplificación es poder ajustar la ganancia de las señales filtradas en el rango justo de digitalización (5Vpp aproximadamente), permitiendo diferenciar cambios importantes generados por los movimientos realizados en la rodilla. Esta ganancia varía mediante un potenciómetro de 50kΩ dentro de una configuración de amplificador no inversor implementada con AO LM324 y resistencias de 1kΩ. Figura 12. Diagrama circuital para la segunda etapa de amplificación. 9.5 Nivel Offset Usando el mismo AO LM324 se configuró un sumador no inversor, para ubicar la señal entre 0V y 5V por medio de un valor DC (2.5V), resultante de un divisor de voltaje modificable por una resistencia variable de precisión de 100kΩ. 24 IEL2-II-04-15 IEL2-II-04-21 Figura 13. Diagrama circuital para el sumador de offset. 25 IEL2-II-04-15 IEL2-II-04-21 10. Diseño de la Etapa Digital 10.1 Microcontrolador Para el desarrollo del proceso digital de forma independiente con respecto a un PC se usó un microcontrolador de la familia Motorola de referencia MC68HC908GP32, por incluir entre sus dispositivos internos conversores análogos digitales de 8 bits de resolución (19.6mV por bit), además de tener 2 salidas de modulación de ancho de pulso (PWM) usadas en nuestro proyecto para controlar el modelo de prótesis, y el protocolo serial. Los anteriores procesos fueron programados con ayuda del programa Processor Expert® un modulo perteneciente a METROWERKS® en lenguaje de C que es el software de desarrollo de esta familia de microcontroladores. Este dispositivo es el encargado de tomar las señales análogas después de ser tratadas, convertirlas a datos digitales con una frecuencia de muestreo de 54.392Khz que es la frecuencia de muestreo que se puede usar con la velocidad escogida para el manejo del reloj interno del bus del microcontrolador que corresponde a 7.3728Mhz, y asegurarse que en lo posible no se pierda información de las señales análogas. Además de la digitalización de la señal, en este dispositivo se realiza el procesamiento de la señal para el control del modelo de prótesis, la Multiplexación y sincronización con el PC, para su transmisión serial a una velocidad de 28800 baudios (bits por segundo), correspondiente a una frecuencia de 2880 datos por segundo.26 IEL2-II-04-15 IEL2-II-04-21 La información del programa desarrollado para los procesos realizados en este dispositivo se encuentra en el anexo 1. 27 IEL2-II-04-15 IEL2-II-04-21 11. Visualización Para la visualización de las señales se desarrolló un programa ejecutable en Visual Basic®, ya que con este se puede manejar de forma mas natural la interfaz con el usuario, pues se ejecuta sobre Windows. En programas desarrollados anteriormente se usó Turbo C ++, sin embargo este se ejecuta sobre DOS, lo cual lo convierte en una herramienta poco eficiente debido a los recursos que este toma del PC, otros programas usados para la pruebas preliminares fueron Labview, pero este requiere de una costosa licencia. Figura 14. Ventana de la interfaz gráfica de Visual Basic. 28 IEL2-II-04-15 IEL2-II-04-21 El programa final se desarrolló en Visual Basic® , este se encarga de tomar directamente del registro del puerto serial, 1 dato cada vez que se reciba, por esta razón, la grafica obtenida de la señal esta filtrada por la velocidad a la cual el programa es capaz de llevar a cabo esta tarea, es decir a una frecuencia de 434.78hz, correspondiente a tomar un dato cada 2.3ms, suficiente para que se alcance a tomar el espectro de frecuencia en el cual se concentra la señal, con la información necesaria sobre los movimientos (estiramiento \ flexión) de la rodilla. Al ejecutar el programa, este por defecto tiene la escala asignada para 1 s por división y en cuanto al voltaje se encuentra limitado y estático en el intervalo de - 2.5 y 2.5 V, sin embargo la escala referente al tiempo se puede variar entre 0.5 s, 1 s, 2 s y 4 s por división, de manera independiente para cada señal. El programa además de mostrar la evolución de las señales en el tiempo, almacena los datos, junto con el tiempo en archivos independientes para cada señal en un archivo de texto, que luego puede ser visualizado de manera estática con ayuda de Microsoft Excel® o Matlab®. El código de este programa se presenta en el anexo [2]. Para el modulo de visualización se desarrolló un programa ejecutable trabajado en Visual Basic®, que recibe los datos por medio del puerto serial del computador a una velocidad de 28800 baudios, almacenando los datos de la conversión digital de cada canal en dos archivos de texto independientes. Estos datos son graficados simultáneamente en tiempo real en dos ejes independientes, con la opción de modificar la escala de tiempo en 4 valores adecuados para este tipo de señales (0.5s, 1s, 2s y 4s por división) según las necesidades de visualización. Debido a las características del programa se tiene la restricción de muestreo a una frecuencia de 434.78hz, es decir toma un dato cada 2.3ms, lo cual funciona como un filtro pasa-bajas ocasionando la perdida de información que caracteriza a 29 IEL2-II-04-15 IEL2-II-04-21 las señales de electromiografía. Sin embargo para la aplicación de este modulo visual, la señal obtenida y graficada es lo suficientemente buena para verificar el funcionamiento del control de la prótesis y para la aplicación de entrenamiento neuromuscular por medio de Biofeedback. 30 IEL2-II-04-15 IEL2-II-04-21 12. Control Bidireccional PWM El control de movimiento para el motor DC del modelo de prótesis, se desarrolló con las dos señales independientes PWM1 y PWM2 del microcontrolador. La primera corresponde a la señal del canal 1 del sistema de medición (Rectus Femoris) y la segunda al canal 2 (Biceps Femoris). Al tener dos señales distintas se puede controlar la dirección del motor como se especifica en la tabla 1. El habilitador se dejó siempre en 5V. Para determinar que tanto, a que velocidad y con que dirección debía moverse el motor, se realizó un análisis continuo de los valores digitales a la tasa de conversión del ADC del microcontrolador, para asignar el porcentaje de ancho de pulso correspondiente al valor de amplitud de la señal muestreada, como lo muestra la tabla 2. Para esto decidimos fijar la frecuencia de transmisión en 1Khz, calculando los porcentajes adecuados para el ancho de pulso de las señales PWM sobre este valor. Se dividió la escala de conversión del ADC de los 256 valores posibles en cuatro intervalos cerrados ([0, 21], [22, 121], [122, 132], [133, 232], [233, 255] ). Habilitador PWM 1 PWM 2 Función 1 1 0 Giro a la derecha 1 0 1 Giro a la izquierda 1 1 1 Detención rápida 1 0 0 Detención rápida 0 X X Movimiento libre Tabla 1. Señales del control bidireccional. Para ausencia de movimiento en la rodilla las dos señales análogas permanecen en el valor establecido de offset (2.5V) con un umbral de ruido de 31 IEL2-II-04-15 IEL2-II-04-21 196mVpp comprendido en el intervalo [122,132] del ADC. Para este caso se debe mantener el motor quieto lo cual ocurre con un valor de 50% en las dos salidas PWM (500µs de ancho de pulso), con habilitador en 1. Cuando hay flexión o estiramiento de la rodilla la amplitud de la señal que se genera aumenta para el músculo involucrado en el movimiento, con una amplitud pico-pico repartida casi simétricamente sobre el valor de offset (2.5V). En este caso se deshabilita la señal PWM del músculo con menor amplitud (aquel que no interviene en el movimiento) y para la señal PWM del otro músculo se establece el porcentaje correspondiente para el valor digital registrado. A partir del intervalo definido para reposo, el porcentaje de ancho de pulso aumenta en 1% (20µs) por cada aumento en 1 (19,6mV) en la escala digital a partir de 133 (2.582V – 1%) hasta 232 (4.594 – 99%) y por cada disminución a partir de 121 (2,373V – 1%) hasta 22 (0.431 – 99%). Para los otros dos intervalos [0, 21] y [233, 255] se asignó un porcentaje de 99% (ancho de pulso de 990µs), lo cual corresponde a una señal con posible saturación referente a fuerza en los extremos de movilidad de la rodilla. Para un mejor resultado en las señales de control se optó finalmente por trabajar únicamente con el intervalo de 127 a 255, que corresponde a los valores positivos de voltaje de la señal análoga. Con esto se calcula un promedio cada 30 datos a la tasa de muestreo del ADC del microcontrolador. La señal resultante de estos valores promediados corresponde a la envolvente de la señal mioeléctrica. Las condiciones para el cálculo de porcentaje de las salidas PWM se reducen al eliminar la mitad de la escala de voltaje y se asegura una mejor comparación entre los dos canales. 32 IEL2-II-04-15 IEL2-II-04-21 Esta asignación de valores hace que el motor usado en la prótesis se mueva a la velocidad determinada, correspondiente al movimiento de la rodilla del paciente, haciendo los movimientos indicados en tiempo aceptable. Valor Análogo (V) Valor Digital PWM % Ancho de Pulso (µs) [0, 0.412] [0,21] 99 990 [0.431, 2,373] [22, 121] [1, 99] [10, 990] [2.392, 2.582] [122, 132] 50 500 [2.608, 4.594] [133, 232] [1, 99] [10, 990] [4.569, 5] [233, 255] 99 990 Tabla 2. Correspondencia de señales de control PWM. 33 IEL2-II-04-15 IEL2-II-04-21 13. Modelo de Prótesis 13.1 Potencia Fue necesario adicionar al sistema un circuito para satisfacer las exigencias del motor utilizado, al tiempo que permitiera utilizar las señales de PWM para el control del modelo. Para esto se implementó un control bidireccional de motor DC con un L293B, que entrega una corriente de salida de 1A. 13.2 Diseño del Modelo El modelo simple de prótesis mioeléctrica es un dispositivo conformado por un motor DC (rodilla electrónica), un par de poleas que transmiten el movimiento del rotor a un eje del mismo radio, una pieza con 2 grados de libertad acoplada al eje que representa la parte inferior de la pierna (tibia y peroné) y otra piezacon 0 grados de libertad que sostiene la estructura del modelo y que representa la parte superior de la pierna (fémur). El movimiento en dos direcciones de la pieza móvil está limitado en 135º, para representar el desplazamiento real de la parte inferior de la pierna. Cuando la rodilla se encuentra totalmente flexionada, esta pieza forma un ángulo de 45º con la pieza fija y cuando se presenta estiramiento completo el ángulo es de 90º. En cada límite se coloca un tope que asegura el detenimiento del modelo, además de un pulsador que le indica al microcontrolador la posición extrema haciendo que se detenga el motor con fuerza si se mantiene en esta posición o que se mueva en sentido contrario si registra nuevamente señal de movimiento en el canal alterno. 34 IEL2-II-04-15 IEL2-II-04-21 Figura 14. Bosquejo del modelo simple de prótesis. Se escogió un micromotor DC 1624E012 de Faulhaber, que tiene una potencia de salida de 1.44W, 13000rpm sin carga a voltaje nominal (12V) y un consumo de corriente inferior a 180mA para condiciones extremas. Su alimentación es independiente del resto del sistema y se hizo con una batería recargable de Níquel Metal Híbrido (NiMH) de 9V y 170mA/hora. 35 IEL2-II-04-15 IEL2-II-04-21 14. Resultados Las siguientes figuras muestran las señales graficadas con el programa de visualización obtenidas con el sistema de medición implementado. Se puede observar claramente la variación de amplitud y frecuencia de las señales al realizar movimientos en ambas direcciones (flexión y estiramiento), con valores opuestos según el movimiento realizado. El eje vertical de la cuadricula corresponde al voltaje entre -2.5V y 2.5V (centrado en 0) y el eje horizontal al tiempo en segundos que varía como se indicó anteriormente. Figura 15. Estiramiento de la rodilla. 36 IEL2-II-04-15 IEL2-II-04-21 La diferencia de amplitud entre las dos señales permitió desarrollar el control bidireccional PWM del motor que se explicó en el numeral 12. Figura 16. Flexión de la rodilla. 37 IEL2-II-04-15 IEL2-II-04-21 Figura 17. Estiramiento, flexión estiramiento de la rodilla. 38 IEL2-II-04-15 IEL2-II-04-21 15. Inconvenientes Durante el desarrollo del proyecto se presentaron los siguientes inconvenientes: • Los electrodos y el electrolito utilizados para captar las señales no fueron los adecuados como se especifica para EMG, debido a la dificultad para conseguirlos y su elevado costo. • Por la longitud de los cables de los electrodos, se produjo una serie de señales con frecuencias pertenecientes al espectro definido para EMG, siendo interpretadas en un principio como señales mioeléctricas. • La limitación de Visual Basic en tiempo de recepción de datos por el puerto serial haciendo perder resolución en la visualización. • Las características del motor seleccionado dificultaron el diseño del modelo de prótesis y la escogencia de los materiales del mismo. 39 IEL2-II-04-15 IEL2-II-04-21 16. Conclusiones • Fue desarrollado VISUALIZACION, programa en el cual se grafican casi instantáneamente (buscando una aproximación a la visualización en tiempo real) los datos obtenidos a través del puerto serial, de las señales generadas en los músculos trabajados, para la verificación del movimiento del modelo de prótesis. • El sistema de EMG fue capaz de obtener señales bien definidas con el nivel de amplitud ajustable, adecuado para el procesado digital. • El control bidireccional PWM fue una herramienta eficaz para definir el movimiento exacto de la rodilla traducido en velocidad y dirección del motor DC. • El modelo mioeléctrico representó el comportamiento real, respondiendo a los estímulos correspondientes al movimiento de la rodilla. • La resolución y tiempos de muestreo definidos fueron apropiados para visualizar las señales claramente diferenciadas y para controlar el modelo de prótesis en un tiempo aceptable. 40 IEL2-II-04-15 IEL2-II-04-21 17. Referencias [1] Juan Camilo López, “Desarrollo de un Equipo de Biofeedback para Rehabilitación”, Tesis de Ingeniería Eléctrica, Universidad de los Andes, Santafé de Bogotá D.C. Enero de 1996. [2] Ing. Carlos Andrés Sánchez, “Métodos de clasificación de la señal EMG del antebrazo basado en redes neuronales artificiales y su aplicación sobre una prótesis virtual”, Tesis de Maestría en Ingeniería Electrónica y de Computadores, Universidad de los Andes, Santafé de Bogotá D.C. Febrero de 2004. [3] http://www.fun-and-fitness.com/mus-zone/legs.html. [4] Carlo J. de Luca, “Surface Electromiography: Detection And Recording”, DelSys Inc 2002. [5] Jeffrey R. Cram, PhD, Glenn S. Kasman, MS, PT, Jonathan Holtz, MA, PT, “Introduction To Surface Electromyography”, An Aspen Publication, Maryland 1998. [6] Análisis y Síntesis de Circuitos, Universidad de los Andes. [7] Brayan Alexis Arias Martínez, “Diseño de un instrumento para la adquisición, almacenamiento, procesado y reproducción de señales EMG”, Tesis de Grado, Universidad de los Andes, Santafé de Bogotá D.C. Junio de 2003. [8] Juan Gabriel Hincapié Ordóñez, “Diseño de una red neuronal optima para predecir el movimiento del brazo a partir de señales de electromiografia (EMG)”, Tesis de Grado, Universidad de los Andes, Santafé de Bogotá D.C. 2002. [9] J. Roca Jr., J. M. Jiménez, J. A. Villarrejo, J. Roca, “Reconocimiento De Patrones En Actividad EMG Superficial De Uso En Ayudas Tecnológicas Y Biofeedback”, La Habana, Cuba 2001. [10] http://personales.ya.com/emgnm/emg.htm [11] http://www.ottobockus.com/products/lower_limb_prosthetics/c-leg.asp 41 IEL2-II-04-15 IEL2-II-04-21 ANEXOS Anexo [1] Programa del microcontrolador #include "Cpu.h" #include "Events.h" #include "PWM1.h" #include "PWM2.h" #include "AS1.h" #include "AD1.h" #include "Bit1.h" #include "PE_Types.h" #include "PE_Error.h" #include "PE_Const.h" #include "IO_Map.h" void main(void) { PE_low_level_init(); principal (); #ifndef PE_OS_OSEK_SUPPORT for(;;){} #else StartOS(Mode); #endif PE_OS_OSEK_SUPPORT } /* END prueba */ /* ** ################################################################### ** ** This file was created by UNIS Processor Expert 03.51 for ** the Motorola HC08 series of microcontrollers. ** ** ################################################################### */ A continuación se describe la rutina principal() static byte myValues[2]; static byte entrada; static int i; static int j;// static int k;// static long senal1; static long senal2; 42 IEL2-II-04-15 IEL2-II-04-21 static int duty; static int bandera; static int contador1; static int contador2; static int dato; static int canal; static int funcion; void principal (void) { i=0; duty=0; bandera=0; contador1=0; contador2=0; senal1=0; senal2=0; dato=0; canal=0; PWM2_Enable(); PWM1_Enable(); for(;;) { AD1_Measure(TRUE); AD1_GetValue((byte *)myValues); AS1_Enable(); funcion=Bit1_GetVal(); if (funcion==1) { while (AS1_GetCharsInRxBuf()==0); AS1_RecvChar(&entrada); if(entrada==49) { AS1_SendChar(myValues[i]); entrada=0; } if(i==1) { i=0; } else { i++; } PWM1_SetDutyUS(500); PWM2_SetDutyUS(500); bandera=1; } else { if (myValues[0]>127) { senal1=senal1+myValues[0]; contador1++; 43 IEL2-II-04-15 IEL2-II-04-21 } if (myValues[1]>127) { senal2=senal2+myValues[1]; contador2++; } if (contador1>=30||contador2>=30){ senal1=senal1/contador1; senal2=senal2/contador2; contador1=0; contador2=0; if(senal2>senal1) { dato=senal2; canal=1; } else { dato=senal1; canal=0; } senal1=0; senal2=0; if ((dato>126 && dato<133)) { PWM1_SetDutyUS(500); PWM2_SetDutyUS(500); bandera=1; } else if(dato>132 && dato<233) { duty=1000-(dato-132)*10; bandera=0; } else if(dato>232) { duty=0; bandera=0; } if(bandera==0) { if(canal==1) { PWM2_SetDutyUS(duty); PWM1_SetDutyUS(999); } if(canal==0) { PWM1_SetDutyUS(duty); PWM2_SetDutyUS(999); } } } 44 IEL2-II-04-15 IEL2-II-04-21 } } } Anexo [2] Programa de visualización desarrollado en Visual Basic Option Explicit Dim nuevo As Integer Dim tiempo1 As Variant Dim tiempo2 As Variant Dim contcanaA As Integer Dim contcanaB As Integer Dim rangocanaA As Long Dim rangocanaB As Long Dim i As Integer Dim AB As Integer Dim dato As String Dim canaA(10000) As Integer Dim canaB(10000) As Integer Public Ficheropath1 As String Public Ficheropath2 As String Private Sub algo_DragDrop(Source As Control, X As Single, Y As Single) End Sub Private Sub cmdescala1_1_Click() If nuevo = 1 Then rangocanaA = 543 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaA(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_1.Cls pctnumer1_1.Print 500 & "ms" pctnumer2_1.Cls pctnumer2_1.Print 1000 & "ms" pctnumer3_1.Cls 45 IEL2-II-04-15 IEL2-II-04-21 pctnumer3_1.Print 1500 & "ms" pctnumer4_1.Cls pctnumer4_1.Print 2000 & "ms" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala1_2_Click() If nuevo = 1 Then rangocanaB = 543 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaA(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_2.Cls pctnumer1_2.Print 500 & "ms" pctnumer2_2.Cls pctnumer2_2.Print 1000 & "ms" pctnumer3_2.Cls pctnumer3_2.Print 1500 & "ms" pctnumer4_2.Cls pctnumer4_2.Print 2000 & "ms" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue 46 IEL2-II-04-15 IEL2-II-04-21 pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala2_1_Click() If nuevo = 1 Then rangocanaA = 1087 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaB(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_1.Cls pctnumer1_1.Print 1 & "s" pctnumer2_1.Cls pctnumer2_1.Print 2 & "s" pctnumer3_1.Cls pctnumer3_1.Print 3 & "s" pctnumer4_1.Cls pctnumer4_1.Print 4 & "s" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue 47 IEL2-II-04-15 IEL2-II-04-21 pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala2_2_Click() If nuevo = 1 Then rangocanaB = 1087 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaA(i) & " "; tiempo2i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_2.Cls pctnumer1_2.Print 1 & "s" pctnumer2_2.Cls pctnumer2_2.Print 2 & "s" pctnumer3_2.Cls pctnumer3_2.Print 3 & "s" pctnumer4_2.Cls pctnumer4_2.Print 4 & "s" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue 48 IEL2-II-04-15 IEL2-II-04-21 pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala3_1_Click() If nuevo = 1 Then rangocanaA = 2174 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaB(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_1.Cls pctnumer1_1.Print 2 & "s" pctnumer2_1.Cls pctnumer2_1.Print 4 & "s" pctnumer3_1.Cls pctnumer3_1.Print 6 & "s" pctnumer4_1.Cls pctnumer4_1.Print 8 & "s" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala3_2_Click() 49 IEL2-II-04-15 IEL2-II-04-21 If nuevo = 1 Then rangocanaB = 2174 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaA(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_2.Cls pctnumer1_2.Print 2 & "s" pctnumer2_2.Cls pctnumer2_2.Print 4 & "s" pctnumer3_2.Cls pctnumer3_2.Print 6 & "s" pctnumer4_2.Cls pctnumer4_2.Print 8 & "s" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala4_1_Click() If nuevo = 1 Then rangocanaA = 4348 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo 50 IEL2-II-04-15 IEL2-II-04-21 i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaB(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctnumer1_1.Cls pctnumer1_1.Print 4 & "s" pctnumer2_1.Cls pctnumer2_1.Print 8 & "s" pctnumer3_1.Cls pctnumer3_1.Print 12 & "s" pctnumer4_1.Cls pctnumer4_1.Print 16 & "s" pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub cmdescala4_2_Click() If nuevo = 1 Then rangocanaB = 4348 pctseñal1.Cls pctseñal2.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 51 IEL2-II-04-15 IEL2-II-04-21 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaA(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctnumer1_2.Cls pctnumer1_2.Print 4 & "s" pctnumer2_2.Cls pctnumer2_2.Print 8 & "s" pctnumer3_2.Cls pctnumer3_2.Print 12 & "s" pctnumer4_2.Cls pctnumer4_2.Print 16 & "s" pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5,0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End Sub Private Sub crear_Click() Control.Filter = "texto(*.txt)|*.txt|todos (*.*)|*.*" ' Extenciones por defecto para mostrar en la caja de dialogo Control.DefaultExt = "texto" ' Extención por defecto para guardar el archivo Control.ShowSave ' Mostrar ventana de salvar archivo Ficheropath1 = Control.FileName ' Contiene el path y el nombre del archivo Control.Filter = "texto (*.texto)|*.txt|todos (*.*)|*.*" ' Extenciones por defecto para mostrar en la caja de dialogo Control.DefaultExt = "texto" ' Extención por defecto para guardar el archivo Control.ShowSave ' Mostrar ventana de salvar archivo Ficheropath2 = Control.FileName ' Contiene el path y el nombre del archivo Open Ficheropath1 For Output As #1 ' Creamos el archivo Close #1 ' Cerramos el archivo Open Ficheropath2 For Output As #2 ' Creamos el archivo Close #2 ' Cerramos el archivo nuevo = 1 52 IEL2-II-04-15 IEL2-II-04-21 pctseñal1.Cls pctseñal2.Cls contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue AB = 1 pctnumer1_1.Cls pctnumer1_1.Print 1 & "s" pctnumer2_1.Cls pctnumer2_1.Print 2 & "s" pctnumer3_1.Cls pctnumer3_1.Print 3 & "s" pctnumer4_1.Cls pctnumer4_1.Print 4 & "s" pctnumer1_2.Cls pctnumer1_2.Print 1 & "s" pctnumer2_2.Cls pctnumer2_2.Print 2 & "s" pctnumer3_2.Cls pctnumer3_2.Print 3 & "s" pctnumer4_2.Cls pctnumer4_2.Print 4 & "s" MSComm1.Output = "1" End Sub Private Sub Form_Load() nuevo = 0 contcanaA = 1 contcanaB = 1 tiempo1 = 0.0023 tiempo2 = 0.0023 rangocanaA = 1067 rangocanaB = 1067 pctseñal1.DrawWidth = 1 pctseñal2.DrawWidth = 1 MSComm1.CommPort = 1 'puerto com1 MSComm1.PortOpen = True 'se abre el puerto para que funcione MSComm1.RTSEnable = False MSComm1.RThreshold = 1 MSComm1.Handshaking = 0 53 IEL2-II-04-15 IEL2-II-04-21 MSComm1.Settings = "28800,n,8,1" End Sub Private Sub mnucrear_Click() Control.Filter = "texto(*.txt)|*.txt|todos (*.*)|*.*" ' Extenciones por defecto para mostrar en la caja de dialogo Control.DefaultExt = "texto" ' Extención por defecto para guardar el archivo Control.ShowSave ' Mostrar ventana de salvar archivo Ficheropath1 = Control.FileName ' Contiene el path y el nombre del archivo Control.Filter = "texto (*.texto)|*.txt|todos (*.*)|*.*" ' Extenciones por defecto para mostrar en la caja de dialogo Control.DefaultExt = "texto" ' Extención por defecto para guardar el archivo Control.ShowSave ' Mostrar ventana de salvar archivo Ficheropath2 = Control.FileName ' Contiene el path y el nombre del archivo Open Ficheropath1 For Output As #1 ' Creamos el archivo Close #1 ' Cerramos el archivo Open Ficheropath2 For Output As #2 ' Creamos el archivo Close #2 ' Cerramos el archivo nuevo = 1 pctseñal1.Cls pctseñal2.Cls contcanaA = 1 contcanaB = 1 pctseñal1.Scale (0, 255)-(rangocanaA, 0) pctseñal2.Scale (0, 255)-(rangocanaB, 0) pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue AB = 1 pctnumer1_1.Cls pctnumer1_1.Print 1 & "s" pctnumer2_1.Cls pctnumer2_1.Print 2 & "s" pctnumer3_1.Cls pctnumer3_1.Print 3 & "s" pctnumer4_1.Cls pctnumer4_1.Print 4 & "s" pctnumer1_2.Cls pctnumer1_2.Print 1 & "s" pctnumer2_2.Cls pctnumer2_2.Print 2 & "s" pctnumer3_2.Cls pctnumer3_2.Print 3 & "s" pctnumer4_2.Cls 54 IEL2-II-04-15 IEL2-II-04-21 pctnumer4_2.Print 4 & "s" MSComm1.Output = "1" End Sub Private Sub MSComm1_OnComm() If MSComm1.CommEvent = 2 Then 'el 2 indica datos recibidos dato = MSComm1.Input If nuevo = 1 Then If AB = 1 Then canaA(contcanaA) = Asc(dato) pctseñal1.Scale (0, 255)-(rangocanaA, 0) If contcanaA > 1 Then pctseñal1.Line (contcanaA - 2, canaA(contcanaA - 1))-(contcanaA - 1, canaA(contcanaA)), vbRed End If contcanaA = contcanaA + 1 AB = 2 MSComm1.Output = "1" Else canaB(contcanaB) = Asc(dato) pctseñal2.Scale (0, 255)-(rangocanaB, 0) If contcanaB > 1 Then pctseñal2.Line (contcanaB - 2, canaB(contcanaB - 1))-(contcanaB - 1, canaB(contcanaB)), vbRed End If contcanaB = contcanaB + 1 AB = 1 MSComm1.Output = "1" End If If contcanaA = rangocanaA Then pctseñal1.Cls Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA tiempo1 = tiempo1 + 0.0023 Print #1, canaA(i) & " "; tiempo1 i = i + 1 Wend Close #1 contcanaA = 1 pctseñal1.Line(rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If If contcanaB = rangocanaB Then pctseñal2.Cls 55 IEL2-II-04-15 IEL2-II-04-21 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB tiempo2 = tiempo2 + 0.0023 Print #2, canaB(i) & " "; tiempo2 i = i + 1 Wend Close #2 contcanaB = 1 pctseñal1.Line (rangocanaA / 5, 255)-(rangocanaA / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 2 / 5, 255)-(rangocanaA * 2 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 3 / 5, 255)-(rangocanaA * 3 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 4 / 5, 255)-(rangocanaA * 4 / 5, 0), vbBlue pctseñal1.Line (rangocanaA * 5 / 5, 255)-(rangocanaA * 5 / 5, 0), vbBlue pctseñal1.Line (0, 64)-(rangocanaA, 64), vbBlue pctseñal1.Line (0, 192)-(rangocanaA, 192), vbBlue pctseñal2.Line (rangocanaB / 5, 255)-(rangocanaB / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 2 / 5, 255)-(rangocanaB * 2 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 3 / 5, 255)-(rangocanaB * 3 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 4 / 5, 255)-(rangocanaB * 4 / 5, 0), vbBlue pctseñal2.Line (rangocanaB * 5 / 5, 255)-(rangocanaB * 5 / 5, 0), vbBlue pctseñal2.Line (0, 64)-(rangocanaB, 64), vbBlue pctseñal2.Line (0, 192)-(rangocanaB, 192), vbBlue End If End If End If End Sub Private Sub mnuSalir_Click() If nuevo = 0 Then End Else Open Ficheropath1 For Append As #1 ' Creamos el archivo i = 1 While i <= contcanaA Print #1, canaA(i) i = i + 1 Wend Close #1 Open Ficheropath2 For Append As #2 ' Creamos el archivo i = 1 While i <= contcanaB Print #2, canaB(i) i = i + 1 Wend Close #2 End End If End Sub 56
Compartir