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
Schilder doch bitte mal genau, was du nicht verstehst. Es ist doch egal ob du einen oder n Taster abfragst.
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.
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
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
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.
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.
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
Als Bus soll der I2C Bus verwendet werden. Taster direkt an jeweils ein PIN keine Matrix
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
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"
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
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.
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
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?
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 ?
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.
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?
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
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.
Im Prinzip interessant sind doch nur logische Eingaben und nicht solche, wo alle 5 Taster betätigt sind
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
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.
Habe mir die Entprellung von Peter angesehen. Muss mal versuchen beides zu kombienieren.
Hallo Klaas Anbei die logische (!) Kombination incl der Hex-Werte - alle anderen Kombinationen sind obsolet, da Unsinn
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
Hallo Klaas zu meiner Tabelle - nicht ausgefüllte Zellen = nicht betätigter Taster
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...
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
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
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...
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
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!
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
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.
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!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.