Arduino Keypad lib 4.0 augmented with password/secret code recognition

Hi all,

In need for a keypad library supporting sequences of keys (aka passwords or secret/non-scret codes...), I've been observing that most users reimplemented the code detection on their own and thus I decided to make this feature built-in in the "official" Keypad library.

After few coding, I got a lib supporting secret codes and backward compatible with sketches using the Keypad library <3.1. It's not much work but it can avoid spending time uselessly to reimplement this feature every time.

Everything is on github, with an included sample.... and it's RFC :slight_smile:

Hi myoan,

I just caught the changes you made to the Keypad library and it looks really clean. However, "My" version of the Keypad library is not so "official" ;). I originally wrote it for myself and then just got carried away trying to make it as simple as possible to use. I've had many people ask for the ability to que arbitrary strings or numbers but I couldn't figure out how to do it without inheriting the string library. I wonder if you would be willing to give it a try and extend your changes even further?

-Mark

Hi,

Yes that's what I had understood, but it seems the most popular keypad lib used. Even chinese sellers on ebay add a link to this lib to explain how to use the keypad you've bought with an Arduino :slight_smile:

I've had many people ask for the ability to que arbitrary strings or numbers

You mean using any type instead of a char as a key identifier? If yes inheriting from string or any custom classes seems the cleanest implementation indeed. But an issue remains to use primitive types, especially "int" since there is no standard Integer class. Maybe everything can be represented as a string, and then we can allow implicit conversions to go back to primitive types like int or char.

That's not that clean, and it will increase memory consumption. What do you think about it?

Why not, I can give a try. Let's add that in my todo list :wink:

I'm not even completely sure what I mean...

I've been asked for passwords (like your utility), strings, and numbers (ints, floats, hex) greater than a single keypress. Basically whatever the person wanted in their sketch at the time.

It got me thinking that maybe a buffer could be implemented. I'm still not sure about returning different types. I thought I would have to use C++ templates but I wanted the library code to remain simple enough for sketch authors. I guess templates aren't any worse than the virtual functions I used. I'm also trying to be careful about adding things that aren't keypad related. For example, it doesn't make sense to have the keypad performing math functions.

I guess the same could be said about passwords but I really liked the method you used to implement it. That's what got me back on the idea of a buffer, or que. It would be great to have a que that could return any type.

So those are my thoughts but I'm not really committed to anything. It's just that your code brought everything to the front again. Thanks :wink:

-Mark

Ok, if I understand well what they would like to do is, for instance, typing 0.0001 or 0x0001 or abcdef on they keypad and receive respectively the float value 0.0001, the hex value 0x0001 and the string "abcdef"?

So we don't need to change anything to the current char representing a key.

Unfortunately runtime type info (RTTI) is disabled by default by the arduino compiler. They have probably good reasons not to allow it so I don't want to bypass that and find another way to implement a generic queue. I decided to provide manually the output type as a parameter. Here is the prototype I coded:

/* Write the last "length" chars in the buffer "buffer" of type "type"*/
bool Keypad::getQueue(byte length, byte type, void *buffer);

/* Usage */
float f; int i; char str[6]; long l;
bool ok = k.getQueue(5, TYPE_FLOAT, &f); // This allow to read 0.001 for instance
ok = k.getQueue(5, TYPE_INT, &i);
ok = k.getQueue(5, TYPE_STR, str);
ok = k.getQueue(5, TYPE_HEX, &l);

I've coded this function quickly but apparently I've got an incorrect memory access somewhere cause the output is sometimes polluted by random data. I have to deepen that before pushing, but tell me what do you think of such a method?

The drawback is that you have to know by advance the max number of chars that you're gonna read.

I like this idea a lot. I think you understand better than I did what the sketch author might like. :wink:

Having the sketch author define the length is OK. I can provide example sketches that will help. Later on, if Arduino starts to use RTTI, a simpler getQueue() function could be written.

I can't see anything wrong with your idea. It is clean and easy to use. One minor thing... Would you consider changing the function name? I generally try to use words that make sense to artists as that is the Arduino's target market. I don't have any ideas right now but maybe we can think of something.

I can provide example sketches that will help

Yes, why not.

I solved the random values bug yesterday ("== '\0'" instead of "=" ....). Hopefully I will be able to push tonight (UTC+1).

I was thinking to change the method names as well, but I don't know what. I would like to keep "queue" or "buffer" to suggest it uses a longlife buffer and so needs to be reset sometimes. "Queue" is more expressive than "buffer" is the sense that it implies that old values are replaced by new ones.

Maybe "read" would be more suggestive: readQueue(...), or readBuffer(...).

Do we keep the testCode(...) function? It's useful for passwords, and avoid getting the string with getQueue() and then comparing manually whether it's equal to the password.

bool Keypad::testCode(const char* code, byte codeLength);
bool accessGranted = k.testCode("12345", 5);

It's done btw, can you try and tell me what you think about it?

I'm also thinking to create a program helping the user setting up the keyboard, instead of measuring manually the pins with a ohmeter.

myoan:
It's done btw, can you try and tell me what you think about it?

Sorry, but I'm back in school now so it won't be until May before I can take a serious look. But if I can find some time before then I will do it.

I'm also thinking to create a program helping the user setting up the keyboard, instead of measuring manually the pins with a ohmeter.

I thought about that too. But I couldn't get around the problem of what to do with all the unused pins. For example, my keypad has 14 pins but only 7 of them are used. Wires would have to be soldered to all 14 pins and then connected to the Arduino. After running the sketch the unused wires would have to be unsoldered. That seemed like a waste of time to me especially if the person doesn't have a soldering iron and either has to borrow one or take the Arduino to a friends house.

So now that you have all my excuses for not doing it please don't let me discourage you. This is a very good example of using matrices in code and it could be beneficial just going through the steps. Then go ahead and post the code anyway because you never know who might actually want to use it.

I'm back in school now so it won't be until May before I can take a serious look.

Really? Is you school a jail lost nowhere? ^^

That seemed like a waste of time to me

Well, it's just a question of good organization?

I would say in most cases it's possible to plug the keypad on the board without soldering, just for prototyping, if it has wires, or male female pins. Your issue is true when there are none of these and you have to solder wires on electronic tracks.

Thus imo it's worth creating the program and let the user choosing to use an ohmeter or the program to identify the pins. I would say a good explanation with a red warning "avoid soldering the pins during setup, since some pins may have to be unplugged" are enough to let people free choosing between both procedures.