getting delay in count down timer...

i am using count down timer for my function ...

here is the code.. i am getting some delay in this timer...plz help me

unsigned long previousMillis = 0;
unsigned long interval = 1000;
unsigned long count_down = 300;
unsigned long hours;
unsigned long mins;
unsigned long seconds;
byte hold = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long currentMillis = millis();//one second into timers
  if (currentMillis - previousMillis > interval) {
    if (hold != 1) {
      count_down--;
    }
    previousMillis = currentMillis;
  }

  hours = count_down / 3600;
  mins = ((count_down % 3600) / 60);
  seconds = ((count_down % 3600) % 60);

  if ((hours == 0) && (mins == 0) && (seconds == 0)) {
    Serial.println (" done ");
    hold = 1;
  }
  else {
    if (hours < 10) {
      Serial.print(" ");
    }
    Serial.print (hours);
    Serial.print (":");
    if (mins < 10) {
      Serial.print("0");
    }
    Serial.print (mins);
    Serial.print (":");
    if (seconds < 10) {
      Serial.print("0");
    }
    Serial.println (seconds);
  }
}

Why are you updating the display every time through "loop()"?

..plz help me

The word is spelled "please"

Indeed, printing it every loop looks a bit pointless.

If you do things multiple times it's time to make a function :wink:

unsigned long previousMillis = 0;
const unsigned int Interval = 1000;
unsigned int countDown = 300;  //stick to one way of naming your variables

byte hold = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (hold != 1) {  
    if (millis() - previousMillis > Interval) {
      countDown--;
      previousMillis = millis();
      
      byte seconds = countDown % 60;
      countDown /= 60;
      byte minutes = countDown % 60;
      byte hours = countDown / 60;

      if ((hours == 0) && (minutes == 0) && (seconds == 0)) {
        Serial.println (" done ");
        hold = 1;
      }
      else {
        serialPrintTime(hours, minutes, seconds);
      }
    }
  }
}

void serialPrintLeading(byte value, char lead = '0'){
  if(value < 10){
    Serial.print(lead);
  }
  Serial.print(value);
}

void serialPrintTime(byte h, byte m, byte s){
  serialPrintLeading(h, ' ');
  Serial.print(':');
  serialPrintLeading(m);
  Serial.print(':');
  serialPrintLeading(s);
  Serial.println();
}

I don't really care he says plz but for the sake of it use caps!

void serialPrintLeading(byte value, char lead = '0'){
  if(value < 10){
    Serial.print(lead);
  }
  Serial.print(value);
}

Will this work?

Why do you make "lead" a parameter? What are you passing to it when you call it?

aarg:
Why do you make "lead" a parameter? What are you passing to it when you call it?

The leading character, either '0' or ' ' (the numeral zero or else a space).

By the way, what does Serial.print() do when you pass it a byte without specifying a base?

For example, something like:

byte myFifty = 50;
Serial.print("Here --> ");
Serial.print(myFifty);
Serial.println(" <-- should be the number fifty");

What do you get?
(Somebody please test this; I don't have an Arduino handy, but I suspect that the number that comes out will not be 50.)

If you want me to test something, you have to give me a complete sketch, clickable.

aarg:
If you want me to test something, you have to give me a complete sketch, clickable.

I'm odometer, not clickable.

Anyway, try this:

void setup() {
  Serial.begin(9600); // or whatever speed you prefer
    
  byte myFifty = 50;
  Serial.print("Here --> ");
  Serial.print(myFifty);
  Serial.println(" <-- should be the number fifty");
}

void loop() {
  // this is only here to make the Arduino compiler happy
}

@septillion thank you very much..

i use this but it did not decrements it print values like this.

print this.png

Nilanj:
it print values like this.

What is "it"?

Post your code.

@septillion:

You've a bug in your code.

      countDown--;
      previousMillis = currentMillis;
      
      byte seconds = countDown % 60;
      countDown /= 60;  // this line has the bug
      byte minutes = countDown % 60;
      byte hours = countDown / 60;

In your calculation of minutes and hours, you are changing the value of countDown. This is a bug because you will need countDown for later. And this is what was causing Nilanj to see the funny output he got.

@odometer, dohhhhh, thanks for spotting that! Just quickly wrote the code without an Arduino connected :stuck_out_tongue:

Fixed code:

unsigned long previousMillis = 0;
const unsigned int Interval = 1000;
unsigned int countDown = 10;  //stick to one way of naming your variables

byte hold = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (hold != 1) {  
    if (millis() - previousMillis > Interval) {
      previousMillis = millis();
      countDown--;
      
      
      unsigned int temp = countDown;
      byte seconds = temp % 60;
      temp /= 60;
      byte minutes = temp % 60;
      byte hours = temp / 60;

      if ((hours == 0) && (minutes == 0) && (seconds == 0)) {
        Serial.println (" done ");
        hold = 1;
      }
      else {
        serialPrintTime(hours, minutes, seconds);
      }
    }
  }
}

void serialPrintLeading(byte value, char lead = '0'){
  if(value < 10){
    Serial.print(lead);
  }
  Serial.print(value);
}

void serialPrintTime(byte h, byte m, byte s){
  serialPrintLeading(h, ' ');
  Serial.print(':');
  serialPrintLeading(m);
  Serial.print(':');
  serialPrintLeading(s);
  Serial.println();
}

Printing byte muByte = 50 will just print 50 on the screen (so the ASCII "50" aka 0x35 0x30)

@aarg, it's the option to pass a leading character. For minutes and seconds you want the default 0 but TS did a space for the hours. This way you can do that. If you want to extend it you can also use make the width a parameter but is to complicated for this purpose alone.

void serialPrintLeading(int value, char lead, byte width){
  int temp = value;
  byte valWidth = 0;
  
  //get width of the value
  while(temp){
    valWidth++;
    temp /= 10;
  }
  
  //add another place for the sign
  if(value < 0){
    valWidth++;
    if(lead == '0'){
      Serial.print('-');
      value = abs(value);
    }
  }
  
  //width becomes width of white space, 
  //if value is wider (or as width) no spaces (but don't crop)
  if(valWidth <= width){
    width -= valWidth;
  }
  else{
    width = 0;
  }
  
  //print leading chars
  while(width){
    Serial.print(lead);
    width--;
  }
  
  //and the value
  Serial.print(value);
}

@AWOL, although a post of text would have been easier he included a image just fine...

@AWOL, although a post of text would have been easier he included a image just fine...

The picture was of a screen of output.

I wanted to see his/her code

He was talking about running my code so posting it again would have been quite useless...

septillion:
He was talking about running my code so posting it again would have been quite useless...

I never assume that the code the person is running is the code that they think is running.

That's why I want to see their code.

@septillion, here is the output from your code:

0:00:09
 0:00:08
 0:00:07
 0:00:06
 0:00:05
 0:00:04
 0:00:03
 0:00:02
 0:00:01
 done

There is an approximately one second delay between line prints.