Ciao skalash sono pronto a ricevere 6 numeri?
Ok, dove li mando?
Ecco l'indirizzo.
Ok, ho ricevuto tutto correttamente.
Ciao skalash
@#%""%"%!==(%
Che minkia hai detto??
![]()
Ho reso l'idea?
![]()
Ciao skalash sono pronto a ricevere 6 numeri?
Ok, dove li mando?
Ecco l'indirizzo.
Ok, ho ricevuto tutto correttamente.
Ciao skalash
@#%""%"%!==(%
Che minkia hai detto??
![]()
Ho reso l'idea?
![]()
1)ok ho capito, la funzione nunchuck_send_request() comunica che la ricezione del dato è andato bene, quindi sarebbe una controrisposta ![]()
if (cnt >= 5) {
return 1; //restituisce 1 se fallisce
}
ma al ritorno della funzione non importa a nessuno se fallisce perchè non viene controllato da niente era utile che se al ritorno c'era 1 allora comunicava " è andato tutto a schifio" altrimenti "tutto ok" ![]()
inoltre la condizione è sbagliata perchè restituisce errore quando riceve 5 o più byte quindi quando riceve la giusta quantita di dati da 1 cioè sbagliato
sarebbe giusto fare un controllo del genere
if (cnt <= 5 || cnt >= 7)
{
return 1; //restituisce 1 se fallisce
}
Il controllo sui dati lo puoi aggiungere tu. La funizone restituisce un valore che puoi controllare con un IF.
Riguardo il controllo sul numero dei dati bisognerebbe controllare il protocollo di comunicazione e capire il perché l'IF è strutturato in quel modo.
Si lo so che lo posso aggiungere io :P, la mia osservazione era che nel codice iniziale quel controllo sul return è inutile e sbagliato ![]()
Un ultimo aiuto abbiate pazzienza
if ((nunchuck_buf[5] >> 0) & 1)
{
z_button = 1;
}
questa condizione significa se il bit 0 (quello relativo al pulsante Z) AND 1 sono != 0, cioè il bit è 1, il valore del pulsante è 1, altrimenti 0
è giusto?
Si, ma non essendoci l'ELSE rimane il vecchio valore. Che può essere 0 ma può anche essere diverso.
PaoloP approfitta della tua bonta, mi spieghi perchè i valori in binario letti dal nunchuck vengono decodificati con questo metodo, in particolar modo si eleva la lettura X a 0x17 e poi si somma 0x17 che in decimale vale 23
// metodi di codifica dei nunchuck originali
char nunchuk_decode_byte (char x)
{
// x = int(x);
x = (x ^ 0x17) + 0x17;
return x;
}
Boh!
Forse perché il nunckacku prima di inviare il dato gli sottrae 23 e fa la radice 23°?
Credo sia un modo per codificare i dati per renderli difficilmente utilizzabili, ma li hanno sgamati. ![]()
Bene sono nella m***a
ma se io leggo un byte e lo concateno con gli altri due bit e ottengo 10 bit che vengo convertiti in intero dici che si puo fare?
Non capisco perché devi fare quella operazione.
Dopo che legge i dati dal nunckacku li hai disponibili ognuno nella sua variabile.
Se li devi inviare al Pc oppure stampare su seriale o utilizzare in altra maniera hai comunque il dato già decodificato disponibile.
il valore della letture per esempio dell' asse x del potenziometro è a 10 bit divisi in 2 bit e 8 bit quindi pensavo di concatenarli e memorizzarli in una variabile intera a 16 bit in modo da averli uniti e non suddivisi in due variabili
Attenzione che l'operazione x^0x17 è lo XOR bit a bit, non l'elevamento a potenza.
Tenere conto dei 2 bit ulteriori lo fa per ogni asse cosi:
if ((nunchuck_buf[5] >> 2) & 1)
accel_x_axis += 2;
nid69ita hai raggione non ci stavo proprio pensado abituato con l'elevazione in matematica e l' ho letto in quel modo, comunque perchè c'è bisogno di fare la XOR con 0x17(23 in decimale) e poi sommargli sempre 0x17?
E' un modo come un'altro per "mascherare" i valori. Una specie di cifratura.
Io comunque sui 2 nunchuck che ho non ho usato quel calcolo e i valori li ottengo lo stesso.
Forse non ottengo valori corretti? Boh. A me sembrano valori normali.
17 in esa => 10111 in binario
Te come la fai la lettura dei dati? io pensavo di leggere i primi 5 byte e convertire bit a bit il valore della posizione in decimale e sommare i valori decimali di tutti i bit in una variabile (senza tralasciare i 2 bit piu significativi) in modo da avere in decimale il valore della lettura
Io comunque ho ritrovato l'articolo ariginale in cui si fa uso di questa decodifica ma mi pare di capire che è un modo per " tarare il nunchuck alla buona", quindi iopenso che i comuni mortali non usano questo metodo.
Sono riuscito nel mio intento vi posto il codice magari puo tornare utile a qualcuno ![]()
/*
Programma che esegue la lettura dei dati dal controller nunchuck della wii e mostra i valori letti tramite monitor seriale
*/
// includo la libreria Wire.h
#include <Wire.h>
void setup()
{
// setto la seriale
Serial.begin(115200);
// inizio la comunicazione i2c
Wire.begin();
// inizializzo il nunchuck
nunchuckInizializzazazione();
}
void loop()
{
// chiamo la funzione per ottenere i dati dal nunchuck
nunchuckRichiestaDati();
// chiamo la funzione per inviare i dati dalla seriale e stamparli a video
nunchuckStampaDati();
// inserisco un ritardo per non sovraccaricare il processore
delay(200);
}
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Nunchuck funzioni
//array utilizzato per immagazzinare i dati in arrivo dal nunchuck,
static uint8_t nunchuck_buf[6];
// funzione di inizializzazione del nunchuck
void nunchuckInizializzazazione ()
{
// inizio la trasmissione con la periferica indicando l'indirizzo della stessa 0x52
Wire.beginTransmission(0x52);
// trasmetto l'indirizzo della memoria
Wire.write(0x40);
// trasmetto uno 0 perchè voglio leggere i dati dalla periferica
Wire.write(0x00);
// fermo la trasmissione
Wire.endTransmission();
}
// funzione che invia la richiesta alla periferica per ottenere dati
void nunchuckInviaRicezione ()
{
// inizio la trasmissione con la periferica indicando l'indirizzo della stessa 0x52
Wire.beginTransmission(0x52);
// trasmetto un byte con valore '0' in questo modo comunico che la periferica deve inviare i dati da leggere
Wire.write(0x00);
// fermo la trasmissione
Wire.endTransmission();
}
// funzione che riceve i dati e li immagazzina in un buffer
int nunchuckRichiestaDati()
{
// creo un contatore per scorrere il buffer contenente i dati ricevuti
int cnt = 0;
// invio la richiesta alla periferica di 6 byte
Wire.requestFrom (0x52, 6);
// mentre ci sono dati da leggere, leggo i dati e li memorizzo nel buffer
while (Wire.available () != 0 )
{
// leggo i byte che arrivano e li memorizzo nel buffer
nunchuck_buf[cnt] = Wire.read();
// mi sposto all'elemento successivo del buffer
cnt++;
}
// controllo che il quantitaivo di dati arrivati sia giusto e comunico il risultato
if(cnt = 6)
{
// confermo che i dati sono stati ricevuti correttamente sia all'utente che alla periferica
nunchuckInviaRicezione();
Serial.println("OK");
}
else
{
// comunico che i dati non sono giusti e che c'è stato un errore
Serial.println("ERRORE");
}
// restituisco 0
return 0;
}
// funzione che stampa i dati arrivati, i dati di accelerazione sono lunghi 10 bit, quindi ne leggiamo 8 poi aggiungiamo gli ultimi 2 bit
void nunchuckStampaDati ()
{
/*
DOCUMENTAZIONE SUL PACCHETTO DATI INVIATO DALLA PERIFERICA
Byte/Bit 7 6 5 4 3 2 1 0
1 Asse X del joystick analogico
2 Asse Y del joystick analogico
3 8 bit MSB del valore dell’accelerazione sull’asse X
4 8 bit MSB del valore dell’accelerazione sull’asse Y
5 8 bit MSB del valore dell’accelerazione sull’asse Z
6 Z Z Y Y X X C Z
*/
// memorizzo i dati del buffer relativi al joypad (x,y) in due variabili
byte joy_x_axis = nunchuck_buf[0];
byte joy_y_axis = nunchuck_buf[1];
// setto a '0' il buffer
for(int i=0; i <=6 ;i++)
{
nunchuck_buf[i] = 0;
}
// creo due variabili di appoggio
byte x=0;
byte y=0;
// taratura nunchuck
x = abs(joy_x_axis-23);
y = abs(joy_y_axis-28);
// stampo il risultato sul monitor
Serial.print("x = ");
Serial.print(x,DEC);
Serial.print(" y = ");
Serial.print(y, DEC);
Serial.print("\r\n"); // newline
}
Tuttavia ho notato una grande difficolta e innaffidabilita dei nunchuck, per esempio spingendo il joystick su i valori per qualche istante anziche aumentare diminuiscone e poi aumentano di colpo ad esempio se non spinto, il valore è 96, spingendolo passa da 70 e poi a 120,stessa cosa con l' asse x, ho provato a usare anche un' altro nunchuck sempre originale ma il risultato non cambia, è molto piu semplice e affidabile usare un mini joystick resistivo tipo quelli montati sul controller della ps3.
Io ho questo codice, tratto dagli esempi trovati in internet ma da me modificato
#include <Wire.h>
#include <string.h>
#include <stdio.h>
class Nunchuck
{
private:
uint8_t outbuf[6];
void _sendByte(byte data, byte location)
{ Wire.beginTransmission(0x52);
Wire.write(data);
Wire.write(location);
Wire.endTransmission();
//delay(10);
}
void _send_zero()
{ Wire.beginTransmission (0x52);
Wire.write(0x00);
Wire.endTransmission ();
}
public:
int Joy_x;
int Joy_y;
int Acc_x;
int Acc_y;
int Acc_z;
int Button_z;
int Button_c;
int Type;
void Init()
{ Wire.begin();
if(Type==1)
_sendByte(0xF0,0x55);
else
_sendByte(0x40,0x00);
}
void update()
{ int t;
int cnt = 0;
t++;
long last = millis();
if( t == 1)
{ t = 0;
Wire.requestFrom (0x52, 6);
while (Wire.available())
{ outbuf[cnt] = Wire.read(); //nunchuk_decode_byte (Wire.read());
cnt++;
}
cnt = 0;
_send_zero();
} // if(t==)
Joy_x = outbuf[0];
Joy_y = outbuf[1];
Acc_x = outbuf[2]; // * 2 * 2;
Acc_y = outbuf[3]; // * 2 * 2;
Acc_z = outbuf[4]; // * 2 * 2;
Button_z = 1;
Button_c = 1;
if ((outbuf[5] >> 0) & 1) Button_z = 0;
if ((outbuf[5] >> 1) & 1) Button_c = 0;
if ((outbuf[5] >> 2) & 1) Acc_x += 2;
if ((outbuf[5] >> 3) & 1) Acc_x += 1;
if ((outbuf[5] >> 4) & 1) Acc_y += 2;
if ((outbuf[5] >> 5) & 1) Acc_y += 1;
if ((outbuf[5] >> 6) & 1) Acc_z += 2;
if ((outbuf[5] >> 7) & 1) Acc_z += 1;
}
};
Nunchuck xnc;
int dtime=500;
void setup()
{ Serial.begin(9600);
xnc.Type=1;
xnc.Init();
Serial.print("Finished setup\n");
}
void loop()
{ int i=0;
xnc.update();
Serial.print("X: "); Dec2Str(xnc.Joy_x); Serial.print ("\t");
Serial.print("Y: "); Dec2Str(xnc.Joy_y); Serial.print ("\t");
Serial.print("AccX: "); Dec2Str(xnc.Acc_x); Serial.print ("\t");
Serial.print("AccY: "); Dec2Str(xnc.Acc_y); Serial.print ("\t");
Serial.print("AccZ: "); Dec2Str(xnc.Acc_z); Serial.print ("\t");
Serial.print(xnc.Button_z,DEC); Serial.print (" ");
Serial.print(xnc.Button_c,DEC); Serial.print ("\r\n");
delay(dtime);
i++;
}
void Dec2Str(int p_val)
{ char Str1[4];
Str1[2]='0'+( p_val % 10);
p_val=p_val/10;
Str1[1]='0'+( p_val % 10);
p_val=p_val/10;
Str1[0]='0'+( p_val % 10);
Str1[3]=0;
Serial.print (Str1);
}
karma per entrambi,
codici molto istruttivi ![]()