Merge pull request #17 from TKJElectronics/master

After several request I decided to port the library to USB too
This commit is contained in:
Oleg Mazurov 2012-05-25 17:03:45 -07:00
commit d9878181ca
8 changed files with 1292 additions and 255 deletions

View file

@ -369,6 +369,9 @@ void PS3BT::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr )
/* Performs a cleanup after failed Init() attempt */ /* Performs a cleanup after failed Init() attempt */
uint8_t PS3BT::Release() uint8_t PS3BT::Release()
{ {
PS3Connected = false;
PS3MoveConnected = false;
PS3NavigationConnected = false;
pUsb->GetAddressPool().FreeAddress(bAddress); pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0; bAddress = 0;
bPollEnable = false; bPollEnable = false;
@ -486,13 +489,13 @@ double PS3BT::getAngle(Angle a) {
double accYval; double accYval;
double accZval; double accZval;
if(PS3BTConnected) { if(PS3Connected) {
// Data for the Kionix KXPC4 used in the DualShock 3 // Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V) const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
accXval = -((double)getSensor(aX)-zeroG); accXval = -((double)getSensor(aX)-zeroG);
accYval = -((double)getSensor(aY)-zeroG); accYval = -((double)getSensor(aY)-zeroG);
accZval = -((double)getSensor(aZ)-zeroG); accZval = -((double)getSensor(aZ)-zeroG);
} else if(PS3MoveBTConnected) { } else if(PS3MoveConnected) {
// It's a Kionix KXSC4 inside the Motion controller // It's a Kionix KXSC4 inside the Motion controller
const uint16_t zeroG = 0x8000; const uint16_t zeroG = 0x8000;
accXval = getSensor(aXmove); accXval = getSensor(aXmove);
@ -534,7 +537,7 @@ bool PS3BT::getStatus(Status c)
} }
String PS3BT::getStatusString() String PS3BT::getStatusString()
{ {
if (PS3BTConnected || PS3NavigationBTConnected) if (PS3Connected || PS3NavigationConnected)
{ {
char statusOutput[100]; char statusOutput[100];
@ -566,7 +569,7 @@ String PS3BT::getStatusString()
return statusOutput; return statusOutput;
} }
else if(PS3MoveBTConnected) else if(PS3MoveConnected)
{ {
char statusOutput[50]; char statusOutput[50];
@ -586,12 +589,12 @@ String PS3BT::getStatusString()
} }
void PS3BT::disconnect()//Use this void to disconnect any of the controllers void PS3BT::disconnect()//Use this void to disconnect any of the controllers
{ {
if (PS3BTConnected) if (PS3Connected)
PS3BTConnected = false; PS3Connected = false;
else if (PS3MoveBTConnected) else if (PS3MoveConnected)
PS3MoveBTConnected = false; PS3MoveConnected = false;
else if (PS3NavigationBTConnected) else if (PS3NavigationConnected)
PS3NavigationBTConnected = false; PS3NavigationConnected = false;
//First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection //First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection
l2cap_disconnection_request(0x0A, interrupt_dcid, interrupt_scid); l2cap_disconnection_request(0x0A, interrupt_dcid, interrupt_scid);
@ -1030,7 +1033,7 @@ void PS3BT::ACL_event_task()
else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1])//l2cap_interrupt else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1])//l2cap_interrupt
{ {
//Serial.print("\r\nL2CAP Interrupt"); //Serial.print("\r\nL2CAP Interrupt");
if(PS3BTConnected || PS3MoveBTConnected || PS3NavigationBTConnected) if(PS3Connected || PS3MoveConnected || PS3NavigationConnected)
{ {
readReport(); readReport();
#ifdef PRINTREPORT #ifdef PRINTREPORT
@ -1155,30 +1158,29 @@ void PS3BT::L2CAP_task()
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n")); Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"));
#endif #endif
PS3BTConnected = true; PS3Connected = true;
} else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N') } else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
setLedOn(LED1); // This just turns LED constantly on, on the Navigation controller setLedOn(LED1); // This just turns LED constantly on, on the Navigation controller
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nNavigation Controller Enabled\r\n")); Notify(PSTR("\r\nNavigation Controller Enabled\r\n"));
#endif #endif
PS3NavigationBTConnected = true; PS3NavigationConnected = true;
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M') } else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
moveSetBulb(Red); moveSetBulb(Red);
timerBulbRumble = millis(); timerBulbRumble = millis();
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nMotion Controller Enabled\r\n")); Notify(PSTR("\r\nMotion Controller Enabled\r\n"));
#endif #endif
PS3MoveBTConnected = true; PS3MoveConnected = true;
} }
l2cap_state = L2CAP_EV_L2CAP_DONE; l2cap_state = L2CAP_EV_L2CAP_DONE;
} }
break; break;
case L2CAP_EV_L2CAP_DONE: case L2CAP_EV_L2CAP_DONE:
if (PS3MoveBTConnected)//The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on if (PS3MoveConnected)//The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
{ {
dtimeBulbRumble = millis() - timerBulbRumble; if (millis() - timerBulbRumble > 4000)//Send at least every 4th second
if (dtimeBulbRumble > 4000)//Send at least every 4th second
{ {
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);//The Bulb and rumble values, has to be written again and again, for it to stay turned on HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);//The Bulb and rumble values, has to be written again and again, for it to stay turned on
timerBulbRumble = millis(); timerBulbRumble = millis();
@ -1217,11 +1219,13 @@ void PS3BT::L2CAP_task()
/************************************************************/ /************************************************************/
void PS3BT::readReport() void PS3BT::readReport()
{ {
if (l2capinbuf == NULL)
return;
if(l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT if(l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT
{ {
if(PS3BTConnected || PS3NavigationBTConnected) if(PS3Connected || PS3NavigationConnected)
ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16)); ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
else if(PS3MoveBTConnected) else if(PS3MoveConnected)
ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16)); ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
//Notify(PSTR("\r\nButtonState"); //Notify(PSTR("\r\nButtonState");
@ -1252,6 +1256,8 @@ void PS3BT::readReport()
void PS3BT::printReport() //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers void PS3BT::printReport() //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
{ {
if (l2capinbuf == NULL)
return;
if(l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT if(l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT
{ {
for(uint8_t i = 10; i < 58;i++) for(uint8_t i = 10; i < 58;i++)
@ -1506,10 +1512,8 @@ void PS3BT::HID_Command(uint8_t* data, uint16_t nbytes)
for (uint16_t i = 0; i < nbytes; i++)//L2CAP C-frame for (uint16_t i = 0; i < nbytes; i++)//L2CAP C-frame
buf[8 + i] = data[i]; buf[8 + i] = data[i];
dtimeHID = millis() - timerHID; if (millis() - timerHID <= 250)// Check if is has been more than 250ms since last command
delay((uint32_t)(250 - (millis() - timerHID)));//There have to be a delay between commands
if (dtimeHID <= 250)// Check if is has been more than 250ms since last command
delay((uint32_t)(250 - dtimeHID));//There have to be a delay between commands
pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf); pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
@ -1602,10 +1606,8 @@ void PS3BT::HIDMove_Command(uint8_t* data,uint16_t nbytes)
for (uint16_t i = 0; i < nbytes; i++)//L2CAP C-frame for (uint16_t i = 0; i < nbytes; i++)//L2CAP C-frame
buf[8 + i] = data[i]; buf[8 + i] = data[i];
dtimeHID = millis() - timerHID; if (millis() - timerHID <= 250)// Check if is has been less than 200ms since last command
delay((uint32_t)(250 - (millis() - timerHID)));//There have to be a delay between commands
if (dtimeHID <= 250)// Check if is has been less than 200ms since last command
delay((uint32_t)(250 - dtimeHID));//There have to be a delay between commands
pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf); pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
@ -1622,15 +1624,14 @@ void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b)//Use this to set the Co
} }
void PS3BT::moveSetBulb(Colors color)//Use this to set the Color using the predefined colors in "enums.h" void PS3BT::moveSetBulb(Colors color)//Use this to set the Color using the predefined colors in "enums.h"
{ {
//set the Bulb's values into the write buffer moveSetBulb((uint8_t)(color >> 16),(uint8_t)(color >> 8),(uint8_t)(color));
HIDMoveBuffer[3] = (uint8_t)(color >> 16);
HIDMoveBuffer[4] = (uint8_t)(color >> 8);
HIDMoveBuffer[5] = (uint8_t)(color);
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
} }
void PS3BT::moveSetRumble(uint8_t rumble) void PS3BT::moveSetRumble(uint8_t rumble)
{ {
#ifdef DEBUG
if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"));
#endif
//set the rumble value into the write buffer //set the rumble value into the write buffer
HIDMoveBuffer[7] = rumble; HIDMoveBuffer[7] = rumble;

View file

@ -361,9 +361,9 @@ public:
void moveSetBulb(Colors color);//Use this to set the Color using the predefined colors in "enum Colors" void moveSetBulb(Colors color);//Use this to set the Color using the predefined colors in "enum Colors"
void moveSetRumble(uint8_t rumble); void moveSetRumble(uint8_t rumble);
bool PS3BTConnected;// Variable used to indicate if the normal playstation controller is successfully connected bool PS3Connected;// Variable used to indicate if the normal playstation controller is successfully connected
bool PS3MoveBTConnected;// Variable used to indicate if the move controller is successfully connected bool PS3MoveConnected;// Variable used to indicate if the move controller is successfully connected
bool PS3NavigationBTConnected;// Variable used to indicate if the navigation controller is successfully connected bool PS3NavigationConnected;// Variable used to indicate if the navigation controller is successfully connected
bool buttonChanged;//Indicate if a button has been changed bool buttonChanged;//Indicate if a button has been changed
bool buttonPressed;//Indicate if a button has been pressed bool buttonPressed;//Indicate if a button has been pressed
bool buttonReleased;//Indicate if a button has been released bool buttonReleased;//Indicate if a button has been released
@ -411,9 +411,7 @@ private:
uint32_t ButtonState; uint32_t ButtonState;
uint32_t OldButtonState; uint32_t OldButtonState;
uint32_t timerHID;// timer used see if there has to be a delay before a new HID command uint32_t timerHID;// timer used see if there has to be a delay before a new HID command
uint32_t dtimeHID;// delta time since last HID command
uint32_t timerBulbRumble;// used to continuously set PS3 Move controller Bulb and rumble values uint32_t timerBulbRumble;// used to continuously set PS3 Move controller Bulb and rumble values
uint32_t dtimeBulbRumble;// used to know how longs since last since the Bulb and rumble values was written
uint8_t my_bdaddr[6]; //Change to your dongles Bluetooth address in PS3BT.cpp uint8_t my_bdaddr[6]; //Change to your dongles Bluetooth address in PS3BT.cpp
uint8_t hcibuf[BULK_MAXPKTSIZE];//General purpose buffer for hci data uint8_t hcibuf[BULK_MAXPKTSIZE];//General purpose buffer for hci data

605
PS3USB.cpp Normal file
View file

@ -0,0 +1,605 @@
/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").
Contact information
-------------------
Kristian Lauszus, TKJ Electronics
Web : http://www.tkjelectronics.com
e-mail : kristianl@tkjelectronics.com
*/
#include "PS3USB.h"
#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
prog_char PS3_REPORT_BUFFER[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
prog_char MOVE_REPORT_BUFFER[] PROGMEM = {
0x02, 0x00, // Always 0x02, 0x00,
0x00, 0x00, 0x00, // r, g, b,
0x00, // Always 0x00,
0x00 // Rumble
};
PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0):
pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory
bPollEnable(false) // don't start polling before dongle is connected
{
for(uint8_t i=0; i<PS3_MAX_ENDPOINTS; i++)
{
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
my_bdaddr[4] = btadr4;
my_bdaddr[3] = btadr3;
my_bdaddr[2] = btadr2;
my_bdaddr[1] = btadr1;
my_bdaddr[0] = btadr0;
}
uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed)
{
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
#ifdef EXTRADEBUG
Notify(PSTR("\r\nPS3BT Init"));
#endif
// check if address has already been assigned to an instance
if (bAddress)
{
#ifdef DEBUG
Notify(PSTR("\r\nAddress in use"));
#endif
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
}
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p)
{
#ifdef DEBUG
Notify(PSTR("\r\nAddress not found"));
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo)
{
#ifdef DEBUG
Notify(PSTR("\r\nepinfo is null"));
#endif
return USB_ERROR_EPINFO_IS_NULL;
}
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
if(rcode)
goto FailGetDevDescr;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress );
if (rcode)
{
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "));
#endif
PrintHex<uint8_t>(rcode);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "));
PrintHex<uint8_t>(bAddress);
#endif
p->lowspeed = false;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the PID and VID we will use known values for the
configuration values for device, interface, endpoints and HID for the PS3 Controllers */
/* Initialize data structures for endpoints of device */
epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ PS3_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if( rcode )
goto FailSetDevTblEntry;
delay(200);//Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
if( rcode )
goto FailSetConf;
if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
{
if(PID == PS3_PID) {
#ifdef DEBUG
Notify(PSTR("\r\nDualshock 3 Controller Connected"));
#endif
PS3Connected = true;
} else { // must be a navigation controller
#ifdef DEBUG
Notify(PSTR("\r\nNavigation Controller Connected"));
#endif
PS3NavigationConnected = true;
}
/* Set internal bluetooth address and request for data */
setBdaddr(my_bdaddr);
enable_sixaxis();
// Needed for PS3 Dualshock and Navigation commands to work
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
for (uint8_t i = 6; i < 10; i++)
readBuf[i] = 0x7F; // Set the analog joystick values to center position
setLedOn(LED1);
timer = millis();
}
else // must be a Motion controller
{
#ifdef DEBUG
Notify(PSTR("\r\nMotion Controller Connected"));
#endif
PS3MoveConnected = true;
setMoveBdaddr(my_bdaddr); // Set internal bluetooth address
moveSetBulb(Red);
// Needed for Move commands to work
for (uint8_t i = 0; i < MOVE_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&MOVE_REPORT_BUFFER[i]);
timer = millis();
}
}
else
goto FailUnknownDevice;
bPollEnable = true;
Notify(PSTR("\r\n"));
return 0; // successful configuration
/* diagnostic messages */
FailGetDevDescr:
#ifdef DEBUG
Notify(PSTR("\r\ngetDevDescr:"));
#endif
goto Fail;
FailSetDevTblEntry:
#ifdef DEBUG
Notify(PSTR("\r\nsetDevTblEn:"));
#endif
goto Fail;
FailSetConf:
#ifdef DEBUG
Notify(PSTR("\r\nsetConf:"));
#endif
goto Fail;
FailUnknownDevice:
#ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "));
PrintHex<uint16_t>(VID);
Notify(PSTR(" PID: "));
PrintHex<uint16_t>(PID);
#endif
goto Fail;
Fail:
#ifdef DEBUG
Notify(PSTR("\r\nPS3 Init Failed, error code: "));
Serial.print(rcode);
#endif
Release();
return rcode;
}
/* Performs a cleanup after failed Init() attempt */
uint8_t PS3USB::Release()
{
PS3Connected = false;
PS3MoveConnected = false;
PS3NavigationConnected = false;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
}
uint8_t PS3USB::Poll()
{
if (!bPollEnable)
return 0;
if(PS3Connected || PS3NavigationConnected) {
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
if(millis() - timer > 100) { // Loop 100ms before processing data
readReport();
#ifdef PRINTREPORT
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
#endif
}
}
else if(PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
if (millis() - timer > 4000) // Send at least every 4th second
{
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
timer = millis();
}
}
return 0;
}
void PS3USB::readReport()
{
if (readBuf == NULL)
return;
if(PS3Connected || PS3NavigationConnected)
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
//Notify(PSTR("\r\nButtonState");
//PrintHex<uint32_t>(ButtonState);
if(ButtonState != OldButtonState)
{
buttonChanged = true;
if(ButtonState != 0x00) {
buttonPressed = true;
buttonReleased = false;
} else {
buttonPressed = false;
buttonReleased = true;
}
}
else
{
buttonChanged = false;
buttonPressed = false;
buttonReleased = false;
}
OldButtonState = ButtonState;
}
void PS3USB::printReport() //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
{
if (readBuf == NULL)
return;
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE;i++)
{
PrintHex<uint8_t>(readBuf[i]);
Serial.print(" ");
}
Serial.println("");
}
bool PS3USB::getButton(Button b)
{
if (readBuf == NULL)
return false;
if ((readBuf[(uint16_t)b >> 8] & ((uint8_t)b & 0xff)) > 0)
return true;
else
return false;
}
uint8_t PS3USB::getAnalogButton(AnalogButton a)
{
if (readBuf == NULL)
return 0;
return (uint8_t)(readBuf[(uint16_t)a]);
}
uint8_t PS3USB::getAnalogHat(AnalogHat a)
{
if (readBuf == NULL)
return 0;
return (uint8_t)(readBuf[(uint16_t)a]);
}
int32_t PS3USB::getSensor(Sensor a)
{
if (readBuf == NULL)
return 0;
return ((readBuf[(uint16_t)a] << 8) | readBuf[(uint16_t)a + 1]);
}
double PS3USB::getAngle(Angle a) {
double accXval;
double accYval;
double accZval;
if(PS3Connected) {
// Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
accXval = -((double)getSensor(aX)-zeroG);
accYval = -((double)getSensor(aY)-zeroG);
accZval = -((double)getSensor(aZ)-zeroG);
}
// Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees
if (a == Pitch) {
double angle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG;
return angle;
} else {
double angle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG;
return angle;
}
}
bool PS3USB::getStatus(Status c)
{
if (readBuf == NULL)
return false;
if (readBuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff))
return true;
return false;
}
String PS3USB::getStatusString()
{
if (PS3Connected || PS3NavigationConnected)
{
char statusOutput[100];
strcpy(statusOutput,"ConnectionStatus: ");
if (getStatus(Plugged)) strcat(statusOutput,"Plugged");
else if (getStatus(Unplugged)) strcat(statusOutput,"Unplugged");
else strcat(statusOutput,"Error");
strcat(statusOutput," - PowerRating: ");
if (getStatus(Charging)) strcat(statusOutput,"Charging");
else if (getStatus(NotCharging)) strcat(statusOutput,"Not Charging");
else if (getStatus(Shutdown)) strcat(statusOutput,"Shutdown");
else if (getStatus(Dying)) strcat(statusOutput,"Dying");
else if (getStatus(Low)) strcat(statusOutput,"Low");
else if (getStatus(High)) strcat(statusOutput,"High");
else if (getStatus(Full)) strcat(statusOutput,"Full");
else strcat(statusOutput,"Error");
strcat(statusOutput," - WirelessStatus: ");
if (getStatus(CableRumble)) strcat(statusOutput,"Cable - Rumble is on");
else if (getStatus(Cable)) strcat(statusOutput,"Cable - Rumble is off");
else if (getStatus(BluetoothRumble)) strcat(statusOutput,"Bluetooth - Rumble is on");
else if (getStatus(Bluetooth)) strcat(statusOutput,"Bluetooth - Rumble is off");
else strcat(statusOutput,"Error");
return statusOutput;
}
}
/* Playstation Sixaxis Dualshock and Navigation Controller commands */
void PS3USB::PS3_Command(uint8_t* data, uint16_t nbytes)
{
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
}
void PS3USB::setAllOff()
{
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setRumbleOff()
{
writeBuf[1] = 0x00;
writeBuf[2] = 0x00;//low mode off
writeBuf[3] = 0x00;
writeBuf[4] = 0x00;//high mode off
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setRumbleOn(Rumble mode)
{
/* Still not totally sure how it works, maybe something like this instead?
* 3 - duration_right
* 4 - power_right
* 5 - duration_left
* 6 - power_left
*/
if ((mode & 0x30) > 0)
{
writeBuf[1] = 0xfe;
writeBuf[3] = 0xfe;
if (mode == RumbleHigh)
{
writeBuf[2] = 0;//low mode off
writeBuf[4] = 0xff;//high mode on
}
else
{
writeBuf[2] = 0xff;//low mode on
writeBuf[4] = 0;//high mode off
}
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
}
void PS3USB::setLedOff(LED a)
{
writeBuf[9] &= ~((uint8_t)(((uint16_t)a & 0x0f) << 1));
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setLedOn(LED a)
{
writeBuf[9] |= (uint8_t)(((uint16_t)a & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setLedToggle(LED a)
{
writeBuf[9] ^= (uint8_t)(((uint16_t)a & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setBdaddr(uint8_t* BDADDR)
{
/* Set the internal bluetooth address */
uint8_t buf[8];
buf[0] = 0x01;
buf[1] = 0x00;
for (uint8_t i = 0; i < 6; i++)
buf[i+2] = BDADDR[5 - i];//Copy into buffer, has to be written reversed
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
#ifdef DEBUG
Notify(PSTR("\r\nBluetooth Address was set to: "));
for(int8_t i = 5; i > 0; i--)
{
PrintHex<uint8_t>(my_bdaddr[i]);
Serial.print(":");
}
PrintHex<uint8_t>(my_bdaddr[0]);
#endif
return;
}
void PS3USB::enable_sixaxis()//Command used to enable the Dualshock 3 and Navigation controller to send data via USB
{
uint8_t cmd_buf[4];
cmd_buf[0] = 0x42;// Special PS3 Controller enable commands
cmd_buf[1] = 0x0c;
cmd_buf[2] = 0x00;
cmd_buf[3] = 0x00;
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
}
/* Playstation Move Controller commands */
void PS3USB::Move_Command(uint8_t* data, uint16_t nbytes)
{
pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
}
void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b)//Use this to set the Color using RGB values
{
// set the Bulb's values into the write buffer
writeBuf[2] = r;
writeBuf[3] = g;
writeBuf[4] = b;
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
}
void PS3USB::moveSetBulb(Colors color)//Use this to set the Color using the predefined colors in "enums.h"
{
moveSetBulb((uint8_t)(color >> 16),(uint8_t)(color >> 8),(uint8_t)(color));
}
void PS3USB::moveSetRumble(uint8_t rumble)
{
#ifdef DEBUG
if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"));
#endif
//set the rumble value into the write buffer
writeBuf[6] = rumble;
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
}
void PS3USB::setMoveBdaddr(uint8_t* BDADDR)
{
/* Set the internal bluetooth address */
uint8_t buf[11];
buf[0] = 0x05;
buf[7] = 0x10;
buf[8] = 0x01;
buf[9] = 0x02;
buf[10] = 0x12;
for (uint8_t i = 0; i < 6; i++)
buf[i + 1] = BDADDR[i];
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00,11,11, buf, NULL);
#ifdef DEBUG
Notify(PSTR("\r\nBluetooth Address was set to: "));
for(int8_t i = 5; i > 0; i--)
{
PrintHex<uint8_t>(my_bdaddr[i]);
Serial.print(":");
}
PrintHex<uint8_t>(my_bdaddr[0]);
#endif
return;
}

244
PS3USB.h Normal file
View file

@ -0,0 +1,244 @@
/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").
Contact information
-------------------
Kristian Lauszus, TKJ Electronics
Web : http://www.tkjelectronics.com
e-mail : kristianl@tkjelectronics.com
*/
#ifndef _ps3usb_h_
#define _ps3usb_h_
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Usb.h"
/* PS3 data taken from descriptors */
#define EP_MAXPKTSIZE 64 // max size for data via USB
/* Endpoint types */
#define EP_INTERRUPT 0x03
/* Names we give to the 3 ps3 pipes - this is only used for setting the bluetooth address into the ps3 controllers */
#define PS3_CONTROL_PIPE 0
#define PS3_OUTPUT_PIPE 1
#define PS3_INPUT_PIPE 2
//PID and VID of the different devices
#define PS3_VID 0x054C // Sony Corporation
#define PS3_PID 0x0268 // PS3 Controller DualShock 3
#define PS3NAVIGATION_PID 0x042F // Navigation controller
#define PS3MOVE_PID 0x03D5 // Motion controller
#define PS3_REPORT_BUFFER_SIZE 48 // Size of the output report buffer for the Dualshock and Navigation controllers
#define MOVE_REPORT_BUFFER_SIZE 7 // Size of the output report buffer for the Move Controller
// used in control endpoint header for HCI Commands
#define bmREQ_HCI_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
// used in control endpoint header for HID Commands
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
#define HID_REQUEST_SET_REPORT 0x09
#define PS3_MAX_ENDPOINTS 3
enum LED
{
LED1 = 0x01,
LED2 = 0x02,
LED3 = 0x04,
LED4 = 0x08,
LED5 = 0x09,
LED6 = 0x0A,
LED7 = 0x0C,
LED8 = 0x0D,
LED9 = 0x0E,
LED10 = 0x0F,
};
enum Colors
{
//Used to set the colors of the move controller
Red = 0xFF0000,//((255 << 16) | (0 << 8) | 0);
Green = 0xFF00,//((0 << 16) | (255 << 8) | 0);
Blue = 0xFF,//((0 << 16) | (0 << 8) | 255);
Yellow = 0xFFEB04,//((255 << 16) | (235 << 8) | 4);
Lightblue = 0xFFFF,//((0 << 16) | (255 << 8) | 255);
Purble = 0xFF00FF,//((255 << 16) | (0 << 8) | 255);
White = 0xFFFFFF,//((255 << 16) | (255 << 8) | 255);
Off = 0x00,//((0 << 16) | (0 << 8) | 0);
};
enum Button
{
// byte location | bit location
//Sixaxis Dualshcock 3 & Navigation controller
SELECT = (2 << 8) | 0x01,
L3 = (2 << 8) | 0x02,
R3 = (2 << 8) | 0x04,
START = (2 << 8) | 0x08,
UP = (2 << 8) | 0x10,
RIGHT = (2 << 8) | 0x20,
DOWN = (2 << 8) | 0x40,
LEFT = (2 << 8) | 0x80,
L2 = (3 << 8) | 0x01,
R2 = (3 << 8) | 0x02,
L1 = (3 << 8) | 0x04,
R1 = (3 << 8) | 0x08,
TRIANGLE = (3 << 8) | 0x10,
CIRCLE = (3 << 8) | 0x20,
CROSS = (3 << 8) | 0x40,
SQUARE = (3 << 8) | 0x80,
PS = (4 << 8) | 0x01,
};
enum AnalogButton
{
//Sixaxis Dualshcock 3 & Navigation controller
UP_ANALOG = 14,
RIGHT_ANALOG = 15,
DOWN_ANALOG = 16,
LEFT_ANALOG = 17,
L2_ANALOG = 18,
R2_ANALOG = 19,
L1_ANALOG = 20,
R1_ANALOG = 21,
TRIANGLE_ANALOG = 22,
CIRCLE_ANALOG = 23,
CROSS_ANALOG = 24,
SQUARE_ANALOG = 25,
};
enum AnalogHat
{
LeftHatX = 6,
LeftHatY = 7,
RightHatX = 8,
RightHatY = 9,
};
enum Sensor
{
// Sensors inside the Sixaxis Dualshock 3 controller
aX = 41,
aY = 43,
aZ = 45,
gZ = 47,
};
enum Angle
{
Pitch = 0x01,
Roll = 0x02,
};
enum Status
{
// byte location | bit location
Plugged = (29 << 8) | 0x02,
Unplugged = (29 << 8) | 0x03,
Charging = (30 << 8) | 0xEE,
NotCharging = (30 << 8) | 0xF1,
Shutdown = (30 << 8) | 0x01,
Dying = (30 << 8) | 0x02,
Low = (30 << 8) | 0x03,
High = (30 << 8) | 0x04,
Full = (30 << 8) | 0x05,
CableRumble = (31 << 8) | 0x10, // Opperating by USB and rumble is turned on
Cable = (31 << 8) | 0x12, // Opperating by USB and rumble is turned off
BluetoothRumble = (31 << 8) | 0x14, // Opperating by bluetooth and rumble is turned on
Bluetooth = (30 << 8) | 0x16, // Opperating by bluetooth and rumble is turned off
};
enum Rumble
{
RumbleHigh = 0x10,
RumbleLow = 0x20,
};
class PS3USB : public USBDeviceConfig
{
public:
PS3USB(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0);
// USBDeviceConfig implementation
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
virtual uint8_t Release();
virtual uint8_t Poll();
virtual uint8_t GetAddress() { return bAddress; };
virtual bool isReady() { return bPollEnable; };
void setBdaddr(uint8_t* BDADDR);
void setMoveBdaddr(uint8_t* BDADDR);
/* PS3 Controller Commands */
bool getButton(Button b);
uint8_t getAnalogButton(AnalogButton a);
uint8_t getAnalogHat(AnalogHat a);
int32_t getSensor(Sensor a);
double getAngle(Angle a);
bool getStatus(Status c);
String getStatusString();
/* Commands for Dualshock 3 and Navigation controller */
void setAllOff();
void setRumbleOff();
void setRumbleOn(Rumble mode);
void setLedOff(LED a);
void setLedOn(LED a);
void setLedToggle(LED a);
/* Commands for Motion controller only */
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);//Use this to set the Color using RGB values
void moveSetBulb(Colors color);//Use this to set the Color using the predefined colors in "enum Colors"
void moveSetRumble(uint8_t rumble);
bool PS3Connected;// Variable used to indicate if the normal playstation controller is successfully connected
bool PS3MoveConnected;// Variable used to indicate if the move controller is successfully connected
bool PS3NavigationConnected;// Variable used to indicate if the navigation controller is successfully connected */
bool buttonChanged;//Indicate if a button has been changed
bool buttonPressed;//Indicate if a button has been pressed
bool buttonReleased;//Indicate if a button has been released
protected:
/* mandatory members */
USB *pUsb;
uint8_t bAddress; // device address
EpInfo epInfo[PS3_MAX_ENDPOINTS]; //endpoint info structure
private:
bool bPollEnable;
uint32_t timer; // used to continuously set PS3 Move controller Bulb and rumble values
uint32_t ButtonState;
uint32_t OldButtonState;
uint8_t my_bdaddr[6]; // Change to your dongles Bluetooth address in PS3BT.cpp
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
void readReport(); // read incoming data
void printReport(); // print incoming date - Uncomment for debugging
/* Private commands */
void PS3_Command(uint8_t* data, uint16_t nbytes);
void enable_sixaxis();//Command used to enable the Dualshock 3 and Navigation controller to send data via USB
void Move_Command(uint8_t* data, uint16_t nbytes);
};
#endif

View file

@ -0,0 +1,202 @@
/*
Example sketch for the PS3 Bluetooth library - developed by Kristian Lauszus
For more information visit my blog: http://blog.tkjelectronics.dk/ or
send me an e-mail: kristianl@tkjelectronics.com
*/
#include <PS3BT.h>
USB Usb;
/* You can create the instance of the class in two ways */
PS3BT PS3(&Usb); // This will just create the instance
//PS3BT PS3(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
boolean printTemperature;
boolean printAngle;
void setup()
{
Serial.begin(115200);
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while(1); //halt
}
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop()
{
Usb.Task();
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117) {
Serial.print(F("LeftHatX: "));
Serial.print(PS3.getAnalogHat(LeftHatX));
Serial.print("\t");
} if(PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117) {
Serial.print(F("LeftHatY: "));
Serial.print(PS3.getAnalogHat(LeftHatY));
Serial.print("\t");
} if(PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117) {
Serial.print(F("RightHatX: "));
Serial.print(PS3.getAnalogHat(RightHatX));
Serial.print("\t");
} if(PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
Serial.print(F("RightHatY: "));
Serial.print(PS3.getAnalogHat(RightHatY));
}
Serial.println("");
}
//Analog button values can be read from almost all buttons
if(PS3.getAnalogButton(L2_ANALOG) > 0 || PS3.getAnalogButton(R2_ANALOG) > 0) {
if(PS3.getAnalogButton(L2_ANALOG) > 0) {
Serial.print(F("L2: "));
Serial.print(PS3.getAnalogButton(L2_ANALOG));
Serial.print("\t");
} if(PS3.getAnalogButton(R2_ANALOG) > 0) {
Serial.print(F("R2: "));
Serial.print(PS3.getAnalogButton(R2_ANALOG));
}
Serial.println("");
}
if(PS3.buttonPressed)
{
Serial.print(F("PS3 Controller"));
if(PS3.getButton(PS)) {
Serial.print(F(" - PS"));
PS3.disconnect();
} else {
if(PS3.getButton(TRIANGLE))
Serial.print(F(" - Traingle"));
if(PS3.getButton(CIRCLE))
Serial.print(F(" - Circle"));
if(PS3.getButton(CROSS))
Serial.print(F(" - Cross"));
if(PS3.getButton(SQUARE))
Serial.print(F(" - Square"));
if(PS3.getButton(UP)) {
Serial.print(F(" - Up"));
PS3.setAllOff();
PS3.setLedOn(LED4);
} if(PS3.getButton(RIGHT)) {
Serial.print(F(" - Right"));
PS3.setAllOff();
PS3.setLedOn(LED1);
} if(PS3.getButton(DOWN)) {
Serial.print(F(" - Down"));
PS3.setAllOff();
PS3.setLedOn(LED2);
} if(PS3.getButton(LEFT)) {
Serial.print(F(" - Left"));
PS3.setAllOff();
PS3.setLedOn(LED3);
}
if(PS3.getButton(L1))
Serial.print(F(" - L1"));
//if(PS3.getButton(L2))
//Serial.print(F(" - L2"));
if(PS3.getButton(L3))
Serial.print(F(" - L3"));
if(PS3.getButton(R1))
Serial.print(F(" - R1"));
//if(PS3.getButton(R2))
//Serial.print(F(" - R2"));
if(PS3.getButton(R3))
Serial.print(F(" - R3"));
if(PS3.getButton(SELECT)) {
Serial.print(F(" - Select - "));
Serial.print(PS3.getStatusString());
} if(PS3.getButton(START)) {
Serial.print(F(" - Start"));
printAngle = !printAngle;
while(PS3.getButton(START))
Usb.Task();
}
Serial.println("");
}
}
if(printAngle) {
Serial.print(F("Pitch: "));
Serial.print(PS3.getAngle(Pitch));
Serial.print(F("\tRoll: "));
Serial.println(PS3.getAngle(Roll));
}
}
else if(PS3.PS3MoveConnected)
{
if(PS3.getAnalogButton(T_MOVE_ANALOG) > 0) {
Serial.print(F("T: "));
Serial.println(PS3.getAnalogButton(T_MOVE_ANALOG));
} if(PS3.buttonPressed) {
Serial.print(F("PS3 Move Controller"));
if(PS3.getButton(PS_MOVE)) {
Serial.print(F(" - PS"));
PS3.disconnect();
} else {
if(PS3.getButton(SELECT_MOVE)) {
Serial.print(F(" - Select"));
printTemperature = !printTemperature;
while(PS3.getButton(SELECT_MOVE))
Usb.Task();
} if(PS3.getButton(START_MOVE)) {
Serial.print(F(" - Start"));
printAngle = !printAngle;
while(PS3.getButton(START_MOVE))
Usb.Task();
} if(PS3.getButton(TRIANGLE_MOVE)) {
Serial.print(F(" - Triangle"));
PS3.moveSetBulb(Red);
} if(PS3.getButton(CIRCLE_MOVE)) {
Serial.print(F(" - Circle"));
PS3.moveSetBulb(Green);
} if(PS3.getButton(SQUARE_MOVE)) {
Serial.print(F(" - Square"));
PS3.moveSetBulb(Blue);
} if(PS3.getButton(CROSS_MOVE)) {
Serial.print(F(" - Cross"));
PS3.moveSetBulb(Yellow);
} if(PS3.getButton(MOVE_MOVE)) {
PS3.moveSetBulb(Off);
Serial.print(F(" - Move"));
Serial.print(F(" - "));
Serial.print(PS3.getStatusString());
}
//if(PS3.getButton(T))
//Serial.print(F(" - T"));
Serial.println("");
}
}
if(printAngle) {
Serial.print(F("Pitch: "));
Serial.print(PS3.getAngle(Pitch));
Serial.print(F("\tRoll: "));
Serial.println(PS3.getAngle(Roll));
}
else if(printTemperature) {
String templow;
String temphigh;
String input = String(PS3.getSensor(tempMove));
if (input.length() > 3) {
temphigh = input.substring(0, 2);
templow = input.substring(2);
} else {
temphigh = input.substring(0, 1);
templow = input.substring(1);
}
Serial.print(F("Temperature: "));
Serial.print(temphigh);
Serial.print(F("."));
Serial.println(templow);
}
}
delay(1);
}

View file

@ -0,0 +1,188 @@
/*
Example sketch for the PS3 USB library - developed by Kristian Lauszus
For more information visit my blog: http://blog.tkjelectronics.dk/ or
send me an e-mail: kristianl@tkjelectronics.com
*/
#include <PS3USB.h>
USB Usb;
/* You can create the instance of the class in two ways */
PS3USB PS3(&Usb); // This will just create the instance
//PS3USB PS3(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
boolean printAngle;
uint8_t state = 0;
void setup() {
Serial.begin(115200);
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while(1); //halt
}
Serial.print(F("\r\nPS3 USB Library Started"));
}
void loop() {
Usb.Task();
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117) {
Serial.print(F("LeftHatX: "));
Serial.print(PS3.getAnalogHat(LeftHatX));
Serial.print("\t");
}
if(PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117) {
Serial.print(F("LeftHatY: "));
Serial.print(PS3.getAnalogHat(LeftHatY));
Serial.print("\t");
}
if(PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117) {
Serial.print(F("RightHatX: "));
Serial.print(PS3.getAnalogHat(RightHatX));
Serial.print("\t");
}
if(PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
Serial.print(F("RightHatY: "));
Serial.print(PS3.getAnalogHat(RightHatY));
}
Serial.println("");
}
// Analog button values can be read from almost all buttons
if(PS3.getAnalogButton(L2_ANALOG) > 0 || PS3.getAnalogButton(R2_ANALOG) > 0) {
if(PS3.getAnalogButton(L2_ANALOG) > 0) {
Serial.print(F("L2: "));
Serial.print(PS3.getAnalogButton(L2_ANALOG));
Serial.print("\t");
}
if(PS3.getAnalogButton(R2_ANALOG) > 0) {
Serial.print(F("R2: "));
Serial.print(PS3.getAnalogButton(R2_ANALOG));
}
Serial.println("");
}
if(PS3.buttonPressed)
{
Serial.print(F("PS3 Controller"));
if(PS3.getButton(PS))
Serial.print(F(" - PS"));
if(PS3.getButton(TRIANGLE))
Serial.print(F(" - Traingle"));
if(PS3.getButton(CIRCLE))
Serial.print(F(" - Circle"));
if(PS3.getButton(CROSS))
Serial.print(F(" - Cross"));
if(PS3.getButton(SQUARE))
Serial.print(F(" - Square"));
if(PS3.getButton(UP)) {
Serial.print(F(" - Up"));
PS3.setAllOff();
PS3.setLedOn(LED4);
}
if(PS3.getButton(RIGHT)) {
Serial.print(F(" - Right"));
PS3.setAllOff();
PS3.setLedOn(LED1);
}
if(PS3.getButton(DOWN)) {
Serial.print(F(" - Down"));
PS3.setAllOff();
PS3.setLedOn(LED2);
}
if(PS3.getButton(LEFT)) {
Serial.print(F(" - Left"));
PS3.setAllOff();
PS3.setLedOn(LED3);
}
if(PS3.getButton(L1))
Serial.print(F(" - L1"));
//if(PS3.getButton(L2))
//Serial.print(F(" - L2"));
if(PS3.getButton(L3))
Serial.print(F(" - L3"));
if(PS3.getButton(R1))
Serial.print(F(" - R1"));
//if(PS3.getButton(R2))
//Serial.print(F(" - R2"));
if(PS3.getButton(R3))
Serial.print(F(" - R3"));
if(PS3.getButton(SELECT)) {
Serial.print(F(" - Select - "));
Serial.print(PS3.getStatusString());
}
if(PS3.getButton(START)) {
Serial.print(F(" - Start"));
printAngle = !printAngle;
while(PS3.getButton(START))
Usb.Task();
}
Serial.println("");
}
if(printAngle) {
Serial.print(F("Pitch: "));
Serial.print(PS3.getAngle(Pitch));
Serial.print(F("\tRoll: "));
Serial.println(PS3.getAngle(Roll));
}
}
else if(PS3.PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
switch(state) {
case 0:
PS3.moveSetRumble(0);
PS3.moveSetBulb(Off);
state = 1;
break;
case 1:
PS3.moveSetRumble(75);
PS3.moveSetBulb(Red);
state = 2;
break;
case 2:
PS3.moveSetRumble(125);
PS3.moveSetBulb(Green);
state = 3;
break;
case 3:
PS3.moveSetRumble(150);
PS3.moveSetBulb(Blue);
state = 4;
break;
case 4:
PS3.moveSetRumble(175);
PS3.moveSetBulb(Yellow);
state = 5;
break;
case 5:
PS3.moveSetRumble(200);
PS3.moveSetBulb(Lightblue);
state = 6;
break;
case 6:
PS3.moveSetRumble(225);
PS3.moveSetBulb(Purble);
state = 7;
break;
case 7:
PS3.moveSetRumble(250);
PS3.moveSetBulb(White);
state = 0;
break;
}
delay(1000);
}
}

View file

@ -1,202 +0,0 @@
/*
Example sketch for the PS3 Bluetooth library - developed by Kristian Lauszus
For more information visit my blog: http://blog.tkjelectronics.dk/ or
send me an e-mail: kristianl@tkjelectronics.com
*/
#include <PS3BT.h>
USB Usb;
/* You can create the instance of the class in two ways */
PS3BT BT(&Usb); // This will just create the instance
//PS3BT BT(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
boolean printTemperature;
boolean printAngle;
void setup()
{
Serial.begin(115200);
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while(1); //halt
}
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop()
{
Usb.Task();
if(BT.PS3BTConnected || BT.PS3NavigationBTConnected) {
if(BT.getAnalogHat(LeftHatX) > 137 || BT.getAnalogHat(LeftHatX) < 117 || BT.getAnalogHat(LeftHatY) > 137 || BT.getAnalogHat(LeftHatY) < 117 || BT.getAnalogHat(RightHatX) > 137 || BT.getAnalogHat(RightHatX) < 117 || BT.getAnalogHat(RightHatY) > 137 || BT.getAnalogHat(RightHatY) < 117) {
if(BT.getAnalogHat(LeftHatX) > 137 || BT.getAnalogHat(LeftHatX) < 117) {
Serial.print(F("LeftHatX: "));
Serial.print(BT.getAnalogHat(LeftHatX));
Serial.print("\t");
} if(BT.getAnalogHat(LeftHatY) > 137 || BT.getAnalogHat(LeftHatY) < 117) {
Serial.print(F("LeftHatY: "));
Serial.print(BT.getAnalogHat(LeftHatY));
Serial.print("\t");
} if(BT.getAnalogHat(RightHatX) > 137 || BT.getAnalogHat(RightHatX) < 117) {
Serial.print(F("RightHatX: "));
Serial.print(BT.getAnalogHat(RightHatX));
Serial.print("\t");
} if(BT.getAnalogHat(RightHatY) > 137 || BT.getAnalogHat(RightHatY) < 117) {
Serial.print(F("RightHatY: "));
Serial.print(BT.getAnalogHat(RightHatY));
}
Serial.println("");
}
//Analog button values can be read from almost all buttons
if(BT.getAnalogButton(L2_ANALOG) > 0 || BT.getAnalogButton(R2_ANALOG) > 0) {
if(BT.getAnalogButton(L2_ANALOG) > 0) {
Serial.print(F("L2: "));
Serial.print(BT.getAnalogButton(L2_ANALOG));
Serial.print("\t");
} if(BT.getAnalogButton(R2_ANALOG) > 0) {
Serial.print(F("R2: "));
Serial.print(BT.getAnalogButton(R2_ANALOG));
}
Serial.println("");
}
if(BT.buttonPressed)
{
Serial.print(F("PS3 Controller"));
if(BT.getButton(PS)) {
Serial.print(F(" - PS"));
BT.disconnect();
} else {
if(BT.getButton(TRIANGLE))
Serial.print(F(" - Traingle"));
if(BT.getButton(CIRCLE))
Serial.print(F(" - Circle"));
if(BT.getButton(CROSS))
Serial.print(F(" - Cross"));
if(BT.getButton(SQUARE))
Serial.print(F(" - Square"));
if(BT.getButton(UP)) {
Serial.print(F(" - Up"));
BT.setAllOff();
BT.setLedOn(LED4);
} if(BT.getButton(RIGHT)) {
Serial.print(F(" - Right"));
BT.setAllOff();
BT.setLedOn(LED1);
} if(BT.getButton(DOWN)) {
Serial.print(F(" - Down"));
BT.setAllOff();
BT.setLedOn(LED2);
} if(BT.getButton(LEFT)) {
Serial.print(F(" - Left"));
BT.setAllOff();
BT.setLedOn(LED3);
}
if(BT.getButton(L1))
Serial.print(F(" - L1"));
//if(BT.getButton(L2))
//Serial.print(F(" - L2"));
if(BT.getButton(L3))
Serial.print(F(" - L3"));
if(BT.getButton(R1))
Serial.print(F(" - R1"));
//if(BT.getButton(R2))
//Serial.print(F(" - R2"));
if(BT.getButton(R3))
Serial.print(F(" - R3"));
if(BT.getButton(SELECT)) {
Serial.print(F(" - Select - "));
Serial.print(BT.getStatusString());
} if(BT.getButton(START)) {
Serial.print(F(" - Start"));
printAngle = !printAngle;
while(BT.getButton(START))
Usb.Task();
}
Serial.println("");
}
}
if(printAngle) {
Serial.print(F("Pitch: "));
Serial.print(BT.getAngle(Pitch));
Serial.print(F("\tRoll: "));
Serial.println(BT.getAngle(Roll));
}
}
else if(BT.PS3MoveBTConnected)
{
if(BT.getAnalogButton(T_MOVE_ANALOG) > 0) {
Serial.print(F("T: "));
Serial.println(BT.getAnalogButton(T_MOVE_ANALOG));
} if(BT.buttonPressed) {
Serial.print(F("PS3 Move Controller"));
if(BT.getButton(PS_MOVE)) {
Serial.print(F(" - PS"));
BT.disconnect();
} else {
if(BT.getButton(SELECT_MOVE)) {
Serial.print(F(" - Select"));
printTemperature = !printTemperature;
while(BT.getButton(SELECT_MOVE))
Usb.Task();
} if(BT.getButton(START_MOVE)) {
Serial.print(F(" - Start"));
printAngle = !printAngle;
while(BT.getButton(START_MOVE))
Usb.Task();
} if(BT.getButton(TRIANGLE_MOVE)) {
Serial.print(F(" - Triangle"));
BT.moveSetBulb(Red);
} if(BT.getButton(CIRCLE_MOVE)) {
Serial.print(F(" - Circle"));
BT.moveSetBulb(Green);
} if(BT.getButton(SQUARE_MOVE)) {
Serial.print(F(" - Square"));
BT.moveSetBulb(Blue);
} if(BT.getButton(CROSS_MOVE)) {
Serial.print(F(" - Cross"));
BT.moveSetBulb(Yellow);
} if(BT.getButton(MOVE_MOVE)) {
BT.moveSetBulb(Off);
Serial.print(F(" - Move"));
Serial.print(F(" - "));
Serial.print(BT.getStatusString());
}
//if(BT.getButton(T))
//Serial.print(F(" - T"));
Serial.println("");
}
}
if(printAngle) {
Serial.print(F("Pitch: "));
Serial.print(BT.getAngle(Pitch));
Serial.print(F("\tRoll: "));
Serial.println(BT.getAngle(Roll));
}
else if(printTemperature) {
String templow;
String temphigh;
String input = String(BT.getSensor(tempMove));
if (input.length() > 3) {
temphigh = input.substring(0, 2);
templow = input.substring(2);
} else {
temphigh = input.substring(0, 1);
templow = input.substring(1);
}
Serial.print(F("Temperature: "));
Serial.print(temphigh);
Serial.print(F("."));
Serial.println(templow);
}
}
delay(1);
}

View file

@ -1,16 +1,17 @@
################################################ ####################################################
# Syntax Coloring Map For PS3 Bluetooth Library # Syntax Coloring Map For PS3 Bluetooth/USB Library
################################################ ####################################################
################################################ ####################################################
# Datatypes (KEYWORD1) # Datatypes (KEYWORD1)
################################################ ####################################################
PS3BT KEYWORD1 PS3BT KEYWORD1
PS3USB KEYWORD1
################################################ ####################################################
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
################################################ ####################################################
setBdaddr KEYWORD2 setBdaddr KEYWORD2
setMoveBdaddr KEYWORD2 setMoveBdaddr KEYWORD2
@ -32,18 +33,18 @@ setLedToggle KEYWORD2
moveSetBulb KEYWORD2 moveSetBulb KEYWORD2
moveSetRumble KEYWORD2 moveSetRumble KEYWORD2
PS3BTConnected KEYWORD2 PS3Connected KEYWORD2
PS3MoveBTConnected KEYWORD2 PS3MoveConnected KEYWORD2
PS3NavigationBTConnected KEYWORD2 PS3NavigationConnected KEYWORD2
buttonChanged KEYWORD2 buttonChanged KEYWORD2
buttonPressed KEYWORD2 buttonPressed KEYWORD2
buttonReleased KEYWORD2 buttonReleased KEYWORD2
isWatingForConnection KEYWORD2 isWatingForConnection KEYWORD2
################################################ ####################################################
# Constants and enums (LITERAL1) # Constants and enums (LITERAL1)
################################################ ####################################################
LED1 LITERAL1 LED1 LITERAL1
LED2 LITERAL1 LED2 LITERAL1
LED3 LITERAL1 LED3 LITERAL1