Countdown Timer Help

Hey all!

Having a bit of trouble with my countdown timer. It is supposed to simply count down from a set default value (currently 99:59), one second at a time. It IS counting down...but opposite of what it is supposed to. Rather than counting down the seconds (from 59), it is counting down the minutes (from 99). Also, it is counting down the minutes as milliseconds almost. when the minutes DO reach zero, all digits reach zero.

There are also two buttons--a Button_Start (start/pause timer and in setup mode inreases minutes
and seconds values) and a Button_Set (if timer is paused it resets timer to start. Long press
activates setup mode in which button is for going through minutes, seconds setup
and leaving setup mode). Neither of which are working properly. Button_Start currently decrements the seconds by four, and Button_Set currently pauses the minute countdown until you release the button.

Here is the code:

/*
Arduino 4 digits 7 segments LED countdown timer with buzzerm from
electronicsblog.net. If You share/use this code elsewhere on the internet
please meantion this code source.
*/

// segment | Arduino board PIN number 

#define G 8
#define S 7
#define A A1
#define B 3
#define E A0
#define D 5
#define C 4
#define DP 13

// Commonn cathodes control
#define GND1 11
#define GND2 10
#define GND3 9
#define GND4 6

// buttons
/*
Button_start - start/pause timer and in setup mode inreases minutes
and seconds values
Button_set - if timer is paused it resets timer to start. Long press
activates setup mode in which button is for going through minutes, seconds setup
and leaving setup mode.


*/


#define Button_start 12
#define Button_set 1

///
#define Buzzer 46
#define LED 47 // or relay insted



int i=0; 
char run=0; // shows if timer is runnig
int b=0;  //for buttons
int c=0;
int d=0; // for buzzer
char set_mode=0; // shows if timer is in setup mode
char alarm =0;  // if "1" buzzer is on



//timer variables

// user setted and "turn on" values
int default_Sec=59;
int default_Min=99;

// current values
int Sec;
int Min;
int Thousandth;

//timer interrupt

ISR(TIMER1_OVF_vect) {
Thousandth = Thousandth +1;
if (Thousandth == 1000){
Thousandth = 0;
Sec--; // timer values decreases
TCNT1=0x0BDC;
  
}

}


// functions to display digits



void digit0() {
// for 0 needed to turn ON F A B C D E segments, so:

digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(S, LOW);

//////////////////////// G segment should be turn OFF
digitalWrite(G, HIGH);



};



void digit1 () {


digitalWrite(A,HIGH);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(S, HIGH);
digitalWrite(G, HIGH);
};

void digit2 () {


digitalWrite(A,LOW);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(S, HIGH);
digitalWrite(G, LOW);
};


void digit3 () {


digitalWrite(A,LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(S, HIGH);
digitalWrite(G, LOW);
};

void digit4 () {


digitalWrite(A,HIGH);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(S, LOW);
digitalWrite(G, LOW);
};

void digit5 () {


digitalWrite(A,LOW);
digitalWrite(B, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, HIGH); 
digitalWrite(S, LOW);
digitalWrite(G, LOW);
};

void digit6 () {


digitalWrite(A,LOW);
digitalWrite(B, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, LOW); 
digitalWrite(S, LOW);
digitalWrite(G, LOW);
};

void digit7 () {


digitalWrite(A,LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH); 
digitalWrite(S, HIGH);
digitalWrite(G, HIGH);
};


void digit8 () {


digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(S, LOW);
digitalWrite(G, LOW);



};

void digit9 () {


digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(S, LOW);
digitalWrite(G, LOW);



};


//function to display digit from inputed int

void showdigit (int digit)

{
  
 switch (digit) {
 
 case 0:
 digit0 ();
 break;
 
 case 1:
 digit1 ();
 break;
 
 case 2:
 digit2 ();
 break;
 
 case 3:
 digit3 ();
 break;
 
 case 4:
 digit4 ();
 break;
 
 case 5:
 digit5 ();
 break;
 
 case 6:
 digit6 ();
 break;
 
 case 7:
 digit7 ();
 break;
 
 case 8:
 digit8 ();
 break;
 
 case 9:
 digit9 ();
 break;
 
 default:

 
 
 break;
 
 
 
 }; 

};


// showing 4 digits
//  not only shows 4 digit number, but also there is option to turn on
//only selected digits and decimal point.

void showdigits (int number, char digit_on, char  decimal_point) 
{

  

digitalWrite(GND4, LOW);
  // e.g. we have "1234"
showdigit(number/1000);  // segments are set to display "1"
if (decimal_point&8) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&8) {
digitalWrite(GND1, HIGH); // first digit on,
digitalWrite(GND2, LOW); // other off
digitalWrite(GND3, LOW);
 }
 delay (1);


number = number%1000;  // remainder of 1234/1000 is 234
digitalWrite(GND1, LOW); // first digit is off
 showdigit(number/100); //// segments are set to display "2"
if (decimal_point&4) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&4) {
digitalWrite(GND2, HIGH); // second digit is on
  } delay (1);// and so on....
 
number =number%100;    
digitalWrite(GND2, LOW);
showdigit(number/10);
if (decimal_point&2) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&2) {
digitalWrite(GND3, HIGH);
 }
 delay (1);

number =number%10; 
digitalWrite(GND3, LOW);
showdigit(number); 
if (decimal_point&1) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&1) {
digitalWrite(GND4, HIGH); 
  }
  delay (1);

}; 

void setup()

{

  
pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
pinMode(E, OUTPUT);
pinMode(S, OUTPUT);
pinMode(G, OUTPUT);
pinMode(DP, OUTPUT);

pinMode(GND1, OUTPUT);
pinMode(GND2, OUTPUT);
pinMode(GND3, OUTPUT);
pinMode(GND4, OUTPUT);


pinMode(Button_start, INPUT);
digitalWrite(Button_start, HIGH); //pull up resistor

pinMode(Button_set, INPUT);
digitalWrite(Button_set, HIGH); //pull up resistor

pinMode(Buzzer, OUTPUT);
pinMode(LED, OUTPUT);

TIMSK1=0x01; // enabled global and timer overflow interrupt;
TCCR1A = 0x00; // normal operation 148 page (mode0);

TCNT1=0x0BDC;

TCCR1B = 0x00; // stop hardware timer

// loading default timer values

Sec = default_Sec ; 
Min = default_Min ;



};
void loop ()

{
 //////////// button_start////////// 
  if (!digitalRead(Button_start)&&!b) {
  
  if (!set_mode) { if (run) {TCCR1B=0x00; run=0;} else {TCCR1B=0x04; run=1;}}
  
  if (set_mode==1) {Min--;} 
  
   if (set_mode==2) {Sec--;} 
      
   if (set_mode) {b=25;} else b=100;
  
         };
         
 if (!digitalRead(Button_start)&&b==1) {
     
        };       


if (!b==0) b--;

 //////////// button_set///////// 
 if (!digitalRead(Button_set)&&!c) {
  
   if(!run&&!set_mode) {Min=default_Min; Sec=default_Sec;}
            
  if (set_mode>0) set_mode++;
  
  if (set_mode==3) {set_mode=0;  default_Sec = Sec ;
default_Min = Min; }
  
   c=100;      };   
   
 if (!digitalRead(Button_set)&&c==1&&!run) {
   
     set_mode=1;
     
     c=100;
   
        };       


if (!c==0) c--;
////////////////////////////

if (set_mode) {if (Sec==60) {Sec=00;} 

 if (Min==100) {Min=0;} }

      
       else {
 
 if (Sec==-1) {Min--;Sec=59;} 
 
 }  
 
 
//decimal point indication control 

if (!set_mode) {
  
  
  if (!(Sec%2)) { showdigits (Min*100+Sec,0x0F,0x04); } //0X00

else  {showdigits (Min*100+Sec,0x0F,0x00); }; //0000

} else {
  
  if (set_mode==1) {
  
  showdigits (Min*100+Sec,0x0F,0x0C);   //XX00
                                } else { 
                     
                     
                     
                     showdigits (Min*100+Sec,0x0F,0x03);      } //00XX

}
if (run) {  // to do while timer is running; e.g. control relay 

digitalWrite(LED, HIGH);


} else digitalWrite(LED, LOW);



if ((Min==0)&&(Sec==0)&&run) {
run=0;
TCCR1B=0x00; //stop timer

//// to do after count down is finished e.g. start alarm as in this example


alarm=1;
d=500;

}

// Alarm part
if (alarm) { if (!(d%100)) { // sound 500/100= 5 times ;
  tone(Buzzer, 440, 200); }
  d--; 
  if (d==0) {alarm=0; Sec = default_Sec ;
  Min = default_Min ; // After alarm is off, timer goes to start
          }
    }  
};

Any help at all would be deeply appreciated. I am using an Arduino Uno.

Thanks so much in advance.

Baylee

Formatting your code with CTRL T would really really help.
One line one instruction.
Place comments on your lines, for example when I see mode 1, my eyes glaze over.
Use Serial.print statements at different places in your code to help trouble shoot your sketch. Then when you prove a section of code move the Serial.print debug statement and prove out the next section of code.

Well...I put a Serial.println("Okay_") in every if statement from the loop function and down..this is what I got.

1 if (!digitalRead(Button_start)&&!b) {
2 if (!set_mode) {
3 else {
     TCCR1B=0x04; 
      run=1;
      }
    }
7 else b=100;
9 if (!b==0) b--;
16 if(!c==0) c--;
20 else {
21 if (!set_mode) {
23 else {
27 if (run) {
28 else digitalWrite(LED, LOW);
9  if (!b==0) b--;
.
.
.

I'm really confused as to what is going wrong...

If you add the Serial.print below what happens on the serial monitor?
Edit, Sorry you cannot use Serial print in the ISR

//timer interrupt
ISR(TIMER1_OVF_vect)
 {
   Thousandth = Thousandth +1;
   if (Thousandth == 1000)
   {
   Thousandth = 0;
   Sec--; // timer values decreases
   TCNT1=0x0BDC;
   Serial.println("Reached 1000");  
   }
}

I didn't think you could print from within an ISR, serial print uses interrupts, and interrupts were turned off once the interrupt was being handled?

It's 11:30
Yes you are right, you cannot Serial print in the ISR! :sleeping:

I recommend you use the TimerOne library if you must use interrupts in your project.
http://code.google.com/p/arduino-timerone/downloads/list
Or
Just use the technique using millis() as in BlinkWithoutDelay example, for timing in your project.

Also this may be of some interest:

Alright....so I went and did some innovations. I think I got the right idea, but it's only outputting the last number...I have no idea why. Do you think you could guess what's wrong? Iam really stumped...

long n = 0;
int x = 100;
int del = 45;

int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int buttonState6 = 0;

int m = 1;
int mm = 0;
int s =5;
int ss = 9;

int m2 = 0;
int mm2 = 2;
int s2 =5;
int ss2 = 9;

int mode = 1;
void setup() {
  
  
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  
  //////////////////
  Serial.begin(9600);

  pinMode(ledPin, OUTPUT);      
 
   pinMode(pushButton1, INPUT);
  pinMode(pushButton2, INPUT);
 pinMode(pushButton3, INPUT);
pinMode(pushButton4, INPUT); 
pinMode(pushButton5, INPUT); 
pinMode(pushButton6, INPUT); 
}

void loop(){
  
  buttonState1 = digitalRead(pushButton1);
  buttonState2 = digitalRead(pushButton2);
  buttonState3 = digitalRead(pushButton3);
  buttonState4 = digitalRead(pushButton4);
  buttonState5 = digitalRead(pushButton5);
  buttonState6 = digitalRead(pushButton6);
  
  n++;
  
  if (digitalRead(13) == HIGH)
  {
    n = 0;
  }

/////////////////////////////
    delay(1000); 
  

   if (buttonState5 == HIGH && mode ==1) {
     
    mode=2;
    show2();
    
     } 
        else if (buttonState5 == HIGH && mode ==2) {
    mode=1;
    show1();
   
     }
    if (buttonState1 == HIGH) {     
      adjust1();
     } 
if (buttonState2 == HIGH) {     
      adjust2();
     } 
     if (buttonState3 == HIGH) {     
      adjust3();
     } 
     if (buttonState4 == HIGH) {     
      adjust4();
     } 

     if (buttonState6 == HIGH && mode == 1){//&& buttonState2 == HIGH) {     
      start();
     }
     if(buttonState6 == HIGH && mode == 2)
     {
       start2();
     }
  
  }
void adjust1(){
  m++;
  if(m==10)
  {m=0;}
   //digitalWrite(ledPin, HIGH);  

     char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m, mm, s,ss);
Serial.println(buffer);
     delay(1000); 
  
}


void adjust2(){
  mm++;
  if(mm==10)
 {mm=0;}
   digitalWrite(ledPin, HIGH);  

     char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m, mm, s,ss);
Serial.println(buffer);
    delay(1000); 
  
}

void adjust3(){
  s++;
  if(s==10)
  {s=0;}
   //digitalWrite(ledPin, HIGH);  

     char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m, mm, s,ss);

Serial.println(buffer);

     delay(1000); 
  
}
void adjust4(){
  ss++;
  if(ss==10)
  {ss=0;}
digitalWrite(ledPin, HIGH);  

     char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m, mm, s,ss);
Serial.println(buffer);
    delay(1000); 
  
}
////////////////////////////////////////////
void start()
{
  while(m >-1)
  {
    /////////////////////////
    
  clearLEDs();
  pickDigit(1);
  pickNumber((m)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(2);
  pickNumber((mm)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(3);
  dispDec(3);
  pickNumber((s)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(4);
  pickNumber((ss)%10);
  delayMicroseconds(del);
  
  n++;
  
  if (digitalRead(13) == HIGH)
  {
    n = 0;
  }   
    ///////////////////////
    delay(1000);
       char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m, mm, s,ss);
Serial.println(buffer);
  
  ss--;
  if(ss== -1)
  {
    s--;
    ss=9;
  }
  if(s==-1)
  {
    s=5;
    mm--;
  }
  if(mm==-1)
  {
    mm=9;
    m--;
  }
 if(m==-1)
  {
    Serial.println("game over");
  }
   if (buttonState5 == HIGH) {
    start2();
  }
  }
 }

/////////////////////////////

void start2()
{
  while(m2 >-1)
  {
    ////////////////////////
    
  clearLEDs();
  pickDigit(1);
  pickNumber((m2)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(2);
  pickNumber((mm2)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(3);
  dispDec(3);
  pickNumber((s2)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(4);
  pickNumber((ss2)%10);
  delayMicroseconds(del);
  
  n++;
  
  if (digitalRead(13) == HIGH)
  {
    n = 0;
  }
    ////////////////////////
    delay(1000);
       char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m2, mm2, s2,ss2);
Serial.println(buffer);
  
  ss2--;
  if(ss2== -1)
  {
    s2--;
    ss2=9;
  }
  if(s2==-1)
  {
    s2=5;
    mm2--;
  }
  if(mm2==-1)
  {
    mm2=9;
    m2--;
  }
 if(m2==-1)
  {
    Serial.println("game over");
  }
  }
}
/////////////////////////////
void show2()
{
  ////////////////////
  
  clearLEDs();
  pickDigit(1);
  pickNumber((m2)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(2);
  pickNumber((mm2)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(3);
  dispDec(3);
  pickNumber((s2)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(4);
  pickNumber((ss2)%10);
  delayMicroseconds(del);
  
  n++;
  
  if (digitalRead(13) == HIGH)
  {
    n = 0;
  }
////////////////
         char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m2, mm2, s2,ss2);
Serial.println(buffer);
    delay(1000);
}
void show1()
{
  //////////////
  clearLEDs();
  pickDigit(1);
  pickNumber((m)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(2);
  pickNumber((mm)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(3);
  dispDec(3);
  pickNumber((s)%10);
  delayMicroseconds(del);
  
  clearLEDs();
  pickDigit(4);
  pickNumber((ss)%10);
  delayMicroseconds(del);
  
  n++;
  
  if (digitalRead(13) == HIGH)
  {
    n = 0;
  }
    ///////////////////////
         char buffer[32];
snprintf(buffer, 32, "%u : %u : %u :%u", m, mm, s,ss);
Serial.println(buffer);
    delay(1000);
}
///////////////////////
void pickDigit(int x)
{
  digitalWrite(d1, LOW);
  digitalWrite(d2, LOW);
  digitalWrite(d3, LOW);
  digitalWrite(d4, LOW);
  
 switch(x)
  {
    case 1: digitalWrite(d1, HIGH); break;
    case 2: digitalWrite(d2, HIGH); break;
    case 3: digitalWrite(d3, HIGH); break;
    default: digitalWrite(d4, HIGH); break;
  }
}
void pickNumber(int x)
{
  switch(x)
  {
    default: zero(); break;
    case 1: one(); break;
    case 2: two(); break;
    case 3: three(); break;
    case 4: four(); break;
    case 5: five(); break;
    case 6: six(); break;
    case 7: seven(); break;
    case 8: eight(); break;
    case 9: nine(); break;
  }
}
void dispDec(int x)
{
//  digitalWrite(p, LOW);
}

void clearLEDs()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
 // digitalWrite(p, HIGH);
}
void zero()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}
void one()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void two()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}
void three()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}
void four()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void five()
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void six()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void seven()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}
void eight()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void nine()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void show()
{
}

Thanks! I left out some of the initialization stuff just fyi. It's the same as it always was.

I think the on-time, 45uS, is too short. Try 500, 1000, for 0.5mS to 1mS.