Forum: Mikrocontroller und Digitale Elektronik Attiny 2313 - mehrfache Abfrage Taster


von Klaas (Gast)


Lesenswert?

Hallo
möchte mit einem Attiny 2313 5 Taster abtasten und über einen Bus 
weiterleiten möchte. Im Grund ist es kein Problem mit einem Taster 
jeweils eine bestimmte LED zu schalten. Was passiert aber wenn ich 2 
oder noch mehr Taster gleichzeitig drücke. Wie kann ich die Taster 
vernünftig auswerten und auf doppelte Taster reagieren?
LG Klaas

von Ingo L. (corrtexx)


Lesenswert?

Schilder doch bitte mal genau, was du nicht verstehst. Es ist doch egal 
ob du einen oder n Taster abfragst.

von SeppJosef (Gast)


Lesenswert?

Wie sind die Taster am Controller beschaltet?
Sind die Taster jeweils mit einem Port verbunden, oder sind die Taster 
in einer Matrix verschalten.
Aber Grundsätzlich kannst Du einen bestimmten Wert der gedrückten Taster 
erzeugen. Egal ob nur ein Taster oder mehrere gedrückt werden.

von Joachim B. (jar)


Lesenswert?

https://www.mikrocontroller.net/articles/Entprellung

suche Dannegger
Beitrag "Entprellen für Anfänger"

klappt auch in einer ISR (10ms Timer) mit I2C PCF8574(a)

in der ISR wird die Taste (oder die Tasten) entprellt und steht dann in 
der Loop zur Verfügung bis man "bereit" ist diese zu verarbeiten.

: Bearbeitet durch User
von Georg (Gast)


Lesenswert?

Klaas schrieb:
> Was passiert aber wenn ich 2
> oder noch mehr Taster gleichzeitig drücke

Es passiert das was du programmiert hast bzw. programmieren willst. 
Also: was soll denn passieren, wenn 2 Taster gedrückt werden? 2 LEDs 
leuchten? Garkeine LED (schwierig wegen Gleichzeitigkeit)? Das Gerät 
explodiert?

Georg

von Peter D. (peda)


Lesenswert?

Klaas schrieb:
> möchte mit einem Attiny 2313 5 Taster abtasten und über einen Bus
> weiterleiten möchte.

Nun, der ATtiny2313 hat bis zu 18 IO-Pins. Da sollte es doch kein 
Problem sein, jedem der 5 Taster einen eigenen Eingang zu spendieren.

Zum Entprellen und zur Flankenerkennung kann man Routinen nehmen, die 
ganze Ports parallel verarbeiten oder ruft 5 Routinen für je einen Pin 
hinteinander auf. Diese Routinen dürfen natürlich nicht blockierend 
sein.

Was für ein Bus soll das sein und welches Protokoll soll darauf laufen?
Busse verkomplizieren solche einfachen Aufgaben allerdings erheblich. 
Sie sollte man daher nur verwenden, wenn es dafür handfeste Gründe gibt, 
z.B. sehr lange Leitungen mit wenigen Adern.

von Sebastian S. (amateur)


Lesenswert?

Das ganze steht und fällt mit der Anzahl an freien Eingängen.

Bist Du gezwungen eine Matrix zu verwenden, wird es etwas komplizierter, 
wegen der Mehrfachbetätigung.

Hast Du aber für jeden Taster einen Eingang frei so gilt:
Einen Taster abfragen = n Taster abfragen.

von Klaas (Gast)


Lesenswert?

Am Attiny 2313 habe ich 5 Taster zur Eingabe. Dabei ist die Betätigung 
von 1 oder mehr (max 5) Taster möglich. Einzeln kann ich sie ohne 
Problem abfragen und mir an 5 LEDs auch anzeigen lasse welcher Taster 
betätigt wurde. Wenn ich eine Übertragung mit einem Bus machen will, 
möchte ich wissen welcher Taster gedrückt wurde.
Beispiel:
Taster 1 - LED 1 - Bus - 1
Taster 2 - LED 2 - Bus - 2
Taster 1 und 2 - LED 1+2 - Bus ?
Taster 1 und 2 und 3 - LED 1 und 2 und 3 - Bus ?
usw.
Wie kann ich genau detektieren welcher Taster einzeln oder zusammen 
gedrückt wird und die genaue Übertragung über den Bus vornehmen?
Da der Prozessor noch andere Aufgaben erledigen soll kann ich keinen PCF 
nehmen.
Das "Entprellen für Anfänger" nutze ich bereits in andere Aufgaben. Kann 
ich damit auch im Bus übertragen welcher Taster oder Mehrzahl gedrückt 
wurde?
Die Taster sind an 5 verschiedenen Eingängen mit einem Widerstand nach 
Vcc (+). Taster legt die Eingänge auf GND

von Klaas (Gast)


Lesenswert?

Als Bus soll der I2C Bus verwendet werden. Taster direkt an jeweils ein 
PIN keine Matrix

von Georg G. (df2au)


Lesenswert?

Klaas schrieb:
> Taster 1 und 2 - LED 1+2 - Bus ?

Die Taster werden bestimmt nicht genau zur gleichen Zeit aktiv. Also 
erscheint auf dem Bus zuerst der eine Taster und dann der zweite Taster.

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

Hallo

Deklariere doch ein BITFELD, schreib da die Daten (die 5 Taster) rein 
(z.B Taster gedrueckt = "1") und schicke das Bitfeld mittels I2C an den 
Empfänger, dort demaskierst Du das empfangene Bitfeld "und gut is"

von Osszilierer (Gast)


Lesenswert?

wenn ich dich richtig verstehe ist dein Problem doch eigentlich schön 
längst gelöst.
Du liest das Port ein, jeder Taster ist ein anderes Bit im Port und 
damit weisst du welche Taste gedrückt ist, wenn du das Port-Byte 
überträgst. Du kannst natürchlich auch einfach jedem Taster ein Bit 
zuweisen und dann das Byte übertragen

also
Taster 1 -> Bit 0
Taster 2 -> Bit 1
Taster 3 -> Bit 2
Taster 4 -> Bit 3
Taster 5 -> Bit 4

diese Byte übertragen und auf der anderen Seite auswerten

von Peter D. (peda)


Lesenswert?

Martin schrieb:
> Deklariere doch ein BITFELD

Oft will man aber auch auf die Betätigung reagieren und nicht nur auf 
den Zustand.
Dann schicke 2 Bytes, eins für Flanke erkannt und eins für den neuen 
Zustand.

von Klaas (Gast)


Lesenswert?

Habe mal die Möglichkeiten zusammen gezählt.

-12
-13
-14
-15
-123
-124
-125
-134
-135
-23
-24
-25
-234
-235
-245
-34
-35
-345
-45

Es können auch zwei und mehr Tasten gleichzeitig gedrückt werden. Bei 5 
Tasten dürften sich diese Möglichkeiten ergeben. Wenn ich diese über den 
Bus übertrage kann ich sie im Master einer Funktion zuweisen. Sehe 
gerade das noch Zahlen fehlen

Osszilierer schrieb:
> also
> Taster 1 -> Bit 0
> Taster 2 -> Bit 1
> Taster 3 -> Bit 2
> Taster 4 -> Bit 3
> Taster 5 -> Bit 4
>
> diese Byte übertragen und auf der anderen Seite auswerten

ist wahrscheinlich fast das selbe. Muss mir noch was überlegen ob das so 
eine Matrix ist

von Martin (Gast)


Lesenswert?

Ja, korrekt, da fehlen noch einige Kombinationen ..

Ich habe noch nicht ganz verstanden, was Du machen willst - nur die 
Zustände der Taster einlesen /auswerten, wenn sie gedrückt wurden (nach 
dem Prellen) oder willst Du auch die Zustandsänderungen mitlesen?

Eigentlich interessant ist doch nur der Zustand "in Ruhe", d.h. wenn sie 
betätigt/nicht betätigt wurden, oder reagiert Deine SW auch auf 
Zustandsänderungen?

von Klaas (Gast)


Lesenswert?

Martin schrieb:
> Deklariere doch ein BITFELD, schreib da die Daten (die 5 Taster) rein
> (z.B Taster gedrueckt = "1") und schicke das Bitfeld mittels I2C an den
> Empfänger, dort demaskierst Du das empfangene Bitfeld "und gut is

Das mit dem Bitfeld klingt gut. Habe noch die fehlenden Zahlen 
aufgeschrieben. Das ergibt nur mit der Zahl (Taster) 1 16 Möglichkeiten.
Gibt es für eine solche Matrix eine Berechnung mit Reduzierung der 
Möglichkeiten ?

von Klaas (Gast)


Lesenswert?

Nutze ich z.B. die Taster als Bedienfeld mit hoch runter links rechts 
schnell langsam könnte ich runter und schnell gleichzeitig betätigen, 
dadurch könnte der Cursor bewegt werden.
Möchte nur die Zustände der Taster auslesen. Eine Zustandsänderung 
scheint nicht nötig zu sein, Entprellung auf jeden Fall.

von Joachim B. (jar)


Lesenswert?

Klaas schrieb:
> Als Bus soll der I2C Bus verwendet werden. Taster direkt an jeweils ein
> PIN keine Matrix

habe ich doch schon beantwortet:
Beitrag "Re: Attiny 2313 - mehrfache Abfrage Taster"

lesen und verstehen musst du, oder brauchst du die Auflösung?

von Winne Z. (rugbywinne)


Lesenswert?

Also bei 5 Tasten ergeben sich 2^5 Möglichkeiten also 32.
Ist ne 5-bit -Binäzahl die du auswerten kannst.

Für jede Tastenkombination gibt es nur einen Wert.
Dieser Wert gilt nur für die eine Tastenkombination.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Winne Z. schrieb:
> Also bei 5 Tasten ergeben sich 2^5 Möglichkeiten als 32.
> Ist ne 5-bit -Binäzahl die du auswerten kannst.

und am I2C 8574 sogar auf EINEM Port da muss man nicht mal Bits 
schieben.
Die gedrückten Tasten liegen also alle in einem Byte, das ist doch easy.

Aber auch bei Tasten auf verschiedenen Ports wäre das möglich ein 
Hiflsbyte definieren, die beteiligten Ports abzufragen, die Bits schön 
in das Hilfsbyte passend verschieben und fertig.

von Martin (Gast)


Lesenswert?

Im Prinzip interessant sind doch nur logische Eingaben und nicht solche, 
wo alle 5 Taster betätigt sind

von Osszilierer (Gast)


Lesenswert?

löse dich einfach mal von der dezimalen Welt, der Prozessor versteht 
hexadezimal!!

Bit    7 6 5 4 3 2 1 0  = 1 Byte
Taste  x x x 5 4 3 2 1

jetzt ist einfach in dem Byte das entsprechende Bit für den 
entsprechenden Taster gesetzt und du überträgst das Byte und schaust auf 
der anderen eite welches Bit gesetzt ist und du weisst welche Taste 
gedrückt ist

Beispiel:
Taste     x x x 5 4 3 2 1
gedrückt  x x x 1 0 0 0 1 = 11hex
gedrückt  x x x 1 1 0 0 1 = 19hex

wenn du das Byte sendest filterst du auf der Empfängerseite einfach die 
Bits aus

von Klaas (Gast)


Lesenswert?

Osszilierer schrieb:
> Beispiel:
> Taste     x x x 5 4 3 2 1
> gedrückt  x x x 1 0 0 0 1 = 11hex
> gedrückt  x x x 1 1 0 0 1 = 19hex

Das gefällt mir sehr gut. Ist einfach. Hatte gar nicht an hex dabei 
gedacht, einfach und gut.
Bleibt noch die Frage wie ich es am besten in C umsetzen kann.

von Klaas (Gast)


Lesenswert?

Habe mir die Entprellung von Peter angesehen. Muss mal versuchen beides 
zu kombienieren.

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Klaas

Anbei die logische (!) Kombination incl der Hex-Werte - alle anderen 
Kombinationen sind obsolet, da Unsinn

von Martin (Gast)


Lesenswert?

Hallo Klaas

Hinterleg' die im *.pdf genannten HEX-Werte mittels ARRAY[x][y] im SRAM 
(PROGMEM) => x-Wert wäre ARRAY-Wert und y-Wert die auszuführende Aktion

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Klaas

zu meiner Tabelle - nicht ausgefüllte Zellen = nicht betätigter Taster

von Martin (Gast)


Lesenswert?

Ist ja klar - wenn Taster "AUF" UND Taster "AB" gleichzeitigt betätigt 
werden, erfolgt KEINE Reaktion, man könnte aber natürlich dennoch dann 
einen Hinweis machen, dass Taster falsch betätigt wurden - 'ne 
Möglichlichkeit, den User auf eine Falscheingabe hinzuweisen...

von Georg (Gast)


Lesenswert?

Martin schrieb:
> Ist ja klar - wenn Taster "AUF" UND Taster "AB" gleichzeitigt betätigt
> werden

Nur werden sie niemals gleichzeitig betätigt, nicht für einen Prozessor, 
der in Millisek oder weniger reagiert. Es gibt verschiedene 
Lösungsmöglichkeiten, z.B. eine Zeitverzögerung, innerhalb der kein 
zweiter Taster betätigt werden darf, sonst keine Reaktion - aber so 
etwas dürfte den TO überfordern.

Georg

von Joachim B. (jar)


Lesenswert?

Klaas schrieb:
> Habe mir die Entprellung von Peter angesehen. Muss mal versuchen beides
> zu kombienieren.

wo klemmts denn?
1
// in der ISR
2
// ein paar defines
3
4
 #if defined(__AVR_ATmega328P__)
5
#define COUNTER1
6
7
#ifdef COUNTER1
8
  #define   TIMSKx              TIMSK1
9
  #define   OCIExA              OCIE1A
10
  #define   TIMERx_COMPA_vect   TIMER1_COMPA_vect  // ATmega
11
  #define   TCCRxA              TCCR1A
12
  #define   COMxA0              COM1A0
13
  #define   OCRxA               OCR1A
14
  #define   TCCRxB              TCCR1B
15
  #define   WGMx2               WGM12
16
  #define   CSx0                CS10
17
#endif
18
19
20
ISR(TIMERx_COMPA_vect)
21
{
22
#ifdef TASTER
23
      if( i2c_test_flags&(1<<I2C_TASTATUR_8574) || i2c_test_flags&(1<<I2C_TASTATUR_8574A) ) {
24
        //if(!_i2c_busy) {
25
          int _address, _data, _error; //  Wire.begin();
26
          if(i2c_test_flags&(1<<I2C_TASTATUR_8574A)) _address = 0x38;
27
          if(i2c_test_flags&(1<<I2C_TASTATUR_8574)) _address = 0x20;
28
          Wire.beginTransmission(_address); Wire.requestFrom(_address, 1);
29
          _data = readIIC();
30
          _error = Wire.endTransmission();
31
          if(!_error) ii = key_state ^ ~_data;
32
          ii &= ALL_KEYS;
33
          ct0 = ~( ct0 & ii );                             // reset or count ct0
34
          ct1 = ct0 ^ (ct1 & ii);                          // reset or count ct1
35
          ii &= ct0 & ct1;                                 // count until roll over ?
36
          key_state ^= ii;                                 // then toggle debounced state
37
          key_press |= key_state & ii;                     // 0->1: key press detect
38
               
39
          if( (key_state & REPEAT_MASK) == 0 )            // check repeat function
40
            rpt = REPEAT_START;                          // start delay
41
          if( --rpt == 0 ) {
42
            rpt = REPEAT_NEXT;                            // repeat delay
43
            key_rpt |= key_state & REPEAT_MASK;
44
          }
45
        //} // if(!_i2c_busy)
46
      } // if(_i2c_key)
47
      else { // !if( i2c_key
48
        ii = key_state ^ ~PIND;
49
        ii &= ALL_KEYS;
50
        ct0 = ~( ct0 & ii );                             // reset or count ct0
51
        ct1 = ct0 ^ (ct1 & ii);                          // reset or count ct1
52
        ii &= ct0 & ct1;                                 // count until roll over ?
53
        key_state ^= ii;                                 // then toggle debounced state
54
        key_press |= key_state & ii;                     // 0->1: key press detect
55
               
56
        if( (key_state & REPEAT_MASK) == 0 )            // check repeat function
57
          rpt = REPEAT_START;                          // start delay
58
        if( --rpt == 0 ) {
59
          rpt = REPEAT_NEXT;                            // repeat delay
60
          key_rpt |= key_state & REPEAT_MASK;
61
        } // if( --rpt == 0 )
62
      } // else !if( i2c_key
63
#endif
64
65
66
unsigned char res_key=0;
67
void loop() { 
68
  res_key=get_key_press( ALL_KEYS );
69
  if(res_key) {
70
    switch(res_key) {
71
      case (1<<HELLUP):
72
        backlight_p();
73
        break;
74
      case (1<<HELLDOWN):
75
        backlight_m();
76
        break;
77
      default:
78
        break;
79
    }
80
    res_key=0;      
81
  }

istz zwar nur ein Gerippe, aber vielleicht hilft dir das schon.

lese den Artikel und versuche es nachzuvollziehen, hilft dir mehr als 
fertiger Code

meines ist zwar nurn arduino lastig, aber das klappt auch gut mit der 
fleury LIB in A-Studio
http://homepage.hispeed.ch/peterfleury/avr-software.html

von Martin (Gast)


Lesenswert?

Georg schrieb:
> Martin schrieb:
>> Ist ja klar - wenn Taster "AUF" UND Taster "AB" gleichzeitigt betätigt
>> werden
>
> Nur werden sie niemals gleichzeitig betätigt, nicht für einen Prozessor,
> der in Millisek oder weniger reagiert. Es gibt verschiedene
> Lösungsmöglichkeiten, z.B. eine Zeitverzögerung, innerhalb der kein
> zweiter Taster betätigt werden darf, sonst keine Reaktion - aber so
> etwas dürfte den TO überfordern.
>
> Georg

Bin bei meiner Liste davon ausgegangen, dass der TO mit dem Entprellen 
von Tastern vertraut ist, gemäß einem Eintrag weiter oben will er nur 
mit "statischen" Signalen arbeiten..

soweit mir bekannt, hat er schon mit der DEBOUNCE FKT von P. Danegger 
gearbeitet - somit dürfte ihm das klar sein...

von Georg (Gast)


Lesenswert?

Martin schrieb:
> dass der TO mit dem Entprellen
> von Tastern vertraut ist

Vielleicht, vielleicht nicht, aber das ändert ja nichts daran, dass 
zuerst ein Taster kommt und dann der zweite (Der dem ersten womöglich 
widerspricht).

Georg

von Martin (Gast)


Lesenswert?

Georg schrieb:
> Martin schrieb:
>> dass der TO mit dem Entprellen
>> von Tastern vertraut ist
>
> Vielleicht, vielleicht nicht, aber das ändert ja nichts daran, dass
> zuerst ein Taster kommt und dann der zweite (Der dem ersten womöglich
> widerspricht).
>
> Georg

Ja und???? Dann muss das die SW abfangen, was sonst!

von Georg (Gast)


Lesenswert?

Martin schrieb:
> Ja und???? Dann muss das die SW abfangen, was sonst!

So klar scheint das dem TO nicht zu sein:

Klaas schrieb:
> Was passiert aber wenn ich 2
> oder noch mehr Taster gleichzeitig drücke. Wie kann ich die Taster
> vernünftig auswerten und auf doppelte Taster reagieren?

Georg

von Joachim B. (jar)


Lesenswert?

Klaas schrieb:
> Was passiert aber wenn ich 2
> oder noch mehr Taster gleichzeitig drücke.

dann werden 2 oder mehr passende Bits in der Entprellroutine gesetzt

Deswegen den Artikel durcharbeiten, verstehen und anwenden.

von Martin (Gast)


Lesenswert?

Taster einlesen, per Entprellroutine (oder mittels Timer) ausmaskieren, 
dieses gültige Byte (muss ja letztendlich eines sein) mit meiner look-up 
Tabelle (siehe *.pdf weiter oben) vergleichen (mittels Schleife) und 
entsprechend reagieren - das ist kein Hexenwerk!

von Klaas (Gast)


Lesenswert?

Hallo Jooachim
dein Beispiel verwendet die Entprellung von Peter mit Timer. Diese 
verwende ich auch in andere Programmen. Ein paar Sachen sind etwas 
anderes. Werde es mal vergleichen. Ansonsten läuft das Programm super. 
Ziemlich weit oben ist auch eine Entprellung von Peter angegeben. Ist 
sehr einfach. Mit dieser habe ich nie gearbeitet. Mal ansehen, würde ja 
voll reichen. Das mit dem PDF finde ich super, ist so einfach zu machen.
Danke für eure Hilfe.
LG Klaas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.