Академический Документы
Профессиональный Документы
Культура Документы
La precisión del valor digital obtenido depende de tres parámetros que están
interrelacionados: ① la resolución (configurable hasta 16 bits), ② el ancho del pulso
que determina el tiempo de iluminación de los LED (entre 200 µs y 1600 µs) y ③ la
velocidad de muestreo del fotodiodo (entre 50 y 1000 muestras por segundo). Para
obtener una mayor resolución debe ser mayor la duración del pulso y se reduce el
número de muestras que pueden tomarse. Los valores de más resolución (16 bits)
corresponden con el pulso de 1600 µs y un máximo de 100 lecturas por segundo.
En el esquema de ejemplo anterior se han utilizado reguladores 6206 (hasta 250 mA),
como los LM6206 o los XC6206, pensando en el bajo consumo del MAX30100. Si se
necesitara una corriente mayor para otros componentes del circuito, con mínimas
modificaciones (condensadores electrolíticos de 10 µF a la entrada y 22 µF a la salida),
se puede sustituir, por ejemplo, por algún 1117 (algo más de 1 A) como los LM1117 o
los AMS1117, que también son muy económicos y sencillos de encontrar.
Para el esquema, solamente se ha utilizado una conexión para ambos LED pero
el MAX30100 permite conectarlos por separado, incluyendo una conexión para cada
ánodo. Los ánodos están internamente conectados a GND a través del driver de
los LED. Típicamente, los ánodos de ambos LED se dejan sin conectar, por lo que no
están indicados en el diagrama del ejemplo.
El uso más habitual consiste en realizar una lectura periódica del sensor de pulso pero
también se puede optar por usar la interrupción que se activa cuando la FIFO está casi
llena y recoger los valores cuando se produzca el aviso. Una vez generada la
interrupción el proceso de lectura sería el mismo. Si se opta por la lectura periódica, no
es necesario gestionar el tiempo desde el MCU, ya que el MAX30100 generará una
interrupción cuando termine el ciclo de integración, que tiene una duración fija y
configurable.
Además del modo de lectura de HbO2oxihemoglobina, que entrega dos bytes para los
valores de intensidad de luz roja en infrarroja detectada, el MAX30100 dispone de un
«modo latido» (o pulso) que solamente almacena el valor (dos bytes) de la lectura de
la luz infrarroja, dejando a cero los dos restantes que igualmente será necesario recibir
para que se actualice el puntero de lectura.
Utilizando el valor de esas intensidades a lo largo del tiempo es posible estimar tanto
el pulso (la frecuencia cardíaca) como en nivel de oxigenación de la sangre (la relación
entre la cantidad de hemoglobina y la cantidad de oxihemoglobina)
Ya se ha dicho que el MAX30100 almacena varias lecturas en una FIFO lo que permite
leer varios valores ya preparados en lugar de ir cargando cada uno que se integra. Si
el MCU no está muy ocupado con otras tareas también es posible leer cada valor
cuando el MAX30100 informe, generando una interrupción, de que el proceso de
la ADC ha terminado.
En el caso de optar por leer la FIFO cuando haya varias muestras disponibles sería
necesario primero calcular las que hay disponibles y luego realizar las lecturas de los
valores dentro un bucle.
1 recibir_i2c(MAX30100_DIRECCION,MAX30100_FIFO_PUNTERO_ESCRITURA,1,&cantidad_lecturas);
2 recibir_i2c(MAX30100_DIRECCION,MAX30100_FIFO_PUNTERO_LECTURA,1,max30100_buffer);
3 cantidad_lecturas-=(max30100_buffer[0]-1);
4 for(byte numero_lectura=0;numero_lectura<cantidad_lecturas;numero_lectura++)
Para construir el valor de la intensidad se asigna a un entero sin signo (16 bits) y se
rota 8 bits el primer valor que se carga en la lectura del bus I2C del MAX30100 (ya que
son los 8 bits más significativos) luego se le suman (OR) los 8 bits (los menos
significativos) de la segunda lectura.
Dos de las formas más económicas en recursos del MCU que pueden utilizarse
consisten en ① promediar los valores obtenidos hasta que solamente resulten
relevantes los máximos y los mínimos y tomar unos u otros y determinar el tiempo
transcurrido entre ellos y ② estimar cuándo los valores dejan de subir o de bajar,
admitiendo una tolerancia (máximo de duración de valores en una dirección cuando se
atiende a la contraria) y midiendo el tiempo entre ambos eventos. Si el rango de datos
está muy bien acotado el primer método parece más sencillo pero se intuye que el
segundo será más flexible si el rango de datos es variable (normalmente cuando el
contexto físico es más susceptible de cambiar) por lo que es la opción que se toma
como referencia.
Para hacer pruebas de los valores que se obtienen con esta estimación, se
puede descargar el código de ejemplo para Arduino de cálculo del pulso con la lectura
de luz infrarroja del MAX30100. En la captura de pantalla de abajo se puede ver un
ejemplo de resultado una vez estabilizada la medida.
Supuesto que la longitud de onda de la luz emitida por cada LED sea la correcta, un
inconveniente al calcular la SpO2 podría consistir en la intensidad diferencial emitida
por cada uno de los LED. Para compensarla, además de un desplazamiento y un
coeficiente estimados por ensayo, sería posible suministrar diferente corriente a cada
uno de los LED. Para ilustrar esta posibilidad y para poder visualizar la distribución de
ambas medidas, en el siguiente código de ejemplo se utilizan 30600 µA para el rojo y
50000 µA para el infrarrojo de forma que en la gráfica que se obtiene con el trazador
serie de Arduino puede superponer los valores medidos para ambos LED.
1 #include <Wire.h>
2 #include "MAX30100.h"
3 #include "enviar_recibir_i2c.h"
4
5 #define PIN_INTERRUPCION 7
6
7 byte max30100_buffer[4];
8 unsigned int intensidad_rojo;
9 unsigned int intensidad_infrarrojo;
1 boolean intensidad_preparada=false;
0
1 void setup()
1 {
1 pinMode(PIN_INTERRUPCION,INPUT_PULLUP);
2 Wire.begin();
1 enviar_i2c(MAX30100_DIRECCION,MAX30100_INTERRUPCION_ACTIVA,MAX30100_LED_LISTOS);
3 enviar_i2c(MAX30100_DIRECCION,MAX30100_CONFIGURACION_MODO,MAX30100_LED_ACTIVAR);
1 enviar_i2c(MAX30100_DIRECCION,MAX30100_CONFIGURACION_SPO2,MAX30100_ALTA_RESOLUCION|MAX30100_PULS
4 O_100_MPS|MAX30100_TIEMPO_LED_1600);
1 enviar_i2c(MAX30100_DIRECCION,MAX30100_CONFIGURACION_LED,MAX30100_ROJO_30600|MAX30100_INFRARROJO_
5 50000);
1 attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPCION),avisar_lectura,LOW);
6 Serial.begin(9600);
1 while(!Serial);
7 }
1
8 void loop()
1 {
9 if(intensidad_preparada)
2 {
0 intensidad_preparada=false;
2 recibir_i2c(MAX30100_DIRECCION,MAX30100_INTERRUPCION_ESTADO,1,max30100_buffer);
1 if
2 (
2 max30100_buffer[0]&MAX30100_LED_LISTOS &&
2 recibir_i2c(MAX30100_DIRECCION,MAX30100_FIFO_DATOS,4,max30100_buffer)
3 )
2 {
4 intensidad_infrarrojo=max30100_buffer[0];
2 intensidad_infrarrojo=max30100_buffer[1]|intensidad_infrarrojo<<8;
5 intensidad_rojo=max30100_buffer[2];
2 intensidad_rojo=max30100_buffer[3]|intensidad_rojo<<8;
6 Serial.print(intensidad_infrarrojo);
2 Serial.print("\t");
7 Serial.println(intensidad_rojo);
2 }
8 attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPCION),avisar_lectura,LOW);
2 }
9 }
3
0 void avisar_lectura()
3 {
1 detachInterrupt(digitalPinToInterrupt(PIN_INTERRUPCION));
3 intensidad_preparada=true;
2 }
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
Con pruebas de este tipo se pueden conocer mejor los márgenes en los que funciona
un de sensor, el MAX30100, en este caso. Por ejemplo, he observado que hasta no
llegar a los 7600 µA no se detecta de manera estable la luz reflejada y que la luz que
emite el LED rojo a más de 40200 µA satura el fotodiodo.
Suponiendo que la calibración de la relación entre la luz roja e infrarroja sea correcta
(hay que recordar que se detecta la luz reflejada, no la absorbida), al sustituir en el
anterior código de lectura de ambas intensidades la salida (los
códigos Serial.print de las líneas 41 a 43) del valor por:
1 Serial.println(100.0*(float)intensidad_rojo/((float)intensidad_rojo+(float)intensidad_infrarrojo));
se obtiene una lectura como la de la captura de pantalla de abajo, en la que puede
verse que el porcentaje está siempre muy cerca del 100 %, como cabría esperar. De
hecho, al tratarse de un dispositivo usado como wearable de salud (es decir, un equipo
no apto para su uso clínico), el límite inferior de lectura debería estar siempre por
encima del 95 % de saturación.