[068] Arduino i klawiatura PC - cz. 1

[068] Arduino i klawiatura PC - cz. 1

Projektowanie różnego rodzaju urządzeń może mieć różne priorytety. Amatorzy będą się kierować przyjemnością, praktycy natomiast – temu, co w danym momencie jest najważniejsze. Życie pokazuje, że najczęściej są to koszty i czas, a w przypadku budowania dużej klawiatury obie te wartości są spore. Cena typowego panelu z pełną klawiaturą alfanumeryczną choćby w technice membranowej, przy ilości detalicznej to tysiące złotych. Tymczasem klawiatura komputerowa kosztuje kilkadziesiąt razy mniej, jest kompletna, każdy to umie obsługiwać i na pewno działa poprawnie.


Mimo, że od lat klawiatury pecetowe pracują już w standardzie USB, wersje ze złączem PS/2 wciąż są produkowane i dostępne. Do naszych dzisiejszych zabawa wybiorę taką właśnie klawiaturę, choć oczywiście wersja USB także będzie współpracować z Arduino, ale z nieco bardziej zaawansowanymi modelami, a z prostymi – po pewnych modyfikacjach drugiego mikrokontrolera znajdującego się na płytce, co dla początkujących niekoniecznie jest takie proste i na razie ten temat pozostawię sobie na później.

Klawiatury, zarówno w standardzie USB jak i PS/2, używają tylko czterech przewodów, co znakomicie ułatwia ich współpracę z systemami mikroprocesorowymi. Jeśli mowa o starszym standardzie, ten także początkowo używał dwóch rodzajów złącz – większego: DIN i mniejszego, zwanego PS/2. Różnice dotyczyły tylko mechaniki, sygnały były w stu procentach kompatybilne.

Do naszych zabaw będziemy potrzebowali tylko jednego elementu: gniazdka PS/2 z przewodami. Było one niegdyś dodawane obowiązkowo do płyt głównych. Ostatecznie można zawsze wtyczkę obciąć, przylutowując do przewodów goldpiny. Masę i zasilanie należy oczywiście dołączyć do masy i wyjścia +5V, które każda płytka Arduino pracująca w tym standardzie napięć oferuje. Linię danych należy podłączyć do dowolnego wyprowadzenia (użyłem ósmego), natomiast linię zegara – do 2 albo 3, ze względu na to, że biblioteka, o której zaraz opowiem, używa przerwań, a te w module Uno są dostępne tylko na tych dwóch portach. Zatem czy użyjemy najprostszego modułu: Nano, czy płytki edukacyjnej TME, nie będziemy potrzebować nawet jednego rezystora. I w tym tkwi prostota tego rozwiązania.

Przyjrzyjmy się teraz samej klawiaturze, choć wiedza, którą teraz w skrócie przedstawię, nie ma dla nas znaczenia, o ile nie zdecydujemy się na napisanie oprogramowania współpracującego z nią w całości na piechotę.

Urządzenie to posiada własny mikrokontroler, kompatybilny z prastarym układem Intela 8049. Jest to układ ośmiobitowy, ze skromną pamięcią programu równą 2 kB i wszystkimi peryferiami, które pozwalają zbudować dużą klawiaturę. Problemy mamy dwa: jeden, niewielki, ale łatwy do pokonania: klawiatura rozmawia w nieco mniej znormalizowanym narzeczu: szeregowo, synchronicznie, ale ze słowem jedenastobitowym, który zawiera także bit parzystości. Używając biblioteki, możemy się tym nie przejmować.

Drugi problem to słowa, którymi klawiatura się posługuje. O ile w pierwszej wersji, znanej z komputerów XT, był tam jeszcze jakiś porządek, w toku poprawek i usprawnień, reakcje przyciśnięcia bądź zwolnienia klawiszy zaczęły generować jeden, dwa, a nawet trzy bajty, do tego nie mające nic wspólnego z kodowaniem znaków w standardzie ASCII. Czas więc zabrać się za programowanie. Jak mówiłem, nie będziemy pisać procedury obsługi klawiatury na piechotę, choć byłoby to ciekawe ćwiczenie. Użyjemy praktycznej biblioteki, która nazywa się PS2Keyboard.h

#include <PS2Keyboard.h>  // Biblioteka obsługi klawiatury PS/2
const byte PS2data = 8;   // Adres linii DATA klawiatury.
const byte PS2clck = 3;   // Adres linii CLCK klawiatury, dla wersji UNO może przyjmować wartość 2 lub 3
PS2Keyboard klawiatura;   // Powołaj do życia obiekt o nazwie klawiatura.

void setup() {
  Serial.begin(9600);                  // Inicjuj przesyłanie danych portem szeregowym.
  klawiatura.begin(PS2data, PS2clck);  // Deklaruj wejścia, do których podłączona jest klawiatura.
}
void loop() {
  if (klawiatura.available()) {         // Jeśli klawisz został wciśnięty, to...
    Serial.println(klawiatura.read());  // Wyślij kod klawisza.
  }
}

Zaraz po zaimportowaniu biblioteki należy zadeklarować linię danych i zegara. Biblioteka wymaga nazwania obiektu jakąś własną nazwą, naturalnie nasuwa się tutaj słowo: klawiatura. Kolejno należy zainicjować monitor, który wyświetli nam przychodzące kody z klawiatury. W końcu należy zadeklarować samą bibliotekę.

W głównej pętli dziać się będzie niewiele. Klawiatura.available sprawdza czy jakiś klawisz został wciśnięty. Jeśli tak się stało, klawiatura.read pobierze kod owego klawisza i wyśle go do monitora.

Możemy się już cieszyć konkretnym działaniem i w zasadzie to wystarczy, by zaprzęgnąć nasz fragment programu do jakiegoś większego zadania, interpretując odpowiednio wartości, które obecnie widzimy w okienku monitora. Trzeba jednak pamiętać, że klawisze będą generować powtarzalne, ale jednak użyteczne w ograniczonym stopniu wartości wyrażane liczbami. Tymczasem często potrzebujemy znaków zgodnych ze standardem ASCII, a nie jakichś cyferek, zupełnie człowiekowi obcych. Zobaczmy co w tej kwestii da się zrobić.

#include <PS2Keyboard.h>  // Biblioteka obsługi klawiatury PS/2
const byte PS2data = 8;   // Adres linii DATA klawiatury.
const byte PS2clck = 3;   // Adres linii CLCK klawiatury, dla wersji UNO może przyjmować wartość 2 lub 3
PS2Keyboard klawiatura;   // Powołaj do życia obiekt o nazwie klawiatura.
char wcisnieto;           // Zmienna przechowująca znak wciśniętego klawisza.

void setup() {
  Serial.begin(9600);                  // Inicjuj przesyłanie danych portem szeregowym.
  klawiatura.begin(PS2data, PS2clck);  // Deklaruj wejścia, do których podłączona jest klawiatura.
}
void loop() {
  if (klawiatura.available()) {     // Jeśli klawisz został wciśnięty, to...
    wcisnieto = klawiatura.read();  // zapamiętaj jego kod w zmiennej wcisnieto.
    Serial.print(wcisnieto);        // Wyślij kod klawisza.
  }
}

Program będzie podobny do poprzedniego. Zadeklarujemy sobie dodatkową zmienną znakową, którą nazwę wcisnieto. Teraz pobrane kody będziemy przekazywać bezpośrednio do niej i już niejako z automatu dostaniemy znane nam literki.

Wszystko działa w przypadku wciskania kolejnych liter, cyfr i znaków specjalnych. Jednak próby wciskania klawiszy związanych z nawigacją nic nie dają oprócz wstawiania spacji i to nie za każdym razem. Okazuje się, że te klawisze także dają swoje kody, ale char nie potrafi ich zaczarować w nic konkretnego. Czy da się coś z tym zrobić? O tym napiszę w kolejnym artykule.

Powiązane tematy

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2Sprawdź tutaj

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2024 arduino.pl