Epileptic seizure detector

Hi here is my code for my detector

// bibliothèque de code 
#include <Wire.h>
#include <MPU6050.h>
#include <MAX30100_PulseOximeter.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Initialisation des capteurs
MPU6050 mpu;
PulseOximeter pox;  // Utiliser la classe PulseOximeter IMPORTANT

// Initialisation de l'écran OLED
#define SCREEN_WIDTH 128 // Largeur de l'écran OLED vérfier si bonne valeurs
#define SCREEN_HEIGHT 64  // Hauteur de l'écran OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // Adresse I2C par défaut sinon vérifier l'adresse 11C

const int buzzerPin = 9; // Broche du buzzer
bool alert = false;

// Seuils de détection constante de détections
const float accThreshold = 2.0; // Seuil d'accélération
const float hrThreshold = 30.0;  // Seuil de changement de la fréquence cardiaque (bpm)
const float spO2Threshold = 5.0; // Seuil de changement de la SpO2 (%)
unsigned long lastMovementTime = 0; // Temps du dernier mouvement
unsigned long lastHeartRateTime = 0; // Temps de la dernière mesure de pouls
unsigned long lastSpO2Time = 0; // Temps de la dernière mesure de SpO2
const unsigned long movementInterval = 2000; // Intervalle de temps entre les mouvements
const unsigned long heartRateInterval = 2000; // Intervalle pour la mesure de pouls
const unsigned long spO2Interval = 2000; // Intervalle pour la mesure de SpO2

float lastHeartRate = 0;
float lastSpO2 = 0;

void activateAlarm(const char* message); // Déclaration de la fonction d'activation de l'alarme
void deactivateAlarm();                  // Déclaration de la fonction de désactivation de l'alarme

// Initialisation du programme
void setup() {
    Serial.begin(115200);
    Wire.begin();
    
    mpu.initialize();
    pox.begin();

    pinMode(buzzerPin, OUTPUT);
    digitalWrite(buzzerPin, LOW);

    // Initialiser l'écran OLED Elegoo
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Adresse I2C de l'écran OLED
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0, 0);
    display.print("Initialisation..."); // message afficher lors du setup
    display.display();
    delay(2000);
    display.clearDisplay(); // enlever informations avant void loop
}
// action continuellement effectuer loop

void loop() {
    // Mettre à jour les données du capteur de pouls et de SpO2
    pox.update(); 
    float heartRate = pox.getHeartRate();
    float spO2 = pox.getSpO2();

    // Lire les données de l'accéléromètre
    int16_t ax, ay, az; // trois axes de mouvement x,y,z
    mpu.getAcceleration(&ax, &ay, &az); // Récupérer les valeurs d'accélération transférer nano

    // Afficher les données sur l'écran OLED
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("HR:"); // données rhytme cardiaquee
    display.print(heartRate);
    display.print(" bpm");

    display.setCursor(0, 10);
    display.print("SpO2:"); // saturation oxygène dans le sang
    display.print(spO2);
    display.print("%");

    display.display(); // Mettre à jour l'affichage

    // Détection de mouvement brusque
    if ((abs(ax) > accThreshold || abs(ay) > accThreshold || abs(az) > accThreshold) &&
        (millis() - lastMovementTime > movementInterval)) {
        lastMovementTime = millis();
        alert = true;
        activateAlarm("Mouvement brusque!"); // afficher sur l'écran oled
    }

    // Détection d'augmentation ou de diminution soudaine du pouls
    if (heartRate > 0 && (abs(heartRate - lastHeartRate) > hrThreshold) && 
        (millis() - lastHeartRateTime > heartRateInterval)) {
        lastHeartRateTime = millis();
        lastHeartRate = heartRate; // Mettre à jour la dernière fréquence cardiaque (environ une secconde)
        alert = true;
        activateAlarm("Changement bpm!");
    }

    // Détection d'augmentation ou de diminution soudaine de la SpO2
    if (spO2 > 0 && (abs(spO2 - lastSpO2) > spO2Threshold) && 
        (millis() - lastSpO2Time > spO2Interval)) {
        lastSpO2Time = millis();
        lastSpO2 = spO2; // Mettre à jour la dernière valeur de SpO2
        alert = true;
        activateAlarm("Changement Saturation O2!");
    }

    // Désactiver l'alarme si les conditions sont normales
    if (!alert) {
        deactivateAlarm();
    }

    delay(100);
}

// Fonction pour activer l'alarme
void activateAlarm(const char* message) {
    digitalWrite(buzzerPin, HIGH);  // Activer le buzzer
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print(message);  // Afficher le message d'alarme
    display.display(); // Mettre à jour l'affichage
    alert = true;  // Marquer l'état d'alerte
}

// Fonction pour désactiver l'alarme lorsque les conditions redeviennent normales
void deactivateAlarm() {
    digitalWrite(buzzerPin, LOW);  // Désactiver le buzzer
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("Conditions OK");
    display.display(); // Mettre à jour l'affichage
    alert = false;  // Réinitialiser l'état d'alerte
    }

The problem here is that the code seem code but the max30100 and the screen doesn't work.

Did you get sections of code to work for example each of the perpherial devices first?

Yes the mpu6050 was working and the buzzer and the max30100 with a small code for test but all it failed.

Also I used Wowki to run some test and the screen was working but in real life it wasn't.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050.h>  // Librairie pour le MPU6050

// Taille de l'écran OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Adresse I2C de l'écran OLED (0x3C pour la plupart des écrans)
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Crée un objet pour le MPU6050
MPU6050 mpu;

// Seuil d'accélération pour déclencher l'alarme (en g)
const float ACCEL_THRESHOLD = 1.5; // Par exemple, 1.5g (ajuster selon besoin)

void setup() {
  // Initialisation de la communication série
  Serial.begin(9600);

  // Initialisation de l'écran OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("Échec de l'initialisation de l'écran OLED"));
    for(;;);
  }
  
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print("Initialisation...");
  display.display();
  
  // Initialisation du MPU6050
  Wire.begin();
  mpu.initialize();
  if (!mpu.testConnection()) {
    Serial.println("MPU6050 non connecte correctement");
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("MPU6050 Error!");
    display.display();
    while (1);
  }

  // Indique que l'initialisation est terminée
  Serial.println("MPU6050 Pret!");
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("MPU6050 Ready!");
  display.display();
  delay(1000);
}

void loop() {
  // Variables pour stocker les données d'accélération
  int16_t ax, ay, az;

  // Récupération des valeurs d'accélération
  mpu.getAcceleration(&ax, &ay, &az);

  // Conversion en "g" (1g = 9.81 m/s^2)
  float accelX = ax / 16384.0;
  float accelY = ay / 16384.0;
  float accelZ = az / 16384.0;

  // Calcul de la magnitude de l'accélération totale
  float totalAccel = sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ);

  // Vérifie si l'accélération dépasse le seuil
  if (totalAccel > ACCEL_THRESHOLD) {
    triggerAlarm(totalAccel); // Déclenche l'alarme si dépassement
  } else {
    // Affichage des données sur l'écran OLED
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("Accel (g):");
    display.setCursor(0, 10);
    display.print("X: "); display.print(accelX);
    display.setCursor(0, 20);
    display.print("Y: "); display.print(accelY);
    display.setCursor(0, 30);
    display.print("Z: "); display.print(accelZ);
    display.setCursor(0, 40);
    display.print("Total: "); display.print(totalAccel);
    display.display();
  }

  // Affiche aussi dans le moniteur série
  Serial.print("X: "); Serial.print(accelX);
  Serial.print(" Y: "); Serial.print(accelY);
  Serial.print(" Z: "); Serial.print(accelZ);
  Serial.print(" Total: "); Serial.println(totalAccel);

  delay(500); // Attente de 500ms entre chaque mise à jour
}

// Fonction pour déclencher une alarme si trop de mouvement
void triggerAlarm(float accel) {
  // Affiche un message d'alarme sur l'écran OLED
  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(2);  // Texte plus grand pour l'alarme
  display.print("ALERTE!");
  display.setTextSize(1);
  display.setCursor(0, 30);
  display.print("Mouvement trop fort");
  display.setCursor(0, 50);
  display.print("Accel: "); display.print(accel);
  display.display();
  
  // Affiche également dans le moniteur série
  Serial.println("ALERTE! Mouvement excessif detecte");
  Serial.print("Acceleration totale: "); Serial.println(accel);
  
  delay(1000); // Attend 1 seconde avant de reprendre
}

That the code I used in Wowki.

If that doesn’t work, then combining them won’t work either. Get the individual components working first so you can understand what is required.

Which Arduino are you using? With the Adafruit_SSD1306 library you might be running out of memory.

What does the IDE report for the memory usage (dynamic memory)? You will need to add 1024 bytes to that and the result should basically stay below 75%.

It stay at around 68%

I am using a arduino uno

ok thank

Any data in the Serial Monitor?

The two three I2C devices are connected and addressed correctly?

The adress looked fine but maybe the connection weren't that good i was using a old breadboard and jumper wire

That is roughly 1.3 kByte used; add 1kByte for the screen and you're out of memory.

ok I am gonna do some change

@emile234 - comment-out OLED library and code and use the Serial Monitor for output.

ok thank

It is very faithful. This points to a wiring error or bad parts.

Did you mean to say that when you combinated them the result did not work?

Post your little tests that worked each.

a7

What is the question? What do you want to happen, and what does happen.

So here the code for the test of the heart rate detector

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MAX30100_PulseOximeter.h>

// Define the dimensions of the OLED screen
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Create an OLED display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Create a PulseOximeter object for the MAX30100 sensor
PulseOximeter pox;

// Variables to store sensor readings
float heartRate;
float spO2;

void setup() {
  // Initialize the serial port
  Serial.begin(115200);

  // Initialize the OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("Failed to initialize the OLED display"));
    while (true); // Infinite loop in case of an error
  }

  // Clear the OLED display and set up initial text
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Initializing...");
  display.display();

  // Initialize the MAX30100 sensor
  if (!pox.begin()) {
    Serial.println("Error initializing the MAX30100 sensor");
    display.clearDisplay();
    display.setCursor(0, 0);
    display.println("MAX30100 Error");
    display.display();
    while (true); // Infinite loop in case of an error
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Sensor Ready!");
  display.display();
  delay(2000);  // Pause for 2 seconds
}

void loop() {
  // Update the sensor readings
  pox.update();

  // Get heart rate and SpO2 data
  heartRate = pox.getHeartRate();
  spO2 = pox.getSpO2();

  // Display the data on the OLED screen
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("BPM: ");
  display.print(heartRate);  // Show heart rate
  display.setCursor(0, 20);
  display.print("SpO2: ");
  display.print(spO2);       // Show blood oxygen saturation level
  display.print("%");
  display.display();

  // Also print the data to the serial monitor
  Serial.print("Heart Rate: ");
  Serial.print(heartRate);
  Serial.print(" bpm | SpO2: ");
  Serial.print(spO2);
  Serial.println("%");

  delay(1000);  // Pause for 1 second between readings
}

What was supposed to happen is that the heart rate sensor detect it stuff and the accelerometer too and if it exceed a certain limit it make an alarm with the buzzer (that is working) and all the number are suposed to be displayed on the screen.

the problem was that the screen wasn't working and that the max30100 wasn't working in the big code for the detector but only in a small code so my theory is that it was connections that were wrong for the max30100 but for the screen I need help