3

Part of my current assignment involves reading the input from a 4x4 keypad connected to an Arduino UNO. While this may be done easily using <Keypad.h>, the project is being done with Tinkercad's online simulator, meaning I don't have access to that library. I have to do it the manual way.

This is the code I've got so far:

#include <Wire.h>
#define DIMENSIONS 4
const unsigned long period = 50;
unsigned long prevMillis = 0;
byte modo = 0;
const byte rowsPins[DIMENSIONS] = {11, 10, 9, 8};
const byte columnsPins[DIMENSIONS] = {7, 6, 5, 4};
char keys[DIMENSIONS][DIMENSIONS] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

void setup()
{
    Serial.begin(9600);// debug
    for(byte i = 0; i < DIMENSIONS; i++){
        pinMode(columnsPins[i], INPUT);
        digitalWrite(columnsPins[i], HIGH);
        pinMode(rowsPins[i], INPUT_PULLUP);
    }
    Wire.begin();
}

void loop()
{
    switch(modo){
        case 0:
            Serial.print("Master (2) boot up\n");
            modo++;
            break;
        case 1:
            if(millis() >= 1000){
                modo++;
            }
            break;
        case 2:
            if (millis() - prevMillis > period){
                prevMillis = millis();
                for(byte c = 0; c < DIMENSIONS; c++){
                    pinMode(columnsPins[c], OUTPUT);
                    digitalWrite(columnsPins[c], LOW);
                    for(byte r = 0; r < DIMENSIONS; r++){
                        if(digitalRead(columnsPins[r]) == LOW){
                            Serial.println(keys[r][c]);
                        }
                    }
                    digitalWrite(columnsPins[c], HIGH);
                    pinMode(columnsPins[c], INPUT);
                }
            }
            break;
        default:
            break;
    }
}

(the "modes" and Wire.h are a different part of the assignment and not related to my issue)

This code should, in theory, read the input from the connected 4x4 keypad and then print on the serial monitor which key was pressed. I've done a fair bit of searching, and other solutions for detecting key presses without the Keypad library aren't super different from what I've done here. However, for some reason, what I wrote is not working properly for me.

On starting the simulation, the serial monitor prints 1, 5, 9, D continuously and repeatedly on a loop. Pressing the keys does sometimes print the appropriate character, but it does not stop the flood of 1s, 5s, 9s and Ds.

I know for a fact that it's not a matter of the pins being misconnected, I've checked for that at least a dozen times by now. It's most certainly a matter of code... but I can't figure out where the problem lies.

1
  • you could add a 4x4 array to store button state ... then do a 50 ms debounce delay whenever the button state changes
    – jsotola
    Jun 24 at 21:54

1 Answer 1

5

In case 2:

digitalWrite(columnsPins[c], LOW);
for(byte r = 0; r < DIMENSIONS; r++){
   if(digitalRead(columnsPins[r]) == LOW){
   Serial.println(keys[r][c]);
   }
}

Since you just wrote one of the column pins low, you can guarantee that one is going to read low. Did you mean to read the row pins?

4
  • I can't believe I did not notice such an obvious mistake. Thanks for the save, Delta_G.
    – Maf95
    Jun 24 at 21:20
  • Post a annotated schematic as to how you have actually wired the keyboard, be sure to show all resistors and diodes.
    – Gil
    Jun 24 at 23:57
  • @Gil not a keyboard, just a humble 4x4 keypad. Here you go. It's extremely simple, the pins on the Arduino are connected directly to the keypad, so I didn't feel it was necessary to include it in the OP.
    – Maf95
    Jun 25 at 0:30
  • @Maf95 "When a programmer has a hard time finding a bug, it's because he's looking in the wrong place." Jun 25 at 7:45

Your Answer

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

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