Source: http://polaridad.es/libreria-arduino-frecuencia-cardiaca-oximetro-pulso/
Timestamp: 2016-09-26 08:41:25+00:00

Document:
Librería Arduino de medida de pulso con oxímetro
Mar 2015 Librería Arduino para monitorización de la frecuencia cardíaca con oxímetro de pulso
10 Uno de los parámetros que se monitorizan en mi proyecto de gestión del sueño es el pulso. Para medirlo desarrollé un dispositivo basado en el comportamiento de la hemoglobina y la oxihemoglobina frente a las diferentes longitudes de onda de la luz. Básicamente se trata de medir cuánta luz de determinado tipo es capaz de atravesar o es reflejada en una zona del cuerpo bien irrigada. La frecuencia con la que ocurre un ciclo completo de este fenómeno permite medir el pulso.
En la fase de diseño y prueba del dispositivo para medir el pulso desarrollé algunos pequeños programas para ayudarme a verificar que el montaje era correcto. En primer lugar escribí el código de abajo, que iba tomando los valores medidos cada cierto tiempo (como mínimo cada TIEMPO_MAXIMO_MEDIDA y como máximo cada TIEMPO_MINIMO_MEDIDA) cuando variaban un mínimo entre uno y el anterior (el valor que corresponde con MEDIDA_MINIMA) y los monitorizaba desde un ordenador con una aplicación en Python para poder analizarlos posteriormente.
Programa de prueba para monitorizar los valores leídos por el oxímetro
#define PIN_OXIMETRO 0 // Pin analógico 0
#define MEDIDA_MINIMA 10 // Cambio menor monitorizado
#define TIEMPO_MAXIMO_MEDIDA 200 // Cambio menor entre medidas (determina la resolución vertical)
#define TIEMPO_MINIMO_MEDIDA 100 // Milisegundos entre medidas (determina la resolución horizontal)
int lectura_anterior_oximetro=0;
int lectura_oximetro;
unsigned long cronometro_minimo=0;
unsigned long cronometro_maximo=0;
//pinMode(PIN_OXIMETRO,INPUT); // Ya es entrada por defecto
if(millis()>cronometro_minimo)
lectura_oximetro=analogRead(PIN_OXIMETRO);
if(abs(lectura_oximetro-lectura_anterior_oximetro)>MEDIDA_MINIMA||millis()>cronometro_maximo)
cronometro_minimo=millis()+TIEMPO_MINIMO_MEDIDA;
cronometro_maximo=millis()+TIEMPO_MAXIMO_MEDIDA;
lectura_anterior_oximetro=lectura_oximetro;
Serial.println(String(millis(),DEC)+","+String(lectura_oximetro,DEC));
#define PIN_OXIMETRO 0 // Pin analógico 0#define MEDIDA_MINIMA 10 // Cambio menor monitorizado#define TIEMPO_MAXIMO_MEDIDA 200 // Cambio menor entre medidas (determina la resolución vertical)#define TIEMPO_MINIMO_MEDIDA 100 // Milisegundos entre medidas (determina la resolución horizontal) int lectura_anterior_oximetro=0;int lectura_oximetro;unsigned long cronometro_minimo=0;unsigned long cronometro_maximo=0; void setup(){ Serial.begin(9600); //pinMode(PIN_OXIMETRO,INPUT); // Ya es entrada por defecto} void loop(){ if(millis()>cronometro_minimo) { lectura_oximetro=analogRead(PIN_OXIMETRO); if(abs(lectura_oximetro-lectura_anterior_oximetro)>MEDIDA_MINIMA||millis()>cronometro_maximo) { cronometro_minimo=millis()+TIEMPO_MINIMO_MEDIDA; cronometro_maximo=millis()+TIEMPO_MAXIMO_MEDIDA; lectura_anterior_oximetro=lectura_oximetro; Serial.println(String(millis(),DEC)+","+String(lectura_oximetro,DEC)); } }}
Una vez ajustados los valores (empezando en medidas muy densas) conseguí una colección de valores del oxímetro de pulso a lo largo del tiempo que podía representar gráficamente utilizando una hoja de cálculo, LibreOffice Calc de LibreOffice, en concreto.
Con los datos recabados, como representa la imagen de arriba, la siguiente operación era determinar si la densidad de valores permitía calcular de manera fiable pero «económica» (no muestrear más de los datos necesarios) el valor del pulso; como puede verse en el gráfico de abajo, las medidas tomadas parecían servir para obtener los resultados que es razonable esperar.
A continuación, con la información del muestreo de datos, quedaba elaborar un algoritmo que midiera la frecuencia del pulso. Ateniéndose a la gráfica que, por simplificar, se asume que representa un trazado similar al complejo QRS, lo más sencillo parece medir los tiempos entre las partes más destacadas, con valores mayores (que corresponde con la zona qRs de despolarización de los ventrículos) descartando la zona más plana y «ruidosa», más difícil de medir, por tanto. La solución adoptada, que corresponde con el código de prueba de abajo, funciona conforme al siguiente procedimiento:
Detectar la zona que se está midiendo en cada caso para atender sólo a los picos de valor qRs y desechar el valle. Para hacerlo se podrían medir valores superiores a cierta constante pero existe el riesgo de que un individuo y/o unas circunstancias que, aunque proporcionalmente, subieran o bajaran los valores. Para evitarlo, se considera un valor en la zona mayor al que supera en cierto coeficiente al valor medio. De esta forma, la medida se auto-calibra sensiblemente y se podría ajustar aún más afinando el coeficiente, que en mi caso he conseguido experimentalmente durante las pruebas.
Elegir para la medida los valores de la zona descendente (Rs) del pico qRs, lo más cercanos posible al máximo de la curva. Para saber que se abandona la zona ascendente basta con comprobar que un nuevo valor es menor que el anterior y verificar que no se ha encontrado todavía el valor buscado puesto que, en general, hay varios valores en la zona descendente de qRs dependiendo de la densidad de muestreo. Para cronometrar el pulso se almacena el valor del instante en el que se encontró el punto (los milisegundos devueltos por millis()) y se compara con el siguiente.
Para asegurarse de que el valor que se mide es el mayor de la zona descendente de la curva más alta se usa una variable booleana (medir_pulso en este ejemplo y medicion_de_pulso_activa en la librería) que se activa al entrar en la zona ascendente de la curva mayor y se desactiva una vez encontrado el primer valor descendente, que es el cronometrado.
Como lo habitual es representar la duración del pulso como pulsaciones por minuto (ppm) se corrige el valor de tiempo entre pulsaciones obtenido calculando dividiendo el tiempo total de la representación (un minuto, 60000 milisegundos) entre el intervalo obtenido al restar los milisegundos actuales (del valor actual) entre los anteriormente cronometrados.
Para evitar medidas falsas (como el dispositivo midiendo en vacío, por ejemplo) se verifica que el resultado se encuentra entre unos valores máximos y mínimos antes de darlo por cierto. Aunque se considera como media que un valor normal para un adulto sano en reposo se encuentra entre 60 y 100 ppm, hay valores admisibles por debajo, es fácil encontrar 40 ppm en un atleta en reposo, hasta 200 ppm sometido a un ejercicio intenso y más de 100 ppm en adultos sedentarios en estados de excitación, precisamente un factor interesante para el proyecto de gestión del sueño que me lleva a desarrollar este dispositivo de medición del pulso. Por esto, es recomendable relajar mucho estos valores de manera que no se pierdan los extremos, que precisamente podrían mostrar aspectos relevantes.
El nuevo valor medio se calcula disminuyendo la relevancia de la media actual en función del número de valores muestreados y se añade el último valor, ponderado también con un coeficiente que lo reduce más cuanto más valores se hayan medido hasta el momento.
Prgrama para probar el algoritmo de medición del pulso
#define TIEMPO_MINIMO_MEDIDA 20 // Milisegundos entre medidas (determina la resolución horizontal)
#define COEFICIENTE_PULSO 1.25 // Coeficiente que determina la zona de valores en la que medir el pulso
#define PULSO_MENOR 30 // Ignorar valores menores (Es infrecuente un pulso más lento aún en reposo)
#define PULSO_MAYOR 180 // Ignorar valores mayores (Es infrecuente un pulso mayor en reposo)
#define MINUTO 60000.0 // Milisegundos en un minuto
float velocidad_pulso;
float lectura_media_oximetro=511.5;
unsigned long valores_contados=0;
boolean medir_pulso=false;
unsigned long cronometro_pulso=0;
unsigned long cronometro_oximetro=0;
if(millis()>cronometro_oximetro)
cronometro_oximetro=millis()+TIEMPO_MINIMO_MEDIDA;
valores_contados++;
lectura_media_oximetro=lectura_media_oximetro*(float(valores_contados-1)/valores_contados);
lectura_media_oximetro+=lectura_oximetro*(1.0/valores_contados);
if(lectura_oximetro>lectura_media_oximetro*COEFICIENTE_PULSO)
if(lectura_anterior_oximetro<lectura_oximetro)
medir_pulso=true;
if(medir_pulso)
velocidad_pulso=MINUTO/float(millis()-cronometro_pulso);
medir_pulso=false;
if(velocidad_pulso>PULSO_MENOR&&velocidad_pulso<PULSO_MAYOR)
Serial.println("Pulso "+String(velocidad_pulso,DEC));
cronometro_pulso=millis();
#define PIN_OXIMETRO 0 // Pin analógico 0#define TIEMPO_MINIMO_MEDIDA 20 // Milisegundos entre medidas (determina la resolución horizontal)#define COEFICIENTE_PULSO 1.25 // Coeficiente que determina la zona de valores en la que medir el pulso#define PULSO_MENOR 30 // Ignorar valores menores (Es infrecuente un pulso más lento aún en reposo)#define PULSO_MAYOR 180 // Ignorar valores mayores (Es infrecuente un pulso mayor en reposo)#define MINUTO 60000.0 // Milisegundos en un minuto float velocidad_pulso;float lectura_media_oximetro=511.5;unsigned long valores_contados=0;int lectura_anterior_oximetro=0;int lectura_oximetro;boolean medir_pulso=false;unsigned long cronometro_pulso=0;unsigned long cronometro_oximetro=0; void setup(){ Serial.begin(9600); //pinMode(PIN_OXIMETRO,INPUT); // Ya es entrada por defecto} void loop(){ if(millis()>cronometro_oximetro) { cronometro_oximetro=millis()+TIEMPO_MINIMO_MEDIDA; lectura_oximetro=analogRead(PIN_OXIMETRO); valores_contados++; lectura_media_oximetro=lectura_media_oximetro*(float(valores_contados-1)/valores_contados); lectura_media_oximetro+=lectura_oximetro*(1.0/valores_contados); if(lectura_oximetro>lectura_media_oximetro*COEFICIENTE_PULSO) { if(lectura_anterior_oximetro<lectura_oximetro) { medir_pulso=true; } else { if(medir_pulso) { velocidad_pulso=MINUTO/float(millis()-cronometro_pulso); medir_pulso=false; if(velocidad_pulso>PULSO_MENOR&&velocidad_pulso<PULSO_MAYOR) { Serial.println("Pulso "+String(velocidad_pulso,DEC)); } cronometro_pulso=millis(); } } } lectura_anterior_oximetro=lectura_oximetro; }}
Por último, utilizando el algoritmo descrito antes, desarrollé la librería para calcular el pulso detectando la presencia de la hemoglobina o la oxihemoglobina (según la longitud de onda de la luz usada) del código de abajo.
La librería espera que se llame periódicamente a la función de muestreo monitorizar_pulso() para ir calculando el pulso, que puede consultarse con la función ultimo_pulso() o con la función pulso_medio() el pulso medio. Además de por ser un recurso limitado, descarté utilizar interrupciones por no necesitar valores inmediatos sino sostenidos en el tiempo para monitorizar el pulso en mi proyecto de gestión del sueño . En cualquier caso, por las pruebas que he hecho, no parece ser necesario; ya sea por el dispositivo o por el comportamiento del pulso, un muestreo a determinada frecuencia ofrece suficiente información y no se obtiene mucha más (relevante) por aumentarlo ni es posible disminuirla mucho sin perder datos relevantes para el cálculo; en las primeras versiones del código para monitorizar la lectura del oxímetro de pulso descubrí que no era necesario atenerse a un tiempo de medida máximo ya que, si se consideraban correctamente las variaciones de valores sucesivos, era muy cercano al mínimo.
Librería para calcular el pulso en función de la detección de hemoglobina/oxihemoglobina
//pulso.h
#if defined(ARDUINO) && ARDUINO>=100
#define PULSO_MINIMO 5 // Pulso mínimo. Un pulso menor se considera un error.
#define PULSO_MAXIMO 200 // Pulso máximo. Un pulso mayor se considera un error.
#define COEFICIENTE_PULSO 1.25 // Coeficiente que multiplica el pulso medio para determinar si el valor medido está en la zona que se cronometra. Puede usarse para calibra el dispositivo
#define OXIMETRIA_MEDIA 511.5 // Medida media inicial del pulso (1023/2) Puede usarse para calibrar el dispositivo
#define PULSO_MEDIO 80.0 // Pulso medio de un adulto en reposo (sólo para referencia)
class Pulso
byte pin_oximetro; // Pin analógico al que se conecta el sensor de pulso
int lectura_oximetro; // Último valor medido en el sensor de pulso
int lectura_anterior_oximetro; // Penúltimo valor medido en el sensor de pulso para compararlo con el último y establecer la zona de valores en la que se encuentra
unsigned long numero_lecturas_oximetro; // Número de medidas del oxímetro tomadas. Usado para calcular la media
unsigned long numero_lecturas_pulso; // Número de medidas de pulso tomadas. Usado para calcular la media
float lectura_media_oximetro; // Medida media del sensor de pulso. Usado para saber si un valor se encuentra en la zona de medida (que se cronometra) del pulso
boolean medicion_de_pulso_activa; // Verdadero si se ha entrado de la zona del pulso (para no confundir si aún se encuentra en una zona ya medida)
float velocidad_pulso; // Último valor de pulso calculado
float ultima_velocidad_pulso; // Último valor de pulso correcto
float velocidad_media_pulso; // Media de los pulsos calculados durante la última sesión (creación del objeto Pulso)
unsigned long cronometro_pulso; // Tiempo entre medidas de pulso consecutivas
Pulso(byte pin_oximetro_solicitado);
~Pulso();
void monitorizar_pulso(); // Se llama periódicamente (entre 10 y 50 ms) para calcular el pulso
byte ultimo_pulso(); // Devuelve el último valor correcto de pulso muestreado
byte pulso_medio(); // Devuelve el pulso medio de la sesión
//pulso.h #if defined(ARDUINO) && ARDUINO>=100 #include "Arduino.h"#else #include "WProgram.h"#endif #define PULSO_MINIMO 5 // Pulso mínimo. Un pulso menor se considera un error.#define PULSO_MAXIMO 200 // Pulso máximo. Un pulso mayor se considera un error.#define COEFICIENTE_PULSO 1.25 // Coeficiente que multiplica el pulso medio para determinar si el valor medido está en la zona que se cronometra. Puede usarse para calibra el dispositivo#define OXIMETRIA_MEDIA 511.5 // Medida media inicial del pulso (1023/2) Puede usarse para calibrar el dispositivo#define PULSO_MEDIO 80.0 // Pulso medio de un adulto en reposo (sólo para referencia) class Pulso{	private:	byte pin_oximetro; // Pin analógico al que se conecta el sensor de pulso	int lectura_oximetro; // Último valor medido en el sensor de pulso	int lectura_anterior_oximetro; // Penúltimo valor medido en el sensor de pulso para compararlo con el último y establecer la zona de valores en la que se encuentra	unsigned long numero_lecturas_oximetro; // Número de medidas del oxímetro tomadas. Usado para calcular la media	unsigned long numero_lecturas_pulso; // Número de medidas de pulso tomadas. Usado para calcular la media	float lectura_media_oximetro; // Medida media del sensor de pulso. Usado para saber si un valor se encuentra en la zona de medida (que se cronometra) del pulso	boolean medicion_de_pulso_activa; // Verdadero si se ha entrado de la zona del pulso (para no confundir si aún se encuentra en una zona ya medida)	float velocidad_pulso; // Último valor de pulso calculado	float ultima_velocidad_pulso; // Último valor de pulso correcto	float velocidad_media_pulso; // Media de los pulsos calculados durante la última sesión (creación del objeto Pulso)	unsigned long cronometro_pulso; // Tiempo entre medidas de pulso consecutivas	protected:	public:	Pulso(byte pin_oximetro_solicitado);	~Pulso();	void monitorizar_pulso(); // Se llama periódicamente (entre 10 y 50 ms) para calcular el pulso	byte ultimo_pulso(); // Devuelve el último valor correcto de pulso muestreado	byte pulso_medio(); // Devuelve el pulso medio de la sesión};
//pulso.cpp
#include "pulso.h"
Pulso::Pulso(byte pin_oximetro_solicitado)
pin_oximetro=pin_oximetro_solicitado;
numero_lecturas_oximetro=0;
numero_lecturas_pulso=0;
lectura_media_oximetro=OXIMETRIA_MEDIA;
velocidad_media_pulso=PULSO_MEDIO;
medicion_de_pulso_activa=false;
lectura_anterior_oximetro=0;
ultima_velocidad_pulso=0; // Para indicar que es un valor incorrecto por el momento
cronometro_pulso=0;
Pulso::~Pulso()
byte Pulso::ultimo_pulso()
return round(ultima_velocidad_pulso);
byte Pulso::pulso_medio()
return round(velocidad_media_pulso);
void Pulso::monitorizar_pulso()
numero_lecturas_oximetro++;
lectura_media_oximetro=lectura_media_oximetro*(float(numero_lecturas_oximetro-1)/numero_lecturas_oximetro); // Cambiar la representatividad de la parte actual de la media de pulso
lectura_media_oximetro+=lectura_oximetro*(1.0/numero_lecturas_oximetro); // Añadir la nueva lectura a la media
if(lectura_anterior_oximetro<lectura_oximetro) // Medida de valores creciente
medicion_de_pulso_activa=true;
if(medicion_de_pulso_activa)
velocidad_pulso=60000.0/float(millis()-cronometro_pulso); // Cálculo de las pulsaciones por minuto (representación habitual del pulso)
medicion_de_pulso_activa=false; // Ya se ha medido el pulso, no medir hasta entrar en una nueva zona ascendente
if(velocidad_pulso>PULSO_MINIMO&&velocidad_pulso<PULSO_MAXIMO)
numero_lecturas_pulso++;
ultima_velocidad_pulso=velocidad_pulso;
velocidad_media_pulso=velocidad_media_pulso*(float(numero_lecturas_pulso-1)/numero_lecturas_pulso); // Calcular la representatividad de la media actual en la nueva media
velocidad_media_pulso+=velocidad_pulso*(1.0/numero_lecturas_pulso); // Añadir la nueva lectura a la media
//pulso.cpp #include "pulso.h" Pulso::Pulso(byte pin_oximetro_solicitado){	pin_oximetro=pin_oximetro_solicitado;	//pinMode(pin_oximetro,INPUT); // Ya es entrada por defecto	numero_lecturas_oximetro=0;	numero_lecturas_pulso=0;	lectura_media_oximetro=OXIMETRIA_MEDIA;	velocidad_media_pulso=PULSO_MEDIO;	medicion_de_pulso_activa=false;	lectura_anterior_oximetro=0;	ultima_velocidad_pulso=0; // Para indicar que es un valor incorrecto por el momento	cronometro_pulso=0;} Pulso::~Pulso(){} byte Pulso::ultimo_pulso(){	return round(ultima_velocidad_pulso);} byte Pulso::pulso_medio(){	return round(velocidad_media_pulso);} void Pulso::monitorizar_pulso(){	lectura_oximetro=analogRead(pin_oximetro);	numero_lecturas_oximetro++;	lectura_media_oximetro=lectura_media_oximetro*(float(numero_lecturas_oximetro-1)/numero_lecturas_oximetro); // Cambiar la representatividad de la parte actual de la media de pulso	lectura_media_oximetro+=lectura_oximetro*(1.0/numero_lecturas_oximetro); // Añadir la nueva lectura a la media	if(lectura_oximetro>lectura_media_oximetro*COEFICIENTE_PULSO)	{	if(lectura_anterior_oximetro<lectura_oximetro) // Medida de valores creciente	{	medicion_de_pulso_activa=true;	}	else	{	if(medicion_de_pulso_activa)	{	velocidad_pulso=60000.0/float(millis()-cronometro_pulso); // Cálculo de las pulsaciones por minuto (representación habitual del pulso)	medicion_de_pulso_activa=false; // Ya se ha medido el pulso, no medir hasta entrar en una nueva zona ascendente	if(velocidad_pulso>PULSO_MINIMO&&velocidad_pulso<PULSO_MAXIMO)	{	numero_lecturas_pulso++;	ultima_velocidad_pulso=velocidad_pulso;	velocidad_media_pulso=velocidad_media_pulso*(float(numero_lecturas_pulso-1)/numero_lecturas_pulso); // Calcular la representatividad de la media actual en la nueva media	velocidad_media_pulso+=velocidad_pulso*(1.0/numero_lecturas_pulso); // Añadir la nueva lectura a la media	}	cronometro_pulso=millis();	}	}	}	lectura_anterior_oximetro=lectura_oximetro;}
En el siguiente programa de ejemplo se muestra cómo utilizar la librería anterior para medir el pulso con un oxímetro de pulso. Además de instanciar la clase Pulso se llama periódicamente a la monitorización del nivel de oxihemoglobina/hemoglobina y con una periodicidad menor se muestra el valor del pulso calculado y de la media.
Para asegurar que las medidas son relevantes se programa una espera antes de mostrar ningún valor. Como el valor puede ser incorrecto (por ejemplo si el usuario se retira el dispositivo) sólo se muestran valores si están dentro del rango de los considerados válidos.
Ejemplo de uso de la librería para medida del pulso con oxímetro
#define PIN_PULSOMETRO 0
#define TIEMPO_MONITORIZACION_PULSO 20
#define TIEMPO_PRESENTACION_PULSO 5000
Pulso pulso(PIN_PULSOMETRO);
unsigned long cronometro_monitorizacion_pulso;
unsigned long cronometro_presentacion_pulso;
byte velocidad_pulso;
byte velocidad_media_pulso;
cronometro_monitorizacion_pulso=0;
cronometro_presentacion_pulso=TIEMPO_PRESENTACION_PULSO*2;
if(millis()>cronometro_monitorizacion_pulso)
cronometro_monitorizacion_pulso=millis()+TIEMPO_MONITORIZACION_PULSO;
pulso.monitorizar_pulso();
if(millis()>cronometro_presentacion_pulso)
cronometro_presentacion_pulso=millis()+TIEMPO_PRESENTACION_PULSO;
velocidad_pulso=pulso.ultimo_pulso();
velocidad_media_pulso=pulso.pulso_medio();
if(velocidad_pulso)
Serial.print("Pulso ");
Serial.print(velocidad_pulso,DEC);
Serial.print(" | Pulso medio ");
Serial.println(velocidad_media_pulso,DEC);
#define PIN_PULSOMETRO 0#define TIEMPO_MONITORIZACION_PULSO 20#define TIEMPO_PRESENTACION_PULSO 5000 #include "pulso.h" Pulso pulso(PIN_PULSOMETRO);unsigned long cronometro_monitorizacion_pulso;unsigned long cronometro_presentacion_pulso;byte velocidad_pulso;byte velocidad_media_pulso; void setup(){	Serial.begin(9600);	cronometro_monitorizacion_pulso=0;	cronometro_presentacion_pulso=TIEMPO_PRESENTACION_PULSO*2;} void loop(){	if(millis()>cronometro_monitorizacion_pulso)	{	cronometro_monitorizacion_pulso=millis()+TIEMPO_MONITORIZACION_PULSO;	pulso.monitorizar_pulso();	}	if(millis()>cronometro_presentacion_pulso)	{	cronometro_presentacion_pulso=millis()+TIEMPO_PRESENTACION_PULSO;	velocidad_pulso=pulso.ultimo_pulso();	velocidad_media_pulso=pulso.pulso_medio();	if(velocidad_pulso)	{	Serial.print("Pulso ");	Serial.print(velocidad_pulso,DEC);	Serial.print(" | Pulso medio ");	Serial.println(velocidad_media_pulso,DEC);	}	}}
Víctor VenturaDesarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que he tenido desde siempre y ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.Más entradas - Página web Sígueme: Arduino, Frecuencia cardíaca, Librería, Oxímetro, Pulso, Pulsómetro Sobre el Autor
Librería de codificación Base64 con Arduino
MLX90614. Termómetro sin contacto por infrarrojos con comunicaciones SMBus.
Responder hola que tal me intereso la informacion me gustaria tener el esquematico del pulso oximetro para la utilisacion de esa libreria gracias
Responder Hola, Darío.
Como explico en el artículo sobre el principio de funcionamiento del oxímetro para monitorización del pulso, puede hacerse de varias formas dependiendo de qué componentes elijas (fotodiodo, fototransistor o ambos) y cómo decidas amplificar y filtrar la señal.
Si necesitas partir de cero puedes usar los esquemáticos de algún proyecto comercial que funcione (abajo te indico algunos) y cuando esté en marcha, para no acumular problemas, hacerte tu propia versión; no es especialmente complicado.
Responder donde encuantro esa libreria
En polaridad.es nos gusta más explicar las cosas que darlas hechas. En cualquier caso, esperaba que no fuera difícil copiar el código para hacer la librería. Como también nos gusta ayudar a nuestros lectores, la he grabado para ti: descargar la librería Arduino para monitorización de la frecuencia cardíaca (el pulso) por oximetría.
Gracias por visitar el blog polaridad.es ¡vuelve pronto!
Jeisson Ochoa
Responder hola me gustaría saber cual es la periodicidad con la que se debe encender el led rojo y el infrarrojo con el arduino para la medición de oxihemoglobina/hemoglobina gracias
Responder Hola, Jeisson.
Los LED de cada color se encienden cuando va a leerse cada uno de ellos, no es buena idea mantener ambos encendidos a la vez, ya que se puede falsear la lectura porque, salvo parejas emisores-receptores muy bien limitadas en longitud de onda, los receptores de infrarrojos detectan algo de la luz roja y al contrario.
El uso de la librería prevé que se tomen muestras cada vez que sea posible, es decir, a lo largo del programa en el que la uses, debes incluir monitorizar_pulso() cada vez que sea posible.
Si el teorema de muestreo de Nyquist-Shannon es cierto 🙂 debes muestrear a una frecuencia superior al doble de la que esperas medir, pero la forma (muy simple) de calcular el pulso que hace la librería necesita encontrar puntos en los que ascienda y descienda el nivel, digamos cuatro. Dependiendo del pulso máximo que esperes, digamos 150 ppm (2.5 Hz) sería necesario tomar, para tener un mínimo de seguridad, 2×4×2.5=20 muestras cada segundo, es decir, una muestra cada 50 ms. Si te fijas en el código de ejemplo, tomo muestras cada 20 ms y funciona bien. La verdad, no he probado a 50 ms, solamente teorizo para ayudarte a entender cómo lo he planteado.
Sería fenomenal que nos contaras el resultado de tus pruebas. Y por supuesto, se admiten sugerencias.
Gracias por visitar polaridad.es y un saludo.
Gracias por el artículo, me ha servido de gran utilidad. Lo único, es una tontería pero hay una pequeña errata en el segundo gráfico del pulso (el de color verde), donde pone “IrrigacióN (Y) a lo largo del tiempo (X en ms) |—-| pulso ¬ 91 ms ¬ 66 ppm”, haciendo referencia a la detección entre pulso y pulso, donde el gráfico indica que hay 91 ms cuando debería ser 910 ms
Tienes razón. Que fuera verde (y no «color polaridad.es») tendría que haberme dado una pista de que el gráfico no era el bueno.
Ya está corregido para no confundir a los lectores.
Responder hola que tal estoy desarrollando un proyecto de meidor de pulsos cardiacos y presentarlos en una lcd deseo saber si me pudiese ayudar con el codigo de arduino si me podria facilitarlo gracias
Responder Hola, Gabriel.
No sé si te entiendo ¿Quieres que te haga yo el programa de tu proyecto? Si te refieres a si puedes usar el código, la respuesta es sí, conforme a lo establecido en la licencia Creative Commons Reconocimiento-CompartirIgual 3.0, como el resto del contenido.
septiembre 2016 julio 2016 junio 2016 mayo 2016 abril 2016 marzo 2016 noviembre 2015 octubre 2015 septiembre 2015 marzo 2015 febrero 2015 enero 2015 diciembre 2014 si te gusta polaridad.esvota en la categoría de tecnología de los Premios Bitácoras 2016
Entradas recientes	Librería de codificación Base64 con Arduino
Se anuncia la primera aplicación práctica del memristor; el cuarto componente.
Conectar a una protoboard un módulo con una tira de pines doble
Cómo poner pines a un componente de montaje superficial
vota a polaridad.esen la categoría de tecnología de los Premios Bitácoras

References: resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución