Ciao ragazzi, ho iniziato a giochicchiare con arduino e volevo chiederti dov'è il miglior posto per comprare i componenti elettronici.
Sapreste anche dirmi dove trovo il connettore per usare il telecomando della nintendo wii ?
Io sono di milano zona maciachini.
Grazie a tutti
volendo il circuito puoi non usarlo, se tagli il filo troverai 4 fili rosso-nero-giallo-bianco.
rosso a 5V
nero a gnd
giallo a SDA (analog pin 4)
bianco a SCL (analog pin 5)
poi come codice usi uno dei tanti che trovi sul forum.
Ho provato ma non funzione, ho un telecomando non originale cambia qualcosa ?
La prima volta che ho fatto i contatti ho messo 5V al posto di 3.3V si può essere bruciato il telecomando wii ?
si, cambiano i valori di inizializzazione...
ti passo il mio codice che ho avuto lo stesso preoblema (la parte del codice originale è commentata)
nunchuck_init(){
/*
//
// FOR ORIGINAL NUNCHUCK
//
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
//
// END FOR ORIGINAL NUNCHUCK
//
*/
//
// FOR FAKE NUNCHUCK
//
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
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
//
// END FAKE NUNCHUCK
//
nunchuck_send_request();
}
alle volte il nunckuck si blocca tra Serial.print ("Begin40\n"); e Serial.print ("Begin41\n"); per risolvere stacca completamente l'alimentazione ad arduino, credo che ciò accada quando resetti l'arduino mentre sta inviando un comando, e allora all'inizializzazione successiva (dato che il nun non si resetta) rimane salavata mezzo comando e l'inizializzazione fallisce.
Ho sostituito quello che mi hai scritto dentro la funzione mi da questo errore:
sketch_may02a:72: error: 'ctrlr_type' was not declared in this scope
Riesci a postarmi tutto il codice per leggere i dati ?
Grazie mille
ok, in realtà uso un classe.
Una classe è composta da 2 file, uno .cpp e uno .h. Li metti nella stessa cartella del file .pde
NunchukFarlocco.cpp:
#include "NunchukFarlocco.h"
//I 3 VALORI SEGUENTI SONO LO ZERO DELL'ACCELEROMETRO(ZERO-OFFSET), POSSONO VARIARE (di poco) DAL TUO NUNCHUCK!
#define ACC_ZERO_X 484
#define ACC_ZERO_Y 530
#define ACC_ZERO_Z 405
void NunchukFarlocco::update(){
nunchuck_get_data();
}
float* NunchukFarlocco::leggi(){
return value;
}
int NunchukFarlocco::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 elaborate them
if (cnt >= 5) {
nunchuk_elaborate_data();
return 1; // success
}
return 0; //failure
}
float gSquared=0, g, minE, maxE;
void NunchukFarlocco::nunchuk_elaborate_data(){
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;
// 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;
value[0]=accel_x_axis;//-ACC_ZERO_X;
value[1]=accel_y_axis;//-ACC_ZERO_Y;
value[2]=accel_z_axis;//-ACC_ZERO_Z;
float x = map(value[0], 90, 890, -100, 100);
float y = map(value[1], 130, 900, -100, 100);
float z = map(value[2], 90, 700, -100, 100);
float t = x*x+y*y+z*z;
Serial.print( "t:" );
Serial.print( sqrt(t) );
Serial.print("x:");
Serial.print(x);
Serial.print("y:");
Serial.print(y);
Serial.print("z:");
Serial.println(z);
/*
float t = value[0]*value[0]+value[1]*value[1]+value[2]*value[2];
Serial.print( "t:" );
Serial.print( sqrt(t) );
Serial.print("x:");
Serial.print(value[0]);
Serial.print("y:");
Serial.print(value[1]);
Serial.print("z:");
Serial.println(value[2]);
/*
if (gSquared==0){
g = x*x+y*y+z*z;
gSquared=sqrt(g);
minE = g-(g/5);
maxE = g+(g/5);
}else{
float t = x*x+y*y+z*z;
/*
Serial.print( "t:" );
Serial.print( sqrt(t) );
Serial.print(" should be:");
Serial.println( gSquared );
if (t!=g){
if (t >= minE && t <= maxE){
double phi = atan2(y, x);
double theta = acos( z/sqrt(t) );
x=gSquared*sin(theta)*cos(phi);
y=gSquared*sin(theta)*sin(phi);
z=gSquared*cos(theta);
/*
Serial.print("old distance:");
Serial.print( sqrt(t) );
Serial.print(" new distance:");
Serial.print( sqrt(x*x+y*y+z*z) );
Serial.print(" should be:");
Serial.println( gSquared );
}else{
/*
Serial.print( "acc no good data; t:" );
Serial.print( sqrt(t) );
Serial.print(" should be:");
Serial.println( gSquared );
}
}
}
*/
}
// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char NunchukFarlocco::nunchuk_decode_byte (char x){
x = (x ^ 0x17) + 0x17;
return x;
}
void NunchukFarlocco::nunchuck_send_request(){
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}
void NunchukFarlocco::nunchuck_init(){
/*
//
// FOR ORIGINAL NUNCHUCK
//
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
//
// END FOR ORIGINAL NUNCHUCK
//
*/
//
// FOR FAKE NUNCHUCK
//
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
//
// END FAKE NUNCHUCK
//
nunchuck_send_request();
}
NunchukFarlocco.h
#ifndef NunchukFarlocco_h
#define NunchukFarlocco_h
#include "WProgram.h"
#include "Wire.h"
class NunchukFarlocco{
public:
void nunchuck_init(); // send the initilization handshake
void update();
float* leggi();
float value[3];
private:
int nunchuck_get_data();
char nunchuk_decode_byte (char x);
void nunchuck_send_request();
void nunchuk_elaborate_data();
uint8_t nunchuck_buf[6]; // array to store nunchuck data,
uint8_t ctrlr_type[6];
};
#endif
.pde di prova e esempio di utilizzo:
#include <Wire.h>
#include "NunchukFarlocco.h"
#define ledPin 13
NunchukFarlocco nun;
void setup(){
Serial.begin(19200);
delay(1000);//per evitare che si incasini l'upload per via dell'uso "aggressivo" della seriale
digitalWrite(ledPin, HIGH);
nun.nunchuck_init(); // send the initilization handshake
}
boolean statoLedPin=true;
int loopNumber=0;
void loop(){
nun.update();
float *valori = nun.leggi();
Serial.print("X: ");
Serial.print(valori[0]);
Serial.print(" Y: ");
Serial.print(valori[1]);
Serial.print(" Z: ");
Serial.println(valori[2]);
loopNumber++;
if (loopNumber>100){
statoLedPin=!statoLedPin;
if (statoLedPin)
digitalWrite(ledPin, HIGH);
else
digitalWrite(ledPin, LOW);
loopNumber=0;
}
}
il lampeggio del led serve per vedere se si blocca il codice. Ricordatio che per ricevere dei nuovi valori prima fai l'update() e poi leggi()(primi 2 comandi del loop() ), altrimenti leggerai i valori letti nell'ultimo update
edit:
il codice originale è di
/*
- NunchuckPrint
- 2007 Tod E. Kurt, todbot blog – Random experiments, circuits, code, rapid prototyping, sometimes things to buy, and the odd tune by Tod Kurt.
- The Wii Nunchuck reading code is taken from Windmeadow Labs
-
http://www.windmeadow.com/node/42
*/
pesantemente modificata in classe e per i farlocchi da me, i codici di inizializzazione li ho trovati sul forum ma non so da chi...
funziona?
Funziona, però non capisco i dati che mi da:
t:120.97x:8.00y:13.00z:120.00
X: 524.00 Y: 568.00 Z: 764.00
Che cosa é t,x,y,z ?
Come posso regolare X Y X e quali sono i valori limite ?
Posso recuperare informazioni sui pulsanti e sul joystick ?
Grazie mille
x, y, e z sono i valori dell'accelerometro in un range da -100 a 100
t è la lunghezza del vettore accelarzione, quando il nunchuck è fermo dovrebbe sempre essere 100 qualsiasi sia la posizione, altrimenti non è calibrato bene (ovvio che un minimo di errore ci può essere)
Come puoi notare sono valori di debug che non mi sono accorto di aver lasciato, come il codice seguente (tutto commentato) che si occupa di eliminare le letture il cui vettore gravità è sballato (presenza di accelerazioni)
X, Y e Z sono i valori reali che puoi utilizzare in output dal nunchuck
ehm mi sono acorto di un errore:
value[0]=accel_x_axis;//-ACC_ZERO_X;
value[1]=accel_y_axis;//-ACC_ZERO_Y;
value[2]=accel_z_axis;//-ACC_ZERO_Z;
dovrebbe essere:
value[0]=accel_x_axis-ACC_ZERO_X;
value[1]=accel_y_axis-ACC_ZERO_Y;
value[2]=accel_z_axis-ACC_ZERO_Z;
altrimenti non tieni conto dello zero offset.
lo zero offset lo puoi regolare dalle define:
#define ACC_ZERO_X 484
#define ACC_ZERO_Y 530
#define ACC_ZERO_Z 405
i suoi valori limite sono da 0 a 1024 meno lo zero offset.
per leggere i bottoni deccomenta il codice:
/*
if ((nunchuck_buf[5] >> 0) & 1)
z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1)
c_button = 1;
*/
per leggere il joystick (asse x e y) aggiungi il codice:
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
direi che questa volta c'è tutto!