#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <MAX30105.h>
#include "spo2_algorithm.h"
#include "heartRate.h"
// Display OLED
Adafruit_SSD1306 display(128, 64, &Wire, -1);
// DHT22
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// MAX30102
MAX30105 particleSensor;
uint32_t irBuffer[100]; // Infrared LED sensor data
uint32_t redBuffer[100]; // Red LED sensor data
int32_t bufferLength; // Data length
int32_t spo2; // SPO2 value
int8_t validSPO2; // Indicator to show if the SPO2 calculation is valid
int32_t heartRate; // Heart rate value calculated as per Maxim's algorithm
int8_t validHeartRate; // Indicator to show if the heart rate calculation is valid
void setup() {
Serial.begin(115200);
// Inicializar display OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000);
display.clearDisplay();
// Inicializar DHT22
dht.begin();
// Inicializar MAX30102
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
Serial.println(F("MAX30105 was not found. Please check wiring/power."));
while (1);
}
byte ledBrightness = 50; // Options: 0=Off to 255=50mA
byte sampleAverage = 4; // Options: 1, 2, 4, 8, 16, 32
byte ledMode = 2; // Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
byte sampleRate = 100; // Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; // Options: 69, 118, 215, 411
int adcRange = 4096; // Options: 2048, 4096, 8192, 16384
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
}
void loop() {
// Leer temperatura y humedad del DHT22
float h = dht.readHumidity();
float t = dht.readTemperature();
// Leer datos del MAX30102
bufferLength = 100; // Buffer length of 100 stores 4 seconds of samples running at 25sps
for (byte i = 0; i < bufferLength; i++) {
while (particleSensor.available() == false) { // Do we have new data?
particleSensor.check(); // Check the sensor for new data
}
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); // We're finished with this sample so move to next sample
}
// Calcular frecuencia cardíaca y SpO2 después de los primeros 100 samples (primeros 4 segundos de muestras)
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
// Mostrar datos en el display OLED
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE);
display.print("Temp: ");
display.print(t);
display.println(" *C");
display.print("Humidity: ");
display.print(h);
display.println(" %");
if (validHeartRate) {
display.print("Heart Rate: ");
display.print(heartRate);
display.println(" bpm");
} else {
display.println("Invalid Heart Rate");
}
if (validSPO2) {
display.print("SpO2: ");
display.print(spo2);
display.println(" %");
} else {
display.println("Invalid SpO2");
}
display.display();
delay(2000); // Espera 2 segundos entre actualizaciones
}