Hi everyone,
I'm working on a project that involves reading an 8x8 pressure sensor matrix (though my circuit is designed for 16x16, only the first 8 rows and 8 columns are currently connected). My setup uses shift registers (74HC595) to control the rows and a multiplexer (CD74HC4067) to read the columns. The circuit and the readings work fine when I press a single point, a single row, or a single column. However, I'm facing a strange issue when pressing multiple points which i've been trying to fix for weeks now.
The Problem:
When I press three points in the matrix that form a square (e.g., A12
, A21
, and A22
), the fourth corner of the square (A11
, in this case) gives very high readings, almost as if it's being pressed. This behavior persists regardless of which square I press in the matrix.
For example:
Pressing A12
, A21
, and A22
causes A11
to also register as high, even though it’s not being pressed.
Pressing B23
, B32
, and B33
causes B22
to register high.
I think the issue is not cross talk because the extra sensor that gives high readings is giving very high readings, like when it is pressed. for example the other 3 sensors I press will give 600 en the forth corner I don't press gives 550 (where it would give 30 or somthing when it would be cross talk).
My Setup
Microcontroller: Arduino Uno
Shift Registers: 74HC595 to control rows (send)
Multiplexer: CD74HC4067 to read columns (receive MUX)
Sensors: Pressure-sensitive resistors connected at each matrix intersection.
The rows are activated one at a time using the shift register, while the MUX reads the analog values for each column.
What I've Tried:
- Pull-Down Resistors: Added 10kΩ pull-down resistors on the column lines to prevent floating signals.
- Signal Damping: Added 100Ω resistors in series between the shift register and the rows.
- Delays for Stabilization: Added small delays (10 microseconds) between setting a row high and reading the columns.
//sent shifter
int SER_Pin = 2; // defining arduino pin 8 for serial output shift register1
int RCLK_Pin = 4; // defining arduino pin 9 for clock signal shift register1
int SRCLK_Pin = 5; // defining arduino pin 10 for clock signal shift register1
int OE_Pin1 = 3; //pin for controling high impedance state shift register 1
int shift = B1; // Bite for shifting shift register
// Pin-definities voor de receive MUX (kolommen)
const int receiveMuxS0 = 6;
const int receiveMuxS1 = 7;
const int receiveMuxS2 = 8;
const int receiveMuxS3 = 9;
const int receiveMuxSIG = A0; // Analoge pin voor het ontvangen
// Array om de druksensorwaardes op te slaan (8x8 matrix)
int pressureValues[8][8];
void setup() {
// Zet seriële communicatie op voor de monitor
Serial.begin(115200);
// Zet de MUX selectie pinnen als output
pinMode(SER_Pin, OUTPUT);
pinMode(RCLK_Pin, OUTPUT);
pinMode(SRCLK_Pin, OUTPUT);
pinMode(OE_Pin1, OUTPUT);
pinMode(receiveMuxS0, OUTPUT);
pinMode(receiveMuxS1, OUTPUT);
pinMode(receiveMuxS2, OUTPUT);
pinMode(receiveMuxS3, OUTPUT);
// Zet de SIG pinnen als input of output
pinMode(receiveMuxSIG, INPUT); // SIG voor de receive MUX leest analoge waardes
}
void loop() {
// Doorloop de rijen (send MUX), nu van kanaal 8 t/m 15
for (int row = 0; row < 8; row++) {
// Stel de rij in via de send MUX (C8 t/m C15)
digitalWrite(OE_Pin1, LOW); //turn onn shift register 1
digitalWrite(SRCLK_Pin, LOW); // turn off clock signal shift register
digitalWrite(RCLK_Pin, LOW); // turn off clock signal shift register
shiftOut(SER_Pin, SRCLK_Pin, MSBFIRST, shift); // Send binairy value to shift register
delayMicroseconds(10); // Allow signal to stabilize
digitalWrite(RCLK_Pin, HIGH); // turn on clock signal shift register
digitalWrite(SRCLK_Pin, HIGH); // turn on clock signal shift registert
shift = shift * 2; //shifting the binairy value for controlling shift register
// Doorloop de kolommen (receive MUX)
for (int col = 8; col < 15; col++) {
// Stel de kolom in via de receive MUX
setMuxChannel(receiveMuxS0, receiveMuxS1, receiveMuxS2, receiveMuxS3, col);
// Lees de druksensorwaarde op de huidige rij en kolom
int sensorValue = analogRead(receiveMuxSIG);
if (sensorValue < 20){
sensorValue = 0;
}
pressureValues[row][col-8] = sensorValue; // Gebruik row - 8 voor array index
}
}
// solving error for the bit returning to 0
shift = B1; // When shift is 0 rewrite to 1
// Print de waardes naar de seriële monitor
printMatrix();
// Wacht even voordat de volgende uitlezing begint
delay(500);
}
// Functie om de MUX op een bepaalde channel te zetten
void setMuxChannel(int s0, int s1, int s2, int s3, int channel) {
digitalWrite(s0, bitRead(channel, 0));
digitalWrite(s1, bitRead(channel, 1));
digitalWrite(s2, bitRead(channel, 2));
digitalWrite(s3, bitRead(channel, 3));
}
// Functie om de druksensorwaardes in de matrix te printen
void printMatrix() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
Serial.print(pressureValues[i][j]);
Serial.print("\t"); // Tab gescheiden voor netjes printen
}
Serial.println(); // Nieuwe regel voor de volgende rij
Serial.println(); // Nieuwe regel voor de volgende rij
}
Serial.println(); // Extra lege regel tussen matrix uitlezingen
}
The issue only occurs when multiple points forming a square are pressed.
Single row or column presses work perfectly.
The readings at the "phantom" fourth corner are almost as high as if it's being pressed.
Questions:
- What could cause the fourth corner to give a high reading in this scenario?
- Is this a hardware issue in my circuit design, or could it be software-related?
- Has anyone else encountered a similar issue with matrix-based circuits, and how was it resolved?
I've attached my circuit schematic as well. Any help would be greatly appreciated!
Thank you in advance for your time and insights.