16er-Matrix-Tastatur mit Demultiplexer- und Multiplexerbauteile für Arduino
Abfrage von Matrix-Tastaturen bis zu 16 Tasten im Format 4 x 4 oder z.B. 12 Tasten (4 x 3) mit Demultiplexer- und Multiplexerbauteile 74HC238 und 74HC153. Statt maximal 8 digitaler Ein- bzw. Ausgänge am Arduino werden nur 5 benötigt!
Diese Variante war meine erste Variante zur Abfrage von Matrixtastaturen, die dann aber bei mir etwas in den Hintergrund gerückt ist, nachdem ich eine zweite Variante der Tastaturabfrage über I2C-Bus realisiert habe (siehe: 16er-Tastatur mit I2C).
Aber: Nicht immer steht der I2C-Bus für die Tastaturauslesung zur Verfügung, z.B. wenn der Uno selbst nur ein "Slave" am I2C-Bus ist. Dann hat man die Möglichkeit, auf nachfolgende Variante zurück zu greifen. Mittlerweile hat die dazugehörige Library auch die gesamte Funktionalität, wie die für die Ansteuerung von Tastaturen über I2C-Bus.
Testaufbau:
Verwendete Bauteile:
- 1 Arduino Uno
- 1 Multiplexer 74HC153
- 1 Decoder/Demultiplexer 74HC238
- 5 Widerstände 10 kOhm
- 1 Tastatur 16 Tasten (4 x 4)
Anschluss des Arduino:
Die Anschlussbelegung der Digitalpins am Arduino ist frei wählbar und wird vor dem Setup beim Bilden einer Instanz (z.B. MyKey) der Klasse MyKeypad festgelegt:
MyKeypad MyKey(outPinA0, outPinA1, outPinS0, outPinS1, inPinY);
z.B.:
#include <MyKeypad.h>
#define outPinA0 3
#define outPinA1 4
#define outPinS0 5
#define outPinS1 6
#define inPinY 7MyKeypad MyKey(outPinA0, outPinA1, outPinS0, outPinS1, inPinY);
wobei nachfolgende Zuordnung der Arduinopins zu den Pins der Multiplexer/Demultiplexerbausteine gegeben ist:
outPinA0: Arduino-Pin verbunden mit 74HC238 Pin 1
outPinA1: Arduino-Pin verbunden mit 74HC238 Pin 2
outPinS0: Arduino-Pin verbunden mit 74HC153 Pin 2
outPinS1: Arduino-Pin verbunden mit 74HC153 Pin 14
inPinY : Arduino-Pin verbunden mit 74HC153 Pin 7
Anschluss der Tastatur:
Für die Funktionalität ist beim Anschluss der Tastatur darauf zu achten, dass die Zeilen der Tastaturmatrix nur auf den Pins Y0-Y3 des 74HC238 und die Spalten nur auf den Pins I0-I3 des 74HT153 - oder umgekehrt - geschaltet sind, aber nicht vermischt!!
Oft sind am Tastaturstecker die zeilen- und spaltenzugehörigen Anschlüsse durch Markierungen ersichtlich
und manchmal auch in getrennten Flachbandleitern geführt.
Ansonsten können die Zeilen und Spalten der Tastaturmatrix mit Hilfe eines Durchgansprüfers ermittelt werden.
Library MyKeypad:
Die Library ist für 16er-Matrix-Tastaturen (4 x 4 Tasten) zu verwenden, kann aber auch für Tastaturen mit weniger Tasten, also z.B. mit 4, 9 oder 12 Tasten verwendet werden.
Die Library hat folgende Funktionen:
- Abfrage des Tastenwertes einer gedrückten Taste
- Löschen aller Tastencodes
- Eingabe der Tastencodes zur Anpassung an verschiedene Tastaturen
- Ausgabe des Tastencodes und des Rückgabewertes einer gedrückten Taste
- Ausgabe aller Tastencodes am Seriellen Monitor
Für eine gedrückte Taste z.B. 0.....9 gibt die Library die Zahlen (Format Byte) 0.....9 zurück, für Sondertasten wie z.B. A.......F oder Sonderzeichen wie Raute oder Stern die Zahlen 10....15. Wurde keine Taste gedrückt, ist der Rückgabewert 255.
Die Abfrage des Tastenwertes muss im Hauptprogramm erfolgen und sollte für eine sichere Tastendruckerkennung alle 100 bis 200 ms durchgeführt werden. Als guter Wert hat sich 150 ms erwiesen. Ich verwende für die zyklische Abfrage der Tastatur gerne die Metro-Library (siehe nachfolgendes Programmbeispiel).
Bei der Abfrage des Tastenwertes ist ein Übergabeparameter mit anzugeben, der bei anhaltendem Tastendruck die Funktion der Taste bestimmt (siehe nachfolgendes Programmbeispiel):
Übergabeparameter = 0:
Wird eine Taste längere Zeit gehalten, gibt die Funktion als Rückgabewert bei jedem Abfragefragezyklus den Tastenwert der gedrückten Taste zurück.
Übergabeparameter >= 1:
Wird eine Taste längere Zeit gehalten, gibt die Funktion als Rückgabewert nach einer definierbaren Zeit nicht mehr 0....15, sondern 100 bis 115 zurück. Dadurch hat man im aufrufenden Programm die Möglichkeit, entsprechend auf einen längeren Tastendruck zu reagieren. Wie lange die Taste gedrückt werden muss, wird durch den Übergabeparameter definiert. Gibt man als Übergabeparameter z.B. 5 an, so wird die Rückgabe nach 5 Abfragezyklen (z.B. 5 x 150ms = 750 ms) geändert.
Übergabeparameter = (-1):
Wird eine Taste längere Zeit gehalten, gibt die Funktion als Rückgabewert nur einmalig den Tastenwert der gedrückten Taste zurück.
Ähnlich wie bei einer PC-Tastatur wird (bei Übergabeparameter 0 oder >1) die Rückgabe des Tastenwertes nach der ersten Rückgabe kurz verzögert um eine unbeabsichtigte Doppel- oder Mehrfachrückgabe zu verhindern. Die Verzögerung ist in den Libraries mit 2 Abfragezyklen festgelegt. Ist der Abfragezyklus also z.B. 150 ms, so beträgt die Verzögerung 2 x 150 = 300 ms.
Die Library kann hier heruntergeladen werden:
Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!
Version 1.0
MyKeypad.cpp.txt
MyKeypad.h.txt
keywords.txt
Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Library das Suffix ".txt" aus diesen Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyKeypad" im Sketchbook-Ordner im Ordner "libraries" speichern.
Zur Auflistung der Funktionen der Library geht es hier: Funktionen
Programmbeispiel MyKeypad:
Das Beispielprogramm zu MyKeypad verwendet auch die Library Metro, wo mit einem vordefinierten Zyklus (hier im Beispiel 150 ms) die Tastatur abfragt wird.
Einen Link zu Metro findet ihr hier: Fremd-Libraries
Das Funktionieren des Programms setzt voraus, dass die Anpassung der jeweiligen Tastatur entweder in der Library selbst oder im Setup des Beispielprogrammes - wie im nachfolgendem Kapitel "Die Verwendung der Library mit den verschiedenen Tastaturen" beschrieben - bereits erfolgt ist!
//Programmbeispiel zu MyKeypad
#include <Metro.h>
#include <MyKeypad.h>
//Definiere Digitalpins
#define outPinA0 3
#define outPinA1 4
#define outPinS0 5
#define outPinS1 6
#define inPinY 7
Metro tastZyklusMetro(150); //Tastatur-Abfragezyklus 150 ms
MyKeypad MyKey(outPinA0, outPinA1, outPinS0, outPinS1, inPinY);
byte tastWert; //Rückgabewert der Tastatur
void setup()
{
Serial.begin(115200);
Serial.println("Warte auf Taste ...");
// Festlegen der Tastencodes, falls abweichend von den in der Library festgelegten Codes
//MyKey.setKeyCode(......);
//MyKey.setKeyCode(......);
//............................
}
void loop()
{
if (tastZyklusMetro.check())
{
tastWert = MyKey.receiveKey(5);
if (tastWert != 255)
{
Serial.println(tastWert);
}
}
}
Die Verwendung der Library mit den verschiedenen Tastaturen
Matrix-(Folien-)Tastaturen erhält man in verschiedenen Ausführungen, mit unterschiedlichen Tastenanzahlen, Tastenbeschriftungen und Tastenverschaltungen. Und auch der Anschluss an den Multiplexer-/Demultiplexerbauteile kann durch Vertauschen der Tastaturmatrix (Zeilen- und Spaltenanschlüsse) und durch unterschiedliche Anzahl von Zeilen und Spalten variieren. Dadurch ist eine Anpassung der Library an jede Tastaturtype erforderlich.
Beispiele für unterschiedliche Ausführungen von Tastenanzahl und Tastenbeschriftung
16er- 16er- 12er- 4er-Tastatur
7 8 9 A 1 2 3 A 1 2 3 1 2 3 4
4 5 6 B 4 5 6 B 4 5 6
1 2 3 C 7 8 9 C 7 8 9
0 F E D * 0 # D * 0 #
Zur Anpassung der jeweiligen Tastatur an die Library gibt es 2 Möglichkeiten:
- Anpassung im Setup des Programms oder
Anpassung direkt in einer - in der Library hinterlegten - Tabelle
Je nach Verschaltung der Spalten-Zeilen-Matrix wird beim Drücken einer Taste durch die Library ein sogenannter Tastencode (Variable keyCode) ermittelt. Mit Hilfe einer Tabelle wird nun aufgrund dieses Tastencodes ein Rückgabewert (=gedrückter Tastenwert) ermittelt. Stimmt nun dieser Rückgabewert mit dem gewünschten Rückgabewert (also z.B. Rückgabewert 7 für die gedrückte Taste "7") nicht überein, so muss die Tabelle entsprechend geändert werden:
Die aktuellen Tastencodes erhält man durch Drücken aller Tasten mit nachfolgendem Hilfsprogramm:
//Hilfsprogramm zur Abfrage der Tastcodes
#include <MyKeypad.h>
//Definiere Digitalpins
#define outPinA0 3
#define outPinA1 4
#define outPinS0 5
#define outPinS1 6
#define inPinY 7
MyKeypad MyKey(outPinA0, outPinA1, outPinS0, outPinS1, inPinY);
void setup() {
Serial.begin(115200);
Serial.println("TastenCode-Abfrage");
}
void loop() {
MyKey.checkKey();
delay(150);
}
Ausgabe am Seriellen Monitor, nachdem alle Tasten einer 16er-Tastatur (beginnend von links oben nach rechts unten) gedrückt wurden:
So sollte z.B. bei gedrückter Taste "7" der Rückgabewert eben 7 sein, bei Taste "A" z.B. 10 oder bei Taste "#" z.B. 15.
Erhält man bei Drücken der Taste "7" nicht den gewünschten Rückgabewert 7, so gibt es zwei Möglichkeiten zur Anpassung:
1. Eingabe der Tastencodes im Setup des Programms (wenn man verschiedene Tastaturen verwendet)
Die mit Hilfe des obigen Programms - für die jeweilige Tastatur - ermittelten Tastencodes können mit der Anweisung
MyKey.setKeyCode(byte Tastencode, byte Rueckgabewert);
im Setup des Programms eingegeben werden.
Werden die Tastencodes z.B. für eine Tastatur mit weniger als 16 Tasten, also z.B. mit nur 9 oder 12 Tasten eingegeben, dann sollte die Vorbelegung der Tastencodes in der Library, vorher mit der Funktion
MyKey.clearAllKeyCodes();
gelöscht werden!
Beispiel:
//Beispiel fuer Festlegen der Tastencodes, die abweichend von den in der
//Library festgelegten Codes sind, fuer eine Tastatur mit 12 Tasten:
//
// Tastenbelegung Rueckgabewerte
// 1 2 3 1 2 3
// 4 5 6 4 5 6
// 7 8 9 7 8 9
// * 0 # 11 0 13//
MyKey.clearAllKeyCodes(); //Loeschen der in der Library definierten Tastencodes
//
MyKey.setKeyCode(7, 0); //Tastencode 7, Rueckgabewert 0
MyKey.setKeyCode(0, 1); //Tastencode 0, Rueckgabewert 1
MyKey.setKeyCode(4, 2); //Tastencode 4, Rueckgabewert 2
MyKey.setKeyCode(5, 3); //etc.
MyKey.setKeyCode(1, 4);
MyKey.setKeyCode(5, 5);
MyKey.setKeyCode(9, 6);
MyKey.setKeyCode(2, 7);
MyKey.setKeyCode(6, 8);
MyKey.setKeyCode(10, 9);
MyKey.setKeyCode(3, 11);
MyKey.setKeyCode(11, 13);
Auf diese Art kann für jede Taste der Rückgabewert für den entsprechenden Tastencode angepasst werden.
2. Anpassung der Tastencodes in der Library selbst (wenn man immer nur eine Tastatur bzw. einen Tastaturtyp verwendet)
Die mit obigem Hilfsprogramm ermittelten Rückgabewerte können direkt in der Library angepasst werden.
Nachfolgend ein Programmauszug aus "MyKeypad.cpp" mit den vorbelegten Tastencodes.
(Die hier dargestellten Tastencodes sind beispielhaft und gelten für eine von mir verwendete Tastatur).
//Vorbelegte Tastencodes
// Tastenbelegung Rueckgabewerte
// 7 8 9 A 7 8 9 10
// 4 5 6 B 4 5 6 11
// 1 2 3 C 1 2 3 12
// 0 F E D 0 15 14 13
////Tastencode = Index
keyCode[0] = 4; //Tastencode 0, Rueckgabe 4
keyCode[1] = 5; //Tastencode 1, Rueckgabe 5
keyCode[2] = 6; //Tastencode 2, Rueckgabe 6
keyCode[3] = 11; //etc.
keyCode[4] = 7;keyCode[5] = 8;
keyCode[6] = 9;
keyCode[7] = 10;
keyCode[8] = 1;
keyCode[9] = 2;
keyCode[10] = 3;
keyCode[11] = 12;
keyCode[12] = 0;
keyCode[13] = 15;
keyCode[14] = 14;
keyCode[15] = 13;
Nach der Anpassung der Tastencodes im File "MyKeypad.cpp" die Datei speichern, den "Tastcode-Abfrage-Sketch" neu übersetzen und die Rückgabewerte kontrollieren. Wenn alle Werte passen, kann die Library für genau diese Tastatur und für diese Verschaltung verwendet werden.