Issues with the joystick & keypad library

Hi guys,

I have an issue, and i’ve been picking my brain since yesterday. I usually try to figure things on my own but now i need your help. I don’t really know all the technical details about the libraries and HID drivers.

So i made a joystick controller, for a flightsim, with a few switches and knobs. The rotors work fine, and the buttons individually, but when i activate more than 10 switches the chip doesn’t refresh the buttons anymore. As far as i could tell, it does not matter which switches.

I took the multimeter and mapped all the buttons to the respective pins. Note that each button was on in the OFF state. I have no duplicates and all the connections seem fine. In the pictures below you’ll see beside the switches some numbers. Those are not the ID’s from the button matrix picture. (don’t want to confuse you with those)

I’ve added all the details i could think of, and also the code. Please tell me if you need more. Thanks

EDIT : more info and pics
Board → ProMicro / flashed with Leonardo setting
A0,A1,A2,A3 for rotors
VCC → 5v rotors
GND → GND rotors
rotor push button not connected

EDIT: Each button has a diode before being connected to the pullup pin

//BUTTON BOX 
//USE w ProMicro
//Tested in WIN10 + Assetto Corsa
//AMSTUDIO
//20.8.17

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

#define ENABLE_PULLUPS
#define NUMROTARIES 2
#define NUMBUTTONS 32
#define NUMROWS 6
#define NUMCOLS 6


byte buttons[NUMROWS][NUMCOLS] = {
  {0,1,2,3,4,5},
  {8,9,10,11,12,13},
  {15,16,17,18,19,20},
  {26,27,28,29,30,31},
  {21,22,23,24,25},
  {6,7},
};

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

rotariesdef rotaries[NUMROTARIES] {
  {18,19,32,33,0},
  {20,21,34,35,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] = {2,4,5,7,6,3}; 
byte colPins[NUMCOLS] = {8,9,10,16,14,15}; 
const int size = sizeof(colPins) / sizeof(int);

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

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

void setup() {
  
    for (int i = 0; i < size; i++)
      pinMode(colPins[i], INPUT_PULLUP); 
      
  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:
                    case HOLD:
                            Joystick.setButton(buttbx.key[i].kchar, 1);
                            break;   
                    case RELEASED:
                    case IDLE:
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
              }
           }   
         }
     }
}


void rotary_init() {
  for (int i=0;i<NUMROTARIES;i++) {
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
    #ifdef ENABLE_PULLUPS
      digitalWrite(rotaries[i].pin1, HIGH);
      digitalWrite(rotaries[i].pin2, HIGH);
    #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);
    };
  }
}

OK, let's look at these.
IMG_20200327_145033_resized.jpg

IMG_20200327_145115_res.jpg

pro_micro.jpg

Please read the instructions then go back and modify your original post to cite the code as described in item 7.

It does matter which switches you have on simultaneously, but it will be confusing to enumerate it. Suffice it to say you need to include a diode in series with each switch.

Hi, thanks for the advice. I've modified the code snippet. I've mentioned above that each button has a diode between itself and the pullup pin

ktzzz:
I’ve mentioned above that each button has a diode between itself and the pullup pin

Not quite sure what that actually means.

Otherwise, I don’t quite know how the Keypad library operates, so I can’t answer much about it now.

Solved it. There’s a limit to active buttons in Keypad.h
If you have the same issue just modify LIST_MAX with the number of simultaneous buttons pressed.