Forum: Projekte & Code Tastenmatrix auslesen über nur 2 Leitungen


von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

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

von Joerg W. (joergwolfram)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Joerg W. (joergwolfram)


Lesenswert?

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

von Jupp (Gast)


Lesenswert?

Faszinierend, ich wäre nie auf die Idee gekommen, Taster mit dem ADC 
abzufragen. Klasse!!

von Falk (Gast)


Lesenswert?

@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

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

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

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

Das gleiche Prinzip hat sogar schon vor Jahren bei der C-Controll 
Wetterstation benutzt (was nicht heißst, dass das prinzip schlecht ist)

von Falk (Gast)


Angehängte Dateien:

Lesenswert?

@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

von Peter D. (peda)


Lesenswert?

@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

von jonas (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Stephan (Gast)


Lesenswert?

Die richtigen Ideen muß man eben nur haben....

von Falk (Gast)


Lesenswert?

@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

von F.H. (Gast)


Lesenswert?

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/

von Pinsparenwoller (Gast)


Lesenswert?

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 ;-)

von gerhard (Gast)


Lesenswert?

hallo,
nette idee.
ich würde aber noch einen spannungsfolger spendieren da der adc der avr 
gerne eine niedrigere quellimpedanz sieht.

gruss
gerhard

von Roland P. (pram)


Lesenswert?

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

von gerhard (Gast)


Lesenswert?

@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

von Roland P. (pram)


Lesenswert?

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

von ulf hausmann (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von ulf hausmann (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

@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

von ulf hausmann (Gast)


Lesenswert?

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...

von Peter D. (peda)


Lesenswert?

@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

von rfr (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

@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

von H. G. (ledi)


Lesenswert?

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?

von Helmut B. (helmut70)


Lesenswert?

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...

von Peter D. (peda)


Lesenswert?

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

von Helmut B. (helmut70)


Lesenswert?

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?

von Joern DK7JB .. (moin)


Lesenswert?

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

von Tobi M. (ubbut)


Angehängte Dateien:

Lesenswert?

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!

von uC (Gast)


Lesenswert?

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 ;))

von Tobi M. (ubbut)


Lesenswert?

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

von qyq (Gast)


Lesenswert?

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

von Michael W. (Firma: Michael Willert) (michacz)


Lesenswert?

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
Noch kein Account? Hier anmelden.