range delay

hi, i want to ask about the code which is delay range.

if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
    if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
    reset();
    } else {
    reset();
    loop();
    }  
  }

i want to add delay in second if, but the delay i want is range delay.
example when delay between 100ms - 200ms if the second if code active they do something.

sorry if my english is bad. help me please..

Can you please explain more clearly what you want to do and please post all of your code as it is now.

Whatever you want to do it is unlikely that you shoud call the loop() function as you do if you are using the Arduino IDE.

what i want to do is i want to make phone call code using DTMF decoder and Arduino. and i want add range delay in the second if code. so that second if code active when in the range delay. here my full code

// PROGRAM VARIABLES
int Q4 = 2;
int Q3 = 3;
int Q2 = 4;
int Q1 = 5;
int tow = 6;
int tombol = 7;
int relay = 8;
int dtmf;
void setup() {
pinMode(Q4, INPUT); //Q4
pinMode(Q3, INPUT); //Q3
pinMode(Q2, INPUT); //Q2
pinMode(Q1, INPUT); //Q1
pinMode(tombol, INPUT); //tombol
pinMode(relay, OUTPUT); //relay
pinMode(tow, INPUT); //tow
}
// DISPLAY DATA FROM DTMF DECODER
void loop() {
if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
    if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
    reset();
    } else {
    reset();
    loop();
    }  
  }
  if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == HIGH) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH)) {
    if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == HIGH) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH)){
      reset();
    } else {
      reset();
      loop();
    }
      if ((digitalRead(Q4) == HIGH) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == HIGH) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH)) {
        reset();
        loop();
      }
  }
  if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == HIGH) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
    if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == HIGH) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
      reset();
      delay(300);
      reset();
    } else {
      reset();
      loop();
   }
  }
  if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == HIGH) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH)) {
    if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == HIGH) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH)) {
      reset();
    } else {
      reset();
      loop();
      if ((digitalRead(Q4) == HIGH) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == HIGH) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH)) {
         }
              else {
              reset();
              loop();
              }
        if ((digitalRead(Q4) == HIGH) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == LOW) && (digitalRead(tow) == HIGH))  {
             }
              else {
              reset();
              loop();
              }
          if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
             }
              else {
              reset();
              loop();
              }
            if ((digitalRead(Q4) == HIGH) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH) ) {
             }
              else {
              reset();
              loop();
              }  
  }
  }
  if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == HIGH) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) {
    reset();
    loop();
  } else {
    reset();
    loop();
  }
  if (digitalRead(tombol) == HIGH) {
    loop();
  } 
}
void reset() {
    digitalWrite(relay, HIGH);
    delay(100);
    digitalWrite(relay, LOW);
}

hope you can understand my bad explanation in english

You really should not be calling "loop()" recursively like that - you'll run out of stack very quickly.
Your code needs a major restructure.

what should i do then? where i must restructure? so that second if not skipped before i put the input

As a first attempt, I'd just remove all the calls to "loop"

i put loop(); in there for safety. so if user wrong make input it will back to the top and user need input the "code" again.

what i need now code for range delay for my if code so the second if and the next if not skipped because user late to make input. so i want make interval delay for user make input.

ps: "code" refer to code for make call using phone

i put loop(); in there for safety

But you achieved the opposite - the calls to loop make your code less safe.
loop gets called again when it returns, which is one reason it is called "loop"

so,if i delete all loop(); is the code will automatically back to the top? not execute the next line?

It will execute the next line, but if the next line is an implicit or explicit "return", all will be well.

What do you mean explisit or implisit return? Is in my code there is implisit or explisit return?

In the code in reply #2, there are no explicit "return"s.
It looks like if you replaced the calls to "loop();" with "return;", you'd probably be close to where you want to be.
Use of auto format would make your code easier to follow.

Oh.. i see.. so first thing i need to do is change all "loop();" with "return;" ?

Yes, then explain exactly what you want to do with your 'range delay'
Is it that the user must press the keys associated with the second if within a certain time ?

  if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH)) 
  {
    if ((digitalRead(Q4) == LOW) && (digitalRead(Q3) == LOW) && (digitalRead(Q2) == LOW) && (digitalRead(Q1) == HIGH) && (digitalRead(tow) == HIGH) && theUserPressedorReleasedTheKeysSoonEnough == true) 
    {
      reset();
    } 
    else 
    {
      reset();
      return;
    }  
  }

Note that I have formatted your code differently as personally I find it easier to read that way, particularly when using nested if/else.

Your code would be much simpler if you refactored it.
It looks to me like all conditions depend on "tow" being HIGH, so test that first, then your tone inputs, then read all the tone inputs in one go into variables, or better still, bit-packed into a single variable.
Spreading code across the page with repeated digitalReads is hard to read.

ok i already change it all.. and sorry for that. maybe its much simple if i put my second code in here.

// PROGRAM VARIABLES
int dtmf;
String dial(16);

void setup() {
dial = "";

// CM8870 BINARY INPUT PORT
pinMode(2, INPUT); //Q4
pinMode(3, INPUT); //Q3
pinMode(4, INPUT); //Q2
pinMode(5, INPUT); //Q1
pinMode(7, INPUT); //tombol
pinMode(8, OUTPUT); //relay

// CM8870 BINARY DATA VALID PIN
pinMode(6, INPUT); //tow

}

// DISPLAY DATA FROM DTMF DECODER
void loop() {
  check();
  if (dtmf == 4) { //2
    check();
    if (dtmf == 8) { //1
    reset();
      }
      else {
       reset();
       return;
      }
  }
  check();
  if (dtmf == 12) { //3
    check();
    if (dtmf == 8) { //1
      reset();
    } else {
      reset();
      return;
    }
    check();
      if (dtmf == 5) { //0
        reset();
        return;
      }
    }
  check();
  if (dtmf == 2) { //4
    check();
    if (dtmf == 8) { //1
      reset();
      delay(500);
      reset();
    }
    else {
      reset();
      return;
    }
  }
  if (digitalRead(7) == HIGH) {
    reset();
    return;
  }

}
  
void reset() {
    digitalWrite(8, HIGH);
    delay(100);
    digitalWrite(8, LOW);
}

void check() {
  // WAIT FOR DATA VALID SIGNAL
if (digitalRead(6) == HIGH) {
// DECODE CM8870 DATA
dtmf = 0;
if (digitalRead(2) == HIGH) dtmf = dtmf + 1;
if (digitalRead(3) == HIGH) dtmf = dtmf + 2;
if (digitalRead(4) == HIGH) dtmf = dtmf + 4;
if (digitalRead(5) == HIGH) dtmf = dtmf + 8;
}
}

the different is there only 3 main if not 4 main if like first code.

what i want to do with my range delay is like you said UKHeliBob. because i'm afraid the user not press the key in time which is make the code skipped

hi i got from google about "millis();" code. and i applied it in my code. but i dont know it is right or not. and i dont know when its active or when its stop counting. is it always counting until its reach the max?
here my new code

// PROGRAM VARIABLES
int dtmf;
long previousMillis = 0;
long interval = 200;
unsigned long currentMillis = millis();
String dial(16);

void setup() {
dial = "";

// CM8870 BINARY INPUT PORT
pinMode(2, INPUT); //Q4
pinMode(3, INPUT); //Q3
pinMode(4, INPUT); //Q2
pinMode(5, INPUT); //Q1
pinMode(7, INPUT); //tombol
pinMode(8, OUTPUT); //relay

// CM8870 BINARY DATA VALID PIN
pinMode(6, INPUT); //tow

}

// DISPLAY DATA FROM DTMF DECODER
void loop() {
  jeda();
  if (dtmf == 4) { //2
    jeda();
    if (dtmf == 8) { //1
    reset();
      }
      else {
       reset();
       return;
      }
  }
  jeda();
  if (dtmf == 12) { //3
    jeda();
    if (dtmf == 8) { //1
      reset();
    } else {
      reset();
      return;
    }
    jeda();
      if (dtmf == 5) { //0
        reset();
        return;
      }
    }
  jeda();
  if (dtmf == 2) { //4
    jeda();
    if (dtmf == 8) { //1
      reset();
      delay(500);
      reset();
    }
    else {
      reset();
      return;
    }
  }
  if (digitalRead(7) == HIGH) {
    reset();
    return;
  }

}
  
void reset() {
    digitalWrite(8, HIGH);
    delay(100);
    digitalWrite(8, LOW);
}
void jeda(){
if(previousMillis <= currentMillis <= interval){
  check();
} else if(currentMillis == interval) {
  reset();
  return;
}
}
void check() {
  // WAIT FOR DATA VALID SIGNAL
if (digitalRead(6) == HIGH) {
// DECODE CM8870 DATA
dtmf = 0;
if (digitalRead(2) == HIGH) dtmf = dtmf + 1;
if (digitalRead(3) == HIGH) dtmf = dtmf + 2;
if (digitalRead(4) == HIGH) dtmf = dtmf + 4;
if (digitalRead(5) == HIGH) dtmf = dtmf + 8;
} else if(digitalRead(6) == LOW){
  check();
}
}
if(previousMillis <= currentMillis <= interval)

Have you ever seen a construct like that before?
There's a good reason why you haven't.

no, i havent. thats just my logic and i dont know that logic can work with millis();
can it work?

// PROGRAM VARIABLES
int dtmf;
long previousMillis = 0;
long interval = 200;
unsigned long currentMillis = millis();
String dial(16);

void setup() {
dial = "";

// CM8870 BINARY INPUT PORT
pinMode(2, INPUT); //Q4
pinMode(3, INPUT); //Q3
pinMode(4, INPUT); //Q2
pinMode(5, INPUT); //Q1
pinMode(7, INPUT); //tombol
pinMode(8, OUTPUT); //relay

// CM8870 BINARY DATA VALID PIN
pinMode(6, INPUT); //tow

}

// DISPLAY DATA FROM DTMF DECODER
void loop() {
  jeda();
  if (dtmf == 4) { //2
    jeda();
    if (dtmf == 8) { //1
    reset();
      }
      else {
       reset();
       return;
      }
  }
  jeda();
  if (dtmf == 12) { //3
    jeda();
    if (dtmf == 8) { //1
      reset();
    } else {
      reset();
      return;
    }
    jeda();
      if (dtmf == 5) { //0
        reset();
        return;
      }
    }
  jeda();
  if (dtmf == 2) { //4
    jeda();
    if (dtmf == 8) { //1
      reset();
      delay(500);
      reset();
    }
    else {
      reset();
      return;
    }
  }
  if (digitalRead(7) == HIGH) {
    reset();
    return;
  }

}
  
void reset() {
    digitalWrite(8, HIGH);
    delay(100);
    digitalWrite(8, LOW);
}
void jeda(){
if(currentMillis - previousMillis <= interval){
  check();
} else if(currentMillis == interval) {
  reset();
  currentMillis = 0;
  return;
}
}
void check() {
  // WAIT FOR DATA VALID SIGNAL
if (digitalRead(6) == HIGH) {
// DECODE CM8870 DATA
dtmf = 0;
if (digitalRead(2) == HIGH) dtmf = dtmf + 1;
if (digitalRead(3) == HIGH) dtmf = dtmf + 2;
if (digitalRead(4) == HIGH) dtmf = dtmf + 4;
if (digitalRead(5) == HIGH) dtmf = dtmf + 8;
} else if(digitalRead(6) == LOW){
  check();
}
}

i change my millis(); logic like that. but i dont know it will work or not. and it will disturb the other delay or not since i not know when it stop and when it start