[Résolu] Compte à rebours

Bonjour à tous,

Je me suis lancé dans un projet de compte à rebours pour la maison, celui-ci sera composé de:

  • Arduino uno (au final un arduino micro)
  • Un module 7 segments pour l’affichage du temps (0.56" 7-segment LED HT16K33 Backpack)
  • 3 boutons (temps +, temps -, start/stop)
  • un buzzer.

La gestion des boutons et du buzzer ne me posent pas de problème, néanmoins j’ai un soucis avec l’affichage, je n’arrive pas à écrire correctement sur mon module.

J’ai cherché avec l’aide des moteurs de recherche, j’ai trouvé des posts sur le même sujet mais jamais avec mon module.

Ce code se rapproche vraiment très fort de ce que je veux faire, mais je n’arrive pas à le modifier pour mon module 4 digits.

/*
 * Minuteur simpliste à base arduino
 */
 
/* Commandes de l'afficheur 7 segments */
enum {
  AFF_RESET = 0x76,   // Reste l'afficheur
  AFF_CRTL_DP = 0x77, // Affichage d'un point
  DP_HORAIRE = 0x10   // Double point horaire
};
 
/* Câblage */
#define BP_UP 4      // Bouton +
#define BP_DOWN 3    // Bouton -
#define BP_START 2   // Bouton Start/Stop (interruption)
#define BUZZER_PIN 5 // Buzzer
 
/* Variables globales */
volatile byte running = false; // Etat du minuteur (true = en fonctionnement, false = à l'arrêt)
char minutes_remain = 0;       // Nombre de minutes restantes (par défaut 0)
char secondes_remain = 10;     // Nombre de secondes restantes (par défaut 10)
 
/* Setup() */
void setup() {
 
  // Initialisation du port série
  Serial.begin(9600);
 
  // Initialisation des broches
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BP_UP, INPUT_PULLUP);
  pinMode(BP_DOWN, INPUT_PULLUP);
  pinMode(BP_START, INPUT_PULLUP);
  // pinMode(x, INPUT_PULLUP) correspondant à un pinMode(x, INPUT) puis à un digitalWrite(x, HIGH)
  attachInterrupt(0, bp_start_int, FALLING);
 
  // Reset de l'afficheur
  delay(1000);
  Serial.write(AFF_RESET);
 
  // Affiche le temps restant initial
  affiche_temps();
}
 
/* Loop() */
void loop() {
 
  /* Variables locales de gestion du temps */
  static unsigned long last_time = 0; // Temps antérieur
  unsigned long time_now = millis();  // Temps actuel
 
  // Si le minuteur est en marche
  if(running) {
 
    // Et que 1 sec s'est écoulée
    if(time_now - last_time >= 1000) {
 
      // Décrémentation des secondes
      if(--secondes_remain < 0) {
        secondes_remain = 59; // Si il n'y as plus de seconde
 
        // Décrémentation des minutes
        if(--minutes_remain < 0) {
          minutes_remain = 0;   //
          secondes_remain = 0; // Si il n'y as plus de minute
          affiche_temps();
 
          // Mise en marche du buzzer jusqu'à ce que l'utilisateur appui sur le bouton Start/Stop
          while(running) {
            tone(BUZZER_PIN, 500, 500);
            delay(600); 
          }
 
          // Reprise à l'état initial
          secondes_remain = 10;
        }
      }
 
      // Affichage du temps restant
      affiche_temps();
      last_time = time_now;
    }
  } 
  else { // Si le minuteur n'est pas en marche
 
      // Si le bouton + est appuyé
    if(digitalRead(BP_UP) == LOW) {
 
      // Incrémentation des secondes
      if(++secondes_remain > 59) {
        secondes_remain = 0; // Si le nombre de secondes atteint 60
 
          // Incrémentation des minutes
        if(++minutes_remain > 99) {
          minutes_remain = 99;  // Si le nombre de minutes atteint 99
          secondes_remain = 59; // Blocage à 99:59
        }
      }
 
      // Attente variable (basé sur le temps d'appui)
      delay_increment(false);
 
      // Affichage du temps restant
      affiche_temps();
 
    } // Si le bouton - est appuyé
    else if(digitalRead(BP_DOWN) == LOW) {
 
      // Décrémentation des secondes
      if(--secondes_remain < 0) {
        secondes_remain = 59; // Si il n'y as plus de seconde
 
        // Décrémentation des minutes
        if(--minutes_remain < 0) {
          minutes_remain = 0; // Si il n'y as plus de minute
          secondes_remain = 0;
        }
      }
 
      // Attente variable (basé sur le temps d'appui)
      delay_increment(false);
 
      // Affiche du temps restant
      affiche_temps();
 
    } // Si aucun bouton n'est appuyé
    else {
 
      // Remise à zéro du delai variable
      delay_increment(true);
    } 
  }
}
 
/* Delai variable en fonction du temps d'appui */
void delay_increment(byte rst) {
  static unsigned long last_time = 0; // Temps antérieur
  unsigned long time_now = millis();  // Temps actuel
 
  // Si le paramètre de reset est activé
  if(rst) {
    last_time = time_now; // Remise à zéro
    return;        // Fin de fonction
  }
   
  // Si le temps d'appui est supérieur ou égale à 20 secondes
  if(time_now - last_time >= 20000) {
    delay(125);
  } // Si le temps d'appui est supérieur ou égale à 10 secondes
  else if(time_now - last_time >= 10000) {
    delay(250);
  } // Sinon pour tout appui de moins de 10 secondes
  else {
    delay(500);
  }
}
 
/* Interruption du bouton Start/Stop */
void bp_start_int() {
  running = !running;
}
 
/* Fonction d'affichage du temps restant */
void affiche_temps() {
 
  // Converti le temps restant en chaîne de caractères
  char tmp[5];
  sprintf(tmp, "%02d%02d", minutes_remain, secondes_remain);
 
  // Active les doubles points horaire
  Serial.write(AFF_CRTL_DP);
  Serial.write(DP_HORAIRE);
 
  // Affiche les 4 digits
  Serial.write((uint8_t*)tmp, 4);
}

Source: Tuto Skywodd

Je vous remercie d’avance pour vos conseils. :slight_smile:

l'afficheur série sparkfun du tuto skywood et le module ht16k33 ne se pilote pas de la même manière
tu devrais trouver des biblios pour ht16k33

Adafruit en propose une

Bonjour lesept et elektrax,

Je vous remercie pour vos réponses, j'ai en effet les librairies Adafruit pour ce module.
Je les ais incluses au code, modifié les lignes qu'il me semblait nécessaire mais ça ne fonctionne pas, je n'arrive pas à afficher le compteur.
J'ai déjà utilisé ce module pour d'autres applications de comptage avec succès mais jamais pour une application de type minuteur-compte à rebours. Et j'avoue que le débutant que je suis n'arrive pas à trouver le problème.

Merci

Bonjour,

Mets ton nouveau code.

Bonjour Kamill,

Pas de soucis je fais ça dès que je rentre ce soir.

Merci

Voici le code que j’ai essayé d’adapté sans succès:

#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_7segment matrix = Adafruit_7segment();
 
/* Câblage */
#define BP_UP 4      // Bouton +
#define BP_DOWN 3    // Bouton -
#define BP_START 2   // Bouton Start/Stop (interruption)
#define BUZZER_PIN 5 // Buzzer
 
/* Variables globales */
volatile byte running = false; // Etat du minuteur (true = en fonctionnement, false = à l'arrêt)
char minutes_remain = 0;       // Nombre de minutes restantes (par défaut 0)
char secondes_remain = 10;     // Nombre de secondes restantes (par défaut 10)
 
/* Setup() */
void setup() {
 
  // Initialisation du port série
  Serial.begin(9600);
  matrix.begin(0x70);
  // Initialisation des broches
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BP_UP, INPUT_PULLUP);
  pinMode(BP_DOWN, INPUT_PULLUP);
  pinMode(BP_START, INPUT_PULLUP);
  // pinMode(x, INPUT_PULLUP) correspondant à un pinMode(x, INPUT) puis à un digitalWrite(x, HIGH)
  attachInterrupt(0, bp_start_int, FALLING);
 
 
  // Affiche le temps restant initial
  affiche_temps();
}
 
/* Loop() */
void loop() {
 
  /* Variables locales de gestion du temps */
  static unsigned long last_time = 0; // Temps antérieur
  unsigned long time_now = millis();  // Temps actuel
 
  // Si le minuteur est en marche
  if(running) {
 
    // Et que 1 sec s'est écoulée
    if(time_now - last_time >= 1000) {
 
      // Décrémentation des secondes
      if(--secondes_remain < 0) {
        secondes_remain = 59; // Si il n'y as plus de seconde
 
        // Décrémentation des minutes
        if(--minutes_remain < 0) {
          minutes_remain = 0;   //
          secondes_remain = 0; // Si il n'y as plus de minute
          affiche_temps();
 
          // Mise en marche du buzzer jusqu'à ce que l'utilisateur appui sur le bouton Start/Stop
          while(running) {
            tone(BUZZER_PIN, 500, 500);
            delay(600); 
          }
 
          // Reprise à l'état initial
          secondes_remain = 10;
        }
      }
 
      // Affichage du temps restant
      affiche_temps();
      last_time = time_now;
    }
  } 
  else { // Si le minuteur n'est pas en marche
 
      // Si le bouton + est appuyé
    if(digitalRead(BP_UP) == LOW) {
 
      // Incrémentation des secondes
      if(++secondes_remain > 59) {
        secondes_remain = 0; // Si le nombre de secondes atteint 60
 
          // Incrémentation des minutes
        if(++minutes_remain > 99) {
          minutes_remain = 99;  // Si le nombre de minutes atteint 99
          secondes_remain = 59; // Blocage à 99:59
        }
      }
 
      // Attente variable (basé sur le temps d'appui)
      delay_increment(false);
 
      // Affichage du temps restant
      affiche_temps();
 
    } // Si le bouton - est appuyé
    else if(digitalRead(BP_DOWN) == LOW) {
 
      // Décrémentation des secondes
      if(--secondes_remain < 0) {
        secondes_remain = 59; // Si il n'y as plus de seconde
 
        // Décrémentation des minutes
        if(--minutes_remain < 0) {
          minutes_remain = 0; // Si il n'y as plus de minute
          secondes_remain = 0;
        }
      }
 
      // Attente variable (basé sur le temps d'appui)
      delay_increment(false);
 
      // Affiche du temps restant
      affiche_temps();
 
    } // Si aucun bouton n'est appuyé
    else {
 
      // Remise à zéro du delai variable
      delay_increment(true);
    } 
  }
}
 
/* Delai variable en fonction du temps d'appui */
void delay_increment(byte rst) {
  static unsigned long last_time = 0; // Temps antérieur
  unsigned long time_now = millis();  // Temps actuel
 
  // Si le paramètre de reset est activé
  if(rst) {
    last_time = time_now; // Remise à zéro
    return;        // Fin de fonction
  }
   
  // Si le temps d'appui est supérieur ou égale à 20 secondes
  if(time_now - last_time >= 20000) {
    delay(125);
  } // Si le temps d'appui est supérieur ou égale à 10 secondes
  else if(time_now - last_time >= 10000) {
    delay(250);
  } // Sinon pour tout appui de moins de 10 secondes
  else {
    delay(500);
  }
}
 
/* Interruption du bouton Start/Stop */
void bp_start_int() {
  running = !running;
}
 
/* Fonction d'affichage du temps restant */
void affiche_temps() {
 
  // Converti le temps restant en chaîne de caractères
  char tmp[5];
  matrix.println(tmp, "%02d%02d", minutes_remain, secondes_remain);

Merci :slight_smile:

Et qu'est-ce qui se passe avec ce code?

Bonjour,

Dans affiche_temps l'appel à println est incorrect.
Inspires toi des exemples de la librairie

/* Fonction d'affichage du temps restant */
void affiche_temps() {
  int displayValue = minutes_remain*100 + secondes_remain;
  matrix.print(displayValue, DEC);
}

Merci Kamill,

Tu as juste dis ce qu’il était nécessaire pour que cela fonctionne, du coup j’ai cherché et j’ai trouvé :slight_smile:

Voici la fin du code:

/* Fonction d'affichage du temps restant */
void affiche_temps() {
  
  //reset affichage
  matrix.writeDisplay();
  delay(100);
 
  // Converti le temps restant en chaîne de caractères
  int displayValue = minutes_remain*100 + secondes_remain;
  matrix.print(displayValue, DEC);
  
  //affichage des deux point entre les minutes et les secondes
  matrix.drawColon(secondes_remain % 2 == 0);

  //affichage des quatre chiffres
  if (minutes_remain < 10){
    matrix.writeDigitNum(0, 0);
    if (minutes_remain < 1){
      matrix.writeDigitNum(1, 0);
      if (secondes_remain < 10){
        matrix.writeDigitNum(3, 0);    
      }
    }
  }
}

Merci beaucoup Kamill :slight_smile:

Et si jamais une personne a besoin du code complet:

#include <Wire.h> 
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_7segment matrix = Adafruit_7segment();
 
/* Câblage */
#define BP_UP 4      // Bouton +
#define BP_DOWN 3    // Bouton -
#define BP_START 2   // Bouton Start/Stop (interruption)
#define BUZZER_PIN 5 // Buzzer
 
/* Variables globales */
volatile byte running = false; // Etat du minuteur (true = en fonctionnement, false = à l'arrêt)
char minutes_remain = 0;       // Nombre de minutes restantes (par défaut 0)
char secondes_remain = 10;     // Nombre de secondes restantes (par défaut 10)
 
/* Setup() */
void setup() {
 
  // Initialisation du port série
  Serial.begin(9600);
  matrix.begin(0x70);
 
  // Initialisation des broches
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BP_UP, INPUT_PULLUP);
  pinMode(BP_DOWN, INPUT_PULLUP);
  pinMode(BP_START, INPUT_PULLUP);
  // pinMode(x, INPUT_PULLUP) correspondant à un pinMode(x, INPUT) puis à un digitalWrite(x, HIGH)
  attachInterrupt(0, bp_start_int, FALLING);
 
  // Affiche le temps restant initial
  affiche_temps();
}
 
/* Loop() */
void loop() {
 
  /* Variables locales de gestion du temps */
  static unsigned long last_time = 0; // Temps antérieur
  unsigned long time_now = millis();  // Temps actuel
 
  // Si le minuteur est en marche
  if(running) {
 
    // Et que 1 sec s'est écoulée
    if(time_now - last_time >= 1000) {
 
      // Décrémentation des secondes
      if(--secondes_remain < 0) {
        secondes_remain = 59; // Si il n'y as plus de seconde
 
        // Décrémentation des minutes
        if(--minutes_remain < 0) {
          minutes_remain = 0;   //
          secondes_remain = 0; // Si il n'y as plus de minute
          affiche_temps();
 
          // Mise en marche du buzzer jusqu'à ce que l'utilisateur appui sur le bouton Start/Stop
          while(running) {
            tone(BUZZER_PIN, 650, 450);
            delay(600); 
          }
 
          // Reprise à l'état initial
          secondes_remain = 10;
        }
      }
 
      // Affichage du temps restant
      affiche_temps();
      last_time = time_now;
    }
  } 
  else { // Si le minuteur n'est pas en marche
 
      // Si le bouton + est appuyé
    if(digitalRead(BP_UP) == LOW) {
 
      // Incrémentation des secondes
      if(++secondes_remain > 59) {
        secondes_remain = 0; // Si le nombre de secondes atteint 60
 
          // Incrémentation des minutes
        if(++minutes_remain > 99) {
          minutes_remain = 99;  // Si le nombre de minutes atteint 99
          secondes_remain = 59; // Blocage à 99:59
        }
      }
 
      // Attente variable (basé sur le temps d'appui)
      delay_increment(false);
 
      // Affichage du temps restant
      affiche_temps();
 
    } // Si le bouton - est appuyé
    else if(digitalRead(BP_DOWN) == LOW) {
 
      // Décrémentation des secondes
      if(--secondes_remain < 0) {
        secondes_remain = 59; // Si il n'y as plus de seconde
 
        // Décrémentation des minutes
        if(--minutes_remain < 0) {
          minutes_remain = 0; // Si il n'y as plus de minute
          secondes_remain = 0;
        }
      }
 
      // Attente variable (basé sur le temps d'appui)
      delay_increment(false);
 
      // Affiche du temps restant
      affiche_temps();
 
    } // Si aucun bouton n'est appuyé
    else {
 
      // Remise à zéro du delai variable
      delay_increment(true);
    } 
  }
}
 
/* Delai variable en fonction du temps d'appui */
void delay_increment(byte rst) {
  static unsigned long last_time = 0; // Temps antérieur
  unsigned long time_now = millis();  // Temps actuel
 
  // Si le paramètre de reset est activé
  if(rst) {
    last_time = time_now; // Remise à zéro
    return;        // Fin de fonction
  }
   
  // Si le temps d'appui est supérieur ou égale à 20 secondes
  if(time_now - last_time >= 20000) {
    delay(125);
  } // Si le temps d'appui est supérieur ou égale à 10 secondes
  else if(time_now - last_time >= 10000) {
    delay(250);
  } // Sinon pour tout appui de moins de 10 secondes
  else {
    delay(500);
  }
}
 
/* Interruption du bouton Start/Stop */
void bp_start_int() {
  running = !running;
}
 
/* Fonction d'affichage du temps restant */
void affiche_temps() {
  
  //reset affichage
  matrix.writeDisplay();
  delay(100);
 
  // Converti le temps restant en chaîne de caractères
  int displayValue = minutes_remain*100 + secondes_remain;
  matrix.print(displayValue, DEC);
  
  //affichage des deux point entre les minutes et les secondes
  matrix.drawColon(secondes_remain % 2 == 0);

  //affichage des quatre chiffres
  if (minutes_remain < 10){
    matrix.writeDigitNum(0, 0);
    if (minutes_remain < 1){
      matrix.writeDigitNum(1, 0);
      if (secondes_remain < 10){
        matrix.writeDigitNum(3, 0);    
      }
    }
  }
}

++ Inspiré du code de Skywodd et modifié pour l’utilisation du module HT16K33.