Commodore Amiga to komputer, który czasy świetności ma już za sobą. Mało kto kojarzy, że w ogóle istniał taki komputer. Do dzisiejszego dnia są jednak ludzie, którzy z nostalgią uruchamiają trzydziestoletnie urządzenia, żeby przypomnieć sobie czasy młodości;) Naturalne zużycie sprzętu powoduje, że kolejne podzespoły odmawiają posłuszeństwa. Najbardziej narażone na uszkodzenia są mysz oraz klawiatura jako urządzenia mechaniczne. W poniższym artykule opiszę w jaki sposób podłączyć myszkę PS/2 do naszej przyjaciółki.
Na początek ważna informacja. Myszka PS/2 została celowo wybrana, ponieważ dużo modeli jest w chwili obecnej w sprzedaży, są relatywnie tanie i co najważniejsze proste w obsłudze (oczywiście programowej). Myszka podłączona do USB jest dzisiaj standardem, niestety oprogramowanie takiej myszki jest trudniejsze, a na pewno droższe od strony wykorzystania sprzętu.
UWAGA!!! Nie ponoszę odpowiedzialności za ewentualne szkody związane z wykonaniem poniższego urządzenia. Wszelkie modyfikacje sprzętowo programowe wykonujecie na własną odpowiedzialność.
Krok 1 - niezbędne materiały
Do zbudowania interfejsu niezbędne będą cztery komponenty:
- Dowolny egzemplarz Arduino (ze względu na gabaryty polecam wersję Nano lub ProMini),
- Złącze Cannon D-SUB DB9 - żeńskie
- Obudowa Canon D-SUB DB9
- Gniazdo PS/2 (na kabel)
Dodatkowo przyda się lutownica i kilkanaście centymetrów przewodu połączeniowego. Układ Arduino może być w tym przypadku dowolny. Jeżeli zależy nam na miniaturyzacji, to warto skorzystać z wersji Nano, Micro lub ProMini.
Krok 2 - podłączenie elementów
Trochę teorii na początek. W przypadku Amigi możemy podłączyć zamiennie myszkę lub joystick do dowolnego portu. W zależności od podłączonego urządzenia piny spełniają określone funkcje. W poniższej tabelce przedstawiono poszczególne wykorzystywane sygnały:
Numer pinu | Nazwa sygnału |
1 | V |
2 | H |
3 | VQ |
4 | HQ |
5 | MIDDLE_BTN |
6 | LEFT_BTN |
7 | VCC(+5V) |
8 | GND |
9 | RIGHT_BTN |
Piny 7 i 8 to zasilanie układów myszki, piny 1,3 oraz 2,4 to informacja o kierunku przesuwania myszki (w pionie i poziomie). Sygnał jest aktywny, gdy jest zwarty do masy. Pin 6 to lewy przycisk myszy. Pin 9 to prawy przycisk myszy, a pin 5 to środkowy przycisk. W przeciwieństwie do joysticka myszka przesyła informację o położeniu wykorzystując pary sygnałów V-VQ oraz H-HQ. Kierunek wyznaczany jest na zasadzie sprawdzenia który sygnał nastąpi pierwszy (V czy VQ lub odpowiednio H czy HQ). Odległość określa się na podstawie ilości zmian sygnałów. Jest to proste w implementacji sprzętowej. Listę połączeń przedstawiono w tabelce poniżej:
Nazwa sygnału | Złącze D-SUB | Arduino |
V | 1 | D9 |
H | 2 | D8 |
VQ | 3 | D7 |
HQ | 4 | D6 |
MIDDLE_BTN | 5 | D10 |
LEFT_BTN | 6 | D5 |
VCC(+5V) | 7 | 5V |
GND | 8 | GND |
RIGHT_BTN | 9 | D4 |
Pora na połączenie od strony myszki PS/2. Złącze PS/2 to złącze 6-pinowe. W tabeli przedstawiono funkcje poszczególnych pinów.
Nr pinu | Nazwa sygnału |
1 | Data |
2 | - |
3 | GND |
4 | VCC |
5 | CLK |
6 | - |
Gniazdo PS/2 połączymy z Arduino za pomocą czterech przewodów. Musimy dostarczyć zasilanie do myszki PS/2 oraz obsłużyć transmisję na liniach Data/CLK. W tabelce poniżej przedstawiono połączenie gniazda PS/2 z układem Arduino.
Nazwa sygnału | Gniazdo PS/2 | Arduino |
Data | 1 | D3 |
- | 2 | - |
GND | 3 | GND |
VCC | 4 | VCC |
CLK | 5 | D2 |
- | 6 | - |
Do wykonania połączeń wykorzystujemy dostępne materiały - ja skorzystałem z kawałka skrętki do podłączenia Arduino z gniazdem D-SUB (nie podłączyłem sygnału środkowego przycisku, który w standardowej myszy Amigi nie występował). Z drugiej strony wykorzystałem gniazdo PS/2 z zarobionym fabrycznie kablem, ponieważ dysponowałem takim kabelkiem po uszkodzonej przejściówce USB-PS/2. Normalnie należy polutować przewód do złącza PS/2, a z drugiej strony do Arduino. Warto mieć na uwadze również inną praktyczną rzecz: Nie ma większego znaczenia jakie piny Arduino wykorzystamy do podłączenia złącza D-SUB. Ważne, aby zgodnie z rzeczywistym połączeniem przypisać sygnały w programie.
Po wykonaniu połączeń i sprawdzeniu ich poprawności możemy przystąpić do napisania programu, który ożywi nasze dzieło...
Krok 3 - software
Pora na napisanie programu, który odczyta dane z myszki i przetworzy je na postać zrozumiałą dla Amigi. W pierwszym kroku musimy zaopatrzyć się w bibliotekę, która wykona większość skomplikowanych operacji za nas. Ściągamy ze strony GitHub bibliotekę PS2-Mouse-Arduino i dodajemy ją do naszego środowiska ArduinoIDE. Następnie przechodzimy do napisania prostego programu.
#include <PS2Mouse.h>
#include <EEPROM.h>
#define MOUSE_DATA 3
#define MOUSE_CLOCK 2
#define LMB 5
#define RMB 4
#define MMB 10
#define H 8
#define HQ 6
#define V 9
#define VQ 7
int x=0,y=0,prescaler;
PS2Mouse mouse(MOUSE_CLOCK, MOUSE_DATA, STREAM);
void setup()
{
prescaler=EEPROM.read(0);
if(!prescaler)prescaler=8; //wstępne ustawienie
pinMode(LMB,OUTPUT);
pinMode(RMB,OUTPUT);
pinMode(MMB,OUTPUT);
pinMode(V,OUTPUT);
pinMode(VQ,OUTPUT);
pinMode(H,OUTPUT);
pinMode(HQ,OUTPUT);
digitalWrite(LMB,HIGH);
digitalWrite(RMB,HIGH);
digitalWrite(MMB,HIGH);
digitalWrite(V,HIGH);
digitalWrite(VQ,HIGH);
digitalWrite(H,HIGH);
digitalWrite(HQ,HIGH);
mouse.initialize();
mouse.set_sample_rate(200);
mouse.set_sample_rate(100);
mouse.set_sample_rate(80);
}
void loop()
{
int data[4];
mouse.report(data);
if(data[0]& 7)EEPROM.write(0,prescaler);
else if(data[0]& 3)prescaler=EEPROM.read(0);
if(data[0]& 1) digitalWrite(LMB,LOW);else digitalWrite(LMB,HIGH);
if(data[0]& 2) digitalWrite(RMB,LOW);else digitalWrite(RMB,HIGH);
if(data[0]& 4) digitalWrite(MMB,LOW);else digitalWrite(MMB,HIGH);
if((data[0]& 4)&&(data[3])){
if(data[3]==1)
prescaler--;
else
prescaler++;
if(prescaler<1)prescaler=1;
if(prescaler>30)prescaler=30;
}
x=x+data[1];
y=y+data[2];
while(x>prescaler) {
x=x-prescaler;
digitalChange(H);
digitalChange(HQ); }
while(x<-prescaler) {
x=x+prescaler;
digitalChange(HQ);
digitalChange(H);
}
while(y<-prescaler) {
y=y+prescaler;
digitalChange(V);
digitalChange(VQ);
}
while(y>prescaler) {
y=y-prescaler;
digitalChange(VQ);
digitalChange(V);
}
}
void digitalChange(byte nr_pinu){
const PROGMEM byte pin[]={1,2,4,8,16,32,64,128};
if(nr_pinu<8)
PORTD ^=pin[nr_pinu];
if(nr_pinu>7)
PORTB ^=pin[nr_pinu-8];
delayMicroseconds(4);
}
Przedstawiona wersja kodu jest prymitywna, ale działająca. W celu przyspieszenia funkcjonowana myszy napisałem prostą funkcję digitalChange, która zmienia stan podanego pinu na przeciwny. Oryginalna funkcja digitalWrite jest zbyt wolna, co przekłada się na spowolnienie ruchu myszki na ekranie. Dodatkowym problemem jest cykliczny odczyt danych z myszy, co powoduje, że nie zawsze jesteśmy w stanie przenieść dokładnie ruch do wejścia Amigi. W obecnej wersji kodu czas pomiędzy impulsami H,HQ oraz V,VQ jest stały. W rzeczywistości zależy od prędkości przesuwania myszki. W kolejnej wersji programu zostanie to poprawione. Zdefiniowałem zmienną prescaler, która umożliwia określenie rozdzielczości myszki. W zależności od fizycznej rozdzielczości myszy i rozdzielczości ekranu możemy dopasować proporcje. Wartość prescalera przechowywana jest w pamięci EEPROM. Wstępnie zdefiniowaną wartość można w dowolnym momencie zmienić poprzez naciśnięcie rolki myszki i przeskrolowanie w odpowiednim kierunku. W każdej chwili można powrócić do zapisanego w EEPROM-ie ustawienia poprzez jednoczesne wciśnięcie lewego i prawego przycisku myszy. Zapis nowej wartości do EEPROM następuje po naciśnięciu rolki, a następnie lewego i prawego przycisku.
Uwaga!!! Funkcja digitalChange zostala napisana wyłącznie z myślą o powyższym projekcie. Nie każdy pin da się zmienić (działają piny 0-13, analogowe nie), dodatkowo funkcja nie będzie poprawnie działała na mikrokontrolerach Atmega32u4, czyli płytki Leonardo i Micro będą funkcjonowały nieprawidłowo.
Podsumowanie
Arduino umożliwia podłączenie nowej myszki do komputera Amiga. Myszka sprawuje się całkiem dobrze, nie ma problemów z zacinającą się kulką, a w przypadku uszkodzenia bez problemu możemy wymienić myszkę na inny egzemplarz.