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 ! :)

About these ads

Discussion

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

  1. Skywodd, vient manger ta soupe :D

    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], 0×76, 0×70, et 0×10 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

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Archives

Wow. Dogecoin. Amaze.

Laissez un tip en Dogecoin

DMMNFk6WBVTpx2Wu1Z35GL61QXSd6r6WQx

Suivre

Recevez les nouvelles publications par mail.

Joignez-vous à 678 followers