Aiuto Wii Nunchuck + Arduino Duemilanove

Salve a tutti… Ho costruito di recente un braccio robotico che viene controllato dall’arduino duemilanove che monta un atmega328. Da tempo volevo integrare nel progetto anche un accellerometro per muovere il braccio usando i valori letti. Considerando i costi dei sensori etc, alla fine ho pensato che era meglio comprare un Nunchuck per wii che ha sia l’accelletometro che il Joystick e 2 tasti oltre ad aver prima letto un sacco di guide online. Morale della favola, stamattina mi sono precipitato da gamestop dove il commesso mi ha proposto di comprare il nunchuck non originale (visto che mi serviva per un uso “improprio” e che costava meno dell originale). Così ho fatto. Tornato a casa, ho installato le librerie per gestirlo e ho fatto partire vari programmi di prova (ho già provato con i programmi presenti nel playground, e quelli proposti da todbot e windmeadow). Sul forum ho anche trovato un programma che “testa” la connessione i2c. L’arduino riconosce e trova l’address giusto del controller ma quando cerco di stampare i valori sulla seriale, questi non cambiano. Ovvero, mi da 255, 255 per il joystick e 258,258,258 per l’accellerometro indipendentemente dall orientamento dello stesso. Ho provato varie configurazioni, con o senza pull up, collegare l’alimentazione a 5V o a 3,3V o anche collegare il Nunchuck ai 4 pin analogici come fa chi usa l’adattatore venduto da todbot.Ho pure provato a cambiare i valori in twi.h come suggerito in alcune pagine per quanto riguarda la velocità di comunicazione e altro ma nulla da fare. Provato con almeno 6 valori diversi di baud rate ma nulla lo stesso. Il risultato non cambia. Ora mi trovo a pensare: è forse dovuto al fatto che il nunchuck non è quello originale ma quello di gamestop (aka invece di risparmiare 5 euri ne ho persi 15)? C’è qualcuno che ha riscontrato lo stesso problema e se si, come ne è uscito? Ho trovato già parecchia gente che si ritrova a leggere valori costanti dal nunchuck ma nessuno ha postato il modo per risolvere il problema (anche se alcuni hanno postato che l’hanno effettivamente risolto). Ringrazio in anticipo chiunque si prenda il tempo di rispondere.

un esempio di codice che mi da valori costanti è il seguente (uno dei tanti che ho provato):

#include <Wire.h>
#include <nunchuck_funcs.h>

void setup()
{
Serial.begin(9600);
nunchuck_init();
Serial.println(“Finished setup”);
}

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

il programma che testa la connessione i2c:

// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011

#include <Wire.h>

void setup() {
Serial.begin (115200);
Serial.println ();
Serial.println (“I2C scanner. Scanning …”);
byte count = 0;

Wire.begin();
for (byte i = 1; i < 120; i++)
{
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0)
{
Serial.print (“Found address: “);
Serial.print (i, DEC);
Serial.print (” (0x”);
Serial.print (i, HEX);
Serial.println (")");
count++;
} // end of good response
delay (5); // give devices time to recover
} // end of for loop
Serial.println (“Done.”);
Serial.print (“Found “);
Serial.print (count, DEC);
Serial.println (” device(s).”);
} // end of setup

void loop() {}

Prova con il codice che ti allego, è sicuramente funzionante sia con i nunchuk originali che i cloni, collega il tutto seguendo lo schemino in testa al programma.

/*
_________
| 1 2 3 |
|       |
| 6 5 4 |
|_-----_|

•pin 1: verde - data (Arduino analog pin 4) 
•pin 2: (not connected) 
•pin 3: rosso - 3.3V 
•pin 4: giallo - clock (Arduino analog pin 5) 
•pin 5: (not connected) 
•pin 6: bianco - GND 
*/

#include <Wire.h>

void setup()
{
Serial.begin(115000);
nunchuck_init(); // inizializza il nunchuck
}

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

//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6];   //array utilizzato per immagazzinare i dati in arrivo dal nunchuck,


void nunchuck_init()
{ 
Wire.begin();                    
Wire.beginTransmission(0x52);    // trasmettiamo l'indirizzo della periferica 0x52
Wire.send(0x40);        // trasmettiamo l'indirizzo della memoria
Wire.send(0x00);        // trasmettiamo uno 0 perchè vogliamo leggere dati
Wire.endTransmission();    // smettiamo di trasmettere
}

void nunchuck_send_request()
{
Wire.beginTransmission(0x52);    //trasmettiamo l'indirizzo del nunchuck 
Wire.send(0x00);        // trasmettiamo un byte
Wire.endTransmission();    // smettiamo di trasmettere
}

// Ricevere dati e immagazzinarli in un buffer
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6);   
while (Wire.available ()) {
// decodifichiamo i byte che ci arrivano e li traformiamo in un intero
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request();  

if (cnt >= 5) {
return 1;  //restituisce 1 se fallisce
}
return 0; //restituisce 0 se i dati sono stati ricevuti in maniera corretta
}

// Stampare i dati arrivati
// i dati di accelerazione sono lunghi 10 bit
// quindi ne leggiamo 8 poi aggiungiamo
// gli ultimi 2 bit.
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; 
int accel_y_axis = nunchuck_buf[3] << 2;
int accel_z_axis = nunchuck_buf[4] << 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 += 1;
if ((nunchuck_buf[5] >> 3) & 1) accel_x_axis += 2;

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

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

Serial.print(i,DEC);
Serial.print(",");

Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print(",");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(",");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);
Serial.print(",");
Serial.print(nunchuck_buf[5], BIN);

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

//  codifica nunchuck
char nunchuk_decode_byte (char x)
{
 x = (x ^ 0x17) + 0x17;
 return x;
}

il mio nunchuck non originale funziona usando questa funzione di init:

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{ 
  /*
  Wire.begin();	                // join i2c bus as master
  Wire.beginTransmission(0x52);	// transmit to device 0x52
  Wire.send(0x40);		// sends memory address
  Wire.send(0x00);		// sends sent a zero.  
  Wire.endTransmission();	// stop transmitting
  */
  byte cnt;
Serial.print ("Begin3\n");
Wire.begin();
            Serial.print ("Begin4\n");
// init controller
delay(1);
Wire.beginTransmission(0x52);	// device address
Serial.print ("Begin40\n");
Wire.send(0xF0);		        // 1st initialisation register
Serial.print ("Begin40\n");
Wire.send(0x55);		        // 1st initialisation value
Serial.print ("Begin40\n");
Wire.endTransmission();
Serial.print ("Begin41\n");
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0xFB);		        // 2nd initialisation register
Wire.send(0x00);		        // 2nd initialisation value
Serial.print ("Begin42\n");
Wire.endTransmission();
delay(1);
            Serial.print ("Begin5\n");
// 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
Serial.print ("Begin6\n");
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
    }
    Serial.print ("Begin7\n");
}
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 


}

il resto rimane uguale agli originali