[SOLVED] Very simple countdown timer problem

Hello,

I want to build a simple countdown timer just for fun. I have a 7 segment led for displaying the time from 9s to 0s, one push button to start the countdown, one push button to increase the time, and a buzzer to buzz when the time is over.

The problem is my code is not running well. It display a 8 and nothing append when I push on a button.

Have you got any idea of what is the problem ?

/* Test de compteur à rebours
*
* un afficheur 7 segments affiche un temps de 0 à 9s
* un bouton on
* un bouton pour incrémenter le temps
* un buzzer pour signaler la fin du temps
*
*/

//constantes
int onPin = 12 ;    //pour le bouton on
int reglPin = 13 ;    //pour le bouton de réglage - for incrementing button
int buzzerPin = 11 ;    //pour le buzzer
int ledPins[] = {2, 3, 4, 5, 6, 7, 8} ;    //liste des leds

//variables
int compte = 0 ;    //variable de comptage - for counting

// listes des pins pour faire les nombres
//pin 1, 2, 4, 5, 7, 9, 10 sur l'afficheur - on the 7 segment led
int seven_seg_digits[10][7] = {  { 0,1,1,1,1,1,1 },  // = 0
                                  { 0,0,0,0,1,1,0 },  // = 1
                                  { 1,0,1,1,0,1,1 },  // = 2
                                  { 1,0,0,1,1,1,1 },  // = 3
                                  { 1,1,0,0,1,1,0 },  // = 4
                                  { 1,1,0,1,1,0,1 },  // = 5
                                  { 1,1,1,1,1,0,1 },  // = 6
                                  { 0,0,0,0,1,1,1 },  // = 7
                                  { 1,1,1,1,1,1,1 },  // = 8
                                  { 1,1,0,0,1,1,1 }   // = 9
                               };

/*
* Fonctions
*/

// pour faire craquer le buzzer - for buzzing
void buzz() {
  digitalWrite(buzzerPin, HIGH);
  delayMicroseconds(2000);
}

// pour l'affichage - for displaying
void afficheLeds(int digit) {
  int pin = 2;
  for (int count = 0; count<7 ; ++count) {
    digitalWrite(pin, seven_seg_digits[digit][count]);
    ++pin;
  }
}

// pour compter à rebours - countdown
void compteRebours(int count) {
  for (int c = count; c>0; --c) {
    delay(1000);
    afficheLeds(c); 
  }
  buzz();
}


/*
* SetUp
*/
void setup()
{
  for(int i=0; i<7 ; i++) {    //on défini les leds comme des outputs
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(buzzerPin, OUTPUT);   //on défini le buzzer en output
  
  pinMode(onPin, INPUT);
  pinMode(reglPin, INPUT);
}

/*
* Boucle principale
*/
void loop()
{
  afficheLeds(compte);
  
  // pour incrémenter le temps - for incrementing time
  if (digitalRead(reglPin) == LOW) {
    ++compte;
    if(compte>9) {
      compte = 0;
    }
    afficheLeds(compte);
  }
  
  //pour lancer le compte à rebours - for running the countdown
  else if (digitalRead(onPin) == LOW) {
    compteRebours(compte);
  }
}

At first sight the code looks OK, can you tell how you connected the buttons ?
Have you used a pull up resistor?
This can be done in the setup as the Arduino has builtin pullups.

void setup()
{
  for(int i=0; i<7 ; i++) 
  {
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(buzzerPin, OUTPUT); 
  
  pinMode(onPin, INPUT);
  digitalWrite(onPin, HIGH);   // pullup
  pinMode(reglPin, INPUT);
  digitalWrite(reglPin, HIGH); // pullup
}

Thank you for your answer.

Yes I used a pull up resistor for each button. This is my circuit (my 7 segment led is not the same but it's not important, it works with another code)

I tried your code but it is always the same.

It isn't clear where your problem is; is it a button-reading problem, or a display problem?
I'd break down the problem even further - ignore the button-pressing, and just test the countdown loop and check that your display code is working.

I've just try the compteRebours and afficheLeds fonctions, they both work.

So my problem is a button-reading problem or my main loop is not good

So, I've solved one part of my problem. I tested each buttons and pins and I discovered that my #13 pin was the guilty. So I plugged the reglPin on pin 10.

Now, it works but not totaly. When I push the start button, it count-down and then play the melody (that I copied from an exemple) But when I push the setting button, it doesn't increase by 1 but it displays random numbers.

Here is my corrected code:

/* Test de compteur à rebours
*
* un afficheur 7 segments affiche un temps de 0 à 9s
* un bouton onoff
* un bouton pour incrémenter le temps
* un buzzer pour signaler la fin du temps
*
*/

#include "pitches.h"
// notes in the melody:
int melody[] = {
  NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 8, 8, 4,4,4,4,4 };



//constantes
int onPin = 12 ;    //pour le bouton on off
int reglPin = 10 ;    //pour le bouton de réglage
int buzzerPin = 11 ;    //pour le buzzer
int ledPins[] = {2, 3, 4, 5, 6, 7, 8} ;    //liste des leds

//variables
int compte = 9 ;    //variable de comptage

// listes des pins pour faire les nombres
//pin 1, 2, 4, 5, 7, 9, 10 sur l'afficheur
int seven_seg_digits[10][7] = {  { 0,1,1,1,1,1,1 },  // = 0
                                  { 0,0,0,0,1,1,0 },  // = 1
                                  { 1,0,1,1,0,1,1 },  // = 2
                                  { 1,0,0,1,1,1,1 },  // = 3
                                  { 1,1,0,0,1,1,0 },  // = 4
                                  { 1,1,0,1,1,0,1 },  // = 5
                                  { 1,1,1,1,1,0,1 },  // = 6
                                  { 0,0,0,0,1,1,1 },  // = 7
                                  { 1,1,1,1,1,1,1 },  // = 8
                                  { 1,1,0,0,1,1,1 }   // = 9
                               };

/*
* Fonctions
*/

// pour faire craquer le buzzer
void buzz() {
  for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second 
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/noteDurations[thisNote];
    tone(11, melody[thisNote],noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(11);
  }
}

// pour l'affichage
void afficheLeds(int digit) {
  int pin = 2;
  for (int count = 0; count<7 ; ++count) {
    digitalWrite(pin, seven_seg_digits[digit][count]);
    ++pin;
  }
}

// pour compter à rebours
void compteRebours(int count) {
  for (int c = count; c>=0; --c) {
    afficheLeds(c);
    delay(1000);
  }
  buzz();
}


/*
* SetUp
*/
void setup()
{
  for(int i=0; i<7 ; i++) {    //on défini les leds comme des outputs
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(buzzerPin, OUTPUT);   //on défini le buzzer en output
  
  pinMode(onPin, INPUT);
  digitalWrite(onPin, HIGH);
  pinMode(reglPin, INPUT);
  digitalWrite(reglPin, HIGH);
}

/*
* Boucle principale
*/
void loop()
{

  // pour incrémenter le temps
  if (digitalRead(reglPin) == LOW) {
    ++compte;
    if(compte>9) {
      compte = 0;
    }
    afficheLeds(compte);
  }
  
  //pour lancer le compte à rebours
  if (digitalRead(onPin) == LOW) {
    compteRebours(compte);
  }
}

Reset compte after the countdown explicitely?

  if (digitalRead(onPin) == LOW) {
    compteRebours(compte);
    compte = 0;
  }

It is still the same.

My problem is, I think, on this part of code:

  if (digitalRead(reglPin) == LOW) {
    ++compte;
    if(compte>9) {
      compte = 0;
    }
    afficheLeds(compte);
  }

But I don't understand why :~. If the button is pressed : increase "compte" from 1. If "compte" is superior to 9 so it is equal to 0. And then display the number on the 7 segment led.

You are not debouncing the switch. How many times does that if block execute each time the switch is pressed?

Thank you

It works now :slight_smile:

Here is the code:

/* Test de compteur à rebours
*
* un afficheur 7 segments affiche un temps de 0 à 9s
* un bouton onoff
* un bouton pour incrémenter le temps
* un buzzer pour signaler la fin du temps
*
*/

#include "pitches.h"
// notes in the melody:
int melody[] = {
  NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 8, 8, 4,4,4,4,4 };



//constantes
int onPin = 12 ;    //pour le bouton on off
int reglPin = 10 ;    //pour le bouton de réglage
int buzzerPin = 11 ;    //pour le buzzer
int ledPins[] = {2, 3, 4, 5, 6, 7, 8} ;    //liste des leds

//variables
int compte = 0 ;    //variable de comptage
int buttonState = 0;  //variable d'état du bouton de réglage
int lastButtonState = 0;  //variable pour le dernier état du bouton

// listes des pins pour faire les nombres
//pin 1, 2, 4, 5, 7, 9, 10 sur l'afficheur
int seven_seg_digits[10][7] = {  { 0,1,1,1,1,1,1 },  // = 0
                                  { 0,0,0,0,1,1,0 },  // = 1
                                  { 1,0,1,1,0,1,1 },  // = 2
                                  { 1,0,0,1,1,1,1 },  // = 3
                                  { 1,1,0,0,1,1,0 },  // = 4
                                  { 1,1,0,1,1,0,1 },  // = 5
                                  { 1,1,1,1,1,0,1 },  // = 6
                                  { 0,0,0,0,1,1,1 },  // = 7
                                  { 1,1,1,1,1,1,1 },  // = 8
                                  { 1,1,0,0,1,1,1 }   // = 9
                               };

/*
* Fonctions
*/

// pour faire craquer le buzzer
void buzz() {
  for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second 
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/noteDurations[thisNote];
    tone(11, melody[thisNote],noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(11);
  }
}

// pour l'affichage
void afficheLeds(int digit) {
  int pin = 2;
  for (int count = 0; count<7 ; ++count) {
    digitalWrite(pin, seven_seg_digits[digit][count]);
    ++pin;
  }
}

// pour compter à rebours
void compteRebours(int count) {
  for (int c = count; c>=0; --c) {
    afficheLeds(c);
    delay(1000);
  }
  buzz();
}


/*
* SetUp
*/
void setup()
{
  for(int i=0; i<7 ; i++) {    //on défini les leds comme des outputs
    pinMode(ledPins[i], OUTPUT);
  }
  afficheLeds(compte);
  pinMode(buzzerPin, OUTPUT);   //on défini le buzzer en output
  
  pinMode(onPin, INPUT);
  digitalWrite(onPin, HIGH);
  pinMode(reglPin, INPUT);
  digitalWrite(reglPin, HIGH);
}

/*
* Boucle principale
*/
void loop()
{

  // pour incrémenter le temps
  buttonState = digitalRead(reglPin);  //on lit l'état du bouton
  
  if (buttonState != lastButtonState) {  //on compare l'état du bouton avec son dernier état mémorisé
    if (buttonState == LOW) {
      ++compte;
      if(compte>9) {
        compte = 0;
      }
      afficheLeds(compte);
    }
  }
  
  lastButtonState = buttonState;  //on mémorise l'état du bouton comme étant le dernier état
  
  //pour lancer le compte à rebours
  if (digitalRead(onPin) == LOW) {
    compteRebours(compte);
    compte = 0;
  }
}

I will try now to improve it. There is a delay when I press the start button and before it ring when it arrive to 0