Digital Graffiti. For the Pi-casso in us all!

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!

image1

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

Followed by:

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:

hcitool scan

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!

wii_bar

(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.

92727BA6-AFD4-45DC-B473-AE2B4001916E

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!)

wii_mirror

The completed attachment.

And in place….

wii_mirror2

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:

idle

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.

digital_graffiti_keys

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…

sam_graffiti

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…

 

 

2 thoughts on “Digital Graffiti. For the Pi-casso in us all!

  1. Why does this project use a Bluetooth dongle? The Pi 3 and 3B+ both have onboard BT, I believe. Is it somehow incompatible with the libraries used here?

    1. This is a really good question :) I’d had issues using onboard the bluetooth with earlier versions of Raspbian and the Cwiid library so had been using a dongle as a standard fallback method ever since. I’ve actually just tried it without the dongle for the first time and it works perfectly with onboard BT! Have updated instructions to reflect this. Thanks for feedback.

Leave a Reply

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