Basic Countdown Timer (no display, just an output after X time)

Hi guys, Im really new to arduino and have only made a single project which used an Arduino. I am again stuck as it has been so long! I have essentially forgotten everything and I know what I am trying to do is very basic! My aim is to activate a relay for 10 seconds, after a button is pressed and a delay which can be adjusted in the IDE and then quickly reprogrammed.
The process is: (Arduino power on) -> Wait (possibly cause an LED to flash at this stage?) -> Button press -> delay of (e.g.)60 seconds (beep a piezo buzzer?) -> Relay on for 10 seconds (constant buzzer?) -> End (It would be good if pressing the button again at any point would disable and reset the timer)
Thanks, Id really appreciate any help! Just as background info - this is for a prototype release mechanism for a CANSAT (a model satellite which will fit in a 330ml soft drinks can, collect and send data (such as air pressure, temperature, GPS data and pollution levels) over the air while being carried by a weather balloon).

How would YOU perform this task, given a pencil and some paper (the equivalent of variables on the Arduino) and a watch (the equivalent of millis() on the Arduino)?

The demo several things at a time may give you some ideas.

...R

PaulS:
How would YOU perform this task, given a pencil and some paper (the equivalent of variables on the Arduino) and a watch (the equivalent of millis() on the Arduino)?

While I appreciate the reply, I'm not sure that I quite understand your analogy... Currently the only way I can think of to 'demosnstrate' my idea, is as a flowchart type of diagram. Sorry!

Robin2:
The demo several things at a time may give you some ideas.

…R

Thanks, I’ve just had a quick look through the sketch and not a lot stands out, but I’ll be sure to check again later (after I finsh work!)

Stanmore95:
is as a flowchart type of diagram. Sorry!

A flowchart is a good idea.

I had posted the other link because I thought you were a bit further advanced in your planning.

This Thread Planning and Implementing a Program starts with an "English" description of the activities and may provide some ideas. It uses a similar approach to several things at a time.

...R

For your sketch you could use something like this

int relayPin=10;//pick a pin, any pin
int LEDPin=13;//I think this is the onboard LED
int buttonPin=12;//or whatever

void setup()
{
pinMode(relayPin,OUTPUT);
digitalWrite(relayPin,LOW);
pinMode(LEDPin,OUTPUT);
digitalWrite(LEDPin,LOW);
delay(5000);//wait 5 seconds(I don't know why);
digitalWrite(LEDPin,HIGH);
pinMode(buttonPin,INPUT_PULLUP);
digitalWrite(LEDPin,LOW);
}

byte currentState=0;//0 waiting
                    //1 triggered but may abort
                    //2 buzzing
                    
//allow 60 seconds to abort before firing relay
unsigned long int abortTime=60000;
unsigned long int buzzerDuration=10000;
unsigned long int lastPress;


void loop()
{
bool buttonState=digitalRead(buttonPin);
 if(!buttonState)//active low
    {currentState=(currentState>0)? 0:1;
     lastPress=millis();
     delay(100);//allow user time to remove finger
   }
   
//keep LED alight if still waiting for input
digitalWrite(LEDPin,(currentState)? LOW:HIGH);

if((currentState==1)&&
   ((millis()-lastPress)> abortTime))
     {
     currentState++;
     lastPress=millis();
     }
     
if (currentState==2)//buzzer sounding
  if ((micros()-lastPress)>buzzerDuration)
     currentState=0;  
   digitalWrite(relayPin,(currentState==2)? HIGH:LOW);
}

KenF:
For your sketch you could use something like this

int relayPin=10;//pick a pin, any pin

int LEDPin=13;//I think this is the onboard LED
int buttonPin=12;//or whatever

void setup()
{
pinMode(relayPin,OUTPUT);
digitalWrite(relayPin,LOW);
pinMode(LEDPin,OUTPUT);
digitalWrite(LEDPin,LOW);
delay(5000);//wait 5 seconds(I don't know why);
digitalWrite(LEDPin,HIGH);
pinMode(buttonPin,INPUT_PULLUP);
digitalWrite(LEDPin,LOW);
}

byte currentState=0;//0 waiting
                   //1 triggered but may abort
                   //2 buzzing
                   
//allow 60 seconds to abort before firing relay
unsigned long int abortTime=60000;
unsigned long int buzzerDuration=10000;
unsigned long int lastPress;

void loop()
{
bool buttonState=digitalRead(buttonPin);
if(!buttonState)//active low
   {currentState=(currentState>0)? 0:1;
    lastPress=millis();
    delay(100);//allow user time to remove finger
  }
 
//keep LED alight if still waiting for input
digitalWrite(LEDPin,(currentState)? LOW:HIGH);

if((currentState==1)&&
  ((millis()-lastPress)> abortTime))
    {
    currentState++;
    lastPress=millis();
    }
   
if (currentState==2)//buzzer sounding
 if ((micros()-lastPress)>buzzerDuration)
    currentState=0;  
  digitalWrite(relayPin,(currentState==2)? HIGH:LOW);
}

THANKS! That looks excellent! I have not yet tested (or indeed built!) the circuit/sketch combiation, but that is likely to be tomorrow or the day after and should pose no issues! Two questions to follow though, 1, I see mention of the 'buzzer', but no pin assigned to a buzzer, only the relay, LED an button. And 2, when you say "could", how likely is that :wink:

I see mention of the 'buzzer', but no pin assigned to a buzzer, only the relay,

Sorry I was treating Buzzer and Relay as interchangeable.
I thought you hadn't decided which to go with. :slight_smile:

KenF:
Sorry I was treating Buzzer and Relay as interchangeable.

Oh sorry, thats my fault, I should have made it clearer! As this is a prototype/demonstration piece, I wanted both an audio and visual indicator. This is because I plan to test this 'release method' via hanging the satellite below either a tethered balloon or a kite, for this reason an audible buzzer would be ideal to check for faults and to know when the circuit has powered off, but could be turned off with an inline switch for hands on testing when the led could be used alone.
The basic principle is the cord between the satellite and the balloon has a piece of thin nichrome wire wrapped around it, then at the correct altitude, the Arduino triggers the relay, which will provide power to the wire, heating it red hot, hence melting through the thin (but strong!) nylon cord. A parachute is automatically deployed and the satellite returns to earth!
The LED and buzzer could have the same on/off pattern, but I would like it so that:

  • Power is connected to Arduino (probably a Nano for this test) or RESET button is pressed.
  • Nothing happens until button is pressed.
  • Button is pressed to start countdown and warning
  • LED and buzzer oscillate on, for say 200ms, and off for 2000ms or so. This continues for 60000ms.
  • Relay is activated and buzzer/LED on continuous for 10000ms
  • Relay, LED and buzzer switch off and cannot be repeated until board loses power or is reset.

Well since you can have a switch to decide between the buzzer and/or LED, your new criteria could be filled along the following lines.

//Pin Assignments
int relayPin=10;
int LEDPin=13;//I think this is the onboard LED
int buttonPin=12;

//how much time to allow user to abort
unsigned long int abortTime=60000; //(60 seconds)

unsigned int relayHoldTime=10000;//time to hold relay on to cut the cord

byte currentState=0;//0 waiting
                    //1 triggered but may abort
                    //2 Shot our load


unsigned long int lastPress;



void setup()
{
pinMode(LEDPin,OUTPUT);
//Flash LED once to let user know it's turned on
digitalWrite(LEDPin,HIGH);
delay(1000);//wait 1 second(I don't know why);
digitalWrite(LEDPin,LOW);
pinMode(buttonPin,INPUT_PULLUP);

}


                    


void loop()
{
bool buttonState=digitalRead(buttonPin);
 if(!buttonState)//active low
  switch(currentState)
   {case 0: //toggle between waiting and triggered
   case 1:     
             currentState=1-currentState;
             lastPress=millis();            
             delay(400);//allow finger time to go away
  
  //any other state we ignore the keypress
   }
   
if(!currentState)
  {digitalWrite(relayPin,LOW);
   digitalWrite(LEDPin,LOW);
  }
  
if (currentState==1)
   doWarning();

//we don't need to worry about state 2
//as doDrop is called from doWarning at the appropriate time


}


//Will beep for 200 ms every 2 seconds
//for a duration of 60 seconds
void doWarning()
{
unsigned int WarningbeepDuration=200;
unsigned int WarningBeepPeriod=2000;

unsigned int patternWindow=millis() % WarningBeepPeriod;
bool onOrOff=(patternWindow < WarningbeepDuration);

digitalWrite(LEDPin,onOrOff);

if ((millis()-lastPress)>abortTime)
  doDrop();
}


//turn on relay AND LED for 10 seconds.

void doDrop()
{
digitalWrite(LEDPin,HIGH);
pinMode(relayPin,OUTPUT);
digitalWrite(relayPin,HIGH);
delay(relayHoldTime);
pinMode(relayPin,LOW);
digitalWrite(relayPin,LOW);
digitalWrite(LEDPin,LOW);
currentState=2;
}

KenF:
Well since you can have a switch to decide between the buzzer and/or LED, your new criteria could be filled along the following lines.

//Pin Assignments

int relayPin=10;
int LEDPin=13;//I think this is the onboard LED
int buttonPin=12;

//how much time to allow user to abort
unsigned long int abortTime=60000; //(60 seconds)

unsigned int relayHoldTime=10000;//time to hold relay on to cut the cord

byte currentState=0;//0 waiting
                   //1 triggered but may abort
                   //2 Shot our load

unsigned long int lastPress;

void setup()
{
pinMode(LEDPin,OUTPUT);
//Flash LED once to let user know it’s turned on
digitalWrite(LEDPin,HIGH);
delay(1000);//wait 1 second(I don’t know why);
digitalWrite(LEDPin,LOW);
pinMode(buttonPin,INPUT_PULLUP);

}

void loop()
{
bool buttonState=digitalRead(buttonPin);
if(!buttonState)//active low
 switch(currentState)
  {case 0: //toggle between waiting and triggered
  case 1:    
            currentState=1-currentState;
            lastPress=millis();            
            delay(400);//allow finger time to go away
 
 //any other state we ignore the keypress
  }
 
if(!currentState)
 {digitalWrite(relayPin,LOW);
  digitalWrite(LEDPin,LOW);
 }
 
if (currentState==1)
  doWarning();

//we don’t need to worry about state 2
//as doDrop is called from doWarning at the appropriate time

}

//Will beep for 200 ms every 2 seconds
//for a duration of 60 seconds
void doWarning()
{
unsigned int WarningbeepDuration=200;
unsigned int WarningBeepPeriod=2000;

unsigned int patternWindow=millis() % WarningBeepPeriod;
bool onOrOff=(patternWindow < WarningbeepDuration);

digitalWrite(LEDPin,onOrOff);

if ((millis()-lastPress)>abortTime)
 doDrop();
}

//turn on relay AND LED for 10 seconds.

void doDrop()
{
digitalWrite(LEDPin,HIGH);
pinMode(relayPin,OUTPUT);
digitalWrite(relayPin,HIGH);
delay(relayHoldTime);
pinMode(relayPin,LOW);
digitalWrite(relayPin,LOW);
digitalWrite(LEDPin,LOW);
currentState=2;
}

Thanks yet again! Again, I’ve not tested, but from what I can understand and from your comments, its still not quite what I’m after :frowning: I think I have entirely over complicated this… How about just a delay, so as soon as the Arduino powers up, the 60 second countdown begins. As soon as 60 seconds are up, the relay activates for 10 seconds, then powers off, end of until reset/power removed and applied again. I really do appreciate all your help!