Go Down

Topic: Keypad Issues (Read 1 time) previous topic - next topic

Markham

Hi,

I'm having some issues with a program i'm writing that uses an Arduino nano, a nokia 5110 lcd, a 4x4 keypad, and a small coil. All connections are tested and working fine.

I'm using the function ReadKeypad() to read the buttons pressed on my keypad and convert them into a char(code_read[a]). In my first if statement it has no problem reading and executing an order given but when I use the code_read[a] again for a second input it wont work. On the second statement I put all the values in ReadKeypad() to 0 but it doesn't work. Am I doing this wrong? Is their a better way? In my code I intend to read from the keypad 3 times in total although currently it only reads twice.

Any advice would be gratefull! Thanks!!


PaulS

Code: [Select]
     if (End_code == 1 && ID[0] == code_read[a-6] && ID[1] == code_read[a-5] && ID[2] == code_read[a-4] && ID[3] == code_read[a-3]&& ID[4] == code_read[a-2])
What happens if a user presses 3 keys and then presses the # key. What is code_read[-2] going to access? Why isn't ID[0] being compared to code_read[0]?
The art of getting good answers lies in asking good questions.

Markham

Hi Pauls,

If a press the # key before or after the 5 digit comparison it will sent the code to the else if statement. Do you think I should try to simplify the if statement, and is that the cause?

PaulS

Quote
If a press the # key before or after the 5 digit comparison it will sent the code to the else if statement.

Why do you think that? When the # key is pressed, in ReadKeypad(), the # is stored in code_read and a is incremented.

There is nothing in the if statement I showed earlier that is necessarily false, so there is no reason to conclude that the else if part will be evaluated.
The art of getting good answers lies in asking good questions.

Markham

So I took another look at the code and you were right so I simplified things and equalled the the ID[_] to its respective code_read[_] and did the same to Pass[_].

Then I realised that the else if wasn't working right so I brought it back to an if statement. Finally it was working right! Every time the 1º function ended it would drop down to the second IntrodPass(), but the only answer it took was ID[_] never the Pass[_] specified in IntrodPass(). So it got me thinking that this happens because the IntrodID() function is in the loop() function.

I finally resolved to put it in the setup() function and make it run only once as intended but oddly enough it just doesn't do anything other than type the code_read[a] on my lcd.

I really have no clue as to why this is happening, so I'd love some more intake!

Thanks again

PaulS

Quote
I finally resolved to put it in the setup() function and make it run only once as intended but oddly enough it just doesn't do anything other than type the code_read[a] on my lcd.

As intended? That seems strange. I would have thought that the intention was to run it every time the # key was pressed.

Which means that it should be called from ReadKeypad() when the # key is detected.

This:
Code: [Select]
     if (End_code == 1 && ID[0] == code_read[0] && ID[1] == code_read[1] && ID[2] == code_read[2] && ID[3] == code_read[3]&& ID[4] == code_read[4])
is silly. If the value in End_code is 1, you THEN want to use a for loop to test the values. Imagine what this code would look like if you needed a 64 character ID. What would a for loop that iterated 64 times instead of 5 times look like? Not much difference, eh?
The art of getting good answers lies in asking good questions.

Markham

Hi,

I had actually tried calling from the ReadKeypad() before although i hadn't understood that it was comparing every time a key was pressed. So I went ahead and did it again, Unfortunately it leads me to the same problem. It will only compare to the first function and never to the second so i placed a condition in the ReadKeypad() function to either go to function IntrodID() or IntrodPass()
Code: [Select]
if(step1==0) {IntrodID();}
        if(step1==1) {IntrodPass();}


So I thought that that ought to do it, but again I now have multiple problems, If I fail to insert the right ID on the 1º try it will never accept any other attempt, and on the second condition it doesn't accept the right pass. So I guess the issue is related to the 3 values I reset when the conditions I need aren't met.
Code: [Select]
a=0;
           code_read[a] = 0;
           End_code=0;

I just don't understand why!

Quote
If the value in End_code is 1, you THEN want to use a for loop to test the values.


Relating to this, It makes sense I should consider changing everything to a for function, but I haven't worked out these bugs so maybe i'll tackle that after understanting whats going on right now.

PaulS

Quote
So I guess the issue is related to the 3 values I reset when the conditions I need aren't met.

Yes. You also need to set step1 back to 0.
The art of getting good answers lies in asking good questions.

Markham

So I've taken another look at the code, and I can only resume that the issue is probably related as I said earlier to
Code: [Select]
End_code=0;
a=0;
code_read[a] = 0;
. I Think that what is happening is that while these 3 values are zeroed in the if statements they are sort in loop putting the values to zero everytime I hit a button. Does this sound right? The only time it reads correctly is if I type the right value at the first try.

How can I make the code do this just once?

PaulS

Quote
The only time it reads correctly is if I type the right value at the first try.

What indicates to the program that you entered the correct value? a = 0 does not. code_read[a] = 0 does not. End_code does not.
The art of getting good answers lies in asking good questions.

Markham

I really don't undestand what you mean.   :smiley-red:

What indicates the correct value are the if functions that compare both the ID and the pass to the code_read. When those are read I need to reset them, in order to read the code_read and compare it correctly which I try to do zeroing those 3 values. I then shift from one function to the other with the step1. To me as it is, it's sounding logical i'm sure it's not otherwise it would be working...heheh

PaulS

Quote
What indicates the correct value are the if functions that compare both the ID and the pass to the code_read.

I know that the if functions compare the values. If they don't match, you need to NOT advance to the next step. Isn't the step number contained in step1? If not, that variable needs a better name. If that is the correct variable, and the value entered does not match the expected value, step1 needs to be set back to 0. This seems obvious.
The art of getting good answers lies in asking good questions.

Markham

Okay, I didn't mention that in the other comments but I have been putting Step1 Back to 0 if it is supposed to be in the first function and putting step1 to 1 if I want it to go to the second function. If that is the case it should be working but it isn't. I really don't understand whereelse I need to put the step1 to 0.

I'm sorry for sounding like a broken record but I really am stumbling on this.

PaulS

Code: [Select]
        if(code_read[a] == '#') {End_code = 1;}
        if(code_read[a] != '#') {End_code = 0;}
        if(step1==0) {IntrodID();}
        if(step1==1) {IntrodPass();}

First, End_code is a useless variable. Instead of using it:
Code: [Select]
        if(code_read[a] == '#')
        {
           if(step1==0)
           {
               IntrodID();
           }
           else
          {
                IntrodPass();
          }
        }

Putting every { and every } on new lines, as I have done, would make your code easier to read.

Now, in IntroID(), there is no need to test End_code. and your first if statement could be
Code: [Select]
   if(memcmp(ID, code_read, 5) == 0)
which is much shorter than what you have now.

The second if statement is pretty stupid, too. It should be
Code: [Select]
   else
If the code was not correct, it can't be anything but wrong, can it?

Once the user has entered the correct password once, and the password that was entered has been erased, why would you then call IntroPass()? IntroID() should not call IntroPass().
The art of getting good answers lies in asking good questions.

Markham

Hi,

I'm sorry I haven't said anything before but I have been out the whole weekend, I tried changing it on friday and asside the dramatic change on the code it's still not working as intended. Tommorow I'll take a better look at the code and then get back here.

I don't have alot of experience writing code so the memcmp looks really cool, and simple to use! Thanks alot! The way you choose to redo the use of # is really smart! I guess my lack of experience doesn't let me see so far... but I hope to do better! So bare with me! hehe

Go Up