diff --git a/BTHID.cpp b/BTHID.cpp index 00b09085..d0d93c2e 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -336,11 +336,11 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { Notify(PSTR(" "), 0x80); } #endif - if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT + if(l2capinbuf[8] == 0xA1) { // HID BT DATA (0xA0) | Report Type (Input 0x01) uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); - ParseBTHIDData((uint8_t)(length - 1), &l2capinbuf[9]); + ParseBTHIDData((uint8_t)(length - 1), &l2capinbuf[9]); // First byte will be the report ID - switch(l2capinbuf[9]) { + switch(l2capinbuf[9]) { // Report ID case 0x01: // Keyboard or Joystick events if(pRptParser[KEYBOARD_PARSER_ID]) pRptParser[KEYBOARD_PARSER_ID]->Parse(reinterpret_cast(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance @@ -357,6 +357,11 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { break; #endif } + } else { +#ifdef EXTRADEBUG + Notify(PSTR("\r\nUnhandled L2CAP interrupt report: "), 0x80); + D_PrintHex (l2capinbuf[8], 0x80); +#endif } } else if(l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) { // l2cap_control #ifdef PRINTREPORT @@ -366,9 +371,14 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { Notify(PSTR(" "), 0x80); } #endif - if(l2capinbuf[8] == 0xA3) { + if(l2capinbuf[8] == 0xA3) { // HID BT DATA (0xA0) | Report Type (Feature 0x03) uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); - ParseBTHIDControlData((uint8_t)(length - 1), &l2capinbuf[9]); + ParseBTHIDControlData((uint8_t)(length - 1), &l2capinbuf[9]); // First byte will be the report ID + } else { +#ifdef EXTRADEBUG + Notify(PSTR("\r\nUnhandled L2CAP control report: "), 0x80); + D_PrintHex (l2capinbuf[8], 0x80); +#endif } } #ifdef EXTRADEBUG diff --git a/PS5BT.h b/PS5BT.h index e00f0351..dbb3c8a6 100644 --- a/PS5BT.h +++ b/PS5BT.h @@ -21,7 +21,12 @@ #include "BTHID.h" #include "PS5Parser.h" -/*const uint32_t crc32_table[] PROGMEM = { +/** + * Generated from the standard Ethernet CRC-32 polynomial: + * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 + * Source: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c + */ +const uint32_t crc32_table[] PROGMEM = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, @@ -67,76 +72,35 @@ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -uint32_t crc32(uint8_t *buffer, size_t length) { // Inspired by: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c and http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=28214 - uint32_t crc = ~0L; // Initial value - for (size_t i = 0; i < length; i++) - crc = (crc >> 8) ^ pgm_read_dword(&crc32_table[*buffer++ ^ (crc & 0xFF)]); - return ~crc; -};*/ - /* * There are multiple 16-bit CRC polynomials in common use, but this is * *the* standard CRC-32 polynomial, first popularized by Ethernet. * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 */ -#if 0 #define CRC32_POLY_LE 0xedb88320 -#define CRC32_POLY_BE 0x04c11db7 -#define CRC_LE_BITS 1 - -typedef uint32_t u32; - -static inline u32 crc32_le_generic(u32 crc, unsigned char const *p, size_t len, const u32 (*tab)[256], u32 polynomial) -{ -#if CRC_LE_BITS == 1 +static inline uint32_t crc32_le_generic(uint32_t crc, uint8_t const *p, size_t len, uint32_t polynomial) { + // Source: https://github.com/torvalds/linux/blob/c4cf498dc0241fa2d758dba177634268446afb06/lib/crc32.c int i; while (len--) { crc ^= *p++; for (i = 0; i < 8; i++) crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); } -# elif CRC_LE_BITS == 2 - while (len--) { - crc ^= *p++; - crc = (crc >> 2) ^ tab[0][crc & 3]; - crc = (crc >> 2) ^ tab[0][crc & 3]; - crc = (crc >> 2) ^ tab[0][crc & 3]; - crc = (crc >> 2) ^ tab[0][crc & 3]; - } -# elif CRC_LE_BITS == 4 - while (len--) { - crc ^= *p++; - crc = (crc >> 4) ^ tab[0][crc & 15]; - crc = (crc >> 4) ^ tab[0][crc & 15]; - } -# elif CRC_LE_BITS == 8 - /* aka Sarwate algorithm */ - while (len--) { - crc ^= *p++; - crc = (crc >> 8) ^ tab[0][crc & 255]; - } -# else - crc = (__force u32) __cpu_to_le32(crc); - crc = crc32_body(crc, p, len, tab); - crc = __le32_to_cpu((__force __le32)crc); -#endif return crc; } -#if CRC_LE_BITS == 1 -static u32 crc32_le(u32 crc, unsigned char const *p, size_t len) -{ - return crc32_le_generic(crc, p, len, NULL, CRC32_POLY_LE); -} -#else -static u32 crc32_le(u32 crc, unsigned char const *p, size_t len) -{ - return crc32_le_generic(crc, p, len, (const u32 (*)[256])crc32table_le, CRC32_POLY_LE); -} -#endif - +static inline uint32_t crc32(uint32_t crc, const void *buf, size_t size) { +#if 1 // Use a table, as it's faster, but takes up more space + // Inspired by: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c + const uint8_t *p = (const uint8_t*)buf; + while (size--) + crc = pgm_read_dword(&crc32_table[*p++ ^ (crc & 0xFF)]) ^ (crc >> 8); + return crc; +#else // Can be used to save flash, but is slower + return crc32_le_generic(crc, (uint8_t const*)buf, size, CRC32_POLY_LE); #endif +}; /** * This class implements support for the PS5 controller via Bluetooth. @@ -151,7 +115,7 @@ public: * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used. */ PS5BT(BTD *p, bool pair = false, const char *pin = "0000") : - BTHID(p, pair, pin) { + BTHID(p, pair, pin), output_sequence_counter(0) { PS5Parser::Reset(); }; @@ -182,10 +146,10 @@ protected: virtual void OnInitBTHID() { PS5Parser::Reset(); enable_sixaxis(); // Make the controller send out the entire output report - if (pFuncOnInit) - pFuncOnInit(); // Call the user function - else - setLed(Blue); + + // Only call this is a user function has not been set + if (!pFuncOnInit) + setLed(Red); // Set the LED to red, as the PS5 controller turns Bluetooth when searching for a device }; /** Used to reset the different buffers to there default values */ @@ -196,20 +160,17 @@ protected: /** @name PS5Parser implementation */ virtual void sendOutputReport(PS5Output *output) { -#if 1 - return; // TODO: Fix this -#else - // See the series of patches here: https://patchwork.kernel.org/project/linux-input/patch/20201219062336.72568-14-roderick@gaikai.com/ - - uint8_t buf[1 /* BT Set Output Report */ + 1 /* report id */ + 1 /* seq_tag */ + 1 /* tag */ + 47 /* common */ + 24 /* reserved */ + 4 /* crc32 */]; + // See the series of patches here: https://patchwork.kernel.org/project/linux-input/cover/20201219062336.72568-1-roderick@gaikai.com/ + uint8_t buf[1 /* BT DATA Output Report */ + 1 /* report id */ + 1 /* seq_tag */ + 1 /* tag */ + 47 /* common */ + 24 /* reserved */ + 4 /* crc32 */]; memset(buf, 0, sizeof(buf)); - buf[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02) + // Send as a Bluetooth HID DATA output report on the interrupt channel + buf[0] = 0xA2; // HID BT DATA (0xA0) | Report Type (Output 0x02) buf[0x01] = 0x31; // Report ID - buf[0x02] = (output_sequence << 4) | 0x0; // Highest 4-bit is a sequence number, which needs to be increased every report. Lowest 4-bit is tag and can be zero for now. - if(++output_sequence == 15) - output_sequence = 0; + buf[0x02] = (output_sequence_counter << 4) | 0x0; // Highest 4-bit is a sequence number, which needs to be increased every report. Lowest 4-bit is tag and can be zero for now. + if(++output_sequence_counter == 15) + output_sequence_counter = 0; buf[0x03] = 0x10; // Magic number must be set to 0x10 buf[0x01 + 3] = 0xFF; // feature flags 1 @@ -243,40 +204,30 @@ protected: buf[0x2E + 3] = output->g; // Green buf[0x2F + 3] = output->b; // Blue - //uint32_t crc = crc32(&buf[1], 79 - 1 /* do not include the BT Set Output Report */ - 4 /* crc */); - - uint8_t seed = 0xA2; - uint32_t crc = crc32_le(0xFFFFFFFF, &seed, 1); - crc = ~crc32_le(crc, &buf[1], 79 - 1 /* do not include the BT Set Output Report */ - 4 /* crc */); - - buf[75] = crc; - buf[76] = crc >> 8; - buf[77] = crc >> 16; - buf[78] = crc >> 24; + uint32_t crc = ~crc32(0xFFFFFFFF, buf, sizeof(buf) - 4 /* Do not include the crc32 */); // Note how the report type is also included in the output report + buf[75] = crc & 0xFF; + buf[76] = (crc >> 8) & 0xFF; + buf[77] = (crc >> 16); + buf[78] = (crc >> 24); output->reportChanged = false; - // The PS5 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed - - HID_Command(buf, sizeof(buf)); -#endif + // Send the Bluetooth DATA output report on the interrupt channel + pBtd->L2CAP_Command(hci_handle, buf, sizeof(buf), interrupt_scid[0], interrupt_scid[1]); }; /**@}*/ private: - uint8_t output_sequence = 0; - void enable_sixaxis() { // Command used to make the PS5 controller send out the entire output report - // Request the paring info. This makes the controller send out the full report - see: https://patchwork.kernel.org/project/linux-input/patch/20201219062336.72568-14-roderick@gaikai.com/ + // Request the paring info. This makes the controller send out the full report - see: https://patchwork.kernel.org/project/linux-input/cover/20201219062336.72568-1-roderick@gaikai.com/ uint8_t buf[2]; buf[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03) - buf[1] = 9; // Report ID for paring info + buf[1] = 0x09; // Report ID for paring info - HID_Command(buf, 2); + // Send the Bluetooth Get_report Feature report on the control channel + pBtd->L2CAP_Command(hci_handle, buf, 2, control_scid[0], control_scid[1]); }; - void HID_Command(uint8_t *data, uint8_t nbytes) { - pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); - }; + uint8_t output_sequence_counter; }; #endif diff --git a/PS5Parser.cpp b/PS5Parser.cpp index 1a28e82e..fa3576c2 100644 --- a/PS5Parser.cpp +++ b/PS5Parser.cpp @@ -16,7 +16,7 @@ Thanks to Joseph Duchesne for the initial code. Based on Ludwig Füchsl's https://github.com/Ohjurot/DualSense-Windows PS5 port - and the series of patches found here: https://patchwork.kernel.org/project/linux-input/patch/20201219062336.72568-14-roderick@gaikai.com/ + and the series of patches found here: https://patchwork.kernel.org/project/linux-input/cover/20201219062336.72568-1-roderick@gaikai.com/ */ #include "PS5Parser.h" @@ -80,7 +80,8 @@ uint8_t PS5Parser::getAnalogHat(AnalogHatEnum a) { void PS5Parser::Parse(uint8_t len, uint8_t *buf) { if (len > 1 && buf) { #ifdef PRINTREPORT - Notify(PSTR("\r\n"), 0x80); + Notify(PSTR("\r\nLen: "), 0x80); Notify(len, 0x80); + Notify(PSTR(", data: "), 0x80); for (uint8_t i = 0; i < len; i++) { D_PrintHex (buf[i], 0x80); Notify(PSTR(" "), 0x80); @@ -89,7 +90,7 @@ void PS5Parser::Parse(uint8_t len, uint8_t *buf) { if (buf[0] == 0x01) // Check report ID memcpy(&ps5Data, buf + 1, min((uint8_t)(len - 1), MFK_CASTUINT8T sizeof(ps5Data))); - else if (buf[0] == 0x31) { // This report is send via Bluetooth, it has an offset of 2 compared to the USB data + else if (buf[0] == 0x31) { // This report is send via Bluetooth, it has an offset of 1 compared to the USB data if (len < 3) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nReport is too short: "), 0x80); @@ -127,8 +128,9 @@ void PS5Parser::Parse(uint8_t len, uint8_t *buf) { oldDpad = newDpad; } } + + message_counter++; } - message_counter++; if (ps5Output.reportChanged || leftTrigger.reportChanged || rightTrigger.reportChanged) sendOutputReport(&ps5Output); // Send output report diff --git a/PS5Parser.h b/PS5Parser.h index 3286d6df..df7eb3b2 100644 --- a/PS5Parser.h +++ b/PS5Parser.h @@ -16,7 +16,7 @@ Thanks to Joseph Duchesne for the initial code. Based on Ludwig Füchsl's https://github.com/Ohjurot/DualSense-Windows PS5 port - and the series of patches found here: https://patchwork.kernel.org/project/linux-input/patch/20201219062336.72568-14-roderick@gaikai.com/ + and the series of patches found here: https://patchwork.kernel.org/project/linux-input/cover/20201219062336.72568-1-roderick@gaikai.com/ */ #ifndef _ps5parser_h_ @@ -146,14 +146,14 @@ struct PS5Output { /** This class parses all the data sent by the PS5 controller */ class PS5Parser { public: - PS5Trigger leftTrigger; - PS5Trigger rightTrigger; - /** Constructor for the PS5Parser class. */ PS5Parser() : leftTrigger(), rightTrigger() { Reset(); }; + /** Used these to manipulate the haptic triggers */ + PS5Trigger leftTrigger, rightTrigger; + /** @name PS5 Controller functions */ /** * getButtonPress(ButtonEnum b) will return true as long as the button is held down. @@ -227,9 +227,9 @@ public: */ float getAngle(AngleEnum a) { if (a == Pitch) - return (atan2f(ps5Data.accY, ps5Data.accZ) + PI) * RAD_TO_DEG; + return (atan2f(-ps5Data.accY, -ps5Data.accZ) + PI) * RAD_TO_DEG; else - return (atan2f(ps5Data.accX, ps5Data.accZ) + PI) * RAD_TO_DEG; + return (atan2f(ps5Data.accX, -ps5Data.accZ) + PI) * RAD_TO_DEG; }; /** @@ -356,6 +356,7 @@ public: */ void setPlayerLed(uint8_t mask) { ps5Output.playerLeds = mask; + ps5Output.reportChanged = true; } /** Use to turn the microphone LED off. */ @@ -369,6 +370,7 @@ public: */ void setMicLed(bool on) { ps5Output.microphoneLed = on ? 1 : 0; + ps5Output.reportChanged = true; } /** Get the incoming message count. */ diff --git a/PS5USB.h b/PS5USB.h index b656f161..7c7ee793 100644 --- a/PS5USB.h +++ b/PS5USB.h @@ -83,7 +83,7 @@ protected: if (pFuncOnInit) pFuncOnInit(); // Call the user function else - setLed(Blue); + setLed(Red); // Set the LED to red, so it is consistent with the PS5BT driver }; return 0; }; @@ -92,9 +92,9 @@ protected: /** @name PS5Parser implementation */ virtual void sendOutputReport(PS5Output *output) { // Source: https://github.com/chrippa/ds4drv // PS4 Source: https://github.com/chrippa/ds4drv - // PS5 values from https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/ - // , Ludwig Füchsl's https://github.com/Ohjurot/DualSense-Windows - // and the series of patches found here: https://patchwork.kernel.org/project/linux-input/patch/20201219062336.72568-14-roderick@gaikai.com/ + // PS5 values from https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/, + // Ludwig Füchsl's https://github.com/Ohjurot/DualSense-Windows and + // the series of patches found here: https://patchwork.kernel.org/project/linux-input/cover/20201219062336.72568-1-roderick@gaikai.com/ uint8_t buf[1 /* report id */ + 47 /* common */]; memset(buf, 0, sizeof(buf)); @@ -133,7 +133,7 @@ protected: output->reportChanged = false; - // The PS5 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed + // There is no need to calculate a crc32 when the controller is connected via USB pUsb->outTransfer(bAddress, epInfo[ hidInterfaces[0].epIndex[epInterruptOutIndex] ].epAddr, sizeof(buf), buf); }; diff --git a/examples/Bluetooth/PS5BT/PS5BT.ino b/examples/Bluetooth/PS5BT/PS5BT.ino index 39bf361a..6d6fc0d4 100644 --- a/examples/Bluetooth/PS5BT/PS5BT.ino +++ b/examples/Bluetooth/PS5BT/PS5BT.ino @@ -1,7 +1,7 @@ /* Example sketch for the PS5 Bluetooth library - developed by Kristian Sloth Lauszus For more information visit the Github repository: github.com/felis/USB_Host_Shield_2.0 or - send me an e-mail: lauszus@gmail.com + send me an e-mail: lauszus@gmail.com */ #include @@ -25,10 +25,11 @@ PS5BT PS5(&Btd, PAIR); // After that you can simply create the instance like so and then press the PS button on the device //PS5BT PS5(&Btd); -bool printAngle, printTouch; +bool printAngle = false, printTouch = false; uint16_t lastMessageCounter = -1; uint8_t player_led_mask = 0; bool microphone_led = false; +uint32_t ps_timer; void setup() { Serial.begin(115200); @@ -67,91 +68,101 @@ void loop() { } // Set the left trigger to resist at the right trigger's level - PS5.leftTrigger.setTriggerForce(PS5.getAnalogButton(R2), 255); + static uint8_t oldR2Value = 0xFF; + if (PS5.getAnalogButton(R2) != oldR2Value) { + oldR2Value = PS5.getAnalogButton(R2); + PS5.leftTrigger.setTriggerForce(oldR2Value, 255); + } - if (PS5.getButtonClick(PS)) { + // Hold the PS button for 1 second to disconnect the controller + // This prevents the controller from disconnecting when it is reconnected, + // as the PS button is sent when it reconnects + if (PS5.getButtonPress(PS)) { + if (millis() - ps_timer > 1000) + PS5.disconnect(); + } else + ps_timer = millis(); + + if (PS5.getButtonClick(PS)) Serial.print(F("\r\nPS")); - PS5.disconnect(); - } else { - if (PS5.getButtonClick(TRIANGLE)) { - Serial.print(F("\r\nTriangle")); - PS5.setRumbleOn(RumbleLow); - } - if (PS5.getButtonClick(CIRCLE)) { - Serial.print(F("\r\nCircle")); - PS5.setRumbleOn(RumbleHigh); - } - if (PS5.getButtonClick(CROSS)) { - Serial.print(F("\r\nCross")); + if (PS5.getButtonClick(TRIANGLE)) { + Serial.print(F("\r\nTriangle")); + PS5.setRumbleOn(RumbleLow); + } + if (PS5.getButtonClick(CIRCLE)) { + Serial.print(F("\r\nCircle")); + PS5.setRumbleOn(RumbleHigh); + } + if (PS5.getButtonClick(CROSS)) { + Serial.print(F("\r\nCross")); - // Set the player LEDs - player_led_mask = (player_led_mask << 1) | 1; - if (player_led_mask > 0x1F) - player_led_mask = 0; - PS5.setPlayerLed(player_led_mask); // The bottom 5 bits set player LEDs - } - if (PS5.getButtonClick(SQUARE)) { - Serial.print(F("\r\nSquare")); - PS5.setRumbleOff(); - } + // Set the player LEDs + player_led_mask = (player_led_mask << 1) | 1; + if (player_led_mask > 0x1F) + player_led_mask = 0; + PS5.setPlayerLed(player_led_mask); // The bottom 5 bits set player LEDs + } + if (PS5.getButtonClick(SQUARE)) { + Serial.print(F("\r\nSquare")); + PS5.setRumbleOff(); + } - if (PS5.getButtonClick(UP)) { - Serial.print(F("\r\nUp")); - PS5.setLed(Red); - } if (PS5.getButtonClick(RIGHT)) { - Serial.print(F("\r\nRight")); - PS5.setLed(Blue); - } if (PS5.getButtonClick(DOWN)) { - Serial.print(F("\r\nDown")); - PS5.setLed(Yellow); - } if (PS5.getButtonClick(LEFT)) { - Serial.print(F("\r\nLeft")); - PS5.setLed(Green); - } + if (PS5.getButtonClick(UP)) { + Serial.print(F("\r\nUp")); + PS5.setLed(Red); + } if (PS5.getButtonClick(RIGHT)) { + Serial.print(F("\r\nRight")); + PS5.setLed(Blue); + } if (PS5.getButtonClick(DOWN)) { + Serial.print(F("\r\nDown")); + PS5.setLed(Yellow); + } if (PS5.getButtonClick(LEFT)) { + Serial.print(F("\r\nLeft")); + PS5.setLed(Green); + } - if (PS5.getButtonClick(L1)) - Serial.print(F("\r\nL1")); - if (PS5.getButtonClick(L3)) - Serial.print(F("\r\nL3")); - if (PS5.getButtonClick(R1)) - Serial.print(F("\r\nR1")); - if (PS5.getButtonClick(R3)) - Serial.print(F("\r\nR3")); + if (PS5.getButtonClick(L1)) + Serial.print(F("\r\nL1")); + if (PS5.getButtonClick(L3)) + Serial.print(F("\r\nL3")); + if (PS5.getButtonClick(R1)) + Serial.print(F("\r\nR1")); + if (PS5.getButtonClick(R3)) + Serial.print(F("\r\nR3")); - if (PS5.getButtonClick(CREATE)) - Serial.print(F("\r\nCreate")); - if (PS5.getButtonClick(OPTIONS)) { - Serial.print(F("\r\nOptions")); - printAngle = !printAngle; - } - if (PS5.getButtonClick(TOUCHPAD)) { - Serial.print(F("\r\nTouchpad")); - printTouch = !printTouch; - } - if (PS5.getButtonClick(MICROPHONE)) { - Serial.print(F("\r\nMicrophone")); - microphone_led = !microphone_led; - PS5.setMicLed(microphone_led); - } + if (PS5.getButtonClick(CREATE)) + Serial.print(F("\r\nCreate")); + if (PS5.getButtonClick(OPTIONS)) { + Serial.print(F("\r\nOptions")); + printAngle = !printAngle; + } + if (PS5.getButtonClick(TOUCHPAD)) { + Serial.print(F("\r\nTouchpad")); + printTouch = !printTouch; + } + if (PS5.getButtonClick(MICROPHONE)) { + Serial.print(F("\r\nMicrophone")); + microphone_led = !microphone_led; + PS5.setMicLed(microphone_led); + } - if (printAngle) { // Print angle calculated using the accelerometer only - Serial.print(F("\r\nPitch: ")); - Serial.print(PS5.getAngle(Pitch)); - Serial.print(F("\tRoll: ")); - Serial.print(PS5.getAngle(Roll)); - } + if (printAngle) { // Print angle calculated using the accelerometer only + Serial.print(F("\r\nPitch: ")); + Serial.print(PS5.getAngle(Pitch)); + Serial.print(F("\tRoll: ")); + Serial.print(PS5.getAngle(Roll)); + } - if (printTouch) { // Print the x, y coordinates of the touchpad - if (PS5.isTouching(0) || PS5.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 (PS5.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(PS5.getX(i)); - Serial.print(F("\tY")); Serial.print(i + 1); Serial.print(F(": ")); - Serial.print(PS5.getY(i)); - Serial.print(F("\t")); - } + if (printTouch) { // Print the x, y coordinates of the touchpad + if (PS5.isTouching(0) || PS5.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 (PS5.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(PS5.getX(i)); + Serial.print(F("\tY")); Serial.print(i + 1); Serial.print(F(": ")); + Serial.print(PS5.getY(i)); + Serial.print(F("\t")); } } } diff --git a/examples/PS5USB/PS5USB.ino b/examples/PS5USB/PS5USB.ino index a28ab3fd..36582dad 100644 --- a/examples/PS5USB/PS5USB.ino +++ b/examples/PS5USB/PS5USB.ino @@ -1,7 +1,7 @@ /* Example sketch for the PS5 USB library - developed by Kristian Sloth Lauszus For more information visit the Github repository: github.com/felis/USB_Host_Shield_2.0 or - send me an e-mail: lauszus@gmail.com + send me an e-mail: lauszus@gmail.com */ #include @@ -15,7 +15,7 @@ USB Usb; PS5USB PS5(&Usb); -bool printAngle, printTouch; +bool printAngle = false, printTouch = false; uint16_t lastMessageCounter = -1; uint8_t player_led_mask = 0; bool microphone_led = false; @@ -57,7 +57,11 @@ void loop() { } // Set the left trigger to resist at the right trigger's level - PS5.leftTrigger.setTriggerForce(PS5.getAnalogButton(R2), 255); + static uint8_t oldR2Value = 0xFF; + if (PS5.getAnalogButton(R2) != oldR2Value) { + oldR2Value = PS5.getAnalogButton(R2); + PS5.leftTrigger.setTriggerForce(oldR2Value, 255); + } if (PS5.getButtonClick(PS)) Serial.print(F("\r\nPS"));