Is this Possible - Encoder Matrix

OK I just have a question as to if something is possible and what I need to look at doing to make it happen.. My current sketch is working perfectly with a Matrixed Button Inputs and Encoder support using the Standard Digital inputs via the Buxtronics Encoder decoding programming.

The Question I have is if there is any way to move the Encoders into the (or a second) Matrix and then be able to feed a button state ( 1 or 0 ) for two specific positions in the matrix to the Buxtronics Encoder instead of checking the Encoder Pin1 and Encoder Pin 2 via digitalRead (as it is currently done).

What I am hoping to do is be able to have a Matrix of encoders that are monitored and decoded for CW and CCW Gamepad button Presses to reduce wiring to the controller board.

Right now this works but the encoders eat up the use of quite a few pins on the Microprocessor.

I have been trying out some different codes but I am very new to this and I haven't got anything with the encoder Matrixing that has even come CLOSE to working.

I figure it should be able to be done I just can't seem to figure it out as the keypad buttons issue the Keystates which should be able to somehow be converted to 1 and 0 states which should be able to be substituted for the DigitalRead state 1 and 0.

Problems I have found though is how to possibly group the 2 numbers of each encoder so that Pin 1 and Pin 2 can be together and read concurrently so the grey code of the encoder flows to the Decoder properly and doesn't get mixed up with other encoder signals in the matrix.

Anyway Sorry I don't have code as such for this but because it is currently working without the Encoder Matrix it seems to me it is more of a theoretical question where I just need a little guidance for where to research.

Thank you

Please read the forum guidelines in the sticky post and provide the information you failed to include in your post above. Without that, the most accurate answer we can give is "maybe".

What I can say is that reading rotary encoders requires fast responses from the mcu, otherwise movements can be missed. Reading the encoders as part of a key matrix may not allow a fast enough response.

OK here is the encoder code I am using currently:

which is basically the buxtronics code which uses a loop table to not Miss encoder output as it works on a state change table:


//Define Rotary Physical Addressing
struct rotariesdef {
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;

// Define Rotary Pin and Number Map
// { PinCCW, PinCW, ButtonCCW, ButtonCW, Initial State}
rotariesdef rotaries[NUMROTARIES] {
   { 9, 10, 17, 18, 0},
   { 11, 12, 19, 20, 0},
   { 13, 14, 21, 22, 0},
   { 15, 16, 23, 24, 0}

//Rotary Decoding

// #define HALF_STEP    //Uncomment #define HALF_STEP this for HALFSTEP encoder operation
#define DIR_CCW 0x10
#define DIR_CW 0x20
#define DIR_NONE 0x0

#ifdef HALF_STEP        // Use the half-step state table (emits a code at 00 and 11)
#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,     DIR_NONE},
  {R_START_M | DIR_CW,   R_CW_BEGIN,       DIR_NONE,        DIR_NONE},
  // R_START_M (11)
  {R_START_M,            R_CCW_BEGIN_M,    R_CW_BEGIN_M,    DIR_NONE},
  {R_START_M,            R_START_M,        R_CW_BEGIN_M,    DIR_NONE | DIR_CW},
  {R_START_M,            R_CCW_BEGIN_M,    R_START_M,       DIR_NONE | DIR_CCW},

#else     // Use the full-step state table (emits a code at 00 only)
#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
  {DIR_NONE,        R_CW_BEGIN,       R_CCW_BEGIN,     DIR_NONE},
  {R_CW_NEXT,       DIR_NONE,         R_CW_FINAL,      DIR_NONE | DIR_CW},
  {R_CW_NEXT,       R_CW_BEGIN,       DIR_NONE,        DIR_NONE},
  // R_CW_NEXT
  {R_CW_NEXT,       R_CW_BEGIN,       R_CW_FINAL,      DIR_NONE},
  {R_CCW_NEXT,      DIR_NONE,         R_CCW_BEGIN,     DIR_NONE},
  {R_CCW_NEXT,      R_CCW_FINAL,      DIR_NONE,        DIR_NONE | DIR_CCW},

// Rotary Initialization
/* Call this once in setup(). */
void rotary_init() {
    for (int i=0;i<NUMROTARIES;i++) {
       pinMode(rotaries[i].pin1, INPUT);
       pinMode(rotaries[i].pin2, INPUT);
       digitalWrite(rotaries[i].pin1, HIGH);
       digitalWrite(rotaries[i].pin2, HIGH);

void setup() {

void loop() { 

void CheckAllEncoders(void) {
    for (int i=0; i<NUMROTARIES; i++) // Scan the rotary list.
        unsigned char result = rotary_process(i);
        if (result == DIR_CCW) {
            Joystick.button(rotaries[i].ccwchar, 1); delay(0); Joystick.button(rotaries[i].ccwchar, 0);
        if (result == DIR_CW) {
            Joystick.button(rotaries[i].cwchar, 1); delay(0); Joystick.button(rotaries[i].cwchar, 0);

// Check State Of Rotatry Encoder - Returns 0 on no event, otherwise 0x80 or 0x40 depending on the direction
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);

This all works fine as is and is very quick to respond and doesn’t have any delays, the very last part of the code (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1) is where the encoder pin state is detected… So basically I want to read the matrix for the Encoder state A / B (1 / 0) state and request and watch a pair of matrix positions. as of course if it watches the entire Matrix and only detects state changes I think the encode mapping would get confused.

Ok and right now the Keypad.h matrix is what I plan on using but it could be something different.

Thanks for posting your code and for using code tags. But please read the forum guidelines again, there is other stuff you missed which would really help us to help you.