/*

   Forum: https://forum.arduino.cc/t/button-matrix-and-sx1509-wiring/1176266/17
   Wokwi: https://wokwi.com/projects/378388105009033217

   Keyboard matrix for 20 buttons
   uses 4 pins for the rows
   and 5 pins for the columns


*/


//Keyboard Matrix
int keyrow[] = {8, 9, 10};
int keycol[] = {2, 3, 4};
int col_scan;
int last_scan = -1;

constexpr int noOfRows  = sizeof(keyrow) / sizeof(keyrow[0]);
constexpr int noOfColumns = sizeof(keycol) / sizeof(keycol[0]);
constexpr int noOfKeys = noOfRows*noOfColumns;

boolean matrix[noOfKeys];


void setup()
{
  Serial.begin(115200);
  for (int i = 0; i < noOfRows; i++)
  {
    //Init rows
    pinMode(keyrow[i], OUTPUT);
  }
  for (int i = 0; i < noOfColumns; i++)
  {
    //Init columns
    pinMode(keycol[i], INPUT_PULLUP);
    digitalWrite(keycol[i], HIGH);
  }
}


void loop()
{
  if (buttonPressed()) {
    takeAction();
  }
}

boolean buttonPressed() {
  //Search for a pressed key
  static boolean keyPressed = false;
  static unsigned long lastPressTime = 0;
  if (keyPressed && millis() - lastPressTime < 200) {
    // 300 msec as a simple way of debouncing
    // and to slow down repetition of the same action
    return false;
  }
  keyPressed = false;
  for (int j = 0; j < noOfRows; j++) {
    pinMode(keyrow[j], INPUT);
    digitalWrite(keyrow[j], HIGH);
  }
  for (int i = 0; i < noOfRows; i++)
  {
    pinMode(keyrow[i], OUTPUT);
    digitalWrite(keyrow[i], LOW);
    for (int j = 0; j < noOfColumns; j++)
    {
      col_scan = digitalRead(keycol[j]);
      int keyNo = j + i*noOfColumns;
      if (col_scan == LOW)
      {
        lastPressTime = millis();
        keyPressed = true;
        matrix[keyNo] = true;
      } else {
        matrix[keyNo] = false;
      }
    }
    pinMode(keyrow[i], INPUT);
   digitalWrite(keyrow[i], HIGH);
  }
  return keyPressed;
}


void takeAction()
{
 for (int i=0;i<noOfKeys;i++){
  if (matrix[i]) {
    Serial.print(i+1);
    Serial.print(" ");
  }
 }
 Serial.println();
}