Delai de réactivité du programme

Bonjour à tous,

Je suis entièrement novice dans le domaine de la programmation et je profite de certaines IA pour m'aider sans conviction.

Je prépare un réveil pour mon petit-fils et j'ai un problème avec l'arrêt du réveil.
Je n'arrive pas à avoir un arrêt total du réveil quand j'appuie sur le bouton 2.
J'ai essayé plusieurs formules comme une tempo ou des problèmes de rebond sur le bouton, mais rien à faire.
il s'agit d'un Arduino Nano 33 IOT

#include <WiFiNINA.h>           // Inclut la bibliothèque pour la connexion Wi-Fi
#include <NTPClient.h>          // Inclut la bibliothèque pour récupérer l'heure via un serveur NTP
#include <WiFiUdp.h>            // Inclut la bibliothèque UDP nécessaire pour le client NTP
#include <Adafruit_NeoPixel.h>  // Inclut la bibliothèque pour gérer le ruban LED
#include <DFRobotDFPlayerMini.h> // Inclut la bibliothèque pour contrôler le module MP3
#include <TimeLib.h>            // Inclut la bibliothèque pour manipuler les dates et heures
#include <TM1637Display.h>      // Inclut la bibliothèque pour gérer l'afficheur 7 segments

// Informations Wi-Fi
const char* ssid = « ****;             // SSID de votre réseau Wi-Fi
const char* password = « *****;  // Mot de passe de votre réseau Wi-Fi

// Initialisation du client NTP
WiFiUDP ntpUDP;                       // Crée un objet WiFiUDP pour la communication UDP
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 60000); // Crée un client NTP, fuseau horaire (UTC+1), intervalle de mise à jour

// Pinout pour le ruban LED et le module MP3
#define LED_PIN 4                    // Définie la broche de contrôle du ruban LED
#define NUMPIXELS 12                 // Nombre de LEDs dans le ruban
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800); // Crée l'objet de contrôle des LEDs

// Pins pour les boutons, le capteur et le module MP3
#define BUTTON1_PIN 2                // Pin pour le bouton 1
#define BUTTON2_PIN 3                // Pin pour le bouton 2
#define TRIG_PIN 7                   // Broche TRIG du capteur HC-SR04
#define ECHO_PIN 8                   // Broche ECHO du capteur HC-SR04

DFRobotDFPlayerMini myDFPlayer;       // Crée l'objet pour contrôler le module DFPlayer

// Configuration de l'afficheur TM1637
#define TM1637_CLK 5                 // Broche CLK (connectée à D5)
#define TM1637_DIO 6                 // Broche DIO (connectée à D6)
TM1637Display display(TM1637_CLK, TM1637_DIO); // Crée l'objet de l'afficheur 7 segments

// Variables globales
bool alarmActive = true;              // Indique si l'alarme est activée
bool ledsOn = false;                  // Indique si les LEDs sont allumées
bool useSensor = false;               // Indique si le capteur est utilisé pour ajuster la luminosité
int brightness = 255;                 // Luminosité des LEDs
int alarmHour = 17;                   // Heure de l'alarme
int alarmMinute = 30;                 // Minute de l'alarme

// Parametrage des jours de la semaine Dimanche, Lundi, mardi, Mercredi, Jeudi, Vendredi, Samedi
bool alarmDays[7] = {false, true, true, true, true, true, false}; // true : actif, false : non actif

unsigned long lastLedUpdate = 0;      // Timer pour l'effet LED
int ledStep = 0;                      // Étape pour l'effet LED

// Structure pour les périodes de vacances
struct PeriodeVacances {
  int startYear;                      // Année de début des vacances
  int startMonth;                     // Mois de début des vacances
  int startDay;                       // Jour de début des vacances
  int endYear;                        // Année de fin des vacances
  int endMonth;                       // Mois de fin des vacances
  int endDay;                         // Jour de fin des vacances
  const char* description;            // Description de la période de vacances
};

// Définition des périodes de vacances
PeriodeVacances vacances[] = {
  {2025, 2, 15, 2025, 3, 2, "Vacances d'hiver"},
  {2025, 4, 12, 2025, 4, 27, "Vacances de printemps"},
  {2025, 5, 1, -1, -1, -1, "Jour ferié"},
  {2025, 5, 8, -1, -1, -1, "Jour ferié"},
  {2025, 6, 9, -1, -1, -1, "Jour ferié"},
  {2025, 5, 29, 2025, 6, 1, "Pont fin Mai"},
  {2025, 7, 5, 2025, 9, 1, "Vacances d'été"},
  {2025, 10, 18, 2025, 11, 2, "Vacances de la Toussaint"},
  {2025, 11, 11, -1, -1, -1, "Jour ferié"},
  {2025, 12, 20, 2026, 1, 4, "Vacances de Noël"}
};

// Fonction pour vérifier si nous sommes en période de vacances
bool isHoliday(int year, int month, int day) {
  for (int i = 0; i < sizeof(vacances) / sizeof(vacances[0]); i++) { // Parcours toutes les périodes de vacances
    // Vérifie si la date actuelle est dans une période de vacances
    if ((year > vacances[i].startYear || (year == vacances[i].startYear && (month > vacances[i].startMonth || (month == vacances[i].startMonth && day >= vacances[i].startDay)))) &&
        (year < vacances[i].endYear || (year == vacances[i].endYear && (month < vacances[i].endMonth || (month == vacances[i].endMonth && day <= vacances[i].endDay))))) {
      Serial.println("C'est une période de vacances !");
      return true;  // C'est une période de vacances
    }
  }
  return false;  // Ce n'est pas une période de vacances
}

void setup() {
  pinMode(BUTTON1_PIN, INPUT_PULLUP); // Configure le bouton 1 en entrée avec pull-up interne
  pinMode(BUTTON2_PIN, INPUT_PULLUP); // Configure le bouton 2 en entrée avec pull-up interne
  pinMode(TRIG_PIN, OUTPUT);          // Configure la broche TRIG du capteur HC-SR04 en sortie
  pinMode(ECHO_PIN, INPUT);           // Configure la broche ECHO du capteur HC-SR04 en entrée

  Serial.begin(9600);                 // Initialisation du port série pour le débogage

  // Initialisation Wi-Fi
  connectToWiFi();                   // Fonction pour connecter l'appareil au Wi-Fi
  timeClient.begin();                 // Initialisation du client NTP pour récupérer l'heure

  // Initialisation du ruban LED
  pixels.begin();                     // Initialisation du ruban LED
  pixels.clear();                     // Efface le ruban LED (éteint toutes les LEDs)

  // Initialisation de l'afficheur TM1637
  display.setBrightness(5);           // Régle la luminosité de l'afficheur TM1637
  display.clear();                    // Efface l'afficheur

  Serial1.begin(9600);                // Initialisation du port série pour communiquer avec le DFPlayer
  Serial.println(F("Initialisation du DFPlayer..."));

  if (!myDFPlayer.begin(Serial1)) {   // Initialisation du module DFPlayer
    Serial.println(F("Échec de l'initialisation du DFPlayer."));
    while (true);                      // Bloque le programme en cas d'échec
  }
  Serial.println(F("DFPlayer initialisé avec succès."));
  myDFPlayer.volume(30);               // Régle le volume du DFPlayer
  Serial.println(F("Volume réglé à 30."));
}

void loop() {

  // Vérifie immédiatement si le bouton 2 est pressé pour donner la priorité à cette action
  checkButton2(); 

  if (WiFi.status() != WL_CONNECTED) {  // Vérifie si la connexion Wi-Fi est active
    connectToWiFi();                    // Si non, tente de se reconnecter au Wi-Fi
  }

  timeClient.update();                  // Met à jour l'heure depuis le serveur NTP
  time_t rawTime = timeClient.getEpochTime();  // Récupère l'heure en secondes depuis 1970
  setTime(rawTime);                      // Définit l'heure sur l'Arduino avec l'heure récupérée

  int currentHour = hour();             // Récupère l'heure actuelle
  int currentMinute = minute();         // Récupère la minute actuelle
  int currentDay = weekday() - 1;       // Récupère le jour de la semaine (0 = Dimanche, 1 = Lundi, ...)
  int currentMonth = month();           // Récupère le mois actuel
  int currentDate = day();              // Récupère le jour du mois actuel
  int currentYear = year();             // Récupère l'année actuelle

  // Vérifie si nous sommes pendant les vacances
  if (isHoliday(currentYear, currentMonth, currentDate)) {
    alarmActive = false;  // Désactive l'alarme pendant les vacances
  } else {
    alarmActive = true;   // Active l'alarme en dehors des vacances
  }

  displayTime(currentHour, currentMinute);  // Affiche l'heure sur l'afficheur 7 segments

  checkButton1();  // Vérifie si le bouton 1 a été pressé

  // Vérifie si l'alarme doit être déclenchée
  if (alarmActive && currentHour == alarmHour && currentMinute == alarmMinute && alarmDays[currentDay]) {
    triggerAlarm();  // Déclenche l'alarme
  }

  // Ajuste la luminosité en fonction du capteur HC-SR04 si activé
  if (useSensor) {
    int distance = measureDistance();   // Mesure la distance avec le capteur HC-SR04
    brightness = map(distance, 5, 50, 0, 255); // Mappe la distance à une valeur de luminosité
    brightness = constrain(brightness, 0, 255);  // Contrainte de la luminosité
    Serial.print("Distance mesurée : ");
    Serial.print(distance);
    Serial.print(" cm, Luminosité : ");
    Serial.println(brightness);
  }

  // Si les LEDs sont allumées, effectue un effet lumineux
  if (ledsOn) {
    ledAlarmEffect();
  } else if (useSensor) {
    activateLedsWithBrightness();  // Active les LEDs avec la luminosité calculée
  }
}

void connectToWiFi() {
  Serial.print("Connexion à Wi-Fi...");   // Affiche un message dans le port série
  while (WiFi.begin(ssid, password) != WL_CONNECTED) { // Essaye de se connecter au Wi-Fi
    delay(1000);                          // Attends 1 seconde avant de réessayer
    Serial.print(".");                    // Affiche un point pendant la tentative
  }
  Serial.println("Connecté !");            // Affiche un message de succès
  Serial.print("IP : ");
  Serial.println(WiFi.localIP());         // Affiche l'adresse IP locale une fois connecté
}

// Fonction pour déclencher l'alarme (activant les LEDs et jouant un son)
void triggerAlarm() {
  if (ledsOn) { 
    Serial.println("L'alarme est déjà déclenchée."); 
    return; 
  }

  Serial.println("Déclenchement de l'alarme...");
  ledsOn = true;               // Indique que l'alarme est active
  playAlarm();                 // Joue le son de l'alarme
  startLightShow();            // Démarre le jeu de lumière
}

// Fonction pour démarrer un jeu de lumière aléatoire avec les LEDs
void startLightShow() {
  unsigned long startTime = millis();   // Enregistre l'heure de début

  while (millis() - startTime < 30000) {  // Pendant 30 secondes
    for (int i = 0; i < NUMPIXELS; i++) {
      uint8_t red = random(256);           // Génère une valeur aléatoire pour la couleur rouge
      uint8_t green = random(256);         // Génère une valeur aléatoire pour la couleur verte
      uint8_t blue = random(256);          // Génère une valeur aléatoire pour la couleur bleue

      pixels.setPixelColor(i, pixels.Color(red, green, blue));  // Applique la couleur aléatoire
    }
    pixels.show();  // Met à jour le ruban LED
    delay(100);     // Pause de 100ms avant de changer les couleurs
  }
}

// Fonction pour ajuster la luminosité des LEDs en fonction de la distance mesurée
void activateLedsWithBrightness() {
  for (int i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(brightness, brightness, brightness));  // Définit la couleur de chaque LED selon la luminosité
  }
  pixels.show();  // Met à jour le ruban LED
}

// Fonction pour éteindre les LEDs
void deactivateLeds() {
  pixels.clear();  // Efface les LEDs
  pixels.show();   // Met à jour le ruban LED
}

// Fonction pour jouer le son de l'alarme
void playAlarm() {
  myDFPlayer.play(1);  // Joue le premier fichier MP3
}

// Fonction pour arrêter l'alarme (arrête la lecture et éteint les LEDs)
void stopAlarm() {
  if (!ledsOn) {
    Serial.println("L'alarme est déjà arrêtée.");  // Empêche d'exécuter deux fois l'arrêt
    return;
  }

  Serial.println("Arrêt de l'alarme...");
  myDFPlayer.stop();  // Arrête la lecture du MP3
  deactivateLeds();   // Éteint les LEDs
  ledsOn = false;     // Met à jour l'état des LEDs
  Serial.println("LEDs éteintes, alarme arrêtée.");
}

// Fonction pour vérifier l'appui sur le bouton 1
void checkButton1() {
  static bool lastState = HIGH;
  bool currentState = digitalRead(BUTTON1_PIN);  // Lit l'état actuel du bouton

  if (currentState == LOW && lastState == HIGH) { // Si le bouton a été pressé
    useSensor = !useSensor;  // Bascule l'utilisation du capteur
    if (useSensor) {
      Serial.println("Capteur HC-SR04 activé.");  // Affiche que le capteur est activé
    } else {
      Serial.println("Capteur HC-SR04 désactivé. Luminosité fixe.");  // Affiche que le capteur est désactivé
      deactivateLeds();  // Éteint les LEDs
    }
  }
  lastState = currentState;  // Met à jour l'état précédent du bouton
}

// Fonction pour vérifier l'appui sur le bouton 2
// Fonction pour gérer l'appui sur le bouton 2
void checkButton2() {
  static bool lastState = HIGH;          // État précédent du bouton
  static unsigned long pressStart = 0;      // Temps de début de l'appui
  const unsigned long shortPressDuration = 500; // Durée d'un appui court (en ms)
  const unsigned long longPressDuration = 2000; // Durée d'un appui long (en ms)

  bool currentState = digitalRead(BUTTON2_PIN);  // Lit l'état actuel du bouton

  if (currentState == LOW && lastState == HIGH) {  // Bouton pressé
    pressStart = millis();
  } else if (currentState == HIGH && lastState == LOW) {  // Bouton relâché
    unsigned long pressDuration = millis() - pressStart;
    if (pressDuration >= shortPressDuration && pressDuration < longPressDuration) {
      // Appui court : arrêter l'alarme
      stopAlarm();
    } else if (pressDuration >= longPressDuration) {
      // Appui long : snooze (à implémenter)
      snoozeAlarm();
    }
  }

  lastState = currentState;  // Met à jour l'état précédent
}

// Fonction pour mettre en pause l'alarme (snooze)
void snoozeAlarm() {
  // Implémentez ici la logique pour mettre en pause l'alarme
  // Par exemple, vous pouvez reporter l'heure de l'alarme de 5 minutes
  alarmHour += 0; // Ajuster l'heure
  alarmMinute += 5; // Ajuster les minutes
  if (alarmMinute >= 60) {
    alarmHour++;
    alarmMinute -= 60;
  }
  Serial.println("Snooze activé !");
}

// Fonction pour mesurer la distance avec le capteur HC-SR04
int measureDistance() {
  digitalWrite(TRIG_PIN, LOW);       // Envoie un signal bas pour s'assurer que le TRIG est éteint
  delayMicroseconds(2);              // Attendre 2 microsecondes
  digitalWrite(TRIG_PIN, HIGH);      // Envoie un signal haut pour déclencher l'impulsion
  delayMicroseconds(10);             // Attente de 10 microsecondes
  digitalWrite(TRIG_PIN, LOW);       // Arrête l'impulsion

  long duration = pulseIn(ECHO_PIN, HIGH);  // Mesure la durée de l'impulsion retour
  int distance = duration * 0.034 / 2;     // Calcule la distance (vitesse du son 340m/s)
  return distance;                      // Retourne la distance mesurée
}

// Fonction pour afficher l'heure sur l'afficheur 7 segments
void displayTime(int hour, int minute) {
  int timeDisplay = hour * 100 + minute;  // Combine l'heure et la minute en un nombre entier
  display.showNumberDecEx(timeDisplay, 0b11100000, true); // Affiche l'heure sur l'afficheur
}

// Fonction pour créer un effet lumineux lors de l'alarme
void ledAlarmEffect() {
  unsigned long currentTime = millis();  // Récupère l'heure actuelle
  if (currentTime - lastLedUpdate > 50) { // Si 50ms se sont écoulées
    lastLedUpdate = currentTime;         // Met à jour l'heure de la dernière mise à jour des LEDs
    ledStep++;                           // Passe à l'étape suivante de l'effet lumineux
    for (int i = 0; i < NUMPIXELS; i++) {
      int color = (i + ledStep) % NUMPIXELS;  // Crée un dégradé de couleurs en fonction de l'étape
      pixels.setPixelColor(i, pixels.Color(color * 10, 0, 255 - color * 10));  // Définit la couleur de la LED
    }
    pixels.show();  // Affiche les couleurs sur le ruban LED
  }
}

J'accepte toute remarque, merci de votre aide

Philippe

Bonjour,

Le problème, c'est que tu repasses par le test suivant aussitôt et cela réenclenche l'alarme.

Lorsque tu acquittes l'alarme, il faudrait peut-être bloquer ce test pendant une minute afin que la condition ne soit plus remplie.

bonsoir fdufnews

Merci pour l'information je vais faire des tests

Bonjour

Merci probleme résolu :clap:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.