How to read the active row and column from a keypad?

Hello, I am working on an arduino project to control an led matrix from a keypad matrix. Right now I would like to learn how to print to console the active button pressed by printing the row and column that correspond to that button. Any guidance would be appreciated, and here is the sample of the code I have written already.

#include <Adafruit_MCP23017.h>
#include <Keypad_MC17.h>
#include <Keypad.h>        // GDY120705
#include <Wire.h>

#define I2CADDR 0x20

#include "LedControl.h" //  need the library
LedControl lc = LedControl(12, 11, 10, 1); //LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);

byte val[8][8] = {0};

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'0', '1', '2', '3'},
  {'4', '5', '6', '7'},
  {'8', '9', 'A', 'B'},
  {'C', 'D', 'E', 'F',}
};


byte rowPins[ROWS] = {0, 1, 2, 3}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad_MC17 customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR);

Adafruit_MCP23017 mcp;

void setup() {
  //  Wire.begin( );
  customKeypad.begin( );        // GDY120705
  Serial.begin(9600);

  lc.shutdown(0, false); // turn off power saving, enables display
  lc.setIntensity(0, 8); // sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  //Add input button
  mcp.begin();      // use default address 0

  mcp.pinMode(0, INPUT);
  mcp.pullUp(0, HIGH);  // turn on a 100K pullup internally

}

void loop() {
  
  char customKey = customKeypad.getKey();

  if (customKey != NO_KEY) {

    //Serial.println(mcp.digitalRead(0));
    //Serial.println(digitalRead(colPins[COLS]));
    //Serial.println(COLS);
    Serial.println(customKey);
  }
  if (customKey == '0' && val[0][0] == 0)  {
    val[0][0] = 1;
    lc.setLed(0, 0, 0, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '0' && val[0][0] == 1) {
    val[0][0] = 0;
    lc.setLed(0, 0, 0, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '1' && val[0][1] == 0) {
    val[0][1] = 1;
    lc.setLed(0, 0, 1, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '1' && val[0][1] == 1) {
    val[0][1] = 0;
    lc.setLed(0, 0, 1, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '2' && val[0][2] == 0) {
    val[0][2] = 1;
    lc.setLed(0, 0, 2, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '2' && val[0][2] == 1) {
    val[0][2] = 0;
    lc.setLed(0, 0, 2, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '3' && val[0][3] == 0) {
    val[0][3] = 1;
    lc.setLed(0, 0, 3, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '3' && val[0][3] == 1) {
    val[0][3] = 0;
    lc.setLed(0, 0, 3, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '4' && val[1][0] == 0) {
    val[1][0] = 1;
    lc.setLed(0, 1, 0, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '4' && val[1][0] == 1) {
    val[1][0] = 0;
    lc.setLed(0, 1, 0, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '5' && val[1][1] == 0) {
    val[1][1] = 1;
    lc.setLed(0, 1, 1, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '5' && val[1][1] == 1) {
    val[1][1] = 0;
    lc.setLed(0, 1, 1, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '6' && val[1][2] == 0) {
    val[1][2] = 1;
    lc.setLed(0, 1, 2, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '6' && val[1][2] == 1) {
    val[1][2] = 0;
    lc.setLed(0, 1, 2, false);
    customKey = '\0';
    delay(200);
  }
  if (customKey == '7' && val[1][3] == 0) {
    val[1][3] = 1;
    lc.setLed(0, 1, 3, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey == '7' && val[1][3] == 1) {
    val[1][3] = 0;
    lc.setLed(0, 1, 3, false);
    customKey = '\0';
    delay(200);
  }



}

One obvious way would be to read the character using getKey() then iterate through the hexaKeys array to find it, With only 16 entries to test at most it would be quite fast to execute

Thank you for your quick reply. Could you write that in a sample line of code? I am having trouble visualizing what you wrote. Forgive me because I am a novice, but thank you again for taking the time to help me!

Another obvious method would be to put a row/colum encoding in the returned char.

char hexaKeys[ROWS][COLS] = {
  {0x11, 0x12, 0x13, 0x14},
  {0x21, 0x22, 0x23, 0x24},
  {0x31, 0x32, 0x33, 0x34},
  {0x41, 0x42, 0x43, 0x44},
};

2 nested for loops

int row;
int col;
for (row = 0; row < 4; row++)
  {
    for (col = 0; col < 4; col++)
     {
        if (hexaKeys[row][col] == targetChar)
          {
             break;  //row and col are where the character is located
          }
      }
  }

EDIT : actually there is a problem with this simple code as on finding the match the code needs to exit both loops. Not difficult to fix but I don’t want to complicate the posted code by adding edits to it

Another obvious method would be to put a row/colum encoding in the returned char.

I considered suggesting that but we don't know whether the actual character has any significance

I should clarify, that the reason why I want to know the row and column of the active button pressed is because I want to use those two numbers to feed a second array that is the lc.setled array to toggle the led's on and off.

I want to start off by printing it to the serial monitor to know I am on the right track. Such as a digitalread active button print to serial monitor. Currently I am using the MCP23017 shift register that makes a bit more complicated.

See reply #4

byte row;
byte col;
byte matchCol;
byte matchRow;
for (row = 0; row < 4; row++)
{
  for (col = 0; col < 4; col++)
  {
    if (hexaKeys[row][col] == targetChar)
    {
      matchCol = col;
      matchRow = row;
    }
  }
}

Thank you, that worked and I implemented it into my code.

#include <Adafruit_MCP23017.h>
#include <Keypad_MC17.h>
#include <Keypad.h>        // GDY120705
#include <Wire.h>

#define I2CADDR 0x20

#include "LedControl.h" //  need the library
LedControl lc = LedControl(12, 11, 10, 1); //LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);

byte val[8][8] = {0};

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'0', '1', '2', '3'},
  {'4', '5', '6', '7'},
  {'8', '9', 'A', 'B'},
  {'C', 'D', 'E', 'F',}
};


byte rowPins[ROWS] = {0, 1, 2, 3}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the keypad

byte row;
byte col;
byte matchCol;
byte matchRow;

//initialize an instance of class NewKeypad
Keypad_MC17 customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR);

Adafruit_MCP23017 mcp;

void setup() {
  //  Wire.begin( );
  customKeypad.begin( );        // GDY120705
  Serial.begin(9600);

  lc.shutdown(0, false); // turn off power saving, enables display
  lc.setIntensity(0, 8); // sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  //Add input button
  mcp.begin();      // use default address 0

  //mcp.pinMode(0, INPUT);
  //mcp.pullUp(0, HIGH);  // turn on a 100K pullup internally

}

void loop() {



  char customKey = customKeypad.getKey();

  for (row = 0; row < 4; row++)
  {
    for (col = 0; col < 4; col++)
    {
      if (hexaKeys[row][col] == customKey)
      {
        matchCol = col;
        matchRow = row;
      }
    }}

    if (customKey != NO_KEY) {

      //Serial.println(mcp.digitalRead(0));
      //Serial.println(digitalRead(colPins[COLS]));
      //Serial.println(COLS);
      Serial.println(matchRow);
      Serial.println(matchCol);
    }
    if (customKey == '0' && val[0][0] == 0)  {
      val[0][0] = 1;
      lc.setLed(0, 0, 0, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '0' && val[0][0] == 1) {
      val[0][0] = 0;
      lc.setLed(0, 0, 0, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '1' && val[0][1] == 0) {
      val[0][1] = 1;
      lc.setLed(0, 0, 1, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '1' && val[0][1] == 1) {
      val[0][1] = 0;
      lc.setLed(0, 0, 1, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '2' && val[0][2] == 0) {
      val[0][2] = 1;
      lc.setLed(0, 0, 2, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '2' && val[0][2] == 1) {
      val[0][2] = 0;
      lc.setLed(0, 0, 2, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '3' && val[0][3] == 0) {
      val[0][3] = 1;
      lc.setLed(0, 0, 3, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '3' && val[0][3] == 1) {
      val[0][3] = 0;
      lc.setLed(0, 0, 3, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '4' && val[1][0] == 0) {
      val[1][0] = 1;
      lc.setLed(0, 1, 0, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '4' && val[1][0] == 1) {
      val[1][0] = 0;
      lc.setLed(0, 1, 0, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '5' && val[1][1] == 0) {
      val[1][1] = 1;
      lc.setLed(0, 1, 1, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '5' && val[1][1] == 1) {
      val[1][1] = 0;
      lc.setLed(0, 1, 1, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '6' && val[1][2] == 0) {
      val[1][2] = 1;
      lc.setLed(0, 1, 2, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '6' && val[1][2] == 1) {
      val[1][2] = 0;
      lc.setLed(0, 1, 2, false);
      customKey = '\0';
      delay(200);
    }
    if (customKey == '7' && val[1][3] == 0) {
      val[1][3] = 1;
      lc.setLed(0, 1, 3, true);
      customKey = '\0';
      delay(200);
    }

    if (customKey == '7' && val[1][3] == 1) {
      val[1][3] = 0;
      lc.setLed(0, 1, 3, false);
      customKey = '\0';
      delay(200);
    }

  }

I was also able to truncate my code to remove duplication’s to feed the rows and columns directly into the arrays.

#include <Adafruit_MCP23017.h>
#include <Keypad_MC17.h>
#include <Keypad.h>        // GDY120705
#include <Wire.h>

#define I2CADDR 0x20

#include "LedControl.h" //  need the library
LedControl lc = LedControl(12, 11, 10, 1); //LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);

byte val[8][8] = {0};

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'0', '1', '2', '3'},
  {'4', '5', '6', '7'},
  {'8', '9', 'A', 'B'},
  {'C', 'D', 'E', 'F',}
};


byte rowPins[ROWS] = {0, 1, 2, 3}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the keypad

byte row;
byte col;
byte matchCol;
byte matchRow;

//initialize an instance of class NewKeypad
Keypad_MC17 customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR);

Adafruit_MCP23017 mcp;

void setup() {
  //  Wire.begin( );
  customKeypad.begin( );        // GDY120705
  Serial.begin(9600);

  lc.shutdown(0, false); // turn off power saving, enables display
  lc.setIntensity(0, 8); // sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen
  //Add input button
  mcp.begin();      // use default address 0

  //mcp.pinMode(0, INPUT);
  //mcp.pullUp(0, HIGH);  // turn on a 100K pullup internally

}

void loop() {



  char customKey = customKeypad.getKey();

  for (row = 0; row < 4; row++)
  {
    for (col = 0; col < 4; col++)
    {
      if (hexaKeys[row][col] == customKey)
      {
        matchCol = col;
        matchRow = row;
      }
    }
  }

  if (customKey != NO_KEY) {

    //Serial.println(mcp.digitalRead(0));
    //Serial.println(digitalRead(colPins[COLS]));
    //Serial.println(COLS);
    Serial.println(matchRow);
    Serial.println(matchCol);
  }
  if (customKey != '\0' && val[matchRow][matchCol] == 0)  {
    val[matchRow][matchCol] = 1;
    lc.setLed(0, matchRow, matchCol, true);
    customKey = '\0';
    delay(200);
  }

  if (customKey != '\0' && val[matchRow][matchCol] == 1) {
    val[matchRow][matchCol] = 0;
    lc.setLed(0, matchRow, matchCol, false);
    customKey = '\0';
    delay(200);
  }

}