DigitalRead() Delay with 10 Switch

Hi,

I have a project where there are 10 switches. I have codes (as shown below) to detect which switch was pressed and the number will be displayed on the LCD. I realized that there was a delay (about 0.2 to 0.5 sec) between the reading and the switch (means I have to hold the switch for a while before releasing it in order for the board to detect the switch I pressed). If I am not wrong, it’s due to the looping of digitalRead the state of the switch. May I know is there anyway (or may be the algorithm) to speed up the switch detection?
It would be good if it can be as quick as ONE switch detection. Please advise. Thanks

while(num1Flag == 0)
{ 

  for(digit1=0; digit1<10; digit1++)
  {
    num[digit1] = digitalRead(button[digit1]);

    //Serial.print(num[digit1]);
    Serial.print("digit1 =");
    Serial.println(digit1);
    
    lcd.setCursor(1,0);
    lcd.print("1st Secret Code");
    
    lcd.setCursor(4,1);
    lcd.cursor();

    if(num[digit1] == LOW)
    { 
    correctDigit1 = digit1;
    
    lcd.setCursor(4, 1);
    lcd.print(digit1);

      while(digitalRead(button[digit1]) == 0) {
       
       Serial.print("1st Ball Stuck");

       
      }

    num1Flag = 1;
    }     
  }
  Serial.println();
 }

I realized that there was a delay (about 0.2 to 0.5 sec) between the reading and the switch (means I have to hold the switch for a while before releasing it in order for the board to detect the switch

Could be something in the code you DIDN'T show. Off to http://snippets-r-us.com for you.

Ok. here you go again…

#include <LiquidCrystal.h>

const byte pass1 = 1;
const byte pass2 = 2;
const byte pass3 = 9;
const byte pass4 = 0;


const byte button[10] = {A9,A0,A1,A2,A3,A4,A5,A6,A7,A8};

const byte magneticLock = A15;

 const byte startButton= A10;
 
 const byte startLight = A14;
 
 const byte lcdBacklight = 8;

const byte resetLED = 13;

int num[10];

byte num1Flag = 0;
byte num2Flag = 0;
byte num3Flag = 0;
byte num4Flag = 0;

byte digit1;
byte digit2;
byte digit3;
byte digit4;

byte correctDigit1;
byte correctDigit2;
byte correctDigit3;
byte correctDigit4;

byte allCorrect;

//                Rs,En,D4,D5,D6,D7
LiquidCrystal lcd(6, 7, 2, 3, 4, 5);

 String txtsc, txtsc2;
 
void setup()
{
Serial.begin(9600);
  


for(int i=0; i < 10; i++)
pinMode(button[i], INPUT);

pinMode(startButton, INPUT);

pinMode(magneticLock, OUTPUT);

pinMode(startLight, OUTPUT);

pinMode(lcdBacklight, OUTPUT);

pinMode(resetLED, OUTPUT);

// set up the LCD's number of columns and rows: 
lcd.begin(16, 2);

digitalWrite(resetLED, LOW);
  
txtsc="     Key 4 Security Codes to Escape  ";
txtsc2 = "   Press To Start  ";


}
void loop()
{
  
  digitalWrite(magneticLock,HIGH);
  
  
  
  while(digitalRead(startButton) == HIGH)
  {
  lcd.setCursor(3,0);
  lcd.print("PRISON MAP");

  lcd.setCursor(1,1);
  lcd.print("Press To Start");
  
  digitalWrite(startLight,HIGH);
  digitalWrite(lcdBacklight,LOW);

  }
  
  digitalWrite(startLight,LOW);
  digitalWrite(lcdBacklight,HIGH);
  
  lcd.clear();
  
  
  lcd.setCursor(2,1);
  lcd.print("Starts in ");
  
  lcd.setCursor(13,1);
  lcd.print("s");
  
 
  byte timer;
  byte startTimer=9;
  
  for (int x = 19; x > 0; x--) {
    lcd.setCursor(0,0);
    txtsc=ScrollTxt(txtsc);
    lcd.print(txtsc);
    
    timer = x % 2;
    
    if (timer ==0)
    {
      lcd.setCursor(12,1);
      lcd.print(startTimer);
      startTimer--;
    }
    
    delay(500);
  }


lcd.clear();
lcd.setCursor(0,0);
lcd.print("Initiating.....");

delay(1000);

lcd.clear();



// Digit 1 Evaluation
while(num1Flag == 0)
{ 

  for(digit1=0; digit1<10; digit1++)
  {
    num[digit1] = digitalRead(button[digit1]);

    //Serial.print(num[digit1]);
    Serial.print("digit1 =");
    Serial.println(digit1);
    
    lcd.setCursor(1,0);
    lcd.print("1st Secret Code");
    
    lcd.setCursor(4,1);
    lcd.cursor();

    if(num[digit1] == LOW)
    { 
    correctDigit1 = digit1;
    
    lcd.setCursor(4, 1);
    lcd.print(digit1);

      while(digitalRead(button[digit1]) == 0) {
       
       Serial.print("1st Ball Stuck");

       
      }

    num1Flag = 1;
    }     
  }
  Serial.println();
 } 
  

//Evaluate Digit 2  
while(num2Flag == 0)
{ 

  for( digit2=0; digit2<10; digit2++)
  {
    num[digit2] = digitalRead(button[digit2]);


    Serial.print("digit2 =");
    Serial.println(digit2);

    lcd.setCursor(1,0);
    lcd.print("2nd Secret Code");
    
    lcd.setCursor(6,1);
    lcd.cursor();
 
    if(num[digit2] == LOW)
    { 
    correctDigit2 = digit2;
  
    lcd.setCursor(6, 1);
    lcd.print(digit2);
    
      while(digitalRead(button[digit2]) == 0) {
       
       Serial.print("2nd Ball Stuck");

       
      }
 
    num2Flag = 1;

    }     
  }
  Serial.println();
 }

//Evaluate Digit 3  
while(num3Flag == 0)
{ 

  for( digit3=0; digit3<10; digit3++)
  {
    num[digit3] = digitalRead(button[digit3]);

    
    Serial.print("digit3 =");
    Serial.println(digit3);

    lcd.setCursor(1,0);
    lcd.print("3rd Secret Code");
    
    lcd.setCursor(8,1);
    lcd.cursor();
 
    if(num[digit3] == LOW)
    { 
      
    correctDigit3 = digit3;

    lcd.setCursor(8, 1);
    lcd.print(digit3);
    
       while(digitalRead(button[digit3]) == 0) {
       
       Serial.print("3rd Ball Stuck");

       
      }

 
    num3Flag = 1;

    }     
  }
  Serial.println();
 }
 
 //Evaluate Digit 4  
while(num4Flag == 0)
{ 

  for( digit4=0; digit4<10; digit4++)
  {
    num[digit4] = digitalRead(button[digit4]);


//    Serial.println(digit4);

    lcd.setCursor(1,0);
    lcd.print("4th Secret Code");
    
    lcd.setCursor(10,1);
    lcd.cursor();
 
    if(num[digit4] == LOW)
    { 
      
      correctDigit4 = digit4;
      
    lcd.setCursor(10, 1);
    lcd.print(digit4);
    
       while(digitalRead(button[digit4]) == 0) {
       
       Serial.print("4th Ball Stuck");

       
      }

    num4Flag = 1;

    }     
  }
  Serial.println();
 }
 
 lcd.clear();
 
 if(correctDigit1 == pass1 && correctDigit2 == pass2 && correctDigit3 == pass3 && correctDigit4 == pass4)
  { 
    lcd.setCursor(0,0);
    lcd.print("Code Accepted");
    lcd.setCursor(0,1);
    lcd.print("Good Luck!");
    
    digitalWrite(magneticLock,LOW);
    
    allCorrect = 1;
    
    while(allCorrect == 1)
    {
      Serial.println("Mission Accomplished! Press Reset Button to Restart");
      digitalWrite(resetLED,HIGH);
    }
    
  }
  
 else

  {
    lcd.setCursor(2,0);
    lcd.print("Wrong Codes!");
    
    lcd.setCursor(2,1);
    lcd.print("Retry in");
    
    lcd.setCursor(12,1);
    lcd.print("s");
    
    for(byte y=5; y>0; y--)
    {
      lcd.setCursor(11,1);
      lcd.print(y);
      delay(1000);
    }
    
    
    num1Flag = 0;
    num2Flag = 0;
    num3Flag = 0;
    num4Flag = 0;
  }
  
  lcd.clear();
   
}


String ScrollTxt(String txt){
  return txt.substring(1,txt.length()) + txt.substring(0,1);

}

I say that there are too much cycles.

the looping (FOR) is too much? Any good way to reduce the cycle hence improve the reading frequency?

Can you describe what you really what to do?
I think is more easy that try to read your code. (I’m sorry to say this, but is what I think)

I see a delay(500), that's a good candidate for a start.

The repetitious nature of the button testing code is an immediate glaring issue to be addressed - use array(s), data-driven loop, then you only have to write the code one time, not ten times.

First LAYOUT YOUR CODE, the IDE contains a tool for laying out code. Never post code which is not correct layed out. Correct layout makes it a lot easier to follow the logic and find errors. It will also help you do that.

You have two (at least) delays() in your code most like this is the problem. See blink without delay.

Mark

Yes, your right MarkT. There are at least one delay(500) and one delay(1000). I don’t even saw that. But I think that is after the actual read starts.

  while(digitalRead(startButton) == HIGH)
  {
  lcd.setCursor(3,0);
  lcd.print("PRISON MAP");

  lcd.setCursor(1,1);
  lcd.print("Press To Start");
  
  digitalWrite(startLight,HIGH);
  digitalWrite(lcdBacklight,LOW);

  }

Is there some reason you need to do this stuff over and over again, while the start switch state is HIGH? Seems to me that you'd do this stuff once IF the switch is HIGH, and then simply do nothing WHILE the switch is HIGH.

I gave up at this point. Your code is nearly unreadable, with no indentation.

I apologize for the confusion: Please let me try again to explain -

I am pretty sure the the following section of the code is the cause. I have 10 switches to show the specific (1 - 10) numeric number on the LCD panel when it is being triggered.

My programming logic is: if the switch is not triggered, it will have endless loop inside the WHILE. For every WHILE loop, it will step through 10 times (FOR LOOP) to check the state of the button. The problem with this code is that the button has to be held for awhile (0.2s to 0.5s) before it is considered triggered (change state). I am sure that the delay is caused by the FOR loop because it’s checking the state of specific button.

I wonder if you have any advice for the algorithm to reduce the delay?

const byte button[10] = {
  A9,A0,A1,A2,A3,A4,A5,A6,A7,A8};

int num[10];

while(num1Flag == 0)
  { 

    for(digit1=0; digit1<10; digit1++)
    {
      num[digit1] = digitalRead(button[digit1]);



      if(num[digit1] == LOW)
      { 
        correctDigit1 = digit1;



        while(digitalRead(button[digit1]) == 0) {

          Serial.print("1st Ball Stuck");


        }

        num1Flag = 1;
      }     
    }
    Serial.println();
  }

I think the code like this, looks much better:

const byte button[10] = {
  A9, A0, A1, A2, A3, A4, A5, A6, A7, A8
};

int num[10];

while (num1Flag == 0) {
   
  for (digit1 = 0; digit1 < 10; digit1++) {
    num[digit1] = digitalRead(button[digit1]);

    if (num[digit1] == LOW) {
      correctDigit1 = digit1;

      while (digitalRead(button[digit1]) == 0) {

        Serial.print("1st Ball Stuck");
      }

      num1Flag = 1;
    }
  }
  Serial.println();
}

After this, I think you need a “break”, like this:

const byte button[10] = {
  A9, A0, A1, A2, A3, A4, A5, A6, A7, A8
};

int num[10];

while (num1Flag == 0) {
   
  for (digit1 = 0; digit1 < 10; digit1++) {
    num[digit1] = digitalRead(button[digit1]);

    if (num[digit1] == LOW) {
      correctDigit1 = digit1;

      while (digitalRead(button[digit1]) == 0) {

        Serial.print("1st Ball Stuck");
      }

      break;    // <<<<<<<<<<<< THIS BREAK HERE

      num1Flag = 1;
    }
  }
  Serial.println();
}

Why? Because after you detect the button pressed, I think you don’t need to look for any other key, so, you can exit the for loop.

Ic…Let me try out… Thanks…