4x4 Keypad on tinkercad always gives zero value no matter what I press

Image of project:

my code:

void setup()
{
  Serial.begin(9600);
  pinMode(13, INPUT);
  pinMode(12, INPUT);
  pinMode(11, INPUT);
  pinMode(10, INPUT);
  pinMode(9, INPUT);
  pinMode(8, INPUT);
  pinMode(7, INPUT);
  pinMode(6, INPUT);
}

int keypadChar() {
	byte row1 = digitalRead(13);
  	byte row2 = digitalRead(12);
    byte row3 = digitalRead(11);
    byte row4 = digitalRead(10);
  	byte collum1 = digitalRead(9);
  	byte collum2 = digitalRead(8);
  	byte collum3 = digitalRead(7);
  	byte collum4 = digitalRead(6);
  if (row1 == HIGH && collum1 == HIGH) {
  	return 1; 
  }
  if (row1 == HIGH && collum2 == HIGH) {
  	return 2; 
  }
  if (row1 == HIGH && collum3 == HIGH) {
  	return 3; 
  }
  if (row1 == HIGH && collum4 == HIGH) {
  	return 10; // A 
  }
  if (row2 == HIGH && collum1 == HIGH) {
  	return 4; 
  }
  if (row2 == HIGH && collum2 == HIGH) {
  	return 5; 
  }
  if (row2 == HIGH && collum3 == HIGH) {
  	return 6; 
  }
  if (row2 == HIGH && collum4 == HIGH) {
  	return 11;  // B
  }
  if (row3 == HIGH && collum1 == HIGH) {
  	return 7; 
  }
  if (row3 == HIGH && collum2 == HIGH) {
  	return 8;
  }
  if (row3 == HIGH && collum3 == HIGH) {
  	return 9; 
  }
  if (row3 == HIGH && collum4 == HIGH) {
  	return 12;  // C
  }
  if (row4 == HIGH && collum1 == HIGH) {
  	return 13; // *
  }
  if (row4 == HIGH && collum2 == HIGH) {
  	return 0; 
  }
  if (row4 == HIGH && collum3 == HIGH) {
  	return 14; // # 
  }
  if (row4 == HIGH && collum4 == HIGH) {
  	return 15;  // D
  }
  return NULL;
}


void loop()
{
  byte letterPressed = keypadChar();
  
  
  
  if(letterPressed != NULL) {
  	 Serial.println(letterPressed);
    delay(100);
  }
}

They can’t all be inputs, 4 must be outputs.

There is a Keypad library that will help you and do exactly what you are looking for.

I don't want to use the library. Can you explain which ones need to be outputs and why?

You need to output a signal in order to read which key is pressed. So if you make the rows outputs and columns inputs, then for each row you scan the column. If you get a high signal at y-row for x-column then a key was pressed and all you need to do is figure out which key it was.

You can use a 2D array to hold all the key characters and all you need to do is index through them when the correct key is pressed.

I think the keypad library is doing the opposite, its outputting to the columns and reading the rows.

Can you please explain in more detail? I tried doing something like what you said but it didn't work.

google is your friend.

There's a reason ppl use a library for this, it isn't a beginner's project.

Google

scan a matrix keyboard

and see if any of the hits gives you more to go on based on what you know so far. I saw many articles laying the hole thing out. I do not know if any would make the least sense to you.

Also, you could read the source code for a library scanner, here's one:

This isn't something we can talk you through a step at a time. I won't, anyway, it's just bigger than a simple answer to a simple question.

In general reading code is a good way to see how various things are accomplished.

a7

Thanks

I have had that exact same keypad for about 4 years and never got around to using it. I had nothing better to do so I wrote some code to test it. This works correctly on an Uno R3. The wiring is exactly as shown in the image in post #1.

// Define pins connected to keypad
const byte columnPins[4] = {6, 7, 8, 9};
const byte rowPins[4] = {10, 11, 12, 13};
// Define characters for each key
const char keyChars[4][4] = {{'D','#','0','*'},
                             {'C','9','8','7'},
                             {'B','6','5','4'},
                             {'A','3','2','1'}};

void setup() {
  Serial.begin(9600);
  // Set column pins to inputs with pull up
  for (byte column = 0; column < sizeof(columnPins); column++) {
    pinMode(columnPins[column], INPUT_PULLUP);
  }
  // Set row pins to high outputs
  for (byte row = 0; row < sizeof(rowPins); row++) {
    pinMode(rowPins[row], OUTPUT);
    digitalWrite(rowPins[row], HIGH);
  }
}

void loop() {
  // Check each row to see if a key is pressed on that row
  for (byte row = 0; row < sizeof(rowPins); row++) {
    // Set the output pin for this row to LOW
    digitalWrite(rowPins[row], LOW);
    // Check each column of this row for a key pressed
    for (byte column = 0; column < sizeof(columnPins); column++) {
      if (digitalRead(columnPins[column]) == LOW) {
        Serial.println("Key pressed row=" + String(row) + " column=" + String(column) + " = key " + String(keyChars[row][column]));
      }
    }
    // Put the output for this row back to HIGH
    digitalWrite(rowPins[row], HIGH);
  }
  // Delay to stop serial monitor getting full of text for 1 click  
  delay(250);
}

When a key is pressed it prints what key has been pressed to the serial monitor. This output is for key presses on key '1', then '5', then '9', then 'D'

Key pressed row=3 column=3 = key 1
Key pressed row=2 column=2 = key 5
Key pressed row=1 column=1 = key 9
Key pressed row=0 column=0 = key D

Nice. One hopes that @gabriel_hugi can test it, and then read it carefully to match it to whatever else she learns about how the scanning magic works.

That sketch got me interested in seeing how the libraries handle debouncing and their various ways of presented keystroke activity to the programmer using them.

I know it's a PITA, but you really can get along without using Strings. I appreciate the ease of doing, but it is totally unnecessary and going without here needs no deep dive into C character arrays:

      Serial.print("Key pressed at row = ");
      Serial.print(row);
      Serial.print("    column = ");
      Serial.print(column);
      Serial.print("     = key ");
      Serial.print(keyChars[row][column]);
      Serial.println(".");

Just put "Serial.print" on a hot key...

Strings might never be an issue with a little test program, of course.

a7

Yes I know, and do mostly avoid them in real code. I did it for a mixture of: being lazy and reducing the line count. Not particularly valid reasons.
I like this article on using Strings.

This works, thanks. I still don't really understand it but I will study it more later.

If you have any questions about how it works, I'll be happy to answer them

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.