[070] Mysz w świecie Arduino - cz. 1

[070] Mysz w świecie Arduino - cz. 1

Poprzednie artykuły poruszały problem współpracy klawiatur pecetowych z Arduino. O tym jakie to może być pożyteczne nie będę przypominał – wszak mamy tu doskonałe urządzenie do wprowadzania tekstów lub do sterowań, gotowe do pracy i tanie. Naturalnym będzie przyjrzenie się teraz komputerowej myszy. I jak poprzednio, na początku skupimy się na myszach z interfejsem PS/2, bo ten zapewni nam współpracę z każdym modelem Arduino i nie będzie wymagać jakichkolwiek elementów dodatkowych. Myszy współczesne, ze złączem USB, będą współpracować z wybranymi płytkami Arduino albo – jeśli to potrafią – z przejściówką. Nimi także kiedyś się zajmę, na razie ograniczę się do wciąż dostępnych myszy z okrągłą wtyczką.


Zacznijmy od podstaw. Czym jest mysz, każdy wie. Zwykle przybiera kształty klasyczne, ale nie musi tak być. Odpuszczę zatem opis wyglądu urządzenia, skupiając się na danych wysyłanych przez nią. Myszka umożliwia określenie swojego położenia w dwóch płaszczyznach i w wersji minimum posiada dodatkowo dwa przyciski. Standard przewiduje użycie trzech przycisków, a kolejne jego rozwinięcia wprowadzają trzecią oś, którą wykorzystuje rolka przewijania. Realizacje bardziej rozbudowanych myszy wymykają się standardom i by móc korzystać z przycisków czwartego i następnych, potrzeba wiedzy o sposobie kodowania tych informacji.

Dla przykładu ta mysz została zaopatrzona w dwie rolki, które sprytnie wykorzystują wspólny bajt trzeciej osi, ale już dwa dodatkowe przyciski nie są widoczne dla biblioteki, której dziś tu użyję. Ale do tego wrócimy za chwilę. Podsumowując: klasyczna mysz dostarcza następujących informacji: stanu wciśnięcia jednego z trzech przycisków i szybkości poruszania się wzdłuż dwóch osi. Istotne jest to, by rozróżnić tę ostatnią wielkość od informacji o położeniu. Zauważmy, że mysz nie wie gdzie jest, tylko z jaką szybkością się przesuwa. To gdzie się znajduje i w związku z tym, gdzie rysować kursor na ekranie komputera, to już zadanie programu interpretującego te dane.

Wymienione informacje są pakowane do trzech bajtów, przy czym dwa ostatnie zawierają dane o szybkości poruszania się myszy, a pierwszy – stany przycisków, zwrot wektora przesuwu oraz przepełnienie, tzn. szybkość powyżej maksymalnej wykrywalnej przez mysz. W przypadku rozszerzenia standardu do czterech bajtów, którą zapoczątkował Microsoft w serii IntelliMouse, w ostatnim przechowuje się informację o rolce i dwóch kolejnych przyciskach.

Realizacja sprzętowa przesyłanych danych jest podobna do tej, o której pisałem w artykułach poświęconych klawiaturze. Mamy tu więc identyczne gniazdo z tak samo rozmieszczonymi sygnałami: masą, zasilaniem oraz linią danych i zegara.

Jednak transmisja różni się zdecydowanie i w zasadzie w pecetach nie można było sobie podłączać myszy do portu klawiatury. Stąd ustalone standardowe kolory, ten dla myszy jest turkusowy. Transmisja jest synchroniczna, o szybkości kilkunastu kilobodów. W zasadzie to mysz nadaje, ale może także odebrać kilka komend konfiguracyjnych. Nie jest to jednak dla nas istotne. Ważne jest to, że interfejs ten nie ma obowiązku resetować się samoczynnie, więc operacje przyłączania myszy winno się przeprowadzać po wyłączeniu zasilania. W szczególności przełączanie myszy bez resetowania systemu może wprowadzać tryby pracy uboższe dla danego egzemplarza, zależne również od tego, co było podłączone w chwili startu systemu. Tak było w przypadku myszy widocznej na zdjęciu powyżej, rolki pozostawały martwe do chwili jej inicjacji, choć podstawowe funkcje działały.

Wykorzystam sobie przejściówkę, która już wystąpiła z klawiaturą, którą to podłączę bezpośrednio do płytki edukacyjnej TME.

Poza tym nie użyjemy żadnego dodatkowego elementu. Nie powiedziałem ani słowa o tym jak mysz jest zbudowana, więc tylko wspomnę: wewnątrz znajdziemy mechanizm zamieniający ruch na ciąg danych. Może być on mechaniczny – jak tutaj, wprawiający w obroty obracającą się kulką dwa enkodery optyczne umieszczone względem siebie prostopadle.

Szybkość obrotu świadczy o szybkości przesuwania się myszy. Dodatkowe rolki pracują na tej samej zasadzie, przy czym w tanich myszach stosuje się enkodery mechaniczne, które zużywają się szybko i denerwują, powodując skakanie obrazu podczas przewijania. Przyciski to najczęściej mikroprzełączniki, trwałe tylko w przypadku myszy lepszej klasy. Całość nadzorowana jest mikrokontrolerem i zasilana napięciem przychodzącym z komputera. Myszy optyczne zamiast rolek wykorzystują rodzaj małej kamery o niskiej rozdzielczości, która na podstawie różnic kolejnych obrazów wyznacza kierunek przesuwania. Jak wszyscy wiemy, od dawna już używa się wyłącznie tego typu myszy.

Czas na szkice. Przyjrzymy się dwóm, pierwszy zapozna nas z możliwościami biblioteki w ogóle, drugi natomiast będzie już bardziej praktyczny, ale na tym etapie będzie stanowił jedynie wstęp do jakiegoś konkretnego zastosowania. Zacznijmy zatem od rzeczy prostej. Standardowe minimum nie jest skomplikowane do zrealizowania na piechotę, ale po co, skoro mamy sprawne biblioteki oferujące coś jeszcze. Dlatego po przyjrzeniu się kilku wybrałem wygodną i niespecjalnie żarłoczną PS2MouseHandler. Nie znajdziemy jej w zestawie, dlatego bez ściągnięcia z sieci nie obejdzie się. Następnie zawartość katalogu trzeba skopiować ręcznie do katalogu bibliotek Arduino i to wszystko.

#include <PS2MouseHandler.h>                                       // Biblioteka obsługi myszy PS/2
#define MOUSE_DATA 5                                               // Linia DATA
#define MOUSE_CLOCK 6                                              // Linia CLCK
PS2MouseHandler mouse(MOUSE_CLOCK, MOUSE_DATA, PS2_MOUSE_REMOTE);  // Inicjuj bibliotekę.

void setup() {
  Serial.begin(115200);                     // Inicjuj monitor.
  if (mouse.initialise() != 0) {            // Inicjuj mysz.
    Serial.println("Nierozpoznana mysz.");  // Komunikat błędu.
  }
}
void loop() {
  mouse.get_data();  // Pobierz status myszy.

  Serial.print("A:");  // Przycisk pierwszy.
  Serial.print(mouse.button(0));
  Serial.print("/");
  Serial.print(mouse.clicked(0));

  Serial.print(" B:");  // Przycisk drugi.
  Serial.print(mouse.button(1));
  Serial.print("/");
  Serial.print(mouse.clicked(1));

  Serial.print(" C:");  // Przycisk trzeci.
  Serial.print(mouse.button(2));
  Serial.print("/");
  Serial.print(mouse.clicked(2));

  Serial.print(" X=");  // Szybkość przesuwania w osi X
  Serial.print(mouse.x_movement());

  Serial.print(" Y=");  // Szybkość przesuwania w osi Y
  Serial.print(mouse.y_movement());

  Serial.print(" Z=");  // Szybkość przesuwania w osi Z (scroll)
  Serial.print(mouse.z_movement());

  Serial.print(" ID:");  // Numer ID, zwykle 250
  Serial.print(mouse.device_id());

  Serial.print(" STATUS:");  // Bajt statusu.
  Serial.println(mouse.status(), BIN);

  delay(100);
}

W szkicu zaczynamy oczywiście od zaczytania biblioteki. Kolejno trzeba zadeklarować piny dla emulowanego portu PS/2 – w naszym przypadku DATA to 5, CLOCK - 6 i inicjujemy pracę biblioteki. Szkic posłuży nam do przetestowania wszystkich danych wychodzących z myszy, więc do ich czytania użyjemy pokładowego monitora, zatem także należy go zainicjować. Następnie trzeba będzie zresetować mysz. Jeśli otrzymamy niezerową odpowiedź albo nie otrzymamy żadnej, wyświetlimy stosowny komunikat.

W pętli głównej będziemy pobierać status myszy, a następnie rozbierać go na kawałki i wysyłać do monitora. Pobieraniem zajmuje się instrukcja mouse.get_data() Ładuje ona dane w zestaw zmiennych, do których teraz możemy już dobierać się konkretnie i będziemy je wyświetlać jedną po drugiej. Przyciski nazwiemy sobie literami, od A do C. Mouse.button z numerem zwraca nam stan przycisku, a mouse.clicked ustawia się jednorazowo po jego wciśnięciu i zeruje przy następnym odpytaniu myszy. Zauważmy, że standardowo systemy operacyjne odpytują przyciski pierwszy i trzeci, drugi traktując po macoszemu.

Poniżej znajduje się sekcja analizy ruchu. Biblioteka obsługuje rozszerzony standard, więc przepytujemy tutaj trzy osie. Wartości X, Y i Z zwracają ośmiobitowe dane, choć na przykład mysz ze zdjęcia serwuje tylko siedem bitów. Wartości korespondują ściśle z szybkością przesuwania myszy, a znak przy nich oznacza kierunek jej przesuwania. W przypadku ostatniej zmiennej bywa różnie: w jednym przypadku nie było żadnej reakcji podczas kręcenia rolką, w innym rolki były dwie i zachowują się inaczej: ta od przewijania pionowego ustawia pierwszy bit tej zmiennej zawsze po wykryciu impulsu, druga rolka – drugi. Więc zmienna przyjmuje tylko wartości jeden bądź dwa ze znakiem zależnym od kierunku obrotu rolek. Wspomniane przyciski czwarty i piąty, mimo iż standard tak twierdzi, nie dawały żadnych śladów w transmisji.

Przedostatnią zmienną jest tzw. ID, które w przypadku kilku posiadanych przeze mnie myszy dało tę samą wartość równą 250, więc jest to zupełnie nieprzydatne. W końcu mamy STATUS, czyli pierwszy bajt komunikatu. Tutaj są kodowane wspomniane dane o stanie przycisków, kierunku ruchu i przepełnieniu, czyli przekroczeniu dozwolonej szybkości myszy. Przedstawiłem go w formie binarnej, bo tak jest czytelniej. Jak widać, trzeci bit zawsze jest jedynką.

Szkic ten pozwala zaspokoić ciekawość i zidentyfikować sprawność myszy. Przypomnę, że sporo myszy USB pracuje jako PS/2, przy czym linia danych to D-, a zegara – D+ Przy adaptacji własnej myszy zawsze należy sprawdzić zachowywanie się elementów ponadstandardowych, a więc drugiej rolki i kolejnych przycisków. W następnym artykule raz jeszcze spojrzymy na mysz, wykorzystując tym razem wyświetlacz obecny na płytce TME i spróbujemy zamienić dane o szybkości na informację o położeniu myszy.

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