Question regarding 74HC164 74HC165 shift registers 8x8 Button Grid value readout

Hello everyone,

years ago I build an Arduinome. It’s an 8x8 LED Button Grid controller that sent Serial Data over USB and another Program translated that to MIDI / OSC to be used for Music applications.

Recently I got an Arduino Leonardo and want to port/modify the old Duemilanove Firmware and use the MIDIUSB library to send Midi directly via USB.

I’m having trouble porting/understanding the code that reads the button states of grid since it’s using lots of bitwise operators which I’m not comfortable with yet :confused: .

The project uses a 74HC164 74HC165 shift register combo to manage the button grid and a Max7219 to drive the LED’s. Driving the Max7219 with the LedControl lib was pretty straight forward :).

The issue I’m having is that I’m not really able to read the individual button values - or interpret what I read from the 165 correctly?

The output looks like this when I press a button. I was expecting to only see one value change instead of all:

7:11111111
6:11111111
5:11111111
4:11111111
3:11111111
2:11111111
1:11111111
0:11111111
---
7:01111111
6:01111111
5:01111111
4:01111111
3:01111111
2:01111111
1:01111111
0:01111111
---

Here’s my code so far.

#include "LedControl.h"

LedControl lc=LedControl(4,6,5,1); //

// Connections to the 164 shift register
// dataPin = 3 = PORTD, bit 3
// clockPin = 2 = PORTD, bit 2
int dataPin = 3;
int clockPin = 4;

// Connections to the 165 shift register
// inloadPin = arduino digital pin 8 = PORTB, bit 0
// indataPin = arduino digital pin 9 = PORTB, bit 1
// inclockPin = arduino digital pin 7 = PORTD, bit 7
int inloadPin = 8;
int indataPin = 9;
int inclockPin = 7;

byte r = 0;

void setup() {

  Serial.begin(9600);

  // 164
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  // 165
  pinMode(indataPin, INPUT);
  pinMode(inclockPin, OUTPUT);
  pinMode(inloadPin, OUTPUT);

  // the zero refers to the MAX7219 number
  lc.shutdown(0,false);// turn off power saving
  lc.setIntensity(0,4);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen

  whoosh();
}

void buttonPress() {

  for(int i = 7; i >= 0; i--) {
    // 164 
    shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);

    // 165 take snapshot
    digitalWrite(inloadPin, 0);
    digitalWrite(inloadPin, 1);

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

    // read 165 inputs
    for(int j = 0; j < 8; j++) {
      digitalWrite(inclockPin, 0);
      // delayMicroseconds(2);
      r = digitalRead(indataPin);
      digitalWrite(inclockPin, 1);
      Serial.print(r);
    }
    Serial.println("");
  }
  Serial.println("---");
  delay(3000);
}

void whoosh() {
    for (int row=0; row<8; row++) {
    for (int col=0; col<8; col++) {
      lc.setLed(0,col,row,true); // turns on LED at col, row
      delay(25);
    }
  }
  for (int row=0; row<8; row++) {
    for (int col=0; col<8; col++) {
      lc.setLed(0,col,row,false); // turns off LED at col, row
      delay(25);
    }
  }
}

void loop() {
  buttonPress();
}

For readability purposes I used pastebin for the original firmware, you can find it here the code that reads the button presses starts at line 313

Thanks in advance for any pointers and have a nice Sunday everyone!

Can you post the original code here also between code tags, or is it too long? If so, please attach it to your post. (We prefer not to follow links to other sites when it is not necessary.)

So you are rebuilding the circuit using a Leonardo, connecting everything in the same way as it was on the Duemilanove? Why do you think the fault is in the code and not a wiring fault?

Hi Paul,

thanks for the reply.

I’ve attached the code, it think it’s a bit too long to post here.

If you decide to look into it please let me know how I can make it up to you :).

The project used a shield, so the wiring is okay. I’ve tested the board with my Due and it works. The code however doesn’t compile for the Leonardo. I’ve googled the errors but this is a bit over my head. Since I wanted to send the button presses of the 8x8 grid via MIDIUSB anyway I thought I might be better of to start from scratch and use libs like LedControl (which worked like a charm).

I’m only having trouble reading the out the 8x8 button grid correctly.

Thanks in advance!

Here are the compile errors:

Preparing boards...
Verifying...
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:30:0,

                 from sketch\ArduinomeFirmware3_3a.ino.cpp:1:

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino: In function 'void TIMER2_OVF_vect()':

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:373:5: warning: 'TIMER2_OVF_vect' appears to be a misspelled 'signal' handler, missing '__vector' prefix [-Wmisspelled-isr]

 ISR(TIMER2_OVF_vect) {

     ^

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino: In function 'void setup()':

ArduinomeFirmware3_3a:512:3: error: 'TCCR2A' was not declared in this scope

   TCCR2A = 0;

   ^~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:512:3: note: suggested alternative: 'TCCR0A'

   TCCR2A = 0;

   ^~~~~~

   TCCR0A

ArduinomeFirmware3_3a:514:3: error: 'TCCR2B' was not declared in this scope

   TCCR2B = 1<<CS21;

   ^~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:514:3: note: suggested alternative: 'TCCR0B'

   TCCR2B = 1<<CS21;

   ^~~~~~

   TCCR0B

ArduinomeFirmware3_3a:514:15: error: 'CS21' was not declared in this scope

   TCCR2B = 1<<CS21;

               ^~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:514:15: note: suggested alternative: 'CS01'

   TCCR2B = 1<<CS21;

               ^~~~

               CS01

ArduinomeFirmware3_3a:520:3: error: 'TIMSK2' was not declared in this scope

   TIMSK2 = 1<<TOIE2;

   ^~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:520:3: note: suggested alternative: 'TIMSK0'

   TIMSK2 = 1<<TOIE2;

   ^~~~~~

   TIMSK0

ArduinomeFirmware3_3a:520:15: error: 'TOIE2' was not declared in this scope

   TIMSK2 = 1<<TOIE2;

               ^~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:520:15: note: suggested alternative: 'TOIE0'

   TIMSK2 = 1<<TOIE2;

               ^~~~~

               TOIE0

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterCode.ino: At global scope:

ShiftRegisterCode:3:5: error: conflicting declaration 'int dataPin'

 int dataPin = 2;

     ^~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:83:6: note: previous declaration as 'byte dataPin'

 byte dataPin = 3;

      ^~~~~~~

ShiftRegisterCode:8:5: error: conflicting declaration 'int indataPin'

 int indataPin = 12;

     ^~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:103:6: note: previous declaration as 'byte indataPin'

 byte indataPin = 1;

      ^~~~~~~~~

ShiftRegisterCode:9:5: error: conflicting declaration 'int inclockPin'

 int inclockPin = 13;

     ^~~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:107:6: note: previous declaration as 'byte inclockPin'

 byte inclockPin = 7;

      ^~~~~~~~~~

ShiftRegisterCode:10:5: error: conflicting declaration 'int inloadPin'

 int inloadPin = 10; // toggling this tells the 165 to read the value into its memory for reading

     ^~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:98:6: note: previous declaration as 'byte inloadPin'

 byte inloadPin = 0;

      ^~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterCode.ino: In function 'void setup()':

ShiftRegisterCode:12:6: error: redefinition of 'void setup()'

 void setup() {

      ^~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:490:6: note: 'void setup()' previously defined here

 void setup () {

      ^~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterCode.ino: In function 'void loop()':

ShiftRegisterCode:31:6: error: redefinition of 'void loop()'

 void loop() {

      ^~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:596:6: note: 'void loop()' previously defined here

 void loop () {

      ^~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterExample.ino: At global scope:

ShiftRegisterExample:4:5: error: conflicting declaration 'int dataPin'

 int dataPin = 3;

     ^~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:83:6: note: previous declaration as 'byte dataPin'

 byte dataPin = 3;

      ^~~~~~~

ShiftRegisterExample:5:5: error: redefinition of 'int clockPin'

 int clockPin = 4;

     ^~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterCode.ino:4:5: note: 'int clockPin' previously defined here

 int clockPin = 3;

     ^~~~~~~~

ShiftRegisterExample:9:5: error: conflicting declaration 'int indataPin'

 int indataPin = 9;

     ^~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:103:6: note: previous declaration as 'byte indataPin'

 byte indataPin = 1;

      ^~~~~~~~~

ShiftRegisterExample:10:5: error: conflicting declaration 'int inclockPin'

 int inclockPin = 10;

     ^~~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:107:6: note: previous declaration as 'byte inclockPin'

 byte inclockPin = 7;

      ^~~~~~~~~~

ShiftRegisterExample:11:5: error: conflicting declaration 'int inloadPin'

 int inloadPin = 12; // toggling this tells the 165 to read the value into its memory for reading

     ^~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:98:6: note: previous declaration as 'byte inloadPin'

 byte inloadPin = 0;

      ^~~~~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterExample.ino: In function 'void setup()':

ShiftRegisterExample:15:6: error: redefinition of 'void setup()'

 void setup() {

      ^~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:490:6: note: 'void setup()' previously defined here

 void setup () {

      ^~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ShiftRegisterExample.ino: In function 'void loop()':

ShiftRegisterExample:73:6: error: redefinition of 'void loop()'

 void loop() {

      ^~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:596:6: note: 'void loop()' previously defined here

 void loop () {

      ^~~~

ArduinomeFirmware3_3a.ino (19.5 KB)

Have you got 3 .ino files in the same folder? It looks like that. I suspect "ShiftRegisterExample.ino" and "ShiftRegisterCode.ino" should not be in that folder. Try moving them somewhere else and verify again.

You’re right, forgot to move these out, however the errors persist.

I also did try the “suggested alternatives” but without any luck.

Preparing boards...
Verifying...
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:30:0,

                 from sketch\ArduinomeFirmware3_3a.ino.cpp:1:

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino: In function 'void TIMER2_OVF_vect()':

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:373:5: warning: 'TIMER2_OVF_vect' appears to be a misspelled 'signal' handler, missing '__vector' prefix [-Wmisspelled-isr]

 ISR(TIMER2_OVF_vect) {

     ^

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino: In function 'void setup()':

ArduinomeFirmware3_3a:512:3: error: 'TCCR2A' was not declared in this scope

   TCCR2A = 0;

   ^~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:512:3: note: suggested alternative: 'TCCR0A'

   TCCR2A = 0;

   ^~~~~~

   TCCR0A

ArduinomeFirmware3_3a:514:3: error: 'TCCR2B' was not declared in this scope

   TCCR2B = 1<<CS21;

   ^~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:514:3: note: suggested alternative: 'TCCR0B'

   TCCR2B = 1<<CS21;

   ^~~~~~

   TCCR0B

ArduinomeFirmware3_3a:514:15: error: 'CS21' was not declared in this scope

   TCCR2B = 1<<CS21;

               ^~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:514:15: note: suggested alternative: 'CS01'

   TCCR2B = 1<<CS21;

               ^~~~

               CS01

ArduinomeFirmware3_3a:520:3: error: 'TIMSK2' was not declared in this scope

   TIMSK2 = 1<<TOIE2;

   ^~~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:520:3: note: suggested alternative: 'TIMSK0'

   TIMSK2 = 1<<TOIE2;

   ^~~~~~

   TIMSK0

ArduinomeFirmware3_3a:520:15: error: 'TOIE2' was not declared in this scope

   TIMSK2 = 1<<TOIE2;

               ^~~~~

e:\Dev\Arduino\ArduinomeFirmware3_3a\ArduinomeFirmware3_3a.ino:520:15: note: suggested alternative: 'TOIE0'

   TIMSK2 = 1<<TOIE2;

               ^~~~~

               TOIE0

exit status 1

These errors, they are from the sketch in your original post, or the longer code in pastebin?

Edit: I think they must be from the pastebin code. That code is really old, and uses direct port manipulation and directly accesses timer resisters and uses timer interrupt service routines. These things tend to be a little frowned upon these days in favour of libraries which hide all that grubby stuff from all but the most advanced and experienced Arduino users. Another reason is that the libraries can often hide the differences between different MCU, making the code easier to port between chips, as you are doing. Even the atmega328 and atmega32u4 have some significant differences when it comes to ports, timers and registers, and guess that’s why the code won’t compile.

Your code in your original post seems to be an attempt to rewrite the code, using libraries and avoiding low-level stuff. But re-writing and debugging the original firmware won’t be easy for a beginner. It’s that what you want to achieve?

PaulRB:
These errors, they are from the sketch in your original post, or the longer code in pastebin?

Yeah, these are from the pastbin code (the one I later attached).

PaulRB:
Your code in your original post seems to be an attempt to rewrite the code, using libraries and avoiding low-level stuff. But re-writing and debugging the original firmware won't be easy for a beginner. It's that what you want to achieve?

Yes that's exactly what I want to achieve. The original Firmware used Serial for sending the Button readouts. I want to use the MIDIUSB library, that's why I got the Leonardo because it can use this library.

I'm aware of the difficulty. As far as I can tell a lot of that old code deals with optimization of the serial communication which needed to work both ways. I'm not interested in that, I'm merely trying to understand how to read out the button presses of the 8x8 grid via the shift registers :).

I got that halfway working (see my 1st post). I can read out the pressed row, but somehow fail to make it work to get an individual button readout.

Thanks again for taking your time to help a beginner :).

Ok, seems we went off at a tangent there for a while. Let's forget the old firmware and it's errors and focus on your new sketch.

Do you have a schematic showing how the button matrix, '164 and '165 chips, pull-up/down resistors, diodes, bypass caps etc are wired? If not, please draw one. You don't have to show all 64 buttons, maybe just the 4 at the corners and we can assume the others in-between are similar. I know you said it works ok with the old Arduino, but we will need to understand its operation to write new code for it.

Do you want to ever press more than one button at once?

PaulRB:
Ok, seems we went off at a tangent there for a while. Let’s forget the old firmware and it’s errors and focus on your new sketch.

Okay :).

PaulRB:
Do you have a schematic showing how the button matrix, '164 and '165 chips, pull-up/down resistors, diodes, bypass caps etc are wired? If not, please draw one. You don’t have to show all 64 buttons, maybe just the 4 at the corners and we can assume the others in-between are similar. I know you said it works ok with the old Arduino, but we will need to understand its operation to write new code for it.

Do you want to ever press more than one button at once?

Sorry it took me a while to gather everything since the original page with the build instructions isn’t online anymore. But I got lucky and recovered everything using the wayback machine of archive.org.

The build uses 4 of these Sparkfun button pad PCBs & button pads:

I tried several times to attach pictures to the forum reply but the forum kept deleting my reply after the bot check so I’ve uploaded a picture of the Arduino Shield PCB (I still got a couple spare ones in case you want one :)) ) and the wiring schematic to imgur. I hope that’s okay.

And yes, ideally I would like to be able to press several buttons at once (bitmasks?).

Thanks again and have nice weekend!

It seems you forgot how to post links. You did it ok in your original post.

Not sure why you can't attach images. Did you read and follow the instructions in the forum guide?

I would like to be able to press several buttons at once (bitmasks?).

Not "bitmasks", no. Diodes. Do your pcbs have them fitted in series with each switch?

PaulRB:
It seems you forgot how to post links. You did it ok in your original post.

No, but it seems I took your 1st reply about people not being to keen of external links a bit too literal :D. Apologies. My bad.

PaulRB:
Not sure why you can't attach images. Did you read and follow the instructions in the forum guide?

Yes, I did read the forum guide, and having been online since the inception of the Internet I hope to be able to use a forum :smiley: (even though I stopped using the for the most part in recent years). I tried with several browsers. Whenever I attached a .jpeg and submitted the post the forum would re-load to an empty submit form. Either I was having bad luck or the forum doesn't like .jpeg images or sth. else. On a related note: I tried replying to this thread from my ipad earlier just using the quick reply button (chrome) the quote function did nothing and the reply didn't go through either.

I am already making myself a habit of copying the text I write here before submitting so I don't have to write it all over xD.

But back on topic.

PaulRB:
Not "bitmasks", no. Diodes. Do your pcbs have them fitted in series with each switch?

The original Firmware did allow for simultaneous button presses. I assume that to be the case yes.

Thank you and have a great week :)!

Try this:

    // 164
    shiftOut(dataPin, clockPin, MSBFIRST, ~(1 << i));

PaulRB:
Try this:

    // 164

shiftOut(dataPin, clockPin, MSBFIRST, ~(1 << i));

Thanks again Paul!

Unfortunetly that gives me the same results as just 1 << i.

I suspect there might sth. else not really right in my buttonPress() function. I’ll learn more about bitwise operators and try to dissect/understand the original Firmware better.

If you have any other ideas, I’d be happy to hear.

Thanks again for being so helpful thus far!

That wasn’t just a random “try something” suggestion. I came up with it from reading the old firmware.

The old firmware shifts in a 0 bit, then shifts in 7 x 1 bits, pushing the zero from one end of the register to the other, thus scanning the columns (rows?) in turn by grounding them while the other columns are 5V.

Your code is doing, in effect, the opposite: it shifts in a 1 bit, then shifts in 7 x 0 bits to push the 1 bit from one end to the other. This scans the columns by making one 5V while the other 7 are grounded. The opposite way that the the matrix was intended to be scanned.

My suggestion of using “~” inverts the 1s and 0s, making your code act like the old firmware. At least that was the theory.

Try this instead:

void buttonPress() {

  digitalWrite(dataPin, LOW);

  for(int i = 0; i < 8; i++) {
    // 164
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
    digitalWrite(dataPin, HIGH);

    // 165 take snapshot
    digitalWrite(inloadPin, LOW);
    digitalWrite(inloadPin, HIGH);

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

    // read 165 inputs
    for(int j = 0; j < 8; j++) {
      // delayMicroseconds(2);
      r = digitalRead(indataPin);
      Serial.print(r);
      digitalWrite(inclockPin, HIGH);
      digitalWrite(inclockPin, LOW);
    }
    Serial.println("");
  }
  Serial.println("---");
  delay(3000);
}

PaulRB:
That wasn't just a random "try something" suggestion. I came up with it from reading the old firmware.

The old firmware shifts in a 0 bit, then shifts in 7 x 1 bits, pushing the zero from one end of the register to the other, thus scanning the columns (rows?) in turn by grounding them while the other columns are 5V.

Your code is doing, in effect, the opposite: it shifts in a 1 bit, then shifts in 7 x 0 bits to push the 1 bit from one end to the other. This scans the columns by making one 5V while the other 7 are grounded. The opposite way that the the matrix was intended to be scanned.

My suggestion of using "~" inverts the 1s and 0s, making your code act like the old firmware. At least that was the theory.

Try this instead:

Thank you for this thorough explanation and your patience!

I tried this and it also gives me a result like this when pressing a single button.

0:10111111
1:10111111
2:10111111
3:10111111
4:10111111
5:10111111
6:10111111
7:10111111

Could it be that this is in some why related to this part of the old firmare. If I understand that correctly that's how the INPUT/OUTPUT's are set in the old firmware right?

// IMPORTANT - you'll need to make sure that you set the data following two direction register variables to match your
// pin assignments.
byte PORTD_Data_Direction = 0xFE; // 11111110
byte PORTB_Data_Direction = 0xFD; // 11111101

...

setup() {
  DDRD = PORTD_Data_Direction;
  DDRB = PORTB_Data_Direction;

....

My setup looks like this:

  // 164
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  // 165
  pinMode(indataPin, INPUT);
  pinMode(inclockPin, OUTPUT);
  pinMode(inloadPin, OUTPUT);

Thanks again!

Btw, if you have an amazon book wishlist or any other way how I can thank you for spending so much time on my problem please let me know.

The Duemilanove had an atmega168 or 328, with a pinout like this:

These lines

byte PORTD_Data_Direction = 0xFE; // 11111110
byte PORTB_Data_Direction = 0xFD; // 11111101

seem to set pins PD0 and PB1 which are Arduino pins 0 (Rx) and 9 to input. The other pins on those ports are all set to output, Arduino pins 1-8, 10-13. That seems to match what you have in your new sketch.

The board pinout of Duemilanove looks like this

The board pinout of Leonardo looks like

So the positions of all the pins look identical.

Here is the pinout of the atmega32u4:

Your new sketch says

// Connections to the 164 shift register
// dataPin = 3 = PORTD, bit 3
// clockPin = 2 = PORTD, bit 2
int dataPin = 3;
int clockPin = 4;

// Connections to the 165 shift register
// inloadPin = arduino digital pin 8 = PORTB, bit 0
// indataPin = arduino digital pin 9 = PORTB, bit 1
// inclockPin = arduino digital pin 7 = PORTD, bit 7
int inloadPin = 8;
int indataPin = 9;
int inclockPin = 7;

The old firmware says

// Connections to the 164 shift register
//  dataPin = 3 = PORTD, bit 3
// clockPin = 2 = PORTD, bit 2
#define DATA_PORT_164 (PORTD)
byte dataPin = 3;
byte dataPinMaskHigh = 1 << dataPin;
byte dataPinMaskLow = ~dataPinMaskHigh;
 
#define CLOCK_PORT_164 (PORTD)
byte ClockPin = 2;
byte clockPinMaskHigh = 1 << ClockPin;
byte clockPinMaskLow = ~clockPinMaskHigh;
// end connections to the 164 shift register
 
// Connections to the 165 shift register
//  inloadPin = arduino digital pin 8 = PORTB, bit 0
// indataPin = arduino digital pin 9 = PORTB, bit 1
// inclockPin = arduino digital pin 7 = PORTD, bit 7
#define LOAD_PORT_165 (PORTB)
byte inloadPin = 0;
byte inloadPinMaskHigh = 1 << inloadPin;
byte inloadPinMaskLow = ~inloadPinMaskHigh;
 
#define INPUT_DATA_PORT_165 (PINB)
byte indataPin = 1;
byte indataPinMask = 1 << indataPin;
 
#define CLOCK_PORT_165 (PORTD)
byte inclockPin = 7;
byte inclockPinMaskHigh = 1 << inclockPin;
byte inclockPinMaskLow = ~inclockPinMaskHigh;
// end connections to the 165 shift register

void buttonpress ()
{
 
  DATA_PORT_164 &= dataPinMaskLow;
  //164
  for(i = 0; i < 8; i++)
  {
    CLOCK_PORT_164 |= clockPinMaskHigh;
    CLOCK_PORT_164 &= clockPinMaskLow;  
    DATA_PORT_164 |= dataPinMaskHigh;  
 
 
    // SlowDown is put in here to waste a little time while we wait for the state of the output
    // pins to settle.  Without this time wasting loop, a single button press would show up as
    // two presses (the button and its neighbour)
    volatile int SlowDown = 0;
 
    while (SlowDown < 15)
    {
      SlowDown++;
    }
 
    button_last [i] = button_current [i];
 
    //165
    LOAD_PORT_165 &= inloadPinMaskLow; // digitalWrite(inloadPin, LOW);
    LOAD_PORT_165 |= inloadPinMaskHigh;// digitalWrite(inloadPin, HIGH);
 
    for(id = 0; id < 8; id++) {
 
      t = (INPUT_DATA_PORT_165 & indataPinMask) >> 1;//t = digitalRead(indataPin);
      t = (t == 0);
      if(t){
        button_current [i] |= (1 << id);
      }
      else{
          button_current [i] &= ~(1 << id);
      }
 
      buttonCheck(i, id);
 
      if (button_event[i] & (1 << id)) {
        button_event[i] &= ~(1 << id);
        if(button_state[i] & (1 << id)){
          b = 1;
        }
        else{
          b = 0;
        }
        Serial.write((0 << 4) | (b & 15));
        Serial.write((id << 4) | (i & 15));
 
      }
      CLOCK_PORT_165 |= inclockPinMaskHigh;
      CLOCK_PORT_165 &= inclockPinMaskLow;  
    }
  }
 
}

So as far as I can see, you are using all the correct Arduino pin numbers.

0:10111111
1:10111111
2:10111111
3:10111111
4:10111111
5:10111111
6:10111111
7:10111111

I think what this tells us is that all 8 outputs of the 164 are LOW all the time. To scan the matrix, only one should be LOW at a time and the other 7 should be HIGH. I strongly suspect all 8 inputs of the 165 are pulled up to HIGH with resistors.