|
Controllare Arduino con un joypad della Playstation 2

Materiale occorrente:
- Joypad ps2 (anche della Psx va bene, non vanno bene quelli della Ps3)
- Arduino
- Generatore da 9 volt
- #2 resitenze da 1K (Di Pull-Up)
- Breadboard
Collegamenti

Codice Arduino
Per prima cosa dovrete installare la libreria GPSX che troverete a questo link.
Le librerie arduino si installano molto semplicemente, una volta scaricato l'archivio lo dovrete scompattare in una cartella e nominarla GPSX.
Dentro questa cartella ci devono essere i seguenti files:
- GPSX.c
- GPSX.h
- GPSXClass.cpp
- GPSXClass.h
- keywords.txt
- README_en.txt
- README_ja.txt
- Schematic.bmp
Ora potrete fare una scelta, se volete seguire lo schema sopra dovrete editare la libreria GPSX.c con un editor di testo (notepad e gedit vanno benissimo).
Una volta aperto nel file sostituite le seguenti righe
#define DAT_PIN 7 // CTL1 Data
#define CMD_PIN 6 // CTL2 Command
// CTL3 9V for Motor (Optional)
// CTL4 GND
// CTL5 VCC
#define AT1_PIN 5 // CTL6 Attention (PAD1)
#define CLK_PIN 4 // CTL7 Clock
// CTL8 N/C
#define ACK_PIN 3 // CTL9 ACK
#define AT2_PIN 2 // CTL6 Attention (PAD2) per un eventuale secondo joypad
con
#define DAT_PIN 2 // CTL1 Data
#define CMD_PIN 3 // CTL2 Command
// CTL3 9V for Motor (Optional)
// CTL4 GND
// CTL5 VCC
#define AT1_PIN 4 // CTL6 Attention (PAD1)
#define CLK_PIN 5 // CTL7 Clock
// CTL8 N/C
#define ACK_PIN 6 // CTL9 ACK
#define AT2_PIN 9 // CTL6 Attention (PAD2) per un eventuale secondo joypad
Salvate il file e assicuratevi che l'estenzione sia sempre .c poi copiate la cartella GPSX contenente tutti i files nella cartella libraries dentro la cartella arduino-00xx.
Ora potete aprire arduino e controllare nel menù->sketchbook->import libraries se la libreria è stata installata correttamente.
Istruzioni della libreria GPSX
La libreria GPSX è in grado di gestire 2 joypad sulla stessa linea semplicemente connettendo connettendo il pin AT della seconda manopola al pin 9 di arduino e connettere insieme gli altri bit delle 2 manopole.
I tasti che possono essere premuti sul joypad, definiti dalla libreria, sono :
- SELECT(padNo)
- LEFT(padNo)
- DOWN(padNo)
- RIGHT(padNo)
- UP(padNo)
- START(padNo)
- STICK_RIGHT(padNo)
- STICK_LEFT(padNo)
- SQUARE(padNo)
- CROSS(padNo)
- IRCLE(padNo)
- TRIANGLE(padNo)
- R1(padNo)
- L1(padNo)
- R2(padNo)
- L2(padNo)
I pulsanti sono considerati in 3 casi:
- Vengono premuti, quindi l'istruzione sarà PRESSED_nometasto(padNo) e l'istruzione restituirà un 1 se è vera uno 0 se è falsa.
- Stanno premuti, quindi l'istruzione sarà IS_DOWN_nome tasto(padNo) e l'istruzione restituirà un 1 se è vera o uno 0 se è falsa Es. while(IS_DOWN_SQUARE(PSX_PAD1) ==1){ //fai qualcosa} Arduino fa qualcosa dentro al loop while fin quando il tasto quadrato rimane premuto.
- Vengono rilasciati, quindi l'istruzione sarò RELEASED_nome tasto(padNo) e l'istruzione restituirà un 1 se è vera o uno 0 se è falsa.
Inolte possiamo leggere dati analogici dai due joystick sulla manopola lungo i 2 assi, i valori restituiti dalle seguenti istruzioni varieranno da 0 a 255.
- ANALOG_RIGHT_X(padNo)
- ANALOG_RIGHT_Y(padNo)
- ANALOG_LEFT_X(padNo)
- ANALOG_LEFT_Y(padNo)
Nelle manopole della playstation 2 ci sono 2 motori (Dual Shock) ed è possibile abilitarli e disabilitarli. Un motore da una vibrazione più forte mentre l'altro da una vibrazione più lieve.
- PSX.motorEnable(padNo, Motor1Enable, Motor2Enable)
Gli attributi di questa funzione sono:
- padNo = PSX_PAD1 | PSX_PAD2
- Motor1Enable = MOTOR1_ENABLE | MOTOR1_DISABLE
- Motor2Enable = MOTOR2_ENABLE | MOTOR2_DISABLE
La vibrazione è regolabile via software con una semplice istruzione.
- PSX.motor(padNo, Motor1OnOff, uint8_t Motor2Speed)
Attributi:
- padNo = PSX_PAD1 | PSX_PAD2
- Motor1OnOff = MOTOR1_ON | MOTOR1_OFF
- Motor2Speed = uint8_t che assumerà il valore zero se sarà uguale a 0x00 fino ad arrivare a 255 se posto uguale a 0xFF.
Possiamo infine decidere via software se usare la manopola in modalità digitale, (quindi il joystick sinistrò avrà lo stesso effetto di freccia sù, freccia giù, sinistra destra, e il joystick sinistro avrà lo stesso effetto di triangolo, cerchio quadrato e x), oppure in modalità analogica quindi i joystick, se mossi, restituiranno un valore analogico come visto nella funzione precedente (ANALOG_xxx_YYY_asse(padNo)).
- PSX.mode(padNo, mode, lock)
Attributi:
- padNo = PSX_PAD1 | PSX_PAD2
- mode = MODE_DIGITAL | MODE_ANALOG
- lock = MODE_UNLOCK | MODE_LOCK
Arduino Code
Testate il vostro circuito con questo sketch per vedere se tutto funziona propriamente. Includete la libreria GPSX.h
#undef round //serve per non far fallire la compilazione
int asd =0;
void setup()
{
Serial.begin(9600);
PSX.mode(PSX_PAD1, MODE_ANALOG, MODE_LOCK);
PSX.motorEnable(PSX_PAD1, MOTOR1_ENABLE, MOTOR2_ENABLE);
// Poll current state once.
PSX.updateState(PSX_PAD1);
}
void loop()
{
PSX.updateState(PSX_PAD1);
int data1 = ANALOG_RIGHT_X(PSX_PAD1);
int data2 = ANALOG_RIGHT_Y(PSX_PAD1);
int data3 = ANALOG_LEFT_X(PSX_PAD1);
int data4 = ANALOG_LEFT_Y(PSX_PAD1);
if (IS_DOWN_CIRCLE(PSX_PAD1)) {
PSX.motor(PSX_PAD1, MOTOR1_ON, ANALOG_RIGHT_X(PSX_PAD1));
}
if (PRESSED_CIRCLE(PSX_PAD1)) {
Serial.println("Pressed circle");
}
if (RELEASED_CIRCLE(PSX_PAD1)) {
Serial.println("Released circle");
PSX.motor(PSX_PAD1, MOTOR1_OFF, 0);
}
if (PRESSED_SQUARE(PSX_PAD1)) {
Serial.println("Pressed square");
PSX.mode(PSX_PAD1, MODE_DIGITAL, MODE_UNLOCK);
}
if (RELEASED_SQUARE(PSX_PAD1)) {
Serial.println("Released square");
}
if (PRESSED_CROSS(PSX_PAD1)) {
Serial.println("Pressed cross");
PSX.mode(PSX_PAD1, MODE_ANALOG, MODE_UNLOCK);
PSX.motorEnable(PSX_PAD1, MOTOR1_ENABLE, MOTOR2_ENABLE);
}
if (RELEASED_CROSS(PSX_PAD1)) {
Serial.println("Released cross");
}
if (IS_DOWN_TRIANGLE(PSX_PAD1)) {
PSX.motor(PSX_PAD1,MOTOR1_ON ,ANALOG_LEFT_X(PSX_PAD1));
}
if (PRESSED_TRIANGLE(PSX_PAD1)) {
Serial.println("Pressed triangle");
}
if (RELEASED_TRIANGLE(PSX_PAD1)) {
Serial.println("Released triangle");
PSX.motor(PSX_PAD1, MOTOR1_OFF, 0x00);
}
if (PRESSED_UP(PSX_PAD1)) {
Serial.println("Pressed Up");
}
if (RELEASED_UP(PSX_PAD1)) {
Serial.println("Released Up");
}
if (PRESSED_DOWN(PSX_PAD1)) {
Serial.println("Pressed Down");
}
if (RELEASED_DOWN(PSX_PAD1)) {
Serial.println("Released Down");
}
if (PRESSED_LEFT(PSX_PAD1)) {
Serial.println("Pressed Left");
}
if (RELEASED_LEFT(PSX_PAD1)) {
Serial.println("Released Left");
}
if (PRESSED_RIGHT(PSX_PAD1)) {
Serial.println("Pressed Right");
}
if (RELEASED_RIGHT(PSX_PAD1)) {
Serial.println("Released Right");
}
if (PRESSED_CROSS(PSX_PAD1)) {
Serial.println("Pressed cross");
PSX.mode(PSX_PAD1, MODE_ANALOG, MODE_UNLOCK);
PSX.motorEnable(PSX_PAD1, MOTOR1_ENABLE, MOTOR2_ENABLE);
}
if (RELEASED_CROSS(PSX_PAD1)) {
Serial.println("Released cross");
}
if (IS_DOWN_TRIANGLE(PSX_PAD1)) {
PSX.motor(PSX_PAD1, MOTOR1_ON, ANALOG_LEFT_X(PSX_PAD1));
}
if (PRESSED_TRIANGLE(PSX_PAD1)) {
Serial.println("Pressed triangle");
}
if (RELEASED_TRIANGLE(PSX_PAD1)) {
Serial.println("Released triangle");
PSX.motor(PSX_PAD1, MOTOR1_OFF, 0x00);
}
if (PRESSED_R2(PSX_PAD1)) Serial.println("Pressed R2");
if (RELEASED_R2(PSX_PAD1)) Serial.println("Released R2");
if (PRESSED_R1(PSX_PAD1)) Serial.println("Pressed R1");
if (RELEASED_R1(PSX_PAD1)) Serial.println("Released R1");
if (PRESSED_L2(PSX_PAD1)) Serial.println("Pressed L2");
if (RELEASED_L2(PSX_PAD1)) Serial.println("Released L2");
if (PRESSED_L1(PSX_PAD1)) Serial.println("Pressed L1");
if (RELEASED_L1(PSX_PAD1)) Serial.println("Released L1");
if (PRESSED_SELECT(PSX_PAD1)) Serial.println("Pressed Select");
if (RELEASED_SELECT(PSX_PAD1)) Serial.println("Released Select");
if(PRESSED_STICK_RIGHT(PSX_PAD1)){
Serial.println("analog right x= ");
Serial.println(data1);
Serial.println("analog right y= ");
Serial.println(data2);
}
if(RELEASED_STICK_RIGHT(PSX_PAD1)) Serial.println("Released Right Stick");
if(PRESSED_STICK_LEFT(PSX_PAD1)){
Serial.println("analog left x= ");
Serial.println(data3);
Serial.println("analog left y= ");
Serial.println(data4);
}
if(RELEASED_STICK_LEFT(PSX_PAD1)) Serial.println("Released Left Stick");
if(PRESSED_START(PSX_PAD1)){
Serial.println("analog right x= ");
Serial.println(data1);
Serial.println("analog right y= ");
Serial.println(data2);
Serial.println("analog left x= ");
Serial.println(data3);
Serial.println("analog left y= ");
Serial.println(data4);
}
if(RELEASED_START(PSX_PAD1))
Serial.println("Released Start");
}
In questo video è spiegato cosa fa il programma
In foto il circuito fatto da me. Nella scatolina trasparente si trova un LM7809 che mi abbassa la tensione di un generatore da 12V a 9V, dato che non avevo un alimentatore a 9V.

Liberamente tratto dal playground inglese di arduino e riadattato da Calamaro.
![]()