Home > Arduino, Bluetooth, TKJ Electronics, USB > PS4 controller now supported by the USB Host library

PS4 controller now supported by the USB Host library

I am very pleased to announce that I have now added support for the PS4 controller via Bluetooth. This will allow you to read all the buttons and joysticks with the same API as all the other libraries I have written for the USB Host library.

PS4 controller

To get started you should look at the provided example. It shows how to read the different buttons and joysticks. I still haven’t figured out how to control the light, rumble and read the accelerometer, gyroscope and touchpad, but hopefully I will figure that out soon.

The pairing process for the PS4 controller is a little different than the PS3 controller, as it works like a regular Bluetooth joystick, as you simply make the PS4 controller discoverable by holding down the PS and Share button at the same time. The light will then start to blink rapidly.

After that you should be able to pair with the controller, by creating the PS4BT instance like so:

PS4BT PS4(&Btd, PAIR);

You should also check out the readme which will always have the newest information available.

The PS4 Bluetooth library actually uses the BTHID library to handle all the Bluetooth communication. This is much more modular and easier to maintain. I will work on making all the Bluetooth classes like that, so it will reduce the footprint of the libraries, but also make it much easier to maintain, as all the L2CAP communication would be handled in only one class.

I still haven’t written a library to use it via USB, but I will do that in the coming weeks, when I have time.

This is all for now. Please leave a comment below if you got any questions and I will answer as quickly as possible.

Update 18. January 2014
A USB version of the library is now also available. It allows you to read the gyroscope, accelerometer and touchpad as well.

Update 22. January 2014
I now also figured out how to read the IMU and touchpad data via Bluetooth. The problem is that the controller does not send out this information via Bluetooth by default.
To enable the full output the code sends out a get feature report. For more information see this excellent Wiki: http://eleccelerator.com/wiki/index.php?title=DualShock_4 by Frank Zhao.

Update 16. February 2014
It is now also possible to control the rumble and light as well. The code was inspired by this Linux driver: https://github.com/chrippa/ds4drv.

Categories: Arduino, Bluetooth, TKJ Electronics, USB Tags:
  1. Vinit
    February 11th, 2015 at 07:48 | #1

    Sorry to be late !!

    Link for the controller -- http://www.sony.co.in/product/ps4+dualshock+wave+blue .

  2. February 12th, 2015 at 00:29 | #2

    @Vinit
    It’s sounds like a problem with your dongle. Please try another one.

  3. Krunal
    February 26th, 2015 at 16:15 | #3

    Hello,
    I am using two PS4 controllers to control two robots with arduino Uno simultaneously. But, the PS4 often loses synchronization with the arduino. As soon as 1 controller loses sync, the other one loses it immediately. And this happens very often. Please help!!!

  4. February 26th, 2015 at 17:33 | #4

    @Krunal
    Can you post your code somewhere? For instance here: https://gist.github.com/.

    Also make sure that you have a stable 5V rail.

  5. Krunal
  6. Krunal
    February 28th, 2015 at 18:18 | #7

    @Lauszus
    Actually I had put that line because if the connection is lost, I had to upload the program again to pair the controllers.
    And also how can i cahnge the pairing key for the controller?

  7. March 1st, 2015 at 00:32 | #8

    @Krunal
    That is not the correct way to do it!

    You should call:

    PS4.pair();

    But why do you want to pair it again and again? It is only needed once. After that you can simply just press on the PS button on the controller.

  8. Krunal
    March 1st, 2015 at 03:37 | #9

    @Lauszus
    Actually while using 2 controllers, there is aproblem occuring that the controllers often get disconnected. I thought it will be so;ved if I change the pairing key for anyone controller which is set to 0000 by default. Bu how to do that?

  9. March 1st, 2015 at 11:38 | #10

    @Krunal
    Please remove that line first. I might be the reason why they are disconnecting. The pairing key doesn’t matter for the PS4 controllers.

  10. Krunal
    March 2nd, 2015 at 08:14 | #11

    @Lauszus
    Ohkk. Now even after removing that line, theres a problem coming. Consider that one of my controllers is connected, when I try to connect my second controller, the first one is disconnected if the second one goes into partial pairing mode (ie a constant white led is on). But this happens often. So please tell me a solution for this.

  11. March 2nd, 2015 at 22:41 | #12

    @Krunal
    Okay now I understand what you are trying to do. You need to make a instance for each controller. Please see this example for the PS3 controller for inspiration: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/PS3Multi/PS3Multi.ino.

  12. Marco
    March 17th, 2015 at 21:12 | #13

    Hello, my son and I are willing to connect PS4 controller using Arduino due native USB port, but seems that Bluetooth dongle is not recognised by the library. We tried also with PS3 controller (and related software) but same bad result.
    Do the library support also native USB port or only USB shield?
    Thank you

  13. March 18th, 2015 at 00:21 | #14

    @Marco
    Unfortunately the Due native port is not supported as of yet, but this is something we are working on supporting. Hopefully it will get released in a couple of months.

    If you can’t wait, then you can buy a shield. The API should be almost the same in the new library, so you won’t have to rewrite your code once it is released.

  14. Frank
    March 25th, 2015 at 23:58 | #15

    I’m attempting to use a PS4 controller over BT. It doesn’t seem very stable at all, and there are delays that happen when using the PS4BT sketch. For instance I will press the up button which should turn the LED red. IT doesn’t. I press it again, and then it lights up red. I next press right, which should go to blue, but it stays red. Then I press it again and it finally goes to blue. I do see the button presses happening, but the led isn’t responding right. After a short bit of time the controller loses connection for whatever reason and won’t reconnect.

  15. March 26th, 2015 at 00:13 | #16

    @Frank
    Make sure that there is actually battery left on the PS4 controller. Also please enable serial debugging: https://github.com/felis/USB_Host_Shield_2.0#enable-debugging and post the output.

  16. Frank
    March 30th, 2015 at 22:05 | #17

    @Lauszus -- Thanks for the quick reply. I picked up a different dongle and it seems to be working much better, but still not 100%. I have a fully charged PS4 controller, so that isn’t the problem. I paired the controller while running PS4BT.ino, and when finished the controller LED turned BLUE, and all the controls functioned correctly.

    Next, I comment out the PAIR line and uncommented the corressponding line. When I ran it, the controller appears to connect, but the light doesn’t turn BLUE, and none of the controls do anything. What are your suggestions?

    Here is the log from that run:

    PS4 Bluetooth Library Started
    BTD ConfigureDevice
    BTD Init
    Addr: 01
    Endpoint descriptor:
    Length: 07
    Type: 05
    Address: 81
    Attributes: 03
    MaxPktSize: 0010
    Poll Intrv: 01
    Endpoint descriptor:
    Length: 07
    Type: 05
    Address: 82
    Attributes: 02
    MaxPktSize: 0040
    Poll Intrv: 01
    Endpoint descriptor:
    Length: 07
    Type: 05
    Address: 02
    Attributes: 02
    MaxPktSize: 0040
    Poll Intrv: 01
    Bluetooth Dongle Initialized
    Connection established
    Connection established
    Connection established
    HCI Reset complete
    Write class of device
    Local Bluetooth Address: 5C:F3:70:65:E8:27
    Wait For Incoming Connection Request
    Gamepad is connecting
    Class of device: 00 25 08
    Incoming Connection Request
    Remote Name: Wireles
    Connection established
    Connected to Device: 1C:96:5A:81:F9:25
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Wait For Incoming Connection Request

  17. Frank
    March 30th, 2015 at 22:08 | #18

    I tried it again, and the same situation on the PS4 controller, but slightly different debug output….

    BTD ConfigureDevice
    BTD Init
    Addr: 01
    Endpoint descriptor:
    Length: 07
    Type: 05
    Address: 81
    Attributes: 03
    MaxPktSize: 0010
    Poll Intrv: 01
    Endpoint descriptor:
    Length: 07
    Type: 05
    Address: 82
    Attributes: 02
    MaxPktSize: 0040
    Poll Intrv: 01
    Endpoint descriptor:
    Length: 07
    Type: 05
    Address: 02
    Attributes: 02
    MaxPktSize: 0040
    Poll Intrv: 01
    Bluetooth Dongle Initialized
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    HCI Reset complete
    Write class of device
    Local Bluetooth Address: 5C:F3:70:65:E8:27
    Wait For Incoming Connection Request
    Gamepad is connecting
    Class of device: 00 25 08
    Incoming Connection Request
    Remote Name: Wireless Controller
    PS4 controller is connecting
    Connection established
    Connected to Device: 1C:96:5A:81:F9:25
    Send HID Control Connection Request
    Connection established
    Connection established
    Connection established
    Connection established
    Connection established
    Received Key Request
    Bluetooth pin is set too: 0000

  18. March 31st, 2015 at 15:14 | #19

    @Frank
    It still looks like a problem with your dongle. Could you try to replace this line: https://github.com/felis/USB_Host_Shield_2.0/blob/master/BTD.cpp#L393 with:

    if(!rcode) {

    And: https://github.com/felis/USB_Host_Shield_2.0/blob/master/BTD.cpp#L619 with:

    else if(rcode != hrNAK) {
  19. Frank
    March 31st, 2015 at 16:11 | #20

    That seemed to work better, but not perfect. Now it either connects correctly (turns BLUE), or else it tries for a moment then stops with (Connection Failed: 10).

    Since it is most likely my dongle, I think I will just order one through your site. You should see the order come through soon.

  20. March 31st, 2015 at 16:46 | #21

    @Frank
    Yes the new dongle should solve your problem :)

  21. Frank
    March 31st, 2015 at 19:03 | #22

    I do have one suggestion if you get time. Could you make a singleton version of the PS4BT project? I have lots of different classes that need to get info from the controller, and a singleton would make it a whole lot easier to use.

    Here some pseudo code of the ino that would use it…

    #include “PS4BTSingleton.h”

    void setup() {
    // init usb
    PS4BTSingleton::instance().init();
    }

    void loop() {
    //usb task
    PS4BTSingleton::instance().task();

    // do something if connected
    if (PS4BTSingleton::instance().connected())
    PS4BTSingleton::instance().setLed(255, 0, 0);
    }

  22. April 1st, 2015 at 15:57 | #23

    @Frank
    No I won’t make the official library a singleton, as you need to create more instances if you want to use multiple PS4 controller.

    Why would you want to use a singleton in the first place?

  23. Frank Trocchia
    April 1st, 2015 at 18:58 | #24

    I’m using the PS4 controller for my R2-D2 build. I only need one controller for the droid. Having a singleton would allow each module to have access to the controller instead of passing the instance around. I could then use it easily with my sound board, servo boards, lighting boards, etc.

    It’s just a suggestion. Thought it would be easier for you since you know the ins and outs of the code that you could make a singleton version that sits side by side with the original.

    Anyway, I did order the dongle, so hopefully that will fix that problem.

  24. April 1st, 2015 at 20:57 | #25

    @Frank Trocchia
    Okay cool. There is actually numerous people using my libraries for R2-D2′s :)
    Hmm, I won’t do that, as it will break a lot of peoples code, but you can just make a new class which inherits it and make it a singleton?

    Why can’t you just make it global and access it from the difference drivers? If they are C++ classes they could just take a pointer to the PS4BT class as an argument, just like the BTD class take a pointer to the USB class as an argument.

  25. Frank Trocchia
    April 2nd, 2015 at 12:03 | #26

    Yeah I will probably go that route. Thanks for all your help. Once the dongle arrives I will give it some tests and if anything is odd I will get back to you.

    Thanks

  26. April 2nd, 2015 at 12:23 | #27

    @Frank Trocchia
    Okay super :)

  27. Frank
    April 10th, 2015 at 00:32 | #28

    The new dongle works much better. I am curious though why it only fully connects every other time? Using the example code… when I start the controller it connects and the light turns blue. I press the PS button and it disconnects, with the light turning off. When I try to connect again, the light flashes briefly then turns on solid white. I hold the PS button for 10 seconds and the controller powers off. When I press the PS button again, it connects and the light turns blue. It just seems like every other time it connects properly.

    Is there something wrong? Is there a timeout period, or some sort of cleanup code that isn’t called that should be?

    Thanks

  28. Frank
    April 10th, 2015 at 01:09 | #29

    Here is a log. You can see it connects the first time… and then I hit PS and it disconnects. The next time it tries it starts the connection process, but just stops with the ‘Received Key Request’ message.

    Wait For Incoming Connection Request
    Gamepad is connecting
    Incoming Connection Request
    Remote Name: Wireless Controller
    PS4 controller is connecting
    Connected to Device: 1C:96:5A:81:F9:25
    Send HID Control Connection Request
    Received Key Request
    Bluetooth pin is set too: 0000
    Send HID Control Config Request
    Set protocol mode: 00
    Send HID Interrupt Connection Request
    Send HID Interrupt Config Request
    HID Channels Established
    Wait For Incoming Connection Request
    PS
    Disconnected Interrupt Channel
    Disconnected Control Channel
    HCI Disconnected from Device
    Wait For Incoming Connection Request
    Gamepad is connecting
    Incoming Connection Request
    Remote Name: Wireless Controller
    PS4 controller is connecting
    Connected to Device: 1C:96:5A:81:F9:25
    Send HID Control Connection Request
    Received Key Request

  29. Frank Trocchia
    April 10th, 2015 at 12:45 | #30

    I don’t see where I’ve posted it, so I want to add that I’m using an Arduino Mega ADK, the bluetooth dongle I just received from you, and a stock PS4 controller.

    Thanks

  30. April 20th, 2015 at 01:23 | #31

    @Frank
    That sounds very weird. Is it exactly every second time? Or does it just happen once in a while?

  31. luis silva
    April 24th, 2015 at 05:22 | #32

    i have a arduino uno with the usb shield and the bluetooth dongle and i got it to connect to the remote but what i want to do it to use my ps4 controller to control an 8 relay module i have connected to pins 2-9 but I’m not getting no where with this sketch cause I’m new to this anyone can help?

  32. April 27th, 2015 at 02:42 | #33

    So I am loving the simplicity this library gives the end user, however I am running into one small issue with PS4.getButtonClick(). It seems that when placed into an if statement, it will only be triggered as True once. If the button you are calling for is being held down, it won’t trip the if statement and will instead go over it. So my question is, what does PS4.getButtonClick() return? and how can I have it continuously perform an action via an if statement while the button is held?

  33. April 27th, 2015 at 06:12 | #34

    @Mike O’Donnell
    You are exactly right, as this is the feature of the getButtonClick() function.
    In your case you should be using the PS4.getButtonPress() method as this will return the current state of the button and therefor work as you require.

  34. April 27th, 2015 at 23:51 | #35

    @luis silva
    Please share you code somewhere, so I can give you some hints. Also check out this code I wrote for a guy some time ago for the SPP library: https://gist.github.com/Lauszus/3383715.

    @Mike O’Donnell
    Yes getButtonPress() is what you are looking for. Also check out the documentation for the PS4BT class: http://felis.github.io/USB_Host_Shield_2.0/class_p_s4_b_t.html.

Comment pages
1 2 4247
  1. No trackbacks yet.