Monitor de oxígeno en sangre y temperatura corporal con Arduino: Sistema de doble sensor
Componentes y suministros
| Arduino UNO | 1 |
| Pantalla LCD I2C 20x4 | 1 |
| Sensor frecuencia cardíaca Max30102 | 1 |
| 2 LEDs | 1 |
| 2 Resistencias 220Ω | 1 |
| Módulo sensor temperatura infrarrojo sin contacto GY-906-BCC (MLX90614) | 1 |
| Protoboard 830 puntos | 1 |
Sobre el proyecto
Este proyecto detecta simultáneamente el valor de oxígeno en sangre (SpO2) y la temperatura corporal. Cualquier valor por debajo del umbral configurado enciende un LED rojo de alerta.
Importante: El módulo de oxígeno en sangre requiere colocar el dedo naturalmente sobre él para la detección, sin ejercer demasiada presión, ya que esto alteraría los valores.
¡Feliz Año Nuevo y diviértete construyéndolo!
- Código en GitHub (esquema y sketch): https://github.com/DKARDU/bloodoxygen
Componentes utilizados
- Arduino UNO
- LCD I2C 20x4
- Sensor Max30102
- 2 LEDs
- 2 Resistencias 220Ω
- Módulo GY-906-BCC (MLX90614)






Código
Blood_Oximeter.ino Arduino
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <EEPROM.h>
#include "MAX30105.h"
MAX30105 particleSensor;
LiquidCrystal_I2C lcd(0x27,20,4);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
double avered = 0; double aveir = 0; double sumirrms = 0; double sumredrms = 0;
int i = 0; int Num = 100; int Temperature; int temp;
float ESpO2; float ESpO2_ROM; double FSpO2 = 0.7; double frate = 0.95;
#define TIMETOBOOT 3000
#define SCALE 88.0
#define SAMPLING 5
#define FINGER_ON 30000
#define USEFIFO
#define Greenled 8
#define Redled 9
void setup() {
Serial.begin(115200);
lcd.init(); lcd.backlight();
lcd.setCursor(3,1); lcd.print("Running......"); delay(3000); lcd.clear();
ESpO2 = readEEPROM(); Temperature = EEPROM.read(6);
pinMode(Greenled,OUTPUT); pinMode(Redled,OUTPUT);
digitalWrite(Greenled,LOW); digitalWrite(Redled,LOW);
while (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
Serial.println("MAX30102 was not found. Please check wiring/power/solder jumper at MH-ET LIVE MAX30102 board. ");
}
byte ledBrightness = 0x7F; byte sampleAverage = 4; byte ledMode = 2;
int sampleRate = 200; int pulseWidth = 411; int adcRange = 16384;
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
particleSensor.enableDIETEMPRDY(); mlx.begin();
}
void loop() {
uint32_t ir, red, green; double fred, fir; double SpO2 = 0;
#ifdef USEFIFO
particleSensor.check();
while (particleSensor.available()) {
#ifdef MAX30105
red = particleSensor.getFIFORed(); ir = particleSensor.getFIFOIR();
#else
red = particleSensor.getFIFOIR(); ir = particleSensor.getFIFORed();
#endif
i++; fred = (double)red; fir = (double)ir;
avered = avered * frate + (double)red * (1.0 - frate);
aveir = aveir * frate + (double)ir * (1.0 - frate);
sumredrms += (fred - avered) * (fred - avered);
sumirrms += (fir - aveir) * (fir - aveir);
if ((i % SAMPLING) == 0) {
if (millis() > TIMETOBOOT) {
float ir_forGraph = (2.0 * fir - aveir) / aveir * SCALE;
float red_forGraph = (2.0 * fred - avered) / avered * SCALE;
if (ir_forGraph > 100.0) ir_forGraph = 100.0;
if (ir_forGraph < 80.0) ir_forGraph = 80.0;
if (red_forGraph > 100.0) red_forGraph = 100.0;
if (red_forGraph < 80.0) red_forGraph = 80.0;
Serial.print(","); Serial.print(ir);Serial.print(".");
float temperature = particleSensor.readTemperatureF();
if (ir < FINGER_ON){
temp = Temperature; EEPROM.write(6,temp); ESpO2_ROM = ESpO2; writeEEPROM(&ESpO2_ROM);
lcd.setCursor(0,2); lcd.print("Last test: "); lcd.setCursor(11,2); lcd.print(ESpO2_ROM); lcd.print(" % ");
lcd.setCursor(0,3); lcd.print("Last temp: "); lcd.setCursor(11,3); lcd.print(temp); lcd.print(" *C");
break;
}
if(ir > FINGER_ON){
Temperature = mlx.readObjectTempC();
lcd.setCursor(0,0); lcd.print("Oxygen % = "); lcd.setCursor(11,0); lcd.print(ESpO2); lcd.print(" % ");
lcd.setCursor(0,1); lcd.print("Temperature: "); lcd.print(Temperature); lcd.print(" *C");
if((ESpO2 >= 90) && (Temperature < 38)){ digitalWrite(Redled,LOW); digitalWrite(Greenled,HIGH); }
if((ESpO2 < 90) || (Temperature > 37)){ digitalWrite(Greenled,LOW); digitalWrite(Redled,HIGH); }
}
}
}
if ((i % Num) == 0) {
double R = (sqrt(sumredrms) / avered) / (sqrt(sumirrms) / aveir);
SpO2 = -23.3 * (R - 0.4) + 100;
ESpO2 = FSpO2 * ESpO2 + (1.0 - FSpO2) * SpO2;
sumredrms = 0.0; sumirrms = 0.0; i = 0; break;
}
particleSensor.nextSample();
}
#endif
}
void writeEEPROM(float *data) {
byte ByteArray[4]; memcpy(ByteArray, data, 4);
for(int x = 0; x < 4; x++) { EEPROM.write(x, ByteArray[x]); }
}
float readEEPROM() {
float ESpO2 = 85.0; byte ByteArray[4];
for(int x = 0; x < 4; x++) { ByteArray[x] = EEPROM.read(x); }
memcpy(&ESpO2, ByteArray, 4); return ESpO2;
}
Esquemáticos
Proceso de manufactura
- Raspberry Pi y HDC2010: Guía completa de configuración I2C para sensor de temperatura y humedad
- Construya un registrador de temperatura con Raspberry Pi y sensor I2C de 5 $
- Construya un sensor de temperatura remoto con Raspberry Pi y Python – Guía paso a paso
- Construya un Sistema de Monitorización de Temperatura y Luz Multi‑Sensor con Raspberry Pi y DS18B20
- Monitor de temperatura casero con Raspberry Pi, MCP9808, InfluxDB y Grafana
- Verifica y calibra tu sensor de humedad para mediciones precisas
- Construcción de un robot con Arduino y Raspberry Pi: Guía paso a paso
- Crear Animación de Corte Progresivo en SolidWorks: Tutorial Paso a Paso
- Sensor de temperatura de rodamientos de precisión: detección y monitorización exactas
- Sensor de Temperatura DS18B20 – Termómetro Digital 1-Wire Preciso para Uso Industrial y Consumo
- La guía completa de producción de fibra de vidrio