Keypad and 7-segment without libraries

I am a complete beginner at this.
I want to display the keypress on a 4x3 keypad on a common cathode 7segment. We are instructed not to use any libraries or fancy work. Just write a simple code that you can understand and explain.
I wrote this but it doesn't work in my proteus simulation. I don't know if it's the code or my circuit. Can someone please help me identify the issue here. Thanks a lot in advance.

//defining segments
#define segmentA 13
#define segmentB 12
#define segmentC 11
#define segmentD 10
#define segmentE 9
#define segmentF 1
#define segmentG 0

//defining keypad rows and cols
const int rows = 4;
const int cols = 3;
const char keys[rows][cols] = {
  { '1', '2', '3' },
  { '4', '5', '6' },
  { '7', '8', '9' },
  { '*', '0', '#' }
};

//arrays for loops
int rowPins[rows] = { 8, 7, 6, 5 };
int colPins[cols] = { 4, 3, 2 };
int seg[7] = { 13, 12, 11, 10, 9, 1, 0 };

//setup
void setup() {
  for (int r = 0; r < rows; r++) {    //rowpins => output
    pinMode(rowPins[r], OUTPUT);    
  }
  for (int c = 0; c < cols; c++) {    //colpins => input
    pinMode(colPins[c], INPUT);
  }
  for (int s = 0; s < 7; s++) {       //segmentpins => output
    pinMode(seg[s], OUTPUT);
  }
}

//main loop
void loop() {
  setLow();
  char key = getKey();
  if (key != 'n' && key != '*' && key != '#') {
    displayNum(key);
  }
}

//making all the keypad keys low
void setLow() {
  for (int r = 0; r < rows; r++) {
    digitalWrite(rowPins[r], LOW);
  }
  for (int c = 0; c < cols; c++) {
    digitalWrite(colPins[c], LOW);
  }
}

//getting the pressed key
char getKey() {
  char k = 'n';                                 //if no key was registered return n
  for (int r = 0; r < rows; r++) {
    digitalWrite(rowPins[r], HIGH);             //set a row high
    for (int c = 0; c < cols; c++) {
      if (digitalRead(colPins[c]) == HIGH) {    //check if any col got high
        delay(20);                              //debounce time
        while (digitalRead(colPins[c]) == HIGH)
          k = keys[r][c];                       //save that value in k
      }
    }
    digitalWrite(rowPins[r], LOW);              //set the row back to low
  }
  return k;                                     
}

//reset all the segment to low
void reset7seg() {
  for (int i = 0; i < seg; i++) {
    digitalWrite(seg[i], LOW);
  }
}

//display on 7segment
void displayNum(char key) {
  reset7seg();
  switch (key) {
    case '0':                         //display 0
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentE, HIGH);
      digitalWrite(segmentF, HIGH);
      break;
    case '1':                         //display 1
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      break;
    case '2':                         //display 2
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentG, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentE, HIGH);
      break;
    case '3':                         //display 3
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentG, HIGH);
      break;
    case '4':                         //display 4
      digitalWrite(segmentG, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentF, HIGH);
      break;
    case '5':                         //display 5
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentG, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentF, HIGH);
      break;
    case '6':                         //display 6
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentG, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentE, HIGH);
      digitalWrite(segmentF, HIGH);
      break;
    case '7':                         //display 7
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      break;
    case '8':                         //display 8
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentE, HIGH);
      digitalWrite(segmentF, HIGH);
      digitalWrite(segmentG, HIGH);
      break;
    case '9':                         //display 9
      digitalWrite(segmentA, HIGH);
      digitalWrite(segmentB, HIGH);
      digitalWrite(segmentC, HIGH);
      digitalWrite(segmentD, HIGH);
      digitalWrite(segmentG, HIGH);
      digitalWrite(segmentF, HIGH);
      break;
  }
}

does your keypad have pullup ?

set the led aside for the time being, write something just for the keypad

I don't know what's a pullup. The setLow() and the getKey() methods are just for the keypad. getKey() returns the the key pressed, to remove the 7-segment from the picture I can just remove the,
displayNum(key);
from the loop.

do you understand your code? (is it your code?)

if you have a pin as INPUT and the switch is open

PIN ----• •---- GND

then the pin is reading whatever electromagnetic wave passing by, it's an antenna

read about pullup

Yes, I wrote it from scratch. I have a very basic understanding of how these things work. I'll read about the pullup.

You may carry out the following steps to show the label of a pressed key on Serial Monitor.

1. Configure Row Lines with internal pull-up resistors as shown in Fig-1. Configure Column Lines as outputs.
keypad4-3
Figure-1:

2. Assert LOW on C1 (Column 1) and HIGHs on C2, C3.
3. Press Key-1. What logic level do you expect on R1 (DPin-8)? LOW? Yes! Because C1 and R1 are shorted together. HIGH of R1 is now pulled down to LOW.
Codes:

#define C1 4
#define C2 3
#define C3 2
#define R1 8
#define R2 7
#define R3 6
#define R4 5

digitalWrite(C1, LOW);
digitalWrite(C2,HIGH);
digitalWrite(C3, HIGH);

if(digitalRead(R1) == LOW)
{
    Serial.println("Key-1 is pressed.");
    while(1);
}

4. Use the codes of Section-3 as a Building Block and then develop your sketch so that whenever a Key is pressed, the corresponding label (0, 1, 2, ..., 9) will appear on the OutputBox of Serial Monitor.

5. Complete Sketch
... pending.

1 Like

when i've done this

  • set the row pins as LOW but initially configure them as INPUT
  • configure the column pins as INPUT_PULLUP

when scanning

  • sequentially re-configure each row pin as an OUTPUT (it's already set LOW)
  • sequentially read each column pin (for each row pin) and test for LOW. when LOW, the key at row, col is pressed
  • reconfigure the row pin as INPUT

with the other row pins configured as INPUT, any button on that row shouldn't be able to pull the pin LOW

1 Like

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