Help with button matrix and diodes

I am in need of guidance on my button box project. A little background on the box and myself. First off I am very new to this kind of project and both excited and nervous at the same time. I wired the box using a 5x5 matrix with a single rotary encoder and all buttons work fine. The problem is there are a couple of toggle switches that when 2 or more are activated and another button is pressed it activates multiple buttons at once. I understand from a previous post that I need to add diodes to each button to prevent that from happening but I have some questions about it. Which type of diode do I need to use and do I need to rewire the buttons to accommodate the diodes or just add them to my existing wiring? I will provide the code I am using and two images of the wiring schematic for you all to help me but I have never done a schematic before so I have no idea if it will help. I am grateful for all the assistance I have received in this forum and hope to get this solved. Thanks in advance

//BUTTON BOX
//USE w ProMicro
//BIGGINS 09-08-22

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMROTARIES 3
#define NUMBUTTONS 25
#define NUMPOTS 1

#define NUMROWS 5
#define NUMCOLS 5
byte buttons[] =
{
  // We are using .kcode (the index, 0-24) instead of 
  // .kchar (the character from this table) so
  // these letters are unused and arbitrary as long as 
  // they are each unique and none of them are '\0'.
  "ABCDE"
  "FGHIJ"
  "KLMNO"
  "PQRST"
  "UVWXY"
};

struct rotariesdef
{
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;
};

rotariesdef rotaries[NUMROTARIES]
{
  {0, 1, 25, 26, 0},
};

#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0

#ifdef HALF_STEP
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] =
{
  // R_START (00)
  {R_START_M,            R_CW_BEGIN,     R_CCW_BEGIN,  R_START},
  // R_CCW_BEGIN
  {R_START_M | DIR_CCW, R_START,        R_CCW_BEGIN,  R_START},
  // R_CW_BEGIN
  {R_START_M | DIR_CW,  R_CW_BEGIN,     R_START,      R_START},
  // R_START_M (11)
  {R_START_M,            R_CCW_BEGIN_M,  R_CW_BEGIN_M, R_START},
  // R_CW_BEGIN_M
  {R_START_M,            R_START_M,      R_CW_BEGIN_M, R_START | DIR_CW},
  // R_CCW_BEGIN_M
  {R_START_M,            R_CCW_BEGIN_M,  R_START_M,    R_START | DIR_CCW},
};
#else
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const unsigned char ttable[7][4] =
{
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif

byte rowPins[NUMROWS] = {A1, A0, 15, 14, 16};
byte colPins[NUMCOLS] = {10, 9, 8, 7, 6};

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
                   JOYSTICK_TYPE_JOYSTICK, 32, 0,
                   false, false, false, false, false, false,
                   false, false, false, false, false);

void setup()
{
  Joystick.begin();
  rotary_init();
}

void loop()
{

  CheckAllEncoders();

  CheckAllButtons();

}

void CheckAllButtons(void)
{
  if (buttbx.getKeys())
  {
    for (int i = 0; i < LIST_MAX; i++)
    {
      if ( buttbx.key[i].stateChanged )
      {
        switch (buttbx.key[i].kstate)
        {
          case PRESSED:
            Joystick.setButton(buttbx.key[i].kcode, 1);
            break;

          case RELEASED:
            Joystick.setButton(buttbx.key[i].kcode, 0);
            break;

          case IDLE:
          case HOLD:
          default:
            break;
        }
      }
    }
  }
}


void rotary_init()
{
  for (int i = 0; i < NUMROTARIES; i++)
  {
#ifdef ENABLE_PULLUPS
    pinMode(rotaries[i].pin1, INPUT_PULLUP);
    pinMode(rotaries[i].pin2, INPUT_PULLUP);
#else
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
#endif
  }
}


unsigned char rotary_process(int _i)
{
  unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
  rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
  return (rotaries[_i].state & 0x30);
}

void CheckAllEncoders(void)
{
  for (int i = 0; i < NUMROTARIES; i++)
  {
    unsigned char result = rotary_process(i);
    if (result == DIR_CCW)
    {
      Joystick.setButton(rotaries[i].ccwchar, 1); 
      delay(50); 
      Joystick.setButton(rotaries[i].ccwchar, 0);
    }

    if (result == DIR_CW)
    {
      Joystick.setButton(rotaries[i].cwchar, 1); 
      delay(50); 
      Joystick.setButton(rotaries[i].cwchar, 0);
    }
  }
}


Thanks for posting code and the not complete schematics.
Your problem is very common. Search and find threads that have solved this issue.
Today, or maybe yesterday, this was discussed in forum.

Read this discussion:

https://www.gammon.com.au/forum/?id=14175

1N4148

Thanks for the reply. I had a look at the article and if I'm correct this is the schematic I need to follow but increase it for a 5x5 matrix? If I am missing anything please let me know. Could I also ask how to adapt the code for my purpose using the diodes?

Compare the circuit you drew to the one offered, go node by node.

Just wire your matrix similar to the offered one, read the link.

Sadly you are not correct.

If you make that schematic in post #4 every time you press a switch it will short out the supply. If powering it with USB you could damage the USB on your computer. The diodes need to be In series with the switch not in parallel.

You can't wire a rotary encoder into a matrix, you will not be able to read it fast enough.

I'm reading through the article posted by LarryD and I see my mistake. I thought the wires were connected but they are not. As I said I'm very new and learning. I see how it is wired but do I attach a wire from the column pin and then to 5V or does the pin supply the 5v? I am powering it with a USB. I should have mentioned that I apologize. It is a button box for PC gaming.

I have read the post again and changed up the wiring schematic and I hope this is correct. I appreciate everyone's patience in helping me figure this out. Unfortunately, I'm a little confused about the code I should use. Am I able to use and adapt the code in the article to suit my purpose?

Where in the schematic does it show the cathodes are connected to anodes ?

All you need to do is add one more column and one more row to get 5X5.

Do you understand where Row1-4 and Column1-4 connect ?

I'm sorry I'm not sure what you mean. Is that the symbol at the top of the diagram you shared? The sharp lines and the 10k?

image

I am assuming the rows would correspond to pins A1,A0,15,14,16 and the columns are pins 10,09,08,07,06. That is currently how I have the box wired. It is also power through usb.

What Arduino are you using ?

I'm using a Pro Micro 5V

Thank you very much for that it is extremely helpful. Do I also need the 10k resistor connected to a 5v pin on the board if I am using a USB cable to power it?

You need to wire your box as shown in the schematic.

  • However, you can do as the web site link did and use on the internal pullup resistors, you would not connect USB 5V to anything if this is done..

Yes, this involves scanning the matrix. The columns are inputs and the rows are outputs. So to scan the matrix you have to produce a walking zero on the rows. That means that at any time one of the rows is producing a zero on it and all the other row outputs are high.

The row that is currently low is the row you are looking at, by reading the columns. Any column you read as being low will indicate that the switch on that column / row intersection is being pressed. In other words your matrix is passing on the row low to the column input.

Note that if you are pressing any key on any other row (which will be high) will not affect the column inputs as they are high anyway due to the pull up resistor.

Note here the Analogue pins are being used as simple digital outputs. Yes you can do that.

I can't thank you guys enough. Grumpy_Mike and LarryD thank you a hundred times for your patience and understanding. I would not have figured this out on my own. You are both legends in my book. Cheers