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])
|
||||
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;
|
||||
#ifdef DEBUG_USB_HOST
|
||||
#ifdef EXTRADEBUG
|
||||
default:
|
||||
Notify(PSTR("\r\nUnknown Report type: "), 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:
|
||||
BTD *pBtd; // Pointer to BTD instance
|
||||
HIDReportParser *pRptParser[NUM_PARSERS]; // Pointer to HIDReportParsers.
|
||||
|
||||
/** Set report protocol. */
|
||||
|
@ -148,19 +160,13 @@ private:
|
|||
|
||||
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
|
||||
|
||||
/* 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;
|
||||
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
|
||||
|
|
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.
|
||||
*/
|
||||
virtual void OnInitBTHID() {
|
||||
enable_sixaxis(); // Make the controller to send out the entire output report
|
||||
if (pFuncOnInit)
|
||||
pFuncOnInit(); // Call the user function
|
||||
};
|
||||
|
@ -84,5 +85,17 @@ protected:
|
|||
|
||||
private:
|
||||
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
|
|
@ -76,17 +76,22 @@ uint8_t PS4Parser::getAnalogHat(AnalogHatEnum a) {
|
|||
void PS4Parser::Parse(uint8_t len, uint8_t *buf) {
|
||||
if (len > 0 && buf) {
|
||||
#ifdef PRINTREPORT
|
||||
Notify(PSTR("\r\n"), 0x80);
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
D_PrintHex<uint8_t > (buf[i], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
}
|
||||
Notify(PSTR("\r\n"), 0x80);
|
||||
#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
|
||||
Notify(PSTR("\r\nUnknown report id"), 0x80);
|
||||
Notify(PSTR("\r\nUnknown report id: "), 0x80);
|
||||
D_PrintHex<uint8_t > (buf[0], 0x80);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@ struct touchpadXY {
|
|||
|
||||
struct PS4Data {
|
||||
/* Button and joystick values */
|
||||
uint8_t reportId; // Always 0x01
|
||||
uint8_t hatValue[4];
|
||||
PS4Buttons btn;
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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/>.
|
||||
|
||||
Also check out this excellent Wiki by Frank Zhao about the PS4 controller: <http://eleccelerator.com/wiki/index.php?title=DualShock_4>.
|
||||
|
||||
### 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.
|
||||
|
|
|
@ -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
|
||||
//PS4BT PS4(&Btd);
|
||||
|
||||
boolean printAngle, printTouch;
|
||||
|
||||
void setup() {
|
||||
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
|
||||
|
@ -88,10 +90,35 @@ void loop() {
|
|||
|
||||
if (PS4.getButtonClick(SHARE))
|
||||
Serial.print(F("\r\nShare"));
|
||||
if (PS4.getButtonClick(OPTIONS))
|
||||
if (PS4.getButtonClick(OPTIONS)) {
|
||||
Serial.print(F("\r\nOptions"));
|
||||
if (PS4.getButtonClick(TOUCHPAD))
|
||||
printAngle = !printAngle;
|
||||
}
|
||||
if (PS4.getButtonClick(TOUCHPAD)) {
|
||||
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