domingo, 5 de dezembro de 2010

Using a WiiMote with Processing


The wiimote is a really cool controller to use with your robots. It has many buttons, accelerometers and even a camera which tells the coordinates of the four principal IR emitters that it sees.
There are many examples of applications using it, some of the most populars are from Johnny Chung Lee. But there are much more, just search for "wiimote" or "wiimote robot" on youtube or google. On LMR there are some examples too:
And others with just its camera:

But I wanted to use it, without having to hack it, to communicate with processing and control my robot TheBox.
On my computer I have installed WIDCOMM bluetooth software which I found here.

To install the processing libraries I followed this tutorial.
I had some problems placing the folders so here is a simple scheme:
+ Prossessing
    + libraries
        + Loc
            + library
                - Loc.jar
            + lll
                + Loc
                     - ...
        + wrj4P5
            + library
                - bluecove-2.1.0.jar
                - bluecove-gpl-2.1.0.jar
                - WiiRemoteJ.jar
                - wrj4P5.jar
                - Loc.jar (optional)
            + lll
                + wrj4P5     
                    - ...

To test if it is all working you can try these examples found here:
If they work, you can pass to the next step, the serial communication with your robot.

The application MyFirstWii is really easy to adapt. 
All you have to do is to import the serial library, create a serial object, define the COM port & the baud rate and add the serial communication where the data about the buttons is analyzed. Here is an example:
import processing.serial.*;
import lll.wrj4P5.*;
Wrj4P5 wii;
Serial TheBox;
void setup() {
  size(300,300,P3D);
  wii=new Wrj4P5(this);
  wii.connect();
  TheBox = new Serial(this, "COM5", 4800);
void draw() {
  background(0);
  stroke(255);
  translate(300/2,300/2,0);
  lights();
  rotateX((int) (wii.rimokon.senced.x*30+300));
  rotateY((int) (wii.rimokon.senced.y*30+300));
  rotateZ((int) (wii.rimokon.senced.z*30+300));
  box(100,100,100);
}
void buttonPressed(RimokonEvent evt, int rid) {
   if (evt.wasPressed(RimokonEvent.TWO)) println("2");
   if (evt.wasPressed(RimokonEvent.ONE)) println("1");
   if (evt.wasPressed(RimokonEvent.B)) {
     println("B");
     TheBox.write('g'); 
    }
   if (evt.wasPressed(RimokonEvent.A)) println("A");
   if (evt.wasPressed(RimokonEvent.MINUS)) println("Minus");
   if (evt.wasPressed(RimokonEvent.HOME)) println("Home");
   if (evt.wasPressed(RimokonEvent.LEFT)){
     println("Left");
     TheBox.write('a'); 
    }
   if (evt.wasPressed(RimokonEvent.RIGHT)){
     println("Right");
     TheBox.write('d');      
    }
   if (evt.wasPressed(RimokonEvent.DOWN)){
     println("Down");
     TheBox.write('s'); 
    }
   if (evt.wasPressed(RimokonEvent.UP)){
     println("Up");
     TheBox.write('w'); 
    }
   if (evt.wasPressed(RimokonEvent.PLUS)) println("Plus");
}