# How do I count time in seconds?

I have a statement:

``````if(control > 100 && control < 130)
{

//count time 30 seconds and open pin1 for 3 seconds.

}
``````

How can I count 30 seconds and open a pin for 3 seconds?

• Arduino measures time in millis() and delay() and in milliseconds, so to convert counts of time in seconds to milliseconds would be 1000x. Feb 21 '16 at 19:39

A non-blocking version is often needed as there is often other tasks to be performed during the wait. The "blink-without-delay"-pattern is a solution but unfortunately it becomes tedious to use with several time periods and logic.

The Timemark library helps abstract the pattern and hide a lot of the details. The below sketch uses two timemarks and a simple state-machine to help reduce complexity.

``````#include <Timemark.h>

Timemark turnOnWait(30000L);
Timemark turnOffWait(3000L);

enum {
IDLE,
TURN_ON_WAIT,
TURN_OFF_WAIT
};
int state = IDLE;

const int pin = 4;
int control = 0;

void setup()
{
...
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}

void loop()
{
...
switch (state) {
case IDLE:
if ((control > 100) && (control < 130)) {
turnOnWait.start();
state = TURN_ON_WAIT;
}
break;
case TURN_ON_WAIT:
if (turnOnWait.expired()) {
digitalWrite(pin, HIGH);
turnOffWait.start();
state = TURN_OFF_WAIT;
}
break;
case TURN_OFF_WAIT:
if (turnOffWait.expired()) {
digitalWrite(pin, LOW);
state = IDLE;
}
break;
default:
;
}
...
}
``````

Two timemarks are used for clarity. It is possible to use a single timemark and reinitiate it with a new time limit.

``````#include <Timemark.h>

const uint32_t TURN_ON_TIMEOUT = 30000L;
const uint32_t TURN_OFF_TIMEOUT = 3000L;

Timemark timemark;

enum {
IDLE,
TURN_ON_WAIT,
TURN_OFF_WAIT
};
int state = IDLE;

const int pin = 4;
int control = 0;

void setup()
{
...
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}

void loop()
{
...
switch (state) {
case IDLE:
if ((control > 100) && (control < 130)) {
timemark.limitMillis(TURN_ON_TIMEOUT);
timemark.start();
state = TURN_ON_WAIT;
}
break;
case TURN_ON_WAIT:
if (timemark.expired()) {
digitalWrite(pin, HIGH);
timemark.limitMillis(TURN_OFF_TIMEOUT);
timemark.start();
state = TURN_OFF_WAIT;
}
break;
case TURN_OFF_WAIT:
if (timemark.expired()) {
digitalWrite(pin, LOW);
state = IDLE;
}
break;
default:
;
}
...
}
``````

The Scheduler library allows the blocking version (delay) to be used. Non-blocking is achieved by context switching on yield() or delay(). Below is a rewrite using this style:

``````#include <Scheduler.h>

const int pin = 4;
int control = 0;

void setup()
{
...
Scheduler.start(setupController, loopController);
}

void loop()
{
...
delay(1000);
}

void setupController()
{
...
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}

void loopController()
{
...
if ((control > 100) && (control < 130)) {
delay(30000L);
digitalWrite(pin, HIGH);
delay(3000L);
digitalWrite(pin, LOW);
}
else {
delay(100);
}
}
``````

Cheers!

What you can also use is non-blocking code, where `delay()` would block for the 30s. My suggesting makes use of `millis()`, one could say similar to blink without delay code example.

Here is an example of what you could place in the loop:

``````//declared variable stuff here

if(control > 100 && control < 130 && !toggled_bit){

toggled_bit = true;     //to control the timing section
start_time = millis();
}
else if (!(control > 100 && control < 130)){
toggled_bit = false;
}

if (toggled_bit){
test1 = millis()
if(test1 - start_time > 30000){

digitalWrite(1, HIGH);
short_wait = millis();
// wait for 3s after fist time
if(short_wait - start_time > 33000)
digitalWrite(1, LOW);
toggled_bit = false;
}
}
}

// other code here
``````

The code sets a 'flag', `toggled_bit`, which is checked by the `if()` later on in the loop, also it sets `start_time`. It then checks if 30s has passed and then waits an extra 3s to turn the output off after being turned on. It then resets the `toggled_bit`.

This will also allow you to check or do other things while waiting.

``````if(control>100 && control<130)
{
//**count time 30 seconds and open pin1 for 3 seconds.**
delay(30000);             // wait for 30 seconds
digitalWrite(1, HIGH);    // turn the LED on (HIGH is the voltage level)
delay(3000);              // wait for 3 seconds
digitalWrite(1, LOW);     // turn the LED off by making the voltage LOW
}
``````

Well 30s equals 30,000ms and the arduino comes with a native function that counts in Milliseconds so the following code should work:

``````Time = millis();  //time passed before entering loop…
If((control > 100) && (control < 130))
{
While (millis() < Time + 30000) //counts to Thirty seconds
{
While (millis() < Time + 3000) // counts to three seconds
{
DigitalWrite(1,HIGH);
};};};
``````

This way you can add some code in the while loops if u want to multitask.