Dual Keypads with Leonado

I have an Arduino Leonardo board successfully passing key presses to my PC from a single 4x3 Key Pad.
Now I need to add a second 4x3 Key Pad.
Here is the code that I have working at present:-

1  #include <Key.h>
2  #include <Keypad.h>
3  #include <Keyboard.h>

4  //Set the number of rows and columns on the keypad
5  const byte ROWS = 4;
6  const byte COLS = 3;

7 //Define which characters are printed when a particular button is pressed on the keypad.
8 //`The characters are laid out just as they appear on the keypad.
9    char hexaKeys[ROWS][COLS] = {
10     {'#', '0', '*'},
11     {'9', '8', '7'},
12    {'6', '5', '4'},
13     {'3', '2', '1'} 
14   };

15  byte rowPins[ROWS] = {9, 8, 7, 6};
16  byte colPins[COLS] = {5, 4, 3};

17  Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

18  void setup() { }

19 void loop() {
20   char customKey = customKeypad.getKey();

21   if (customKey) {
22    Keyboard.begin();
23       Keyboard.write(customKey);
24       Keyboard.end();
25     }
26  }

To add a second key pad two issues arise in my mind:-
A) I will have to attach seven more wires to my Leonardo. This means that I will overflow the digital pins and need to use the Analog pins. Will that work?

B) I think that I will need to create a second instance of the function "keypad" in line 17 but I am not sure how to do this. Is there anyone here able to get me started with that?

A) Yes. On most types of Arduino, most analog pins can also be used as digital pins. There are exceptions such as A6, A7 on Nano 3. As far as I know all analog pins can be used as digital on Leonardo.

B) You don't want to create another instance of the Keypad() function. You want to create another instance of a Keypad object. If you are new to the concepts of Object Orientated Programming, it's easy to get confused.

However, do you really need to create another Keypad object? Could you not simply extend your existing keypad matrix to include more keys? This would be simpler and use fewer pins.

Yes Paul. Thanks for such a swift response.
I did do a course (plus exam) in Object Orientated Programming 22 years ago (Visual Basic.net). I was confused then and I remain confused to this day. Maybe it's Alzheimers, but in truth I have always been surprised if any code I composed ever worked. :slight_smile:
I initially explored the concept you offered in this way:-

line 15  byte rowPins[ROWS] = {12, 11, 10, 9, 8, 7, 6, 5};
line16  byte colPins[COLS] = {A1, A0, 13, 4, 3, 2};

But another friend said that wouldn't work. So I started looking at the Keypad object but couldn't get started.
Hence my appeal for a nudge.

That's not right. Your enlarged keypad would be 6x4 (requiring 10 pins) or possibly 3x8 (requiring 11 pins). Your updated code (using 14 keys pins) would be correct for an 8x6 keypad containing 48 keys!

Maybe the hint you need is that you can use the same row pins for both keypads. That's if you opt for a 6x4 arrangement. Alternatively you could use the same column pins if you opt for a 3x8 matrix.

Oh. Are you suggesting replacing my existing 4x3 keypad with a larger version with more rows and columns?

No, I'm suggesting you connect your 2 3x4 matrices as though they are a single 6x4 or 3x8 matrix.

Thank you very much for the guidance.
I will think on this and experiment with my code.

Point is, you only need 3 or 4 additional pins and you use the same code instance.

//Set the number of rows and columns on the keypad
const byte ROWS = 4;
const byte COLS = 6;

//Define which characters are printed when a particular button is pressed on the keypad.
//`The characters are laid out just as they appear on the keypad.
char hexaKeys[ROWS][COLS] = {
     //Keypad A      //Keypad B
     {'#', '0', '*', 'A', 'B', 'C'},
     {'9', '8', '7', 'D', 'E', 'F'},
     {'6', '5', '4', 'G', 'H', 'I'},
     {'3', '2', '1', 'J', 'K', 'L'} 
   };

byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, A0, A1, A2};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

With this arrangement, pins 9, 8, 7, 6 would be connected to the row pins of both 3x4 keypads in parallel. Pins 5, 4, 3 would connect to the columns of keypad A and A0, A1, A2 to the columns of keypad B.

1 Like

Paul.
This is awesome information!
The reason I have been silent for 4 days is that I have been installing the two keypads and running the wires.
32a Installation & Wiring 220707
(Second handle is to be mounted on the shaft at the left/near end)
My two keypads are identical so would I write the "hexaKeys" definition as below?

char hexaKeys[ROWS][COLS] = {
     //Keypad A      //Keypad B
     {'#', '0', '*', '#', '0', '*'},
     {'9', '8', '7', '9', '8', '7'},
     {'6', '5', '4', '6', '5', '4'},
     {'3', '2', '1', '3', '2', '1'} 
   };

Regards

Am I missing somethign?

If they are identical and perform the same function, why can they not be connected in parallel?

1 Like

In appearance and function? If so I, and you had included that fact in your original post, we could have saved a lot of time!

My sincerest apologies and I am sorry you feel that you wasted your time..
However, none of the above has been a waste of time as far as I am concerned.
All of it was helpful and enlightening for me. Which I expect, would be one of your goals.
In that case you have succeeded and I am grateful.
I would have posted the photograph earlier but at that time I hadn't found out how to upload one (an "aha!" moment).
I was also uncertain about how the Arduino would respond to having two buttons on a single pin (another "Aha!" moment).
Now, as you can see in the photo, I have a practical difficulty with the limited space to work inside that yoke mechanism. This is compounded by two things - my shaking hands and my failing eyesight.
Having physically struggled to get it together to this point it is clear to me that plugging the 7 wires from the second keypad straight in to the Leonardo would be easiest way to get the thing all working.
That brings me back to the original idea of creating a unique "Object" in the code representing each keypad.

So if anyone has the patience to give me a starting line to help me get going with the dual keypad concept that would be awesome.

We can an help with that, but what's important is that you understand why and when you would want to do that. In your project shown above, you would not do that.

Two identical/duplicate keypads: wire them in parallel, no need to change code, only one Keypad object needed.

Two different keypads: wire them as a single, larger keypad, using as many common row/column pins as possible between the two keypads. Only one Keypad object needed. See post #10 for code example.

Two different keypads where none of the same pins can be shared for some reason (I can't think of a good example where this would be the case): use 2 Keypad objects.

There are two ways to make more than one Keypad object.

One way is to simply declare them as different objects with unique names:

Keypad customKeypadA = Keypad(makeKeymap(hexaKeysA), rowPinsA, colPinsA, ROWS_A, COLS_A);
Keypad customKeypadB = Keypad(makeKeymap(hexaKeysB), rowPinsB, colPinsB, ROWS_B, COLS_B);

Here, one object is called customKeypadA and the other is customKeypadB. The other arrays are also duplicated as A and B because different pins and different key symbols would be used, and in case the keypads are different sizes, different constants to describe the size of each keypad.

The second would be to use an array of Keypad objects:

Keypad customKeypad[2] = {
  Keypad(makeKeymap(hexaKeysA), rowPinsA, colPinsA, ROWS_A, COLS_A),
  Keypad(makeKeymap(hexaKeysB), rowPinsB, colPinsB, ROWS_B, COLS_B)
};
1 Like

Thank you PaulRB
I have chosen to declare them as different objects with unique names according to your first suggestion.
When I finished writing the sketch it compiled without error.
I will have to complete running my wires before I can check how successful I have been.
I show it below for comment should you wish.

// This sketch tries to create two unique "Objects" representing the two keypad.
// The Leonado has 14 wires plugged in.  From Pins 3 to 9 and from A0 to A6.
// The two Keypad objects will be customKeypadA and customKeypadB

#include <Keypad.h>
#include <Keyboard.h>

//Set the number of rows and columns on the keypads
const byte ROWS_A = 4;
const byte COLS_A = 3;
const byte ROWS_B = 4;
const byte COLS_B = 3;

//Define which characters are printed when a particular button is pressed on the keypad.
//`The characters are laid out just as they appear on the keypad.
char hexaKeysA[ROWS_A][COLS_A] = {
  {'#', '0', '*'},
  {'9', '8', '7'},
  {'6', '5', '4'},
  {'3', '2', '1'} 
};

char hexaKeysB[ROWS_B][COLS_B] = {
  {'#', '0', '*'},
  {'9', '8', '7'},
  {'6', '5', '4'},
  {'3', '2', '1'} 
};

byte rowPinsA[ROWS_A] = {9, 8, 7, 6};
byte colPinsA[COLS_A] = {5, 4, 3};

byte rowPinsB[ROWS_B] = {A6, A5, A4, A3};
byte colPinsB[COLS_B] = {A2, A1, A0};


Keypad customKeypadA = Keypad(makeKeymap(hexaKeysA), rowPinsA, colPinsA, ROWS_A, COLS_A);
Keypad customKeypadB = Keypad(makeKeymap(hexaKeysB), rowPinsB, colPinsB, ROWS_B, COLS_B);

void setup() { }

void loop() {
  char customKeyA = customKeypadA.getKey();
  char customKeyB = customKeypadB.getKey();

  if (customKeyA) {
      Keyboard.begin();
      Keyboard.write(customKeyA);
      Keyboard.end();
    }
    else if (customKeyB) {
      Keyboard.begin();
      Keyboard.write(customKeyB);
      Keyboard.end();
    }
    else if (customKeyA && customKeyB) {
    // Do nothing
    }
}

//End

Thank you once again.

My only comment is to say again what both @Paul_B and myself have pointed out. In your project, you can simply connect your two identical keypads to the same Arduino pins. There is no need to use two Keypad objects or to change your original code in any way.

You may have learned something new by making these code changes, which is great, but you have also used more Arduino pins and complicated your code unnecessarily, which will make it more difficult to maintain and enhance in future, which is not so great.

So my advice would be to continue to test your new code and prove to your own satisfaction that it now works correctly, and you learned what you wanted to learn, but then simplify the circuit and code again.

1 Like

Advice accepted.
Cheers & thanks again

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.