0
\$\begingroup\$

I'm building a project with an arduino nano, since I don't have enough pins for all the devices that I'm going to attach to it I am trying to share some digital pins between a LCD screen and a matrix keypad 4x3.

The working circuit

If you're interested and/or you think is useful to know how and why I came up whit this stupid looking circuit you can read the Line of thoughts section in which I explain it.

N.B. I wrote the schematic just for the purpose of showing it here so imagine as all the other connections of the LCD are properly connected

circuit that is working

I'm trying to understand what is making this thing work so that I can make a valid and serious circuit for this purpose.

If I try to disconnect the gate of the MOSFETs from ground or I try to disconnect the MOSFETs I get a wrong reading from the keyboard.

I noticed that between the gate and the drain there is a resistance of 1Mohm, so I tried to substitute the MOSFETs with the corresponding resistance but it's not working.

How I read the keyboard

I have 7 wires: 4 rows and 3 columns. To read which button is pressed I simply put all the row lines in the arduino to INPUT_PULLUP then I have a for each column c I put it to LOW and I check all the rows, if a row pin ris reading LOW it means that the button corresponding to the coordinates r an c is been pressed.

Here's the code:

char Keyboard_4x3::read(uint32_t timeout_ms) {
  // initialize to be sure of the initial state of the colums
  uint8_t rows_modes[4];
  char ret_val = '\0';

  for (size_t r = 0; r < 4; ++r) {
    rows_modes[r] = get_pin_mode(rows[r]);
    pinMode(rows[r], INPUT_PULLUP);
  }

  for (size_t c = 0; c < 3; ++c) {
    digitalWrite(cols[c], HIGH);
  }

  auto start = millis();
  do {
    for (size_t c = 0; c < 3; ++c) {
      digitalWrite(cols[c], LOW);
      for (size_t r = 0; r < 4; ++r) {
        if (digitalRead(rows[r]) == LOW) {
          ret_val = key_codes[r][c];
          break;
        }
      }
      digitalWrite(cols[c], HIGH);
    }
  } while (millis() < start + timeout_ms);

  for (size_t r = 0; r < 4; ++r)
    pinMode(rows[r], rows_modes[r]);

  return ret_val;
}

Line of thoughts

My idea (wrong)

My first idea was that since when I'm reading the keyboard I'm not writing the LCD and vice versa, I could simply connect the rows pin to the data lines without any problem.

That was not the case because sometimes the LCD has some data lines set to 0 even if I'm not using it and that was making the reading of the keyboard to give wrong results

second idea (wrong)

I could connect the data line to the same pins of the keyboard, but through a mosfet, in this way the connection between the LCD and the arduino could be turn on by 1 digital pin and could be turn off when I need to read the keyboard.

That didn't work, but I still don't know why it didn't work. I suspect that the data lines are slowed down by the presence of the mosfet and that the LCD is not receiving the data correctly. Unfortunately I don't have a digital analyzer at home to check if I'm correct.

How I created the circuit that is working

While I was going back to think to another option I forgot to detach the connection between the mosfets and the the data lines. In this way I came out with the working circuit. I really cannot understand why and how is that working but it is working.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Is that part number correct - are they really IRF540 MOSFETS? \$\endgroup\$
    – brhans
    Commented Mar 25, 2022 at 22:37
  • \$\begingroup\$ yes they are correct \$\endgroup\$
    – Noè Murr
    Commented Mar 25, 2022 at 22:38
  • 2
    \$\begingroup\$ And what exactly does "I get a wrong reading from the keyboard" mean? Wrong in what way? What result do you expect compared to what result you see? \$\endgroup\$
    – brhans
    Commented Mar 25, 2022 at 22:40
  • \$\begingroup\$ Practically when I press a button in the second row I read the value of the first row, that I think is because the two digital pins are connected between them and I read first the pin connected to the first row. So basically when I type 123456 I read 123123 \$\endgroup\$
    – Noè Murr
    Commented Mar 25, 2022 at 22:44
  • \$\begingroup\$ How do we know if the other pins are connected right or wrong to LCD, and how the code controls them? Who knows if the code leaves the LCD into read mode so it drives the bus. Maybe the FETs just add capacitance, but otherwise they do nothing. \$\endgroup\$
    – Justme
    Commented Mar 25, 2022 at 23:51

1 Answer 1

-1
\$\begingroup\$

This is a great idea to save on IO pins to MUX IO's . This problem works well for static display indicators but you have huge difference in IO BW. Thus over sampling of inputs, must be decimated or averaged to debounce inputs.

Anecdotal

  • in one of my earliest designs in late '70's I used a MC6800 to MUX 96 input switches and 96 output indicators and LED display using 1 of 16 decoders with 4 bit addresses and 4 bit data muxed with R/W and a clock & latch IO's .
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.