#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050.h>
#define nombreDePixelsEnLargeur 128
#define nombreDePixelsEnHauteur 64
#define brocheResetOLED -1
#define adresseI2CecranOLED 0x3C
Adafruit_SSD1306 ecranOLED(nombreDePixelsEnLargeur, nombreDePixelsEnHauteur, &Wire, brocheResetOLED);
MPU6050 mpu;
const int pinBuzzer = 8; // Définition du pin sur lequel est connecté le buzzer
// Variables pour stocker les valeurs maximales absolues de l'accélération et du gyroscope
float maxAccX = 0.0;
float maxAccY = 0.0;
float maxAccZ = 0.0;
float maxGyroX = 0.0;
float maxGyroY = 0.0;
float maxGyroZ = 0.0;
unsigned long startTime = 0; // Temps de début du chronomètre
unsigned long elapsedTime = 0; // Temps écoulé du chronomètre
bool isChronometerRunning = false; // Indicateur pour savoir si le chronomètre est en cours d'exécution
const int batteryPin = A0; // Pin analogique utilisé pour lire la tension de la batterie
const float fullVoltage = 9.0; // Tension maximale de la batterie (en volts)
const float emptyVoltage = 8.0; // Tension minimale de la batterie (en volts)
void setup() {
Serial.begin(9600);
Wire.begin();
mpu.initialize();
// Vérifier si le MPU6050 est connecté correctement
if (!mpu.testConnection()) {
Serial.println("MPU6050 connection failed.");
while (1);
}
if (!ecranOLED.begin(SSD1306_SWITCHCAPVCC, adresseI2CecranOLED))
while (1);
pinMode(pinBuzzer, OUTPUT); // Définit le pin du buzzer en tant que sortie
}
void loop() {
// Variables pour stocker les valeurs d'accélération et de gyroscope
int16_t ax, ay, az, gx, gy, gz;
// Lire les données du MPU6050
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// Mettre à jour les valeurs maximales absolues de l'accélération
maxAccX = max(maxAccX, abs(ax / 16384.0));
maxAccY = max(maxAccY, abs(ay / 16384.0));
maxAccZ = max(maxAccZ, abs(az / 16384.0));
// Mettre à jour les valeurs maximales absolues du gyroscope
maxGyroX = max(maxGyroX, abs(gx / 131.0));
maxGyroY = max(maxGyroY, abs(gy / 131.0));
maxGyroZ = max(maxGyroZ, abs(gz / 131.0));
// Calculer l'angle autour de l'axe X en degrés en utilisant les données de l'accéléromètre
float angleX = atan2(-ay, az) * 180 / M_PI;
// Arrondir l'angle à l'unité
int angleX_rounded = round(angleX);
// Vérifier si l'angle dépasse un certain seuil pour déclencher le chronomètre
if (abs(angleX_rounded) > 10 || angleX_rounded < -10) {
// Si le chronomètre n'est pas déjà en cours d'exécution, démarrer le chronomètre
if (!isChronometerRunning) {
startTime = millis();
isChronometerRunning = true;
}
} else {
// Si la mesure réelle est à nouveau dans la plage spécifiée, mettre en pause le chronomètre
if (isChronometerRunning) {
elapsedTime += millis() - startTime;
isChronometerRunning = false;
}
}
// Émettre un bip toutes les 2 secondes si le chronomètre est en cours d'exécution
if (isChronometerRunning && (millis() - startTime) % 2000 < 100) {
digitalWrite(pinBuzzer, HIGH); // Active le buzzer
} else {
digitalWrite(pinBuzzer, LOW); // Désactive le buzzer
}
// Effacer le contenu précédent de l'écran
ecranOLED.clearDisplay();
// Afficher les données de l'accéléromètre sur la ligne 1
ecranOLED.setTextSize(1);
ecranOLED.setTextColor(SSD1306_WHITE);
ecranOLED.setCursor(0, 0);
ecranOLED.print("X:");
ecranOLED.print(ax / 16384.0);
ecranOLED.print(" Y:");
ecranOLED.print(ay / 16384.0);
ecranOLED.print(" Z:");
ecranOLED.println(az / 16384.0);
// Afficher les valeurs maximales absolues de l'accélération sur la ligne 2
ecranOLED.setCursor(0, 8);
ecranOLED.print("X:");
ecranOLED.print(maxAccX);
ecranOLED.print(" Y:");
ecranOLED.print(maxAccY);
ecranOLED.print(" Z:");
ecranOLED.println(maxAccZ);
// Afficher l'angle arrondi à l'unité sur la ligne 3
ecranOLED.setCursor(0, 16);
ecranOLED.print("Angle X: ");
ecranOLED.print(angleX_rounded);
//ecranOLED.println(" degrees");
// Enregistrement de la dernière valeur maximale et minimale d'angle de l'axe X
static int lastMaxAngleX = INT8_MIN;
static int lastMinAngleX = INT8_MAX;
lastMaxAngleX = max(lastMaxAngleX, angleX_rounded);
lastMinAngleX = min(lastMinAngleX, angleX_rounded);
// Afficher la dernière valeur maximale de l'angle de l'axe X sur la ligne 4
ecranOLED.setCursor(0, 24);
ecranOLED.print("Max Angle X: ");
ecranOLED.print(lastMaxAngleX);
//ecranOLED.println(" degrees");
// Afficher la dernière valeur minimale de l'angle de l'axe X sur la ligne 5
ecranOLED.setCursor(0, 32);
ecranOLED.print("Min Angle X: ");
ecranOLED.print(lastMinAngleX);
//ecranOLED.println(" degrees");
// Afficher les données du gyroscope en temps réel sur la ligne 6
//ecranOLED.setCursor(0, 40);
//ecranOLED.print("X:");
//ecranOLED.print(round(gx / 131.0));
//ecranOLED.print(" Y:");
//ecranOLED.print(round(gy / 131.0));
//ecranOLED.print(" Z:");
//ecranOLED.println(round(gz / 131.0));
// Afficher les valeurs maximales absolues du gyroscope sur la ligne 7
//ecranOLED.setCursor(0, 48);
//ecranOLED.print("X:");
//ecranOLED.print(round(maxGyroX));
//ecranOLED.print(" Y:");
//ecranOLED.print(round(maxGyroY));
//ecranOLED.print(" Z:");
//ecranOLED.println(round(maxGyroZ));
// Afficher le temps écoulé du chronomètre sur la ligne 6
ecranOLED.setCursor(0, 40);
ecranOLED.print("Chrono: ");
printElapsedTime(elapsedTime);
// Afficher le pourcentage de batterie sur la ligne 8
float batteryVoltage = readBatteryVoltage();
int batteryPercentage = mapBatteryPercentage(batteryVoltage);
ecranOLED.setCursor(0, 56);
ecranOLED.print("Battery: ");
ecranOLED.print(batteryPercentage);
ecranOLED.println("%");
// Mettre à jour l'écran
ecranOLED.display();
// Attendre une seconde entre chaque lecture
delay(1000);
}
float readBatteryVoltage() {
int sensorValue = analogRead(batteryPin);
float voltage = sensorValue * (5.0 / 1023.0) * 2; // Convertir la valeur en tension (avec un diviseur de tension)
return voltage;
}
int mapBatteryPercentage(float voltage) {
int percentage = map(voltage * 10, emptyVoltage * 10, fullVoltage * 10, 0, 100);
percentage = constrain(percentage, 0, 100);
return percentage;
}
void printElapsedTime(unsigned long elapsedMillis) {
unsigned long seconds = elapsedMillis / 1000;
unsigned long minutes = seconds / 60;
unsigned long hours = minutes / 60;
ecranOLED.print(hours);
ecranOLED.print(":");
ecranOLED.print(minutes % 60, DEC);
ecranOLED.print(":");
ecranOLED.print(seconds % 60, DEC);
}