Autor Tema: Electro Cardiograma por USB  (Leído 26585 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Electro Cardiograma por USB
« en: 05 de Enero de 2007, 20:02:07 »
El proyecto es para el area de BIOMEDICA

Se trata de capturar las señales electrocardiograficas emitidas por el corazon y subirlas a la computadora utilizando el PIC 18F4550, utilizando el puerto USB.


Desconectado Marioguillote

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1926
    • Servisystem
Re: Electro Cardiograma por USB
« Respuesta #1 en: 05 de Enero de 2007, 20:41:53 »
Hola alquimus.

Me encanta el proyecto. En lo que pueda ayudar cuenta conmigo con algún aporte técnico.
En que fase de desarrollo lo tienes?
Ya tienes claro de cuantos cables va a ser, de tres, de cuatro, de cinco ?
Ya tienes definido como serán los amplificadores de entrada ?
En que lenguaje estás desarrollando el soft ?

En fin; cuéntanos un poco más por donde vás, para poder sumarnos a la marcha.   :)

Saludos
Mario

Desconectado psykhon

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 823
Re: Electro Cardiograma por USB
« Respuesta #2 en: 05 de Enero de 2007, 21:17:43 »
me sumo al interes por el proyecto, no me interesa la electromdicina pero si uso un cardiometro cuando salgo a correr que es una banda que va al pecho y le transmite en 5khz mis pulsos al reloj
No, no se lo que estoy haciendo. Nadie sabe que estoy haciendo. Por eso se llama "Investigacion".

Desconectado IIIC

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
Re: Electro Cardiograma por USB
« Respuesta #3 en: 05 de Enero de 2007, 21:32:03 »
yo tambien me apunto al proyecto, de hecho ya tengo algunos diagramas y documentacion medica al respecto, dejen la organizo y la comienzo  a postear
"Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas."

Albert Einstein

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Electro Cardiograma por USB
« Respuesta #4 en: 06 de Enero de 2007, 02:52:35 »
No entiendo nada, ¿pero no lo tienes ya hecho y lo posteaste aquí?
http://www.todopic.com.ar/foros/index.php?topic=2252.0

Desconectado Marioguillote

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1926
    • Servisystem
Re: Electro Cardiograma por USB
« Respuesta #5 en: 06 de Enero de 2007, 08:38:54 »
Estas cositas me embroncan lo suficiente, como para tomarme mi tiempo y no responder "en caliente".

Gracias Manolo.
Definitivamente eres nuestro Héroe salvador.
Saludos
Mario

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
Re: Electro Cardiograma por USB
« Respuesta #6 en: 06 de Enero de 2007, 11:32:39 »
Parece que no a recibido la atención que creia merecer :D :D :D

Un saludo y lamento que estas cosas pacen.

Atte. CARLOS.
La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #7 en: 06 de Enero de 2007, 12:55:38 »
Asi es, lo tenia posteado dentro del tema del Osciloscopio, pero considero que es un tema para ser posteado individualmente, por eso pienso postearlo aqui para que se tenga un acceso mas simple.


Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #8 en: 06 de Enero de 2007, 13:02:04 »
El primer paso es el tema de la adquisicion de datos, por ser una señal de mucho ruido y por ser del orden de los 1 a 6 mV, se utiliza un Amplificador Instrumental, especificamente el AD620, por eso la primera parte se trata simplemente de hacer lo que nos dice el datasheet en la pagina 12, sin embargo utilizaremos un TL082 en vez del AD705J por ser de similares caracteristicas (y pork no estaba disponible en mi ciudad). Haciendo estos arreglos, el circuito nos quedara de la siguiente forma:


Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #9 en: 06 de Enero de 2007, 13:08:09 »
Como se nota en los graficos anteriores, seran necesarios 3 electrodos que iran conectado al paciente, la calidad de estos es muy importante, asi como los contactos y el cable que utilicemos, porke todos ellos agregaran ruido, lo ideal seria que los contactos fueran de PLATA (solo para la parte de los electrodos). Otra modificacion hecha al circuito es alimentar el instrumental con +-5V. Como ven en el circuito de Eagle, he puesto un jumper para facilitar la lectura de la señal en este punto. El jumper conectara la siguiente etapa, que sera un amplificador. El amplificador consta de 2 TL082 con la configuracion mostrada en la figura, se utilizan potenciometros para poder variar la ganancia.

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #10 en: 06 de Enero de 2007, 13:33:03 »
La siguiente etapa es la de filtrado. El filtro en este punto es muy importante, porque eliminara ruidos ubicados en frecuencias muy cercanas a la frecuencia de nuestra señal ECG. El mas importante  y el mas molesto es el ruido generado por la red electrica (60 Hz en PERU). A pesar de tener filtros en la fuente de alimentacion e incluso en el mismo circuito de alimentacion del ECG, estos 60 Hz se logran infiltrar en nuestro circuito. Por eso es necesario tener un filtro PASABAJAS con una frecuencia de corte de aproximadamente 45 Hz. Ademas, se incluira un filtro PASA ALTAS con una frecuencia de corte mucho menor a la frecuencia en la cual se encuentra la señal de ECG, estamos hablando del orden de los 0.03 Hz (como nos indica el datasheet del Instrumental).

Para hace el diseño del filtro, se simulo el circuito en el programa PROTEUS 6.5 SP5, adjunto el archivo (zipeado ) tambien para quienes deseen ver la respuesta del circuito en frecuencia.

En este punto ademas incluiremos otra etapa necesaria que es una amplificacion final y el pedestal.

Antes de seguir, debo aclarar en este punto que se decidio utilizar baterias para alimentar el circuito ya que el ruido generado por la red era bastante molesto (en realidad fue consejo que tome de otros ECG publicados en la web) , la inlcusion de baterias obligo a hacer un circuito de adaptacion para llevar los +-9V a +-5V.

Hechas las pruebas con estas modificaciones, ya teniamos la señal ECG a la salida del filtro, y era muy buena, pero muy pequeña, fue por eso que se decidio incluir una etapa de amplificacion mas. Es importante notar tambien, que la disposicion de los electrodos en brazos y pierna es importante, ya que una confusion en el orden podria llevar a obtener una señal ECG invertida, fue debido a esto que utilizamos un amplificador inversor en esta etapa, aun asi, hubieron pruebas en las cuales nuestra señal seguia saliendo invertida (desconozco el porque) por ello decidimos implementar ya en el software un algoritmo de inversion muy sencillo que se vera mas adelante.

Finalmente el pedestal para llevar nuestra señal en el rango de 0 a 5V para que pueda ser capturado por nuestro PIC.

Como veran, la placa de adquisicion solo incluye el Instumental, El amplificador inicial y el filtro. La amplificacion final y el pedestal fueron incluidos en la placa del PIC.

En el archivo ZIP se incluyen el archivo del PROTEUS 6.5 SP5 y el diseño en EAGLE 4.15 del esquematico del PIC18F4550

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #11 en: 06 de Enero de 2007, 13:35:57 »
Pues bien, hasta aqui queda la parte del hardware. La parte del PIC18F4550 es bastante simple, he utilizado basicamente el diseño de J1M en su maravilloso proyecto de prender y apagar leds por USB, por eso los 2 leds conectados al pic. La parte del software tambien hara uso de estos leds y como se imaginaran, tambien se basa en el proyecto de J1M, al cual se le añadio la parte del ADC y la visualizacion de imagen. Bueno, lo dejo ahi por ahora, mas tarde sigo con la parte del software.

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #12 en: 06 de Enero de 2007, 15:08:46 »
Pues bien, empecemos con la parte del software.

Empecemos por el PIC18F4550

Usaremos uno de los canales ADC que tiene, especificamente el AN0 o pin2 como vemos en el esquema. Recoremos que este pic tiene una resolucion de 10 bits, sin embargo solo usaremos 8 de ellos, para lo cual haremos uso del compilador CCS.

La idea era mandar tantas muestras como sea posible al computador, sin embargo aqui encontre una traba, el tamaño maximo que pude mandar en el ENDPOINT 1 es de 64 bytes.

Como bien dice J1M, es posible usar la funcion usb_puts() para mandar varios paquetes de 64 bytes, abriendo y cerrando la transferencia solo una vez.

Aqui va el programa:


#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VREGEN
#device ADC=8
#use delay(clock=48000000)

#define USB_HID_DEVICE     FALSE             //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE    64                //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    3                 //size to allocate for the rx endpoint 1 buffer

#include <pic18_usb.h>                       //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <ECGPICUSBconfig.h>                  //Configuración del USB y los descriptores para este dispositivo
#include <usb.c>                             //handles usb setup tokens and get descriptor reports

#define LEDV    PIN_B6
#define LEDR    PIN_B7
#define LED_ON  output_high
#define LED_OFF output_low
#define modo      recibe[0]
#define param1    recibe[1]
#define param2    recibe[2]
#define resultado envia[0]


retardo(BYTE speed1, BYTE speed2)
{
   BYTE i;
   for(i=0;i<speed1;++i) { delay_us(255); }
   delay_us(speed2);
}


void usb_scope_task(BYTE veloH, BYTE veloL) {

   int8 message[64],e;

   for (e=0;e<64;e++) {
       message[e]=Read_ADC();
       retardo(veloH,veloL);
   }
   usb_put_packet(1,message,64,USB_DTS_TOGGLE);
}

void main(void) {

   int8 recibe[3];                  //declaramos variables
   int8 envia[1];
   int i;
   int8 mensaje[64] = {
   20, 20, 20, 20, 20, 24, 25, 20, 18,
   20, 60, 90, 128, 230, 128,90 , 60, 20,
   18, 16, 18, 20, 25, 22, 20, 20, 20,
   20, 20, 20, 20, 20, 20, 20, 20, 20,
   20, 20, 20, 20, 20, 24, 25, 20, 18,
   20, 60, 90, 128, 230, 128,90 , 60, 20,
   18, 16, 18, 20, 25, 22, 20, 20, 20,
   20
   };


   LED_OFF(LEDV);                   //encendemos led rojo
   LED_ON(LEDR);

   usb_init();                      //inicializamos el USB

   usb_task();                      //habilita periferico usb e interrupciones
   usb_wait_for_enumeration();      //esperamos hasta que el PicUSB sea configurado por el host

   LED_OFF(LEDR);
   LED_ON(LEDV);                    //encendemos led verde

   setup_port_a( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel( 0 );

   while (TRUE)
   {
      if(usb_enumerated())          //si el PicUSB está configurado
      {
         if (usb_kbhit(1))          //si el endpoint de salida contiene datos del host
         {
            usb_get_packet(1, recibe, 3); //cojemos el paquete de tamaño 3bytes del EP1 y almacenamos en recibe

            if (modo == 1) // Modo_Led
            {
               if (param1 == 0) {LED_OFF(LEDV); LED_OFF(LEDR);} //apagamos los leds
               if (param1 == 1) {LED_ON(LEDV); LED_OFF(LEDR);} //encendemos led verde
               if (param1 == 2) {LED_OFF(LEDV); LED_ON(LEDR);} //encendemos led rojo
            }

            if (modo == 3) // Modo_Envio Paquete de 64 bytes
            {
               usb_put_packet(1, mensaje, 64, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 64byte del EP1 al PC
            }

            if (modo == 4) // Modo_ADC
            {
               usb_scope_task(param1,param2);

            }
         }
      }
   }
}


--------------------------------------

Como veran, la funcion mas importante es:

usb_scope_task(param1,param2);

La cual sera usada continuamente siempre y cuando la PC le diga que se quede en esta funcion.

Utiliza 2 parametros que en realidad es el retardo que habra entre cada toma de datos del ADC, es necesario utilizar una pequeña funcion para hacer este retardo, ya que la funcion delay_us() tiene como maximo 255 cuando se utiliza como variable.

Pues bien, una vez tomados las 64 muestras, se envian a la computadora con la funcion usb_put_paquet().

Por alli tambien hay un "mensaje" , era simplemente una prueba para ver la cantidad de datos que podia enviar. Lo deje alli, pero si quieren pueden quitarlo.

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #13 en: 06 de Enero de 2007, 15:10:11 »
Una anotacion mas, en el programa anterior, como siempre se utiliza el archivo de configuracion, que en realidad es el mismo del proyecto de J1M, sin embargo aqui se los dejo, con algunas modificaciones por cierto.



#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__

#include <usb.h>

   #DEFINE USB_TOTAL_CONFIG_LEN      32 //config+interface+class+endpoint

   //configuration descriptor
   char const USB_CONFIG_DESC[] = {
   //config_descriptor for config index 1
         USB_DESC_CONFIG_LEN,     //length of descriptor size
         USB_DESC_CONFIG_TYPE,         //constant CONFIGURATION (0x02)
         USB_TOTAL_CONFIG_LEN,0,  //size of all data returned for this config
         1,      //number of interfaces this device supports
         0x01,                //identifier for this configuration.  (IF we had more than one configurations)
         0x00,                //index of string descriptor for this configuration
         0xC0,                //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 reserved and bit7=1
         0x32,                //maximum bus power required (maximum milliamperes/2)  (0x32 = 100mA)

   //interface descriptor 0 alt 0
         USB_DESC_INTERFACE_LEN,  //length of descriptor
         USB_DESC_INTERFACE_TYPE,      //constant INTERFACE (0x04)
         0x00,                //number defining this interface (IF we had more than one interface)
         0x00,                //alternate setting
         2,       //number of endpoints, not counting endpoint 0.
         0xFF,                //class code, FF = vendor defined
         0xFF,                //subclass code, FF = vendor
         0xFF,                //protocol code, FF = vendor
         0x00,                //index of string descriptor for interface

   //endpoint descriptor
         USB_DESC_ENDPOINT_LEN, //length of descriptor
         USB_DESC_ENDPOINT_TYPE,     //constant ENDPOINT (0x05)
         0x81,              //endpoint number and direction (0x81 = EP1 IN)
         0x02,              //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
         USB_EP1_TX_SIZE,0x00,         //maximum packet size supported
         0x01,              //polling interval in ms. (for interrupt transfers ONLY)

   //endpoint descriptor
         USB_DESC_ENDPOINT_LEN, //length of descriptor
         USB_DESC_ENDPOINT_TYPE,     //constant ENDPOINT (0x05)
         0x01,              //endpoint number and direction (0x01 = EP1 OUT)
         0x02,              //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
         USB_EP1_RX_SIZE,0x00,         //maximum packet size supported
         0x01,              //polling interval in ms. (for interrupt transfers ONLY)

  };

   //****** BEGIN CONFIG DESCRIPTOR LOOKUP TABLES ********
   //since we can't make pointers to constants in certain pic16s, this is an offset table to find
   //  a specific descriptor in the above table.

   //NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUST START AT 0 AND BE SEQUENTIAL
   //      FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BE INTERFACE 0 AND INTERFACE 1
   #define USB_NUM_HID_INTERFACES   0

   //the maximum number of interfaces seen on any config
   //for example, if config 1 has 1 interface and config 2 has 2 interfaces you must define this as 2
   #define USB_MAX_NUM_INTERFACES   1

   //define how many interfaces there are per config. 
  • is the first config, etc.

   const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1};

   #if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
      #error USB_TOTAL_CONFIG_LEN not defined correctly
   #endif


//////////////////////////////////////////////////////////////////
///
///   start device descriptors
///
//////////////////////////////////////////////////////////////////

   //device descriptor
   char const USB_DEVICE_DESC[] ={
         USB_DESC_DEVICE_LEN,          //the length of this report
         0x01,                //constant DEVICE (0x01)
         0x10,0x01,           //usb version in bcd
         0x00,                //class code (if 0, interface defines class.  FF is vendor defined)
         0x00,                //subclass code
         0x00,                //protocol code
         USB_MAX_EP0_PACKET_LENGTH,   //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8)
         0xD8,0x04,           //vendor id (0x04D8 is Microchip)
         0x11,0x00,           //product id, me gusta el 11 ;)
         0x01,0x00,           //device release number
         0x01,                //index of string description of manufacturer. therefore we point to string_1 array (see below)
         0x02,                //index of string descriptor of the product
         0x00,                //index of string descriptor of serial number
         USB_NUM_CONFIGURATIONS   //number of possible configurations
   };


//////////////////////////////////////////////////////////////////
///
///   start string descriptors
///   String 0 is a special language string, and must be defined.  People in U.S.A. can leave this alone.
///
///   You must define the length else get_next_string_character() will not see the string
///   Current code only supports 10 strings (0 thru 9)
///
//////////////////////////////////////////////////////////////////

//the offset of the starting location of each string.
//offset[0] is the start of string 0, offset[1] is the start of string 1, etc.
const char USB_STRING_DESC_OFFSET[]={0,4,14};

#define USB_STRING_DESC_COUNT sizeof(USB_STRING_DESC_OFFSET)

char const USB_STRING_DESC[]={
   //string 0
         4, //length of string index
         USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
         0x09,0x04,   //Microsoft Defined for US-English
   //string 1 --> la compañia del producto ???
         10, //length of string index
         USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
         'U',0,
         'N',0,
         'S',0,
         'A',0,
   //string 2 --> nombre del dispositivo
         20, //length of string index
         USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
         'B',0,
         'I',0,
         'O',0,
         'M',0,
         'E',0,
         'D',0,
         'I',0,
         'C',0,
         'A',0
};


#ENDIF

Desconectado Alquimus

  • PIC12
  • **
  • Mensajes: 50
Re: Electro Cardiograma por USB
« Respuesta #14 en: 06 de Enero de 2007, 15:20:39 »
Bien, hasta alli la parte del PIC, entremos ahora con la PC.

Para ello utilizaremos 2 programas, el Visual Studio 2005 ( C# ) y el Measurement Studio 8.0

El Measurement Studio 8.0 es una herramienta que repotencia las capacidades del Visual Studio para poder trabajar con señales, filtrarlas, etc etc etc. Es una herramienta muy util, para este proyecto fueron utilizados el visualizador de graficos, un filtro, y algunas otras opciones que veremos mas adelante. Los puntos en contra del Measurement Studio 8.0 son que, en primer lugar no es gratuito, sin embargo con la version de prueba que dura como 3 meses es posible desarrollar con trankilidad un buen proyecto como este.  La segunda desventaja es que solo funciona con la version Profesional del Visual Studio, es decir, con versiones Express Edition del Visual C# por ejemplo, no funcionara.

Pues bien, aqui les dejo el link para ke puedan bajarse el Measurement Studio 8.0 y para que se enteren un poco mas que es esta herramienta para quienes no la conocian.

http://www.ni.com/mstudio/

Para poder bajar el software (que son como 368 Mb) deberan registrarse en national instruments, lo cual no les llevara mucho tiempo. 

Bien, una vez instalado el measurement studio 8.0, veran las herramientas correspondientes en el Visual Studio.

Aqui les adjunto el programa en Visual C#, ojo que necesitan el Visual Studio 2005 y el Measurement Studio 8.0 para poder correrlo.