Skip to content

Algoritmo de medida de pulsaciones

Para medir las pulsaciones primero se desarrolla un método para detectar cada pulsación. Para calcular las pulsaciones en un minuto y obtener una medida rápido, una opción es leer durante 7,5 segundos y multiplicar por 8, o leer durante 15 segundos y multiplicar por 4. En nuestro caso se utilizan las lecturas durante 7,5 segundos.

Actualización del protocolo

Se ha actualizado el protocolo entre el arduino y el visualizador

Comando Byte (hexadecimal) formato
Dato pulsación 0xF1 0xF1 <MSB> <LSB>
Número pulsaciones 0xF0 0xF0 <Byte pulsaciones>
Pulsación detectada 0xE9 0xE9

Detección de una pulsación

El método de detección es dependiente de la frecuencia de muestreo. A 30Hz la señal tarda entre 2 y 4 ticks en pasar del mínimo valor al máximo con cada pulsación. El algoritmo utilizado guarda el incremento acumulado de los últimos 4 ticks. Es un método eficiente para calcular el incremento acumulado en O(n):

volatile uint8_t beats = 0 ; // Pulsaciones contadas en un intervalo de 7.5 segundos
volatile uint8_t ticks = 0 ; // Lecturas del pletismógrafo realizadas. En 7.5 segundos serán 225
volatile uint8_t ticks_new_beat = 0 ; // Número de lecturas realizadas entre pulsaciones. Utilizaremos un mínimo de 10

ISR(ADC_vect,ISR_NOBLOCK) {
  static uint16_t old_value = 0;
  static int8_t valores[4] = {0,0,0,0} ; // Guardará las derivadas de los últimos 4 valores con los 4 anteriores

  int8_t derivada = ADC - old_value; // Incremento del valor respecto del tick anterior
  old_value = ADC ;

  for (int i=1; i<4 ; i++) {
    valores[i] -= valores[0] ; // El valor[0] va a "salir" del array, así que ajustamos el resto de valores
  }
  for (int i=1; i<4 ; i++) {
    valores[i-1] = valores[i] ; // Movemos los valores una posición atrás
  }
  valores[3] += derivada ; // Actualizamos el último valor con el incremento ocurrido en este tick

en este punto, en valores[3] está el incremento de valor acumulado de los últimos 4 ticks.

Consideraremos una pulsación cuando se produzca un incremento acumulador de 3 unidades positivas. Al mismo tiempo, para evitar  considerar una pulsación muy cercana a otra, comprobamos si ha pasado suficiente tiempo entre una pulsació y otra mediante ‘ticks_new_beat’ (de aquí que se dependa de la frecuencia de muestreo).

if (valores[3]>=3 && ticks_new_beat>10) {
  Serial.print(BEAT,BYTE) ;  // Enviar el comando que informa de que se ha detectado una pulsación
  beats++ ;                  // Incrementamos el número de pulsaciones detectadas
  ticks_new_beat=0;          // Reseteamos el contador de manera que no leemos dos veces una misma pulsación
}

Cada 7,5 segundos se envía el valor que indica el número de pulsaciones:

// Cada 30Hz * 7.5 segundos = 225 ticks
if ((uint8_t)ticks>=(uint8_t)225) {
  beats*=8 ; // Multiplicamos por 8 el número de pulsaciones detectadas en 7.5 segundos
  Serial.print(NUMPULSACIONES,BYTE) ; // Comando de "numero de pulsaciones"
  Serial.print(beats,BYTE) ;
  beats=0; // Reiniciar el contador de pulsaciones leídas
  ticks=0; // Reiniciar el contador de frecuencia de envío
}

Sólo queda actualizar los contadores con cada lectura del pletismógrafo:

// Timer1 que desencadena la lectura del pletismografo
ISR(TIMER1_CAPT_vect,ISR_NOBLOCK) {
  ticks++ ;
  ticks_new_beat++;

  // Opcion de lectura de bajo ruido, durmiendo el arduino
  //  SMCR = B00000011 ; // ADC noise reduction: 001, sleep enable:1
  //  sleep_cpu() ;
  //  SMCR = B00000000 ; // power mode idle:000, sleep disabled:0

  // Opcion de lectura sin dormir
  ADCSRA |= B01000000 ;
}

Descargar el software.

Post a Comment

Your email is never published nor shared. Required fields are marked *