Nintendo Wii Remote, Python and The Raspberry Pi

Nintendo Wii RemoteI was looking for a way to send data to my Raspberry Pi via Bluetooth. Ideally I wanted to do this via an Android tablet and a custom app but I couldn’t get the app to connect.

During a large amount of Google searching I came across a Python library called “CWiid”. It allows you to read data from a Nintendo Wii Controller via Bluetooth and use this within your own Python script.

So I decided to give it a go and see how easy it was. As it turned out it is not difficult at all once you know the steps to take. I used the latest Raspbian image and an “Origo” USB Bluetooth dongle.

Button Mapping

Nintendo Wii Button Mapping

Nintendo Wii Remote Button Mapping

Before starting with the practical stuff we need to look at the button mapping of the Wii remote. When you press a button on the Wii Remote it sends some data via the Bluetooth connection.

The data sent is a number that is the sum of the unique codes associated with each button.

The codes are shown in the diagram to the right and the table below in both decimal and binary notations. You will notice that each button sets a bit to “1″ in the binary number.

Decimal
 Number       Binary       Button
=================================
     1    00000000000001   2
     2    00000000000010   1
     4    00000000000100   B
     8    00000000001000   A
    16    00000000010000   MINUS
   128    00000010000000   HOME
   256    00000100000000   DOWN
   512    00001000000000   UP
  1024    00010000000000   RIGHT
  2048    00100000000000   LEFT
  4096    01000000000000   PLUS
=================================

So pressing A will send 8. Pressing LEFT will send 2048. Pressing MINUS and A at the same time will send 8 + 16 which is 24. The example script you will see further down this page receives this number and works out what buttons are being pressed.

Step 1 – Update Raspbian

I downloaded the latest Raspbian image for my testing and created a fresh SD card. To ensure I had the latest updates I ran the following two commands first :

sudo apt-get update

and

sudo apt-get upgrade

These steps may take a while to complete so go and make a cup of tea while you wait.

Step 2 – Install Bluetooth Drivers

In order to communicate with Bluetooth devices (such as the Wii remote) you need to install the drivers. So start off by typing the following command :

sudo apt-get install --no-install-recommends bluetooth

The “–no-install-recommends” ensures we just install the bits we need for basic Bluetooth communication and not a load of other stuff such as printer drivers.

Step 3 – Install the CWiid Module

Next we need the CWiid Python library so type this :

sudo apt-get install python-cwiid

Step 4 – Test the Connection

Plug in your Bluetooth dongle. For devices that should work with the Pi see the hardware list on the eLinux Pi Wiki. Give it 10 seconds to power-up.

At this point it is a good idea to test that the Pi can see the Nintendo Wii remote. Type the following command :

sudo service bluetooth status

and you should get a response saying :

[ ok ] bluetooth is running.

If you don’t see this message you should reboot your Pi and try it again.

Press the 1 and 2 buttons on your Wii controller at the same time. The blue LEDs should flash. Now type :

hcitool scan

If things are going well you should see a response that shows your Pi can see your remote :

Scanning ...
         00:19:1C:B6:BB:41       Nintendo RVL-CNT-01

Step 5 – Example Python Script

Here is a my example script. It is fairly basic but shows how you can connect to the remote and read the 11 button states.

#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# wii_remote_1.py
# Connect a Nintendo Wii Remote via Bluetooth
# and  read the button states in Python.
#
# Project URL :
# http://www.raspberrypi-spy.co.uk/?p=1101
#
# Author : Matt Hawkins
# Date   : 30/01/2013

# -----------------------
# Import required Python libraries
# -----------------------
import cwiid
import time

button_delay = 0.1

print 'Press 1 + 2 on your Wii Remote now ...'
time.sleep(1)

# Connect to the Wii Remote. If it times out
# then quit.
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print "Error opening wiimote connection"
  quit()

print 'Wii Remote connected...\n'
print 'Press some buttons!\n'
print 'Press PLUS and MINUS together to disconnect and quit.\n'

wii.rpt_mode = cwiid.RPT_BTN

while True:

  buttons = wii.state['buttons']

  # If Plus and Minus buttons pressed
  # together then rumble and quit.
  if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
    print '\nClosing connection ...'
    wii.rumble = 1
    time.sleep(1)
    wii.rumble = 0
    exit(wii)

  # Check if other buttons are pressed by
  # doing a bitwise AND of the buttons number
  # and the predefined constant for that button.
  if (buttons & cwiid.BTN_LEFT):
    print 'Left pressed'
    time.sleep(button_delay)

  if(buttons & cwiid.BTN_RIGHT):
    print 'Right pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_UP):
    print 'Up pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_DOWN):
    print 'Down pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_1):
    print 'Button 1 pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_2):
    print 'Button 2 pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_A):
    print 'Button A pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_B):
    print 'Button B pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_HOME):
    print 'Home Button pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_MINUS):
    print 'Minus Button pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_PLUS):
    print 'Plus Button pressed'
    time.sleep(button_delay)

To download this script directly to your Pi you can type :

wget http://www.raspberrypi-spy.co.uk/archive/python/wii_remote_1.py

You can then run the script using :

python wii_remote_1.py

Pressing the buttons on the Wii controller should result in text being printed to the screen. That text should tell you which button was pressed. Pressing Plus and Minus together will quit the script.

What you do with your new Wii Remote powers is up to your imagination. For me I am going to use it to control a cheap radio controlled car.

This entry was posted in Hardware, Python, Tutorials & Help and tagged , , , , , . Bookmark the permalink.


19 Responses to Nintendo Wii Remote, Python and The Raspberry Pi

  1. Matt this looks like an irresistable opportunity to try out the Technika bluetooth dongles I bought from Tesco. I’m going to give this a go today. Excellent work. Thanks for all you do with the Pi. You’ve helped a lot of people. :)

    • Matt says:

      Are you a mind reader? I went to Tesco yesterday to look for one of those and they didn’t have any! I want one for my RC car project.

  2. It worked first time. Excellent. :)

  3. Dave says:

    Thanks Matt, this has been on my list of things to do since I bought my Pi at Christmas so I thought I’d give it a go when your post popped up yesterday and it worked no problems. I’ve even edited the code now to turn some LED’s on and off as next step to driving some motors (I’m completely new to coding so I was quite impressed with myself!)

    Do you know if there is any way of passing the Wiimote MAC address to CWiid so that the Wiimote will connect automatically without having to put it in discoverable mode?

  4. Thanks, Matt. First class tutorial :-) Works perfectly.

  5. John Crow says:

    The Bluetooth Dongle looks almost identical to the ones in poundworld.
    Ive got a couple of them, 1 in the laptop and a 2nd waiting for somthing like this on the Rpi.
    Will see if I can locate a BT handset and have a play with this.
    Thanks for posting

  6. TeaAddict says:

    Hi, when I press 1 and2 on the wii remote, then run hcitool scan, I get “Device is not available: No such device”. I tried sudo hcitool scan, same result. I tried pressing “sync” on the remote, but still nothing. How do I fix this?

  7. Connor says:

    Can you do this with a Xbox remote as well?

  8. Daan says:

    How can I use the Power button on the Wii Remote?

    Thx

  9. Vee-eight says:

    Just bought a pi and discovered this little gem of an application. For information, I recently bought a bluetooth dongle at Poundland (yes £1 each). Worked first time !!
    Off tomorrow to grab a couple more. Thanks for your efforts.

  10. Excellent stuff – managed to get a £1.99 adapter from Ebay (tesco online had sold out). It works a treat!

  11. Mark Routledge says:

    Anyone who ends up with ‘DEVICE’ with nothing listed when trying ‘hcitool dev’ should try running the bluetooth from the PI (not hub), also try unplugging it and plugging it back in, a reboot also seemed to work for me!

    I’m using a poundland USB Bluetooth dongle (bought 5 last time!), works a treat. I’d recommend if you’re looking at using wii-motes for other projects that you go for a trawl to /etc/cwiid/wminput/, then use Nano or similar (don’t forget the sudo if you’re not ROOT!) to view any of the files here, the ‘fps_config’ is a great one to start with, then just save it as something else. To run this setup just call wminput -c , or silently run it as a daemon.

    I’m just writing one to work with minecraft! so wminput -d -c /etc/cwiid/wminput/mcpi_config

    Hope that helps someone!

  12. Will Caine says:

    Definitely going to try and partner this with xbmc! Really hope I can get it working.

  13. O C says:

    Thanks, this is really useful!! – one thing though; if you’re using these functions in your own program out of IDLE, in geany or equivilant, you MUST include the time.sleep(1) before the while loop as it doesn’t work without. It took me 1 month of confused expressions to work it out :/

  14. Sir,
    hcitool scan gives the mac adress and Nintendo RVL-CNT-01-TR
    python wii_remote_1.py gives txt Press 1 + 2 on your Wii Remote now …
    message on screen after a few sec.
    No wiinotes found
    Is there a solution for it ?
    Greetings and thanks for your efforts.
    Martin

    • Problem solution.
      Have a Wii U remote, it don’t work. Found no error’s in program.
      scan Wii U remote gives Nintendo RVL-CNT-01-TR.
      scan Wii remote gives Nintendo RVL-CNT-01.
      All buttons works fine now.
      Greeting

  15. Rob Jeffrey says:

    What sort of range can you expect with this set-up. I’ve seen people using wiimotes with a wii at huge distances but will the pi work that well? I need mine to have at least 20 metres.

  16. Pingback: Wii リモコン から Rapiro を動かす | アンドロイドな日々

  17. Tony Savage says:

    I’m a complete novice to the Raspberry Pi, Python and Linux (only had my Pi for 4 weeks). But this worked perfectly first time. Thanks, Matt. I’m going to use this for my (semi) autonomous car I’m currently building.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>