Edoardo Vignali
Controllare Arduino con un controller della Play Station 2
Tutorials -
Martedì 27 Aprile 2010 15:39
Scritto da Edoardo Vignali

Controllare Arduino con un joypad della Playstation 2

Joypad

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

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.

Calamaro ps2

Liberamente tratto dal playground inglese di arduino e riadattato da Calamaro.

CC

 

Gioblu Robotics © 2010 - 2012 · Sitemap · privacy

gioscarab@gmail.com

Gioblu BOTServer è online dal 10 Aprile 2010 - 319.232 Visite - 1.027.175 Pagine visualizzate - 182.309 Visitatori unici - 536 utenti attivi