Advertisement

Using a Wii Nunchuck to Control Python Turtle

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

In this tutorial I’ll show you how to connect a Wii nunchuck adaptor to a Raspberry Pi and use Python to control the turtle module.

This tutorial works with both official Nintendo or 3rd party nunchucks. The nunchuck is a good multi-use input for a Raspberry Pi as they can be picked up cheaply and contain a joystick, a three-axis accelerometer and two buttons in a nice ergonomically friendly controller.

Requirements

To get the nunchuck running with the Pi, you will need:

  • A Raspberry Pi with SD card preinstalled with Raspbian (refer to the tutorial How to Flash an SD Card for Raspberry Pi if you need to)
  • A Nintendo nunchuck
  • An adaptor such as MultiChuck
  • Or female jumper wires, soldering iron, solder and electrical tape to cover the joint

Hooking up your Nunchuck

If you are feeling brave, enjoy cutting the connectors off and have spare controllers you can hook the wires directly up to the Raspberry Pi GPIO pins. As each connector may use different coloured wires, it is best to open the controller to work out the wiring colours.


Wiring the 

In my controller I have the following wires, as this is a third-party controller, take note of the colours and the pins to which they connect, as the chances are they could be very different to the connector in my example.

  • Ground–Brown
  • Serial Data–Pink
  • Serial Clock–Yellow
  • Power (VDD)–White
  • Addon Detect–Blue–Not used
An example of the wiring pinout

Cut off the end connector that you plug into the Wiimote, strip back the plastic coating to expose the bare wires. Solder each wire to a female jumper wire, then use electrical tape to protect the soldered joints from touching each other. Once you are sure each colour matches its respective wire, plug them straight on to the i2c and power pins on the Pi.

If you aren't feeling that brave, or you don't have a controller to spare, you can always use an adaptor such as the MultiChuck Adaptor to connect your controller to your Pi without sacrificing the connector.

Using a MultiChuck adapter

Setting Up the Raspberry Pi

i2c isn't enabled by default, this requires the editing of two files. The first file will enable the serial protocol and the second will start the serial driver when the Raspberry Pi boots up.

To edit the first file, type this in to the LXTerminal window or PuTTY if you are connecting remotely: sudo nano /etc/modules

Add i2c-dev and i2c-bcm2708 to the end of the file so it looks like this:

Editing files on the Raspberry Pi

Control-X to save the changes, Y to confirm and Enter to save to the file.

Next, to enable the driver on start up, type:

sudo nano /etc/modprobe.d/raspi-blacklist.conf

then add a # to the beginning of each line so it looks like this:


Editing files on the Raspberry Pi

Again Control-X to save the changes, Y to confirm and Enter to save to the file. Those are the changes needed to for the Raspberry Pi to talk over the i2c protocol. Next type:

sudo reboot restart

to allow the changes to take effect.

Installing the Required Libraries

Once the Raspberry Pi has restarted, open LXTerminal again. The last thing to do now is to install the Python modules to handle the communication between Python and i2c:

sudo apt-get update
sudo apt-get install python-smbus -y

To make handling the nunchuck data easier, I have created a module that can be imported in to your script. Open LXTerminal and type the following command to download it.

wget https://raw.githubusercontent.com/Boeeerb/Nunchuck/master/Raspberry%20Pi/nunchuck.py

Reading Nunchuck Data

Now you have all the libraries and modules required, test that it works. Whilst still in LXTerminal, type in

sudo python

to start the interactive Python console, using this we can write a quick test with Python. 

from nunchuck import nunchuck
wii = nunchuck()
wii.raw()

If everything works as it should, you should expect to see a set of numbers like this:

Testing

The numbers correspond to the outputs of the joystick, accelerometer and states of the buttons. 

Wii.raw() will give you a printout of each–starting at the left you have:
[ Joystick X, Joystick Y, Accelerometer X, Accelerometer X, Accelerometer X, Mixed Data containing Buttons Z and C ]

I have also added individual functions for each of these to make writing your own scripts much easier.

wii.raw()                       # Returns all the data in raw
wii.joystick()                  # Returns just the X and Y positions of the joystick
wii.accelerometer()             # Returns X, Y and Z positions of the accelerometer
wii.button_c()                  # Returns True if C button is pressed, False if not
wii.button_z()                  # Returns True if Z button is pressed, False if not

wii.joystick_x()                # Returns just the X position of the joystick
wii.joystick_y()                # Returns just the Y position of the joystick
wii.accelerometer_x()           # Returns just the X position of the accelerometer
wii.accelerometer_y()           # Returns just the Y position of the accelerometer
wii.accelerometer_z()           # Returns just the Z position of the accelerometer

wii.scale(value,min,max,out_min,out_max) # Works the same as Arduino Map, perfect for changing values returned to a different scale, ie -100 - +100

You can try one out with a loop by typing the following in to a sudo python console. This will output the current position of the joystick, so type it in and move the the joystick around to see the numbers change.

from nunchuck import nunchuck
from time import sleep

wii = nunchuck()

while True:
  wii.joystick()
  sleep(0.2)

Using Turtle

Now you have got your Nunchuck connected to the Raspberry Pi, installed the libraries and modules and tested it works, I’ll show you how to do something fun with it. 

Python, on the Raspberry Pi, comes installed with the Turtle module to allow anyone to create patterns quickly and easily by adding a few lines of code. So as it is really easy to get going, I’ll show you how to use the nunchuck to control a turtle.

For the next section I’ll be using Idle in which to write the Python code, but as the serial protocol requires administrator rights, you’ll need to go back to LXTerminal again and type:

sudo idle

Click File then New Window. The new window is where the Python code will go. Pressing F5 will run the code. Add the code from before to import sleep and nunchuck modules, along with turtle.

from nunchuck import nunchuck
from time import sleep
import turtle

wii = nunchuck()

turtle.setheading(90)
while True:
    if wii.joystick_y() < 100:
        turtle.backward(10)
    if wii.joystick_y() > 160:
        turtle.forward(10)

    if wii.joystick_x() < 100:
        turtle.left(10)
    if wii.joystick_x() > 160:
        turtle.right(10)
nunchuckturtle.py script

After typing in the code, press F5 to run it. You’ll then be asked to save the file, so give it an appropriate name. A window will now pop up with a small black triangle, you are now ready to try it out so give the joystick a test.


In the code you have used, the first four lines import the modules needed and initiate the nunchuck ready to be used. turtle.setheading(90) will point the arrow upwards, as 0 points to the right. The next block starts a forever loop–while True:. Python checks if the joystick position is above or below a certain number and moves the turtle cursor respectively.

Adding Buttons

Now you have movement, I’ill show you how to add some extra interactivity by using the C and Z buttons. Some functions that will handy to have will be to clear the screen, and also to lift the pen up so you can move around without drawing a line.

from nunchuck import nunchuck
from time import sleep
import turtle

wii = nunchuck()
penstate = 0

turtle.setheading(90)
while True:
    if wii.joystick_y() < 100:
        turtle.backward(10)
    if wii.joystick_y() > 160:
        turtle.forward(10)

    if wii.joystick_x() < 100:
        turtle.left(10)
    if wii.joystick_x() > 160:
        turtle.right(10)

    if wii.button_c() == True:
        turtle.setposition(0,0)
        turtle.setheading(90)
        turtle.clear()
    if wii.button_z() == True:
        if penstate == 0:
            turtle.up()
            penstate = 1
        else:
            turtle.down()
            penstate = 0
        sleep(0.2)


Press F5 to save and start the new script, and test the buttons. Button C will clear the screen and reset the position of the cursor, whilst Z will lift up and set down the pen so you can start and stop drawing a line.

Using the nunchuck to draw

I’ll breakdown the button code so you understand what is happening when you press the button. 

When you press the C button, that comes back as True and will turn the turtle back so it is pointing upwards, then move the turtle back to the centre of the screen and finally clear the screen. 

When you press the Z button, a variable is stored to remember the state of the pen, and either lift up the pen to stop drawing, or place the pen back down to continue drawing.

Conclusion

I hope in this tutorial you have gained the knowledge to start applying what you have learnt to expand what that can be done with the nunchuck. 

Some things that can be done such as control robots, create games such as snake or even turn LEDs on and off that are connected to the GPIO pins of a Raspberry Pi.



Advertisement