80 keys Using 74HC164 and 74HC165 Shift registers

Hi all I have a PCB which have 80 keys and 2 cascaded 74HC165 Parallel input Serial output shift registers and 74HC164 Serial input Parallel output register. Master 74HC165 register is connected with MCU with 5 wires . They are VCC, GND, Data out, PL/SH, CLK. the wiring diagram is like that


Then I could obtain a serial data which is corresponding to row or column. But I can not distinguished the button. Here is the code `

const int dataPin = 2;   /* Q7 */
const int clockPin = 3;  /* CP */
const int latchPin = 4;  /* PL */
const int numBits = 16;   
void setup() {
Serial.begin(115200);
pinMode(dataPin, INPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
}

void loop() {
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);


Serial.print("Bits: ");
for (int i = 0; i < numBits; i++) {
  int bit = digitalRead(dataPin);
  if (bit == HIGH) {
    Serial.print("1");
  } else {
     Serial.print("0");
  }
  digitalWrite(clockPin, HIGH); // Shift out the next bit
  digitalWrite(clockPin, LOW);
}
Serial.println();
delay(1000);
}

I think that cyclic pattern needs to monitor whether the exact what should I was pressed. Any help please .

You have to take into account both the row and column of the returned bits. Have an outer loop setting the parallel output (column) shift register and an inner loop scanning the sequential input from the row registers.

Yes thank you for suggestion and that i also taken account as well. I have write this code also . but it
doesn't giving the data that I'm Looking forward.

const int dataPin = 2;   /* Q7 */
const int clockPin = 3;  /* CP */
const int latchPin = 4;  /* PL */

const int numBits = 16;

int r = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(latchPin, LOW);
  for (int i = 0; i < 8; i++) {
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    digitalWrite(latchPin, HIGH);

    Serial.print(i);
    Serial.print(":");

    for (int j = 0; j < 16; j++) {
      int bit = digitalRead(dataPin);
      /*if (bit == HIGH) {
        Serial.print("1");
        } else {
        Serial.print("0");
        }*/
      Serial.print(bit);
      digitalWrite(clockPin, HIGH); // Shift out the next bit
      digitalWrite(clockPin, LOW);
    }
    Serial.println("");

  }
  Serial.println("----");
  delay(3000);
}


snippnnn

Tinkercad does not have the 74HC164 or the 74HC165.
Wokwi has only the 74HC165 (with examples).
One of the examples is by me and I got to 32 inputs.

I would start with the output register and use separate clock signals for input and output to have full control. With slow code you can check with a multimeter if the columns are activated one by one.

If you are sure that the outer loop with the columns is working, then you can make the inner loop and read the 16 rows.

When you are really stuck and in trouble, you could even replace the 74HC164 with the 74HC595, because then you can build the project with Wokwi. Wokwi has the 74HC595.

The 74HC164 does not buffer the data. I'm not sure at this moment what that means for your project.

The 80 keys as bits needs 10 bytes. You also need a function to show the data on the Serial Monitor.

Add a table[rows, cols] and fill it with the expected key codes. Then lookup table[i,j] when you find the bit set.

And don't forget to output the right column bit with every i.

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