XBox 360 S Controller

XBOX controllers

Preamble

I was trying to save cash, whilst trying to design a robot, and I was reluctant to purchase a full-on R/C transmitter, as these can be rather expensive.

After considering the PS2 controller options, which include using:

  • a custom PS2 receiver;
  • a standard generic Bluetooth USB adapter, and;
  • fooling the USB shield from wireless to wired (using the custom PS2 receiver).

For more information about these three options, see the PS2 controller blog.

However, I then thought that I would see if I could use an XBox controller. Again there are multiple options available to the hacker:

  • Using a Microsoft wireless optical desktop receiver;
  • Using a generic Chinese clone;
  • Using the RF receiver from an XBox, and;
  • Some other hardware solution.

This blog will investigate each of these options.

See also the blog, USB Shield.

Microsoft wireless optical desktop receiver

Taking the first option, not wishing to purchase a new Microsoft dongle, I looked around to see what I already had to hand. For example, would it work with my existing, but defunct, Microsoft wireless optical desktop receiver 2.0 (designed for the keyboard and mouse),.?

Microsoft Wireless Optical desktop receiver 2.0
Microsoft Wireless Optical desktop receiver 2.0

which I could then plug into my Arduino USB host shield, without having to purchase a XBox controller specific receiver.

The site has the answer: Will a wireless Xbox controller connect to my PC via a “Microsoft …, or maybe not, seeing as the link is dead, it is hard to tell. This link Is Microsoft wireless optical desktop receiver 1.0A compatible  says that version 1.0 is not.

Video Tutorials

A video on how to attach the controller to a PC

Connecting XBox controller to PC via keyboard and mouse receiver

Can’t be done, version 3.0 again, Connecting Xbox 360 Controller to PC – Microsoft Community

Wireless Xbox 360 Controller Receiver For Windows Not Detecting  , again, no real answers.

Maybe it can not be done, the hardware/firmware of the earlier 2.0 models is incompatible?

How to resolve the driver issue:

Firstly, download the drivers and install them. Then:

  1. Right click on Computer
  2. Go to Properties
  3. Click on Device Manager
  4. Right click on the Unidentified Device
  5. Go to Properties
  6. Go to the Drive tab
  7. Click on Update Driver…
  8. Browse my computer for driver software
  9. Let me pick from a list of device drivers on my computer
  10. Windows Common Controller for Window Class
  11. Xbox 360 Wireless Receiver for Windows Version: 2.1.0.1349
  12. Update Driver Warning
  13. Click Yes

All done. Press the button on the receiver and press the pair button on your controller

Source: 1, 2, 3, …

Install Driver for Windows7 64Bit

1. Download the 64bit driver here: http://www.microsoft.com/hardware/download/download.aspx?category=gaming
2. Plug in your wireless receiver
3. Go to your Control Panel -> Devices and Printers -> Device Manager -> Unknown Device
4.Double Click the Unknown Device and click the Hardware tab , choose Update Driver
5.Select Browser my computer for driver software
6.Select Let me pick from a list of device drivers on my computer
7.Scroll down and select “Microsoft Common Controller for Windows” Class and click “Next”
8.Select “Xbox 360 Wireless Receiver for Windows” and click on next.
9.Select Yes for any warning message
10. Done.

Practical Test

I decided to try regardless, using the kit that I have, and… nothing! My receiver did not appear to recognise the XBox controller at all.

So, time to purchase a USB receiver, to use in conjunction with the Arduino USB Host shield.

Clone USB XBox Receiver Dongle

On eBay, for £4.04, PC Wireless Gaming Controller USB Receiver Adapter For XBOX 360 New HP, is the cheapest.

The next cheapest Chinese clones are about £4.18, PC Wireless Gaming Controller USB Receiver Adapter For Microsoft XBOX 360 LK

USB XBox Receiver
USB XBox Receiver

Some code for USB Dongles

From Get the Xbox Controller Communicating to the Arduino on Instructables

Arduino Code
// *****************************
// *    RC Power Wheels Jeep   *
// *****************************

/*

OVERVIEW
A 12v dual-motor Power Wheels Jeep Hurricane will have drive
and steering remotely-controlled via Arduino.

HARDWARE
Power Wheels Jeep Hurricane
Arduino UNO R3
Circuits@Home USB Host Shield 2.0          http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino
Pololu Simple Motor Controller 18v25       http://www.pololu.com/catalog/product/1381/resources
Pololu JRK Motor Controller 12v12          http://www.pololu.com/catalog/product/1393/resources
Pololu Generic Linear Actuator 4" .6"/s    http://www.pololu.com/catalog/product/2333
Xbox 360 Wireless USB Adapter
Xbox 360 Wireless Controller

HARDWARE CONFIGURATION

* +-------+         +---------------+  USB    +-----------------+
* |Arduino+-------->|USB Host Shield+-------->|XBOX USB Receiver|****/>      // Xbox 360 Wireless Receiver

//Create USB instance? USB SHIELD
USB Usb;

// Create an instance of the Xbox Receiver inputs called XboxRCV
XBOXRECV XboxRCV(&Usb);  // USB SHIELD

// These next constants are bytes part of the Pololu Protocol
const byte pololuCommandByte = 170;
const byte smcDeviceNumber = 13;
const byte smcSpeedDataByte3 = 0;
const byte smcFWDbyte = 5;
const byte smcREVbyte = 6;
const byte jrkDeviceNumber = 11;

char smcSpeed;  // Final speed
long int leftStickX; // Xbox Left Analog Stick value


void setup(){
  Serial.begin(9600);    // Serial baud rate to 9600

    // Halt program until shield is connected
  // USB.Init will return -1 for shield disconnected and 0 if connected
  if (Usb.Init() == -1) {    // If USB shield did not initialise for whatever reason...
    while(1); //halt as long as shield is reported disconnected
  }

}


void loop(){
  Usb.Task();
  // Let's process the Xbox input
  if(XboxRCV.Xbox360Connected[0]) {

    // START button sends exitSafeStart command to SMC
    if(XboxRCV.getButtonClick(START,0)){
      // *******************************
      // *        exitSafeStart        *
      // *******************************
      // Required to allow motors connected to SMC to move
      // Must be called when controller restarts and after any error
      // Pololu Protocol: 0xAA (170) | device number | 0x03 (3)
      Serial.write(pololuCommandByte);
      Serial.write(smcDeviceNumber);
      Serial.write(3);
    }

    /* The Xbox triggers provide values from 0 - 255. The SMC will accept a low
     resolution speed value as a percentage, 0% - 100% (High resolution is
     a 2-byte int). The next two lines maps the controller to output a
     negative value for L2 (Reverse) and positive for R2 (Forward). These two
     values are then summed to provide the final speed and direction. This is
     so that both triggers can be held simultaneosly without causing the values
     to oscillate between Forward and Reverse
     */
    char XboxL2 = map((XboxRCV.getButtonPress(L2,0)), 0, 255, 0, -100);
    char XboxR2 = map((XboxRCV.getButtonPress(R2,0)), 0, 255, 0, 100);


    // Sum the mapped inputs together to give a final speed and direction
    smcSpeed = XboxL2 + XboxR2;



    /* The sample code for the Xbox controller gave a deadzone of -7500 to 7500.
     This code maintains that dead zone for now (I would like to make it
     adjustable while the sketch is running). */

    leftStickX = map(XboxRCV.getAnalogHat(LeftHatX,0), -32768, 32767, 0, 3880);  // Analog stick moved
    // Set the dead band in the left analog stick. Would like this to be adjustable
    if ((leftStickX >= 1500) && (leftStickX <= 1983)){
      leftStickX = 1400;
    }
  }

  // If no triggers/sticks are moving, then center and zero
  else {
    leftStickX = 1400;
    smcSpeed = 0;
  }


  // ************* RESERVED "HEARTBEAT" **********
  // "Heartbeat" will send a serial command every x seconds as a "keep-alive" to the SMC and JRK
  // controllers. It will also prevent duplicate commands from flooding the serial buffer (ideal
  // for Xbee implementation).


  // *******************************
  // *      SEND SERIAL COMMANDS   *
  // *******************************
  /* Reserved for serial commands sent to motor controllers to adjust
   option parameters. Also to process the response from those
   commands if applicable. */



  // THIS SECTION SENDS THE SPEED AND DIRECTION COMMANDS TO THE SMC
  // *******************************
  // *        setMotorSpeed        *
  // *******************************
  /*
  http://www.pololu.com/docs/0J44/6.2.1
  
   The Pololu SMC can use a full resolution speed value (-3200 to 3200), however, this is not needed
   (yet) since the Xbox controller analog triggers only output 0 to 255. The below tables are copied
   straight from the manual linked above. We'll be using a low resolution speed value expressed in
   percentage (0 to 100).
  
   "Alternate Interpretation: The allowed values for the second speed data byte are 0–100,
   so you can ignore the first speed data byte (always set it to 0), and consider the
   second data byte to simply be the speed percentage. For example, to drive the motor at
   53% speed, you would use byte1=0 and byte2=53."
  
   Motor Forward
                    Command Byte Data Byte 1 Data Byte 2 Data Byte 3 Data Byte 4
   Pololu Alternate Use 0xAA (170) device number 0x05 (5) 0 (always)      speed %
  
  
   Motor Reverse (data byte 2 changes)
                    Command Byte Data Byte 1 Data Byte 2 Data Byte 3 Data Byte 4
   Pololu Alternate Use 0xAA (170) device number 0x06 (6) 0 (always)      speed %
  
   */
  // smcSpeed should be a number from -100 to 100

    // First send the Pololu SMC command byte
  Serial.write(pololuCommandByte);

  // Next, send the SMC device number
  Serial.write(smcDeviceNumber);

  // Here, let's determine the speed and direction.
  if (smcSpeed < 0) // Let's reverse since the speed is negative    {     Serial.write(6); // motor reverse command      smcSpeed = -smcSpeed; // make smcSpeed positive b/c command can only read positive numbers    } else {      Serial.write(5); // motor forward command    }    Serial.write(smcSpeedDataByte3); // Always zero (for now) because of the protocol being used                                     // Now let's send the actual speed    Serial.write(smcSpeed);    delay(1); // For stability    // NEXT SECTION SENDS THE POSITION TO THE LINEAR ACTUATOR VIA THE JRK    // *******************************    // * setJRKPos *    // *******************************    /* http://www.pololu.com/docs/0J38/4.e    Pololu protocol, hex: 0xAA, device number, 0x40 + target low 5 bits, target high 7 bits    Here is some example C code that will generate the correct serial bytes,    given an integer “target" that holds the desired target (0 - 4095)    and an array called serialBytes:    1 serialBytes[0] = 0xC0 + (target & 0x1F); // Command byte holds the lower 5 bits of target.    2 serialBytes[1] = (target >> 5) & 0x7F;   // Data byte holds the upper 7 bits of target. 
  */

  Serial.write(pololuCommandByte);
  Serial.write(jrkDeviceNumber);
  Serial.write(0x40 + (leftStickX & 0x1F));
  Serial.write((leftStickX >> 5) & 0x7F);

  delay(1);  // For stability
}

Using a USB Host Shield 2.0 Library

From Xbox360 controller support added to USB Host Shield 2.0 library, there is some fine information of github, about the Xbox Library.

Using parts from an XBox

However, saying that, it should be possible to rig up a 2.4GHz circuit to do the same thing as a USB dongle. That will need looking into, but this topic is rather large and so is covered in a separate blog, see Make an XBox Receiver – From a RROD XBox 360.

Advertisements

4 thoughts on “XBOX controllers”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s