Page 1 of 2

Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 8:43 am
by muh89
Hello!

I made a pressure sensor matrix that has a first layer of 96 copper tape strips (rows), a velostat (semi-conductive material) layer and 176 copper tape strips (columns) for a total of 176x96=16896 sensors! I based my work on this two designs: https://www.youtube.com/watch?v=0uPZwMg5B3k and https://www.youtube.com/watch?v=xvmgzwjKnN4&t=297s.

I'm using a nucleo-144 f746zg board with 11 multiplexers (16 channels) connected to all 176 columns through diods. I'm sending 3,3V at one column at a time and reading the signal of one row at a time through other 6 multiplexers connected to the same ADC pin. Each row is also connected to ground through 1k resistors. The data is transmitted through the st-link USB of the nucleo board to my Mac and a little Processing sketch creates a heatmap from the acquired data. This is a simplified drawing of the wirings:
schematics.jpeg
schematics.jpeg (37.03 KiB) Viewed 4034 times
At first I create a small 16x16 project with Arduino Uno, than a bigger 32x32 project with both Arduino Mega or Nucleo-144 f746zg. All these projects worked perfectly (as you can see from this little video: https://drive.google.com/file/d/18HQxM9 ... sp=sharing) but this bigger version has two major issues:
-crosstalk (or ghosting? i don't know how to call it) along the rows being pressed as you can see from this image of my left hand leaning on the mat
Schermata 2021-05-19 alle 10.02.30.png
Schermata 2021-05-19 alle 10.02.30.png (31.54 KiB) Viewed 4034 times
-sampling frequency. It takes about 1500ms to read all the 16896 sensors and transmit the readings to my Mac. It means 0,7 scans per second when i need, at least, 5 or 10 scans per second.

This is the Arduino IDE code:

Code: Select all

//Mux control pins for analog signal
const byte s0 = PB9;
const byte s1 = PD8;
const byte s2 = PA5;
const byte s3 = PA12;
const byte eninMux1 = PB6;
const byte eninMux2 = PB11;
const byte eninMux3 = PA7;
const byte eninMux4 = PB12;
const byte eninMux5 = PA6;
const byte eninMux6 = PA11;
const byte SIG_pin = A0;

//Mux control pins for Output signal
const byte w0 = PC7;
const byte w1 = PB2;
const byte w2 = PA9;
const byte w3 = PB1; 
const byte enoutMux1 = PA2;
const byte enoutMux2 = PF5;
const byte enoutMux3 = PA10;
const byte enoutMux4 = PC4;
const byte enoutMux5 = PB3;
const byte enoutMux6 = PB5;
const byte enoutMux7 = PB13;
const byte enoutMux8 = PB4;
const byte enoutMux9 = PB14;
const byte enoutMux10 = PB10;
const byte enoutMux11 = PB15;
const byte OUT_pin = PA8;


//Arrays:
const boolean outmuxChannel[176][15]={
    {0,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, //channel 0
    {0,1,1,1,1,1,1,1,1,1,1,1,0,0,0}, //channel 1
    {0,1,1,1,1,1,1,1,1,1,1,0,1,0,0}, //channel 2
    {0,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, //channel 3
    {0,1,1,1,1,1,1,1,1,1,1,0,0,1,0}, //channel 4
    {0,1,1,1,1,1,1,1,1,1,1,1,0,1,0}, //channel 5
    {0,1,1,1,1,1,1,1,1,1,1,0,1,1,0}, //channel 6
    {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, //channel 7
    {0,1,1,1,1,1,1,1,1,1,1,0,0,0,1}, //channel 8
    {0,1,1,1,1,1,1,1,1,1,1,1,0,0,1}, //channel 9
    {0,1,1,1,1,1,1,1,1,1,1,0,1,0,1}, //channel 10
    {0,1,1,1,1,1,1,1,1,1,1,1,1,0,1}, //channel 11
    {0,1,1,1,1,1,1,1,1,1,1,0,0,1,1}, //channel 12
    {0,1,1,1,1,1,1,1,1,1,1,1,0,1,1}, //channel 13
    {0,1,1,1,1,1,1,1,1,1,1,0,1,1,1}, //channel 14
    {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1},  //channel 15

    {1,0,1,1,1,1,1,1,1,1,1,0,0,0,0}, //channel 0
    {1,0,1,1,1,1,1,1,1,1,1,1,0,0,0}, //channel 1
    {1,0,1,1,1,1,1,1,1,1,1,0,1,0,0}, //channel 2
    {1,0,1,1,1,1,1,1,1,1,1,1,1,0,0}, //channel 3
    {1,0,1,1,1,1,1,1,1,1,1,0,0,1,0}, //channel 4
    {1,0,1,1,1,1,1,1,1,1,1,1,0,1,0}, //channel 5
    {1,0,1,1,1,1,1,1,1,1,1,0,1,1,0}, //channel 6
    {1,0,1,1,1,1,1,1,1,1,1,1,1,1,0}, //channel 7
    {1,0,1,1,1,1,1,1,1,1,1,0,0,0,1}, //channel 8
    {1,0,1,1,1,1,1,1,1,1,1,1,0,0,1}, //channel 9
    {1,0,1,1,1,1,1,1,1,1,1,0,1,0,1}, //channel 10
    {1,0,1,1,1,1,1,1,1,1,1,1,1,0,1}, //channel 11
    {1,0,1,1,1,1,1,1,1,1,1,0,0,1,1}, //channel 12
    {1,0,1,1,1,1,1,1,1,1,1,1,0,1,1}, //channel 13
    {1,0,1,1,1,1,1,1,1,1,1,0,1,1,1}, //channel 14
    {1,0,1,1,1,1,1,1,1,1,1,1,1,1,1}, //channel 15

    {1,1,0,1,1,1,1,1,1,1,1,0,0,0,0}, //channel 0
    {1,1,0,1,1,1,1,1,1,1,1,1,0,0,0}, //channel 1
    {1,1,0,1,1,1,1,1,1,1,1,0,1,0,0}, //channel 2
    {1,1,0,1,1,1,1,1,1,1,1,1,1,0,0}, //channel 3
    {1,1,0,1,1,1,1,1,1,1,1,0,0,1,0}, //channel 4
    {1,1,0,1,1,1,1,1,1,1,1,1,0,1,0}, //channel 5
    {1,1,0,1,1,1,1,1,1,1,1,0,1,1,0}, //channel 6
    {1,1,0,1,1,1,1,1,1,1,1,1,1,1,0}, //channel 7
    {1,1,0,1,1,1,1,1,1,1,1,0,0,0,1}, //channel 8
    {1,1,0,1,1,1,1,1,1,1,1,1,0,0,1}, //channel 9
    {1,1,0,1,1,1,1,1,1,1,1,0,1,0,1}, //channel 10
    {1,1,0,1,1,1,1,1,1,1,1,1,1,0,1}, //channel 11
    {1,1,0,1,1,1,1,1,1,1,1,0,0,1,1}, //channel 12
    {1,1,0,1,1,1,1,1,1,1,1,1,0,1,1}, //channel 13
    {1,1,0,1,1,1,1,1,1,1,1,0,1,1,1}, //channel 14
    {1,1,0,1,1,1,1,1,1,1,1,1,1,1,1},  //channel 15

    {1,1,1,0,1,1,1,1,1,1,1,0,0,0,0}, //channel 0
    {1,1,1,0,1,1,1,1,1,1,1,1,0,0,0}, //channel 1
    {1,1,1,0,1,1,1,1,1,1,1,0,1,0,0}, //channel 2
    {1,1,1,0,1,1,1,1,1,1,1,1,1,0,0}, //channel 3
    {1,1,1,0,1,1,1,1,1,1,1,0,0,1,0}, //channel 4
    {1,1,1,0,1,1,1,1,1,1,1,1,0,1,0}, //channel 5
    {1,1,1,0,1,1,1,1,1,1,1,0,1,1,0}, //channel 6
    {1,1,1,0,1,1,1,1,1,1,1,1,1,1,0}, //channel 7
    {1,1,1,0,1,1,1,1,1,1,1,0,0,0,1}, //channel 8
    {1,1,1,0,1,1,1,1,1,1,1,1,0,0,1}, //channel 9
    {1,1,1,0,1,1,1,1,1,1,1,0,1,0,1}, //channel 10
    {1,1,1,0,1,1,1,1,1,1,1,1,1,0,1}, //channel 11
    {1,1,1,0,1,1,1,1,1,1,1,0,0,1,1}, //channel 12
    {1,1,1,0,1,1,1,1,1,1,1,1,0,1,1}, //channel 13
    {1,1,1,0,1,1,1,1,1,1,1,0,1,1,1}, //channel 14
    {1,1,1,0,1,1,1,1,1,1,1,1,1,1,1}, //channel 15

    {1,1,1,1,0,1,1,1,1,1,1,0,0,0,0}, //channel 0
    {1,1,1,1,0,1,1,1,1,1,1,1,0,0,0}, //channel 1
    {1,1,1,1,0,1,1,1,1,1,1,0,1,0,0}, //channel 2
    {1,1,1,1,0,1,1,1,1,1,1,1,1,0,0}, //channel 3
    {1,1,1,1,0,1,1,1,1,1,1,0,0,1,0}, //channel 4
    {1,1,1,1,0,1,1,1,1,1,1,1,0,1,0}, //channel 5
    {1,1,1,1,0,1,1,1,1,1,1,0,1,1,0}, //channel 6
    {1,1,1,1,0,1,1,1,1,1,1,1,1,1,0}, //channel 7
    {1,1,1,1,0,1,1,1,1,1,1,0,0,0,1}, //channel 8
    {1,1,1,1,0,1,1,1,1,1,1,1,0,0,1}, //channel 9
    {1,1,1,1,0,1,1,1,1,1,1,0,1,0,1}, //channel 10
    {1,1,1,1,0,1,1,1,1,1,1,1,1,0,1}, //channel 11
    {1,1,1,1,0,1,1,1,1,1,1,0,0,1,1}, //channel 12
    {1,1,1,1,0,1,1,1,1,1,1,1,0,1,1}, //channel 13
    {1,1,1,1,0,1,1,1,1,1,1,0,1,1,1}, //channel 14
    {1,1,1,1,0,1,1,1,1,1,1,1,1,1,1},  //channel 15

    {1,1,1,1,1,0,1,1,1,1,1,0,0,0,0}, //channel 0
    {1,1,1,1,1,0,1,1,1,1,1,1,0,0,0}, //channel 1
    {1,1,1,1,1,0,1,1,1,1,1,0,1,0,0}, //channel 2
    {1,1,1,1,1,0,1,1,1,1,1,1,1,0,0}, //channel 3
    {1,1,1,1,1,0,1,1,1,1,1,0,0,1,0}, //channel 4
    {1,1,1,1,1,0,1,1,1,1,1,1,0,1,0}, //channel 5
    {1,1,1,1,1,0,1,1,1,1,1,0,1,1,0}, //channel 6
    {1,1,1,1,1,0,1,1,1,1,1,1,1,1,0}, //channel 7
    {1,1,1,1,1,0,1,1,1,1,1,0,0,0,1}, //channel 8
    {1,1,1,1,1,0,1,1,1,1,1,1,0,0,1}, //channel 9
    {1,1,1,1,1,0,1,1,1,1,1,0,1,0,1}, //channel 10
    {1,1,1,1,1,0,1,1,1,1,1,1,1,0,1}, //channel 11
    {1,1,1,1,1,0,1,1,1,1,1,0,0,1,1}, //channel 12
    {1,1,1,1,1,0,1,1,1,1,1,1,0,1,1}, //channel 13
    {1,1,1,1,1,0,1,1,1,1,1,0,1,1,1}, //channel 14
    {1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},  //channel 15

    {1,1,1,1,1,1,0,1,1,1,1,0,0,0,0}, //channel 0
    {1,1,1,1,1,1,0,1,1,1,1,1,0,0,0}, //channel 1
    {1,1,1,1,1,1,0,1,1,1,1,0,1,0,0}, //channel 2
    {1,1,1,1,1,1,0,1,1,1,1,1,1,0,0}, //channel 3
    {1,1,1,1,1,1,0,1,1,1,1,0,0,1,0}, //channel 4
    {1,1,1,1,1,1,0,1,1,1,1,1,0,1,0}, //channel 5
    {1,1,1,1,1,1,0,1,1,1,1,0,1,1,0}, //channel 6
    {1,1,1,1,1,1,0,1,1,1,1,1,1,1,0}, //channel 7
    {1,1,1,1,1,1,0,1,1,1,1,0,0,0,1}, //channel 8
    {1,1,1,1,1,1,0,1,1,1,1,1,0,0,1}, //channel 9
    {1,1,1,1,1,1,0,1,1,1,1,0,1,0,1}, //channel 10
    {1,1,1,1,1,1,0,1,1,1,1,1,1,0,1}, //channel 11
    {1,1,1,1,1,1,0,1,1,1,1,0,0,1,1}, //channel 12
    {1,1,1,1,1,1,0,1,1,1,1,1,0,1,1}, //channel 13
    {1,1,1,1,1,1,0,1,1,1,1,0,1,1,1}, //channel 14
    {1,1,1,1,1,1,0,1,1,1,1,1,1,1,1},  //channel 15

    {1,1,1,1,1,1,1,0,1,1,1,0,0,0,0}, //channel 0
    {1,1,1,1,1,1,1,0,1,1,1,1,0,0,0}, //channel 1
    {1,1,1,1,1,1,1,0,1,1,1,0,1,0,0}, //channel 2
    {1,1,1,1,1,1,1,0,1,1,1,1,1,0,0}, //channel 3
    {1,1,1,1,1,1,1,0,1,1,1,0,0,1,0}, //channel 4
    {1,1,1,1,1,1,1,0,1,1,1,1,0,1,0}, //channel 5
    {1,1,1,1,1,1,1,0,1,1,1,0,1,1,0}, //channel 6
    {1,1,1,1,1,1,1,0,1,1,1,1,1,1,0}, //channel 7
    {1,1,1,1,1,1,1,0,1,1,1,0,0,0,1}, //channel 8
    {1,1,1,1,1,1,1,0,1,1,1,1,0,0,1}, //channel 9
    {1,1,1,1,1,1,1,0,1,1,1,0,1,0,1}, //channel 10
    {1,1,1,1,1,1,1,0,1,1,1,1,1,0,1}, //channel 11
    {1,1,1,1,1,1,1,0,1,1,1,0,0,1,1}, //channel 12
    {1,1,1,1,1,1,1,0,1,1,1,1,0,1,1}, //channel 13
    {1,1,1,1,1,1,1,0,1,1,1,0,1,1,1}, //channel 14
    {1,1,1,1,1,1,1,0,1,1,1,1,1,1,1},  //channel 15

    {1,1,1,1,1,1,1,1,0,1,1,0,0,0,0}, //channel 0
    {1,1,1,1,1,1,1,1,0,1,1,1,0,0,0}, //channel 1
    {1,1,1,1,1,1,1,1,0,1,1,0,1,0,0}, //channel 2
    {1,1,1,1,1,1,1,1,0,1,1,1,1,0,0}, //channel 3
    {1,1,1,1,1,1,1,1,0,1,1,0,0,1,0}, //channel 4
    {1,1,1,1,1,1,1,1,0,1,1,1,0,1,0}, //channel 5
    {1,1,1,1,1,1,1,1,0,1,1,0,1,1,0}, //channel 6
    {1,1,1,1,1,1,1,1,0,1,1,1,1,1,0}, //channel 7
    {1,1,1,1,1,1,1,1,0,1,1,0,0,0,1}, //channel 8
    {1,1,1,1,1,1,1,1,0,1,1,1,0,0,1}, //channel 9
    {1,1,1,1,1,1,1,1,0,1,1,0,1,0,1}, //channel 10
    {1,1,1,1,1,1,1,1,0,1,1,1,1,0,1}, //channel 11
    {1,1,1,1,1,1,1,1,0,1,1,0,0,1,1}, //channel 12
    {1,1,1,1,1,1,1,1,0,1,1,1,0,1,1}, //channel 13
    {1,1,1,1,1,1,1,1,0,1,1,0,1,1,1}, //channel 14
    {1,1,1,1,1,1,1,1,0,1,1,1,1,1,1},  //channel 15

    {1,1,1,1,1,1,1,1,1,0,1,0,0,0,0}, //channel 0
    {1,1,1,1,1,1,1,1,1,0,1,1,0,0,0}, //channel 1
    {1,1,1,1,1,1,1,1,1,0,1,0,1,0,0}, //channel 2
    {1,1,1,1,1,1,1,1,1,0,1,1,1,0,0}, //channel 3
    {1,1,1,1,1,1,1,1,1,0,1,0,0,1,0}, //channel 4
    {1,1,1,1,1,1,1,1,1,0,1,1,0,1,0}, //channel 5
    {1,1,1,1,1,1,1,1,1,0,1,0,1,1,0}, //channel 6
    {1,1,1,1,1,1,1,1,1,0,1,1,1,1,0}, //channel 7
    {1,1,1,1,1,1,1,1,1,0,1,0,0,0,1}, //channel 8
    {1,1,1,1,1,1,1,1,1,0,1,1,0,0,1}, //channel 9
    {1,1,1,1,1,1,1,1,1,0,1,0,1,0,1}, //channel 10
    {1,1,1,1,1,1,1,1,1,0,1,1,1,0,1}, //channel 11
    {1,1,1,1,1,1,1,1,1,0,1,0,0,1,1}, //channel 12
    {1,1,1,1,1,1,1,1,1,0,1,1,0,1,1}, //channel 13
    {1,1,1,1,1,1,1,1,1,0,1,0,1,1,1}, //channel 14
    {1,1,1,1,1,1,1,1,1,0,1,1,1,1,1},  //channel 15

    {1,1,1,1,1,1,1,1,1,1,0,0,0,0,0}, //channel 0
    {1,1,1,1,1,1,1,1,1,1,0,1,0,0,0}, //channel 1
    {1,1,1,1,1,1,1,1,1,1,0,0,1,0,0}, //channel 2
    {1,1,1,1,1,1,1,1,1,1,0,1,1,0,0}, //channel 3
    {1,1,1,1,1,1,1,1,1,1,0,0,0,1,0}, //channel 4
    {1,1,1,1,1,1,1,1,1,1,0,1,0,1,0}, //channel 5
    {1,1,1,1,1,1,1,1,1,1,0,0,1,1,0}, //channel 6
    {1,1,1,1,1,1,1,1,1,1,0,1,1,1,0}, //channel 7
    {1,1,1,1,1,1,1,1,1,1,0,0,0,0,1}, //channel 8
    {1,1,1,1,1,1,1,1,1,1,0,1,0,0,1}, //channel 9
    {1,1,1,1,1,1,1,1,1,1,0,0,1,0,1}, //channel 10
    {1,1,1,1,1,1,1,1,1,1,0,1,1,0,1}, //channel 11
    {1,1,1,1,1,1,1,1,1,1,0,0,0,1,1}, //channel 12
    {1,1,1,1,1,1,1,1,1,1,0,1,0,1,1}, //channel 13
    {1,1,1,1,1,1,1,1,1,1,0,0,1,1,1}, //channel 14
    {1,1,1,1,1,1,1,1,1,1,0,1,1,1,1},  //channel 15
  };

const boolean inmuxChannel[96][10]={
    {0,1,1,1,1,1,0,0,0,0}, //channel 0
    {0,1,1,1,1,1,1,0,0,0}, //channel 1
    {0,1,1,1,1,1,0,1,0,0}, //channel 2
    {0,1,1,1,1,1,1,1,0,0}, //channel 3
    {0,1,1,1,1,1,0,0,1,0}, //channel 4
    {0,1,1,1,1,1,1,0,1,0}, //channel 5
    {0,1,1,1,1,1,0,1,1,0}, //channel 6
    {0,1,1,1,1,1,1,1,1,0}, //channel 7
    {0,1,1,1,1,1,0,0,0,1}, //channel 8
    {0,1,1,1,1,1,1,0,0,1}, //channel 9
    {0,1,1,1,1,1,0,1,0,1}, //channel 10
    {0,1,1,1,1,1,1,1,0,1}, //channel 11
    {0,1,1,1,1,1,0,0,1,1}, //channel 12
    {0,1,1,1,1,1,1,0,1,1}, //channel 13
    {0,1,1,1,1,1,0,1,1,1}, //channel 14
    {0,1,1,1,1,1,1,1,1,1},  //channel 15

    {1,0,1,1,1,1,0,0,0,0}, //channel 0
    {1,0,1,1,1,1,1,0,0,0}, //channel 1
    {1,0,1,1,1,1,0,1,0,0}, //channel 2
    {1,0,1,1,1,1,1,1,0,0}, //channel 3
    {1,0,1,1,1,1,0,0,1,0}, //channel 4
    {1,0,1,1,1,1,1,0,1,0}, //channel 5
    {1,0,1,1,1,1,0,1,1,0}, //channel 6
    {1,0,1,1,1,1,1,1,1,0}, //channel 7
    {1,0,1,1,1,1,0,0,0,1}, //channel 8
    {1,0,1,1,1,1,1,0,0,1}, //channel 9
    {1,0,1,1,1,1,0,1,0,1}, //channel 10
    {1,0,1,1,1,1,1,1,0,1}, //channel 11
    {1,0,1,1,1,1,0,0,1,1}, //channel 12
    {1,0,1,1,1,1,1,0,1,1}, //channel 13
    {1,0,1,1,1,1,0,1,1,1}, //channel 14
    {1,0,1,1,1,1,1,1,1,1},  //channel 15

    {1,1,0,1,1,1,0,0,0,0}, //channel 0
    {1,1,0,1,1,1,1,0,0,0}, //channel 1
    {1,1,0,1,1,1,0,1,0,0}, //channel 2
    {1,1,0,1,1,1,1,1,0,0}, //channel 3
    {1,1,0,1,1,1,0,0,1,0}, //channel 4
    {1,1,0,1,1,1,1,0,1,0}, //channel 5
    {1,1,0,1,1,1,0,1,1,0}, //channel 6
    {1,1,0,1,1,1,1,1,1,0}, //channel 7
    {1,1,0,1,1,1,0,0,0,1}, //channel 8
    {1,1,0,1,1,1,1,0,0,1}, //channel 9
    {1,1,0,1,1,1,0,1,0,1}, //channel 10
    {1,1,0,1,1,1,1,1,0,1}, //channel 11
    {1,1,0,1,1,1,0,0,1,1}, //channel 12
    {1,1,0,1,1,1,1,0,1,1}, //channel 13
    {1,1,0,1,1,1,0,1,1,1}, //channel 14
    {1,1,0,1,1,1,1,1,1,1},  //channel 15

    {1,1,1,0,1,1,0,0,0,0}, //channel 0
    {1,1,1,0,1,1,1,0,0,0}, //channel 1
    {1,1,1,0,1,1,0,1,0,0}, //channel 2
    {1,1,1,0,1,1,1,1,0,0}, //channel 3
    {1,1,1,0,1,1,0,0,1,0}, //channel 4
    {1,1,1,0,1,1,1,0,1,0}, //channel 5
    {1,1,1,0,1,1,0,1,1,0}, //channel 6
    {1,1,1,0,1,1,1,1,1,0}, //channel 7
    {1,1,1,0,1,1,0,0,0,1}, //channel 8
    {1,1,1,0,1,1,1,0,0,1}, //channel 9
    {1,1,1,0,1,1,0,1,0,1}, //channel 10
    {1,1,1,0,1,1,1,1,0,1}, //channel 11
    {1,1,1,0,1,1,0,0,1,1}, //channel 12
    {1,1,1,0,1,1,1,0,1,1}, //channel 13
    {1,1,1,0,1,1,0,1,1,1}, //channel 14
    {1,1,1,0,1,1,1,1,1,1},  //channel 15

    {1,1,1,1,0,1,0,0,0,0}, //channel 0
    {1,1,1,1,0,1,1,0,0,0}, //channel 1
    {1,1,1,1,0,1,0,1,0,0}, //channel 2
    {1,1,1,1,0,1,1,1,0,0}, //channel 3
    {1,1,1,1,0,1,0,0,1,0}, //channel 4
    {1,1,1,1,0,1,1,0,1,0}, //channel 5
    {1,1,1,1,0,1,0,1,1,0}, //channel 6
    {1,1,1,1,0,1,1,1,1,0}, //channel 7
    {1,1,1,1,0,1,0,0,0,1}, //channel 8
    {1,1,1,1,0,1,1,0,0,1}, //channel 9
    {1,1,1,1,0,1,0,1,0,1}, //channel 10
    {1,1,1,1,0,1,1,1,0,1}, //channel 11
    {1,1,1,1,0,1,0,0,1,1}, //channel 12
    {1,1,1,1,0,1,1,0,1,1}, //channel 13
    {1,1,1,1,0,1,0,1,1,1}, //channel 14
    {1,1,1,1,0,1,1,1,1,1},  //channel 15
    
    {1,1,1,1,1,0,0,0,0,0}, //channel 0
    {1,1,1,1,1,0,1,0,0,0}, //channel 1
    {1,1,1,1,1,0,0,1,0,0}, //channel 2
    {1,1,1,1,1,0,1,1,0,0}, //channel 3
    {1,1,1,1,1,0,0,0,1,0}, //channel 4
    {1,1,1,1,1,0,1,0,1,0}, //channel 5
    {1,1,1,1,1,0,0,1,1,0}, //channel 6
    {1,1,1,1,1,0,1,1,1,0}, //channel 7
    {1,1,1,1,1,0,0,0,0,1}, //channel 8
    {1,1,1,1,1,0,1,0,0,1}, //channel 9
    {1,1,1,1,1,0,0,1,0,1}, //channel 10
    {1,1,1,1,1,0,1,1,0,1}, //channel 11
    {1,1,1,1,1,0,0,0,1,1}, //channel 12
    {1,1,1,1,1,0,1,0,1,1}, //channel 13
    {1,1,1,1,1,0,0,1,1,1}, //channel 14
    {1,1,1,1,1,0,1,1,1,1}  //channel 15
};

//Other variables:
int inByte = 0;
int valor = 0;               
int calibra[96][176];         
int minsensor=100;         


void setup(){
  
  pinMode(s0, OUTPUT); 
  pinMode(s1, OUTPUT); 
  pinMode(s2, OUTPUT); 
  pinMode(s3, OUTPUT); 
  pinMode(eninMux1, OUTPUT);
  pinMode(eninMux2, OUTPUT);
  pinMode(eninMux3, OUTPUT);
  pinMode(eninMux4, OUTPUT);
  pinMode(eninMux5, OUTPUT);
  pinMode(eninMux6, OUTPUT);
  
  pinMode(w0, OUTPUT); 
  pinMode(w1, OUTPUT); 
  pinMode(w2, OUTPUT); 
  pinMode(w3, OUTPUT); 
  pinMode(enoutMux1, OUTPUT);
  pinMode(enoutMux2, OUTPUT);
  pinMode(enoutMux3, OUTPUT);
  pinMode(enoutMux4, OUTPUT);
  pinMode(enoutMux5, OUTPUT);
  pinMode(enoutMux6, OUTPUT);
  pinMode(enoutMux7, OUTPUT);
  pinMode(enoutMux8, OUTPUT);
  pinMode(enoutMux9, OUTPUT);
  pinMode(enoutMux10, OUTPUT);
  pinMode(enoutMux11, OUTPUT);
  
  pinMode(OUT_pin, OUTPUT);
  pinMode(SIG_pin, INPUT);
  //analogReadResolution(8);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  
  digitalWrite(w0, LOW);
  digitalWrite(w1, LOW);
  digitalWrite(w2, LOW);
  digitalWrite(w3, LOW);
  
  digitalWrite(OUT_pin, HIGH);
  
  Serial.begin(2000000);
  
  Serial.println("\n\Calibrating...\n");
  
  // Calibration  
    for(byte j = 0; j < 176; j ++){ 
      writeMux(j);
      for(byte i = 0; i < 96; i ++)
        calibra[i][j] =  readMux(i);
    }
  
  //Print averages
  for(byte j = 0; j < 176; j ++){ 
    writeMux(j);
    for(byte i = 0; i < 96; i ++){
     if(calibra[i][j] < minsensor)
     minsensor = calibra[i][j];
      Serial.print(calibra[i][j]);
      Serial.print("\t");
    }
  Serial.println(); 
  }
  
  Serial.println();
  Serial.print("Minimum Value: ");
  Serial.println(minsensor);
  Serial.println();
  
  establishContact();
}


void loop(){
  if (Serial.available() > 0){
    inByte = Serial.read();
    
    if(inByte == 'A'){
    
      for(int j = 0; j < 176; j++){ 
        writeMux(j);
        
        for(int i = 0; i < 96; i++){
            
          valor = readMux(i);
          valor = (valor-calibra[i][j]);
          
          if(valor < 5)
            valor = 0;
          
          Serial.write(valor);
        } 
      }
    }
  }
}

int readMux(byte channel){
  
  byte control1Pin[] = {eninMux1, eninMux2, eninMux3, eninMux4, eninMux5, eninMux6, s0, s1, s2, s3};
  for(int i = 0; i < 10; i ++){
    digitalWrite(control1Pin[i], inmuxChannel[channel][i]); 
  }
  int val = analogRead(SIG_pin);
  return val;
}

void writeMux(byte channel){
  
  byte control2Pin[] = {enoutMux1, enoutMux2, enoutMux3, enoutMux4, enoutMux5, enoutMux6, enoutMux7, enoutMux8, enoutMux9, enoutMux10, enoutMux11, w0, w1, w2, w3};
  for(byte i = 0; i < 15; i ++){
    digitalWrite(control2Pin[i], outmuxChannel[channel][i]);
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');   
    delay(1000);
  }
}
Can anyone help me on this?
Thank you all

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 8:56 am
by fpiSTM
You can try to use digitalWriteFast but you have to use the PinName instead of pin number.
Ex PB6 becomes PB_6
This will be faster but don't know if it would be enough.

https://github.com/stm32duino/Arduino_C ... l_io.h#L94

You could also use HAL or LL for ADC. AnalogRead is not optimised.

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 9:54 am
by mlundin
Strange , I would have thought the pulldown resistors should be placed on the line inputs to the sensing multiplexors. Thus crating a voltage divider:

Column 3V - velostat rsistance - Out put Row sensor line to ADC - row resistor - ground.

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 10:05 am
by muh89
fpiSTM wrote: Sat May 22, 2021 8:56 am You can try to use digitalWriteFast but you have to use the PinName instead of pin number.
Ex PB6 becomes PB_6
This will be faster but don't know if it would be enough.

https://github.com/stm32duino/Arduino_C ... l_io.h#L94

You could also use HAL or LL for ADC. AnalogRead is not optimised.
Thank you, I'll try with the digitalWriteFast. I know of the AnalogRead limits in terms of speed and I've already searched the web looking for alternatives and I found this HAL or LL but I don't know how and where to use them in the code. Have you got some resources or examples to learn from?

And what about the cross talk? What could be the cause?

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 10:12 am
by muh89
mlundin wrote: Sat May 22, 2021 9:54 am Strange , I would have thought the pulldown resistors should be placed on the line inputs to the sensing multiplexors. Thus crating a voltage divider:

Column 3V - velostat rsistance - Out put Row sensor line to ADC - row resistor - ground.
Do you mean one single resistor between the sensing multiplexers and the ADC pin? instead of 96 resistors for each row between the matrix itself and the sensing multiplexers?

I don't know.. my configuration worked well on the 16x16 and 32x32 attempts.

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 11:33 am
by fpiSTM
Here your code updated to use the digitalWriteFast.

Code: Select all

//Mux control pins for analog signal
const byte s0 = PB9;
const byte s1 = PD8;
const byte s2 = PA5;
const byte s3 = PA12;
const byte eninMux1 = PB6;
const byte eninMux2 = PB11;
const byte eninMux3 = PA7;
const byte eninMux4 = PB12;
const byte eninMux5 = PA6;
const byte eninMux6 = PA11;
const byte SIG_pin = A0;

//Mux control pins for Output signal
const byte w0 = PC7;
const byte w1 = PB2;
const byte w2 = PA9;
const byte w3 = PB1;
const byte enoutMux1 = PA2;
const byte enoutMux2 = PF5;
const byte enoutMux3 = PA10;
const byte enoutMux4 = PC4;
const byte enoutMux5 = PB3;
const byte enoutMux6 = PB5;
const byte enoutMux7 = PB13;
const byte enoutMux8 = PB4;
const byte enoutMux9 = PB14;
const byte enoutMux10 = PB10;
const byte enoutMux11 = PB15;
const byte OUT_pin = PA8;

const PinName control1Pin[] = {digitalPinToPinName(eninMux1), digitalPinToPinName(eninMux2), digitalPinToPinName(eninMux3), digitalPinToPinName(eninMux4), digitalPinToPinName(eninMux5), digitalPinToPinName(eninMux6), digitalPinToPinName(s0), digitalPinToPinName(s1), digitalPinToPinName(s2), digitalPinToPinName(s3)};
const PinName control2Pin[] = {digitalPinToPinName(enoutMux1), digitalPinToPinName(enoutMux2), digitalPinToPinName(enoutMux3), digitalPinToPinName(enoutMux4), digitalPinToPinName(enoutMux5), digitalPinToPinName(enoutMux6), digitalPinToPinName(enoutMux7), digitalPinToPinName(enoutMux8), digitalPinToPinName(enoutMux9), digitalPinToPinName(enoutMux10), digitalPinToPinName(enoutMux11), digitalPinToPinName(w0), digitalPinToPinName(w1), digitalPinToPinName(w2), digitalPinToPinName(w3)};

                               //Arrays:
const boolean outmuxChannel[176][15] = {
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1}, //channel 15
};

const boolean inmuxChannel[96][10] = {
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {0, 1, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {0, 1, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {0, 1, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {0, 1, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {0, 1, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {0, 1, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {0, 1, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {0, 1, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {0, 1, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 0, 1, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 0, 1, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 0, 1, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 0, 1, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 0, 1, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 0, 1, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 0, 1, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 0, 1, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 0, 1, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 0, 1, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 0, 1, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 0, 1, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 0, 1, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 0, 1, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 0, 1, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 0, 1, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 0, 1, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 0, 1, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 0, 1, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 0, 1, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 0, 1, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 0, 1, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 0, 1, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 0, 1, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 0, 1, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 0, 1, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 0, 1, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 0, 1, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 0, 1, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 0, 1, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 0, 1, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 0, 1, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 0, 1, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 0, 1, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 0, 1, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 0, 1, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 0, 1, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 0, 1, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 0, 1, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 0, 1, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 0, 1, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 0, 1, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 0, 1, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 0, 1, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 0, 1, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 0, 1, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 0, 1, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 0, 1, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 0, 1, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 0, 1, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 0, 1, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 0, 1, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 0, 1, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 0, 1, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 0, 1, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 0, 1, 1, 1, 1, 1}, //channel 15

  {1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, //channel 0
  {1, 1, 1, 1, 1, 0, 1, 0, 0, 0}, //channel 1
  {1, 1, 1, 1, 1, 0, 0, 1, 0, 0}, //channel 2
  {1, 1, 1, 1, 1, 0, 1, 1, 0, 0}, //channel 3
  {1, 1, 1, 1, 1, 0, 0, 0, 1, 0}, //channel 4
  {1, 1, 1, 1, 1, 0, 1, 0, 1, 0}, //channel 5
  {1, 1, 1, 1, 1, 0, 0, 1, 1, 0}, //channel 6
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 0}, //channel 7
  {1, 1, 1, 1, 1, 0, 0, 0, 0, 1}, //channel 8
  {1, 1, 1, 1, 1, 0, 1, 0, 0, 1}, //channel 9
  {1, 1, 1, 1, 1, 0, 0, 1, 0, 1}, //channel 10
  {1, 1, 1, 1, 1, 0, 1, 1, 0, 1}, //channel 11
  {1, 1, 1, 1, 1, 0, 0, 0, 1, 1}, //channel 12
  {1, 1, 1, 1, 1, 0, 1, 0, 1, 1}, //channel 13
  {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1, 1, 0, 1, 1, 1, 1} //channel 15
};

//Other variables:
int inByte = 0;
             int valor = 0;
             int calibra[96][176];
             int minsensor = 100;


void setup() {

  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(eninMux1, OUTPUT);
  pinMode(eninMux2, OUTPUT);
  pinMode(eninMux3, OUTPUT);
  pinMode(eninMux4, OUTPUT);
  pinMode(eninMux5, OUTPUT);
  pinMode(eninMux6, OUTPUT);

  pinMode(w0, OUTPUT);
  pinMode(w1, OUTPUT);
  pinMode(w2, OUTPUT);
  pinMode(w3, OUTPUT);
  pinMode(enoutMux1, OUTPUT);
  pinMode(enoutMux2, OUTPUT);
  pinMode(enoutMux3, OUTPUT);
  pinMode(enoutMux4, OUTPUT);
  pinMode(enoutMux5, OUTPUT);
  pinMode(enoutMux6, OUTPUT);
  pinMode(enoutMux7, OUTPUT);
  pinMode(enoutMux8, OUTPUT);
  pinMode(enoutMux9, OUTPUT);
  pinMode(enoutMux10, OUTPUT);
  pinMode(enoutMux11, OUTPUT);

  pinMode(OUT_pin, OUTPUT);
  pinMode(SIG_pin, INPUT);
  //analogReadResolution(8);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);

  digitalWrite(w0, LOW);
  digitalWrite(w1, LOW);
  digitalWrite(w2, LOW);
  digitalWrite(w3, LOW);

  digitalWrite(OUT_pin, HIGH);

  Serial.begin(2000000);

  Serial.println("\n\Calibrating...\n");

  // Calibration
  for (byte j = 0; j < 176; j ++) {
    writeMux(j);
    for (byte i = 0; i < 96; i ++)
      calibra[i][j] =  readMux(i);
  }

  //Print averages
  for (byte j = 0; j < 176; j ++) {
    writeMux(j);
    for (byte i = 0; i < 96; i ++) {
      if (calibra[i][j] < minsensor)
        minsensor = calibra[i][j];
      Serial.print(calibra[i][j]);
      Serial.print("\t");
    }
    Serial.println();
  }

  Serial.println();
  Serial.print("Minimum Value: ");
  Serial.println(minsensor);
  Serial.println();

  establishContact();
}


void loop() {
  if (Serial.available() > 0) {
    inByte = Serial.read();

    if (inByte == 'A') {

      for (int j = 0; j < 176; j++) {
        writeMux(j);

        for (int i = 0; i < 96; i++) {

          valor = readMux(i);
          valor = (valor - calibra[i][j]);

          if (valor < 5)
            valor = 0;

          Serial.write(valor);
        }
      }
    }
  }
}

int readMux(byte channel) {
  for (int i = 0; i < 10; i ++) {
    digitalWriteFast(control1Pin[i], inmuxChannel[channel][i]);
  }
  int val = analogRead(SIG_pin);
  return val;
}

void writeMux(byte channel) {
  for (byte i = 0; i < 15; i ++) {
    digitalWriteFast(control2Pin[i], outmuxChannel[channel][i]);
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');
    delay(1000);
  }
}

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 11:51 am
by mlundin
One resistor to ground before the multiplexer, the series diode should not be needed. The walue of this resistor should be adjusted to be approximately equal to the velostat layer resistance for one crossing when half depressed.

If you dont have a pull down resistor the the sense line becomes "floating" then the corresponding row/column crossing is not depressed. So the state is essentially, undefined, dependent on input impedance of the multiplexer inputs. This floating state can very well be the cause of the memory effetc you see.

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 1:09 pm
by GonzoG
I would replace those "digital" multiplexers with shift registers.
Multiplexers need some time to switch between channels and the lower the Vcc is the more time they need.
As you power one column at a time with fast shift registers you'll need only few MCU cycles (using digitalWriteFast(), and -o3 optimization) to shift data by 1 bit.
Also you'll need only 3-4 pins as all registers are connected in series.

As to analog side, I would connect multiplexers to different analog pins on MCU. This way you reduce time needed to switch multiplexer channels as you need to do it only 16 times instead of 96.

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 3:52 pm
by muh89
fpiSTM wrote: Sat May 22, 2021 11:33 am Here your code updated to use the digitalWriteFast.
Thank you, really appreciated. I just tried your code but nothing changed, always around 1500ms for one scan. :?
mlundin wrote: Sat May 22, 2021 11:51 am One resistor to ground before the multiplexer, the series diode should not be needed. The walue of this resistor should be adjusted to be approximately equal to the velostat layer resistance for one crossing when half depressed.

If you dont have a pull down resistor the the sense line becomes "floating" then the corresponding row/column crossing is not depressed. So the state is essentially, undefined, dependent on input impedance of the multiplexer inputs. This floating state can very well be the cause of the memory effetc you see.
But I already have pull down resistors before analog MUX (bigger circle in the image below) do I need one more resistor here (smaller circle on the image)?
schematics.jpeg
schematics.jpeg (41.32 KiB) Viewed 3976 times
GonzoG wrote: Sat May 22, 2021 1:09 pm I would replace those "digital" multiplexers with shift registers.
Multiplexers need some time to switch between channels and the lower the Vcc is the more time they need.
As you power one column at a time with fast shift registers you'll need only few MCU cycles (using digitalWriteFast(), and -o3 optimization) to shift data by 1 bit.
Also you'll need only 3-4 pins as all registers are connected in series.

As to analog side, I would connect multiplexers to different analog pins on MCU. This way you reduce time needed to switch multiplexer channels as you need to do it only 16 times instead of 96.
Thanks! I like the idea of analog switches, I will try it too but I need to print a new PCB. What concerns analog side: I really don't understand why connecting MUXes to different analog pins should reduce the time.

Re: Crosstalk and sample frequency issues on a pressure sensor matrix

Posted: Sat May 22, 2021 5:50 pm
by mlundin
I cant se why you would use pulldown on the sensing outputs, columns, they are driven to 0 or 3.3V
make a circuit diagram and consider what happens