// Custom chips playground
// See https://link.wokwi.com/custom-chips-alpha for more info
#include <Adafruit_GFX.h> // OLED Library
#include <Adafruit_SSD1306.h> // OLED Library
#include <Wire.h> // I2C Library
#include "MAX30105.h" // MAX3010x library
#include "heartRate.h" // Heart rate calculating algorithm
MAX30105 particleSensor;
const byte RATE_SIZE = 4; // Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; // Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; // Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
const int LM35_PIN = 35;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display)
void setup() {
Serial.begin(115200);
Wire.setClock(400000); // Set I2C speed to 400kHz
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Start the OLED display
display.setTextColor(WHITE);
// Initialize sensor
particleSensor.begin(Wire, I2C_SPEED_FAST); // Use default I2C port, 400kHz speed
particleSensor.setup(); // Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); // Turn Red LED to low to indicate sensor is running
}
void loop() {
int sensorValue = analogRead(LM35_PIN); // Lecture de la valeur analogique du capteur
float voltage = sensorValue * (3.3 / 4095.0); // Conversion de la valeur analogique en tension (pour ESP32, la plage de valeurs analogiques est de 0 à 4095 pour une tension de 0 à 3.3V)
float temperature = voltage * 100.0; // La tension du LM35 est de 10mV/°C (0.01V/°C)
long irValue = particleSensor.getIR();
long redValue = particleSensor.getRed();
float SpO2 = calculateSpO2(irValue, redValue);
// Reading the IR value it will permit us to know if there's a finger on the sensor or not
if (irValue > 50000)
{
if (checkForBeat(irValue) == true) //If a heart beat is detected, call checkForBeat as frequent as possible to get accurate value
{
long delta = millis() - lastBeat; //Measure duration between two beats
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0); //Calculating the BPM
if (beatsPerMinute < 255 && beatsPerMinute > 20) //To calculate the average we strore some values (4) then do some math to calculate the average
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
Serial.print("BPM:");
Serial.print(beatAvg);
Serial.print("SpO2:");
Serial.print(SpO2);
Serial.print("Temp:");
Serial.print(temperature);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print("temp:");
display.print(temperature);
display.display();
/*
display.setCursor(0, 45);
display.setTextSize(1);
display.print("SpO2 :");
display.print(SpO2);
display.setCursor(0, 60);
display.setTextSize(1);
display.print("temp :");
display.print(temperature);
display.display();
*/
/*
display.setCursor(0, 20);
display.print("SpO2 :");
display.print(SpO2);
display.setCursor(0, 45);
display.print("Temp :");
display.print(temperature);
display.display();
*/
}
}
}
float calculateSpO2 (float irValue, float redValue) {
// Placeholder calculation - You'll need a proper algorithm for accurate SpO2 calculation
// This is a simple placeholder to illustrate the concept
float ratio = redValue / irValue;
float SpO2 = 100 - 17 * ratio; // This is a simplified calculation
return SpO2;
}
/*
else
{
display.clearDisplay();
display.setTextSize(3);
display.setCursor(0, 20);
display.print("BPM:");
display.print(0);
display.setCursor(0, 45);
display.setTextSize(1);
display.print("Place your finger in sensor and wait..");
display.display();
}
}
*/