Arduino & cheap ebay wii nunchuck

γνωρίζεται κάτι που δεν περιγράφεται πουθενά ? ή βρήκατε κάτι έξυπνο στο δίκτυο ? εδώ είναι ο χώρος για να το μοιραστείτε.

Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό ntgr την 31 Ιαν 2010 08:38

Απο καιρο δοκιμασα να χρησιμοποιησω ενα φτηνο wii nunxhuck αγορασμενο απο το ebay για 5$ με τα ταχυδρομικα και να το συνδεσω στον arduino μου.
Το πρωτο που παρηγγειλα , επειδη νομισα οτι το εκαψα , το εκανα accelerometer.
Στο δευτερο ομως καταλαβα οτι δεν ηταν καμμενο αλλα αλλου ηταν το προβλημα μιας και τα προγραμματα που εβρισκα στο internet δεν δουλευαν με το φτηνο nunchuck που ειχα στα χερια μου παροτι μολις το συνεδεα με την παιχνιδομηχανη δουλευε κανονικα.
Τεσπα για να μην σας ζαλιζω .... οριστε ο κωδικας που κανει το φτηνο μου nunchuck να δουλευει.

Κώδικας: Επιλογή όλων
/*
* Cheap ebay wii NunchuckPrint
*
* 2007 Tod E. Kurt, http://todbot.com/blog/
*
* The Wii Nunchuck reading code is taken from Windmeadow Labs
*   http://www.windmeadow.com/node/42
*/ modified by crimony in http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264805255/0#5

#include <Wire.h>
uint8_t ctrlr_type[6];

void setup()
{
  Serial.begin(19200);
  nunchuck_setpowerpins(); // use analog pins 2&3 as fake gnd & pwr
  nunchuck_init(); // send the initilization handshake
  Serial.print ("Finished setup\n");
}

void loop()
{
  nunchuck_get_data();
  nunchuck_print_data();
  delay(100);
}


//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6];   // array to store nunchuck data,

// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
    DDRC |= _BV(pwrpin) | _BV(gndpin);
    PORTC &=~ _BV(gndpin);
    PORTC |=  _BV(pwrpin);
    delay(100);  // wait for things to stabilize       
}

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
  byte cnt;

Wire.begin();
           
// init controller
delay(1);
Wire.beginTransmission(0x52);   // device address
Wire.send(0xF0);              // 1st initialisation register
Wire.send(0x55);              // 1st initialisation value
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0xFB);              // 2nd initialisation register
Wire.send(0x00);              // 2nd initialisation value
Wire.endTransmission();
delay(1);
           
// read the extension type from the register block       
Wire.beginTransmission(0x52);
Wire.send(0xFA);              // extension type register
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.requestFrom(0x52, 6);            // request data from controller
for (cnt = 0; cnt < 6; cnt++) {
    if (Wire.available()) {
        ctrlr_type[cnt] = Wire.receive(); // Should be 0x0000 A420 0101 for Classic Controller, 0x0000 A420 0000 for nunchuck
    }
}
Wire.endTransmission();
delay(1);
           
// send the crypto key (zeros), in 3 blocks of 6, 6 & 4.
Wire.beginTransmission(0x52);
Wire.send(0xF0);              // crypto key command register
Wire.send(0xAA);              // sends crypto enable notice
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0x40);              // crypto key data address
for (cnt = 0; cnt < 6; cnt++) {
    Wire.send(0x00);              // sends 1st key block (zeros)
}
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.send(0x40);              // sends memory address
for (cnt = 6; cnt < 12; cnt++) {
    Wire.send(0x00);              // sends 2nd key block (zeros)
}
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.send(0x40);              // sends memory address
for (cnt = 12; cnt < 16; cnt++) {
    Wire.send(0x00);              // sends 3rd key block (zeros)
}
Wire.endTransmission();
delay(1);
// end device init

}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
  Wire.beginTransmission(0x52);   // transmit to device 0x52
  Wire.send(0x00);      // sends one byte
  Wire.endTransmission();   // stop transmitting
}

// Receive data back from the nunchuck,
int nunchuck_get_data()
{
    int cnt=0;
    Wire.requestFrom (0x52, 6);   // request data from nunchuck
    while (Wire.available ()) {
      // receive byte as an integer
      nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
      cnt++;
    }
    nunchuck_send_request();  // send request for next data payload
    // If we recieved the 6 bytes, then go print them
    if (cnt >= 5) {
     return 1;   // success
    }
    return 0; //failure
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits.  That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
  static int i=0;
  int joy_x_axis = nunchuck_buf[0];
  int joy_y_axis = nunchuck_buf[1];
  int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
  int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
  int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

  int z_button = 0;
  int c_button = 0;

  // byte nunchuck_buf[5] contains bits for z and c buttons
  // it also contains the least significant bits for the accelerometer data
  // so we have to check each bit of byte outbuf[5]
  if ((nunchuck_buf[5] >> 0) & 1)
    z_button = 1;
  if ((nunchuck_buf[5] >> 1) & 1)
    c_button = 1;

  if ((nunchuck_buf[5] >> 2) & 1)
    accel_x_axis += 2;
  if ((nunchuck_buf[5] >> 3) & 1)
    accel_x_axis += 1;

  if ((nunchuck_buf[5] >> 4) & 1)
    accel_y_axis += 2;
  if ((nunchuck_buf[5] >> 5) & 1)
    accel_y_axis += 1;

  if ((nunchuck_buf[5] >> 6) & 1)
    accel_z_axis += 2;
  if ((nunchuck_buf[5] >> 7) & 1)
    accel_z_axis += 1;

  Serial.print(i,DEC);
  Serial.print("\t");
 
  Serial.print("joy:");
  Serial.print(joy_x_axis,DEC);
  Serial.print(",");
  Serial.print(joy_y_axis, DEC);
  Serial.print("  \t");

  Serial.print("acc:");
  Serial.print(accel_x_axis, DEC);
  Serial.print(",");
  Serial.print(accel_y_axis, DEC);
  Serial.print(",");
  Serial.print(accel_z_axis, DEC);
  Serial.print("\t");

  Serial.print("but:");
  Serial.print(z_button, DEC);
  Serial.print(",");
  Serial.print(c_button, DEC);

  Serial.print("\r\n");  // newline
  i++;
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}


Φυσικα ο κωδικας ΔΕΝ ΕΙΝΑΙ ΔΙΚΟΣ ΜΟΥ αλλα με βοηθησε ο crimony στο http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264805255/0#5
Ελπιζω - πιστευω οτι θα σας φανει χρησιμο. ;)
Αριστοτέλης : Η ευχαρίστηση στην εργασία δίνει τελειότητα στο αποτέλεσμα..
Άβαταρ μέλους
ntgr
 
Δημοσ.: 301
Εγγραφη: 16 Οκτ 2009 11:33
Τοποθεσια: Τρικαλα

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό ntgr την 03 Φεβ 2010 20:19

Επιτελους τα καταφερα :!:
Ο παραπανω κωδικας τροποποιημενος για να "τυπωνει" τις ενδειξεις και σε μοιρες.
Ο υπολογισμος εγινε χρησιμοποιωντας και τους τρεις αξονες , που σημαινει αρκετα μεγαλη ακριβεια στις μετρησεις.(νομιζω :D )
Κώδικας: Επιλογή όλων
/*
* NunchuckPrint Values in DEGREEs
* 2007 Tod E. Kurt, http://todbot.com/blog/
* The Wii Nunchuck reading code is taken from Windmeadow Labs
* http://www.windmeadow.com/node/42
* modified by crimony in http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264805255/0#5 to read cheap ebay nunchucks
* Valuable infos from http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
* and http://rubenlaguna.com/wp/2008/11/03/arduino-tilt-sensor-using-mma7260q/
* Last modification by ntgr (03-2-2010)
*/

#include <Wire.h>
uint8_t ctrlr_type[6];

void setup()
{
  Serial.begin(19200);
  nunchuck_setpowerpins(); // use analog pins 2&3 as fake gnd & pwr
  nunchuck_init(); // send the initilization handshake
  Serial.print ("Finished setup\n");
}

void loop()
{
  nunchuck_get_data();
  nunchuck_print_data();
  delay(100);
}


//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6];   // array to store nunchuck data,

// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
    DDRC |= _BV(pwrpin) | _BV(gndpin);
    PORTC &=~ _BV(gndpin);
    PORTC |=  _BV(pwrpin);
    delay(100);  // wait for things to stabilize       
}

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
  byte cnt;

Wire.begin();
           
// init controller
delay(1);
Wire.beginTransmission(0x52);   // device address
Wire.send(0xF0);              // 1st initialisation register
Wire.send(0x55);              // 1st initialisation value
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0xFB);              // 2nd initialisation register
Wire.send(0x00);              // 2nd initialisation value
Wire.endTransmission();
delay(1);
           
// read the extension type from the register block       
Wire.beginTransmission(0x52);
Wire.send(0xFA);              // extension type register
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.requestFrom(0x52, 6);            // request data from controller
for (cnt = 0; cnt < 6; cnt++) {
    if (Wire.available()) {
        ctrlr_type[cnt] = Wire.receive(); // Should be 0x0000 A420 0101 for Classic Controller, 0x0000 A420 0000 for nunchuck
    }
}
Wire.endTransmission();
delay(1);
           
// send the crypto key (zeros), in 3 blocks of 6, 6 & 4.
Wire.beginTransmission(0x52);
Wire.send(0xF0);              // crypto key command register
Wire.send(0xAA);              // sends crypto enable notice
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0x40);              // crypto key data address
for (cnt = 0; cnt < 6; cnt++) {
    Wire.send(0x00);              // sends 1st key block (zeros)
}
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.send(0x40);              // sends memory address
for (cnt = 6; cnt < 12; cnt++) {
    Wire.send(0x00);              // sends 2nd key block (zeros)
}
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.send(0x40);              // sends memory address
for (cnt = 12; cnt < 16; cnt++) {
    Wire.send(0x00);              // sends 3rd key block (zeros)
}
Wire.endTransmission();
delay(1);
// end device init

}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
  Wire.beginTransmission(0x52);   // transmit to device 0x52
  Wire.send(0x00);      // sends one byte
  Wire.endTransmission();   // stop transmitting
}

// Receive data back from the nunchuck,
int nunchuck_get_data()
{
    int cnt=0;
    Wire.requestFrom (0x52, 6);   // request data from nunchuck
    while (Wire.available ()) {
      // receive byte as an integer
      nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
      cnt++;
    }
    nunchuck_send_request();  // send request for next data payload
    // If we recieved the 6 bytes, then go print them
    if (cnt >= 5) {
     return 1;   // success
    }
    return 0; //failure
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits.  That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
  static int i=0;
  int joy_x_axis = nunchuck_buf[0];
  int joy_y_axis = nunchuck_buf[1];
  int accel_x_axis = nunchuck_buf[2]; // Readings from My wii in X axis
  int accel_y_axis = nunchuck_buf[3]; // Readings from My wii in Y axis
  int accel_z_axis = nunchuck_buf[4]; // Readings from My wii in Z axis

  int z_button = 0;
  int c_button = 0;
 
  //*******************************************************************************************
 
  int minx = 78;       //Minimum Measured value in X axis as readed in my tests.
  int maxx = 182;      //Maximum Measured value in X axis
  int miny = 78;       //Minimum Measured value in Y axis
  int maxy = 182;      //Maximum Measured value in Y axis
  int minz = 78;       //Minimum Measured value in Z axis
  int maxz = 182;      //Maximum Measured value in Z axis
   
  int g0x;
  int g0y;
  int g0z;
  g0x = ((maxx - minx)/2)+minx;
  g0y = ((maxy - miny)/2)+miny;
  g0z = ((maxz - minz)/2)+minz;
 
  int fx = (accel_x_axis - g0x);
  int fy = (accel_y_axis - g0y);
  int fz = (accel_z_axis - g0z);
 
  float ax = fx*(3.3/(1024.0*((maxx-minx))/180));  //The 3.3V supply volt is divided by 1024 steps from the A/D converter. This value is divided by the sensitivity in X axis
  float ay = fy*(3.3/(1024.0*((maxy-miny))/180));  //The 3.3V supply volt is divided by 1024 steps from the A/D converter. This value is divided by the sensitivity in Y axis
  float az = fz*(3.3/(1024.0*((maxz-minz))/180));  //The 3.3V supply volt is divided by 1024 steps from the A/D converter. This value is divided by the sensitivity in Z axis
 
  float rho = 0;             //MyAngle in X Axis
  float phi = 0;             //MyAngle in Y Axis
  float theta = 0;           //MyAngle in Z Axis
  rho =   atan(ax/sqrt(pow(ay,2)+pow(az,2)))*(360/(2*3.1415));  //Calculate the X , Y ,Z angle.
  phi =   atan(ay/sqrt(pow(ax,2)+pow(az,2)))*(360/(2*3.1415));  // this used (360/(2*3.1415) to convert radians to degrees.
  theta = atan(sqrt(pow(ay,2)+pow(ax,2))/az)*(360/(2*3.1415));  //More in http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf (PAGE 4)
 
 
  //*******************************************************************************************

  // byte nunchuck_buf[5] contains bits for z and c buttons
  // it also contains the least significant bits for the accelerometer data
  // so we have to check each bit of byte outbuf[5]
  if ((nunchuck_buf[5] >> 0) & 1)
    z_button = 1;
  if ((nunchuck_buf[5] >> 1) & 1)
    c_button = 1;

  if ((nunchuck_buf[5] >> 2) & 1)
    accel_x_axis += 2;
  if ((nunchuck_buf[5] >> 3) & 1)
    accel_x_axis += 1;

  if ((nunchuck_buf[5] >> 4) & 1)
    accel_y_axis += 2;
  if ((nunchuck_buf[5] >> 5) & 1)
    accel_y_axis += 1;

  if ((nunchuck_buf[5] >> 6) & 1)
    accel_z_axis += 2;
  if ((nunchuck_buf[5] >> 7) & 1)
    accel_z_axis += 1;

  Serial.print(i,DEC);
  Serial.print("\t");
 
  Serial.print("joy:");
  Serial.print(joy_x_axis,DEC);
  Serial.print(",");
  Serial.print(joy_y_axis, DEC);
  Serial.print("  \t");

  Serial.print("acc:");
  Serial.print(accel_x_axis, DEC);
  Serial.print(",");
  Serial.print(accel_y_axis, DEC);
  Serial.print(",");
  Serial.print(accel_z_axis, DEC);
  Serial.print("\t");

  Serial.print("but:");
  Serial.print(z_button, DEC);
  Serial.print(",");
  Serial.print(c_button, DEC);
 
  Serial.print("  \t");
  Serial.print(" ANGLE X --> ");
  Serial.print(rho, DEC);
  Serial.print("  \t");
  Serial.print(" ANGLE Y --> ");
  Serial.print(phi, DEC);
  Serial.print("  \t");
  Serial.print(" ANGLE Z --> ");
  Serial.print(theta, DEC);

  Serial.print("\r\n");  // newline
  i++;
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}


Ενοειται οτι περιμενω τις παρατηρησεις σας αν δειτε κατι το οποιο δεν ειναι σωστο ;)
Αριστοτέλης : Η ευχαρίστηση στην εργασία δίνει τελειότητα στο αποτέλεσμα..
Άβαταρ μέλους
ntgr
 
Δημοσ.: 301
Εγγραφη: 16 Οκτ 2009 11:33
Τοποθεσια: Τρικαλα

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό nick-themachine την 03 Φεβ 2010 20:29

Μπράβο Νίκο!!!
Καλή συνέχεια στην προσπάθειά σου..!!! :D
Αι ιδέαι δεν αποθνήσκουν...
Άβαταρ μέλους
nick-themachine
 
Δημοσ.: 314
Εγγραφη: 01 Νοέμ 2008 18:51
Τοποθεσια: Αίγιο

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό dikos την 03 Φεβ 2010 20:43

Μπράβο και απο εμένα, πολύ χρήσιμο κάτι τέτοιο,θα ήθελα να το δώ και στην πράξη, ανεβασέ μας κανένα βιντεάκι όποτε μπορέσεις... :idea:
Άβαταρ μέλους
dikos
Site Admin
 
Δημοσ.: 529
Εγγραφη: 30 Οκτ 2008 11:13
Τοποθεσια: Πειραιάς

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό ntgr την 03 Φεβ 2010 21:46

Και το video http://www.youtube.com/watch?v=bnd8mhzqkyg
Δεν ειναι κατι special αλλα νομιζω οτι δινει μια εικονα. ;)
Αριστοτέλης : Η ευχαρίστηση στην εργασία δίνει τελειότητα στο αποτέλεσμα..
Άβαταρ μέλους
ntgr
 
Δημοσ.: 301
Εγγραφη: 16 Οκτ 2009 11:33
Τοποθεσια: Τρικαλα

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό -=karpa=- την 04 Φεβ 2010 15:53

λινκ για το ebay παιζει..? :roll:
Άβαταρ μέλους
-=karpa=-
 
Δημοσ.: 164
Εγγραφη: 01 Νοέμ 2008 18:26

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό ntgr την 04 Φεβ 2010 17:03

Εχω παραγγειλει απο 2 διαφορετικους στο ebay και ηταν ακριβως τα ιδια.
Δεν νομιζω να ειναι πολλλες εταιριες που κανουν αυτη την δουλεια.
Απλα ψαξε το πιο φτηνο.Απο 5 εως 6 $ μαζι με τα μεταφορικα. ;)
http://cgi.ebay.com/A41-Brand-New-Nintendo-Wii-Nunchuck-Controller-Remote_W0QQitemZ180455010903QQcmdZViewItemQQptZVideo_Games_Accessories?hash=item2a03f4f257
Ενας απο τους δυο που εχω αγορασει.
Απλα υπολογισε 10-15 μερες μεχρι να ερθει ;)
Αριστοτέλης : Η ευχαρίστηση στην εργασία δίνει τελειότητα στο αποτέλεσμα..
Άβαταρ μέλους
ntgr
 
Δημοσ.: 301
Εγγραφη: 16 Οκτ 2009 11:33
Τοποθεσια: Τρικαλα

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό ntgr την 18 Φεβ 2010 17:43

Εχω παραγγειλει απο 2 διαφορετικους στο ebay και ηταν ακριβως τα ιδια.

Συγνωμη ...μπερδεψα τις παραγγελιες :oops:
Παιδια ΠΡΟΣΟΧΗ !!!
Παρηγγειλα ακομα ενα απο καποιον αλλο απο ebay αλλα ειναι τελειως διαφορετικο. :shock: (δεν εχει καν mC μεσα) :evil:
Πιθανως λοιπον δεν δουλευει με τον παραπανω κωδικα.
Το link που σας εδωσα πιο πανω εχει το wii που ειναι συμβατο με τον κωδικα.
Ελπιζω να μην πηρα καποιον στο λαιμο μου. :cry:
Και παλι συγνωμη
Αριστοτέλης : Η ευχαρίστηση στην εργασία δίνει τελειότητα στο αποτέλεσμα..
Άβαταρ μέλους
ntgr
 
Δημοσ.: 301
Εγγραφη: 16 Οκτ 2009 11:33
Τοποθεσια: Τρικαλα

Re: Arduino & cheap ebay wii nunchuck

Δημοσίευσηαπό flokos την 10 Αύγ 2010 11:07

To δοκιμασα με το δικο μου nunchuck και νομιζω πως δουλεψε τα κουμπια τα εβλεπε και το μοχλο και το πανω κατω δεξια αριστερα
αλλα δεν ειμαι σιγουρος για το ποσο ακριβης ειναι οι μετρησεις.
Imagination is more important than knowledge. : Albert Einstein
Άβαταρ μέλους
flokos
 
Δημοσ.: 424
Εγγραφη: 17 Σεπ 2009 11:42


Επιστροφή στην Μυστικά και κόλπα

Μελη σε συνδεση

Μέλη σε αυτή την Δ. Συζήτηση : Δεν υπάρχουν εγγεγραμμένα μέλη και 1 επισκέπτης