Xbox 360 receiver added to the USB Host Library
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 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:
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.


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.
@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).
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?
@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?
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
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?
@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
@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?
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?
@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.
> Could use perhaps try to increase this delay:
I tried increasing the delay to 10, and then removing the delay entirely, same results.
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.
@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?
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
@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
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.
@Tim
Try to change this: https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L148 to 0x81 and https://github.com/felis/USB_Host_Shield_2.0/blob/master/XBOXRECV.cpp#L161 to 0x83.
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.
@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?
@Tim
Could you try this on a Mega as well, it might be because you are running out of memory!
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.
@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
@Tim
I did it myself. It’s using 816 of ram at startup, so you are most likely running out of ram.
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.
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.
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.
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;
@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!
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.
@Tim
Okay. I will look into it when I get my hands on a second controller.
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?
@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.
Hi.
I can use your Library with Arduino Nano?
Thanks.
@Rubén González
Yes as long as it is the ATmega328 version.
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.
@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:
You can just cut the GPX connection as it’s not used by ver. 2 of the code.
Ok, I can see, thank you very much.
@Rubén González
See the updated reply. WordPress removed some of the code.
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.
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.
@Adam
Good to hear you solved the issue. Fell free to contact me again if you need any more help
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.
@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