Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Oxímetro de pulso DIY open-source para COVID-19 con Arduino Nano y MAX30102

Componentes y materiales

ComponenteCantidad
Arduino Nano R31
Sensor MAX30102 (frecuencia cardíaca y SpO2)1
Pantalla OLED I2C 128x64 (DFRobot Gravity)1
Filamento PLA, tornillos M3Varios

Herramientas

Software

Sobre el proyecto

Dispositivo portátil que mide frecuencia cardíaca (HR) y saturación de oxígeno (SpO2) para monitorización casera durante la pandemia COVID-19. No es un dispositivo médico certificado; sirve como referencia orientativa.

Electrónica

Montaje paso a paso

  1. Imprimir carcasa: 2 piezas (base y tapa) en PLA, infill 70-80%, soportes medios. Lijar ligeramente.
  2. Soldar electrónica: Arduino Nano en perfboard 44x30mm. Cables VIN, GND, SDA (A4), SCL (A5) al MAX30102. Conector OLED a mismos bus I2C. Fijar con tornillos M3.
  3. Ensamblar: Insertar PCB en base, atornillar OLED en tapa, unir ambas piezas.
  4. Subir sketch: Seleccionar "Arduino Nano" en Tools → Board. Instalar librerías necesarias.
  5. Usar: Colocar dedo sobre sensor, cerrar tapa, alimentar (USB o batería). Esperar lecturas estables (HR y SpO2).

Código principal (sketch)

/* Conexiones: VCC=5V, GND=GND, SDA=A4, SCL=A5, INT=NC */
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

MAX30105 particleSensor;
SSD1306AsciiWire oled;
#define MAX_BRIGHTNESS 255

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
uint16_t irBuffer[50], redBuffer[50]; // 16-bit para ahorrar RAM
#else
uint32_t irBuffer[50], redBuffer[50];
#endif

int32_t spo2; int8_t validSPO2;
int32_t heartRate; int8_t validHeartRate;

void setup() {
  Serial.begin(115200);
  oled.begin(&Adafruit128x64, 0x3C);
  oled.setFont(Arial14);
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
    Serial.println(F("MAX30105 no encontrado. Revisa cableado/alimentación."));
    while(1);
  }
  particleSensor.setup(55, 4, 2, 200, 411, 4096); // Config: ledBrightness=55, sampleAvg=4, ledMode=2, sampleRate=200, pulseWidth=411, adcRange=4096
}

void loop() {
  // Primeras 50 muestras para calibrar rango
  for (byte i=0; i<50; i++) {
    while (!particleSensor.available()) particleSensor.check();
    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample();
    Serial.print("red="); Serial.print(redBuffer[i]);
    Serial.print(", ir="); Serial.println(irBuffer[i]);
  }
  maxim_heart_rate_and_oxygen_saturation(irBuffer, 50, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  // Bucle continuo: ventana deslizante de 50 muestras (25 nuevas cada ciclo)
  while (1) {
    // Desplazar 25 muestras antiguas
    for (byte i=25; i<50; i++) {
      redBuffer[i-25] = redBuffer[i];
      irBuffer[i-25] = irBuffer[i];
    }
    // Adquirir 25 nuevas
    for (byte i=25; i<50; i++) {
      while (!particleSensor.available()) particleSensor.check();
      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample();
      // Debug serie
      Serial.print("red="); Serial.print(redBuffer[i]);
      Serial.print(", ir="); Serial.print(irBuffer[i]);
      Serial.print(", HR="); Serial.print(heartRate);
      Serial.print(", HRvalid="); Serial.print(validHeartRate);
      Serial.print(", SPO2="); Serial.print(spo2);
      Serial.print(", SPO2Valid="); Serial.println(validSPO2);
    }
    maxim_heart_rate_and_oxygen_saturation(irBuffer, 50, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
    printToScreen();
  }
}

void printToScreen() {
  oled.clear(); oled.setCursor(0,0);
  if (validSPO2 && validHeartRate) {
    oled.print(F("HR: ")); oled.println(heartRate);
    oled.print(F("SPO2: ")); oled.println(spo2);
  } else {
    oled.print(F("No válido"));
  }
}

Piezas 3D (carcasa)

Archivos STL disponibles en la sección "Custom parts and enclosures" del proyecto original. Incluyen base, tapa y clip para dedo.

Esquemático

Diagrama de conexiones I2C compartido: Arduino A4/SDA → ambos dispositivos SDA; A5/SCL → ambos SCL; 5V y GND comunes. El MAX30102 tolera 5V en I2C.

Nota importante

Este proyecto es educativo y de referencia. La precisión depende de contacto dedo-sensor, luz ambiente, movimiento, calibración del algoritmo. No sustituye a un oxímetro médico homologado.

Proceso de manufactura

  1. Registro del Proyecto FirePick Delta: Construyendo una MicroFactory Open‑Source con OpenPnP
  2. Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
  3. Construye un Iron Man animado con Arduino: componentes, sensores y guía paso a paso
  4. Find Me: Localizador Inteligente de Objetos con Arduino y Bluetooth
  5. Construye un Brazo Robótico Impreso en 3D Controlado por Arduino – Guía Paso a Paso
  6. Oxímetro de Pulso Portátil para Emergencias COVID-19 - Arduino Nano + MAX30100
  7. Controlador de Humidificador DIY con Arduino y Relé: Configuración Segura de Alto Voltaje
  8. Pong Neón en Matriz NeoPixel con Arduino Nano
  9. Construye un volante joystick personalizado con Arduino para gaming
  10. Health Band: Asistente Inteligente Vestible para Personas Mayores
  11. Por Qué el Open Source Impulsa la Innovación en el Edge: eBook Esencial