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):
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
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;
}