4x4 Matrix Keypad mit Arduino auslesen: Codeschloss & Tastenfeld selbst bauen
Ein Zahlenfeld mit 16 Tasten, aber der Arduino UNO hat nur begrenzt Pins – wie geht das zusammen? Die Antwort ist ein cleverer Trick namens Matrix-Verdrahtung: 16 Tasten hängen an nur 8 Leitungen. In diesem Tutorial liest du ein 4x4 Folientastatur-Keypad mit dem Arduino aus, verstehst wie das Zeilen-Spalten-Prinzip funktioniert und baust Schritt für Schritt ein echtes PIN-Codeschloss – erst mit Ausgabe im Seriellen Monitor, dann auf einem LCD1602-Display, und am Ende schaltest du bei richtigem Code ein Relais als Türöffner.
Wie eine Matrix-Tastatur funktioniert
Ein 4x4 Keypad hat 16 Tasten, aber nur 8 Anschlusspins – vier für die Zeilen (Rows) und vier für die Spalten (Columns). Jede Taste sitzt am Kreuzungspunkt einer Zeile und einer Spalte. Drückst du eine Taste, verbindet sie genau diese eine Zeile mit genau dieser einen Spalte.
Der Arduino nutzt das so: Er legt nacheinander jede Zeile auf ein bestimmtes Signal und prüft dann, an welcher Spalte dieses Signal ankommt. Kommt es an Spalte 2 an, während gerade Zeile 3 aktiv ist, dann wurde die Taste am Kreuzungspunkt (Zeile 3, Spalte 2) gedrückt – in der Standardbelegung ist das die 8. Dieses blitzschnelle Abfragen aller Zeilen nennt man Scannen, und die Keypad-Bibliothek erledigt es komplett für dich.
ℹ️ Warum 8 statt 16 Pins? Würde jede Taste einen eigenen Pin bekommen, bräuchtest du 16 Eingänge plus Masse. Die Matrix halbiert das auf 8 – der gleiche Trick steckt in jeder Computertastatur, nur dort mit hunderten Tasten. Du zahlst dafür mit etwas Rechenzeit (dem Scannen), was bei einem Bedienfeld aber völlig unkritisch ist.
Das brauchst du
1Verkabelung
Das Keypad hat eine Reihe von 8 Pins. Von links geht es typischerweise so: die ersten vier sind die Zeilen (R1–R4), die nächsten vier die Spalten (C1–C4). Wir hängen sie an die Digitalpins D9 bis D2. Ein Vorwiderstand oder Pull-up ist nicht nötig – die Bibliothek nutzt die internen Pull-ups des Arduino.
| Keypad-Pin | Funktion | Arduino UNO |
|---|---|---|
| Pin 1 | Zeile R1 | D9 |
| Pin 2 | Zeile R2 | D8 |
| Pin 3 | Zeile R3 | D7 |
| Pin 4 | Zeile R4 | D6 |
| Pin 5 | Spalte C1 | D5 |
| Pin 6 | Spalte C2 | D4 |
| Pin 7 | Spalte C3 | D3 |
| Pin 8 | Spalte C4 | D2 |
⚠️ Pin-Reihenfolge prüfen: Nicht jede Folientastatur ist gleich beschriftet. Wenn beim ersten Test die falschen Zeichen erscheinen oder Tasten „verrutscht“ wirken, sind meist nur Zeilen und Spalten vertauscht. Dann tauschst du im Code die Pin-Arrays rowPins und colPins – kein Neuverdrahten nötig.
2Erster Test: Welche Taste wurde gedrückt?
Installiere zuerst in der Arduino IDE über Werkzeuge → Bibliotheken verwalten die Bibliothek Keypad von Mark Stanley und Alexander Brevig. Danach liest dieser Sketch jede gedrückte Taste aus und schickt sie an den Seriellen Monitor (115200 Baud):
#include <Keypad.h>
const byte ZEILEN = 4;
const byte SPALTEN = 4;
// Tastenbelegung wie auf dem Keypad aufgedruckt
char tasten[ZEILEN][SPALTEN] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ZEILEN] = {9, 8, 7, 6}; // R1..R4
byte colPins[SPALTEN] = {5, 4, 3, 2}; // C1..C4
Keypad keypad = Keypad(makeKeymap(tasten), rowPins, colPins, ZEILEN, SPALTEN);
void setup() {
Serial.begin(115200);
Serial.println("Keypad bereit - druecke eine Taste");
}
void loop() {
char taste = keypad.getKey();
if (taste) { // nur wenn wirklich gedrueckt
Serial.print("Taste: ");
Serial.println(taste);
}
}
Sobald jede Taste das passende Zeichen liefert, ist die Basis fertig. keypad.getKey() gibt bei jedem Loop-Durchlauf entweder das Zeichen der frisch gedrückten Taste zurück oder NO_KEY – die Bibliothek entprellt automatisch, du musst dich also nicht um flackernde Kontakte kümmern.
3Das Codeschloss: PIN prüfen
Jetzt bauen wir aus den Tastendrücken ein Schloss. Der Nutzer tippt Ziffern, mit # bestätigt er, mit * löscht er die Eingabe. Wir sammeln die Ziffern in einem String und vergleichen ihn mit dem hinterlegten Code.
#include <Keypad.h>
const byte ZEILEN = 4, SPALTEN = 4;
char tasten[ZEILEN][SPALTEN] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ZEILEN] = {9, 8, 7, 6};
byte colPins[SPALTEN] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(tasten), rowPins, colPins, ZEILEN, SPALTEN);
const String GEHEIMCODE = "1234"; // hier deinen Code eintragen
String eingabe = "";
void setup() {
Serial.begin(115200);
Serial.println("Code eingeben, mit # bestaetigen");
}
void loop() {
char taste = keypad.getKey();
if (!taste) return;
if (taste == '#') { // bestaetigen
if (eingabe == GEHEIMCODE) {
Serial.println("\nZugang gewaehrt!");
} else {
Serial.println("\nFalscher Code!");
}
eingabe = ""; // zuruecksetzen
} else if (taste == '*') { // loeschen
eingabe = "";
Serial.println("\nEingabe geloescht");
} else { // Ziffer anhaengen
eingabe += taste;
Serial.print("*"); // Maskierung im Monitor
}
}
💡 Warum ein String und kein int? Ein String unterscheidet "0042" von "42" – führende Nullen bleiben erhalten, und du kannst beliebig lange Codes verwenden. Für Speichersparfüchse auf dem UNO lohnt später ein char-Array, aber fürs Lernen ist der String am klarsten.
4Anzeige auf dem LCD1602
Ohne PC brauchst du eine Anzeige. Das LCD1602 mit I2C-Modul braucht nur vier Kabel (VCC, GND, SDA an A4, SCL an A5). Installiere die Bibliothek LiquidCrystal_I2C. Jede eingegebene Ziffer erscheint als *, das Ergebnis als Klartext:
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adresse ggf. 0x3F
const byte ZEILEN = 4, SPALTEN = 4;
char tasten[ZEILEN][SPALTEN] = {
{'1','2','3','A'},{'4','5','6','B'},
{'7','8','9','C'},{'*','0','#','D'}
};
byte rowPins[ZEILEN] = {9, 8, 7, 6};
byte colPins[SPALTEN] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(tasten), rowPins, colPins, ZEILEN, SPALTEN);
const String GEHEIMCODE = "1234";
String eingabe = "";
void zeigeStart() {
lcd.clear();
lcd.print("Code eingeben:");
lcd.setCursor(0, 1);
}
void setup() {
lcd.init();
lcd.backlight();
zeigeStart();
}
void loop() {
char taste = keypad.getKey();
if (!taste) return;
if (taste == '#') {
lcd.clear();
if (eingabe == GEHEIMCODE) lcd.print("Zugang OK :)");
else lcd.print("Falscher Code");
delay(2000);
eingabe = "";
zeigeStart();
} else if (taste == '*') {
eingabe = "";
zeigeStart();
} else {
eingabe += taste;
lcd.setCursor(eingabe.length() - 1, 1);
lcd.print('*');
}
}
Mehr zu Adressen, Kontrast und Sonderzeichen des Displays findest du im LCD1602-Tutorial. Zeigt das Display nichts, ist fast immer die I2C-Adresse falsch – prüfe sie mit einem I2C-Scanner.
5Relais schalten: der Türöffner
Damit aus dem Codeschloss ein echtes Schloss wird, schalten wir bei korrektem Code ein KY-019 Relais an D10 für zwei Sekunden. Daran hängst du einen elektrischen Türöffner, ein Schloss oder einfach eine Lampe als Signal.
#define RELAIS_PIN 10
// ... Keypad-Setup wie oben ...
void oeffne() {
digitalWrite(RELAIS_PIN, HIGH); // Relais zieht an
delay(2000); // 2 Sekunden offen
digitalWrite(RELAIS_PIN, LOW); // wieder verriegeln
}
void setup() {
pinMode(RELAIS_PIN, OUTPUT);
digitalWrite(RELAIS_PIN, LOW);
Serial.begin(115200);
}
void loop() {
char taste = keypad.getKey();
if (!taste) return;
if (taste == '#') {
if (eingabe == GEHEIMCODE) {
Serial.println("Geoeffnet");
oeffne();
} else {
Serial.println("Abgelehnt");
}
eingabe = "";
} else if (taste == '*') {
eingabe = "";
} else {
eingabe += taste;
}
}
⚠️ Sicherheit und Last: Das KY-019 schaltet potentialfrei über seine Klemmen – einen echten 12-V-Türöffner versorgst du nie über den Arduino, sondern über ein eigenes Netzteil, das das Relais nur durchschaltet. Wie du das Relais korrekt und sicher beschaltest (High-/Low-Trigger, gemeinsame Masse, Freilaufdiode bei Spulen), steht ausführlich im Relais-Tutorial. Und ganz ehrlich: Ein simples PIN-Schloss ist ein Bastelprojekt, keine Tresor-Sicherung.
ℹ️ Zwei Faktoren – noch sicherer: Kombiniere das Keypad mit dem RFID-Modul RC522: Erst Karte auflegen, dann PIN tippen. So brauchst du beides zum Öffnen. Den RFID-Teil zeigt der Guide zum RFID-Türschloss.
Praxistipps für robuste Bedienfelder
Ein paar Kleinigkeiten machen aus dem Prototyp ein Gerät, das man täglich bedienen mag:
-
Timeout: Setze die Eingabe automatisch zurück, wenn 10 Sekunden lang keine Taste kommt – mit
millis()stattdelay(), damit nichts blockiert. Wie das sauber geht, zeigt der Artikel zu millis() statt delay(). - Fehlversuche zählen: Nach drei falschen Eingaben eine Sperrzeit von 30 Sekunden – einfache, aber wirksame Bremse gegen Durchprobieren.
- Feedback: Kurzes Aufleuchten der LCD-Beleuchtung oder ein Ton bei jeder Taste macht die Bedienung angenehm.
- Code änderbar machen: Speichere den PIN im EEPROM, dann bleibt er auch nach dem Stromausfall erhalten und lässt sich per Menü ändern.
Troubleshooting
⚠️ Falsche Zeichen bei jeder Taste: Zeilen und Spalten sind vertauscht. Tausche die Werte in rowPins und colPins oder passe die tasten-Matrix an.
⚠️ Manche Tasten reagieren gar nicht: Eine Leitung hat keinen Kontakt – Folienkabel sitzen oft locker in der Buchse. Stecker fest eindrücken, Kabel prüfen.
⚠️ Mehrere Zeichen pro Druck: Selten, aber möglich bei sehr langen Kabeln. Kurze Dupont-Leitungen verwenden.
⚠️ LCD bleibt leer: Falsche I2C-Adresse (0x27 oder 0x3F) oder Kontrast-Poti auf der Rückseite zu weit gedreht. Adresse mit dem I2C-Scanner ermitteln.
⚠️ Relais klackt beim Start ungewollt: Setze digitalWrite(RELAIS_PIN, LOW) gleich in setup(), bevor du pinMode aktivierst, damit kein kurzer HIGH-Impuls entsteht.
🚀 Dein Codeschloss-Starterpaket
Alle Bauteile für das Tastenfeld-Projekt im Shop:
- 4x4 Matrix Folientastatur – das Herz des Bedienfelds
- UNO R3 Entwicklungsboard (USB-C) – Steuerzentrale
- LCD1602 Display mit I2C – Anzeige ohne PC
- 1-Kanal Relais-Modul KY-019 – schaltet den Türöffner
- RFID-Modul RC522 – optionale zweite Sicherheitsstufe
- Breadboard 400 Kontakte und Dupont-Jumperkabel
Fazit
Mit dem Matrix-Trick liest du 16 Tasten an nur 8 Pins aus – und die Keypad-Bibliothek nimmt dir das gesamte Scannen und Entprellen ab. Vom ersten Tastentest über die PIN-Prüfung und die LCD-Anzeige bis zum Relais-Türöffner hast du ein komplettes, alltagstaugliches Bedienfeld gebaut.
Von hier aus sind viele Wege offen: ein Menü mit A/B/C/D als Funktionstasten, PIN-Änderung über das EEPROM, Kombination mit RFID für Zwei-Faktor-Zugang oder die Anzeige auf einem größeren OLED-Display. Viel Spass beim Tippen!