Interface Playstation DualShock 4 (DS4) Controller on Linux using C++

B. Ueno picture B. Ueno · Dec 11, 2017 · Viewed 7.4k times · Source

I would like to get a PS4 controller to work on my PC and then relay the data to a microcontroller via UART.

The problem is, that I have no experience in C++ programming for Linux. The uC part is more in my favor. Nevertheless, I would like to write a program which can set up a connection with a PS4 controller and read all buttons, sticks, motions and the track-pad. Also, it would be nice to be able to control rumble and the LED color.

I am using Ubuntu 16.4 and have read that the PS4 controller is natively supported since ver. 14.xx. But all I can find regarding a connection is how to set up the controller for steam or gaming in general. But not how to get that status information and work with them using C++.

On the internet, I found some projects but they are all at least 3-4 years old and using an old version of Ubuntu. But since the controller is natively supported it would be nice to use it without outdated plugins/drivers which are obsolete anyway. I also started to look into HID-devices but that seems more like a workaround and I was hoping to find e.g. a library to include and use...

If someone can give me a hint, it would be greatly appreciated.

Answer

MannFromTheMoon picture MannFromTheMoon · Dec 20, 2017

I did most of this on a raspberry pi but most of it still applies because the underlying drivers are mostly the same

Connecting: https://wiki.gentoo.org/wiki/Sony_DualShock look at the part about bluetoothctl and either try to follow that or get a wireless dongle. (That should set up automatically)

Controlls: Your best bet is reading /dev/input/jsX where x is the number of the controller you are connected to (normally 0). This works with normal file reads so should really be no problem. This file contains everything from button presses to trackpad events and all other sensor data. It is event based so if you press a button you will get a 8 Byte burst of data. The structure looks like this:
1. Timestamp lowest byte
2. Timestamp second lowest byte
3. Timestamp second highest byte
4. Timestamp highest byte
5. Measured Data MSB
6. Measured Data LSB
7. Type (1 for Button. 2 for Axis (so a stick or another analog value))
8. ID Byte (so the id of the button you pressed. e.g.: 1 for x, 2 for square, 5 for left stick x)

LEDs: This one is a bit more complicated. The only way i've found so far is accessing /sys/class/leds
That folder should contain a subfolder folder named something like 0005:054C:05C4.0009:<blue/green/red/global>
Those are your R/G/B channels. In these folders there are files called max_brightness and brightness To change the color to 0x00ff00 for instance write 0 to red 255 to green and 0 to blue