Tabla de contenido:
- Paso 1: hardware
- Paso 2: Señales digitales devueltas por MAX30102
- Paso 3: preprocesamiento de la señal
- Paso 4: El caballo de batalla: función de autocorrelación
- Paso 5: Determinación de la saturación de oxígeno
- Paso 6: el código fuente
Video: Pulsioxímetro con mucha precisión mejorada: 6 pasos (con imágenes)
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:42
Si visitó recientemente a un médico, es probable que una enfermera haya examinado sus signos vitales básicos. El peso, la altura, la presión arterial, así como la frecuencia cardíaca (FC) y la saturación de oxígeno en sangre periférica (SpO2). Quizás, los dos últimos se obtuvieron a partir de una sonda digital electrónica de brillo rojo que mostraba números relevantes en una pequeña pantalla en minutos. Esa sonda se llama oxímetro de pulso y puede encontrar toda la información básica al respecto aquí.
Uno puede comprar fácilmente un oxímetro de pulso simple, claro, pero ¿dónde está la diversión? He decidido construir el mío, primero por el gusto de hacerlo, pero lo más importante es con una aplicación específica en mente: oximetría nocturna donde tanto la FC como la SpO2 Los datos se recopilarían continuamente durante la noche y se grabarían en una tarjeta micro SD. Instructables ya contiene varios proyectos de este tipo, por ejemplo, dos que involucran a Arduino aquí y aquí, y uno que utiliza Raspberry Pi. El mío usa el sensor MAX30102 un poco más nuevo de MAXIM Integrated y el Adalogger Feather M0 de Adafruit para el control y el registro de datos.
Por lo tanto, nuestro proyecto no es particularmente innovador en términos de hardware y, como tal, no valdría la pena escribir este Instructable, pero en el proceso de creación, hice avances cruciales en el software que me permitieron extraer datos de MAX30102 con mucha más consistencia y mucho menos ruido que el software escrito por MAXIM para este sensor. El rendimiento de nuestro algoritmo de procesamiento de señales se ilustra en el gráfico anterior, donde los dos gráficos superiores contienen la frecuencia cardíaca nocturna y la saturación de oxígeno calculadas a partir de señales sin procesar por nuestro método (identificadas por "RF"), mientras que los dos gráficos inferiores muestran los resultados de MAXIM producidos a partir de exactamente las mismas señales. Las desviaciones estándar de FC son 4,7 lpm y 18,1 lpm, y para SpO2 0,9% y 4,4%, para RF y MAXIM, respectivamente.
(Ambos gráficos de RF corresponden a un umbral de autocorrelación mínimo de 0,25 y sin límite de correlación R / IR; consulte los pasos 4 y 5 para obtener una explicación de estos términos).
Paso 1: hardware
- Oxímetro de pulso y sensor de frecuencia cardíaca Placa de sistema MAX30102 de MAXIM Integrated, Inc.
- Feather M0 Adalogger de Adafruit, Inc.
- Batería de iones de litio de Adafruit, Inc.
Conexiones:
- Adalogger pines SCL y SDA a los pines SCL y SDA correspondientes en la placa MAX30102
- Adalogger pin 10 a pin INT en la placa MAX30102
- Adalogger GND a placa MAX30102 GND
- Adalogger 3V a MAX30102 VIN
Paso 2: Señales digitales devueltas por MAX30102
Los principios del funcionamiento del sensor son muy simples: dos LED, uno rojo (660 nm) y otro infrarrojo (880 nm, IR) iluminan la piel humana. La luz es absorbida parcialmente por los tejidos subyacentes, incluida la sangre periférica. El fotodetector del sensor recoge la luz reflejada en ambas longitudes de onda y devuelve dos intensidades relativas correspondientes utilizando el protocolo I2C. Dado que los espectros de absorción para la hemoglobina oxigenada y desoxigenada difieren para ambas longitudes de onda, la luz reflejada tiene un componente variable ya que la cantidad de sangre arterial que está presente debajo de la piel pulsa con cada latido del corazón. Averiguar la frecuencia cardíaca y la saturación de oxígeno depende del software de procesamiento de señales.
En las imágenes anteriores se ilustran ejemplos de señales sin procesar (solo canal IR). Uno puede notar un componente periódico superpuesto en una línea de base variable que está cambiando debido a múltiples factores mencionados en la página de Wikipedia. Los artefactos inducidos por el movimiento son particularmente molestos ya que pueden enmascarar la señal de frecuencia cardíaca útil y causar resultados falsos. Por lo tanto, los oxímetros comerciales avanzados cuentan con acelerómetros que ayudan a anular estos artefactos.
Puedo agregar un acelerómetro a la próxima versión de mi oxímetro, pero para FC / SpO nocturna2 grabación, cuando el sensor permanece inmóvil la mayor parte del tiempo, es suficiente para detectar y omitir señales distorsionadas.
El sensor MAX30102 en sí viene en un pequeño paquete montado en la superficie, pero MAXIM amablemente ofrece una placa de conexión (placa del sistema 6300) más software de procesamiento de señal para Arduino y mbed, todo en el paquete de diseño de referencia MAXREFDES117 #. Felizmente lo compré esperando soldar algunos cables entre el sensor y Adalogger y tener un buen oxímetro funcionando en un solo día. Adapté la versión RD117_ARDUINO del software de MAXIM para que se ejecutara en el procesador ARM Cortex M0 de Adalogger. Básicamente, todo lo que tenía que hacer era reemplazar las funciones SofI2C incompatibles en max30102.cpp por las correspondientes llamadas a la biblioteca Wire. El código se compiló bien en Arduino IDE v1.8.5 y se ejecutó en M0 sin errores. Sin embargo, los resultados netos fueron decepcionantes. En el paso de Introducción ya he mostrado una varianza muy alta tanto de FC como de SpO2. Naturalmente, uno puede afirmar que he hecho algo mal y este también fue mi pensamiento original. Sin embargo, en el video instructivo de MAXIM también puede observar valores de FC que varían enormemente en la pantalla. Además, los comentarios debajo del video confirman que otros también han notado un fenómeno similar.
Para abreviar la historia, después de un poco de experimentación, he determinado que el sensor está funcionando bien y un método alternativo de procesamiento de señales digitales da como resultado una estabilidad mucho mejor. Este nuevo método, indicado por "RF", se describe en los siguientes pasos.
Paso 3: preprocesamiento de la señal
En nuestra implementación, la señal sin procesar se recopila a una velocidad de 25 Hz (igual que la de MAXIM) durante 4 segundos completos (el software de MAXIM recopila solo el valor de 1 segundo), lo que da como resultado 100 puntos de tiempo digitalizados por punto de datos final. Cada secuencia de 100 puntos debe procesarse previamente de la siguiente manera:
- Centrado medio (también conocido como "eliminación del componente de CC" para ingenieros eléctricos). Los datos brutos que provienen del sensor son una serie de tiempo de números enteros en el 105 distancia. Sin embargo, la señal útil es solo una parte de la luz reflejada por la sangre arterial, que varía en el orden de solo 102 - primera figura. Por lo tanto, para un procesamiento de señales significativo, es deseable restar la media de cada punto de la serie. Esta parte no es diferente de lo que ya hace el software MAXIM. Sin embargo, lo que es diferente es el centrado medio adicional de los propios índices de tiempo. En otras palabras, en lugar de indexar los puntos de la serie por números del 0 al 99, los nuevos índices ahora son números -49.5, -48.5,…, 49.5. Puede parecer extraño al principio, pero gracias a este procedimiento el "centro de gravedad" de la curva de la señal coincide con el origen del sistema de coordenadas (segunda figura). Este hecho se vuelve bastante útil en el siguiente paso.
- Nivelación de la línea de base. Otra mirada a las formas de onda que se muestran en el Paso 2 ilustra que la línea de base de las señales de oximetría reales está lejos de ser horizontalmente plana, pero varía a través de diferentes pendientes. La tercera figura muestra una señal IR centrada en la media (curva azul) y su línea de base (línea recta azul). En este caso, la pendiente de la línea de base es negativa. El método de procesamiento de señales que se describe a continuación requiere que la línea de base sea horizontal. Esto se puede lograr simplemente restando la línea de base de la señal centrada en la media. Gracias al centrado medio de las coordenadas Y y X, la intersección de la línea de base es cero y su ecuación de pendiente es particularmente simple, como se muestra en la cuarta figura. La señal nivelada de la línea de base se muestra mediante una curva naranja en la tercera figura.
Por lo tanto, la señal preprocesada está lista para el siguiente paso.
Paso 4: El caballo de batalla: función de autocorrelación
Volviendo a la indexación habitual 1,…, n, la primera figura muestra la definición de la función de autocorrelación rmetro - una cantidad que se considera muy útil para detectar la periodicidad y la calidad de la señal. Es simplemente un producto escalar normalizado de la serie de tiempo de la señal con ella misma desplazada por lag m. En nuestra aplicación, sin embargo, es conveniente escalar cada valor de autocorrelación con respecto a su valor en lag = 0, es decir, usar la autocorrelación relativa definida por rmetro / r0.
En la segunda figura se muestra el gráfico de la autocorrelación relativa de una señal IR típica de buena calidad. Como se esperaba, su valor en lag = 0 está en su máximo global igual a 1. El siguiente máximo (local) ocurre en lag = 23 y es igual a 0,79. La presencia de mínimos y máximos locales en la gráfica de autocorrelación es fácil de entender: a medida que la señal se desplaza hacia la derecha, sus picos interfieren destructivamente entre sí al principio, pero en cierto punto la interferencia se vuelve constructiva y alcanza el máximo en el retraso igual al promedio. período de la señal.
La última frase es crucial: para determinar el período de tiempo promedio entre picos, a partir del cual se puede calcular la frecuencia de la señal (es decir, la frecuencia cardíaca), ¡es suficiente encontrar el primer máximo local de la función de autocorrelación! De forma predeterminada, MAX30102 muestrea la entrada analógica a una velocidad de 25 puntos por segundo, por lo tanto, en un m dado, el período en segundos es igual am / 25. Esto lleva a la frecuencia cardíaca expresada en latidos por minuto (lpm) mediante:
HR = 60 * 25 / m = 1500 / m
Por supuesto, no es necesario hacer costosos cálculos de rmetro en todos los valores de retraso. Nuestro algoritmo hace la primera estimación de frecuencia cardíaca = 60 lpm, que corresponde a m = 25. La función de autocorrelación se evalúa en ese punto y se compara con el valor de su vecino izquierdo, m = 24. Si el valor de los vecinos es mayor, entonces el marcha continúa hacia la izquierda hasta rm-1 <rmetro. La m final determinada de este modo se devuelve como el retraso al máximo. La siguiente iteración comienza con ese valor en lugar de 25 y todo el proceso se repite. Si el primer vecino de la izquierda es más bajo, entonces la rutina anterior marca puntos de retraso hacia la derecha de manera similar. La mayoría de las veces, el retraso al máximo requiere solo unas pocas evaluaciones de la función de autocorrelación. Además, los retardos máximos y mínimos aceptables (correspondientes a la frecuencia cardíaca mínima y máxima, respectivamente) se utilizan como valores límite.
Lo anterior funciona muy bien para señales de buena calidad, pero el mundo real está lejos de ser ideal. Algunas señales salen distorsionadas, principalmente debido a artefactos de movimiento. Tal señal se muestra en la tercera figura. La mala periodicidad se refleja en la forma de su función de autocorrelación así como en el valor bajo, 0.28, del primer máximo local en m = 11. Compárelo con el valor máximo de 0.79 determinado para la señal de buena calidad. Junto con los valores límite de retardo, por lo tanto, el valor de rmetro / r0 como máximo es un buen indicador de la calidad de la señal y se puede utilizar un requisito para que supere cierto umbral para filtrar los artefactos de movimiento. Los gráficos de "RF" que se muestran en las introducciones resultaron de dicho umbral igual a 0,25.
Paso 5: Determinación de la saturación de oxígeno
El paso anterior fue suficiente para determinar la frecuencia cardíaca. La SpO2 requiere más trabajo. Primero, debe tenerse en cuenta la señal hasta ahora descuidada en el canal rojo (R). A continuación, se calcula la relación de señales rojas a infrarrojas, Z = R / IR, ambas reflejadas en la sangre arterial. La parte de la "sangre arterial" es crucial, ya que la mayor parte de la luz se refleja en los tejidos y la sangre venosa. ¿Cómo elegir la parte de la señal correspondiente a la sangre arterial? Bueno, este es el componente pulsátil que varía con cada latido del corazón. En palabras de los ingenieros eléctricos, es la "parte de CA", mientras que la luz reflejada restante es la "parte de CC". Dado que las intensidades absolutas de la luz R e IR no son conmensurables, la relación Z se calcula a partir de intensidades relativas, como se muestra en la primera figura. En términos de cantidades realmente calculadas, utilizo la raíz cuadrada media (RMS) de la señal centrada en la media, nivelada en la línea de base, y, para la media ya conocida de la señal sin procesar, <Y>; ver la segunda figura. Sin embargo, la relación Z es solo la mitad del trabajo. La respuesta del sensor no lineal requiere una calibración empírica entre Z y la SpO final2 valores. Tomé la ecuación de calibración del código de MAXIM:
SpO2 = (-45,06 * Z + 30,354) * Z + 94,845
Tenga en cuenta que esta ecuación es válida solo para la placa de diseño MAX30102 comprada en 2017. Es probable que MAXIM vuelva a calibrar sus sensores en una fecha posterior.
El procedimiento anterior todavía produce una gran cantidad de falsa SpO2 lecturas. El canal rojo sufre de muchos artefactos, al igual que el de infrarrojos. Es razonable suponer que ambas señales deben estar fuertemente correlacionadas. De hecho, las señales de buena calidad, como el ejemplo de la tercera figura, se correlacionan muy bien. El coeficiente de correlación de Pearson es en este caso tan alto como 0,99. Este no es siempre el caso, como se ilustra en la cuarta figura. Aunque la señal de infrarrojos pasaría el filtro de calidad de frecuencia cardíaca con su rmetro / r0 = 0,76, la señal R distorsionada da como resultado un coeficiente de correlación pobre entre los dos igual a solo 0,42. Esta observación ofrece el segundo filtro de calidad: tener el coeficiente de correlación entre canales mayor que cierto umbral.
Las dos últimas cifras ejemplifican el efecto neto de dicho filtrado de calidad. Primero, la saturación de oxígeno medida se traza con un umbral de calidad de FC de 0,25, pero sin la SpO.2 filtrar. El siguiente gráfico es el resultado de filtrar la FC y la SpO deficientes2 resultados al 0,5 rmetro / r0 y umbrales de coeficiente de correlación de 0,8. En general, los puntos de datos deficientes que ascienden al 12% del total fueron filtrados por el régimen más estricto.
En nuestro código, el coeficiente de correlación, cc, se calcula de acuerdo con la fórmula de la quinta figura, donde y representa la señal de nivel de línea base centrada en la media, mientras que r0 se definió en el paso anterior.
Paso 6: el código fuente
El código fuente de C para este proyecto, formateado para el IDE de Arduino, está disponible en nuestra cuenta de Github en el siguiente enlace:
github.com/aromring/MAX30102_by_RF
Su página Léame describe los componentes individuales.
Me gustaría tomarme un momento para elogiar a Adafruit por hacer un producto tan excelente como Adalogger basado en M0. Su rápido procesador ARM Cortex M0 de 48 MHz, con mucha RAM, ciertamente ayudó a que este proyecto fuera viable, mientras que el lector de tarjetas SD conectado directamente (más la biblioteca SD de Adafruit) elimina todos los dolores del aficionado asociados con el almacenamiento en tiempo real de grandes cantidades de datos.
Recomendado:
Estrella navideña más grande y mejorada Neopixel Attiny85: 3 pasos (con imágenes)
Estrella navideña más grande y mejorada Neopixel Attiny85: el año pasado hice una pequeña estrella navideña impresa en 3D, ver https://www.instructables.com/id/Christmas-Star-LE … Este año hice una estrella más grande a partir de una hebra de 50 Neopixels (5V WS2811). Esta estrella más grande tenía más patrones (todavía estoy agregando y mejorando
Turbina electrostática mejorada hecha de materiales reciclables: 16 pasos (con imágenes)
Turbina electrostática mejorada hecha de materiales reciclables: se trata de una turbina electrostática (EST) completamente construida desde cero que convierte la corriente continua de alto voltaje (HVDC) en movimiento giratorio de alta velocidad. Mi proyecto se inspiró en el motor Jefimenko Corona, que funciona con electricidad de la atmósfera
DETECTOR DE FUGAS DE LA CARCASA DE LA CÁMARA SUBACUÁTICA MEJORADA: 7 pasos (con imágenes)
DETECTOR DE FUGAS DE LA CARCASA DE LA CÁMARA SUBACUÁTICA MEJORADA: Una versión anterior de este detector de fugas de la carcasa de la cámara subacuática se publicó en Instructables el año pasado, donde el diseño se basó en un AdaFruit Trinket basado en Atmel AVR. Esta versión mejorada emplea el AdaFruit Trinket basado en Atmel SAMD M0. Allí
Radio NRF24L01 mejorada con una modificación de la antena dipolo de bricolaje: 5 pasos (con imágenes)
Radio NRF24L01 mejorada con una modificación de antena dipolo de bricolaje: La situación era que solo podía transmitir y recibir a través de 2 o 3 paredes con una distancia de aproximadamente 50 pies, utilizando módulos estándar nRF24L01 +. Esto fue insuficiente para mi uso previsto. Anteriormente había intentado agregar condensadores recomendados, pero
Cámara térmica mejorada PiEyeR: 8 pasos (con imágenes)
Cámara térmica mejorada PiEyeR: descripción general La placa de cámara térmica infrarroja Adafruit AMG8833 puede proporcionar una cámara de imágenes de infrarrojo lejano similar a "FLIR" a aproximadamente una décima parte del precio de las unidades de imagen térmica infrarroja lejana anteriores. Por supuesto, la resolución y la sensibilidad no son tan altas