Hallo zusammen, ich baue gerade eine IR-Fernsteuerung/Empfänger mit einem Zifferntastenfeld (12 Tasten) und zwei zusätzlichen Tasten, über die ich den Modus (z. B. Senden/Empfangen) einstellen möchte. Das heißt, ich würde gerne 14 Tasten entprellen. Kann ich dazu das Timer-Verfahren (nach Danninger) verwenden? http://www.mikrocontroller.net/articles/Entprellung Der Code ist eigentlich für 8 Tasten ausgelegt. Kann ich da einfach die 8-Bit-Variablen durch 16-Bit-Variablen austauschen und es läuft? Ich habe mir den Code angeschaut, aber nur halbwegs verstanden. Aber würde schätzen, dass es gehen sollte? Oder bin ich da auf dem Holzweg? VG Mike
Die Standard 12 Tastenfelder sind doch auch noch gemultiplext. ->http://www.fritzler-avr.de/HP/Librarys/tastenplex_his.php
Habe dieses hier ohne Multiplexing: http://www.conrad.de/ce/de/product/195561/Drucktastenfeld-1-x-12-Kontakt-Belastung-ca-30-mA-B-x-H-55-mm-x-86-mm
> Kann ich dazu das Timer-Verfahren (nach Danninger) verwenden?
Das ist normalerweise vollkommen überflüssig denn 14 Tasten würde man
normalerweise als 4 x 4 Matrix an 8 I/O Pins im Multiplexverfahren
abfragen und das entprellt automatisch.
Liest eigentlich niemand von euch Beispiele aus den Application Notes
der Hersteller der uC?
Natürlich kannst du, wenn es unbedingt sein muss, auch 14 Pins und
Abfrage nach Dannegger verwenden, einfach 2 bytes verwenden.
MaWin schrieb: > > Das ist normalerweise vollkommen überflüssig denn 14 Tasten würde man > normalerweise als 4 x 4 Matrix an 8 I/O Pins im Multiplexverfahren > abfragen und das entprellt automatisch. > > Liest eigentlich niemand von euch Beispiele aus den Application Notes > der Hersteller der uC? > > Natürlich kannst du, wenn es unbedingt sein muss, auch 14 Pins und > Abfrage nach Dannegger verwenden, einfach 2 bytes verwenden. Ok, nächstes Mal mach ich's so MaWin schrieb: > Liest eigentlich niemand von euch Beispiele aus den Application Notes > der Hersteller der uC? Kenn ich ehrlich gesagt gar nicht... wo finde ich diese Notes? > Natürlich kannst du, wenn es unbedingt sein muss, auch 14 Pins und > Abfrage nach Dannegger verwenden, einfach 2 bytes verwenden Danke! Sollte ich besser eine uint_16 verwenden oder zwei unit_8? Oder egal?
> wo finde ich diese Notes?
Auf der WebSite des Herstellers deines uC.
MaWin schrieb: > Natürlich kannst du, wenn es unbedingt sein muss, auch 14 Pins und > > Abfrage nach Dannegger verwenden, einfach 2 bytes verwenden. Ich hab das jetzt implementiert und getestet. Code anbei. Es hängen 8 Tasten an PORTB und 3 Tasten an PORTE (um die übrigen Tasten an PORTB kümmere ich mich später). Folgendes Problem: Für die Tasten an PORTB funktioniert das Ganze 100% zuverlässig. Für die Tasten an PORTE nur ca. 90-95% - d. h. die Tasten an PORTE muss man ab und zu zwei-/dreimal drücken, bis sie "erkannt" bzw. entprellt zurück geliefert werden. Ich hab zum Test mal den Vorteiler von 1024 auf 256 geändert - das scheint die "Zuverlässigkeit" etwas zu erhöhen, aber auch nicht auf 100% zu bringen. Hat jemand eine Idee? Ist der Ansatz im Prinzip ok? Und müsste die Frequenz (standardmäßig 10ms) bei Nutzung von 2 Bytes/Ports eher nach oben oder nach unten justiert werden (ISR dauert jetzt ja ca. doppelt so lange).
PS: Hatte das nicht explizit erwähnt: ich habe im Prinzip einfach den "Standard"-Code dupliziert und jeweils ein Suffix _A (für PORTA) und _E (für PORTE) an die Variablen dran gehängt.
Sorry, noch ne Korrektur: ich behandele die Tasten an PORTA und PORTE, nicht an PORTB (Schreibfehler oben) Tasten an PORTA --> 100% zuverlässig Tasten an PORTE --> ca. 95% zuverlässig (teilweise mehrfaches Drücken notwendig)
Kann es vielleicht ein Problem sein, dass beim ATMega162 von PORTE nur 3 Bits genutzt werden (und die Routine 8 Bits "einbezieht")? Tappe ziemlich im Dunkeln...
Hat sich erledigt - war ein Copy&Paste Fehler :-( i_E = key_state_A ^ ~PINE --> muss natürlich i_E = key_state_E ^ ~PINE sein. Erstaunlich, dass es trotzdem zu 90% ging ;-)
> Hat jemand eine Idee? > i_A = key_state_A ^ ~PINA; // key changed ? > i_E = key_state_A ^ ~PINE; // key changed ? ^ Das soll doch wohl ein E sein.
Nachdem das jetzt geht, gibt es leider ein neues Problemchen: Ich habe noch 2 Tasten an PC5 und PC6 hängen. An PC0 bis PC3 hängen Ausgänge (Multiplexing eines LED-Displays). Ich möchte nun die Entprell-Routine erweitern, wobei nur PC5 und PC6 "berücksichtigt" werden sollen. Meine erste Idee war so etwas in der Art: i_C = key_state_C ^ ~(PINC & 0b01100000); Aber geht leider nicht - bei Tastendruck passiert nichts, d. h. Änderung Zustand wird wohl nicht erkannt. Was wäre der richtige Ansatz, um die Prüfung der Zustandsänderung auf die Tasten an PC5 und PC6 einzuschränken (wenn ich trotzdem die gleiche Routine verwenden möchte)? Besten Dank.
Anbei mal noch der vollständige Code. Bei Programmstart bzw. nach Reset liefert die Funktion Key_Panel_getKey() eine 255 zurück - danach dann nur noch die Tastendrücke an PORTA und PORTE. Die beiden Tasten an PC5 und PC6 bewirken nichts. Also meine Vermutung ist, dass ich die Wechselwirkungen mit den anderen Pins an PORTC nicht richtig "ausgeblendet" bekomme??
Mike schrieb: > Also meine Vermutung ist, dass ich die Wechselwirkungen > mit den anderen Pins an PORTC nicht richtig "ausgeblendet" bekomme?? Richtig! Du benutzt ja nicht die Funktion get_key_press(), diese wertet nur das gewünschte Bit aus. Dein Switch() ist untauglich, denn es wertet immer 8 Bits zusammen aus. Das Verdreifachen des Codes ist unübersichtlich. Ändere einfach alles auf uint16_t und fasse die Tasten einmalig zu 16Bit zusammen.
1 | uint16_t i; |
2 | |
3 | i = PINA | (((PINE & 0b00000111) | (PINC & 0b01100000)) << 8); |
4 | i = key_state ^ ~i; |
5 | // usw.
|
Mike schrieb: > Die beiden Tasten an PC5 und PC6 > bewirken nichts JTAG noch aktiviert? http://www.mikrocontroller.net/articles/AVR_Checkliste#Fuses_richtig_gesetzt.3F
Peter Dannegger schrieb: > Du benutzt ja nicht die Funktion get_key_press(), diese wertet nur das > > gewünschte Bit aus. > > Dein Switch() ist untauglich, denn es wertet immer 8 Bits zusammen aus. ja, hatte irgendwie versucht, durch das (PINC & 0b01100000) Änderungen an Pins <> PC5 und PC6 zu "neutralisieren" - so dass key_press_C null bleibt, wenn sich ein anderer Pin ändert. Wenn ich get_key_press() verwende (hatte ich anfangs), müsste ich die Funktion mit entsprechender Maske pro Taste einzeln aufrufen, oder? Ich fand das bei 14 Tasten etwas "umständlicher", aber wenn das das Problem löst, gehe ich natürlich diesen Weg. Das Grundproblem ist wohl, dass ich (= Anfänger) den Code noch nicht 100% verstehe - ist ja doch sehr "sophisticated" Peter Dannegger schrieb: > Das Verdreifachen des Codes ist unübersichtlich. Ändere einfach alles > > auf uint16_t und fasse die Tasten einmalig zu 16Bit zusammen. Ok, werde ich machen. Zumal ich die Tasten insgesamt über 4 Ports verteilt sind (ok, erst denken, dann löten). Nur für's Verständnis: Diese Änderung ist eher zwecks Übersichtlichkeit - die Lösung des Problems würde aber in der bitweisen Auswertung in get_key_press() liegen, oder? J.-u. G. schrieb: > JTAG noch aktiviert? > > http://www.mikrocontroller.net/articles/AVR_Checkl... Danke für den Hinweis. Das muss ich auch mal kontrollieren. Werde auch zunächst nochmal eine grundsätzlichen Test machen, ob die Tasten überhaupt "funktionieren" Erstmal danke an Euch!
Peter Dannegger schrieb: > Dein Switch() ist untauglich, denn es wertet immer 8 Bits zusammen aus. Hmmm, warum eigentlich? switch (key_press_E) { case 1: result = 9; break; case 2: result = 6; break; case 4: result = 3; break; } Ich werte doch über {1,2,4,8,16,32,64,128} auch immer genau ein Bit aus, oder? Zumindest funktioniert es für die Ports A und E... Wenn eine Taste gedrückt wurde, ist doch immer das entsprechende Bit gesetzt, d. h. die Variable hat einen Wert 2 hoch Bitposition - grübel Ich werde es heute Abend nochmal testen, aber der Vorschlag i = PINA | (((PINE & 0b00000111) | (PINC & 0b01100000)) << 8); nutzt ja eigentlich die gleiche Methode zum "Neutralisieren" der nicht relevanten Pins...
Mike schrieb: > Ich werte doch über {1,2,4,8,16,32,64,128} auch immer genau ein Bit aus, > oder? Und du hast dann im case auch alle Kombinationen, die sich durch gleichzeitiges Drücken mehrerer Tasten ergeben? Gratuliere, das dürfte dann der switch-case des Jahrhunderts sein. Mach es einfach nur richtig. Dann kommt der Rest von alleine.
> Danke für den Hinweis. Das muss ich auch mal kontrollieren. Werde > auch zunächst nochmal eine grundsätzlichen Test machen, ob die > Tasten überhaupt "funktionieren" Das wäre allerdings eine extrem gute Idee. EIgentlich gehen die meisten davon aus, dass du diesen Test schon längst gemacht hast! Immer diese 'Oooch das wird schon so passen' Anfälle. Wenn du wüsstest, wie oft sich hinten nach, manchmal nach Stunden, rausstellt, dass die primtivsten Vortests nicht gemacht wurden und genau die fehlschlagen, das Problem aber klar und deutlich aufgezeigt hätten.
Karl Heinz Buchegger schrieb: > gleichzeitiges Drücken mehrerer Tasten so weit bin ich noch nicht - ich drücke nur eine Taste gleichzeitig Karl Heinz Buchegger schrieb: > Mach es einfach nur richtig. Dann kommt der Rest von alleine. Ein kleiner Hinweis, was "richtig" ist, wäre hilfreich ;-) Prüfung bzgl. JTAG ist sicherlich notwendig. Aber die Nutzung der Orginalfunktion get_key_press() löst imho nicht das Problem. Diese Funktion würde ich ja auch mit einer Bitmaske aufrufen, um eine EINZELNE Taste zu prüfen (?)
Solche Tastenfelder ließt man am besten mit nem ADC aus, indem quasi einen Spannungsteiler baut. Braucht dann erffektiv einen Pin. Entprellung ist etwas aufwändig, da man das Drücken, Einpendeln und Loslassen per Messung über n paar Werte erfassen muss, wenn man das hat ist es die pinsparendste Variante die es gibt. Vor alles ist sie beliebig erweiterbar, da quasi nur die LUT erweitert werden muss.
Karl Heinz Buchegger schrieb: > primtivsten Vortests nicht gemacht Ich hab zumindest die Leitungen etc. getestet, passt alles. Die Option über JTAG kannte ich nicht - muss ich mich jetzt entschuldigen? ;-) Dass das Problem an der nicht verwendeten get_key_press() (bzw. andere Version) oder der Aufteilung auf mehrere uint8 statt eine uint16 liegt, bezweifele ich ehrlich gesagt
Ingo schrieb: > Solche Tastenfelder ließt man am besten mit nem ADC aus, indem quasi > > einen Spannungsteiler baut. Braucht dann erffektiv einen Pin. > > Entprellung ist etwas aufwändig, da man das Drücken, Einpendeln und > > Loslassen per Messung über n paar Werte erfassen muss, wenn man das hat > > ist es die pinsparendste Variante die es gibt. Vor alles ist sie > > beliebig erweiterbar, da quasi nur die LUT erweitert werden muss. Danke für den Tip - werde ich beim nächsten Mal entsprechend anders umsetzen - dieses Mal hab ich schon so viel Aufwand in die Hardware gesteckt, dass ich jetzt irgendwie auf diesem Weg zum Ziel kommen möchte. Trotzdem danke.
J.-u. G. schrieb: > JTAG noch aktiviert? Das war das Problem - funktioniert jetzt einwandfrei - danke!!
MaWin schrieb: > Das ist normalerweise vollkommen überflüssig denn 14 Tasten würde man > normalerweise als 4 x 4 Matrix an 8 I/O Pins im Multiplexverfahren > abfragen und das entprellt automatisch. Natürlich nur, wenn das Pollingintervall groß genug ist. Das ist nicht zwingend gegeben, z.B. nicht bei der häufig anzutreffenden Pinsparlösung, das Muxen zwischen Displays und Tasten zu "sharen". Für das Display strebt man ja Muxraten von wenigstens ca. 60 Hz an. 16ms können bei stark prellenden Tastern aber schon deutlich zu knapp sein als Zeitkonstante zur Entprellung. Das ist natürlich kein Problem, man fragt dann einfach nur in jedem zweiten Muxintervall die Tasten ab. Aber man muß halt dran denken, dies auch tatsächlich zu tun. Und dabei sind gerade falsche Axiome wie "Tasterabfrage im Mux-Verfahren debounced automatisch" nicht gerade hilfreich...
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.