Posts

PS3 and Wiimote Game Controllers on the Arduino Host Shield: Part 1

Bluetooth

Bluetooth


Revision 0.9 – 13th January 2010

Part 1: Introduction

1.       Background
These articles describe how to interface PS3 and Wiimote game controllers directly onto the Arduino using the USB Host Shield. These controllers have not previously been directly connected to an Arduino due to the USB and Bluetooth interfaces and protocols used, and their relative complexity. The game controllers are a good match to the capabilities of the Arduino, and to the imagination of Arduino users, they have not only buttons and joysticks, but also motion sensing, and other goodies which deserve to be in the hands and ideas of Arduino users. Also I hope these articles provide some guidance for people to develop other USB host and Bluetooth applications for small embedded processors.
Arduino already comes in versions which have USB and Bluetooth interfaces, but these are not suitable for our chosen game controllers. When used in USB mode, the PS3 controller is a USB device and needs to talk to a USB host. The normal Arduino USB interface is also a device, so not compatible. When in Bluetooth mode, both of these game controllers use the Bluetooth HID protocol and this is not compatible with the commonly used Bluetooth modules which support only the RFCOMM Serial Port Protocol. Arduino users have successfully used a PC as an intermediary between the game controllers and the Arduino, so the PC is host to both devices.

These articles were written by Richard who is new to the Arduino, blogs, github, libraries, etc, so please give me any help and feedback on how I might improve or correct these articles and software.

This video shows the PS3 controller and the Wiimote bluetooth working on the basic Atmega168 Arduino.
Introduction Youtube Video

Recently a new Arduino shield has been developed by Oleg here at Circuits@Home, which provides a USB host interface directly onto the Arduino. This shield is based on the MAX3421E USB controller IC from Maxim, which can operate in both device and host modes. Oleg has also created libraries for the basic functions of the MAX3421E and USB host operation. I have previously used the MAX3421E with success on other processors and decided to try to add support for our game controllers using this shield. There are significant challenges to this due to the complexity of the protocols and the limited flash and SRAM space on the base Atmega168 based Arduino.

The code developed here is licensed under the LGPL License and should be fairly easy to port to other USB host controllers. Given the recent explosion in availability of microcontrollers with integrated USB OTG or reduced host, from Atmel, Microchip and others, then I would expect quite a few derived versions.

You will see as the code develops the fairly high complexity of the protocols involved, and such development effort is only really justified in a case like this where no off the shelf alternative has been found. There are integrated USB host solutions from GHI Electronics and FTDI Vinculum, but these again do not support the Bluetooth HID yet. They do support many other devices and classes including mass storage, serial, and HID, they can be interfaced to Arduino and do not put such a drain on the memory and programming of the Arduino.

2.       The PS3 Controller

Sony PS3 Controller
I have used two PS3 different game controllers; the first is a Sony Six Axis Dual Shock 3 Wireless controller, and the second is the Madcatz Wireless six axis controller. The Sony has a USB connector and also operates in Bluetooth mode for wireless. The Madcatz comes with its own USB dongle, so uses a proprietary wireless protocol instead of Bluetooth. The PS3 controller is well documented and supported already with drivers and applications on Windows and Linux besides the PS3 itself, so there is plenty of interface information available.
Madcatz PS3 Controller
 

The PS3 controller has a large number of buttons which can be read as digital values and some as analog pressure values. There are two joysticks which can be read with analog values to 8 bit resolution, and also 4 LED’s which can be remotely controlled. There are additionally a 3 axis accelerometer and a single axis gyro which give outputs based on the motion of the controller. The Sony controller additionally has two rumble motors.

The following sources have been used to find information and code examples for the PS3 controllers:

PS3 Wiki General

PS3 using Python

PS3 under Linux

SixAxis on Windows

PS3 Windows Driver

3.       Wiimote Controller

Wiimote
 

The Wiimote has less buttons than the PS3 controller and the characteristic stick shape. Though less well endowed with buttons and joysticks than the PS3 controller it has a 3 axis accelerometer, rumble, Infra-Red Camera, speaker and LED. It also has an expansion port where additional devices including 3 axis Gyro and remote joystick can be connected.

The Wiimote does not have a direct USB connection and only works under Bluetooth.

The following sources have been used to find information and code examples for the Wiimote Controllers:

Wiimote Wiki General

Wiimote Information

Wiimote Wiki: Detail

Wiimote using Linux

4.       Arduino

I chose to use the lowest spec AtMega168 based Arduino and this forced me to be always conscious of the amount of Flash and data memory used. I made extensive use of the MemoryFree library to keep track of the usage of the 1K of RAM. I tried to limit were possible the number and size of data buffers, and to keep the number of text strings as low as possible.

Original MemoryFree

I later modified MemoryFree to allow capture and storage of minimum values. This enables the viewing of free memory at the deepest level of the function calls, where any problems occur.

Modified MemoryFree

 
In terms of processing power the Arduino does not seem to limit performance. Some complexity is added to the code because it is necessary to avoid blocking code. Blocking code would prevent some of the background processes running. These processes are not absolutely time critical, but must be called regularly. The time taken to write a serial string is usually OK, the time to wait for a key press would not be.

 

5.       USB  Host Shield

The Circuits at Home USB host shield is based on the Maxim MAX3421E USB controller IC. This IC can operate in device and host modes, though the Arduino library only supports the host mode. The USB host shield offers a number of interface options for different Arduino types using 3.3V or 5V power supplies. There is also two 8 bit GPIO ports and a library to support an LCD display on this port.

The USB Host Shield is described and well documented here on the Circuits@Home website.

Full construction information is provided including schematic and PCB layout, or PCB and built boards are available in the on-line store.

The USB shield uses the following Arduino hardware resources which are then not available for other purposes:
Digital Pin 7 used for MAX_RESET
Digital Pin 8 used for GPX
Digital Pin 9/PWM used for INT
Digital Pin 10/PWM used for SS
Digital Pin 11/PWM used for MOSI
Digital Pin 12 used for MISO
Digital Pin 13/LED used for SCLK

Power for the USB host shield is taken from the Arduino and also powers the USB device. Care must be taken to ensure the total supply current required is available from the Arduino and its power source.

The MAX3421 is documented in Datasheets, programming guide, and application notes by Maxim:

MAX3421E Datasheet

MAX3421E Programming Guide

Maxim Application Notes

Oleg at Circuits@Home has provided Arduino libraries for the MAX3421E function and the USB host function. Small modifications were necessary in these to support the game controllers, mainly in the NAK handling to ensure non blocking behaviour. The changes should not interfere with existing applications using the libraries and may be incorporated to the standard library.

USB Host Shield Library

The library is based on code from Maxim for the ARM processor, but this original code is not complete:

Original Maxim ARM Code

USB is a complex protocol and even though much is done automatically by the MAX3421E, some knowledge of the USB protocol is needed. As primers, these are good sources:

USB in a Nutshell

USB Standards

After that the best references are the USB protocol specifications:

USB Specification

USB HID Specifications

6.       Bluetooth Dongles

Bluetooth USB dongles come from many suppliers and there is no way to support them all in a simple embedded application. I have used devices which are based on the Cambridge Silicon Radio(CSR) Bluecore 4. These devices are common and low cost at less than $5 each. The dongle is used is based on the BC41B143A chip. The data sheet is here:

BC41B143A Datasheet

The dongle conforms to the Bluetooth specification for an HCI interface and is available here:

Bluetooth 2.0 Specification

Bluetooth HID Specification

The dongle used came packaged like this:
Bluetooth USB Dongle
 
A more general Bluetooth protocol tutorial is available from palowireless.

7.       My Development Process and Following Articles

I decided to split the development and these articles into the following steps:

Part 2: Develop the USB interface to the PS3 controller. This allowed me to gain experience of the Arduino and the USB shield. It also provides a quick working wireless solution using the Madcatz game controller.

Part 3: Develop the Bluetooth USB and HCI interface used in the support of the Wiimote and PS3 game controller, and also some utilities needed to analyse and configure these devices.

Part 4: Develop the Wiimote support over Bluetooth

Part 5: Develop the PS3 support over Bluetooth

 
This article is provided under the Creative Commons Share Alike License

Associated software code developed by the author is licensed under the LGPL License.

50 comments to PS3 and Wiimote Game Controllers on the Arduino Host Shield: Part 1

  • […] has put together some libraries that make it easy to use gaming controllers with an Arduino. They interface through the USB host shield. This means that PS3 controllers connect via USB […]

  • Santiago Saldana

    Just wanted to say that I got the code to work with a Broadcom BCM2045 Here is my output from the program above:

    freeMemory() reports: 1514
    CSR Initialized
    HCI Reset complete
    ACL Data Packet Length: 1017
    SCO Data Packet Length: 64
    Total ACL Data Packets: 8
    Total SCO Data Packets: 0
    HCI Version: 3
    HCI Revision: 16430
    LMP Version: 3
    Manufacturer Id: 15
    LMP Subversion: 17166
    Local Name: BCM2045B3
    Unmanaged Event: 0

    Unmanaged Event: 0

    Local Bluetooth Address: 001E0A000062
    Search for devices
    Search complete
    Devices Found : 1
    Found BDADDR: 0017AB227962 Class: 042500 Mode: 1 Offset: 4C2D

    Remote Name: 0 Nintendo RVL-CNT-01
    Unmanaged Event: 0

    Connected to device

    However, I have issues getting the results to be consistent, so far I have to start the program, wait a few moments then push in the bluetooth dongle and hope for the best. It then searches for the wii remote, it says connected, but the light on the wiimote does not stay on. Is this normal, or do you get it to stay connected and receive events from pressing the various buttons on the wii remote?

  • Santiago Saldana

    Oh yeah, everytime I connect the Offset changes.

  • Richard

    Good to see the BCM2045 shows signs of working.
    The problems at startup may need some more delay for the Broadcom compared to the CSR.
    Offset will be different every time. It is the clock offset between the two devices, and only used to speed connections. I don’t use it.
    The blueutils sketch makes the HCI connection, but not the L2CAP connections, so that is why the wiimote times out.
    I have been distracted and not posted the next article with th L2CAP and HID part. I will put a sketch on github today which supports the LED, buttons and accelerometers on the wiimote, or I can e-mail to you. The nunchuck and IR camera is not complete in this version.
    I am not sure what the unmanaged event is, “0” is not a normal event code. It doesn’t seem to give a problem, but it would be good to investigate. What is the external manufacturer and model of your USB Bluetooth ?

  • Richard

    Sketch is here: http://github.com/ribbotson/USB-Host/blob/master/examples/wiiblue.pde
    It should set the LED 1 on and stop the flashing.
    Button codes are sent to serial port. “1” button shows accelerometer values.
    If you get a message after a sketch restart of ” No response to HCI Reset”, you may have to unplug and replug the dongle to cycle power because the USB Host shield does not have power control. I am still tring to find a reset method without power control.

  • I only wanted to drop you a short note to inform you that I really enjoy your articles. Thanks! Keep on the good work

  • Sam

    Hi. I’m in my school’s robotics club and we’re following these guides to try and sync up a PS3 controller to an arduino board to control our robot. We have got the PS3LCD sketch to compile (finally) and now have absolutely no idea where to connect the pins? Is there a clear picture of how to connect it all up? We really need to know just what pins to plug into where from where and all that.

    Any help would be incredibly appreciated. 🙂
    Thanks so much and keep up the good work.
    Sam.

  • Jeremy

    Hi. I wanted to control 3 motors thanks to a Wiimote, by using the accelerometers. I think that using an Arduino card is the best solution, but I don’t really know how to proceed.

    In fact, I want to connect the Wiimote directly with the Arduino, without computer as host. I find your post very interesting and now I’m sure it’s possible but I wanted some help to know which Arduino card I must buy. Is it possible with an Arduino BT, which already contains a Bluetooth module ? (I’ve seen nowhere that it supports HID technology)

    If not, what changes must I make on the Arduino USB Host Shield ? I’ve read the topic “Arduino USB Host Shield build” but I don’t really understand what changes I must do…

    Thanks for your help !

    • Arduino Duemilanove seems like a logical choice for this project. USB Host Shield “Simple” configuration is the one to which works with Duemilanove.

  • Richard

    The bluetooth on the Arduino BT supports only the serial SPP profile for communication between the PC and the Arduino. The Wiimote needs bluetooth HID, which can only be done on the host shield and USB bluetooth.
    Oleg can advise the right USB Host shield configuration for your Arduino version.

  • wingman128

    Hey Guys,

    I am using the bluegiga wt32 to connect to the wii mote and I was wondering if anyone has done this before? I am able to connect to the PSM 13 and I am having trouble connection to 11.

    Thanks

  • Richard

    As far as I know, nobody has succeeded in getting the wiimote working on a blugiga using iwrap. Bluegiga state they only support mouse and keyboard on HID. It can be done a bluegiga HCI module, but you have to write the HCI, L2CAP, and HID code.

    • wingman128

      I was able to get a connection using the wt32. I can change the LED and turn on rumble, and I can get x30 reports. The thing is now that I request x31 reports I get nothing. It seems like the wii mote just doesn’t want to send the info. Do you know if there is any trick to get the wii mote to send x31 reports.

      Wingman128

  • David

    Hi guys, I’m struggling with a few things and hope somebody might be able to advise me. I’m trying to use the ps3 accelerometers and gyro to control a movieclip in flash. I have tried a few different approaches but have run into a number of problems. When using an actionscript 3 socket the serial data displayed by flash is split into two lines. I’ve done some digging and found that this may to be due to the way that modern communications ports operate. As yet I cannot find a way to control the flow of data to avoid this issue. In addition to this splitting of data there seems to be a problem with reading a particular value for example if I do the following;

    trace(“sensors ” +accX);

    The outputs alternates between values for ALL the sensors i.e, accY, accX, accZ and gyrZ

    This may be connected to the timing problem also but I don’t know enough to tell.

    I’ve also had similar problem with an script written in as2, although this seems to be more to do with the fact that the data is coming in so fast it causes the app to hang then crash.

    Does anybody have any hints on the best way to interface with Flash? Can the hostshield be used with AS3glue? I’ve tried but don’t get usable data, I guess this may be because of the custom library for the shield…

    Any advice at this point would be massively appreciated.

    thanks,

    David

  • Richard

    I don’t know about flash and as2. or AS3glue. My thoughts are that the serial stream from the arduino is too fast for the PC app. and you lose data.
    Could you make the flash app. request data from the arduino, and make the arduino code only send data when requested ? I guess this is how firmata does it to control the data flow.

    • David

      Thanks for your reply Richard. I think some sort of flow control of the sort you suggested is what I need, I’m just not sure exactly how to apply it. I’ve abandoned that angle of attack for the moment and am using GLOVEPIE (which is actually pretty cool) but it’s dirty hack so may come back to the Hostshield.

      Thanks again,

      David

  • yashar

    hi,
    i have a question about the bluetooth library!!! how do you get the info about the hci commands and their parameters.
    like how would you know for example for inquiry what parameters should be set… the specification is too broad and lengthy and it seems i cant find it.
    i really appreciate your work and its been 3 months of fun studying and learning about usb and bluetooth and your libraries.
    yashar

  • Richard

    Though the bluetooth specifications are long and have a lot of information which is not needed, they remain my reference.

    For HCI commands and events, go straight to Volume 2, Part E, Section 7.

  • Paul

    Hi,

    has already somebody tried to connect an UMTS stick to the usb host shield?

    Regards,

    Paul

  • kerchunk

    I say, outstanding project and writeup! This thread seems a good place to post my question – I’d like to create something quite similar but with two USB ports to serve as an interface between a PC-centric game controller (Thrustmaster HOTAS Cougar flightstick) and a PS3. The HOTAS is configured as a USB device and would connect to the interface via MAX3421E(host), while the PS3 would connect to the interface via MAX3421E(device), with the interface doing the translating. It’d also read a bank of DIP switches to determine which set of HOTAS/PS3 controller button mappings to use (because the “throttle” pressure button on a PS3 controller for one game is not the same for a different game – this results in really lousy scores!)

    Or a simpler alternative would be to wire the PS3 controller’s buttons to a Arduino’s assorted GPIO pins – this has the advantage of not having to monkey with the PS3 side of the interface at all.

    Ideas/suggestions/comments/constructive criticisms are all welcome!

    TIA,

    Still-learning Steve

  • Dan

    Whatever happened to parts 4 and 5 anyways?

  • Nathan

    So, I plan on using the USB Host Shield eventually, but I noticed in the introduction that you said using the PC as host had already been done. I’ve been researching this topic, and would love a link to how to do this. I’d like to use a Wiimote to send commands to the Arduino via the serial port/bluetooth communication. I realize that I need HID to do direct communication, but which programs should I use to host the communication with my computer?

    Cheers,

    Nathan

  • Beeker

    Theoretically, would it be possible to have a ps3 controller connected to a ps3 normally, either wirelessly or via usb, and then also have an arduino listening only (reading) the commands being sent from the controller.

    I’m imaging a scenario where an arduino triggers lights/motors things during gameplay of a ps3 via the controller.

    Almost all of the work I’ve seen done is where the controller is being used as a one to one, or a many to one, but not a one to many (multiple listening points, a computer, an arduino, a ps3, etc.)

    Thanks!

  • Justin manchester

    I have a question. I have seen alot of ps3 input support but how about output? For instance. Ps3 plugged into usb shield. Would we need to create and load a firmware to output the controls to the ps3? Basically you press x on the controller the arduio reads x and you have it set to. Whenever x is pressed you output simulation of holding r1 and x.

    Any info would be greatly appriciated. I just want the ps3 to accept output from the arduino as a valid joystick. Thanks.

  • Richard Ibbotson

    To talk to the PS3 you need a USB HID device. You are probably best using an Atmel device with built in USB device. It may be possible to program the mega8u2 on an arduino mega2560 or a Uno. I think if I were doing this, I would look a chip with two USB (host + device) ports to avoid serialising the HID data.

    While making USB devices is usually easier than making hosts at the lower protocol levels, the reverse is often true at higher levels as you find a large number of enquiries and settings made by the PS3 and similar boxes when communicating with the controller. Some of this is to make it difficult for 3rd party clone controller suppliers, so often information is not documented.

    My suggestion would be to make first a sort of HID bridge between a USB device and the USB host shield to transparently connect a PS3 controller to the PS3. Then you can monitor the data transfer and maybe hopefully the data.

    I don’t have a PS3 so can’t be of much help.

  • Joshua Crisp

    I am a theatre student, and I want to use what you have made to create glasses with LED lights for each button on the game controller. I want audience members to be able to “control” live actors as if they were video game characters.I am a complete novice, but I have started working through “getting started with Arduino” and will be purchasing the USB host controller from this site shortly. I have three questions for those willing to help a highly motivated (but oblivious)non-tech person:

    1. Which code should I use from this page in order to recreate what you have done here with the Madcats controller pictured above?
    2. The code examples I saw while browsing tour links appear to be made of multiple files that reference each other like in Actionscript. Am I correct and, if so, how do I do that with Arduino?
    3. How do I modify the code to make it so that the buttons control LED lights?

    Thank you

  • nero

    I bought an arduino ADK board and a bluetooth dongle
    but wasnt able to apply the code for the BT PS3 controller

  • You have to uncomment the following line: https://github.com/felis/USB_Host_Shield_2.0/blob/master/avrpins.h#L25 for it to work with the Arduino ADK.

  • Towayne

    I know tht this has been done along tie ago but i am teen who want s to get into robotics and was wonder if you can use the ps3 controller and wii remote as the same time or would you need another arduino for that

  • Jerry bloom

    Hai,

    i am currently working on how to connect PS3 game controller with Bluetooth dongle + USB host Shield + Arduino Uno. It seems need a simple connection. i uploaded a Code that i found from Github sources to the Arduino board. When i am trying to Turn on the PS3 ps button, it seems Not able to communicate with the BlueTooth Dongle… Why is that?

    on Serial Monitor, i am able to see, ‘PS3 Library has started’ only..

    Anyone can help me, pls, Thank you in advance.

  • jerry bloom

    hai there, thanks for the info anyway. Finally, i managed to connect the PS3 controller to Bluetooth+usbhost shield + Arduino Uno board. i uploaded program code, i took off bluetooth dongle, i plugged in PS3 controller by using USB cable, then initialised, i plugged the Bluetooth dongle, then it worked fine.
    Now, the problems are, the Output pins from 2-12 wont gives out 5 volts, some pins only gives out 0.1106V – 2.4V, it varies aftersome time. i expect it to result out 5V. i ve tried to fix it by using an external 9V dc battery source into Vin Pin of arduino. but it wont work as expected. i need to know why it is like that? thank you in advance

  • electrolics

    Hello

    I have the madcatz wireless gamepad for ps3 but without the usb receiver.

    is possible to hack it to make it work with PC, Arduino and Android?

    thanks in advance

    • The Madcatz PS3 controller is already supported by the library. You can simply connect the controller directly to the USB Host shield.
      What are you trying to do with the Android phone?

      • jolean

        hey man I would like to know what code to use to clicks and presses into commands like turn on led.

        • Here is an example of turning an LED on/off:

          if (PS3.getButtonPress(CROSS))
            digitalWrite(led, HIGH);
          else
            digitalWrite(led, LOW);
          
  • AntonisK

    I am trying to build a R/C car controlled by wiimote using Arduino Uno, Usb Host Shield 2.0 and a bluetooth dongle. But I am kinda confused which bluetooth dongle I should buy. Should I look for something specifically or everything will work fine with just a typical CSR V4.0 bluetooth dongle?

  • Naseem Abbas

    Hi, I am trying to get the data from sensor through USB host shield, any example code how to proceed ??

  • Tim

    Hey!! How are you,
    Do you know a way to get the arduino to react to a button combination? for example if you press UP and DOWN.

    The next wil react to both, either UP or DOWN.
    if(PS3.getButtonClick(UP) || PS3.getButtonClick(DOWN)){

    but I need UP and DOWN, you know a way?
    Hope you can help,
    thanks in advanced

  • Daniel

    Hi,
    Hopefully someone can help, i was hoping to connect the wii balance board to my arduino as described for the wiimote.
    I have been able to connect the wiimote but have no idea where to go next.
    cheers

  • Hi,
    I try to connect the Bluetooth keyboard and I am successful but on some BT Kay boards its not allow to give the pin from BT remote key boards ..Can I disable BT request pin request from library?

  • Hi,
    I just trying to connect my Bluetooth keyboard and terminal says this and stuck at the last line “Send HID Control Connection Request” any body know what I do next but on when I try to connect my bluetooth mouse its successfully paired and establish communication perfectly.

    HID Bluetooth Library Started
    Bluetooth Dongle Initialized
    HCI Reset complete
    Write class of device
    Local Bluetooth Address: 00:15:83:0C:BF:EB
    Please enable discovery of your device
    Keyboard found
    HID device found
    Now just create the instance like so:
    BTHID bthid(&Btd);
    And then press any button on the device
    Connecting to HID device
    Connected to HID device
    Received Key Request
    Bluetooth pin is set too: 1234
    Pairing successful with HID device
    Send HID Control Connection Request

    • and this is with my Mouse terminal perfect output

      HID Bluetooth Library Started
      Bluetooth Dongle Initialized
      HCI Reset complete
      Write class of device
      Local Bluetooth Address: 00:15:83:0C:BF:EB
      Please enable discovery of your device
      Mouse found
      HID device found
      Now just create the instance like so:
      BTHID bthid(&Btd);
      And then press any button on the device
      Connecting to HID device
      Connected to HID device
      Received Key Request
      Bluetooth pin is set too: 0000
      Pairing successful with HID device
      Send HID Control Connection Request
      Send HID Control Config Request
      Set protocol mode: 00
      Send HID Interrupt Connection Request
      L2CAP Control: 00
      Send HID Interrupt Config Request
      HID Channels Established
      Wait For Incoming Connection Request
      L2CAP Interrupt: A1 03 85 DC 2C 26 00 11 79
      L2CAP Interrupt: A1 02 07 03 04 00 L Butt Dn
      R Butt Dn
      M Butt Dn
      dx=3 dy=4

      L2CAP Interrupt: A1 02 07 06 0A 00 dx=6 dy=10

      L2CAP Interrupt: A1 02 03 00 00 00 M Butt Up

      L2CAP Interrupt: A1 02 03 0C 14 00 dx=12 dy=20

      L2CAP Interrupt: A1 02 02 00 00 00 L Butt Up

      L2CAP Interrupt: A1 02 00 03 05 00 R Butt Up