This thread only applies to college teams.
There was lots of discussion earlier this year about the partner joystick port and alternative devices that could be interfaced to it.
magicode had asked about using this port and had received this answer.
There had also been posts about the communications protocol in threads such as this and this. I had posted some code that could be used on a PC to communicate with the partner port but what was/is really needed is an embedded solution.
To address this I have put together a technology demo that interfaces a playstation Dualshock 3 controller (although it should also work with other PS3 controllers as well). The only reason I chose to use this device is that I have them laying around at home, the principle used for interfacing this would be the same for many other USB controllers, in particular I know there was interest in using the Logitech 3D Pro, it would take some extra work but I see no reason why college students could not handle that.
Most devices like the PS3 controller implement a class of USB communications know as HID (Human interface device). There is lots of existing firmware available that shows how to interface to HID devices and many different micro-controllers that have the capability to implement a USB host interface. For this project I chose to use an arduino, mostly because I have them available but also because there has been some useful development already done in interfacing HID controllers.
Hardware
The small embedded system I put together consisted of an arduino pro and a USB shield both from sparkfun.
[ATTACH]6358[/ATTACH]
http://www.sparkfun.com/products/10914
http://www.sparkfun.com/products/9947
In addition to these I used a small breakout board to turn the logic level serial data into appropriate RS232 levels.
http://www.sparkfun.com/products/11189
And some headers for connecting the two boards.
http://www.sparkfun.com/products/10007
Total investment about $55 not including various wire and connectors I already had.
Edit: I should add that if you are starting from scratch you would need a programming adapter such as this one. check the voltage depending on which board you go with.
http://www.sparkfun.com/products/9873
Firmware
The arduino development environment is free and available for Mac, PC and Linux. You can download it from the arduino home page.
The firmware is simple, the PS3 controller is initialized, the values of its joysticks and buttons are read and placed into a data structure suitable for sending to the VEX joystick, the packet is then sent to the serial port on the arduino.
The USB communications are handled by code developed by a gentleman know as Oleg, his home page is here.
The library can be downloaded from github.
https://github.com/felis/USB_Host_Shield_2.0
Oleg developed the original version of the USB shield (as far as I know) but his version is a little different from the sparkfun version. Specifically, reset to the USB controller is handled a little differently between the two boards, this means that the examples included with the library do not work out of the box as reset on the sparkfun system is held low by default. To rectify this a couple of lines of code need to be added to the arduino setup function.
// reset USB shield - this is needed for the sparkfun version
pinMode( 7, OUTPUT);
digitalWrite( 7, 0 );
digitalWrite( 7, 1 );
digitalWrite( 7, 0 );
digitalWrite( 7, 1 );
This simply toggles the reset line, which is connected to output 7 on the sparkfun board, and then holds it high.
The arduino pro uses an Atmel Atmega328P running at 8MHz (although there is also a 16MHz version for the same price). This micro-controller only has one serial port, as we wish to use the serial port for interfacing to the VEX joystick we need to be careful as it is often also used for debugging purposes. The arduino development system also provides a âsoftware serialâ library but I find this does not work well at the 115200 baud rate the VEX partner port needs. The PS3USB class has some debugging turned on by default and this needs to be turned off, the file PS3USB.cpp needs to be edited and the definitions for debugging commented out.
//#define DEBUG // Uncomment to print data for debugging
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
I have attached the sketch (the arduino guys call programs sketches) for this project but the key parts are as follows.
Definition of the vex communications data.
// Storage for the vex communications data
typedef union _vexdata {
struct {
unsigned char header_aa;
unsigned char header_55;
unsigned char reply_type;
unsigned char datalen;
unsigned char js_1;
unsigned char js_2;
unsigned char js_3;
unsigned char js_4;
unsigned char button_56;
unsigned char button_78;
unsigned char accel_y;
unsigned char accel_x;
unsigned char accel_z;
unsigned char checksum;
} data;
unsigned char buffer[16];
} vexdata;
The main loop that the arduino code constantly calls.
void loop()
{
static uint32_t timer = 0;
// Run every 50mS
if(millis() - timer < 50)
return;
timer = millis();
// Call the USB task
Usb.Task();
// If we are connected then gather all the data
if(PS3.PS3Connected || PS3.PS3NavigationConnected)
{
// Get analog joystick data
MyVexData.data.js_1 = PS3.getAnalogHat(RightHatX);
MyVexData.data.js_2 = PS3.getAnalogHat(RightHatY);
MyVexData.data.js_3 = PS3.getAnalogHat(LeftHatY);
MyVexData.data.js_4 = PS3.getAnalogHat(LeftHatX);
// Any buttons changed from last time ?
if(PS3.buttonChanged)
{
MyVexData.data.button_78 = 0;
if( PS3.getButton(DOWN) )
MyVexData.data.button_78 |= 0x01;
if( PS3.getButton(LEFT) )
MyVexData.data.button_78 |= 0x02;
if( PS3.getButton(UP) )
MyVexData.data.button_78 |= 0x04;
if( PS3.getButton(RIGHT) )
MyVexData.data.button_78 |= 0x08;
if( PS3.getButton(CROSS) )
MyVexData.data.button_78 |= 0x10;
if( PS3.getButton(SQUARE) )
MyVexData.data.button_78 |= 0x20;
if( PS3.getButton(TRIANGLE) )
MyVexData.data.button_78 |= 0x40;
if( PS3.getButton(CIRCLE) )
MyVexData.data.button_78 |= 0x80;
MyVexData.data.button_56 = 0;
if( PS3.getButton(L2) )
MyVexData.data.button_56 |= 0x01;
if( PS3.getButton(L1) )
MyVexData.data.button_56 |= 0x02;
if( PS3.getButton(R2) )
MyVexData.data.button_56 |= 0x04;
if( PS3.getButton(R1) )
MyVexData.data.button_56 |= 0x08;
}
// Accelerometer data
MyVexData.data.accel_y = PS3.getSensor(aY);
MyVexData.data.accel_x = PS3.getSensor(aX);
MyVexData.data.accel_z = 0x7f;
}
VexDataChecksum();
#ifdef DEBUG
VexDataPrint();
#else
VexDataTransmit();
#endif
}
Iâm not going to explain all of this but the essence of this code is to copy the PS3 control values into the VEX data structure and then send it to the serial port. As this is demo code I did not bother to receive messages back from the VEX joystick, doesnât seem to matter but this should be improved in production code.
The code was checked by using a simple ROBOTC program to display values from the partner joystick on the LCD.
Here is a photo of the system thrown together on my desk, remember itâs only a prototype to prove that it can work.
[ATTACH]6349[/ATTACH]
For competition use this would obviously need to be packaged, a standard VEX battery would easily be able to power it.
The USB shield library also supports an interface to the PS3 controller using bluetooth, a bluetooth dongle is connected to the USB port in place of the cable to the joystick.
I will create a block diagram showing how all this is connected together in another post.
Enjoy.
PS3ToVex.zip (2.97 KB)