Programming a keypad without a library - doesn't work

Hello, I tried to program a 4x4 keypad to my liking using the 'keypad.h' library but as I am relatively new to the arduino platform and coding in general, I couldn't figure out how I could utilise the language reference to the corresponding library.

So I decided to to program a 4x4 keypad to my liking without using a library, I came up with the following code:

// all the needed libraries
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// initialising the pins of the lcd
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
/*schematic of the keypad
  C4 C3 C2 C1
R1 *  *  *  * 
R2 *  *  *  *
R3 *  *  *  *
R4 *  *  *  *
*/

// variables for the column pins
int C4_pin = 2;
int C3_pin = 3;
int C2_pin = 4;
int C1_pin = 5;

// booleans for the column pins, to check if these pins are HIGH or LOW
bool C4_value = true;
bool C3_value = true;
bool C2_value = true;
bool C1_value = true;

//variables for the row pins
int R1_pin = 6;
int R2_pin = 7;
int R3_pin = 8;
int R4_pin = 9;

// booleans for the row pins, to check if these pins are HIGH or LOW
bool R1_value = true;
bool R2_value = true;
bool R3_value = true;
bool R4_value = true;

// array for the column pins
byte columnPins[4] = {C4_pin, C3_pin, C2_pin, C1_pin};

// array for the row pins
byte rowPins[4] = {R1_pin, R2_pin, R3_pin, R4_pin};

void setup() {
  Serial.begin(9600);
    // to initialise the row pins and set their mode
    for(int i = 0; i<4; ++i){
      pinMode(rowPins[i], OUTPUT);
      digitalWrite(rowPins[i], LOW);}
    // to initialise the column pins and set their mode
    for(int x = 0; x<4; ++x){
      pinMode(columnPins[x], OUTPUT);
      digitalWrite(rowPins[x], HIGH);}}
      

void loop() {
  // to check if a button has been pressed
    if(digitalRead(columnPins[0] == LOW)){C4_value == false;}
    if(digitalRead(columnPins[1] == LOW)){C3_value == false;}
    if(digitalRead(columnPins[2] == LOW)){C2_value == false;}
    if(digitalRead(columnPins[3] == LOW)){C4_value == false;}
    
    // to figure out the placemant of the pressed button: column 4
    if(C4_value == false){digitalWrite(rowPins[0], HIGH);}
    if (digitalRead(columnPins[0]) == HIGH){lcd.print("wished character");
    Serial.println("wished character");}
    
    if(C4_value == false){digitalWrite(rowPins[1], HIGH);}
    if (digitalRead(columnPins[0]) == HIGH){lcd.print("wished character");}
    
    if(C4_value == false){digitalWrite(rowPins[2], HIGH);}
    if (digitalRead(columnPins[0]) == HIGH){lcd.print("wished character");}
    
    if(C4_value == false){digitalWrite(rowPins[3], HIGH);}
    if (digitalRead(columnPins[0]) == HIGH){lcd.print("wished character");}
    
    // to figure out the placemant of the pressed button: column 3
    if(C3_value == false){digitalWrite(rowPins[0], HIGH);}
    if (digitalRead(columnPins[1]) == HIGH){lcd.print("wished character");}
    
    if(C3_value == false){digitalWrite(rowPins[1], HIGH);}
    if (digitalRead(columnPins[1]) == HIGH){lcd.print("wished character");}
    
    if(C3_value == false){digitalWrite(rowPins[2], HIGH);}
    if (digitalRead(columnPins[1]) == HIGH){lcd.print("wished character");}
  
    if(C3_value == false){digitalWrite(rowPins[3], HIGH);}
    if (digitalRead(columnPins[1]) == HIGH){lcd.print("wished character");}
    
    // to figure out the placemant of the pressed button: column 2
    if(C2_value == false){digitalWrite(rowPins[0], HIGH);}
    if (digitalRead(columnPins[2]) == HIGH){lcd.print("wished character");}
    
    if(C2_value == false){digitalWrite(rowPins[1], HIGH);}
    if (digitalRead(columnPins[2]) == HIGH){lcd.print("wished character");}
    
    if(C2_value == false){digitalWrite(rowPins[2], HIGH);}
    if (digitalRead(columnPins[2]) == HIGH){lcd.print("wished character");}
    
    if(C2_value == false){digitalWrite(rowPins[3], HIGH);}
    if (digitalRead(columnPins[2]) == HIGH){lcd.print("wished character");}
    
    // to figure out the placemant of the pressed button: column 1
    if(C1_value == false){digitalWrite(rowPins[0], HIGH);}
    if (digitalRead(columnPins[3]) == HIGH){lcd.print("wished character");}
    
    if(C1_value == false){digitalWrite(rowPins[1], HIGH);}
    if (digitalRead(columnPins[3]) == HIGH){lcd.print("wished character");}
    
    if(C1_value == false){digitalWrite(rowPins[2], HIGH);}
    if (digitalRead(columnPins[3]) == HIGH){lcd.print("wished character");}
    
    if(C1_value == false){digitalWrite(rowPins[3], HIGH);}
    if (digitalRead(columnPins[3]) == HIGH){lcd.print("wished character");}
  
    }

The problem is, it doesn't work for some reason. I uploaded a photo of my circuit that I built, I doubt that there is anything wrong with that so I think that there's something wrong with either my code or my understanding of 4x4 keypads. Any help would be greatly appreciated.

Note: my knowledge of 4x4 keypads is based of this article: How to Set Up a Keypad on an Arduino - Circuit Basics

Note: the uploaded diagram of the circuit doesn't contain a 4x4 keypad so you would have to imagine one, sorry.

I believe you need to review the difference between = and ==, and when to use one and when to use the other.

2 Likes

@psbs1, I think one of these should be C1_val

    if(digitalRead(columnPins[0] == LOW)){C4_value == false;}
    if(digitalRead(columnPins[1] == LOW)){C3_value == false;}
    if(digitalRead(columnPins[2] == LOW)){C2_value == false;}
    if(digitalRead(columnPins[3] == LOW)){C4_value == false;}

and yes, check out = versus ==.

Also, you never set those values, and maybe some others, back to true so next time they might get set false.

Whether you switch to a library and figure out libraries or not, I think it would be worth, now or one day, getting your code as you conceived it, to work.

I can't look closer from where I am. At a glance it appears that you are trying to implement something you've learned about as far as scanning a keyboard goes.

Libraries come with examples, they shouldn't be too hard.

a7

1 Like

Try this site... See post #6 and post #7... safety concern... do not use this link verbatim

... it works as a simulation for me. (HOWEVER: see post #6 and post #7... simulation only

1 Like

!!!! DO NOT !!!! set all the row and column pins to OUTPUT mode at the same time.
Pressing a key on the keypad will directly short an output HIGH to an output LOW, likely damaging your Arduino.

void setup() {
  Serial.begin(9600);
  // to initialise the row pins and set their mode
  for (int i = 0; i < 4; ++i) {
    pinMode(rowPins[i], OUTPUT);
    digitalWrite(rowPins[i], LOW);
  }
  // to initialise the column pins and set their mode
  for (int x = 0; x < 4; ++x) {
    pinMode(columnPins[x], OUTPUT);
    digitalWrite(rowPins[x], HIGH);
  }
}

If you look at the code in the Keypad library, the column pins are all set to INPUT_PULLUP, and the row pins are also set to INPUT mode. During the scan of the keypad, one row pin at a time is set to OUTPUT mode and used to output a LOW, then the column pins are each read to determine if a key is pressed, after which the row pin is set back to HIGH and then to INPUT mode. At no time is there more than one pin set to OUTPUT mode.

1 Like

Be careful with that code on a real Arduino, I notice all the column pins are in OUTPUT mode. Pressing two keys in the same row at the same time will short two columns together.

1 Like

It isn't a school assignment, I just coudn't get the hang of the library's functions as I couldn't find any information about them.

I programmed that circuit and drew the schematic of the circuit at 1AM my time, so they both contain a load of errors and as others in this thread may have pointed out, some coding errors certainly were the issue. Forgive me.

Thank you for pointing out that I didn't initialise the lcd, I did change the code to include Serial before posting this post but I decided to delete to prevent others from asking why only one button would print as I only wrote Serial.print under one button.

Thanks

Yep thank you, the second if statement should contain a single equal sign instead of two.

Thank you alto777,

I will change one to C1, thank you for pointing that one out. I should've used a single equals to sign to asign a value to variable and as you stated, I will make a piece of could that will set them back to true.

Thanks,

Thank you Xfpd,
I will be sure to check your sites out.

Thank you for pointing that out, I did not know that. Could you please explain to me how the normal INPUT mode is different than the INPUT_PULLUP mode?

Thanks a lot for your explanation, I now know how to properly rewrite my code.

The lcd is initialised, my bad

this is not the only error in this line

see the parenthesis

2 Likes

The INPUT_PULLUP mode activates an internal pull-up resistor, so that the input pin is pulled to HIGH level when no key is pressed. If you do not use that, and there are no external pull-up or pull-down resistors, then the input would be floating when no key is pressed, causing it to randomly read HIGH or LOW. Floating inputs are very sensitive to picking up any electrical noise.

Thank you very much!

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