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

Xbox 360 receiver added to the USB Host Library

December 29th, 2012 Leave a comment Go to comments

You asked for it and here it is.
I finally got the time to implement support for Wireless Xbox 360 controllers to the USB Host Library. This is done via a Xbox 360 Wireless receiver that is normally intended for Windows computers.

The source code can be found at github: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp
There is an example as well: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Xbox/XBOXRECV/XBOXRECV.ino.

The receiver supports up to four controllers internally, so it was fairly easy to implement it.

Actually I havn’t tested the library with more than one controller, but if somebody out there could confirm if it’s working or not, with more than one controller, I would really appreciate it!
Thanks to Tim, multiple controllers is now confirmed to work!

If you need to use more than four controllers you will need to connect a second receiver via a USB hub which is also supported by the library.
Simply add the following to the start of your Arduino sketch:

USBHub  Hub1(&Usb);
USBHub  Hub2(&Usb);

Note that you might need to add more instances depending on how many chips there is inside your USB hub.

You will also need to create another instance of the XBOXRECV class like so:

USB Usb;
XBOXRECV Xbox1(&Usb);
XBOXRECV Xbox2(&Usb);

For more information regarding the protocol see the following pages: http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/WirelessUsbInfo and https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL.

Categories: Arduino, TKJ Electronics, USB Tags:
  1. Tim
    January 2nd, 2013 at 21:13 | #1

    Thanks for the nice work putting this library together -- it works perfectly with one controller, but when I add a second one I get serial output corruption and hanging.

    Happy to help diagnose the problem where I can, but I don’t have an official Xbox usb receiver, and I am using the Sparkfun USB shield -- so someone with official versions might have more luck.
    I tried using both controllers attached to my PC and it works fine, so it does ordinarily cope with it.

  2. January 2nd, 2013 at 21:15 | #2

    @Tim
    First of all thanks for your feedback. Could you please uncomment EXTRADEBUG (https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L20) and send me the serial output? Then I will see if I can’t spot the problem.
    I don’t think the fact that you are using the Sparkfun shield is a problem, as you can use it with one controller. Please also connect a external powersupply to your Arduino as it might be power related (see this reply: http://blog.tkjelectronics.dk/2012/07/xbox-360-controller-support-added-to-the-usb-host-library/#comment-59256).

  3. Tim
    January 2nd, 2013 at 21:35 | #3

    Here’s the output:

    Xbox Wireless Receiver Library Started
    XBOXRECV Init
    Addr: 01
    Xbox Wireless Receiver Connected
    Bytes Received: 29
    A
    Bytes Received: 29
    Bytes Received: 29
    Bytes Received: 29
    Bytes Received: 29
    B
    Bytes Received: 29
    Bytes Received: 29
    Bytes Received: 29

    --
    the A and B output are correctly showing when I pressed A and B buttons.
    So After the last line is where I turned on the second controller -- which subsequently causes everything to freeze. The first controller becomes unresponsive and the LEDs stay in the same state, and the second controller just flashes away as if it is unable to connect.

    Any ideas?

  4. January 2nd, 2013 at 21:37 | #4

    @Tim
    Hmm, could you uncomment this line too: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L21 and then the output again?

  5. Tim
    January 2nd, 2013 at 21:39 | #5

    Xbox Wireless Receiver Library Started
    XBOXRECV Init
    Addr: 01
    Xbox Wireless Receiver Connected
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 10 00 00 37 00 F3 04 57 F2 C5 FF 00 00 00 00 00 00 00 00 00 00 00
    A
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 37 00 F3 04 57 F2 C5 FF 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 20 00 00 37 00 F3 04 57 F2 C5 FF 00 00 00 00 00 00 00 00 00 00 00
    B
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 37 00 F3 04 57 F2 C5 FF 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    --
    same actions as before

  6. Tim
    January 2nd, 2013 at 21:44 | #6

    I did perform a USB_Desc info dump on the wireless controller, it’s a bit long though, should I post it or email it to you?

  7. January 2nd, 2013 at 21:45 | #7

    @Tim
    What I think is weird is that you never receive the 0x08 report: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L302-L326
    You can just send it to my email: kristianl@tkjelectronics.dk

  8. January 2nd, 2013 at 21:50 | #8

    @Tim
    Thanks for your email. I will have to investigate this further. I might have to borrow a second controller…
    Could use perhaps try to increase this delay: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Xbox/XBOXRECV/XBOXRECV.ino#L109 to 10?

  9. Tim
    January 2nd, 2013 at 21:52 | #9

    This is what I get when I start the feed with no controllers switched on, and then turn them on after the line “Xbox Wireless Receiver Connected” is received:

    Xbox Wireless Receiver Library Started
    XBOXRECV Init
    Addr: 01
    Xbox Wireless Receiver Connected
    Bytes Received: 2
    Controller 0: connected
    Controller 0: 08 80
    Bytes Received: 29
    Controller 0: 00 0F 00 F0 F0 CC 42 AF 3C 60 AC 24 FB 50 00 05 13 E7 20 1D 30 03 40 01 50 01 FF FF FF
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 81 F0 C9 FF CA FF FD 13 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 20 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 F8 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 81 F0 C9 FF CA FF 9C 12 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 13 A2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 13 A2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    --
    I wonder if the message is being missed or dropped somewhere?

  10. January 2nd, 2013 at 21:55 | #10

    @Tim
    Try to remove this check: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L284 and this line: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L358 from nBytes to EP_MAXPKTSIZE.
    This should make it print the output it receives no matter if there are any errors.

  11. Tim
    January 2nd, 2013 at 21:56 | #11

    > Could use perhaps try to increase this delay:
    I tried increasing the delay to 10, and then removing the delay entirely, same results.

  12. Tim
    January 2nd, 2013 at 22:04 | #12

    So, there’s a lot more output this time! It still freezes when I turn the second controller on, I’ve truncated the repeated parts:
    (the first line appears to be random junk, not sure if this is just the Serial connection starting up)

    “µé`/”Åÿ
    Xbox Wireless Receiver Library Started
    XBOXRECV Init
    Addr: 01
    Xbox Wireless Receiver Connected
    Bytes Received: 0
    Controller 0:
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:
    Bytes Received: 0
    Controller 0:
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:

    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:
    Bytes Received: 2
    Controller 0: connected
    Controller 0: 08 80
    Bytes Received: 0
    Controller 1: connected
    Controller 1:
    Bytes Received: 0
    Controller 2: connected
    Controller 2:
    Bytes Received: 0
    Controller 3: connected
    Controller 3:
    Bytes Received: 29
    Controller 0: 00 0F 00 F0 F0 CC 42 AF 3C 60 AC 24 FB 50 00 05 13 A7 20 1D 30 03 40 01 50 01 FF FF FF
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:
    Bytes Received: 29
    Controller 0: 00 00 00 20 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0

    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:
    Bytes Received: 29
    Controller 0: 00 00 00 13 A2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:

    (Then I switched on the second controller)

    Bytes Received: 0
    Controller 2:
    Bytes Received: 0
    Controller 3:
    Bytes Received: 0
    Controller 0:
    Bytes Received: 0
    Controller 1:
    Bytes Received: 0
    Controller 2:
    Bytes Re

    --
    and it’s frozen.

  13. January 2nd, 2013 at 22:19 | #13

    @Tim
    I can’t see what’s wrong. I will get another controller and see if I can fix it! I really appreciate your feedback.
    Do you got a Wired Xbox controller as well, could you perhaps test something for me?

  14. Tim
    January 2nd, 2013 at 22:24 | #14

    I don’t have a wired one, sorry.

    I did just get something interesting though -- by adding a delay(10) at line 289, I can delay the process long enough for the Serial to print its buffer before it freezes, and I actually get a couple of packets from controller 2.
    If i leave the controllers alone, it freezes instantly -- but if i bash button A on Controller1, then press B on Controller2, I sometimes get a brief message from Controller2 before it freezes:

    Xbox Wireless Receiver Library Started
    XBOXRECV Init
    Addr: 01
    Xbox Wireless Receiver Connected
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 10 00 00 E9 01 F6 07 D9 FC 48 05 00 00 00 00 00 00 00 00 00 00 00
    A
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 E9 01 F6 07 D9 FC 48 05 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 10 00 00 E9 01 F6 07 D9 FC 48 05 00 00 00 00 00 00 00 00 00 00 00
    A
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 E9 01 F6 07 D9 FC 48 05 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 10 00 00 E9 01 F6 07 D9 FC 48 05 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 1: 00 01 00 F0 00 13 00 20 00 00 1E FF F7 10 DE 05 F6 03 00 00 00 00 00 00 00 00 00 00 00
    A
    B
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 1: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 01 00 F0 00 13 00 00 00 00 E9 01 F6 07 D9 FC 48 05 00 00 00 00 00 00 00 00 00 00 00
    Bytes Received: 29
    Controller 0: 00 00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  15. January 2nd, 2013 at 22:39 | #15

    @Tim
    Thanks once again. I just realized that I forgot a delay(1) here: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L282 as you can’t poll the endpoints that fast.
    I just pushed it to github: https://github.com/felis/USB_Host_Shield_2.0/commit/4fa973d441aae1dc8558c2274b7c5c688b929875

  16. Tim
    January 2nd, 2013 at 22:44 | #16

    Ok, so I added that, and it didn’t really affect it -- so I changed it to delay(10) and it’s better, I got about 3 seconds of 2 working controllers, but then it still freezes.

  17. Tim
    January 2nd, 2013 at 22:57 | #18

    nope, nothing works if I change those.
    Instead I tried changing #L167 to 0x81, but it still breaks -- with the added bonus of occasional “Error sending Xbox message” messages.

  18. January 2nd, 2013 at 23:01 | #19

    @Tim
    Okay. I just wanted to make sure that I did not have done something stupid.
    I will look more into this is the coming days. I will let you know when I got it working.
    Just one more thing. Do you have a external powersupply connected to the Arduino?

  19. January 2nd, 2013 at 23:04 | #20

    @Tim
    Could you try this on a Mega as well, it might be because you are running out of memory!

  20. Tim
    January 2nd, 2013 at 23:13 | #21

    I have external power connected.
    I don’t have a mega -- the only chips I have at the moment are 168′s -- I hope to have a 328 in a few days.

  21. January 2nd, 2013 at 23:28 | #22

    @Tim
    That’s properly the problem. You are likely running out of ram.
    Try to include the MemoryFree library: https://github.com/sudar/MemoryFree and tell the output of available ram when you run the sketch.
    There is more information here: http://playground.arduino.cc/Code/AvailableMemory

  22. January 2nd, 2013 at 23:49 | #23

    @Tim
    I did it myself. It’s using 816 of ram at startup, so you are most likely running out of ram.

  23. Tim
    January 3rd, 2013 at 18:52 | #24

    So my Arduino 328 Uno arrived and I’ve plumbed it in, but I get the same problem -- one controller is fine, two kills it.

    I had another look at the specs sheet and the Uno has 2Kb of SRAM versus the 1Kb in the Diecimila which I was using before.

    Freemem is reported at a constant 1312 bytes, from boot to crash.

  24. Tim
    January 3rd, 2013 at 19:32 | #25

    I’ve traced the hang down to a function in usbhost.h, line 101:
    void MAX3421e::regWr( uint8_t reg, uint8_t data )

    --
    not sure where to go next.

  25. Tim
    January 3rd, 2013 at 19:59 | #26

    Ok, ignore the previous comment -- the program is stopping because an assert is failing at (approx) line 252 in Usb.cpp:
    assert(pktsize <= nbytes);
    because nbytes is zero.

  26. Tim
    January 3rd, 2013 at 20:09 | #27

    Fixed it :)

    Changed in XBOXRECV.cpp (approx) line 267:
    if (!bPollEnable)
    return 0;
    uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
    for(uint8_t i=0;i<4;i++) {

    --to--
    if (!bPollEnable)
    return 0;
    for(uint8_t i=0;i<4;i++) {
    uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;

  27. January 3rd, 2013 at 20:19 | #28

    @Tim
    Awesome. Thanks man!
    I just pushed it to Github: https://github.com/felis/USB_Host_Shield_2.0/commit/47d1a6b8b69a1a7e6a6e6055a038e61feb6d9a8f please confirm it’s working now! :)

  28. Tim
    January 3rd, 2013 at 20:27 | #29

    Glad I could help, that all works pretty well, but I’ve got a new bug for you :)

    Sometimes the controllers are getting each other’s commands -- if I use the keypad on one controller, it sometimes changes the lights on the other controller.

    Similarly, sometimes pressing the trigger on one controller starts the vibration motor on the other controller.

  29. January 3rd, 2013 at 20:40 | #30

    @Tim
    Okay. I will look into it when I get my hands on a second controller.

  30. Tim
    January 3rd, 2013 at 20:43 | #31

    Ok, now that I’ve refreshed the code I can’t reproduce the problem. So for now I’ll assume that this one was a gremlin in my code :)

    Thanks for your help with this, was good fun figuring out how this stuff works.

    Out of interest, are you going to try to put any more functionality into these files, like reading controller battery level, and powering off the controller?

  31. January 3rd, 2013 at 20:50 | #32

    @Tim
    The problem is that the guy I borrowed the wireless controller from can’t find his charging cable so I’m actually just powering it off 3.3V from the Arduino, so I didn’t look into it.
    But as you can see on this page: http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/WirelessUsbInfo he suspects it’s the byte after 0x13 in the 0x00 report to be the battery level. Maybe you could simply make it output this value for a couple of hours or so and see if it decreased like it should?

    To power the device off try to send these commands: https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL#L609-L610 and see if it works.

  32. Rubén González
    January 8th, 2013 at 23:41 | #33

    Hi.

    I can use your Library with Arduino Nano?

    Thanks.

  33. January 8th, 2013 at 23:54 | #34

    @Rubén González
    Yes as long as it is the ATmega328 version.

  34. Rubén González
    January 9th, 2013 at 00:24 | #35

    Ok, so I will to buy a USBHost http://www.gravitech.us/usadforarna.html for start with my project. I hope work bacause it work with MAX3421E like USB Host Shield 2.0 for Arduino in http://www.circuitsathome.com/products-page/arduino-shields. is correct?

    Sorry for absurd questions but I’m a newbie in the electronic world.

    Thank you for this great work.

  35. January 9th, 2013 at 00:33 | #36

    @Rubén González
    It’s not directly compatible as the pinout is not the same.
    But it will work if you change this line: https://github.com/felis/USB_Host_Shield_2.0/blob/master/Usb.h#L61 to:

    typedef MAX3421e<P8, P2>        MAX3421E;

    You can just cut the GPX connection as it’s not used by ver. 2 of the code.

  36. Rubén González
    January 9th, 2013 at 22:41 | #37

    Ok, I can see, thank you very much.

  37. January 10th, 2013 at 11:13 | #38

    @Rubén González
    See the updated reply. WordPress removed some of the code.

  38. Adam
    May 4th, 2013 at 00:34 | #39

    This is probably simple, but I can’t get the wireless xbox controller to init unless I open the serial window. Then it drops connection the second I close it. I’m looking to impliment a wireless application of the xBox controller without a PC. I tryied turning debug off and it doesn’t seem to help. Any advise would be extreamly helpful.

  39. Adam
    May 4th, 2013 at 00:59 | #40

    I was just able to figure it out, it was a problem with the arduino autoreset and having the max reset pin tied to an IO.

  40. May 4th, 2013 at 17:54 | #41

    @Adam
    Good to hear you solved the issue. Fell free to contact me again if you need any more help :)

  41. Carl Davey
    May 8th, 2013 at 14:39 | #42

    what a fantastic library!
    Does anyone know if the Xbox receiver will work ok on the 3.3v Vbus supplied by the mini host shield.

  42. May 10th, 2013 at 17:08 | #43

    @Carl Davey
    No I have tried it, but if you have 5V available then it’s no problem to connect 5V to the VBUS line anyway :)

  1. January 2nd, 2013 at 22:38 | #1
  2. February 17th, 2013 at 15:32 | #2