Button pressed for 5 seconds not exiting while loop

Hi all, I want to start by saying I’m not a programmer at all, I’m an engineering student working on a project and have been trying to work on a prototype and have been struggling getting it to work.

So this is what my code is supposed to do. I’m trying to make a button that unlocks something only under the condition that a certain time has passed (when the k value reaches 3). When my button is unplugged, it tests correctly: counts k value until it hits 3, when k > 3 it reads the digital input (lockread) of my switch, if val = 0 nothing happens.
The next part is what isn’t working. In the while loop, I want it to read whether the button has been held down for 5 seconds (hence the i > 5), once it detects the button being held down for 5 seconds, I want it to declare “open.” The problem is, once it reads a single input from the switch, it stays stuck in this while loop. If I press the switch once, “val” stays at 1 regardless if I’m holding it or not.
I also want it to completely reset the entire loop once you let go of the switch.

I’m using an Arduino Uno, and my switch is just a basic gate switch plugged directly into the 3.3V output. The Serial.prints are just my method of testing without plugging everything in so I can diagnose.

Can someone please explain why it isn’t working? Or if there is a better function for this? I appreciate any help, thanks!

Code:

int lockread = 8;
int mosfet = 13;
unsigned long val;
int k;
void setup() {
  Serial.begin(9600);
  pinMode(lockread,INPUT);
  pinMode(mosfet,OUTPUT);
  k = 0;
}
  
void loop() {
  Serial.println("INITIALIZING");
  delay(3000);
  int i = 0;
  k++; 
  Serial.print("k: ");
  Serial.println(k);
  while (k > 3) {
    val = digitalRead(lockread);
    if (val == LOW) {
      Serial.print("val: ");
      Serial.println(val);
    }
    while (val == HIGH) {
         Serial.print("val: ");
         Serial.println(val);
         Serial.print("i: ");
         Serial.println(i);
         delay(1000);
         i++;
         if (i > 5) {
          Serial.println("open");
         }
         if (i <= 5 && val != HIGH) {
          Serial.println("waitlongerplz");
          return;
         }
    }      
  }
}

FunctionalTimer1.2.ino (807 Bytes)

You will never be a good engineer if you don't learn how to ask and answer your own questions.

Here is that particular problem:

    while (val == HIGH) {
         Serial.print("val: ");
         Serial.println(val);
         Serial.print("i: ");
         Serial.println(i);
         delay(1000);
         i++;
         if (i > 5) {
          Serial.println("open");
         }
         if (i <= 5 && val != HIGH) {
          Serial.println("waitlongerplz");
          return;
         }
    }

Notice there is nothing in this loop that changes val. val doesn’t magically change if you press or release the button. You have to do a digitalRead() somewhere. As it is currently written, val will always be HIGH, and this loop will never end. If you want something to happen when you press or release the button, you have to check the button. Somewhere where the code is actually being executed.

Awesome! that solved everything, it works now thanks a lot!

Hi, Welcome to the forum. Did you understand what the edit did to your code and why?

Hi all, I want to start by saying I'm not a programmer at all, I'm an engineering student

Engineering students NEED to learn programming. If your course does not include at least C++ programming, then I suggest you go looking for a C++ class.

Tom.... :)

Using the delays might mean you have to press the button for nine seconds or longer. Might want to google "blink without delay" and consider it in your codes.