WebbotLib AVR library
WebbotLib It just does it
  C++ documentation  C documentation

Sony/ps2.h

Adds support for the Sony Playstation PS2 controllers.
Thanks to 'Dunk' for his contributions, testing and patience. Other thanks to Bill Porter.
These controllers come with a 9 pin plug - which you will need to cut off and replace with your own header pin sockets.
ps2wiring.jpg
You will need to provide connections for 'ground' and 'power' - to power the device. The jury is out as to whether it should be 3.3V or 5V.
The other connections are the common SPI bus lines: MISO, MOSI and SCK and the Select wire needs to be connected to a digital I/O used to select the device.
The grey wire is optional depending on whether you want to use the rumble motors. If you want to use them then connect it to an unregulated supply voltage between 7.2v and 9v.
You can of course add as many controllers as you like - each controller requires its own unique Select pin but otherwise the connections are the same for every controller.
The controllers are operated over an SPI bus and so you can do this by using either the hardware SPI bus, spi.h, or by creating a software SPI bus using whichever pins you prefer, spisw.h.
When sharing the hardware SPI bus with an ISP programmer it is recommended that you add a pull up resistor on the Select line of the controller so that it doesn't interfere with the programmer when programming. Alternatively: only have either the controller or the programmer plugged in at any one time. If you are programming via a bootloader then this doesn't apply.
NB The controller is slightly flakey - so, for now, only use a software SPI bus as the hardware bus seems to work too fast for the controller.
To create a controller which is selected using F0 then use:
SONY_PS2 controller1 = MAKE_SONY_PS2(F0);
You are now ready to use the device - but you may want to look at the 'calibrate' and 'setAnalogMode' functions for further set up that you can call from appInitHardware.
If you wish to use the joysticks then you must place the controller into analog mode. This gives access to both the left and right joysticks as well as virtual joysticks using the D-pad buttons on the left and the shape buttons on the right.
Each joystick has two values: X and Y.
The joystick names all start with PS2_STICK_ and are defined in this H file.
Here is an example for the Axon and Axon II:-
// Create a controller SELECTed using F0
SONY_PS2 controller1 = MAKE_SONY_PS2(F0);
 
// Create a list of devices on the SPI bus
static SPI_DEVICE_LIST PROGMEM spiBus_list[] = {&controller1._device_};
 
// Create a software SPI Bus using:-
// B5 = MOSI, B6=MISO, B7=Clock
SPI_SW spiBus = MAKE_SW_SPI(spiBus_list,B5,B6,B7);
In appInitHardware we will initialise the SPI bus and then calibrate the joysticks which also sets analog mode:-
// Initialise the SPI bus
spiBusInit(&spiBus,true);
// Calibrate and set dead zone = 27
sonyPS2_calibrate(&controller1, 27);
In our main loop we read the controller:-
if(sonyPS2_read(&controller1)){
    // We can now test the buttons
    // and the joysticks
}

 

Function

 


boolean sonyPS2_calibrate(SONY_PS2* controller, uint8_t deadzone)

Calibrate the joysticks on the controller.
This command should only be called once - when your program starts up. It will activate the joysticks and then read their current positions and remember these as being the 'centre' locations. Without this call you may notice some non-zero readings from the joystick if it is not being set to the centre position.
You can also specify a 'deadzone' - ie the radius around the centre point that will be considered as being the centre. Try a value of around 27.
This will return TRUE if the calibration was successful or FALSE if communication with the controller could not be done.

boolean sonyPS2_setAnalogMode(SONY_PS2* controller)

Activates the joysticks.
Unless this command is issued successfully then you will only be able to access the pushbuttons on the controller.
Returns FALSE if communication with the controller failed. Note that the 'calibrate' function will automatically try to call this command.

boolean sonyPS2_isAnalogMode(const SONY_PS2* controller

Returns TRUE if the controller is already in analogue mode.
Note that this is only valid after one successful 'read' command has been issued.

boolean sonyPS2_read(SONY_PS2* controller)

Read the values from the controller and store them.
All of the functions that return joystick values and button states work with the data last read by this command.
The function will return TRUE if the controller was read successfully or FALSE if there was a problem.

uint16_t sonyPS2_buttonsRaw(const SONY_PS2* controller)

Return the status of all 16 buttons.
The returned value has one bit per button. The bit is set if that button has been pressed. The button names all start with PS2_BTN_ and are defined in this file.
This function is useful if you want to do a 'Press any button to continue' function ie
sonyPS2_read(&controller);
uint16_t current = sonyPS2_buttonsRaw(&controller);
do{
    sonyPS2_read(&controller);
} while (sonyPS2_buttonsRaw(&controller) == current);
You can also 'OR' together various buttons. So to test if the SELECT and START buttons have both been pressed:-
#define COMBO (PS2_BTN_SELECT | PS2_BTN_START)
sonyPS2_read(&controller);
if( (sonyPS2_buttonsRaw(&controller) & COMBO) == COMBO){
    // Both pressed
}

boolean sonyPS2_buttonPressed(const SONY_PS2* controller, uint16_t button)

Return TRUE if the specified button has been pressed.
The button names all start with PS2_BTN_ and are defined in this H file.
Note that you can only test for one button at a time. If you need to test for multiple buttons then compare with sonyPS2_buttonsRaw(const SONY_PS2* controller)

boolean sonyPS2_buttonDown(const SONY_PS2* controller, uint16_t button)

Return TRUE if the button has just been pressed or FALSE if it was already pressed or is not pressed at all.

boolean sonyPS2_buttonHeld(const SONY_PS2* controller, uint16_t button)

Return TRUE if the button continues to be held down.

boolean sonyPS2_buttonUp(const SONY_PS2* controller, uint16_t button)

Returns TRUE if the button has just been released.

uint8_t sonyPS2_joystickRaw(const SONY_PS2* controller, PS2_STICK stick)

Reads the raw value from a joystick.
The returned value will be in the range 0 to 255 and ignores any calibration and dead zone settings.
The joystick names all start with PS2_STICK_ and are defined in this H file.

int8_t sonyPS2_joystick(const SONY_PS2* controller, PS2_STICK stick)

Read a joystick value relative to its centre point including any dead zone.
The returned value will be 0 if the value is within the centre dead zone. Negative values represent 'left' or 'up, and positive values represent 'right' or 'down'.
The joystick names all start with PS2_STICK_ and are defined in this H file.

uint8_t sonyPS2_buttonPressure(const SONY_PS2* controller, uint16_t button)

Return a value representing how hard a button has been pressed.
This will return 0 if the button is not pressed at all up to a value of 255 if its has been pressed hard. If the controller has not been put into analog mode then it will only return 0 or 255.

void sonyPS_setRumble(SONY_PS2* controller, uint8_t left, boolean right)

Turn on the rumble motors.
Note that there are two different values - one for each motor. One motor can either be on or off whereas the other can be set to any value between 0 and 255.
The motor settings will only change when the next call to read the controller is used.

uint16_t sonyPS2_buttonsChanged(const SONY_PS2* controller)

Returns information on which buttons have changed state since the previous call to read the controller.
The returned value is the combination of all the buttons have changed or 0 if no buttons have been pressed or released. This allows you to perform a quick check to test if anything has changed.

Valid XHTML 1.0 Transitional