user69621: I have task which includes a 30s delay in the void loop. During this delay I want to be able to press a key on a keypad and have a message displayed on the serial monitor as an emergency stop. Since delays block code until they are done I thought I would be able to break them down into smaller sections so I could still press the emergency stop key in between them but of course that doesn't work. I've read through how to use the milis() function but from what I can gather it seems like it wouldn't work for my system as I need user input for it so the time from the start of the Arduino to me pressing the emergency stop button is different every time. Is there a way that isn't too complicated and would allow me to press the button during that 30s?
The delay is in if (key == '2') and the last part of the sketch is the emergency stop.
const int greenLED = 13;  //Declares greenLED as being connected to D13
const int redLED = 12;    //Declares redLED as being connected to D12 
//
const int ButtonT1 = 11;    //Declare pin number for ButtonT1 as D11
int ButtonT1State = 0;      //Variable for reading ButtonT1 state
const int ButtonT2 = 10;    //Declare pin number for ButtonT2 as D10
int ButtonT2State = 0;      //Variable for reading ButtonT2 state
//
int count_value1 = 0;       //Variable for storing counter value for turnstile 1
int count_value2 = 0;       //Variable for storing counter value for turnstile 2
//
const byte ROWS = 4;        //Four row matrix
const byte COLS = 4;        //Four columns matrix
char keys [ROWS] [COLS] = { //Defines symbols on buttons of keypad 
  {'1','2','3','A'},        //Defines ROW 1 
  {'4','5','6','B'},        //Defines ROW 2
  {'7','8','9','C'},        //Defines ROW 3 
  {'*','0','#','D'}};       //Defines ROW 4
  byte rowPins[ROWS] = {9, 8, 7, 6};  //Pin numbres of row pinouts of the keypad 
  byte colPins[COLS] = {5, 4, 3, 2};  //Pin numbers of column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); 
//
void setup() { //Begin void setup, code runs once 
 Serial.begin(9600);      //Begin serial transmission 
 Wire.begin();            //Begin I2C wire communication protocol 
 lcd.begin(16,2);         //Begin LCD with 16 columns and 2 rows
//
 pinMode(greenLED, OUTPUT);  //Set greenLED as an OUTPUT
 pinMode(redLED, OUTPUT);    //Set redLED as an OUTPUT
 pinMode(ButtonT1, INPUT);   //Set ButtonT1 as an INPUT 
 pinMode(ButtonT2, INPUT);   //Set ButtonT2 as an INPUT 
}
//
void loop() {                               //Begin void loop 
   char key = keypad.getKey();              //Get a character key from the keypad 
//
   //counter 1
    ButtonT1State = digitalRead(ButtonT1);  //Read the state of ButtonT1 -  
    if (ButtonT1State == HIGH){             //Begin IF ButtonT1State is HIGH
      count_value1++;                       //IF buttonT1 pressed, increase count value 
      Serial.println(count_value1);         //Print count_value1 on serial monitor
      delay(200);                           //Delay for 200ms, 0.2s 
      digitalWrite(greenLED,HIGH);          //Set greenLED to HIGH,ON 
      digitalWrite(redLED,LOW);             //Set redLED to LOW, OFF
 //
     if (key == '1'){                         //Wait until key '1' is pressed
    }                                         //End IF key == '1'
    ButtonT2State = digitalRead(ButtonT2);   //Read ButtonT2 state
    if (ButtonT2State == HIGH){              //Check if ButtonT2State is == HIGH
      count_value2++;                        //IF buttonT1 pressed, increase count value 
      Serial.println(count_value2);          //Print count_value2 on serial monitor
      delay(500);                            //Delay for 500ms, 0.5s  
//
    if(key == '2'){                            //Wait untill key '2' is pressed - confirm ride is ready
      Serial.println("Ride starting - 30s");   //Print message in brackets on serial monitor
//30s delay, broken into smaller delays
      delay(10000); 
     Serial.println("20s left"); 
      delay(10000);
      Serial.println("10s left");
      delay(10000);
      Serial.println("Ride finished");        //Print message in brackets on serial monitor
      delay(100);                             //Delay for 1000ms, 1s 
    }                                         //End if key == '2'
//
    if (key == '4'){                        //Wait until key '4' is pressed - emergency stop 
      Serial.println("Emergency stop");     //Print message in brackets on serial monitor 
      digitalWrite(redLED,HIGH);            //Set redLED to HIGH,ON
      digitalWrite(greenLED,LOW);           //Set greenLED to LOW,OFF
      lcd.clear();                          //Clear i2c LCD
      lcd.setCursor(0,0);                   //Set cursor to column 0, row 0
      lcd.print("Emergency stop");          //Print message in brackets on i2c LCD
      count_value2 = 0;                     //Set count_value2 to 0
      delay(1000);                          //Delay for 1000ms, 1s 
    }                                       //End IF key == '4' 
}


user359: Make a statemachine.
Take a piece of paper and draw out the order of operation and each time you are waiting you specify what each button will do.
So for example each time button 1 is pushed you increment the counter and change the display.
When waiting for a timeout you check if(startTimestamp - millis() > timeout) for the next step.
Then give each waiting state a number and put a big switch on a global at the start of the loop() and update the global each time the state needs to change.

69621: <p>I have task which includes a 30s delay in the void loop. During this delay I want to be able to press a key on a keypad and have a message displayed on the serial monitor as an emergency stop. Since delays block code until they are done I thought I would be able to break them down into smaller sections so I could still press the emergency stop key in between them but of course that doesn't work. I've read through how to use the milis() function but from what I can gather it seems like it wouldn't work for my system as I need user input for it so the time from the start of the Arduino to me pressing the emergency stop button is different every time. Is there a way that isn't too complicated and would allow me to press the button during that 30s?</p>
<p>The delay is in if (key == '2') and the last part of the sketch is the emergency stop.</p>
<pre><code>const int greenLED = 13;  //Declares greenLED as being connected to D13
const int redLED = 12;    //Declares redLED as being connected to D12 
//
const int ButtonT1 = 11;    //Declare pin number for ButtonT1 as D11
int ButtonT1State = 0;      //Variable for reading ButtonT1 state
const int ButtonT2 = 10;    //Declare pin number for ButtonT2 as D10
int ButtonT2State = 0;      //Variable for reading ButtonT2 state
//
int count_value1 = 0;       //Variable for storing counter value for turnstile 1
int count_value2 = 0;       //Variable for storing counter value for turnstile 2
//
const byte ROWS = 4;        //Four row matrix
const byte COLS = 4;        //Four columns matrix
char keys [ROWS] [COLS] = { //Defines symbols on buttons of keypad 
  {'1','2','3','A'},        //Defines ROW 1 
  {'4','5','6','B'},        //Defines ROW 2
  {'7','8','9','C'},        //Defines ROW 3 
  {'*','0','#','D'}};       //Defines ROW 4
  byte rowPins[ROWS] = {9, 8, 7, 6};  //Pin numbres of row pinouts of the keypad 
  byte colPins[COLS] = {5, 4, 3, 2};  //Pin numbers of column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); 
//
void setup() { //Begin void setup, code runs once 
 Serial.begin(9600);      //Begin serial transmission 
 Wire.begin();            //Begin I2C wire communication protocol 
 lcd.begin(16,2);         //Begin LCD with 16 columns and 2 rows
//
 pinMode(greenLED, OUTPUT);  //Set greenLED as an OUTPUT
 pinMode(redLED, OUTPUT);    //Set redLED as an OUTPUT
 pinMode(ButtonT1, INPUT);   //Set ButtonT1 as an INPUT 
 pinMode(ButtonT2, INPUT);   //Set ButtonT2 as an INPUT 
}
//
void loop() {                               //Begin void loop 
   char key = keypad.getKey();              //Get a character key from the keypad 
//
   //counter 1
    ButtonT1State = digitalRead(ButtonT1);  //Read the state of ButtonT1 -  
    if (ButtonT1State == HIGH){             //Begin IF ButtonT1State is HIGH
      count_value1++;                       //IF buttonT1 pressed, increase count value 
      Serial.println(count_value1);         //Print count_value1 on serial monitor
      delay(200);                           //Delay for 200ms, 0.2s 
      digitalWrite(greenLED,HIGH);          //Set greenLED to HIGH,ON 
      digitalWrite(redLED,LOW);             //Set redLED to LOW, OFF
 //
     if (key == '1'){                         //Wait until key '1' is pressed
    }                                         //End IF key == '1'
    ButtonT2State = digitalRead(ButtonT2);   //Read ButtonT2 state
    if (ButtonT2State == HIGH){              //Check if ButtonT2State is == HIGH
      count_value2++;                        //IF buttonT1 pressed, increase count value 
      Serial.println(count_value2);          //Print count_value2 on serial monitor
      delay(500);                            //Delay for 500ms, 0.5s  
//
    if(key == '2'){                            //Wait untill key '2' is pressed - confirm ride is ready
      Serial.println(&quot;Ride starting - 30s&quot;);   //Print message in brackets on serial monitor
//30s delay, broken into smaller delays
      delay(10000); 
     Serial.println(&quot;20s left&quot;); 
      delay(10000);
      Serial.println(&quot;10s left&quot;);
      delay(10000);
      Serial.println(&quot;Ride finished&quot;);        //Print message in brackets on serial monitor
      delay(100);                             //Delay for 1000ms, 1s 
    }                                         //End if key == '2'
//
    if (key == '4'){                        //Wait until key '4' is pressed - emergency stop 
      Serial.println(&quot;Emergency stop&quot;);     //Print message in brackets on serial monitor 
      digitalWrite(redLED,HIGH);            //Set redLED to HIGH,ON
      digitalWrite(greenLED,LOW);           //Set greenLED to LOW,OFF
      lcd.clear();                          //Clear i2c LCD
      lcd.setCursor(0,0);                   //Set cursor to column 0, row 0
      lcd.print(&quot;Emergency stop&quot;);          //Print message in brackets on i2c LCD
      count_value2 = 0;                     //Set count_value2 to 0
      delay(1000);                          //Delay for 1000ms, 1s 
    }                                       //End IF key == '4' 
}
</code></pre>
 359: <p>Make a statemachine.</p>
<p>Take a piece of paper and draw out the order of operation and each time you are waiting you specify what each button will do.</p>
<p>So for example each time button 1 is pushed you increment the counter and change the display.</p>
<p>When waiting for a timeout you check <code>if(startTimestamp - millis() &gt; timeout)</code> for the next step.</p>
<p>Then give each waiting state a number and put a big switch on a global at the start of the <code>loop()</code> and update the global each time the state needs to change.</p>
