Skip to content

Commit 6373ebe

Browse files
committed
Can now set the rumble and light on the PS4 controller
Still need to test it via USB
1 parent ac5d134 commit 6373ebe

File tree

10 files changed

+200
-39
lines changed

10 files changed

+200
-39
lines changed

PS3Enums.h

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -110,28 +110,6 @@ const uint8_t PS3_ANALOG_BUTTONS[] PROGMEM = {
110110
15, // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading)
111111
};
112112

113-
/** Used to set the colors of the move controller. */
114-
enum ColorsEnum {
115-
/** r = 255, g = 0, b = 0 */
116-
Red = 0xFF0000,
117-
/** r = 0, g = 255, b = 0 */
118-
Green = 0xFF00,
119-
/** r = 0, g = 0, b = 255 */
120-
Blue = 0xFF,
121-
122-
/** r = 255, g = 235, b = 4 */
123-
Yellow = 0xFFEB04,
124-
/** r = 0, g = 255, b = 255 */
125-
Lightblue = 0xFFFF,
126-
/** r = 255, g = 0, b = 255 */
127-
Purble = 0xFF00FF,
128-
129-
/** r = 255, g = 255, b = 255 */
130-
White = 0xFFFFFF,
131-
/** r = 0, g = 0, b = 0 */
132-
Off = 0x00,
133-
};
134-
135113
enum StatusEnum {
136114
// Note that the location is shifted 9 when it's connected via USB
137115
// Byte location | bit location
@@ -160,9 +138,4 @@ enum StatusEnum {
160138
Bluetooth = (40 << 8) | 0x16, // Operating by Bluetooth and rumble is turned off
161139
};
162140

163-
enum RumbleEnum {
164-
RumbleHigh = 0x10,
165-
RumbleLow = 0x20,
166-
};
167-
168141
#endif

PS4BT.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class PS4BT : public BTHID, public PS4Parser {
4646
return BTHID::connected;
4747
};
4848

49+
/**
50+
* Used to call your own function when the device is successfully initialized.
51+
* @param funcOnInit Function to call.
52+
*/
53+
void attachOnInit(void (*funcOnInit)(void)) {
54+
pFuncOnInit = funcOnInit;
55+
};
56+
4957
protected:
5058
/** @name BTHID implementation */
5159
/**
@@ -64,7 +72,12 @@ class PS4BT : public BTHID, public PS4Parser {
6472
* This is useful for instance if you want to set the LEDs in a specific way.
6573
*/
6674
virtual void OnInitBTHID() {
75+
PS4Parser::Reset();
6776
enable_sixaxis(); // Make the controller send out the entire output report
77+
if (pFuncOnInit)
78+
pFuncOnInit(); // Call the user function
79+
else
80+
setLed(Blue);
6881
};
6982

7083
/** Used to reset the different buffers to there default values */
@@ -74,6 +87,34 @@ class PS4BT : public BTHID, public PS4Parser {
7487
/**@}*/
7588

7689
private:
90+
/** @name PS4Parser implementation */
91+
virtual void sendOutputReport(PS4Output *output) { // Source: https://github.com/chrippa/ds4drv
92+
uint8_t buf[79];
93+
memset(buf, 0, sizeof(buf));
94+
95+
buf[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
96+
buf[1] = 0x11; // Report ID
97+
buf[2] = 0x80;
98+
buf[4]= 0xFF;
99+
100+
buf[7] = output->bigRumble; // Big Rumble
101+
buf[8] = output->smallRumble; // Small rumble
102+
103+
buf[9] = output->r; // Red
104+
buf[10] = output->g; // Green
105+
buf[11] = output->b; // Blue
106+
107+
buf[12] = output->flashOn; // Time to flash bright (255 = 2.5 seconds)
108+
buf[13] = output->flashOff; // Time to flash dark (255 = 2.5 seconds)
109+
110+
output->reportChanged = false;
111+
112+
// The PS4 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed
113+
114+
HID_Command(buf, sizeof(buf));
115+
};
116+
/**@}*/
117+
77118
void HID_Command(uint8_t *data, uint8_t nbytes) {
78119
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
79120
};
@@ -85,5 +126,7 @@ class PS4BT : public BTHID, public PS4Parser {
85126

86127
HID_Command(buf, 2);
87128
};
129+
130+
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
88131
};
89132
#endif

PS4Parser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,7 @@ void PS4Parser::Parse(uint8_t len, uint8_t *buf) {
118118
}
119119
}
120120
}
121+
122+
if (ps4Output.reportChanged)
123+
sendOutputReport(&ps4Output); // Send output report
121124
}

PS4Parser.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ struct PS4Data {
102102
// The last three bytes are always: 0x00, 0x80, 0x00
103103
} __attribute__((packed));
104104

105+
struct PS4Output {
106+
uint8_t bigRumble, smallRumble; // Rumble
107+
uint8_t r, g, b; // RGB
108+
uint8_t flashOn, flashOff; // Time to flash bright/dark (255 = 2.5 seconds)
109+
bool reportChanged; // The data is send when data is received from the controller
110+
} __attribute__((packed));
111+
105112
enum DPADEnum {
106113
DPAD_UP = 0x0,
107114
DPAD_UP_RIGHT = 0x1,
@@ -237,6 +244,74 @@ class PS4Parser {
237244
return 0;
238245
}
239246
};
247+
248+
/** Turn both rumble and the LEDs off. */
249+
void setAllOff() {
250+
setRumbleOff();
251+
setLedOff();
252+
};
253+
254+
/** Set rumble off. */
255+
void setRumbleOff() {
256+
setRumbleOn(0, 0);
257+
};
258+
259+
/**
260+
* Turn on rumble.
261+
* @param mode Either ::RumbleHigh or ::RumbleLow.
262+
*/
263+
void setRumbleOn(RumbleEnum mode) {
264+
if (mode == RumbleLow)
265+
setRumbleOn(0xFF, 0x00);
266+
else
267+
setRumbleOn(0x00, 0xFF);
268+
};
269+
270+
/**
271+
* Turn on rumble.
272+
* @param bigRumble Value for big motor.
273+
* @param smallRumble Value for small motor.
274+
*/
275+
void setRumbleOn(uint8_t bigRumble, uint8_t smallRumble) {
276+
ps4Output.bigRumble = bigRumble;
277+
ps4Output.smallRumble = smallRumble;
278+
ps4Output.reportChanged = true;
279+
};
280+
281+
/** Turn all LEDs off. */
282+
void setLedOff() {
283+
setLed(0, 0, 0);
284+
};
285+
286+
/**
287+
* Use this to set the color using RGB values.
288+
* @param r,g,b RGB value.
289+
*/
290+
void setLed(uint8_t r, uint8_t g, uint8_t b) {
291+
ps4Output.r = r;
292+
ps4Output.g = g;
293+
ps4Output.b = b;
294+
ps4Output.reportChanged = true;
295+
};
296+
297+
/**
298+
* Use this to set the color using the predefined colors in ::ColorsEnum.
299+
* @param color The desired color.
300+
*/
301+
void setLed(ColorsEnum color) {
302+
setLed((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
303+
};
304+
305+
/**
306+
* Set the LEDs flash time.
307+
* @param flashOn Time to flash bright (255 = 2.5 seconds).
308+
* @param flashOff Time to flash dark (255 = 2.5 seconds).
309+
*/
310+
void setLedFlash(uint8_t flashOn, uint8_t flashOff) {
311+
ps4Output.flashOn = flashOn;
312+
ps4Output.flashOff = flashOff;
313+
ps4Output.reportChanged = true;
314+
};
240315
/**@}*/
241316

242317
protected:
@@ -267,13 +342,21 @@ class PS4Parser {
267342
oldButtonState.dpad = DPAD_OFF;
268343
buttonClickState.dpad = 0;
269344
oldDpad = 0;
345+
346+
ps4Output.bigRumble = ps4Output.smallRumble = 0;
347+
ps4Output.r = ps4Output.g = ps4Output.b = 0;
348+
ps4Output.flashOn = ps4Output.flashOff = 0;
349+
ps4Output.reportChanged = false;
270350
};
271351

352+
virtual void sendOutputReport(PS4Output *output) = 0; // This is overridden in PS4BT and PS4USB
353+
272354
private:
273355
bool checkDpad(ButtonEnum b); // Used to check PS4 DPAD buttons
274356

275357
PS4Data ps4Data;
276358
PS4Buttons oldButtonState, buttonClickState;
359+
PS4Output ps4Output;
277360
uint8_t oldDpad;
278361
};
279362
#endif

PS4USB.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,44 @@ class PS4USB : public HIDUniversal, public PS4Parser {
7575
* This is useful for instance if you want to set the LEDs in a specific way.
7676
*/
7777
virtual uint8_t OnInitSuccessful() {
78-
PS4Parser::Reset();
79-
if (HIDUniversal::VID == PS4_VID && HIDUniversal::PID == PS4_PID && pFuncOnInit)
80-
pFuncOnInit(); // Call the user function
78+
if (HIDUniversal::VID == PS4_VID && HIDUniversal::PID == PS4_PID) {
79+
PS4Parser::Reset();
80+
if (pFuncOnInit)
81+
pFuncOnInit(); // Call the user function
82+
else
83+
setLed(Blue);
84+
};
8185
return 0;
8286
};
8387
/**@}*/
8488

8589
private:
90+
/** @name PS4Parser implementation */
91+
virtual void sendOutputReport(PS4Output *output) { // Source: https://github.com/chrippa/ds4drv
92+
uint8_t buf[32];
93+
memset(buf, 0, sizeof(buf));
94+
95+
buf[0] = 0x05; // Report ID
96+
buf[1]= 0xFF;
97+
98+
buf[4] = output->bigRumble; // Big Rumble
99+
buf[5] = output->smallRumble; // Small rumble
100+
101+
buf[6] = output->r; // Red
102+
buf[7] = output->g; // Green
103+
buf[8] = output->b; // Blue
104+
105+
buf[9] = output->flashOn; // Time to flash bright (255 = 2.5 seconds)
106+
buf[10] = output->flashOff; // Time to flash dark (255 = 2.5 seconds)
107+
108+
output->reportChanged = false;
109+
110+
// The PS4 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed
111+
112+
pUsb->outTransfer(bAddress, epInfo[ hidInterfaces[0].epIndex[epInterruptOutIndex] ].epAddr, sizeof(buf), buf);
113+
};
114+
/**@}*/
115+
86116
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
87117
};
88118
#endif

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ It enables me to see the Bluetooth communication between my Mac and any device.
120120

121121
The PS4BT library is split up into the [PS4BT](PS4BT.h) and the [PS4USB](PS4USB.h) library. These allow you to use the Sony PS4 controller via Bluetooth and USB.
122122

123-
The [PS4BT.ino](examples/Bluetooth/PS4BT/PS4BT.ino) and [PS4USB.ino](examples/PS4USB/PS4USB.ino) examples shows how to easily read the buttons and joysticks on the controller via Bluetooth and USB respectively.
124-
125-
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.
123+
The [PS4BT.ino](examples/Bluetooth/PS4BT/PS4BT.ino) and [PS4USB.ino](examples/PS4USB/PS4USB.ino) examples shows how to easily read the buttons, joysticks, touchpad and IMU on the controller via Bluetooth and USB respectively. It is also possible to control the rumble and light on the controller.
126124

127125
Before you can use the PS4 controller via Bluetooth you will need to pair with it.
128126

@@ -132,7 +130,7 @@ It should then automatically pair the dongle with your controller. This only hav
132130

133131
For information see the following blog post: <http://blog.tkjelectronics.dk/2014/01/ps4-controller-now-supported-by-the-usb-host-library/>.
134132

135-
Also check out this excellent Wiki by Frank Zhao about the PS4 controller: <http://eleccelerator.com/wiki/index.php?title=DualShock_4>.
133+
Also check out this excellent Wiki by Frank Zhao about the PS4 controller: <http://eleccelerator.com/wiki/index.php?title=DualShock_4> and this Linux driver: <https://github.com/chrippa/ds4drv>.
136134

137135
### PS3 Library
138136

controllerEnums.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,33 @@ enum LEDEnum {
4141
ALL = 5,
4242
};
4343

44+
/** Used to set the colors of the Move and PS4 controller. */
45+
enum ColorsEnum {
46+
/** r = 255, g = 0, b = 0 */
47+
Red = 0xFF0000,
48+
/** r = 0, g = 255, b = 0 */
49+
Green = 0xFF00,
50+
/** r = 0, g = 0, b = 255 */
51+
Blue = 0xFF,
52+
53+
/** r = 255, g = 235, b = 4 */
54+
Yellow = 0xFFEB04,
55+
/** r = 0, g = 255, b = 255 */
56+
Lightblue = 0xFFFF,
57+
/** r = 255, g = 0, b = 255 */
58+
Purble = 0xFF00FF,
59+
60+
/** r = 255, g = 255, b = 255 */
61+
White = 0xFFFFFF,
62+
/** r = 0, g = 0, b = 0 */
63+
Off = 0x00,
64+
};
65+
66+
enum RumbleEnum {
67+
RumbleHigh = 0x10,
68+
RumbleLow = 0x20,
69+
};
70+
4471
/** This enum is used to read all the different buttons on the different controllers */
4572
enum ButtonEnum {
4673
/**@{*/

examples/PS4USB/PS4USB.ino

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
#include <PS4USB.h>
88

9+
// Satisfy IDE, which only needs to see the include statment in the ino.
10+
#ifdef dobogusinclude
11+
#include <spi4teensy3.h>
12+
#endif
13+
914
USB Usb;
1015
PS4USB PS4(&Usb);
1116

hiduniversal.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ class HIDUniversal : public HID {
1717
// Returns HID class specific descriptor length by its type and order number
1818
uint16_t GetHidClassDescrLen(uint8_t type, uint8_t num);
1919

20-
EpInfo epInfo[totalEndpoints];
21-
2220
struct HIDInterface {
23-
2421
struct {
2522
uint8_t bmInterface : 3;
2623
uint8_t bmAltSet : 3;
@@ -29,8 +26,6 @@ class HIDUniversal : public HID {
2926
uint8_t epIndex[maxEpPerInterface];
3027
};
3128

32-
HIDInterface hidInterfaces[maxHidInterfaces];
33-
3429
uint8_t bConfNum; // configuration number
3530
uint8_t bNumIface; // number of interfaces in the configuration
3631
uint8_t bNumEP; // total number of EP in the configuration
@@ -49,6 +44,9 @@ class HIDUniversal : public HID {
4944
void SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest);
5045

5146
protected:
47+
EpInfo epInfo[totalEndpoints];
48+
HIDInterface hidInterfaces[maxHidInterfaces];
49+
5250
bool bHasReportId;
5351

5452
uint16_t PID, VID; // PID and VID of connected device

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ setRumbleOn KEYWORD2
6464
setLedOff KEYWORD2
6565
setLedOn KEYWORD2
6666
setLedToggle KEYWORD2
67+
setLedFlash KEYWORD2
6768
moveSetBulb KEYWORD2
6869
moveSetRumble KEYWORD2
6970

0 commit comments

Comments
 (0)