Maybe i fried my device (Switch Matrix 2x2))

Hi.
Edit at the end......
I have a nodemcu esp32 and want to make this matrix.

...a little matrix of 2x2 of reed switches.

This switches can be all 4 closed at the same time.

in this little matrix with diodes
image

G H
g2 h2
g1 h1

I use this gpio for columns: gpio36, gpio39
this for rows: gpio23, gpio22

Because... i dont know how to do this, i try to just know what is happening in the code like this:

const int columnPins[] = { 36, 39};
const int rowPins[] = { 23, 22};
int COLH;
int COLG;
int FILA1;
int FILA2;

void setup() {
  Serial.begin(115200);

  for (int i = 0; i < 2; i++)
    {
      pinMode(columnPins[i], INPUT_PULLUP);
      pinMode(rowPins[i], OUTPUT);
      //digitalWrite(columnPins[i], HIGH);
      //digitalWrite(columnPins[i], LOW);
  }
  
}

void loop()
{
  COLH=digitalRead(columnPins[0]);
  COLG=digitalRead(columnPins[1]);
  FILA1=digitalRead(rowPins[0]);
  FILA2=digitalRead(rowPins[1]);
  
  Serial.println("Debería ser H1");
  Serial.println(COLH);
  Serial.println(FILA1);

  Serial.println("Debería ser G1");

  Serial.println(COLG);
  Serial.println(FILA1);

  Serial.println("Debería ser H2");
  Serial.println(COLH);
  Serial.println(FILA2);
  
  Serial.println("Debería ser G2");
  Serial.println(COLG);
  Serial.println(FILA2);
  
  delay(100);

 } 

To say the true... i already try changing everything, that is why i think that probably i fried my device... and it is not working.
What is wrong with this code? Maybe the gpio that i choose are not suitable for this?

With this code i was trying to see the state of the columns and rows, to later change the code to reflect when a switch is open or closed... but i dont see nothing consistent. And i change from high to low, from column input_pullup to output and rows input_pullup to output and viceversa......... and nothing is good.
thank you very much

Edit:
I try now this code from here change the rows and columns two my size and gpio setup Issues with 3x3 Matrix of Reed Switches - #2 by flashko
that seems wrote from somebody that knows. But it is also not working. I have the same problem that that person tell in that post.... Bad readings.
After that a person recommend the register shifters BUT, it is suppose that this could be done in a Matrix with diodes. Then it must work in some way! Well, if somebody knows what is going here?!

Why?
This matrix uses 4 pins. And wiring each reed switch direct to an input, with the pull ups enabled would take 4 pins, then you would not have to do very much in the code.

As to your code, you are doing nothing but a digital read. For a matrix you have to put one line low (or high depending on which way you want to scan the matrix), and then read the other two lines to see if anything is pressed.

No it doesn't this is appalling code.

this is just a prototype. Im gonna to make the chessboard, yes i will. Then 64 switchs, then i want a matrix that i always heard about.

yep, in my code i was showing the result of the digital read, so i can see the combinations of the positions.

Then i cant just read the state. I need to put a line low or high (lets say a column), and then read the state of the switches in that column... and then with the other column.

That is not how you drive a scanning matrix.

Are the reed switches normally open or closed?

normally open

So, the row pins are normally HIGH and to read, say G2, you would pull row 2 LOW and read column G pins?

in the following, each row pin is set LOW in an initialization routine but configured as an INPUT so that the row is allowed to float and each column pin configured as an INPUT

in the routine each row is sequentially reconfigured as OUTPUT, driving that row LOW because it was set LOW in the initialization routine. Because the column pins are configured INPUT_PULLUP pulling the pin HIGH, pressing a switch on a column when the row is driven LOW will pull the column pin LOW

each column is checked if it is LOW (i.e. if (! digitalRead (_kpCols [c])). when it is, it sets the row and col arguments to the current row/col, restores the row pin configuration and returns. Otherwise, it restores the row pin and continues

int
keyscan (
    byte*   row,
    byte*   col )
{
    for (unsigned int r = 0; r < _kpRowSize; r++)
    {
        pinMode (_kpRows [r], OUTPUT);

        if (DBG_KEYPAD & debug)
            delay (500);

        for (unsigned int c = 0; c < _kpColSize; c++)
        {
            if (! digitalRead (_kpCols [c]))
            {
                pinMode (_kpRows [r], INPUT);

                *row = r;
                *col = c;
                int  res = (r << 4) | c;

                if (DBG_KEYPAD & debug)  {
                    Serial.print ("keyscan: row ");
                    Serial.print (r);
                    Serial.print (", col");
                    Serial.print (c);
                    Serial.print (", res ");
                    Serial.println (res);
                }

                return res;
            }
        }

        pinMode (_kpRows [r], INPUT);
    }

    return NO_KEY;
}

EDIT2 at the END.
Thank you.
I have some doubts.
You say that in initialization routine column configure as INPUT. But later say that "column pins are configured as INPUT_PULLUP. (i try with input_pullup)
of the code i get rid of dbg things and debug.
ended with this:

const int _kpCols[] = { 36, 39};
const int _kpRows[] = { 23, 22};

int _kpRowSize = 2;
int _kpColSize = 2;

int NO_KEY; //just to avoid a problem with debug, later i will try to figure out if int is good or not :-)

byte ro = 1; //to pass to the function
byte co = 1; //to pass to the funciont

int
keyscan (
    byte*   row,
    byte*   col )
{
    for (unsigned int r = 0; r < _kpRowSize; r++)
    {
        pinMode (_kpRows [r], OUTPUT);

        delay (500);

        for (unsigned int c = 0; c < _kpColSize; c++)
        {
            if (! digitalRead (_kpCols [c]))
            {
                pinMode (_kpRows [r], INPUT);

                *row = r;
                *col = c;
                int  res = (r << 4) | c;

                
                Serial.print ("keyscan: row ");
                Serial.print (r);
                Serial.print (", col");
                Serial.print (c);
                Serial.print (", res ");
                Serial.println (res);
                

                return res;
            }
        }

        pinMode (_kpRows [r], INPUT);
    }

    return NO_KEY;
}

void setup() {
  Serial.begin(115200);

  for (int i = 0; i < 2; i++)
    {
      pinMode(_kpCols[i], INPUT_PULLUP); 
      pinMode(_kpRows[i], INPUT);
      digitalWrite(_kpRows[i], LOW);
      
  }
  
}
void loop()
{
  keyscan(&ro,&co);
  delay(1000);
   } 

alright, keyscan want pointers.
I dont understand what would be a pointer here. Also dont understand why a pointer is need.
But anyway, i pass does to see what happens. And dont work also as i expected:
if i put a magnet in what i label as 1h i get this values:

keyscan: row 1, col0, res 16

and if i put the magnet in any of them i get the same value: 1,0,16.......
Then... how i will know which is which? (maybe is bad wired? maybe my device have some pins fried? or the i change the code wrong?)

Edit: in the other hand if i change "ro" and "co" for lets say 5. I dont get any error and also get the same 1,0,16. So... what is not happening with ro and co here? mmm mysterious world!
Thanks for your patience.

EDIT2: i found this ESP32 Pinout Reference: Which GPIO pins should you use? | Random Nerd Tutorials
It seems that some of the pins i use are just "input only" so probably that is part of why im getting random data. I was doing the 2x2 matrix in a protoboard... i will get rid of the protoboard and solder everything to avoid some noise.
I will come back stronger (with i hope, new questions) Thanks for all the help.

Having a floating input is a very poor design strategy, it means that you are not in control of the input and so it can read back as anything.

that pin is being used as an output ... only one output on a column (?) is being used to pull a row(?) pin HIGH or that switch pulls the row pin LOW

This is a diagram of a 3 by 4 switch matrix. It can be expanded to any size if you keep on adding extra rows and columns.

Here I generated the columns by using a de-multiplexer. These can be generated by just using output pins.

Although if the OP wants to end up with an 8 by 8 matrix then this can get expensive on the pins used. The walking zero pattern is generated at each step to set up the columns. After these have been set up all the inputs are read and return a zero if a key is being pressed or a one if there is no press. Therefore these inputs must have their internal pull up resistors enabled.

This schematic shows how you can cut down the number of outputs you require with a de-multiplexer. For 8 outputs you just need an 8 bit de-multiplexer. This will take up 3 processor pins.

Likewise to save on the number of inputs you need, then just use an 8 bit multiplexer, and scan each input in turn. This takes another 3 processor bits. So 6 in all, as opposed to 16 processor pins without multiplexing / de-multiplexing.

my mistake, each column is configured initially as INPUT_PULLUP and each row and INPUT but LOW. the row pins are set to OUTPUT when checking that row and returned to INPUT when done

to return the row and col indices

was hoping you would study the code to understand how it works, that if column pins are pulled HIGH, it will only be pulled LOW while the switch is pressed, connecting it to ground when the corresponing row pin is LOW

may help it you run the code very slowing an add prints to see what it is doing

There is no need to return an index, because it is all about reading an input and you know what input you are reading. The outputs you should know because you set them.

If you want to scan "the other way" that is with columns as inputs and rows being outputs, then the the diodes in the OP original circuit are the wrong way round.

i'll guess that what you're trying to say is that each button can be assigned a value and that value returned instead of a row/col pair

if so, how would you assign values to buttons on a 2x2, 3x3, 4x4, ... mtrix?

Stop guessing and try and read what I say.

If you are reading an input your code knows what input you are reading, because of the digitalRead call requires you to specify what input you are reading. So your code knows for that input if the key is pressed or unpressed. Why would you want / need to do anything else?

yes, is reads an input pin, but depending on which row is being driven LOW, that input represents an different button.

Of course it does, why is this a problem for you? You are supposed to be an information giver. The solution is quite simple.

The column that is set LOW is the X address of your switch array, the row you are reading is the Y address of your switch array.

Now if you want to transfer this information into an array, of finally an 8 by 8, but in keeping with the diagram I posted a 3 by 4 array, you just change the current contents of this array to reflect the switch you just read.

To translate the currently addressed position you might use a look up table, but this would be silly because you can calculate this.

For the rows, the Y position, if you use consecutive pin numbers, lets say pins 16, 17, and 18. Then your row position in the matrix are simply:-
Y position = pin you are reading - 16.

The same would go for the column pins if no multiplexer were being used. To spell it out:-

For the column, the X position, if you use consecutive pin numbers, lets say pins 28, 29, and 30. Then your column position in the matrix are simply:-
X position = pin you have set low - 28.

With a multiplexer this is simply the address input A0 & A1 plus the pin offset, that is, in the above example would be:-
X position = address input + 28.

In this matrix you can store either a boolean logic TRUE or FALSE to reflect if the switch is in that position. You could save a bit of memory if you used a byte instead of a bool and have each individual byte store 8 bits of data. But for simplicity keep to what I said for the moment.

The only thing you have to check is that the pins you use on your ESP32 are capable of being inputs for the rows and outputs for columns.

The only thing that could have damaged your processor is if you had two pins both set to outputs with one set HIGH and the other set LOW and they got connected together.

don't understand the point you're trying to make. i thought the OP is struggling to appropriate configure and re-configure the I/O pins to recoognize a unique button press

the code in post #8 scans a matrix to determine which button is pressed, returning a row/col pair. That function is called by a higher level function that uses a table/matrix using the row/col indices to return a button value

#include <Arduino.h>

#include "pins.h"
#include "buttons.h"
#include "keypad.h"
#include "koala.h"
#include "menu.h"
#include "vars.h"

enum {
    B_MODE = 10,
    B_F0   = 50,
    B_F1   = 51,
    B_F2   = 52,

    B_F3   = 53,
    B_F4   = 54,
    B_F5   = 55,
    B_F6   = 56,

    B_F7   = 57,
    B_F8   = 58,
    B_F9   = 59,
    B_F10  = 60,

    B_MENU = 13,
    B_SEL  = 23,
    B_UP   = 33,
    B_DN   = 43,
};

// -----------------------------------------------------------------------------
// keypad
// 
//                      + + + +   <------ pin 14 / IO-13 / KB_R0
//                      + + + +   <------ pin 13 / IO-12 / KB_R1
//                      + + + +   <------ pin 12 / IO-14 / KB_R2
//                      + + + +   <------ pin 11 / IO-27 / KB_R3
//                                
//                      | | | |----> pin 21 / IO-15 / KB_C3
//                      | | |------> pin 22 / IO-02 / KB_C2
//                      | |--------> pin 24 / IO-00 / KB_C1
//                      |----------> pin 25 / IO-04 / KB_C0
//

// define the pins in the row and column
byte kpCols[] = {  KB_C0, KB_C1, KB_C2, KB_C3 };
#define KP_COL_SIZE sizeof(kpCols)

byte kpRows[] = { KB_R0, KB_R1, KB_R2, KB_R3 };
#define KP_ROW_SIZE sizeof(kpRows)

// button translation into cab bus codes
char keyCodes [KP_ROW_SIZE] [KP_COL_SIZE] = {

    { B_MODE, B_F3,   B_F7,   B_MENU },
    { B_F0,   B_F4,   B_F8,   B_SEL  },
    { B_F1,   B_F5,   B_F9,   B_UP   },
    { B_F2,   B_F6,   B_F10,  B_DN   },
};

#define N_BUTTONS 16

bool butState   [N_BUTTONS] = {};
bool butPress   [N_BUTTONS] = {};

// -----------------------------------------------------------------------------
// scans for a keypress and translates using spcified tbl
static char getKey (char tbl [KP_ROW_SIZE] [KP_COL_SIZE] )
{
    byte    row  = 0;
    byte    col  = 0;
    int     code = 0;

    if (NO_KEY != keyscan (& row, & col))
    {
        code = tbl [row][col];

        if (DBG_BUT & debug)
            printf ("%s: code %d, row %x, col %x\n",
                __func__, code, row, col); 
    }

    return code;
}

// ---------------------------------------------------------
// process button presses
unsigned long msecMenu = 0;

void
buttonFuncs (
    int button)
{
    static int           buttonLst = 0;

    if (buttonLst == button)
        return;
    buttonLst = button;

    switch (button)  {
    case 0:             // no button press
        break;

    case 10:
        state ^= ST_DVT;
        break;

    case B_MENU:
        menu (M_MENU);
        state |= ST_MENU;
        msecMenu = msec;
        break;

    case B_SEL:
        menu (M_SEL);
        msecMenu = msec;
        break;

    case B_UP:
        menu (M_UP);
        msecMenu = msec;
        break;

    case B_DN:
        menu (M_DN);
        msecMenu = msec;
        break;

    default:
        jmriFuncKey (button - B_F0, FUNC_TGL);
        break;
    }
}

// -------------------------------------
void buttonsChk (void)
{
    button = getKey (keyCodes);
    buttonFuncs (button);

#define MENU_TIMEOUT    4000
    if (msec - msecMenu > MENU_TIMEOUT)
        state &= ~ST_MENU;
}

// -------------------------------------
void buttonsInit (void)
{
    keypadSetup (kpCols, KP_COL_SIZE, kpRows, KP_ROW_SIZE);
}