mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Can now read the IMU and touchpad values of the PS4 controller via Bluetooth as well
Thanks to Frank Zhao - see: http://eleccelerator.com/wiki/index.php?title=DualShock_4#0x11
This commit is contained in:
parent
e2bf041286
commit
2a1db31cf1
7 changed files with 71 additions and 21 deletions
|
@ -202,7 +202,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
if(pRptParser[MOUSE_PARSER_ID])
|
if(pRptParser[MOUSE_PARSER_ID])
|
||||||
pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast<HID *>(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
|
pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast<HID *>(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
|
||||||
break;
|
break;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef EXTRADEBUG
|
||||||
default:
|
default:
|
||||||
Notify(PSTR("\r\nUnknown Report type: "), 0x80);
|
Notify(PSTR("\r\nUnknown Report type: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
|
|
28
BTHID.h
28
BTHID.h
|
@ -126,8 +126,20 @@ protected:
|
||||||
}
|
}
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
/** Pointer to BTD instance */
|
||||||
|
BTD *pBtd;
|
||||||
|
|
||||||
|
/** HCI Handle for connection */
|
||||||
|
uint16_t hci_handle;
|
||||||
|
|
||||||
|
/** L2CAP source CID for HID_Control */
|
||||||
|
|
||||||
|
uint8_t control_scid[2];
|
||||||
|
|
||||||
|
/** L2CAP source CID for HID_Interrupt */
|
||||||
|
uint8_t interrupt_scid[2];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BTD *pBtd; // Pointer to BTD instance
|
|
||||||
HIDReportParser *pRptParser[NUM_PARSERS]; // Pointer to HIDReportParsers.
|
HIDReportParser *pRptParser[NUM_PARSERS]; // Pointer to HIDReportParsers.
|
||||||
|
|
||||||
/** Set report protocol. */
|
/** Set report protocol. */
|
||||||
|
@ -148,19 +160,13 @@ private:
|
||||||
|
|
||||||
void L2CAP_task(); // L2CAP state machine
|
void L2CAP_task(); // L2CAP state machine
|
||||||
|
|
||||||
/* Variables filled from HCI event management */
|
|
||||||
uint16_t hci_handle;
|
|
||||||
bool activeConnection; // Used to indicate if it already has established a connection
|
bool activeConnection; // Used to indicate if it already has established a connection
|
||||||
|
|
||||||
/* Variables used by high level L2CAP task */
|
/* Variables used for L2CAP communication */
|
||||||
|
uint8_t control_dcid[2]; // L2CAP device CID for HID_Control - Always 0x0070
|
||||||
|
uint8_t interrupt_dcid[2]; // L2CAP device CID for HID_Interrupt - Always 0x0071
|
||||||
|
uint8_t identifier; // Identifier for connection
|
||||||
uint8_t l2cap_state;
|
uint8_t l2cap_state;
|
||||||
uint32_t l2cap_event_flag; // l2cap flags of received Bluetooth events
|
uint32_t l2cap_event_flag; // l2cap flags of received Bluetooth events
|
||||||
|
|
||||||
/* L2CAP Channels */
|
|
||||||
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
|
|
||||||
uint8_t control_dcid[2]; // 0x0070
|
|
||||||
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
|
||||||
uint8_t interrupt_dcid[2]; // 0x0071
|
|
||||||
uint8_t identifier; // Identifier for connection
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
13
PS4BT.h
13
PS4BT.h
|
@ -72,6 +72,7 @@ protected:
|
||||||
* This is useful for instance if you want to set the LEDs in a specific way.
|
* This is useful for instance if you want to set the LEDs in a specific way.
|
||||||
*/
|
*/
|
||||||
virtual void OnInitBTHID() {
|
virtual void OnInitBTHID() {
|
||||||
|
enable_sixaxis(); // Make the controller to send out the entire output report
|
||||||
if (pFuncOnInit)
|
if (pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
};
|
};
|
||||||
|
@ -84,5 +85,17 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||||
|
|
||||||
|
void HID_Command(uint8_t *data, uint8_t nbytes) {
|
||||||
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
void enable_sixaxis() { // Command used to make the PS4 controller send out the entire output report
|
||||||
|
uint8_t buf[2];
|
||||||
|
buf[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03)
|
||||||
|
buf[1] = 0x02; // Report ID
|
||||||
|
|
||||||
|
HID_Command(buf, 2);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -76,17 +76,22 @@ uint8_t PS4Parser::getAnalogHat(AnalogHatEnum a) {
|
||||||
void PS4Parser::Parse(uint8_t len, uint8_t *buf) {
|
void PS4Parser::Parse(uint8_t len, uint8_t *buf) {
|
||||||
if (len > 0 && buf) {
|
if (len > 0 && buf) {
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
D_PrintHex<uint8_t > (buf[i], 0x80);
|
D_PrintHex<uint8_t > (buf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy(&ps4Data, buf, min(len, sizeof(ps4Data)));
|
|
||||||
if (ps4Data.reportId != 0x01) {
|
if (buf[0] == 0x01) // Check report ID
|
||||||
|
memcpy(&ps4Data, buf + 1, min(len - 1, sizeof(ps4Data)));
|
||||||
|
else if (buf[0] == 0x11) // This report is send via Bluetooth, it has an offset of 2 compared to the USB data
|
||||||
|
memcpy(&ps4Data, buf + 3, min(len - 3, sizeof(ps4Data)));
|
||||||
|
else {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nUnknown report id"), 0x80);
|
Notify(PSTR("\r\nUnknown report id: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (buf[0], 0x80);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@ struct touchpadXY {
|
||||||
|
|
||||||
struct PS4Data {
|
struct PS4Data {
|
||||||
/* Button and joystick values */
|
/* Button and joystick values */
|
||||||
uint8_t reportId; // Always 0x01
|
|
||||||
uint8_t hatValue[4];
|
uint8_t hatValue[4];
|
||||||
PS4Buttons btn;
|
PS4Buttons btn;
|
||||||
uint8_t trigger[2];
|
uint8_t trigger[2];
|
||||||
|
|
|
@ -124,8 +124,6 @@ The [PS4BT.ino](examples/Bluetooth/PS4BT/PS4BT.ino) and [PS4USB.ino](examples/PS
|
||||||
|
|
||||||
I still have not figured out how to turn rumble on and off and set the color of the light, but hopefully I will figure that out soon.
|
I still have not figured out how to turn rumble on and off and set the color of the light, but hopefully I will figure that out soon.
|
||||||
|
|
||||||
Also the gyro, accelerometer and touchpad values are still only available via USB at the moment.
|
|
||||||
|
|
||||||
Before you can use the PS4 controller via Bluetooth you will need to pair with it.
|
Before you can use the PS4 controller via Bluetooth you will need to pair with it.
|
||||||
|
|
||||||
Simply create the PS4BT instance like so: ```PS4BT PS4(&Btd, PAIR);``` and then hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in paring mode.
|
Simply create the PS4BT instance like so: ```PS4BT PS4(&Btd, PAIR);``` and then hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in paring mode.
|
||||||
|
@ -134,6 +132,8 @@ It should then automatically pair the dongle with your controller. This only hav
|
||||||
|
|
||||||
For information see the following blog post: <http://blog.tkjelectronics.dk/2014/01/ps4-controller-now-supported-by-the-usb-host-library/>.
|
For information see the following blog post: <http://blog.tkjelectronics.dk/2014/01/ps4-controller-now-supported-by-the-usb-host-library/>.
|
||||||
|
|
||||||
|
Also check out this excellent Wiki by Frank Zhao about the PS4 controller: <http://eleccelerator.com/wiki/index.php?title=DualShock_4>.
|
||||||
|
|
||||||
### PS3 Library
|
### PS3 Library
|
||||||
|
|
||||||
These libraries consist of the [PS3BT](PS3BT.cpp) and [PS3USB](PS3USB.cpp). These libraries allows you to use a Dualshock 3, Navigation or a Motion controller with the USB Host Shield both via Bluetooth and USB.
|
These libraries consist of the [PS3BT](PS3BT.cpp) and [PS3USB](PS3USB.cpp). These libraries allows you to use a Dualshock 3, Navigation or a Motion controller with the USB Host Shield both via Bluetooth and USB.
|
||||||
|
|
|
@ -24,6 +24,8 @@ PS4BT PS4(&Btd, PAIR);
|
||||||
// After that you can simply create the instance like so and then press the PS button on the device
|
// After that you can simply create the instance like so and then press the PS button on the device
|
||||||
//PS4BT PS4(&Btd);
|
//PS4BT PS4(&Btd);
|
||||||
|
|
||||||
|
boolean printAngle, printTouch;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||||
|
@ -88,10 +90,35 @@ void loop() {
|
||||||
|
|
||||||
if (PS4.getButtonClick(SHARE))
|
if (PS4.getButtonClick(SHARE))
|
||||||
Serial.print(F("\r\nShare"));
|
Serial.print(F("\r\nShare"));
|
||||||
if (PS4.getButtonClick(OPTIONS))
|
if (PS4.getButtonClick(OPTIONS)) {
|
||||||
Serial.print(F("\r\nOptions"));
|
Serial.print(F("\r\nOptions"));
|
||||||
if (PS4.getButtonClick(TOUCHPAD))
|
printAngle = !printAngle;
|
||||||
|
}
|
||||||
|
if (PS4.getButtonClick(TOUCHPAD)) {
|
||||||
Serial.print(F("\r\nTouchpad"));
|
Serial.print(F("\r\nTouchpad"));
|
||||||
|
printTouch = !printTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printAngle) { // Print angle calculated using the accelerometer only
|
||||||
|
Serial.print(F("\r\nPitch: "));
|
||||||
|
Serial.print(PS4.getAngle(Pitch));
|
||||||
|
Serial.print(F("\tRoll: "));
|
||||||
|
Serial.print(PS4.getAngle(Roll));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printTouch) { // Print the x, y coordinates of the touchpad
|
||||||
|
if (PS4.isTouching(0) || PS4.isTouching(1)) // Print newline and carriage return if any of the fingers are touching the touchpad
|
||||||
|
Serial.print(F("\r\n"));
|
||||||
|
for (uint8_t i = 0; i < 2; i++) { // The touchpad track two fingers
|
||||||
|
if (PS4.isTouching(i)) { // Print the position of the finger if it is touching the touchpad
|
||||||
|
Serial.print(F("X")); Serial.print(i + 1); Serial.print(F(": "));
|
||||||
|
Serial.print(PS4.getX(i));
|
||||||
|
Serial.print(F("\tY")); Serial.print(i + 1); Serial.print(F(": "));
|
||||||
|
Serial.print(PS4.getY(i));
|
||||||
|
Serial.print(F("\t"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue