Wii Remote has to expand, using a proprietary port, with an accessory: the most famous and used is Controller Nunchuck. It's an another free hand controller that allows to have a directional analogic joystick controller plus two buttons (Z and C) and an accelerometer. Ours goal is to use Nunchuck as PC device, so get state information on Nunchuck Controller, i.e.:
In particular we can get the sigle component on each axis.
- If Z or C button is pressed
- The position of analogic in therm of carthesian coordinates
- The values of accelerometer
In particular we can get the sigle component on each axis.
Unexpectedly the cost of nunchuck is lower than of the only accelerometer. If you already have a Wii can use the Nunchuck you have; otherwise you can buy it at very cheap price. In fact if you want learn to use a acceleretion sensor you can start with that.
Please note: the LIS3L02AL is a MEMS accelerometer; in this type of accelerometer is possible to approximate the movement made with the acceleration measured.So before continue be sure to have:
- Arduino 2009 or Uno board
- Some wires (minimum 4)
- Isolator adhesive tape (or common liquid glue)
- The Nintendo Nunchuck
The homemade connectors: so you cannot cut the port of Nunchuck to reach wires directly |
Put 2 wires upon with 4~4,5 mm between and others 2 in back in same way. We need only 4 wires because 2 of 6 connectors of Nunchuck port are connected:
The standard of communication used by periferical device of Wii Remote is TWI bus, that is the same of I²C, and we are very happy! In fact this standard is supported by a lot of software libraries. On our Arduino Board we can use the library Wire.h, programmated to work on Analog 5 and 6 pins to communicate with a TWI bus device.
So if you want to get more information see the link above. You just know that Vdd of TWI devices is 3,3V or 5V (in our case Nunchuck required 3,3V) and each device has a ID to be addressable. Thus as you can see in pictures SCL (Serial Clock Line) and SDA (Serial DAta) must to be connected respectively with A5 and A4 pins of Arduino Board and are the only two wire (except for the power supply) required from standard (In fact, the acronym is Two Wire Interface).We have to connect (finally!) Nunchuck to Arduino using the connector you have made.
Please note: in the pictures that you're seeing I'm using a breadboard; it's not required, but I doing only for a comfort.
Nunchuck connected properly to Arduino Uno |
#define KEY 0x17
#define DEVICE 0x52
#define INIT 0x40
#define ACK_PACKET 0
The first value, named Key, is necessary to uncrypt the bits that we received from Nunchuck; I honestly tell you that there is a way to receive unencrypted data directly, but my implementation doesn't use this new way. You can try implement by yourself.
The second is the ID of Nunchuck device on TWI bus; the third rappresent the value of communication startup and last the acknowledgment packet that we have to send to Nunchuck after reading of bytes stream.
Now we have to define some functions that we'll using in our code:
startup(){
Wire.begin();
Wire.beginTransmission(DEVICE);
Wire.send(INIT);
Wire.send(ACK_PACKET);
Wire.endTransmission();
}
sendAcknoledge(){
Wire.beginTransmission(DEVICE); // send a zero to device 0x52
Wire.send(ACK_PACKET);
Wire.endTransmission();
}
decode(uint8_t x){
return (x^KEY)+KEY;
}
On read line of TWI interface we have to read 6 byte once a time; to comprehend the motivation we can discover what's the data structure:
byte[] reading <-- read();
reading[0] contains analog X value
reading[1] contains analog Y value
reading[2] contains the first 8 bits of accelerometer X axis value
reading[3] contains the first 8 bits of accelerometer Y axis value
reading[4] contains the first 8 bits of accelerometer Z axis value
reading[5] contains 5 fields: the bit in first position indicates if the Z button is pressed; the bit in second position indicates if the C button is pressed; third and fourth contains the LSBs of accelerometer X axis value; fiveth and sixth contains the LSBs of accelerometer Y axis value; seventh and eighth contains the LSBs of accelerometer Z axis value;
So we are ready to write a properly function to decode the byte stream:
read(){
uint8_t buf[6];
int i=0;
Wire.requestFrom(DEVICE, 6);
while(Wire.available()){
buf[i++] = decode(Wire.receive());
}
if(i>=6){ //check if the whole record is been received
decode_packet(buf);
sendAcknoledge();
}
}
decode_packet(uint8_t* packet){
analog_x = (int)packet[0];//-123;
analog_y = (int)packet[1];//-123;
axis_x = (int)(packet[2]<<2)+((packet[5]>>2)&1); //Axis X from accelerometer
axis_y = (int)(packet[3]<<2)+((packet[5]>>4)&2); //Axis Y from accelerometer
axis_z = (int)(packet[4]<<2)+((packet[5]>>6)&3); //Axis Z from accelerometer
button_z = !(packet[5]&1);
button_c = !(packet[5]&2);
}
Now all we need is done and can start with acquisition on ours PC. In my opinion the best and simplest way to excange data between Arduino and PC is the sync communication; in this way you can request data when you want and software application are less critical on acquisition.
If we now try to use this raw data we realize that all is wrong! But don't be afraid: we just need to convert the values. Freely you can choose if do this on Arduino or on Software; I like the second choise. So we can see that the analogical joiystick value are rappresented by 8 bit, 0 to 255; when the joystick is on center the value of X and Y are 125 (in my case; maybe is different to you): if we subtract always this offset obtain correct signal! Similarly we can apply this concept to X, Y, Z axis of accelerometer; in fact this 3 values are rappresented by 10 bit for each, o to 1023: in this case we have to subtract 512.
To comprehend how the accelerometer is positioned you can test with these graphs all movements.
If we now try to use this raw data we realize that all is wrong! But don't be afraid: we just need to convert the values. Freely you can choose if do this on Arduino or on Software; I like the second choise. So we can see that the analogical joiystick value are rappresented by 8 bit, 0 to 255; when the joystick is on center the value of X and Y are 125 (in my case; maybe is different to you): if we subtract always this offset obtain correct signal! Similarly we can apply this concept to X, Y, Z axis of accelerometer; in fact this 3 values are rappresented by 10 bit for each, o to 1023: in this case we have to subtract 512.
Please note: the position of accelerometer in Nunchuck permit to read, when you hold the Nunchuck in a hand, the -Z moving it up and down, the Y when you move it farward and back, the X when you move it left or right. When you read Z remember that on this axis there is -g when the board inner Nunchuck is perpendicular respect gravityAlso if you want obtain a range of value [-2g, 2g] is sufficient divide normalized X, Y and Z with 256.
Plot of 1000 X, Y, Z axis values catched from Serial COM transmission; all the axis are plotted normalized to [-2g, 2g] |
Nessun commento:
Posta un commento