I’ve been playing around with Nintendo WiiMote controllers and the Raspberry Pi for a couple of years, there’s a well used Python library called cwiid (which, after much discussion, we finally realised it’s pronounced ‘seaweed’). Mark C. from Cotswold Jam has built at least a dozen remote controlled bots that use a this set up and we’ve taken the balloon popping spectacular that is ‘Micro Pi-noon’ which uses these bots to many events in the last twelve months.
The WiiMote itself is basically a very nice package of buttons and sensors and the Python library means, with the onboard bluetooth dongle on the Raspberry Pi 3, you can get your hands on all that lovely data in real time.
All of the demos and examples I’ve seen use the WiiMote to control something, usually a small bot using the buttons as controls. But, it does have another trick up its sleeve. A quick glance at the end of the WiiMote reveals a standard looking IR controller type piece of dark plastic. Tucked away behind this however, is a full camera. The sensor bar that is supplied with the Wii contains two blocks of five IR LEDs and the camera is used to detect the position of, and distance between, these two blocks to calculate the controller’s position relative to the screen. This is what allows the controller to be used as a mouse pointer when set up with the Wii.
Sadly, the Cwiid library is no longer actively supported and I’d done a fair amount of searching and found nothing that had used the IR data from the WiiMote although I was fairly certain this data was being exposed via the Cwiid library. After a few trials and by dumping all the data from the WiiMote I found the IR data (wonderfully buried as a list of dictionaries!) and worked out how to extract it. This gives a fairly different x / y position value from a screen resolution x / y value so some conversion is required. Additionally, depending on the position of the controller, only one set of LEDs on the sensor bar may be visible so this must be accounted for too.
I then wrote an initial Pygame script to mimic a cursor using the WiiMote and from there it wasn’t a great leap of imagination to…
GIANT DIGITAL GRAFFITI!
This is my (frankly rather poor) first effort – but it still looks pretty damn cool when it’s 10 feet wide!
I was originally going to build a actual fake spray can but due to time constraints went for a far simpler option. As it transpires this actually makes it far easier for someone else to replicate.
Enough already – show me the goods!
So – to build your own Giant Digital Graffiti Wall you’ll need the following:
- Raspberry Pi 3B+ running latest version of Rasbian Stretch
- WiiMote controller
- Wii sensor bar
- Power supply
- DC/DC power converter
- Projector or large screen TV
- 30mm square mirror
- 3D Printed holder (link to stl file below) – or a lump of Blu-Tac works ok-ish!
The Wii sensor bar and controllers can be picked up really cheaply I’ve found, just shop around. Your local car boot sale is a great place to look! I’ve been paying around £3-5 for a controller and £5-10 for a sensor bar.
Set up the WiiMote controller and Cwiid
*Make sure your Pi is connected to the internet.*
Open a terminal and make sure you’re up to date by entering:
sudo apt-get update
sudo apt-get upgrade
Next, install the bluetooth library:
sudo apt-get install bluetooth
And the Python Cwiid library:
sudo apt-get install python-cwiid
Check the Bluetooth service is running:
sudo service bluetooth status
If everything is running as is should be you’ll get a message confirming this. If not, just reboot the Pi.
Next, grab your WiiMote, press buttons 1 and 2 together. Whilst the LEDs are flashing, type:
And hit enter, which will produce something like the following:
01:A2:33:D6:12:A3 Nintendo RVL-CNT-01
Make a note of the left portion which is the MAC address of your WiiMote, you’ll need to enter this in the Python code to pair the WiiMote to the Raspberry Pi.
That’s the WiiMote set up and ready!
Set up sensor bar
The Wii sensor bar runs at 7.8v – which is annoyingly non-standard so the easiest way to accomplish this is with a 12v DC power supply and a DC/DC converter. Just cut the Nintendo plug off the end and then wire up to the output of the DC/DC converter. The Nintendo wires are *thin* so I added a blob of hot glue over the terminals to ensure everything stayed in place. I’d also recommend boxing the whole board rather than leaving it on the carpet!
(Photo taken through front camera on my phone so you can see the LED array.)
Make a ‘Spray Can’
I wanted to make something that was easy to make but would use the feel of the WiiMote to replicate a spray can. Holding the controller vertically and using the trigger to ‘spray’ felt most natural so I used OpenScad to design a holder that simply slides over the end of the WiiMote.
And then by attaching a 30mm square mirror to the holder, the controller can then be held vertically and the camera still detects the full LED array very well. This does of course invert the x coordinates, which took some head scratching to figure out in the code. I ordered a bunch of these little mirrors from eBay for about 50p each. (Note to self – check quantities contained in each packet before ordering five packets!)
The completed attachment.
And in place….
You can download the stl file to print the holder from my Thingiverse account HERE
Download the Digital Graffiti Python code and graphics
The Python code, the two images used and full instructions on how to use the program are available on my GitHub repo. Download the code with the following command in the terminal:
git clone https://github.com/davejavu1969/digital_graffiti.git
Running the program
The code needs to run in Python 2.7 as cwiid is not supported in Python 3.
In the terminal type:
When Python opens, navigate to the newly created digital_graffiti folder and open digital_graffiti_1080p.py
Before you run the program for the first time, you will need to edit the code at line 51 to enter the MAC address for your WiiMote controller. Once you’ve done this and the sensor bar is positioned centrally in front of your screen, you should be all set up and ready to draw! Full instructions are provided in the digital_graffiti folder. Open the digital_graffiti_keys.png image to see all the controls used.
When you run the program, ‘Connecting to can’ will be displayed on the screen. Press buttons 1 and 2 on your WiiMote at the same time to connect to the Pi. The main drawing screen will then be displayed.
Some notes about usage.
The current ‘brush’ size, colour, and shape is displayed in the bottom left corner of the screen.
The sensor array is more accurate when the controller is pointing closer to the centre of the screen, the very far left and right edges of the screen can produce some anomalous results!
It works best if the controller is 6-15ft away from the sensor bar. Closer than this and accuracy will drop.
We used this set up at a recent Knowledge Makers event at the Open University. We used a projector and had really successful results – and the screen image was about 10ft wide!
Here’s us testing it out before the main event – it all got a bit Jackson Pollack…
The code is ‘hard-coded’ to a screen resolution of 1920 x 1080 at the moment due to how we were using it. I originally ran this on a Pi 3 and it got pretty toasty after 20 minutes usage! It is highly recommended therefore to run this on a 3B+
There’s loads more room for improvements; extra brushes / effects, fill / bucket, select etc etc….
I’ll leave that up to you.
Until next time…