/* Claude EMERY 15/03/2026
Chronometre - Oled 0.96 - I2C - 128x64 pixels - Adresse I2C 0x3c
1 caractère = 7x7 pixels
*/
// Librairies
#include <Wire.h> // Gestion I2C pour Oled SDA / SCL
#include <Adafruit_GFX.h> // Affichage graphique
#include <Adafruit_SSD1306.h> // Driver Oled 0.96" - SSD1306
// Configuration OLED
#define SCREEN_WIDTH 128 // Largeur 128 pixels
#define SCREEN_HEIGHT 64 // Hauteur 64 pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // SDA=A4 SCL=A5 - Initialisation Oled 0.96
// Variables
int BtStartStop = 3; // BtStartStop - Aucun Appui Bt => 5V , Appui Bt => 0V
int BtReset = 2; // BtReset - Aucun Appui Bt => 5V , Appui Bt => 0V
bool EtatBtStartStop; // Etat btStartStop => Repos = 1 , Appuyer = 0
bool EtatBtReset; // Etat BtReset => Repos = 1 , Appuyer = 0
int EtatBtAppuyer; // EtatBtAppuyer => Repos = 0 , Appuyer = 1
int EtatChronoOnOff; // EtatChronoOnOff=> Repos = 0, si Start=1 => Etat=1, si Stop=1 => Etat=0 , Appuyer = 0
int TempsEcoule;
int Milliseconde;
int Seconde;
int Minute;
int Heure;
unsigned long currentTime = 0; // Temps actuel
unsigned long previousTime = 0; // Temps précédent
void setup() {
Serial.begin(9600);
pinMode(BtStartStop, INPUT_PULLUP);
pinMode(BtReset, INPUT_PULLUP);
// Initialisation de l'écran OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("Échec de l'initialisation de l'écran OLED !");
for (;;);
display.display();
display.clearDisplay();
}
// Affichage Oled 0.96
display.clearDisplay(); // Effacement de l'afficheur
display.setTextColor(WHITE); // Couleur du texte en BLANC
display.setCursor(0,0); // Position du curseur - colonne 0 et ligne 0
display.setTextSize(1); // Caractere = Taille 1
display.print("---- Chronometre ----"); // Affichage "Chronometre"
display.setCursor(35,40); // Position du curseur - colonne 35 et ligne 40
display.print("Press Start"); // Affichage "Press Start"
display.setCursor(35,50); // Position du curseur - colonne 35 et ligne 50
display.print("Bouton Vert"); // Affichage "Bouton Vertt"
display.display(); // Affichage sur Oled 0.96
//delay(500);
}
void loop() {
EtatBtStartStop = digitalRead(BtStartStop); // lecture etat BtStartStop -> Repos=1 Appuyer=0
EtatBtReset = digitalRead(BtReset); // lecture etat BtReset -> Repos=1 Appuyer=0
// Lancer ou arreter le chrono
// Si EtatBtStartStop == LOW et EtatBtAppuyer == 0 on exécute les actions entre {}
// EtatBtStartStop -> Repos=1 Appuyer=0
// EtatBoutonAppuyer -> Repos=0 Appuyer=1
if (EtatBtStartStop == LOW && EtatBtAppuyer == 0) {
EtatBtAppuyer = 1; // EtatBtAppuyer prend la valeur de 1
EtatChronoOnOff = !EtatChronoOnOff; // Si EtatChronoOnOff = 0 alors EtatChronoOnOff = 1 et inversement
affichage(); // Appel de la fonction affichage()
}
// Reset le chrono
// Si EtatBtReset == LOW et EtatChronoOnOff == 0 et EtatBtAppuyer == 0
if (EtatBtReset == LOW && EtatChronoOnOff == 0 && EtatBtAppuyer == 0) {
EtatBtAppuyer = 1; // EtatBtAppuyer prend la valeur de 1
// Mise à 0 des valeurs
Milliseconde = 0;
Seconde = 0;
Minute = 0;
Heure = 0;
}
//Détecte les 2 boutons relâchés
// Si EtatBtStartStop == HIGH et EtatBtReset == HIGH on exécute les actions entre {}
if (EtatBtStartStop == HIGH && EtatBtReset == HIGH) {
EtatBtAppuyer = 0; // EtatBtAppuyer = 0
}
// Calcul du temps
currentTime = millis(); // Temps actuel en milliseconde depuis la mise sous tension
TempsEcoule = currentTime - previousTime; // Temps écoulé
previousTime = millis(); // Temps précedent
// Si EtatChronoOnOFF == 1 on exécute les actions entre {}
if (EtatChronoOnOff == 1) {
Milliseconde = Milliseconde + TempsEcoule; // Calcul Milliseconde + TempsEcoule.
if (Milliseconde > 999) { Milliseconde = Milliseconde - 1000; Seconde++; }
if (Seconde > 59) { Seconde = 0; Minute++; }
if (Minute > 59) { Minute = 0; Heure++; }
}
afficheChrono(); // Appel de la fonction afficheChrono()
}
void afficheChrono(){ // Fonction afficheChrono()
display.clearDisplay(); // Effacement de l'afficheur
// AFFICHAGE MILLISECONDE --------------------------------------------------------------------
affichage_haut(); // Appel de la fonction affiche_haut()
display.setCursor(75,20); // Position 75,20
display.print(":");
if (Milliseconde > 99) { // Milliseconde = 100 à 999
display.setCursor(80,20); // Position 80,20
display.print(Milliseconde);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
else if (Milliseconde > 9 && Milliseconde < 100) { // Milliseconde = 10 à 99
display.setCursor(85, 20); // Position 85,20
display.print("0");
display.setCursor(90, 20); // Position 90,20
display.print(Milliseconde);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
else if (Milliseconde > 0 && Milliseconde < 10) { // Milliseconde = 1 à 9
display.setCursor(80, 20); // Position 80,20
display.print("00");
display.setCursor(90, 20); // Position 90,20
display.print(Milliseconde);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
else {
display.setCursor(75, 20); // Position 75,20
display.print(":000");
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
// AFFICHAGE SECONDE ---------------------------------------------------------------
display.setCursor(60, 20); // Position 60,20
display.print(":");
if (Seconde < 10) { //------------------ Seconde = 0 à 9
display.setCursor(65, 20); // Position 65,20
display.print("0");
display.setCursor(70, 20); // Position 70,20
display.print(Seconde);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
else {
display.setCursor(65, 20); // Position 65,20
display.print(Seconde);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
// AFFICHAGE MINUTE ------------------------------------------------------------------
display.setCursor(45, 20); // Position 45,20
display.print(":");
if (Minute < 10) { //------------------ Minute = 0 à 9
display.setCursor(50, 20); // Position 50,20
display.print("0");
display.setCursor(55, 20); // Position 55,20
display.print(Minute);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
else {
display.setCursor(50, 20); // Position 50,20
display.print(Minute);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
// AFFICHAGE HEURE ----------------------------------------------------------------------
if (Heure < 10) { //------------------ Heure 0 à 9
display.setCursor(35, 20); // Position 35,20
display.print("0");
display.setCursor(40, 20); // Position 40,20
display.print(Heure);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
else {
display.setCursor(35, 20); // Position 35,20
display.print(Heure);
affichage_bas(); // Affichage "Press Stop/Start et Bouton Vert"
}
display.display();
}
void affichage(){ // fonction affichage du texte sur Oled 0.96
// Affichage "Start <-> Stop ou Reset"
display.clearDisplay(); // Effacement de l'afficheur
display.setCursor(0,0); // Position du curseur - colonne 0 et ligne 0
display.print("---- Chronometre ----"); // Affichage "Chronometre"
display.setCursor(20,40); // Position du curseur - colonne 20 et ligne 40
display.print("Press Stop/Start"); // Affichage "Press Start"
display.setCursor(35,50); // Position du curseur - colonne 35 et ligne 50
display.print("Bouton Vert"); // Affichage "Bouton Vert"
display.display(); // Affichage sur oled 0.96
}
void affichage_haut(){ // Affichage "---- Chronometre ----"
display.setCursor(0,0);
display.print("---- Chronometre ----");
}
void affichage_bas(){ // Affichage "Press Stop/Start et Bouton Vert"
display.setCursor(20,40);
display.print("Press Stop/Start");
display.setCursor(35,50);
display.print("Bouton Vert");
}
/*
Les commandes display.setTextSize(1); et display.setTextColor(WHITE);
ne sont pas répétées car elles définies dans le setup()
*/