#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"
#include "LiquidCrystal_I2C.h"
// Définition des modules
MAX30105 particleSensor;
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adresse I2C 0x27, LCD 16x2
// Activer simulation (true pour Wokwi, false pour Arduino réel)
#define SIMULATION false
// Définition d'un cœur pour l'affichage
byte heartChar[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
// Variables fréquence cardiaque
const byte RATE_SIZE = 7;
byte rates[RATE_SIZE];
byte rateSpot = 0;
long lastBeat = 0;
float beatsPerMinute;
int beatAvg;
unsigned long previousMillis = 0;
const long interval = 1000;
int buzzer = 3;
void setup() {
Serial.begin(115200);
pinMode(buzzer, OUTPUT);
// Initialisation du LCD
lcd.begin(16, 2);
lcd.backlight();
lcd.createChar(0, heartChar);
lcd.print("Initializing...");
delay(1000);
lcd.clear();
if (!SIMULATION) { // Mode Arduino réel
Wire.begin();
// Scanner l'I2C pour trouver l'adresse du capteur
byte address = scanI2C();
if (address == 0) {
lcd.print("Sensor Error!");
Serial.println("MAX30102 non détecté !");
while (1);
}
// Initialisation du capteur avec l'adresse détectée
if (!particleSensor.begin(Wire, address)) {
lcd.print("Init Failed!");
Serial.println("Echec initialisation MAX30102 !");
while (1);
}
Serial.println("MAX30102 détecté !");
lcd.clear();
lcd.print("MAX30102 Ready!");
delay(1000);
lcd.clear();
particleSensor.setup();
particleSensor.setPulseAmplitudeRed(0x0A);
}
}
// Fonction pour scanner l'adresse I2C du capteur
byte scanI2C() {
Serial.println("Recherche I2C...");
for (byte address = 1; address < 127; address++) {
Wire.beginTransmission(address);
if (Wire.endTransmission() == 0) {
Serial.print("Capteur trouvé à : 0x");
Serial.println(address, HEX);
return address;
}
}
return 0; // Aucun périphérique trouvé
}
void loop() {
long irValue;
if (SIMULATION) {
irValue = random(50000, 100000); // Simule un signal IR
} else {
irValue = particleSensor.getIR(); // Lit la valeur réelle du capteur
}
Serial.print("IR Value: ");
Serial.println(irValue);
if (irValue < 50000) { // Pas de doigt détecté
lcd.clear();
lcd.print("Place finger!");
Serial.println("Doigt non détecté !");
digitalWrite(buzzer, LOW);
return;
}
if (checkForBeat(irValue)) {
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute > 20 && beatsPerMinute < 255) {
rates[rateSpot++] = (byte)beatsPerMinute;
rateSpot %= RATE_SIZE;
beatAvg = 0;
for (byte x = 0; x < RATE_SIZE; x++) beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
if (millis() - previousMillis >= interval) {
previousMillis = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("BPM: ");
lcd.print(beatAvg);
lcd.setCursor(11, 0);
lcd.print("IR:");
lcd.print(irValue / 1000); // Affichage IR normalisé
Serial.print("BPM: ");
Serial.print(beatAvg);
Serial.print(" | IR: ");
Serial.println(irValue);
lcd.setCursor(1, 1);
if (beatAvg < 60) {
lcd.print("LOW BPM");
digitalWrite(buzzer, LOW);
} else if (beatAvg > 100) {
lcd.print("HIGH BPM!");
digitalWrite(buzzer, HIGH);
} else {
lcd.print("Normal BPM");
digitalWrite(buzzer, LOW);
}
if (millis() - lastBeat < 1000) {
lcd.setCursor(13, 0);
lcd.write(0);
}
}
}