Best and easiest way to countdown

Hi everyone!

As the subject says I'm looking for an easy (maybe also affordable) and effettive way to countdown with my Arduino.

I'm developing an Arduino powered laser tag system. I need my Arduino to count down from 10-20-30 or other minutes. When the timer stops I need my Arduino to do an action like playing a sound and writing data on a lcd display or something similar. At first I taught that using a Rtc module like the ds1307 could do the job but then I realised that it's not a good way to deal with.

I also need to use this timer for scheduling reasons:

Since I need to transmit data from an Arduino to another, via radio transmission (433) and I have to avoid that other Arduino are transmitting at the same time, I taught that using this timer and tell the Arduino to transmit, for example every 2 minutes, could be good.

So... Problem is that I attually don't know how to do this without making my Arduino busy all time. I need it to be ready to receive strings via ir and react with other random events.

Oops I forgot... I'm using an Arduino Mega with AtMega 2560.

Do you guys think it's a programming trick or do you think (like me) that an ic is mandatory (like a timer or? I don't know which one)?

Please I need your advices. All suggestions are accepted.

Thank you

Programming a countdown timer is trivial. Doing it without blocking is trivial. See the Blink Without Delay example for some inspiration on timing things without blocking.

Or here's some code I wrote for someone else that might inspire you. Give it a try and we'll help you get it right.

another implementation - https://github.com/RobTillaart/Arduino/tree/master/libraries/CountDown

Thanks a lot, guys :) I will try soon both the solutions you posted.

About the i.c. is there a specific i.c. that could do the job and tell the Arduino when it's time to do something? I mean when the time is up.

Thanks again :)

Some real time clock chips have alarms that will toggle a pin at a certain time. But from what you describe you shouldn't need such a thing.

Hi guys,

first I would like to thank you very much because you gave me the exact type of code I was looking for. They both works like a charm but I decided to use the one from Delta_G since it’s lighter and more suitable for me.

Actually I have been trying to develop some functions able to do this kind of things:

  • Set a timer when a code is received via 433 MHz (a code that contains the number of minutes that inizialize the timer
  • Pause the timer without resetting the countdown
  • Add some time (e.g. +5 min, again from a radio code containing the amount of minutes to add)
  • reset the timer

I’ve adapted the code in order to remove things I don’t need like hours and days, here it is:

#define SEC_PER_MIN (60)
#define SEC_PER_HOUR (60ul * 60)

unsigned long countdownTime = 0;

void setup(){  
  Serial.begin(9600);
  delay(20);
  Serial.println(F("Enter Minutes"));
  int minutes = getInputFromUser();
  Serial.println(F("Enter Seconds"));
  int seconds = getInputFromUser();
  
  countdownTime = seconds + (minutes * SEC_PER_MIN); 
}

void loop(){
  
  static unsigned long lastTick = millis();  
  unsigned long currentMillis = millis();
  
//  Way more accurate timing this way than with delay
//  Also allows for code to do other things during countdown
  if (currentMillis - lastTick >= 1000){
    lastTick += 1000;
    countdownTime--;
    displayTime(countdownTime);
  }
  
  if (countdownTime == 0){
    Serial.println(F("Countdown Finished"));
    while(1);  // infinite loop...  lock up program until reset
  }  
}

// blocks program for input from user via serial
// returns the number entered as an int
int getInputFromUser(){
  char buf[5];
  int index = 0;
  while(Serial.available() < 1);  // DO nothing until serial arrives
  
  buf[index] = Serial.read();
  
  while (buf[index] != '\n'){
    if(Serial.available()){
      buf[++index] = Serial.read();
    }
    //  Don't run over the end of buf
    if (index == 4){
      buf[index] = '\n';
      break;
    }
  }
  // Received a null, Serial transmission is over  
  return atoi(buf);
}


//Prints time to serial in D:H:M:S format  

void displayTime(unsigned long aTime){
  int seconds = aTime % SEC_PER_MIN;
  int minutes = (aTime % (SEC_PER_HOUR)) / SEC_PER_MIN;
  
  Serial.println(F("tick"));
  Serial.print(F(" : "));
  Serial.print(minutes);
  Serial.print(F(" : "));
  Serial.println(seconds);
}

Again, problem is that I don’t know how to make my Arduino, using this code, count every X minutes (e.g. 2 minutes) and do a mySwitch.send(code,24); in order to send data every X minutes to the Control Base Arduino. I need to do this timing in order not to have packet collisions since every rifle must send data to the base without interfering with others (I taught that maybe giving a different seconds amount for every rifle should be good).

Here is the code that I’m using to send data via radio (433 MHz), powered by the RcSwitch Library:

/*
  Example for different sending methods
  
  http://code.google.com/p/rc-switch/
  
*/

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {

  Serial.begin(9600);
  
  // Transmitter is connected to Arduino Pin #10  
  mySwitch.enableTransmit(10);

  // Optional set pulse length.
  // mySwitch.setPulseLength(320);
  
  // Optional set protocol (default is 1, will work for most outlets)
  // mySwitch.setProtocol(2);
  
  // Optional set number of transmission repetitions.
  // mySwitch.setRepeatTransmit(15);
  
}

void loop() {
  /* Same switch as above, but using decimal code */
  mySwitch.send(123456, 24);
}

Could you please tell me the correct way to do these kind of things?

Thanks again, guys.