ITALIAN VERSION HERE.
Completely made in Italy but used in the entire world, Arduino is one of the most famous existing single-board microcontroller, it allows us to execute a lot of operations and so it is largely used in the development and prototyping of various devices.
One of the possible application that we can make of Arduino is to use it as a converter: we can convert the Play Station 2 controller into a fully compatible PC or PS3 controller.
WARNING: this tutorial is to be considered for illustrative purposes only. We don’t assume any responsability for any possible damage caused.
Let’s start! First, take all the necessary:
- Arduino Uno (Leonardo and Mega are also good): if you haven’t already bought it, and you want only to convert your PS2 controller, don’t do it. Converters are avaiable on the net (especially eBay) for few bucks.
- Arduino IDE.
- Library/firmware UnoJoy: you can download it from Google Code, selecting your OS and your Arduino model.
- PS2X library: created by Bill Porter, it is avaiable for download from his site (there is a “Download PS2X” link).
- Breadboard (optional but highly recommended)
- A 10kOhm resistor.
- And, of course, a PS2 controller that you no longer need (it is advisable to cut the connector, even if you can avoid it).
A little opening warning: the vibration won’t work (it requires the use of transistors).
FIRST STEP: let’s do the wiring!
It’s good to know that the PS2 controller has 9 wires (or 8, for the latest) that could differ in color.
The most common colors are the following (of which you can find an image on Curious Inventer):
White: unknown function (it is the missing cable on the 8-wires controllers)
Grey: vibration.
Green: acknowledge, it is used in communication between controller and PS2, we don’t need it.
BLACK: it is the common ground cable.
RED:it is the positive DC supply (3.3V).
BROWN: it is the data cable used by the controller to send data to the Play Station.
ORANGE: it is the “command”, used by the Play Station to send commands to the controller.
YELLOW: “attention”.
BLUE: it is the clock, we use it for establishing the correct data transmission speed.
Well, now we have to make the wiring: take the breadboard and the 10kOhm resistor and let’s start.
These are the connections that we need and as you can see they are pretty simple.
I have also made a Fritzing scheme (the green water is the orange wire).
So, we have to take a wire, strip it and wrap the conductive material around one side of the two jumpers (leaving the other free) and put it on the breadboard. Repeat this operation for all the used wires (they are six) leaving between them 2 free breadboard holes to avoid short circuits. Then link the wires following my same order (black, red, brown, orange, yellow and blu) to avoid bad connections.
Take the black cable on the other jumper side (the one we left free) and link it to one of the GND PINs on Arduino. Then take the 10kOhm resistor and put it on the breadboard (as in the images) and connect the red wire to one resistor side and, with another jumper, connect in series the 3.3V (on the same resistor side, check images if you haven’t understood). On the other resistor side, connect the brown cable (in my image, it is the green jumper) and in series connect it to PIN 11 (watch the scheme).
After that, connect the orange wire to PIN 9, the yellow one to PIN 8 and the blue one to PIN 10.
We have finished the wiring!
[banner]
SECOND STEP: Coding
Now we arrived to a crucial point: the Arduino program coding!
Open the Arduino IDE and import the PS2X library (that we already downloaded and unpacked). We have to click Sketch >> Import Library >> Add Library and then select the folder PS2X_lib.
Ok, now open the UnoJoy folder (or LeoJoy or MegaJoy). There is a folder called “UnoJoyArduinoSample“, that contains a .ino and a .h file, copy and paste it and rename the duplicate file just created as you like, I called it playstation.
Open the playstation folder and rename the .ino file in playstation.ino, after that read the ino with the IDE. Delete all the code (CTRL+A and then CANC) and paste the following (you can download the file here)
[c]
#include “UnoJoy.h”
#include <PS2X_lib.h>
#define PS2_DAT 11 //14
#define PS2_CMD 9 //15
#define PS2_SEL 8 //16
#define PS2_CLK 10 //17
//#define pressures true
#define pressures false
//#define rumble true
#define rumble false
PS2X ps2x;
int error = 0;
byte type = 0;
byte vibrate = 0;
void setup(){
setupPins();
setupUnoJoy();
}
void loop(){
// Always be getting fresh data
dataForController_t controllerData = getControllerData();
setControllerData(controllerData);
error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
}
void setupPins(void){
// Set all the digital pins as inputs
// with the pull-up enabled, except for the
// two serial line pins
for (int i = 2; i <= 12; i++){
pinMode(i, INPUT);
digitalWrite(i, HIGH);
}
pinMode(A4, INPUT);
digitalWrite(A4, HIGH);
pinMode(A5, INPUT);
digitalWrite(A5, HIGH);
}
dataForController_t getControllerData(void){
// Set up a place for our controller data
// Use the getBlankDataForController() function, since
// just declaring a fresh dataForController_t tends
// to get you one filled with junk from other, random
// values that were in those memory locations before
dataForController_t controllerData = getBlankDataForController();
// Since our buttons are all held high and
// pulled low when pressed, we use the “!”
// operator to invert the readings from the pins
ps2x.read_gamepad(false, vibrate);
controllerData.triangleOn = ps2x.Button(PSB_TRIANGLE);
controllerData.circleOn = ps2x.Button(PSB_CIRCLE);
controllerData.squareOn = ps2x.Button(PSB_SQUARE);
controllerData.crossOn = ps2x.Button(PSB_CROSS);
controllerData.dpadUpOn = ps2x.Button(PSB_PAD_UP);
controllerData.dpadDownOn = ps2x.Button(PSB_PAD_DOWN);
controllerData.dpadLeftOn = ps2x.Button(PSB_PAD_LEFT);
controllerData.dpadRightOn = ps2x.Button(PSB_PAD_RIGHT);
controllerData.l1On = ps2x.Button(PSB_L1);
controllerData.r1On = ps2x.Button(PSB_R1);
controllerData.selectOn = ps2x.Button(PSB_SELECT);
controllerData.startOn = ps2x.Button(PSB_START);
controllerData.l2On = ps2x.Button(PSB_L2);
controllerData.l3On = ps2x.Button(PSB_L3);
controllerData.r2On = ps2x.Button(PSB_R2);
controllerData.r3On = ps2x.Button(PSB_R3);
// Set the analog sticks
// Since analogRead(pin) returns a 10 bit value,
// we need to perform a bit shift operation to
// lose the 2 least significant bits and get an
// 8 bit number that we can use
controllerData.leftStickX = ps2x.Analog(PSS_LX), DEC;
controllerData.leftStickY = ps2x.Analog(PSS_LY), DEC;
controllerData.rightStickX = ps2x.Analog(PSS_RX), DEC;
controllerData.rightStickY = ps2x.Analog(PSS_RY), DEC;
// And return the data!
return controllerData;
}
[/c]
After that verify and upload it to Arduino.
If there are problems during the compilation, for a missing folder, try to do Sketch >> Import librery >> PS2X_lib.
If the compiler continues to give you errors, try to look for the problem and send a comment: I’ll be happy to help you!
Well, save and close the IDE and open the UnoJoy folder. There is a subfolder named “UnoJoyProcessingVisualizer“, open it and run the executable file.
A windows will pop up showing a joystick: select the right COM port and test if the controller is working properly. If no, chek the wiring!
THIRD STEP: transform Arduino into a Joystick/Controller
We arrived at the last step: the most decisive.
Now we are going to modify the Arduino’s USBtoSerial chip, the Atmega16U2 or the Atmega8U2 (the one near the USB port)
I want to remember that I won’t assume any responsability for any damage caused and I would like to specify that this is a risky operation that can harm your Arduino (it couldn’t work anymore).
The Arduino DFU mode requires sometimes a modification to the chip consisting of the addition of a resistor, I suggest you to inform yourselves about the DFU mode of your Arduino’s model before proceeding.
First thing you have to do is to install the drivers (they are in the Drivers folder), then, if you use windows, you have to install Atmel’s FLIP.
Next, you have to put Arduino in DFU mode (at your own risk). You can do this by shortcircuiting the 2 pin nearest the USB (see the picture).
After that, your Arduino should be recognized as Atmega16U2 (or Atmega8U2). If it won’t try reinstalling the drivers.
In the DFU mode, open the UnoJoy folder and execute TurnIntoAJoystick. After few seconds you have to press a key (as requested) and next you have to unplug and replug the USB cable. Now your PS2 controller is working also on PC and PS3!
Here are some screens showing its behaviour:
The Axis works also well, of course.
BACK TO ARDUINO
When you want to turn back to Arduino, the only thing you need to do is to put the Arduino in DFU mode, execute TurnIntoAnArduino (into UnoJoy folder), wait for few seconds and then reconnect the USB: Arduino is back!
Don’t hesitate to comment if you have problems, we will try to resolve them!