Uno can't handle 6 array based steps or the cursed pin nº6

Hi, I've been tinkering with this for a while now (1+month on and off), correcting bugs and errors, but I suspect I've come across something deeper than my (scarce) skills with arduino coding, so I might aswell share it and see if someone has a better understanding of what is going on.

The project is fairly simple:
I have 5 pushbuttons connected in a pull-down configuration to pins 2 to 6,
an electronic lock on pin 8 (actually it will be a 5v relay for a 12v lock but right now I'm just measuring the voltage with a multimeter so nevermind),
and a bunch of pushbuttons all connected in parallel (in pulldown configuration through a 1200ohm resistor too) to pin 7 which I haven't even hooked up for this trial so we can ignore it aswell

The idea is you have to press the pushbuttons 1 to 5 in order to open the lock, and if the order is not correct or any of the other bait buttons (on pin7) are pressed it just restarts and waits for the correct order.

Board is an Arduino Uno and all the electronics parts have been thoroughly tested and work fine so the problem's not there, allthough in case it has something to do I should say all pushbutton's grounds are wired together and to the arduino's ground (pushbuttons 1 to 5 have separate individual positive sides which go to the pins 2 to 6, error pushbuttons' positives all go to pin 7) and there's a substantial amount of cable (about 1,5m).

Here's the whole code:

int note[] = {1, 2, 3, 4, 5, 6}; //array for checking password advance
int j = 0; //var changed by buttons
int correct = 0; //var for succesfull entry

void setup() {

  Serial.begin(9600);
  pinMode(2, INPUT); //button 1 (all pushbuttons on pull-down configuration with 1200ohms resistors)
  pinMode(3, INPUT); //button 2
  pinMode(4, INPUT); //button 3
  pinMode(5, INPUT); //button 4
  pinMode(6, INPUT); //button 5
  pinMode(7, INPUT); //error buttons all connected to pin 7
  pinMode(8, OUTPUT); //lock

}




void loop() {
  digitalWrite(8, HIGH); //lock is engaged

  Serial.println("start"); //let's me know the loop has started from the beginning

  while (correct == 0) {
    Serial.println(note[j]); //gives me the place on the array at which we're on, incidently tells me which button I have to push next

    if (digitalRead(2) == HIGH) { //when pushbutton 1 is pressed
      while (digitalRead(2) != LOW) { } //stops the whole process while the button is still being pushed
      delay(100);
      if (1 == note[j]) {
        j++; //checks the correct order and sums up 1 for next step proofing if correct
      }

      else {
        j = 0;  //if the order is not right all is reset to starting point
        correct = 0;
      }
    }

    if (digitalRead(3) == HIGH) { //same procedure for button 2
      while (digitalRead(3) != LOW) { }
      delay(100);
      if (2 == note[j]) {
        j++;
      }

      else {
        j = 0;
        correct = 0;
      }
    }

    if (digitalRead(4) == HIGH) { //same procedure for button 3
      while (digitalRead(4) != LOW) { }
      delay(100);
      if (3 == note[j]) {
        j++;
      }

      else {
        j = 0;
        correct = 0;
      }
    }

    if (digitalRead(5) == HIGH) { //same procedure for button 4
      while (digitalRead(5) != LOW) { }
      delay(100);
      if (4 == note[j]) {
        j++;
      }

      else {
        j = 0;
        correct = 0;
      }
    }

    if (digitalRead(6) == HIGH) { //same procedure for button 5
      while (digitalRead(6) != LOW) { }
      delay(100);
      if (5 == note[j]) {
        j++;
      }

      else {
        j = 0;
        correct = 0;
      }
    }

    if (digitalRead(7) == HIGH) { //if error button is pressed at any moment, all resets
      delay(100);
      j = 0; correct = 0;
    }

    if (note[j] == 6) {
      delay(100);  //when all correct pushbuttons have been preseed in the right order, the correct var turns to 1 thus exiting this while loop...
      correct = 1;
    }


  }

  while (correct == 1) { //...and entering this while loop which opens the lock
    Serial.println("lock open"); //lets me know we've succesfully entered this while loop
    digitalWrite(8, LOW); //lock gets open
    delay(1000); //gives it a second so the mechanism doesn't jam
    Serial.println("reset"); //lets me know we're done
    correct = 0;
    j = 0;
    delay(5);
  }


}

Feel free to copy, use and modify it, just please let me know you've done so (you know: comment, send me a PM or whatever but please let me know! :smiley: )

What's the issue? Well the thing is it does work, but only with 4 buttons.

If I delete the last pressbutton check, e.g.:

 if(digitalRead(6)==HIGH){ //same procedure for button 5
      while(digitalRead(6) != LOW){ }
      delay(100);
      if(5==note[j]){j++;}
         
        else {j=0;correct=0;}}

and set the

if(note[j]==6){delay(100); correct=1;}

to

if(note[j]==5){delay(100); correct=1;}

the whole thing runs smoothly, the while loop for opening the lock runs, I get my 0V on the multimeter wired to pins ground and 8 and I'm happy

But if I run it as it is, it never exits the first while loop, changing my note[] value to 1 and asking for the correct combination again and again...

This has me completely bedazzled and I finally came here (after much frustration) just to see if there's a deeper issue I'm not seeing (as I'm fairly new to this whole arduino coding game) or (gods forgive me) I've writen some mistake I'm not seeing.

Things I've tried:
-running it on 4 and 5 pushbuttons with and without changing the note[] array length (1 to 5 and 1 to 6)
-changing the pin order and the pin numbers in almost every configuration
-checking my circuit (whole hardware side) until I dream with it at night

results so far: it only wants to work with 4 pushbuttons.

So if any fresh eyes could illuminate me and others on this issue, I'ld be forever gratefull. Also general knowledge about arduino coding and or rambling about arduino coding issue's related frustration you might think I haven't grasped yet is more than welcome.

Thanks in advance, I'll keep tinkering and posting my advances.

Also pardon my french, I'm not a native English speaker :slight_smile:

Find a proper button debounce method, e.g. from the IDE examples.

Add debug features, e.g. print out each pressed key, and a new line if the key is not accepted. Then you know whether the debouncing works, and where your logic should be improved.

OnaCustom:
Here's the whole code:

Your code is unreadable because of the way you have formatted it - for example with }} and multiple statements on a single line. Please use the AutoFormat tool to format it in a readable way and re-post it.

It also looks like you have a lot of repetition that is probably unnecessary.

And I suspect most (if not all) of your WHILEs should be replaced with IFs and allow loop() to do the repetition.

...R

Maybe the contents of note[] should be 2 through 6?

Thanks for your answers! So,

first of all

Robin2:
Please use the AutoFormat tool to format it in a readable way and re-post it.

did that, sorry.

DrDiettrich:
Find a proper button debounce method, e.g. from the IDE examples.

Still working on that, I though the empty while loop was a simple enough "debounce"* method: it does work and the whole code works with only 4 pushbuttons but yes, I'm still figuring out how to implement some of the various debounce methods I've found online.

DrDiettrich:
Add debug features

The thing is my main bug is the fact it does work with 4 pushbuttons but not with 5. When the 5th is pressed my "note[j]" counter goes up to 6 yet the if (note[j] == 6) { correct = 1;} and subsequently the while(correct==1){} don't run.
With only 4 pushbuttons I get my note[j] == 5, correct=1 and while(correct==1) right, no problem.
That's the mistery I don't understand.

Robin2:
your WHILEs should be replaced with IFs

You mean the empty whiles I use for "debouncing"* right? Tried that just in case but it just passes on it and restarts the process. The 2 main whiles (for correct = 0 or 1) are essentially the -waiting for password- and -opening lock- states, I tried doing that with 2 different loops (main loop and correct loop) instead of whiles, still there's no change when the 5th pushbutton is pressed. I don't think i can replace them by ifs.

boolrules:
Maybe the contents of note[] should be 2 through 6?

but that makes it 1 step shorter, thus working with 4 pushbuttons (which it does) but not with 5. I should change the array numbers maybe, so the steps match the pins for clarity's sake, if that's what you meant.
Also tried without the array; just assigning a value to j from 1 to 6, if(j==6) {correct=1} and while(correct==1) still doesn't kick.

There's no way I'm forcing the Arduino beyond its processing limit, that much I know. I've also tried with other Uno boards in case this one was broken, same results. Maybe it's my whole approach, should I change the whole logic?

I'll keep posting more changes and results., thanks again.

*what I really need is for the arduino to only read the pushbutton that's meant to be pressed at that moment; as in if any other pushbutton is pressed by mistake it won't read it. The hardware side final setup is a bit complicated and fat fingers might make it happen. Still including proper debouncing for the pushbuttons meant to be pressed at that moment will make it more precise I guess.

If this was my program I would read all the buttons in a readKeypad() function and save the value detected (I am assuming only one key will be pressed at any one time).

Then I would have a counter to keep track of which step in the sequence I am at. And check the current saved value against the list in the array. Something like

void loop() {
   readKeypad();
   if (newKeyPressDetected == true) {
     if (keyPadVal != codeSequence[codeStep]) {
         // the user has made a mistake so do whatever
         codeStep = 0;  // is this appropriate?
      }
      else {
         codeStep ++;
      }
      if (codeStep >= 6) {
         // code is correct
      }
   }
}

...R

OnaCustom:
and a bunch of pushbuttons all connected in parallel (in pulldown configuration through a 1200ohm resistor too) to pin 7 which I haven't even hooked up for this trial so we can ignore it aswell

Sorry, no you can't ignore pin 7 since you have written code that handles it. If you have nothing connected to pin 7 then it is a floating state and could read with any value arbitrarily. Connect it to ground before continuing any further testing.

arduarn:
Sorry, no you can't ignore pin 7 since you have written code that handles it. If you have nothing connected to pin 7 then it is a floating state and could read with any value arbitrarily. Connect it to ground before continuing any further testing.

Turns out this, or something similar, was my issue... I tried some other configurations with the 50+ pushbuttons (I have them wired with duponts so I can change the password and error ones on the hardware side instead of rewriting the code), turns out some work some others don't. I checked the circuit at every point with a multimeter, everything seems fine (no cross connections, no bad soldering, no wrong wiring, no nothing) yet it does fail to read properly with some of them, and I do suspect it has to do with the pin 7 reading values. I guess the signal gets polluted or something, I'll devise a way to test this.
So yes, wire in your full version even if it's just a prototype, lesson learned.
But the code (althought not the best code ever) works.

Robin2:
readKeypad() function

I'm not familiar with those, will dig into it, but your code suggestion gave me the idea that lead to the discovery of the issue. I did implement the cleaner if/else management solution though.

Thanks a lot for your answers! I did learn a lot, and still have a lot to do and learn, but at last I can see some light. I'll post more of my deranged banter if I judge it interesting or usefull. Thanks again!

OnaCustom:

readKeypad() function

I'm not familiar with those, will dig into it, but your code suggestion gave me the idea that lead to the discovery of the issue. I did implement the cleaner if/else management solution though.

You will need to create that function yourself.

...R

OnaCustom:
but that makes it 1 step shorter, thus working with 4 pushbuttons (which it does) but not with 5.

No, it's the correct number of steps. You have 5 "active" pushbuttons. The array contains 5 pin numbers. Modify your code to fit the array.
And you do not really need the array at all. Any time you have an array of constant linear values you should be able to see that your index, "j", can be used by itself.

boolrules:
And you do not really need the array at all. Any time you have an array of constant linear values you should be able to see that your index, "j", can be used by itself.

I have been assuming that when the OP gets his program working he will put different numbers into the array - the sequence of button presses that is required to open the lock.

...R

Robin2:
I have been assuming that when the OP gets his program working he will put different numbers into the array - the sequence of button presses that is required to open the lock.

...R

And I've been assuming that the buttons would be installed in any desirable keypad position.
Which would make them code fixed forever. Not desirable at all.
See what comes from incomplete specifications, OnaCustom?

boolrules:
And I've been assuming that the buttons would be installed in any desirable keypad position.

I don't understand ?

...R

I guess I've been assuming a lot. He says you have to push button 1 - 5 to open a lock. I thought that an actual row of buttons, in order, would make a pretty stupid lock sequence. And then more buttons filling in the remainder of the sequence that don't do anything is even more stupid. So just in the back of my mind I was assuming that maybe the buttons would be arranged in a keypad like manner where pin 2 button is in position 3 for example, and pin 3 button is in position 9 for example, and etc. But I did not worry about it too much since the code did not rely on where the buttons were physically placed. And if he wants them in a row of 1 through N who am I to argue? Maybe it's a dexterity test?

I skimmed the description anyway. I probably failed reading comprehension.

I have been assuming a regular rectangular keypad and a requirement to press the numbers corresponding to the code. If the code was 3 7 9 2 1 then those would be the numbers in the array.

...R

Hi,
The idea is you have to press the pushbuttons 1 to 5 in order to open the lock, and if the order is not correct or any of the other bait buttons (on pin7) are pressed it just restarts and waits for the correct order.

If you need to see 5 correct entries and say at entry 2 you press a bait button, do you still let the operator finish the 5 button input?

If you restart the instant the operator presses a bait button, it won't take long to work out what are the bait buttons and work on the 5 true buttons.

If you wait till a 5 button sequence has been entrered then indicate a wrong code, the operator will not have an idea of what are the bait buttons and how many he/she has pressed.

Keypad would be a better option, as some have suggested, you wouldn't need any bait buttons, just look for the correct number combination.

If the first number has to be "6" then automatically 0-5 and 7-9 are bait numbers.
If the second number has to be "3" then automatically 0-2 and 4-9 are bait numbers.

and so on.

Tom.. :slight_smile:

Robin2:
I have been assuming a regular rectangular keypad and a requirement to press the numbers corresponding to the code. If the code was 3 7 9 2 1 then those would be the numbers in the array.

...R

Yeah, that'll work. And the dead keys with no possibility of software control?

boolrules:
And the dead keys with no possibility of software control?

I must be missing something that is obvious to others. Why would there be "dead keys"?

None of the keys on my laptop is dead but if I want to type the word "keys" I just use 4 of them. If I accidentally type "kesy" or "jklmqt" then I have done it wrong.

...R

Robin2:
I must be missing something that is obvious to others. Why would there be "dead keys"?

None of the keys on my laptop is dead but if I want to type the word "keys" I just use 4 of them. If I accidentally type "kesy" or "jklmqt" then I have done it wrong.

...R

I agree, you just read in the 5 numbers then;
IF they are correct then GO.
IF they are not the RESET.
It sounds like some people are thinking that EACH keypress has to be analysed WHEN a key is pressed, it doesn't, you input ALL 5 keypresses in the order they were entered, THEN check to see if the WHOLE 5 key entry is correct.
Tom... :slight_smile:

If only a couple of key presses are decoded, not individual keys, a feedback is required when a sequence is finished. Else it might be possible that a key already is in the queue, when the user starts entering its sequence.