Es gibt ja fertige 3*4 Tastenfelder und damit ist es viel bequemer, Werte einzugeben, als mit nur 2 Tasten (Up, Down). Dazu braucht man allerdings 6 Portpins und wenn man die nicht übrig hat, gehts auch ganz einfach mit nur einem ADC-Eingang: Zuerst muß man die verschiedenen Tasten in verschiedene Widerstandswerte umwandeln. Dazu legt man z.B. zwischen die Reihenanschlüsse jeweils 1k und man hat je nach Taste zu einer Spalte 0k, 1k, 2k, und 3k. Wenn man dann noch zwischen die Spalten je 4k legt, hat die nächte Spalte 4k, 5k, 6k, 7k, und die letzte 8k, 9k, 10k und 11k. Die Werte sind nicht kritisch, man kann statt der 4k z.B. 3,9k oder 4,7k nehmen. Wichtig ist eben nur, daß man für jede Taste einen anderen Wert erhält. Um nun den Widerstand mit dem ADC zu messen, braucht man noch einen 6. Widerstand vom ADC-Eingang gegen VCC, z.B. 10k. Das Tastenfeld mit den 5 Widerständen liegt zwischen GND und dem ADC-Eingang. Bei 12 Tasten reicht es aus, den ADC im 8Bit-Modus zu betreiben (ADLAR = 1). Nach dem ohmsche Gesetz erhält man nun für jede Taste einen bestimmten Spannungswert. Nun definiert man die Schwellwerte genau dazwischen, legt sie in einer Tabelle ab, die dann solange verglichen wird, bis die Taste gefunden wurde. Die Schwellwerte läßt man bequemer Weise den C-Compiler ausrechnen, man muß nur einmal die entsprechenden Widerstandswerte definieren. Damit es nun zu keinen Fehlerkennungen kommt, muß man nur noch entprellen, das geht am einfachsten mit meiner bewährten 4-fach Entprellung. Man darf aber immer nur eine Taste drücken, eine Erkennung von 2 Tasten gleichzeitig ist mit dieser Schaltung nicht möglich. Anbei ein Beispielcode mit dem ATTiny26. Peter
Gute Idee, für einfache "Gummitastenfelder" erscheinen mir die Widerstände aber etwas niederohmig. Vor ein paar Jahren habe ich das mal so ähnlich realisiert, aber nach einem Jahr in betrieb konnte man je nach Druck auf die Tasten verschiedene Werte eingeben... Gruß Jörg
Joerg Wolfram wrote: > Gute Idee, für einfache "Gummitastenfelder" erscheinen mir die > Widerstände aber etwas niederohmig. Ich hab diese Gummitastatur ausprobiert: http://www.conrad.de/goto.php?artikel=709840 Mehr als 50 Ohm konnte ich nicht erreichen. Da ist also noch reichlich Sicherheit. Man könnte noch die Schwellwerte auf 75% des Abstandes definieren:
1 | #define THRESHOLD(n) (u16)((ADCVAL(n)+3*ADCVAL(n+1))/4)
|
Peter
Ich glaube, das war ein ähnliches Teil, allerdings vor etwa 10 Jahren. Und es stand halt in ner Musikkneipe als Steuerung für die Lichtanlage. Die andren Pins des 80c535 waren alle durch LCD, Steuertasten etc belegt. Vielleicht lag es ja am ständigen Rauch, aber nach 1 jahr habe ich dann einen 89C2051 zusätzlich eingebaut, der die Matrix abgefragt und den Analogwert über Software-PWM ausgegeben hat. Damit erschöpfen sich allerdings auch meine Erfahrungen mit Gummitastaturen... Gruß Jörg
Faszinierend, ich wäre nie auf die Idee gekommen, Taster mit dem ADC abzufragen. Klasse!!
@Peter Dannegger Ein Bild sagt mehr als tausend Worte. Mach doch mal bitte nen Schaltplan zu deinem Program. Und wenn möglich gleich mit üblichen E12 Werten. Das erleichtert die Nachnutzung ungemein, vor allem für Anfänger. MfG Falk
Falk wrote: > Ein Bild sagt mehr als tausend Worte. Mach doch mal bitte nen Schaltplan > zu deinem Program. Und wenn möglich gleich mit üblichen E12 Werten. Das > erleichtert die Nachnutzung ungemein, vor allem für Anfänger. Siehe Anhang. Peter
Das gleiche Prinzip hat sogar schon vor Jahren bei der C-Controll Wetterstation benutzt (was nicht heißst, dass das prinzip schlecht ist)
@Peter Dannegger OK, so wird das schon viel klarer. Ich habs mal in Excel eingehackt. Uups, das wird teilweise schon recht eng. Gerademal 2 % Differenz zwischen den Tasten 9 und #. Da sollte man mit solchen Ausagen vorsichtig sein. Ein 8 Bit ADC hat gerade mal 0,5% Auflösung (also 4 mal besser als für den kleinsten Unterschied gebraucht wird, wobei man min. 1 LSB für Rauschen wegrechnen muss). Vielleicht doch besser den 10 Bit Modus verwenden? >Die Werte sind nicht kritisch, man kann statt der 4k z.B. 3,9k oder 4,7k >nehmen. Wichtig ist eben nur, daß man für jede Taste einen anderen Wert >erhält. Also besser direkt 1% Widerstände (E96) mit den vorgegebenen Werten nutzen. Weitere Stolperfalle. AREF! Wenn nun einige die interne Spannungsreferenz benutzen kann das daneben gehen, denn die ist (bei den AVRs) relativ ungenau. Dann besser VCC als Referenz benutzten, dann wird die Sache ratiometrisch und der absolute Wert von Aref ist egal. MfG Falk
@Falk, man muß natürlich wie in meinem Beispielcode VCC als Referenz nehmen. Ich benutze immer 1% Widerstände. Unsere Stückzahlen sind zu gering, als das sich eine doppelte Lagerhaltung rechnet. Bei 5% kann es zu Problemen kommen. Dann müßte man noch eine Kalibration vorsehen und die Schwellen im EEPROM speichern. Ich hatte auch erst überlegt, einen Kondensator zu Glättung vorzusehen, die ADC-Werte zappelten ganz schön. Aber nach der Entprellung gabs keinerlei Probleme mehr, da hab ich ihn weggelassen. Peter
in dem "mini Roboter" ASURO werden die 6 Taster auch so abgerufen. Schaltplan und Code kann man hier finden: http://www.arexx.com/arexx.php?cmd=goto&cparam=p_asuro_downloads jonas
Ich hab jetzt mal nachgeprüft, wie weit der Tastenwiderstand steigen darf. Dazu habe ich ein Poti in Reihe geschaltet. Bis 310 Ohm funktioniert die Erkennung einwandfrei. Da ist also noch reichlich Reserve. Hier die Tabelle mit den Schwellwerten aus dem Listing: 00000018 <THRESHOLDS>: 18: 87 81 7b 74 6c 63 59 4e 41 32 20 0b 00 00 Eine 10Bit-Messung würde nichts bringen, sie würde höchstens mehr zappeln. Peter
@Peter Dannegger >Eine 10Bit-Messung würde nichts bringen, sie würde höchstens mehr >zappeln. Einen 10..100nF C am ADC-Eingang würde ich aber nicht einsparen wollen. Der EMV sowie dem Datenblatt sollte man schon ein wenig Tribut zollen. Sonst rächt es sich ganz sicher im falschen Moment. MFG Falk
Ich habe eine kleine 4 Fach Relaisplatine gebaut. Der Microcontroller darauf kann für verschiedene Bedürfnisse angepasst werden. 2 Eingänge 4 Ausgänge http://www.ees-hartz.de/Timer/ http://www.ees-hartz.de/
Hallo, netter Ansatz ;-) Mal eine kurze Verständnisfrage: Wenn ich wissen will ob mehrere Tasten gleichzeitig gedrückt sind, muß ich doch nur verschiedene Widerstandswerte nehmen und dem ersten Taster auch einen spendieren ? Oh, sehe gerade die Matrix, dat geht so leider nicht :-P Also muß ich dann jedem Taster einen Widerstand spendieren ;-) Schade ;-) Werd's mal testen ;-)
hallo, nette idee. ich würde aber noch einen spannungsfolger spendieren da der adc der avr gerne eine niedrigere quellimpedanz sieht. gruss gerhard
sofern man den Pin nicht gerade als Ausgang, bzw Pullup konfiguriert hat er laut Datenblatt rund 100 MOhm, und das ist nicht niedrig. Muss aber sagen, wirklich geniale Idee. Gruß Roland
@roland: diesen wert hast du wohl brav aus dem datenblatt abgelesen? nur ein weises mann sagte mal foglendes: "ein datenblatt muß man lesen wie eine zeitung: nichts glauben was drin steht" daher guckst du mal im kapitel "Analog Input Circuitry" des atmega128 und da steht dann folgendes drin: "The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or less. If such a source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling time will depend on how long time the source needs to charge the S/H capacitor, with can vary widely. The user is recommended to only use low impedant sources with slowly varying signals, since this minimizes the required charge transfer to the S/H capacitor." alles klar auf der andrea doria? gruss gerhard
Ja, erwischt... Ein Spannungsfolger halte ich trotzdem für überflüssig, da die Tastaturmatrix in der angegeben Dimensionierung <= 10K Impedanz hat und der ADS sowieso nicht bis aufs letzte Bit ausgenutzt wird :-P Gruß Roland
Hallo Tastenfreunde! Habe mich auch mit dem Thema herumgeschlagen: Meine Widerstände liegen alle in Reihe, die Taste sitzt immer zwischen 2 Widerständen und Null. Durch die Widerstandswerte liegen die AD-Werte immer so, daß im ersten HEX Nibble der Tastencode(0-F) abgefragt werden kann. Durch Rechtsshift des ADWertes wird der niederwertige Teil (immer so ca.6-E)rausgeworfen, der Tastencode steht ohne allen if-else Aufwand zur Verfügung. Im Anhang die an handelsüblichen Reihen orientierten Werte. Man kann einfach die Reihe von hinten(Taste B) einkürzen auf die gewünschte Tastenzahl. Anhang: u/R Tabelle mit "Schaltplan" Grüße ulf.
ulf hausmann wrote: > der Tastencode steht ohne allen if-else Aufwand zur Verfügung. Na übertreib mal nicht. Die paar Byte-Vergleiche sind kein großer Aufwand, die verschwinden im Interrupt-Overhead. > Anhang: u/R Tabelle mit "Schaltplan" Wo ? Peter
Das mit dem Dateianhang wollte wohl nicht so richtig. Hoffentlich könnt Ihr mit dem Schaltplan was anfangen... Hier das Ganze als Text: Widerstandstabelle: Name Wert Uwid HEX Taste RV 4700 R0 0 0 0 0 R1 470 0,454545455 17 1 R2 470 0,833333333 2A 2 R3 470 1,153846154 3A 3 R4 470 1,428571429 48 4 R5 470 1,666666667 54 5 R6 1000 2,080745342 6A 6 R7 1000 2,403314917 7A 7 R8 1000 2,661691542 87 8 R9 1500 2,965367965 97 9 R10 2200 3,290909091 A7 A R11 4700 3,726287263 BE B R12 4700 3,98488121 CB C R13 10000 4,291101056 DA D R14 33000 4,644746788 EC E R15 33000 4,762985376 F2 F leer 5 FF Das schöne ist die Möglichkeit, mit 4xRechtsshift aus der 8bit Spannung gleich den fertigen Tastencode zu erhalten, ohne if und Bereichsabfragen. Schaltung: Die Taster gehen immer senkrecht nach 0V (Taste 0 nach R0, Taste 1 nach R1 usw.) +5V----- | RV(4700 Ohm) | ADPORT--------R0-R1-R2-R3......R15- | | | | T0 T1 T2 ........ T15 | | | | 0V--------------------------------- Ausgewertet wird immer die am weitesten links liegende Taste, weil diese den Kreis schließt. Fehler durch Zwischenwerte gibt es nicht. R0 ist nur hypothetisch, um die Lage der Taste rechts davon zu erklären. Gute Nacht! ulf.
@Ulf, wenn ich 9 Widerstände einsparen kann, ist mir das ein paar Codezeilen allemal Wert. Auch kann man Deine Schaltung für ein Tastenfeld nicht verwenden, da die Tasten ja schon als Matix fest verdrahtet sind. Peter
Na gut- die bei mir vorhandene Tastatur machte es einfach. Nur immer ein Widerstand zwischen die Tasten gepappt, 2 Leitungen dran, fertig. Es funktioniert prima, und niemand MUSS es nachbauen...
@Ulf, sollte keine Kritik sein, Deine Lösung funktioniert bestimmt auch supergut. Aber leider geht sie eben nicht mit den üblichen Matrixtastenfeldern. Und daß ich lieber ne Zeile Software nehme, wenn ich damit ein Bauteil einsparen kann, ist meine rein persönliche Einstellung. Deshalb mag ich es auch nicht, wenn jemand heutzutage noch alte 7-Segment Dekoder dranpappt. Peter
Hi, ich verwende in diesen Fällen ein SDA2008, hierbei handelt es sich um einen Tastaturdecoder für Fernbedienungen, der aber auch per Draht (2 Leitungen) verwendbar ist. Rollover und viele andere Features sind installiert, und das Lesen des Codes ist nicht viel arbeit. Grüsse Robert
@Robert, nen extra IC + Beschaltung wollte ich eigentlich nicht verschwenden. Und wenn, dann würde ich nen billigeren ATTiny2313 nehmen und den per SPI anschließen. Damit spart man sich das aufwendige Dekodieren des FB-Protokolls. Auch haben FB-ICs ne große Verzögerung und können keine schnellen Tastendrücke verarbeiten. Mit 5V als kleinste Betriebsspannung ist der SDA2008 auch nicht richtig MC-kompatibel (2,7...5,5V). Peter
Hallo Peter! Deine Lösung mit dem ADC erscheint mir die für mich Beste zu sein. Wenige Bauteile, günstig und relativ einfach zu realisieren. Wie soll ich das aber mit dem Interrupt zum Aufwachen der CPU machen? An welchen Stellen der Tastenmatrix soll die die Pins für den Pinchange-Interrupt anschließen, damit ich eindeutige Pegel bekomme?
Hallo, das Projekt finde ich sehr interessant. Leider konnte ich bisher nur Erfahrungen mit dem Atmega8 sammeln. Wenn ich den von Peter geposteten Code vom ATTiny26 im Atmega8 umsetzten möchte, was muss ich dazu beachten? Zum Beispiel verstehe ich nicht ganz wieso er PORTA so konfiguriert hat:
1 | PORTA = 0xFF; |
2 | DDRA = 0xFF; |
und welche Funktion das "Togglen" hat:
1 | PORTA ^= 1<<0; |
Wäre nett, wenn mir einer von euch helfen könnte...
Helmut Brammer schrieb: > Zum Beispiel verstehe ich nicht ganz wieso er PORTA so konfiguriert hat: > PORTA = 0xFF; > DDRA = 0xFF; Na irgendwo muß man doch die LEDs zur Ausgabe anschließen. Und da sie im STK500 low-aktiv sind, muß man sie erstmal ausschalten (auf high setzen). Helmut Brammer schrieb: > und welche Funktion das "Togglen" hat: > PORTA ^= 1<<0; Na man soll doch auf das Drücken eine Reaktion sehen können. Nur die Tasteneingabe, ohne das irgendwas passiert, ist doch sinnlos. http://www.dict.cc/englisch-deutsch/to+toggle.html Fang mal besser erst mit dem AVR-Tutorial hier an, wenn Du diese 3 Zeilen nicht verstehst. Peter
Ach so, mir war nicht klar, dass LEDs angeschlossen wurden... Dann ergibt alles einen Sinn! Kann man denn den Code für den ATTiny für den Atmega verwenden, natürlich unter der Voraussetzung, dass man die Definitionen anpasst?
Hallo, diese Tastenansteuerung über den ADC Port finde ich sehr geschickt. Würdet ihr diese Variante auch verwenden, wenn das Störpotential in der Umgebung recht hoch ist (Empfänger/Sender)? Mann könnte z.B. den Eingang des ADC noch mit 33nF abblocken. So ganz habe ich die Entprellroutine noch nicht verstanden, da ich nur in Bascom programmiere. Früher habe ich auch in Assembler programmiert, was aber schon etwas her ist. Könnt ihr mir vielleicht den Grundgedanken erklären, damit ich das Programm von Peter etwas leichter verstehen kann? Grüße Jörn
Hallo, ich möchte das Prinzip erweitern, so dass auch simultane Tastendrücke bzw. Schalter erkannt werden können. Ein Möglichkeit dies zu tun ist im Bild dargestellt, dabei müssen die Werte für R1-R4 unterschiedlich sein. Je nachdem welche Kombinationen von Schaltern gedrück sind, ergibt sich ein anderer Spannungswert am ADC Eingang. U = 1 / ([R1] + [R2] + [R3] + [R4] + 1) (dabei sind R1-R4 jeweil entweder 0 oder Rx) Mögliche Werte für R1-R4 (bezogen auf R0) sind zum Beispiel 1,2,4,8 Nun suche ich einen mathematischen Ansatz zum berechnen der optimalen Widerstandwerte. R1-R4 sollen so gewählt werden, dass der Unterschied zwischen zwei benachbarten Spannungswerten möglichst groß wird. Kann jemand mit einem Ansatz weiterhelfen? Danke!
es dürfen aber auch nicht zu große Differenzen vorhanden sein, da sonst die Auflösung des ADC nicht mehr ausreicht. Aber allgemein: widerstand 2^n kOhm für n=Tasternummer In deinem Beispiel z.B. (jeweils kOhm) 16 8 4 2 1 man müsste nur mal die Reserven bzw. die Abtsände ausrechnen, um zu überprüfen, ob genug Luft ist. Aber theoretisch kann man so jede Kombination ermitteln (aber praktisch wirds schwer ;))
uC schrieb: > Aber allgemein: widerstand 2^n kOhm für n=Tasternummer Das dacht ih intuitiv auch, aber es ist nicht die optimale Lösung!!! 1,2,4,8 Beispielsweise ergibt einen kleinsten Abstand von 0,004 aber 0.5 1 2 4 (einfach mal als Beispiel) ergibt einen kleinsten Abstand vo 0,007
Das beste Ergebnis, das ich erreichen konnte, ist 0.0194 mit folgenden Werten (R0-R4): 1 0.835 0.590 0.325 0.155 Mit E12-Werten bekomme ich das beste Ergebnis von 0.0179 mit (Werte jeweils in Ohm): R0: 1000 R1: 680 R2: 470 R3: 270 R4: 120 Beste Grüße, Torsten
Hallo, ich bin gerade auf der Suche nach genau so einer Lösung. (Ich bin Jahrgang'70 :-)) Meine Erfahrungen mit Mikrocontrollern liegen inzwischen viele Jahre zurück und mein Wissen ist ziemlich eingestaubt.) Die Schaltung die ich einsetzen möchte soll sowohl mit 12V als auch mit 24V funktionieren. Verwenden tue ich ein fertig aufgebautes Modul das leider keinen Referenzspannungsausgang hat. Meine Frage ist, ob es nicht möglich wäre obige Schaltung mit einer Z-Diode zu versehen - um die gleichen Spannungswerte bei unterschiedlichen Betriebsspannungen zu erreichen. Vielen Dank im Voraus. Gruß Michael
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.