Crosstalk and sample frequency issues on a pressure sensor matrix

Post here first, or if you can't find a relevant section!
muh89
Posts: 6
Joined: Mon May 17, 2021 7:48 pm

Crosstalk and sample frequency issues on a pressure sensor matrix

Post 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 3874 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 3874 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
User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

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

Post 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.
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

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

Post 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.
muh89
Posts: 6
Joined: Mon May 17, 2021 7:48 pm

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

Post 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?
muh89
Posts: 6
Joined: Mon May 17, 2021 7:48 pm

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

Post 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.
User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

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

Post 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);
  }
}
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

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

Post 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.
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 26
Location: Prudnik, Poland

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

Post 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.
muh89
Posts: 6
Joined: Mon May 17, 2021 7:48 pm

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

Post 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 3816 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.
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

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

Post 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
Post Reply

Return to “General discussion”