![]() |
ultimo aggiornamento 2 marzo 2012 |
![]() |
Com'è fatto il Nunchuck
Il controller Nunchuck della Nintendo Wii e' un ottimo accessorio di controllo. Ha switches, joystick e un accelerometro, tutto in un comodo package. Il Nunchuk è identificato con una costante a 16-bit 0x0000 (0xFEFE criptato) al registro 0xa400fe indirizzo. Fornisce i dati di accelerazione a tre assi, due pulsanti digitali e uno stick analogico XY.
Formato dei dati
Il controller Nunchuck trasmette le sue informazioni come 6 byte di dati, leggibile a 0xa40008 e in continuo utilizzando un formato di dati che includono byte Extension (i byte inutilizzati sono pieni di 0x00). Il dato è confezionato in sei byte nel modo seguente (dopo la decrittografia)
|
Dove:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I valori restituiti dalla stick analogico del Nunchuk non comprendono
tutta la gamma possibile, ma piuttosto sono i limiti superiori e inferiori.
Lo Stick analogico restituisce per il dato X valori da circa 35 (completamente a
sinistra) a 228 (completamente a destra), mentre
per il valore Y
da circa 27 a 220. Centro per entrambi è di circa 128.
I dati accelerometrici sono compresi nell'intera gamma di 0-1024. Tuttavia, l'intera
gamma è visto solo quando si spostano o ruotando il Nunchuk bruscamente.
Per misurare la rotazione nello spazio, i limiti si applicano la
seguente approssimazione: X va da circa 300 (completamente inclinata a sinistra)
a 740 (a destra inclinato), inizia a trasformare ulteriormente portando il
valore più vicino a 512 (posizione neutra).
Allo stesso modo, Y passa da circa
280 (inclinato all'indietro) a 720 (in avanti). Z va da 320 (a testa in giù) a
760 (a destra in alto).
Hardware
Il controller Nunchuck ufficiale di Nintendo è cablato elettricamente in modo molto semplice. Ha un unico joystick composto da un potenziometro da 30KΩ per asse, due switch, un chip accelerometro e un microcontrollore.
|
Funzione |
Componente |
|
C |
Pulsante a membrana |
|
Z |
Pulsante a membrana |
|
Joystick X |
potenziometro assiale, 30KΩ |
|
Joystick Y |
potenziometro assiale, 30KΩ |
|
Accelerometro |
ST 8XRJ 3L02AE 820 MLT |
|
Microcontroller |
FNURVL 405 849KM |
I potenziometri joystick sembrano essere collegati in parallelo. Il chip accelerometro è il modello LIS3L02 da STMicroelectronics. Il chip microcontrollore sembra essere un NEC (ora Renesas) uDP78F05 microcontrollore, o un equivalente pin-compatibile.

|
Informazioni tecniche del sensore a 3 assi |
|
|
Tensione di alimentazione |
da 2.4 a 3.6V |
|
Range: |
+/-2g |
|
Sensibilità |
Vdd/5 V/g |
|
Livello di zero |
Vdd/2 V |
|
Massima accelerazione |
10000g per 0.1ms, or 3000g for 0.5ms |
Foto della scheda interna al controller
|
|
|
| Lato processore | Lato accelerometro e Joystik |
Adattatore per Nunchuck
Per il collegamento alla scheda Arduino, essendo un un peccato rovinare il connettore è possibile utilizzare appositi adattatori

Caratteristiche:
Due sets di pads di interfaccia
Due tipi di header
La spina del Nunchuck viene bloccata da due apposite anse, per prevenire il distacco accidentale
Sono resenti due fori per applicare eventuali fascette e bloccare il cavo
![]() |
![]() |
|
|
|
|
Shield d'interfaccia
Lo shield d'interfaccia è estremamente semplice limitandosi ad alcuni connettori, un pulsante connesso al pin di reset, e due normali diodi che con la loro caduta di tensione riducono la tensione di +5V prelevata dalla scheda Arduino a quella di circa +3,8V che serve per alimentare, il controller Nunchuck.
![]() |
![]() |
Costruzione della scheda
Vista la semplicità dello schema, il montaggio potrà essere
fatto utilizzando uno spezzone di basetta millefori dalle dimensioni di 35x53 mm
(13x20 fori); se si optasse invece per la realizzazione di un apposto circuito
stampato si potrà
scaricare il PDF che riporta la traccia in scala 1:1. Per la
sua realizzazione si utilizzerà una basetta in vetronite (monofaccia) di
dimensioni 35x53mm circa, il metodo potrà essere quello della fotoincisione o
del trasferimento termico utilizzando i cosiddetti fogli blu (PRESS-N-PELL). Una
volta inciso il rame, si verificherà in controluce o mediante l’utilizzo di un
multimetro, che non vi siano cortocircuiti soprattutto tra le piste più vicine.
Si passerà quindi alla foratura della stessa, utilizzando principalmente una
punta da 0,8-1 mm.
Quindi si posizioneranno e salderanno i componenti seguendo lo schema riportato
sotto.
Per la saldatura si utilizzerà un piccolo saldatore a punta fine, della potenza
di circa 25 – 30 W.
Si inizierà montando i ponticelli, i diodi ricordando che quest’ultimi sono polarizzati, controllare la posizione della fascia sul loro corpo. Si proseguirà con il pulsante e si terminerà montando i vari connettori. Si è così concluso il montaggio della scheda.
| Altro esempio di utilizzo tratto da internet
|
Programma di gestione
Il programma qui presentato permette di azionare un dispositivo Pan & Tilt che può essere auto costruito seguendo le indicazioni riportate in questa pagina
/* Programma:Comando_telecamera_Nunchuk.pde Versione: 1.0 Comando dispositivo Pan & Tilt tramite Nunchuk di Adriano Gandolfo Configuazione delle porte per la gestione della "WII NUNCHUCK" SDA sur port P18 (ANA4) SCK sur port P19 (ANA5) Lettura dei valeuri min e max Joystick X: mini=26 maxi=219 ==> a riposo = 123 Joystick Y: mini=31 maxi=229 ==> a riposo = 129 Bottone C=1 a riposo C=0 premuto Bottone Z=1 a riposo Z=0 premuto */ #include <Wire.h> #include <string.h> #include <stdio.h> uint8_t outbuf[6]; int cnt = 0; int ledPin = 13; int servoPin2 = 5; // Pin servo Rotazione telecamera int servoPin = 6; // Pin servo Rotazione base int pulseWidth = 0; int pulseWidth2 = 0; long lastPulse = 0; long lastPulse2 = 0; int z_button = 0; int c_button = 0; int refreshTime = 20; int minPulse = 200; // int minPulse2 = 200; int zeroPulse = 400; // Azzeramento posizione servo Rotazione base int zeroPulse2 = 350; // Azzeramento posizione Rotazione telecamera int dtime=10; #define pwbuffsize 10 long pwbuff[pwbuffsize]; long pwbuffpos = 0; long pwbuff2[pwbuffsize]; long pwbuffpos2 = 0; void setup() { Serial.begin (9600); Wire.begin (); nunchuck_init (); pinMode(servoPin, OUTPUT); pinMode(servoPin2, OUTPUT); pulseWidth = minPulse; pulseWidth2 = minPulse2; Serial.print ("Impostazione terminata"); } void nunchuck_init() { Wire.beginTransmission (0x52); Wire.send (0x40); Wire.send (0x00); Wire.endTransmission (); } void send_zero() { Wire.beginTransmission (0x52); Wire.send (0x00); Wire.endTransmission (); } int t = 0; void loop() { t++; long last = millis(); if( t == 1) { t = 0; Wire.requestFrom (0x52, 6); while (Wire.available ()) { outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); digitalWrite (ledPin, HIGH); cnt++; } if (cnt >= 5) { printNunchuckData(); int z_button = 0; int c_button = 0; if ((outbuf[5] >> 0) & 1) z_button = 1; if ((outbuf[5] >> 1) & 1) c_button = 1; switch (c_button) { case 1: switch (z_button) { case 0: break; case 1: muovi(); break; } break; case 0: switch (z_button) { case 0: delay(10000); break; case 1: delay(3000); break; } break; } } cnt = 0; send_zero(); } // if(t==) updateServo(); delay(dtime); } void updateServo() { if (millis() - lastPulse >= refreshTime) { digitalWrite(servoPin, HIGH); delayMicroseconds(pulseWidth); digitalWrite(servoPin, LOW); digitalWrite(servoPin2, HIGH); delayMicroseconds(pulseWidth2); digitalWrite(servoPin2, LOW); lastPulse = millis(); } } int i=0; void printNunchuckData() { int joy_x_axis = outbuf[0]; int joy_y_axis = outbuf[1]; int accel_x_axis = outbuf[2]; // * 2 * 2; int accel_y_axis = outbuf[3]; // * 2 * 2; int accel_z_axis = outbuf[4]; // * 2 * 2; int z_button = 0; int c_button = 0; if ((outbuf[5] >> 0) & 1) z_button = 1; if ((outbuf[5] >> 1) & 1) c_button = 1; if ((outbuf[5] >> 2) & 1) accel_x_axis += 2; if ((outbuf[5] >> 3) & 1) accel_x_axis += 1; if ((outbuf[5] >> 4) & 1) accel_y_axis += 2; if ((outbuf[5] >> 5) & 1) accel_y_axis += 1; if ((outbuf[5] >> 6) & 1) accel_z_axis += 2; if ((outbuf[5] >> 7) & 1) accel_z_axis += 1; Serial.print (i,DEC); Serial.print ("\t"); Serial.print ("X: "); Serial.print (joy_x_axis, DEC); Serial.print ("\t"); Serial.print ("Y: "); Serial.print (joy_y_axis, DEC); Serial.print ("\t"); Serial.print ("Tasto Z: "); Serial.print (z_button, DEC); Serial.print (" "); Serial.print ("Tasto C: "); Serial.print (c_button, DEC); Serial.println (""); i++; } char nunchuk_decode_byte (char x) { x = (x ^ 0x17) + 0x17; return x; } void muovi (){ float tilt = (zeroPulse - outbuf[0]); float tilt2 = (zeroPulse2 - outbuf[1]); tilt = (tilt); pulseWidth = (tilt * 5) + minPulse; tilt2 = (tilt2); pulseWidth2 = (tilt2 * 5) + minPulse2; pwbuff [pwbuffpos] = pulseWidth; pwbuff2[pwbuffpos2] = pulseWidth2; if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0; if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0; pulseWidth=0; pulseWidth2=0; for( int p=0; p<pwbuffsize; p++ ){ pulseWidth += pwbuff[p]; pulseWidth2 += pwbuff2[p]; } pulseWidth /= pwbuffsize; pulseWidth2 /= pwbuffsize; } |
| Elenco revisioni | |
| 02/03/2012 | Aggiornato pagina |
| 21/02/2012 | Aggiornato pagina, inserito descrizione scheda, inserito programma. |
| 16/10/2011 | Inserito filmato |
| 16/01/2011 | Emissione preliminare |