[167] Klawiatura matrycowa dla zaawansowanych cz. 1
Postanowiłem zbudować zamek szyfrowy – ale najpierw dokładniej przyjrzymy się jednemu z elementów, który pojawia się w takich konstrukcjach: klawiaturze. Zamki szyfrowe i nie tylko one, są kojarzone z klawiaturką, na której wystukujemy kod, otwierając drzwi, bramę albo schowek. Klawiatury najczęściej zawierają dziesięć przycisków numerycznych i dwa dodatkowe. Jeden zwykle otwiera zamek po wpisaniu kodu, drugi – cofa pomylone znaki. Zanim zabierzemy się do samego zamka, pobawimy się klawiaturą jako taką, bo to pożyteczny element, który można wykorzystywać w wielu różnych projektach. Może mieć kilka dosłownie pozycji albo kilkadziesiąt, udając typową klawiaturę komputerową. O klawiaturach pisałem już wiele razy, dziś jednak chciałbym do tematu powrócić, aby go zgłębić dokładnie i kompletnie.
Ćwiczyć będziemy na takiej, jakże popularnej klawiaturce o organizacji cztery wiersze na cztery kolumny, co daje 16 przycisków. Używając dwustronnych goldpinów możemy ją wetknąć w zduplikowane gniazdo Arduino Uno, które mieści się na płytce edukacyjnej TME.
I już na początku mamy problem: Uno z niezrozumiałych dla mnie powodów ma przesunięcie pinów między siódmym, a ósmym. Oznacza to, że tylko pierwszych osiem pinów stoi sobie równo w rzędzie, umożliwiając wpięcie gniazdka bez użycia dodatkowych przewodów. Niby okej, jednak pin zerowy i pierwszy używane są do programowania kontrolera oraz zrzucania danych na monitor. Co to dla nas oznacza? Jeśli będziemy korzystać z tych pinów, nie będzie można niczego nie wciskać na klawiaturze podczas programowania i trzeba będzie zrezygnować z użycia funkcji serial do wysyłania danych. Ponieważ jednak mam tu wyświetlacz, a poza tym w zamkach szyfrowych nie używa się monitora, problemu nie ma. Gdyby jednak komuś to przeszkadzało, niech ominie pierwsze dwa piny.
Klawiatury pasywne, to znaczy nie wysyłające kodów znaków na jakiejś konkretnej magistrali, możemy podzielić na trzy grupy. Pierwsza to jeden pin – jeden klawisz.
Ma sens tylko przy maksymalnie kilku przyciskach. Druga to klawiatury matrycowe.

W tym wypadku liczba przycisków to iloczyn wierszy i kolumn. Z tego wniosek, że najlepiej, gdy jednych i drugich jest tyle samo. Nasza klawiatura wymaga ośmiu pinów, dając 16 klawiszy. Przy dziesięciu liczba rośnie do 25 i tak dalej. Trzeci rodzaj klawiatur to klawiatury analogowe, które zwierają rezystory dzielące napięcia na wspólnej linii.
W tym wypadku mierzy się przedziały napięć i takie rozwiązania stosuje się dla klawiaturek obejmujących 2-5 przycisków. Zajmują tylko jeden pin, ale tym się na razie zajmować nie będziemy.
Nasza klawiatura to klasyka matrycowa i idea pracy z taką klawiaturą jest prosta: Na jednym z wierszy ustawia się stan niski, na pozostałych – wysoki. Następnie czyta się stany każdej z kolumn i jeśli na którejś pojawi się stan niski, oznacza to, że wciśnięto przycisk znajdujący się na skrzyżowaniu tego wiersza i tej kolumny. Do kompletu trzeba wykonać cztery takie analizy, zmieniając za każdym razem wiersz, któremu podaje się stan niski. Można zamienić aktywne stany miejscami, to już jest kwestia konkretnej umowy i czasem też wymagań sprzętu.
Jak się można domyślić, stworzenie algorytmu dla takiego zadania nie byłoby wyzwaniem ambitnym, jednak postanowiłem skorzystać z biblioteki, bo tak będzie prościej. Zadbano tam o szczegóły i nie jest zasobożerna, zadowalając się półtora kilobajtem pamięci. Napiszmy sobie na początek szkic podstawowy, który pozwoli nam przetestować pracę naszej klawiatury. Jak mówiłem, kody wciskanych znaków będziemy wysyłać na wyświetlacz, a nie na monitor, więc należy tu zadbać o niego, co już wielokrotnie czyniłem więc powtarzać się nie będę.
#include <Wire.h> // Biblioteka obsługująca magistralę I2C
#include <hd44780.h> // Biblioteka obsługująca wyświetlacze 44780
#include <hd44780ioClass/hd44780_I2Cexp.h> // Dodatek obsługujący wyświetlacze podłączone do ekspandera I2C
hd44780_I2Cexp lcd(0x20, I2Cexp_MCP23008, 7, 6, 5, 4, 3, 2, 1, HIGH); // Konfiguracja połączeń wyświetlacza LCD
#include <Keypad.h> // Biblioteka obsługująca klawiaturę.
const byte rowsKeypad = 4; // Liczba wierszy matrycy klawiatury.
const byte colsKeypad = 4; // Liczba kolumn matrycy klawiatury.
byte rowPins[rowsKeypad] = { 7, 6, 5, 4 }; // Adresy kolejnych wierszy klawiatury.
byte colPins[colsKeypad] = { 3, 2, 1, 0 }; // Adresy kolejnych kolumn klawiatury.
char keys[rowsKeypad][colsKeypad] = { // Tablica znaków dla kolejnych klawiszy.
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rowsKeypad, colsKeypad); // Definiuj klawiaturę zgodnie z powyższymi deklaracjami.
void setup() {
lcd.begin(16, 2); // Inicjuj wyświetlacz.
}
void loop() {
char key = keypad.getKey(); // Pozyskaj znak klawiatury.
if (key) { lcd.print(key); } // Jeśli się pojawił, wyślij go na wyświetlacz.
}
Sprawy związane z klawiaturą znajdują się poniżej. Najpierw zaczytujemy bibliotekę keypad.h Jest ona rekomendowana przez organizację Arduino, zatem prześwietlona na wylot. Kolejne dwie linie określają liczbę wierszy oraz kolumn. Następne – przyporządkowują porty dla wierszy i kolumn, czyniąc port klawiatury. Tutaj najlepiej określić sobie wstępnie miernikiem wykrywającym zwarcia co jest co, albo dopasowywać grupy metodą prób i błędów. W końcu mamy matrycę znaków, która przyporządkowuje kody konkretnym przyciskom. To te znaki będą się nam pojawiać potem na wyświetlaczu.
Kolejno inicjujemy bibliotekę takim rozciągniętym wyrażeniem. Keypad keypad to takie trochę mało maślane: pierwsze słowo oznacza definicję biblioteki, drugie jest nazwą tej konkretnej klawiatury i przyjęło się nazywać ją właśnie tak, ale to nie jest obowiązkowe. Mało tego, można sobie zorganizować kilka klawiatur i wtedy należy nadać im tutaj niepowtarzalne nazwy. To co wewnątrz nawiasu, zostało opisane wcześniej, więc nie będę tego wyjaśniał.
Pozostaje jeszcze zainicjować wyświetlacz i można testować klawiaturę. Instrukcja keypad.getKey() zwraca kod wciśniętego przycisku. Kolejna zaś wysyła go na wyświetlacz, jeśli oczywiście pojawiło się zdarzenie wciśnięcia. Siedemnasty znak z kolei już się nam nie zmieści na ekranie i żeby testować klawiaturę dalej, trzeba będzie wcisnąć reset.
Program działa, co oznacza prawidłowe podłączenie wszystkiego i sprawność samej klawiatury. Na tym etapie można już przystąpić do konkretów z wykorzystaniem tej biblioteki, ale ona potrafi więcej, zatem trzeba będzie poznać inne jej możliwości. Ale o tym napiszę w kolejnym artykule.

Inne artykuły z tej kategorii
Jak wyświetlić cyfry o rozmiarze 10x8 i 10x16 pikseli?
















































































































