Nettigo keypad

Jak podłączyć prostą klawiaturkę do Arduino

Jak to działa?

Nettigo Keypad jest prostą klawiaturą złożoną z pięciu klawiszy. Pomyślana została ona jako część interfejsu do Twojego urządzenia – pięć klawiszy jest ułożonych tak, że można je wykorzystać jako cztery klawisze kierunku i jeden wyboru.

Całość jest odczytywana przez jeden pin – aby odczytać, który klawisz został naciśnięty trzeba zarezerwować jedno wejście analogowe. Keypad powstał jako uzupełnienie LCD Kitu klasycznego jak i tego z [LCD podłączanego przez I2C - niebieskiego i zielonego, tak aby razem można było zbudować jakiś prosty interfejs do Arduino.

LCD Kit razem z keypadem ma funkcjonalność zbliżoną do LCD Shielda od Nettigo jak i standardowego LCD Shielda dla Arduino . Jaka jest różnica? Dzięki LCD kitowi (albo innemu wyświetlaczowi – nie 2×16 a np. 4×20) i keypadowi, Arduino może znajdować się w innym miejscu niż wyświetlacz/klawiatura.

Jak jest zbudowany fizycznie keypad? Są to połączone szeregowo rezystory. W zależności od miejsca w którym zostaną zwarte do masy, rezystancja jednej z gałęzi utworzonego dzielnika napięcia zmienia się. Znaczy to, że napięcie mierzone między dwoma gałęziami również ulega zmianie. I to cała filozofia.

Skutek takiego rozwiązania jest taki, że klawisz który jest zwiera rezystor bliżej punktu pomiaru ma większą siłę przebicia i wciskając dwa klawisze jednocześnie zawsze tylko jeden będzie odczytany.

Montaż keypada jest bardo prosty – przyciski i rezystory należy przylutować, goldpina do podłączenia można ale nie trzeba (można przylutować kabelki). Wszystkie rezystory mają jednakową wartość (10k) więc nie ma znaczenia w które miejsce który rezystor zostanie przylutowany.

Po zmontowaniu całość wygląda mniej więcej tak:

Zmontowany keypad (aktualnie, PCB jest żółte)

Co dalej?

Teraz trzeba go podłączyć i oprogramować. Jeżeli chodzi o podłączenie – na płytce miejsce na goldpin lub kabelki oznaczone jest AD1 . Lewy pad (pole do lutowania) ma kwadratowy kształt – to pin nr 1. I tak kolejno:

  1. Zasilanie (+5V)
  2. Sygnał
  3. Masa

Czyli podłączamy zasilanie i masę a sygnał podłączamy do wejścia analogowego Arduino. Ze strony produktu można ściągnąć bibliotekę do obsługi Keypada. Jest ona też dostępna w formie repozytorium na GitHubie. Bibliotekę ściągnąć i rozpakować do sketchbook/libraries. Po uruchomieniu Arduino IDE pojawi się opcja Sketch/Import Library/NettigoKeypad. Prosty przykład jest w File/Examples/NettigoKeypad/.

Najpierw podłączmy LCD do Arduino (numery pinów LCD, wersja LCD oparta o WC1602 – z wydzielonym zasilaniem podświetlenia):

  1. – Masa
  2. – +5V
  3. – wyjście z potencjometru (środkowa nóżka)
  4. – D2 na Arduino
  5. – masa
  6. – D3 na Arduino
  7. – 10 – nie podłączone
  8. – 14 – D4-D7 na Arduino
  9. – +5V (zasilanie podświetlenia)
  10. – masa

Sygnał z keypada podłączamy do A0. Teraz szkic:

#include <NettigoKeypad.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);

NG_Keypad keypad;

char* keys[] = { "NONE", "SELECT", "LEFT", "DOWN", "UP", "RIGHT" };

void setup(){
  lcd.begin(16,2);
  lcd.print("Selected key:");
}

void loop(){
  int rd;
  rd = analogRead(0);
  lcd.setCursor(0,1);
  lcd.print( keys[ keypad.key_pressed(rd) ] );
  lcd.print("      ");
  delay(100);
}

Szkic ten jest oparty o szkic z biblioteki jako przykład BasicRead

Linia: NG_Keypad keypad; odpowiada za stworzenie obiektu, który będzie wykorzystany do odczytu wciśniętego klawisza. setup inicjuje wyświetlacz LCD. W funkcji loop odczytujemy wartość z wejścia analogowego 0 (tam gdzie podłączony został sygnał z keypada). Wywołana funkcja keypad.key_pressed z analogowej wartości sygnału zwraca kod klawisza. Na LCD wypisywany jest opis klawisza wzięty z tablicy keys.

Całość zmontowana wygląda tak:

Keypad i LCD kit razem

Obsługa przycisków

Zdarzenia w postaci naciśnięcia przycisków, można obsłużyć tak samo jak w poprzednim przykładzie. Nie jest jednak to jedyna dostępna metoda. Biblioteka oferuje rejestrację tzw handlerów, procedur wywoływanych po naciśnięciu przycisku. Zacznijmy od przykładowego kodu:

#include <NettigoKeypad.h>

#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);

NG_Keypad keypad;

//This function will be called when key UP was pressed
//just write more on LCD
void up_was_pressed() {
 lcd.print("it goes UP");
}

void down_was_pressed() {
 lcd.print("it goes DOWN");
}

void left_was_pressed() {
 lcd.print("it goes LEFT");
}

void right_was_pressed() {
 lcd.print("it goes RIGHT");
}

void select_was_pressed() {
 lcd.print("SELECT!");
}
void none_pressed() {
 lcd.print("WAITING...");
}


void setup(){
  lcd.begin(16,2);
  lcd.print("Selected key:");
  //Now register handlers for all keys
  keypad.register_handler(NG_Keypad::UP, up_was_pressed);
  keypad.register_handler(NG_Keypad::DOWN, down_was_pressed);
  keypad.register_handler(NG_Keypad::RIGHT, right_was_pressed);
  keypad.register_handler(NG_Keypad::LEFT, left_was_pressed);
  keypad.register_handler(NG_Keypad::SELECT, select_was_pressed);
  keypad.register_handler(NG_Keypad::NONE, none_pressed);
}

void loop(){
  int rd;
  rd = analogRead(0);
  lcd.setCursor(0,1);
  //check if any handler should be called
  keypad.check_handlers(rd);

  lcd.print("          ");
  delay(100);
}

Na pierwszy rzut oka widać serię funkcji, których nazwy kończą się na _pressed. Jak się łatwo domyśleć na podstawie ich nazw, każdą chcemy wywoływać gdy zostanie naciśnięty odpowiedni przycisk. Można to zrobić za pomocą switch albo odpowiedniej ilości if'ów, jednak tutaj pojawia się nastepująca sekwencja:

keypad.register_handler(NG_Keypad::UP, up_was_pressed);
keypad.register_handler(NG_Keypad::DOWN, down_was_pressed);
keypad.register_handler(NG_Keypad::RIGHT, right_was_pressed);
keypad.register_handler(NG_Keypad::LEFT, left_was_pressed);
keypad.register_handler(NG_Keypad::SELECT, select_was_pressed);
keypad.register_handler(NG_Keypad::NONE, none_pressed);

Zwróć uwagę, że register_handler potrzebuje dwóch argumentów. Pierwszy to kod klawisza, a drugi to nazwa funkcji. Jest to sama nazwa, nie jej wywołanie - brakuje nawiasów. Dzięki temu register_handler może zapisać jaką funkcję chcemy wywołać.

Następnie w pętli sprawdzamy jaka jest wartość napięcia na wejściu gdzie podłączyliśmy naszego keypada i wystarczy wyowłać keypad.check_handlers(rd);, gdzie rd to wartość odczytana z wejścia analogowego a biblioteka wywoła właściwą funkcję.

By to mogło działać, argumenty jakie potrzebują funkcje *_pressed muszą być takie same, biblioteka zakłada, że argumentów nie będzie wcale. W swoich programach możesz używać podobnych konstrukcji łącznie z argumentami, ale pamiętaj, że argumenty do wywołania podac musi kod biblioteki, więc musi miec do nich dostęp w momencie wywołania.

LCD Shield i inne cuda

Domyślnie biblioteka pracuje z Nettigo Keypad. Tymczasem zasada działania klawiatury w LCD Shieldzie jest identyczna, czemu więc nie skorzystać? Biblioteka od dawana wspierała nietypowe ustawienia dzielnika napięcia (przez funkcję NG_Keypad::setBoundaries). Przy ostatniej aktualizacji dodaliśmy do przykładów KeypadSetup, który za Was zrobi całą ciężką pracę :)

Wgrajcie go na Arduino (w linii 7 jest define, który określa gdzie jest podłączony keypad, domyślnie to Analog 0) i uruchomcie monitor portu szeregowego (Ctrl+Shift+M) ustawiony na prędkość 115200. Wziąć do ręki keypad/shielda i postępować wg instrukcji naciskając i trzymając kolejne przyciski. Po całym procesie, na konsoli dostaniecie kod konstruktora, który trzeba wpisać w Wasz szkic. I tak cały przebieg procesu wygląda np tak:

Take keypad and be prepared....
Press RIGHT and wait for X
.....................X <- here we will read analog input
.....................X
Reading: 0
Press UP and wait for X
.....................X <- here we will read analog input
.....................X
Reading: 130
Press DOWN and wait for X
.....................X <- here we will read analog input
.....................X
Reading: 306
Press LEFT and wait for X
.....................X <- here we will read analog input
.....................X
Reading: 480
Press SELECT and wait for X
.....................X <- here we will read analog input
.....................X
Reading: 720
Results:
0,130,306,480,720,1024,
Sorted results:
0,130,306,480,720,1024,
Val for RIGHT/0 is 0
Val for UP/1 is 130
Val for DOWN/2 is 306
Val for LEFT/3 is 480
Val for SELECT/4 is 720
NG_Keypad keypad(
  NG_Keypad::SELECT,872,
  NG_Keypad::LEFT,600,
  NG_Keypad::DOWN,393,
  NG_Keypad::UP,218,
  NG_Keypad::RIGHT,65);

Użyj konstruktora z powyższego rezultatu w swoim szkicu, jeśli używasz LCD shielda.

NG_Keypad keypad(
  NG_Keypad::SELECT,872,
  NG_Keypad::LEFT,600,
  NG_Keypad::DOWN,393,
  NG_Keypad::UP,218,
  NG_Keypad::RIGHT,65);

Jeśli chcesz możesz zmienić mapowanie klawiszy w ten sposób (ale po co - to nie wiem ;) ). Będzie działać z każdym 5-cio elementowym dzielnikiem napięcia pod warunkiem, że jeden z rezystorów zwiera całą konstrukcję do masy. Mówiąc ludzkim językiem, przy naciśniętym którymś z klawiszy odczyt z wejścia analogowego jest równy 0.