Go Down

Topic: i2c Arduino (Read 2081 times) previous topic - next topic

skalash

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

nid69ita

#31
Mar 06, 2013, 10:59 pm Last Edit: Mar 06, 2013, 11:01 pm by nid69ita Reason: 1
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;
my name is IGOR, not AIGOR

skalash

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?

nid69ita

#33
Mar 07, 2013, 05:02 pm Last Edit: Mar 07, 2013, 05:22 pm by nid69ita Reason: 1
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
my name is IGOR, not AIGOR

skalash

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.

skalash

Sono riuscito nel mio intento vi posto il codice magari puo tornare utile a qualcuno  ;)

Code: [Select]

/*
  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.

nid69ita

Io ho questo codice, tratto dagli esempi trovati in internet ma da me modificato

Code: [Select]

#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); 
}
my name is IGOR, not AIGOR

Testato

karma per entrambi,
codici molto istruttivi  :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Go Up