Skyduino:~#
Articles
arduino, Corrigé, programmation

[Arduino] Minuteur minutes / secondes avec buzzer

Bonjour tout le monde !

Aujourd’hui je vous propose un nouveau montage à base d’arduino !
Que diriez vous de fabriquer votre propre minuteur ? 😉

Un minuteur c’est toujours pratique, pour cuire un œuf ou une pizza (souvent plus une pizza qu’un œuf personnellement :)), pour faire des vidéos youtube d’une durée fixe, ou tout simplement pour le plaisir de voir l’afficheur s’approcher dangereusement du 00:00 fatidique 😉

Oui je sais, ce genre de minuteur se trouve absolument partout pour trois fois rien, mais c’est tellement plus gratifiant de bricoler un truc par soit même 🙂

Le principe de fonctionnement :

J’ai décidé de rester très simple :
– 3 boutons (+, -, Start / Stop),
– si on reste appuyé longtemps sur un bouton les secondes s’incrémentent/décrémentent plus rapidement,
– on peut mettre en marche ou arrêter le minuteur à n’importe quelle moment,
– quand le temps est écoulé un buzzer beep frénétiquement jusqu’à ce que l’on appuie sur le bouton Stop.

Pour l’affichage j’ai décidé d’utiliser un afficheur 7 segments série de sparkfun, l’effet bleuté rendant le montage plus « classe » 🙂
Faut bien un petit côté « Hollywood » sinon c’est pas un vrai minuteur 😉

Le montage :

Niveau composants on reste là aussi très classique :
- une carte arduino UNO
- une shield breadboard
- un afficheur 7 segments série de sparkfun
- 3 boutons poussoir
- un condensateur de 10µF
- un buzzer (ou un petit haut parleur)
- des fils

Rien de bien transcendant comme vous pouvez le voir 😉
A part pour l’afficheur série vous devriez trouver tout les composants nécessaire au fond d’un tiroir ou de votre starter kit 😉

Le câblage :

Arduino -> Boutons
D2 -> Bouton Start/Stop -> GND (avec un condensateur de 10µF entre D2 et GND)
D3 -> Bouton - -> GND
D4 -> Bouton + -> GND
D5 -> Buzzer

Vous remarquerez que je n’utilise pas de résistances de pull-up dans ce montage !
En réalité je vais utiliser celle intégrée de base dans l’ATmega328p de l’arduino 😉
(Et au passage je vous montrerai une petite nouveauté bien sympa de l’ide arduino 1.0.1)

Arduino -> afficheur 7 segments
+5v -> VCC
GND -> GND
TX -> RX
+5v (ou +3v3) -> CSN

Concernant la connexion de la broche CSN, celle ci doit être reliée au +5v (ou à défaut au +3v3) afin que l’afficheur travaille en mode série uniquement.
Dans le cas contraire le moindre mouvement autour de l’écran génère des parasites pouvant planter l’affichage.

Le code arduino (pour 1.0 ou supérieur) :

Testé, commenté et indenté comme d’habitude 😉
Vous remarquerez que j’ai déporté certains morceaux de code dans des fonctions séparées afin qu’elles soient plus facilement réutilisables 😉

/*
 * 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);
}

Le résultat :

Le résultat en image :

Et le résultat en vidéo :
(la vidéo est fait un peu à l’arrache, je l’ai fait entre deux tweets ;))

PS: j’avais même pas fait gaffe, j’ai sauvé le monde de la destruction à la secondes prés 🙂
00:01 … ouff c’est pas passé loin ^^ (halala les films Américains …)

Enjoy ! 🙂

Discussion

40 réflexions sur “[Arduino] Minuteur minutes / secondes avec buzzer

  1. Skywodd, vient manger ta soupe 😀

    Publié par Barbudor | 28 août 2012, 20 h 09 min
  2. salut skywodd j’ai un haut parleur 4 ohms 5W récup sur un piano éléctronique je peux le brancher direct sur une sortie de l’arduino ??

    Publié par Fabien | 29 août 2012, 10 h 42 min
  3. j’ai des résistance de 300 ohms ,10 kohms et 1 ohms y’en a une qui irait ou pas ??
    parce que passer une commande pour acheter des résistance de 10 ohms c’est un peux c**

    Publié par Fabien | 29 août 2012, 11 h 22 min
  4. Salut,

    C’était quoi la nouvelle fonctionnalité de l’ide 1.0.1 ?

    Publié par PhilippeFromGpe | 29 août 2012, 18 h 06 min
  5. Aaah ok, je l’avais pas vu.
    merci

    Publié par PhilippeFromGpe | 29 août 2012, 18 h 54 min
  6. On voit que tu est rompu a la programmation en C++, c’est compact, bien documenté…j’aimerais bien programmer comme ça ! bravo.
    Par curiosité, il t’a fallu combien de temps pour mettre au point ce programme ?

    Publié par adventum | 4 septembre 2012, 10 h 51 min
    • >> On voit que tu est rompu a la programmation en C++, c’est compact, bien documenté…j’aimerais bien programmer comme ça ! bravo.

      Je suis étudiant en IUT informatique, programmer de manière propre et organisé c’est ce que l’on (essaye) de nous apprendre à chaque cours 😉

      >> Par curiosité, il t’a fallu combien de temps pour mettre au point ce programme ?
      Environ 2h, 1h sur papier pour mettre en forme les grandes lignes (montage, module à utiliser, fonctionnement de base) et 1h pour faire le code et le tester.

      Publié par skywodd | 4 septembre 2012, 11 h 19 min
  7. Encore une question : pourquoi, ou plutôt : dans la fonction « affiche_temps() », que font les instructions char tmp[5], 0x76, 0x70, et 0x10 en liaisons séries ?…en fait, je ne comprends pas cette fonction

    Merci de me répondre

    Publié par adventum | 4 septembre 2012, 11 h 02 min
    • C’est les commandes d’affichage de l’afficheur 7 segments série 😉

      Le détail de cette fonction :

      /* Fonction d'affichage du temps restant */
      void affiche_temps() {
      
        // Tableau de char contenant les valeurs des digits (4 digits + \0)
        char tmp[5];
      
        // Mise en forme des deux valeurs en une chaine de caractére au format "mmss "
        sprintf(tmp, "%02d%02d", minutes_remain, secondes_remain);
       
        // Commande d'affichage d'un point décimal (spécifique à l'afficheur 7 segments de sparkfun)
        Serial.write(AFF_CRTL_DP);
      
        // Commande d'affichage du double point horaire ':'
        Serial.write(DP_HORAIRE);
      
        // Affichage des 4 digits stocké dans tmp[] (on ignore le \0 en fin de chaine)
        Serial.write((uint8_t*)tmp, 4);
      }
      

      Publié par skywodd | 4 septembre 2012, 11 h 25 min
  8. Merci pour tous ces renseignement et encore bravo !
    Pourrais je t’envoyer un petit programme (qui fonctionne), mais programmé avec les pieds,.. ! pour le rendre plus compact, plus élégant …je ne veux pas abuser de ton temps non plus…
    Si tu es d’accord, je te l’envoies sur le forum ?

    Publié par adventum | 4 septembre 2012, 20 h 20 min
  9. Bonjour,
    Je débute avec Arduino et pour l’instant j’avale les infos, les programmes, bref je consulte le travail des autres.
    En regardant ton article, je me suis dit qu’on était pas loin d’un chrono de régate.

    Comme fonctionne ce type de chrono ?
    3 boutons, un afficheur 3 chiffres, un buzzer (faccultatif).
    Le décompte est déclenché par un poussoir à 5 min, un son à 4 min, un à 1 min, puis toutes les 10 sec, et toutes les secondes de 10 à 0.
    Rien de compliqué… Juste un complément : possibilité de synchroniser le chrono par appui sur un poussoir à 4min et 1 min. En régate on a un pavillon qui est hissé ou affalé à 5 min, 4min, 1min et 0.

    Publié par Francis | 13 septembre 2012, 9 h 12 min
  10. Après plus complexe, je suis bénévole dans un groupe d’handicapés pratiquant le miniJI.
    Un des handi est incapable de déclencher le chrono, j’ai pensé à un module HF de radiocommande alimenté par un arduino qui simulerait une trame ppm :
    http://photocerfvolant.free.fr/phpBB2/viewtopic.php?f=6&t=2111
    équipé juste d’un poussoir.
    Le récepteur serait équipé d’un switch qui simulerait l’appui sur le poussoir 5 min.
    kit HF :
    http://www.hobbyking.com/hobbyking/store/__9770__Corona_2_4Ghz_DIY_Module_RX_DSSS_.html
    http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=8833
    mais on pourrait faire décoder directement le signal issu du récepteur par l’arduino horloge moins de hard mais plus de soft.

    Publié par Francis | 13 septembre 2012, 9 h 30 min
  11. Moi dans mon programme, je ne parviens pas à regler les minutes sans affecté les secondes . Quelqu’un peut m’aider ?

    Publié par Sylvain | 10 janvier 2014, 15 h 28 min
  12. salut sans vouloir te déranger peut tu m’expliquer comment
    je peut activer un relais a la fin du temps
    merci d’avance

    Publié par stan | 30 avril 2015, 21 h 46 min
    • A la place de :

      while(running) {
                  tone(BUZZER_PIN, 500, 500);
                  delay(600); 
      }
      

      Tu peux utiliser un digitalWrite() pour actionner ton relay. Ne pas oublier d’ajouter un delay() et un second digitalWrite() après le delay() pour désactiver le relay.

      Exemple rapide :

      digitalWrite(pin, HIGH);
      delay(1000);
      digitalWrite(pin, LOW);
      

      Publié par Skywodd | 4 Mai 2015, 18 h 33 min
  13. Je veux le schema electrique svp

    Publié par Raymond | 7 Mai 2015, 10 h 36 min
  14. bonjour, je voudrais faire un chronomètre à déclenchement et arrêt automatique avec deux barrières à réflecteurs et transmission rf et un afficheur pour le temps en seconde et centième j’ai le matériel mais je butte sur le programme !
    comment se servir d’un afficheur 8×7 segments faut il installer une librairie ? c’est un 5fils VCC-GND-DIO-SCK-RCK

    Publié par ROUSSEAU Louison | 29 octobre 2015, 11 h 26 min
    • je pourrais peu etre faire le declenchement (Start chrono) par un arduino puis l’émission par Rf puis réception et stop chrono sur un autre arduino avec un recepteur RF puis affichage et traitement des chronos sur tablette avec AP inventor ?

      Publié par ROUSSEAU Louison #19R | 5 novembre 2015, 10 h 03 min
      • Pour avoir un temps correct le mieux c’est d’avoir un câble de synchro start/stop avec trois modules : deux barrières (start et stop) et le minuteur (au mi longueur de câble).
        La RF c’est bien pour communiquer mais pas pour faire de la synchro, les temps de latences ne sont pas constant.

        Les barrières de sport RF (pour les timings start/stop des coureurs par exemple) utilisent un système un peu différent. Chaque portique a sa propre horloge. Avant le départ, les horloges de tout les portiques sont synchronisés à partir d’une horloge maître (qui fait aussi office de récepteur RF). Quand un coureur passe, le portique envoi le temps courant de son horloge.

        Publié par Skywodd | 11 novembre 2015, 18 h 27 min
    • Une référence concernant l’afficheur ?
      Un 8×7 segments avec entrée série pour les données, il y en a un paquet de différent.

      Publié par Skywodd | 11 novembre 2015, 18 h 18 min
      • Du coup, j’utilise un écran lcd i2C pour l’affichage sur l’arduino coordonateur et 2 autres arduino avec aussi des modules Xbee (2 router et un coordonateur) ca fonctionne avec une barrière cellules pour le start et une autre pour le stop. Il ne me reste plus qu’a modifier un peu le programme pour que à l’arrivé le temps soit comparé et que le meilleur temps reste affiché sur la 2eme ligne jusqu’au reset, c’est possible ça ?

        Publié par ROUSSEAU LOUISON#19R | 31 janvier 2016, 21 h 07 min
  15. Je suis à la recherche d’un génie capable de concevoir (pour un jeu de société qui se joue à 2, 3 ou 4), un système de classement utilisant 4 buzzers et 4 afficheurs sachant que :

    1 – Chaque joueur a son buzzer et son afficheur
    2 – L’afficheur (déjà matérialisé sur le plateau de jeu) comporte 5 plots numérotés de 1 à 5
    3 – Le plot n°5 doit servir à un reset de tous les afficheurs
    4 Le premier joueur qui actionne son buzzer voit le chiffre 1 s’allumer sur son afficheur, le joueur qui actionne son buzzer en second voit le chiffre 2 sur son afficheur, etc…
    5 – S’il n’y a que 2 ou 3 participants, les buzzers non utilisés doivent être HS.

    Rémunération envisageable.
    Me contacter pour + d’info

    Publié par Roccia Pierre | 7 décembre 2015, 10 h 33 min
  16. merci pour le projet c’est magnéfique SVP moi je n’ai pas l’ affaicheur comment vous, j’ai affaicheur 7 segment (normal) 4 nombre comment vas changer le code pour mon affaicheur et merci infiniment

    Publié par hamouchi | 28 janvier 2016, 21 h 17 min
  17. merci pour le projet c’est magnéfique SVP moi je n’ai pas l’ affaicheur 7 segment série de sparkfun , j’ai affaicheur 7 segment (normal) comment vas changer le code pour mon affaicheur et merci infiniment

    Publié par hamouchi | 28 janvier 2016, 21 h 22 min
  18. Bonjour,

    Comment je reconnais la broche CSN?? Sur mon afficheur sparkfun

    Merci d’avance

    Publié par Tafamaf | 14 août 2016, 21 h 36 min
  19. Bonjour, super petit projet. Mon je cherche à faire un multi timer avec 4 temps réglables (4x l’afficheur et 4 jeux de boutons de programmation de temps mais un seul start stop). Au start, c’est un cycle qui commence et lance le décompte T1 (programmable). En fin de T1 lancement d’une fonction sur un autre Arduino par un pulse OUT et attente sa réponse par un pulse IN puis T2 (programmable) décompte et ainsi de suite jusque fin de T4 qui fait sonner le buzzer et replace l’ensemble en standby. Sur base de ton schéma on pourrait bidouiller le tout en multipliant le croquis 4 x, mais ni aurait-il pas une manière plus rationnelle de prendre ce problème? Grand merci à tous.

    Publié par lucviccaLuc | 1 février 2017, 18 h 46 min
  20. merci grace à toi j’ai reussi mon bac si tu veux on peut aller ce soir boire un verre (nan je deconne on va ce bourrer la gueul)

    Publié par jean jaque | 3 octobre 2017, 15 h 21 min
  21. Salut petite question.. Si je veux par exemple mettre un temps par défaut de 35 ou 40 minutes
    Je change juste ici ??

    /* 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)

    Merci pour votre aide

    Publié par Allan | 28 mars 2018, 23 h 36 min
  22. Bonjour petite question,

    Je n’est pas d’afficheur 7 segment et j’aimerais le mettre dans le moniteur Série. Comment faire s’il te plait ?

    Publié par LANDREAT | 19 Mai 2018, 14 h 27 min
  23. Salut Skywood, encore un bon tuto!
    Cependant j’ai une petite requête: Je veux remplacer le bouton Start/Stop par 2 bp( 1start et 1 stop). Comment puis-je faire?
    Encore merci pour tout le travail accompli.

    Publié par Nicolas BOULAY | 3 juin 2018, 14 h 00 min
  24. j’ai un problème de compilation

    Publié par Merveille Bopda Fotso | 13 août 2018, 23 h 04 min

Rétroliens/Pings

  1. Pingback: Arduino | Pearltrees - 26 avril 2015

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.