AH1751 Hall sensors + 74HC595 shift register grid (chessboard)

Hi everyone!
A lot has been written about hall effect switches and chessboard, but I could not find a solution to my problem.

Circuit
You can see the circuit in the attached file:

  • one 74HC595 shift register, that feeds sensor rows one by one
  • once a row is on, I "scan" colums one by one to check where a magnet is there

Code
Again in the attached file is the code:

  1. I turn all sensor rows off and wait blank_time
  2. I turn row 0 on and wait activate_time
  3. I scan colums 0 to 7 (corresponding to Arduino inputs 5 to 12), waiting read_time between each other
  4. I move to the next row and repeat

Test
If a test the circuit in static conditions, without using the 74HC595 (e.g. feeding a row from the Arduino 5 V pin and leaving other rows off)) it works fine.

But if I use the 74HC595, some sensors (only some, about ten) change their status randomly.

I tried to add delays between rows activation, up to 5000 ms, to see if the problem was during transition.

Then, seeing one single 74HC595 output was at 3 V instead of 5 V, I guessed it could not feed 8 sensors together. I then added 8 NPN transistor, driven by the 74HC595.

But the system still behave the same way.

Possible causes I evaluated
a. defective hall sensors. But during "static" test everything works.
b. too quick transitions. But adding delay the problem's still there.
c. Too high current for 8 hall sensors. But transistors was not the solution.

What can the problem be? What should I do to understand where the problem is?
Thanks!

P.S. I don't really need to tell chess pieces apart. I only need to know if up to 8 magnets are there and where they are.

Grid code ENG.pdf (23.1 KB)

Schema scacchiera.pdf (75.1 KB)

My concern would be residual charge on those output pins. Setting the Arduino pins to OUTPUT and LOW will dissipate that charge:

for(j = 0; j < 8; j++)
{
  pinMode(column[j], OUTPUT);
  digitalWrite(column[j], LOW);
  delay(read_time / 2);
  pinMode(column[j], INPUT); 
  delay(read_time);
  stato[8 * i + j] = digitalRead(column[j]);
}

As an aside the use of a diode is an interesting choice. I would have thought a resistor (~1K) would be more straightforward. Arduino pins also have a 30K pullup if you set the pin to INPUT and digitalWrite(pin, HIGH). I'm not sure if that's enough current, you'd have to test it, but it would eliminate the need for any of the resistors or diodes in your circuit.

I never think about changing the pinMode in the loop() function!
I will try that...thanks!