Let a code wait for a certain time

Can anyone help me code this certain problem I'm having trouble with.

What I would like to happen is this:

Let us say that I have a variable "state1=0" and "state2 =0" and 2 sensors.

Sensor 1 is triggered ---> state1 = 1 -----> wait for at least 5 seconds -----> if sensor 2 is not triggered then turn state1 back to 0.

If sensor 2 is triggered within the given time (5 sec) ------> state2 = 1 ----> if state1 = 1 && state2 = 1 -----> total ++ -------> turn state1 and state2 back to 0.

The "waiting for at least 5 seconds" is the part that I am having trouble with and probably the part that I don't know how to code. Can anyone help me with this or luckily help me code this problem?

Watch this:

Read this:

Come back if you have problems.

consider



enum { Off = HIGH, On = LOW };

byte ledPin     = 13;

byte sensors [] = { A1, A2 };
#define N_SENSOR    sizeof(sensors)

byte sensorState [N_SENSOR];

#define Interval    5000

unsigned long msecTrig = 0;
int           count    = 0;
byte          state    = 0;

char s [80];

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);

    for (unsigned n = 0; n < N_SENSOR; n++)  {
        pinMode (sensors [n], INPUT_PULLUP);
        sensorState [n] = digitalRead (sensors [n]);
    }

    pinMode (ledPin, OUTPUT);
}

// -----------------------------------------------------------------------------
// check for sensor (button) event
int
chkSensors ()  {
    for (unsigned n = 0; n < N_SENSOR; n++)  {
        byte sensor = digitalRead (sensors [n]);

        // check for change in state
        if (sensorState [n] != sensor)  {
            sensorState [n] = sensor;

            if (On == sensor)  {    // check if active
                return n;
            }
        }
    }
    return -1;
};

// -----------------------------------------------------------------------------
void loop () {
    unsigned long msec = millis ();

    // check if armed and time expired
    if (state && (msec - msecTrig) > Interval)  {
        state = 0;
        count++;
        Serial.println (count);
    }

    switch (chkSensors ())  {
    case 1:
        state = 0;              // disarm
        break;

    case 0:
        state    = 1;           // arm
        msecTrig = msec;
        break;
    }

    digitalWrite (ledPin, ! state);
}

Here is a framework that only checks sensors every 5 sec and doesn't do any blocking.. Don't know about the rest of the stuff you want. But maybe this''ll help?

#include <timeObj.h>

timeObj  intervalTimer(5000);

void setup () {
    Serial.begin (9600);

    // Setup sensors..
}


// check the sensors..
int checkSensors ()  {
    // DO your sensor thing.
    Serial.println("Time to check!");
};


void loop (void) {

   if (intervalTimer.ding())  {  // If the timer has expired..
      checkSensors();           // Do your check stuff.
      intervalTimer.stepTime();  // reset the timer.
   }
}

You will need to grab LC_baseTools from the IDE library manager to compile this.

Good luck!

-jim lee

Thanks for the help and the different approaches. I'll work my way around it and I'll come back if ever I encounter problems.

Check out the example sketch for this in my tutorial on How to write Timers and Delays in Arduino
See the DelayExecution.ino example in the Delay execution until condition has been true for X secs section.

Also check out my tutorial on Multi-tasking in Arduino for re-forming your sketch as a series of tasks
multitaskingDiagramSmall

Help as I was trying to apply what I have learned reading about millis(). I have encountered this problem that even the if statement is not true parts of logic is being executed here is my code.

#define trig_1 2
#define echo_1 3
#define trig_2 4
#define echo_2 5

int interval(5000);

float d_1, d_2;
int control1 = 0, control2 = 0;

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  unsigned long currentMillis = millis();
  long sensor1_Time;
  
  sensor(trig_1, echo_1, d_1);
  delay(30);
  sensor(trig_2, echo_2, d_2);
  delay(30);

  if(d_1 <= 12)
  {
    sensor1_Time = currentMillis;
    control1 = 1;
  }
  
  Serial.print(currentMillis);
  Serial.print("  sensor time: ");
  Serial.print(sensor1_Time);
  Serial.print("  control1: ");
  Serial.println(control1);
}
void sensor(int trig, int echo, float &distance)
{
  float duration;
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);

  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delay(5);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);
  distance = (0.013464 * duration) / 2; //distance in inches
}

once I try uploading the code, from the if statement "if(d_1 <= 12)" even if it is not true "control1 = 1" is executed. resulting to this in the serial monitor

0  sensor time: 0  control1: 1
1453  sensor time: 0  control1: 1
1549  sensor time: 0  control1: 1
1645  sensor time: 0  control1: 1
1741  sensor time: 0  control1: 1
1838  sensor time: 0  control1: 1
1934  sensor time: 0  control1: 1
2030  sensor time: 0  control1: 1
2126  sensor time: 0  control1: 1
2223  sensor time: 0  control1: 1

Initially control1 = 0 but here as you can see even the if statement is not true control1 value is changed to 1. When I tried making the if statement true the following are the result from the serial monitor

9195  sensor time: 9195  control1: 1
9282  sensor time: 9195  control1: 1
9378  sensor time: 9195  control1: 1
9475  sensor time: 9195  control1: 1

You can see here that the if statement is working properly because when it became true the currentMillis values are stored in the sensor1_Time variable. My problem is that the "control1" value is changed even when the if statement is false can anyone help me with this so that I can continue trying what I have started? Thanks.

Try printing the value of d_1.

@wildbill

the value of d_1 below

0  sensor time: 0  control1: 1  d_1: 0.00
1453  sensor time: 0  control1: 1  d_1: 70.49
1550  sensor time: 0  control1: 1  d_1: 69.70
1646  sensor time: 0  control1: 1  d_1: 69.70
1742  sensor time: 0  control1: 1  d_1: 69.66

and when I make the if statement true, here are the results

3288  sensor time: 3288  control1: 1  d_1: 7.12
3375  sensor time: 3375  control1: 1  d_1: 5.62
3462  sensor time: 3462  control1: 1  d_1: 4.89
3549  sensor time: 3549  control1: 1  d_1: 2.54
3635  sensor time: 3635  control1: 1  d_1: 2.57
3722  sensor time: 3722  control1: 1  d_1: 3.08

There's nothing in your code that sets control_1 to anything but 1. If it ever gets set to 1, it will never change - as you observe.

I think I found the problem the initial value of d_1 at start up is 0.00 making the if statement true.

Sorry for the multiple questions but I have encountered yet another problem with millis()
as you can see my current code for now is this

#define trig_1 2
#define echo_1 3
#define trig_2 4
#define echo_2 5

int interval(5000);

float d_1, d_2;
int control1 = 0, control2 = 0;

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  unsigned long currentMillis = millis();
  unsigned long sensor1_Time;
  
  sensor(trig_1, echo_1, d_1);
  delay(30);
  sensor(trig_2, echo_2, d_2);
  delay(30);

  if(d_1 <= 12 && d_1 != 0)
  {
    sensor1_Time = currentMillis;
    control1 = 1;
    if(currentMillis - sensor1_Time >= interval)
    {
      control1 = 0;
    }
  }
  
  Serial.print(currentMillis);
  Serial.print("  sensor time: ");
  Serial.print(sensor1_Time);
  Serial.print("  control1: ");
  Serial.print(control1);
  Serial.print("  d_1: ");
  Serial.println(d_1);
}
void sensor(int trig, int echo, float &distance)
{
  float duration;
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);

  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delay(5);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);
  distance = (0.013464 * duration) / 2; //distance in inches
}

When I uploaded the code the serial monitor prints this

0  sensor time: 285541121  control1: 0  d_1: 0.00
1454  sensor time: 285541121  control1: 0  d_1: 69.70
1550  sensor time: 285541121  control1: 0  d_1: 69.60
1647  sensor time: 285541121  control1: 0  d_1: 69.64
1744  sensor time: 285541121  control1: 0  d_1: 69.04
1841  sensor time: 285541121  control1: 0  d_1: 69.03
1938  sensor time: 285541121  control1: 0  d_1: 69.80

I don't know why my sensor time is printing that value. but when I make the if statement true this is what I get from the serial monitor

3486  sensor time: 3486  control1: 1  d_1: 8.76
3574  sensor time: 3574  control1: 1  d_1: 6.02
3661  sensor time: 3661  control1: 1  d_1: 4.35
3748  sensor time: 3748  control1: 1  d_1: 2.38
3834  sensor time: 3834  control1: 1  d_1: 3.46
3921  sensor time: 3921  control1: 1  d_1: 4.75
4007  sensor time: 3921  control1: 1  d_1: 70.00
4105  sensor time: 3921  control1: 1  d_1: 69.19
4201  sensor time: 3921  control1: 1  d_1: 69.04
4297  sensor time: 3921  control1: 1  d_1: 69.65
4395  sensor time: 3921  control1: 1  d_1: 69.03
4491  sensor time: 3921  control1: 1  d_1: 69.18
4587  sensor time: 3921  control1: 1  d_1: 69.03
4683  sensor time: 3921  control1: 1  d_1: 68.99
4781  sensor time: 3921  control1: 1  d_1: 69.04
4877  sensor time: 3921  control1: 1  d_1: 69.20
4973  sensor time: 3921  control1: 1  d_1: 69.20
5069  sensor time: 3921  control1: 1  d_1: 68.99
5167  sensor time: 3921  control1: 1  d_1: 69.19
5263  sensor time: 3921  control1: 1  d_1: 69.20
5359  sensor time: 3921  control1: 1  d_1: 69.37
5455  sensor time: 3921  control1: 1  d_1: 69.20
5553  sensor time: 3921  control1: 1  d_1: 69.04
5649  sensor time: 3921  control1: 1  d_1: 69.03
5745  sensor time: 3921  control1: 1  d_1: 69.02
5841  sensor time: 3921  control1: 1  d_1: 69.03
5939  sensor time: 3921  control1: 1  d_1: 69.03
6035  sensor time: 3921  control1: 1  d_1: 69.53
6131  sensor time: 3921  control1: 1  d_1: 68.87
6228  sensor time: 3921  control1: 1  d_1: 68.87
6325  sensor time: 3921  control1: 1  d_1: 69.20
6421  sensor time: 3921  control1: 1  d_1: 69.70
6517  sensor time: 3921  control1: 1  d_1: 68.98
6615  sensor time: 3921  control1: 1  d_1: 69.03
6711  sensor time: 3921  control1: 1  d_1: 69.35
6807  sensor time: 3921  control1: 1  d_1: 69.03
6903  sensor time: 3921  control1: 1  d_1: 69.69
7001  sensor time: 3921  control1: 1  d_1: 69.19
7097  sensor time: 3921  control1: 1  d_1: 68.84
7193  sensor time: 3921  control1: 1  d_1: 69.69
7290  sensor time: 3921  control1: 1  d_1: 69.02
7387  sensor time: 3921  control1: 1  d_1: 69.03
7483  sensor time: 3921  control1: 1  d_1: 69.03
7580  sensor time: 3921  control1: 1  d_1: 69.69
7676  sensor time: 3921  control1: 1  d_1: 68.85
7773  sensor time: 3921  control1: 1  d_1: 69.03
7869  sensor time: 3921  control1: 1  d_1: 68.81
7966  sensor time: 3921  control1: 1  d_1: 69.18
8062  sensor time: 3921  control1: 1  d_1: 69.70

As you can see it registered the current time value of the millis(); but I don't know why at start it was showing those large numbers. Another problem is that even though it has reached my interval which is int interval(5000); the control1 value does not return back to 0. I can't manage to find where I got it wrong. can anyone yet help me again please?

Update on my code/ project. Everything is working fine now. Thanks to you guys I have made my code and sensors less buggy. Thanks for all of your help I appreciate it a lot. :grinning_face_with_smiling_eyes: