I have made a button box for PC gaming. All buttons work fine 1-25 (I used a 5x5 matrix for wiring) but the problem is when two toggles are activated simultaneously when another button is pressed it activates multiple buttons. I need to be able to have multiple buttons pressed at the same time with no conflict. I assume it is in the code I am using? Any help to point me in the right direction would be appreciated.
//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);
}
}
}