Home > Arduino, TKJ Electronics, USB > Xbox 360 controller support added to the USB Host Library

Xbox 360 controller support added to the USB Host Library

Update
A wireless Xbox 360 controller is now also supported via a Wireless receiver. For more information see the blog post.

Hi everyone. I just wanted to let you know, that I just added support for the Xbox 360 controller via USB to the USB Host Library. The code can as always be found at github: https://github.com/TKJElectronics/USB_Host_Shield_2.0.

Categories: Arduino, TKJ Electronics, USB Tags:
  1. January 16th, 2013 at 02:07 | #1

    @Lauszus
    Thanks Lauszus. Usb.Task(); gets run every time the loop starts. Actually, the loop starts and I run a function called serialListen (it listens for data comin in on the serial port, like acceleration info coming from the adxl from another UNO, via xbee). If an instruction comes in to rumble the controller, then scancontroller fires the delegate() function which will then fire the rumble. Then I run scancontroller(), a function that has at the top of it Usb.Task(); scancontroller checks the values of some of the sticks and buttons.

    My code is very rough and is on github. I just started this project, I hope you don’t mind too much a thicket of code.

    It can be seen here: https://github.com/blairkelly/stackedcontrol/blob/master/stackedcontrol.ino

    I was thinking I might try this with the ps3 controller later. See if it makes any difference.

    P.s. That sketch will also turn on and off rumble if you push the Xbox button. I have found this will also cause the problem of controller reset.

  2. January 16th, 2013 at 15:16 | #2

    @Blair Kelly
    I think I found your problem. You are calling this: https://github.com/blairkelly/stackedcontrol/blob/master/stackedcontrol.ino#L113 without checking if the Xbox controller is actually connected.

    Also try to add a 1ms delay in your loop: https://github.com/blairkelly/stackedcontrol/blob/master/stackedcontrol.ino#L312.

    Try to run Usb.Task() before you run serialListen(), as you are actually sending a command to the controller before you have run Usb.Task, as you execute scancontroller() after serialListen().

    I found that it’s never a good idea to send multiple commands to the controller without calling Usb.Task in between. The problem is that you are not polling the input endpoint at the same rate as you are sending data.

  3. January 16th, 2013 at 16:42 | #3

    @Lauszus
    I am astonished at how much you help everyone out. Thank you very much for taking the time to analyse my code. I will try your suggestions this evening and let you know how I make out.

  4. January 17th, 2013 at 06:59 | #4

    @Lauszus
    I’m a bit embarrassed to say I was starting to run out of ideas when I just happened to plug in an external power source to the Arduino Mega 2560. It started working properly. I had ruled-out that possibility because it was working just fine with your example sketch. Perhaps the adequate power supply keeps the processes and communications from tripping up. Anyway, I thank you again for the time and effort you put into this and I’m sorry it was such a silly little thing I should not have overlooked!

  5. January 17th, 2013 at 18:24 | #5

    @Blair Kelly
    No problem :) Don’t hesitate to contact me again!

  6. Jerry
    April 14th, 2013 at 21:14 | #6

    Hi Lauszus,

    Thanks for all of the work you’ve put in getting the game controllers working with the USB Host Shield.

    I’ve been assigning the button presses to the digital I/O pins, and using the output to a relay board. Everything was working fine until I tried using the non-analog buttons. The comments in the XBOXRECV.h file starting at line 108 is a bit confusing and I’m not sure if what I’m trying to do is even possible.

    Whenever I try to getButtonPress for a non-analog button (L1, L2, X, Y, A, B), I get no outputs. getButtonClick works obviously, but I’d like for a constant output while the button is pressed down. Is this possible with these types of button?

    To clarify, I’ve been using an if/else function with digitalWrite to output low if the getButtonPress is true, else output high if the getButtonPress is false….using your example as a starting point. I’m new to all of this (you addind support for these controllers is really what brought me to the arduino), so if theres a better way of doing it, I’d appreciate it.

    Thanks!

  7. April 15th, 2013 at 17:38 | #7

    @Jerry
    It was caused by a bug in the getButtonPress in the function, but has now been fixed: https://github.com/felis/USB_Host_Shield_2.0/commit/78cb524bcf8e78b65205b0c2d80f73748a998712.
    Thanks for your feedback!

  8. Jerry
    April 15th, 2013 at 18:38 | #8

    @Lauszus

    Awesome! Thank you so much! Everything works perfectly now.

    So it was just an addition of a bool command? I admit I tried troubleshooting it myself before I posted, but the .cpp file is well beyond my comprehension at the moment. Thanks again!

  9. April 15th, 2013 at 18:40 | #9

    @Jerry
    Yes I only added a bool cast. The problem was that it’s was trying to return a uint32_t, but the function is only a uint8_t type, so the top 24 bits where actually thrown away.

  10. November 27th, 2013 at 09:20 | #10

    Hi, great job and thanks. We are using your library for controlling our robots ! We discovered two problems :
    - objects USB , XBOXUSB and XBOXRECV must be declared in global in the main file, otherwise, the usb.task reset the arduino.
    - the first time a button is pressed, it is not detected.

    Any idea or help ?

  11. November 27th, 2013 at 16:13 | #11

    @Sinclair
    Hmm that sounds strange. Are you checking if Usb is not null before calling Usb.Task()?

    Can you post your code somewhere, then I will have a look.

  12. Christoph
    April 9th, 2014 at 00:02 | #12

    Hi Kristian,

    thanks for your library and your hard work. It’s really great. Is it possible to use multiple wired xbox360 controllers if i connect them via an usb hub? Naively I would expect this works if I create multiple XBOXUSB objects. If this is not possible right now, could you give me a hint, how i could make this work?

  13. April 9th, 2014 at 00:06 | #13

    @Christoph
    Yes. Simply include the hub library and create the instance like so:

    #include <usbhub.h>

    USBHub Hub1(&Usb);

    After that just go crazy with those XBOXUSB instances ;)

    But please be aware that there might be several hub chips inside a usb hub, so if you need to connect a lot of devices you properly have to create another hub instance:

    USBHub Hub2(&Usb);
  14. taylor
    February 24th, 2015 at 15:36 | #14

    hi i am trying to make a rov submersible and i need help. I want to control it with a wired xbox controller but i have’int found any code that has output all i can find is code that uses a docgen but i would like to be able output pins on the arduino.

    can some one help?

  15. February 24th, 2015 at 19:32 | #15

    @taylor
    Have you seen the examples: https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/Xbox? You can just use digitalWrite to set a specific pin if a button is pressed etc.

  16. Ben
    June 10th, 2015 at 04:23 | #16

    I’m trying to use a Madkatz 4716 XBox 360 controller with the XBOXUSB example that comes with the USB Host library 2.0. The sketch uploads fine but it’s not detecting the controller (I get “XBOX USB Library Started” but nothing further in the terminal). I ran USB_Desc and saw that the PID (4716) and VID (0738) do not match the ones that correspond to Madcatz in XBOXUSB.h/XBOXUSB.cpp. Is it ok to try subbing those values into my copy of the library? This seems like the reason it’s not detecting. Thoughts?

  17. June 10th, 2015 at 09:26 | #17

    @Ben
    Yes you can just add the VID here: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXUSB.h, but please tell me if it works, so I can add it to the official repository.

  18. June 10th, 2015 at 09:26 | #18

    @Ben
    Btw you can enable serial debugging: https://github.com/felis/USB_Host_Shield_2.0#enable-debugging, so you can see what is going on.

  19. Ben
    June 10th, 2015 at 16:00 | #19

    @Kristian Lauszus
    I added the VID and PID to XBOXUSB.h and XBOXUSB.cpp and now, with debug enabled, I get these messages:

    XBOX USB Library Started
    XBOXUSB Init
    Addr: 01
    Xbox 360 Controller Connected

    However, at this point, it does not respond to pressing the controls. I also tried calling Xbox.setLedOn(LED1) to no effect.

  20. Ben
    June 10th, 2015 at 18:37 | #20

    This is so strange -- I fiddled with various files but then ended up back where I started, programmed, and all of a sudden it was working. Then reprogrammed the exact same thing and it stopped working. As far as I know nothing got changed except the VID/PID stuff. Very frustrating.

    In other news, I acquired a wireless controller with a USB adapter which is also not able to be detected (the PID gets rejected as a wireless controller, and if I change the code not to reject it, it still doesn’t show what the buttons are doing).

  21. June 10th, 2015 at 21:48 | #21

    @Ben
    I am not sure what you might have done wrong, but please test the following pull request: https://github.com/felis/USB_Host_Shield_2.0/pull/157 and tell me if it works or not.

    If you post the VID and PID of the wireless receiver I will add support for that as well.

  22. Ben
    June 11th, 2015 at 22:14 | #22

    After looking at your pull request, It’s doing the same thing I was doing (creating a new VID/PID and modifying the checks in the two library files to allow those identifiers). As before, I get this:

    XBOX USB Library Started
    XBOXUSB Init
    Addr: 01
    Xbox 360 Controller Connected

    There must be some more subtle difference in this Madcatz controller, no?

  23. June 12th, 2015 at 01:37 | #23

    @Ben
    So basically nothing happens when you press any of the buttons. Please try to uncomment the following line: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXUSB.cpp#L21 and tell me if the bytes printed change when you press any button, move the joysticks etc.

  24. Ben
    June 12th, 2015 at 14:58 | #24

    @Kristian Lauszus

    I should have mentioned that I tried this. I retried just because, and both times I got nothing but 00 00 00 00…….etc

  25. June 13th, 2015 at 19:57 | #25

    @Ben
    Could you try to the following example: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/USB_desc/USB_desc.ino and post the output?

  26. Ben
    June 15th, 2015 at 20:32 | #26

    @Kristian Lauszus

    Here’s the output for the Madkatz controller:
    http://codeshare.io/cYMHz

    Here’s the same for the wireless Microsoft controller with the USB adapter:
    http://codeshare.io/A2oqH

  27. June 16th, 2015 at 16:46 | #27

    @Ben
    The Mad Catz controller report looks fine. The only thing I can come up with is that you could try to add a 10 ms delay in your loop i.e.:

    delay(10);

    Note that you can not use a wireless controller via USB. This is a hardware limitation and is nothing we can do about it. The usb cable for the wireless controller is only used for charging. That is why the report: http://codeshare.io/A2oqH shows no endpoints.

  28. Ben
    July 8th, 2015 at 21:41 | #28

    You may recall we talked about that Madkatz controller -- I ended up just buying a wired Microsoft XBox 360 controller which has worked (more or less) fine.

    I have code written to scale a pair of PWM outputs (proportional valves for a bi-directional hydraulic cylinder) based on the left hat x-axis. It works, basically, but for some reason, after working correctly for a short time it locks up and holds the PWM value at the time of lockup indefinitely. Can you see anything in the code that might cause this?

    #include <XBOXUSB.h>

    // Satisfy the IDE, which needs to see the include statment in the ino too.
    #ifdef dobogusinclude
    #include <spi4teensy3.h>
    #include <SPI.h>
    #endif

    USB Usb;
    XBOXUSB Xbox(&Usb);
    int16_t LeftHatXPrev, LeftHatYPrev, RightHatXPrev, RightHatYPrev;
    int16_t LeftHatXCurr, LeftHatYCurr, RightHatXCurr, RightHatYCurr;
    int16_t AnalogHatZeroThresh;
    int16_t AnalogHatMoveThresh;

    void setup() {
      AnalogHatMoveThresh = 1000;
      AnalogHatZeroThresh = 5500;
      LeftHatXPrev = 0;
      LeftHatXCurr = 0;
      pinMode(13,OUTPUT);
      pinMode(12,OUTPUT);
      Serial.begin(115200);
    #if !defined(__MIPSEL__)
      while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
    #endif
      if (Usb.Init() == -1) {
        Serial.print(F("\r\nOSC did not start"));
        while (1); //halt
      }
      Serial.print(F("\r\nXBOX USB Library Started"));
    }

    void loop() {
      Usb.Task();
      if (Xbox.Xbox360Connected)
      {
        // **Left Hat X**
        // Make sure stick has moved AnalogHatMoveThresh before changing output

        LeftHatXCurr = Xbox.getAnalogHat(LeftHatX);
        if(((LeftHatXCurr > LeftHatXPrev) && (LeftHatXCurr - LeftHatXPrev > AnalogHatMoveThresh)) || ((LeftHatXCurr < LeftHatXPrev) && (LeftHatXPrev - LeftHatXCurr > AnalogHatMoveThresh)))
        {
          if(LeftHatXCurr > AnalogHatZeroThresh)
          {
            // Extend Secondary Arm
            analogWrite(5, floor((float)LeftHatXCurr/32768*255));
            analogWrite(4, 0);
          }
          else if (LeftHatXCurr < -AnalogHatZeroThresh)
          {
            // Retract Secondary Arm
            analogWrite(5, 0);
            analogWrite(4, floor((float)(-LeftHatXCurr)/32768*255));
          }
          else
          {
            analogWrite(5,0);
            analogWrite(4,0);
          }
         
          LeftHatXPrev = LeftHatXCurr;
        }
      }
      else
      {
        Serial.print("\nNot connected");
      }
      delay(100);
    }
  29. Ben
    July 8th, 2015 at 21:43 | #29

    @Ben

    I forgot to mention that serial with debug and extra debug enabled does not yield anything useful. Reprogramming or resetting the arduino (a Mega 2560) “fixes” the problem. I’m currently driving LEDs, but when I had serial prints showing what I was writing and what values I was reading from the controller, it behaved in an equivalent way, freezing after a time.

  30. Ben
    July 10th, 2015 at 16:18 | #30

    @Ben

    A further update: the freezing eventually goes away most of the time. Based on my own fiddling with debug print statements I know that the program continues running and that the USB data is not getting updated.

  31. Ben
    July 10th, 2015 at 17:58 | #31

    @Kristian Lauszus if you see this, please ignore -- I opened an issue on the github repo here: https://github.com/felis/USB_Host_Shield_2.0/issues/166

  32. July 11th, 2015 at 11:10 | #32

    @Ben
    I have responded at the Github issue: https://github.com/felis/USB_Host_Shield_2.0/issues/166.

Comment pages
1 2 2767
  1. December 12th, 2012 at 19:02 | #1