Pages: 1 2 [3]   Go Down
Author Topic: i2c Arduino  (Read 1591 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4638
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;
« Last Edit: March 06, 2013, 05:01:38 pm by nid69ita » Logged

my name is IGOR, not AIGOR

Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4638
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: March 07, 2013, 11:22:53 am by nid69ita » Logged

my name is IGOR, not AIGOR

Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sono riuscito nel mio intento vi posto il codice magari puo tornare utile a qualcuno  smiley-wink

Code:
/*
  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.
Logged

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4638
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

my name is IGOR, not AIGOR

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5785
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

karma per entrambi,
codici molto istruttivi  smiley
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Pages: 1 2 [3]   Go Up
Jump to: