Tastenmatrix erkennt 2 Tasten bei einer gedrückten Taste

Gast #3870049
Lesenswert?

Hallo miteinander,

ich bin gerade dabei eine 4x4 Tastenmatrix mit Hilfe eines Mega328 
auszuwerten.

Meine Schaltung sieht folgendermaßen aus:
1
      PD5   PD4   PD3   PD2
2
       |     |     |     |
3
       |     |     |     |
4
PB1----a-----b-----c-----d
5
       |     |     |     |
6
PB0----e-----f-----g-----h
7
       |     |     |     |
8
PD7----i-----j-----k-----l
9
       |     |     |     |
10
PD6----m-----n-----o-----p

Dabei werden PD5 - PD2 als Eingang mit aktivem Pullup und PB1, PB0, PD7 
und PD6 mit hochomig initialisiert.
Dann multiplexe ich die Reihen in einem Timerinterrupt alle 10 ms und 
lese dabei PD5 - PD2 aus.
Nun hab ich folgendes Problem, dass wenn ich die Taste a drücke, erkennt 
er einen Tastendruck auf a und e. Drücke ich Taste e, dann erkennt er 
einen Tastendruck auf e und i. Drücke ich jedoch eine beliebige andere 
Taste (außer a und e), so erkennt er korrekt nur eine Taste.

Mein Code:
Init:
1
   // Ausgangspins fuer Tastenmatrix setzen
2
   // Reihen auf Eingang ohne Pullup
3
   DDRB &= ~(1 << 1);
4
   DDRB &= ~(1 << 0);
5
   DDRD &= ~(1 << 7);
6
   DDRD &= ~(1 << 6);
7
   // Spalten auf Eingang mit Pullup
8
   DDRD &= ~(1 << 5);
9
   DDRD &= ~(1 << 4);
10
   DDRD &= ~(1 << 3);
11
   DDRD &= ~(1 << 2);
12
   PORTD |= (1 << 5);
13
   PORTD |= (1 << 4);
14
   PORTD |= (1 << 3);
15
   PORTD |= (1 << 2);
ISR:
1
ISR(TIMER1_COMPA_vect)
2
{
3
   DDRD &= ~((1 << 7) | (1 << 6));
4
   PORTD &= ~((1 << 7) | (1 << 6));
5
   DDRB &= ~((1 << 1) | (1 << 0));
6
   PORTB &= ~((1 << 1) | (1 << 0));
7
   switch (btn_row)
8
   {
9
      case 0:
10
            DDRB |= (1 << 1);
11
            PORTB &= ~(1 << 1);
12
         break;
13
      case 1:
14
            DDRB |= (1 << 0);
15
            PORTB &= ~(1 << 0);            
16
         break;
17
      case 2:
18
            DDRD |= (1 << 7);
19
            PORTD &= ~(1 << 7);
20
         break;
21
      case 3:
22
            DDRD |= (1 << 6);
23
            PORTD &= ~(1 << 6);      
24
         break;
25
   }
26
   btns[btn_row][0] = (!(PIND & (1 << 5))) ? 1 : 0;
27
   btns[btn_row][1] = (!(PIND & (1 << 4))) ? 1 : 0;
28
   btns[btn_row][2] = (!(PIND & (1 << 3))) ? 1 : 0;
29
   btns[btn_row][3] = (!(PIND & (1 << 2))) ? 1 : 0;
30
   btn_row++;
31
   if (btn_row >= 4) {btn_row = 0;};
32
}

Vielleicht kann mir jemand auf die Sprünge helfen. Danke im vorraus.
Gast #3870071
Lesenswert?

Taster schrieb:

> Vielleicht kann mir jemand auf die Sprünge helfen. Danke im vorraus.

Hmm...

Ich würde von einem "Timing"-Problem ausgehen (eigentlich eher: 
Crosstalk).

Also, wenn ich mit meiner Annahme Recht habe, sollte es genügen, immer 
nach der "Aktivierung" einer jeden Spaltenleitung erst einen kleinen 
Moment zu warten, bevor du die Zeilenstati einliest. Der kleine Moment 
sollte so etwa in der Größenordnung einiger (sehr weniger) µs liegen. 
Vielleicht zum Testen erstmal 2 oder 3.

Wenn das nicht zum Erfolg führt, solltest du überprüfen, ob für alle 
Zeileneingänge wirklich die Pullups aktiviert sind (ich hatte keine 
Lust, deinen Code durchzusehen).
Gast #3870082
Lesenswert?

c-hater schrieb:
> Also, wenn ich mit meiner Annahme Recht habe, sollte es genügen, immer
> nach der "Aktivierung" einer jeden Spaltenleitung erst einen kleinen
> Moment zu warten, bevor du die Zeilenstati einliest. Der kleine Moment
> sollte so etwa in der Größenordnung einiger (sehr weniger) µs liegen.
> Vielleicht zum Testen erstmal 2 oder 3.

Habe nun ein Delay von 2 µs hinzugefügt und tadaa. Nun werden auch a und 
e richtig erkannt.
Danke schön
Gast #3870125
Lesenswert?

Taster schrieb:

> Habe nun ein Delay von 2 µs hinzugefügt und tadaa. Nun werden auch a und
> e richtig erkannt.

Gut. Nun solltest du noch versuchen, das Delay so weit wie möglich zu 
verkleinern. Die 2..3µs waren recht großzügig angegeben, wahrscheinlich 
genügt auch ein wesentlich kürzeres Delay im Bereich einiger 10 bis 
einiger 100 ns bereits, um den crosstalk ausreichend abebben zu lassen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren