Programmation Arduino pour Nunchuk .

Oui j'avais posté sur le forum français Arduino pour savoir si le module était adapté à mon cas puis j'ai dérivé sur mon projet . Et quand j'ai vu la section Robotique ici je me suis dit pourquoi pas .

Justement j'étais en train de relire les réponses sur le forum arduino et tes réponses ici et la documentation sur les fonctions de l'Arduino http://arduino.cc/en/Reference/HomePage pour remettre de l'ordre dans ma tête .

Je commence à cerner un peu mon problème et à comprendre certaines choses , en fin je crois !:rolleyes: Dis moi si je me trompe .

Entre 0 et 255 est un entier qui correspond au duty cycle du signal PWM.
Plus le nombre est grand plus la tension est grande .
Ça ok je connais, mais dans l'automobile on appel ça le "Rapport cyclique" et on l'exprime en pourcentage . C' est une sortie .

J'ai vu aussi une autre "variable" , 0 à 1024 , qui serait en rapport avec un convertisseur analogique/numérique . Cette variable serait une entrée .

Si on a 1024 en entrée (donné par un capteur quelconque ) on aurait 255 en sortie .

Le problème c'est que l'on ne connaît pas la valeur en entier donné par le nunchuk car il nous donne des bytes ? Donc il faudrait connaitre la valeur en entier des bytes reçu (entre 0 et 1024?) et c'est là qu' intervient le produit en crois pour convertir en 0_255 .

C'est bien ça ou je suis complètement a l'ouest ?

Si c'est bien ça , la question est : comment connaitre la valeur d'un byte ?



PS: Je viens de me rendre compte que c'est ce que me disait alxblog sur Arduino FR :rolleyes:

PS2: 0 à 1024 se ne serait pas des octets ? Et 0 à 255 serait les nombres représenté par un octet ?
 
Sav à dit:
Je commence à cerner un peu mon problème et à comprendre certaines choses , en fin je crois !:rolleyes: Dis moi si je me trompe .

Entre 0 et 255 est un entier qui correspond au duty cycle du signal PWM.
Plus le nombre est grand plus la tension est grande .
Ça ok je connais, mais dans l'automobile on appel ça le "Rapport cyclique" et on l'exprime en pourcentage . C' est une sortie .

J'ai vu aussi une autre "variable" , 0 à 1024 , qui serait en rapport avec un convertisseur analogique/numérique . Cette variable serait une entrée .

Si on a 1024 en entrée (donné par un capteur quelconque ) on aurait 255 en sortie .
Il me semble justement que le nunchuk ne renvoi pas une valeur comprise entre 0 et 1024, mais plutôt entre 72 et 176, mais j'ai peut être pas bien lu.

Sav à dit:
Le problème c'est que l'on ne connaît pas la valeur en entier donné par le nunchuk car il nous donne des bytes ? Donc il faudrait connaitre la valeur en entier des bytes reçu (entre 0 et 1024?) et c'est là qu' intervient le produit en crois pour convertir en 0_255 .

C'est bien ça ou je suis complètement a l'ouest ?
Dans ton code, sans lire dans le détail, j'ai vu la fonction nunchuk_decode_byte() et j'en ai déduis, peu être trop rapidement, que c'est exactement ce qu'elle faisait...
En fait cette fonction ne nous est pas utile.
Je ne vois pas trop l'intérêt d'un produit en croix, je me suis dit qu'il fallait trouver la fonction qui permet de convertir tes données entre 72 et 176 en des valeurs entre 0 et 255.
J'ai testé çà, qui à l'air de fonctionner :

int conversion (float test){
nouvelleValeur=(int)(255*test/104)-(2295/13);
return nouvelleValeur;
}

J'ai changé la valeur d'entrée "test" d'un int en un float, après avoir lu ceci :

"Programming Tips:

* Know that integer constants default to int, so some constant calculations may overflow (e.g. 60 * 1000 will yield a negative result)."

http://arduino.cc/en/Reference/Arithmetic

Voici un code qui "devrai" fonctionner

Code:
#include <Wire.h>
#include <string.h>

#undef int
#include <stdio.h>

uint8_t outbuf[6];    // array to store arduino output
int cnt = 0;
int ledPin = 13;
int ledPin1 = 11;     // Led broche digital PWM 11 pour visualisation du signal
int nouvelleValeur = 128;
int valeurRetour = 128;

void
setup ()
{
  beginSerial (9600);
  Serial.print ("Finished setup\n");
  Wire.begin ();        // join i2c bus with address 0x52
  nunchuck_init ();                   // send the initilization handshake
  pinMode(ledPin1, OUTPUT);      // configure broche 11 en sortie 

}

 

void
nunchuck_init ()
{
  Wire.beginTransmission (0x52);    // transmit to device 0x52
  Wire.send (0x40);        // sends memory address
  Wire.send (0x00);        // sends sent a zero. 
  Wire.endTransmission ();    // stop transmitting
}

void
send_zero ()
{
  Wire.beginTransmission (0x52);    // transmit to device 0x52
  Wire.send (0x00);        // sends one byte
  Wire.endTransmission ();    // stop transmitting
}

void
loop ()
{
  Wire.requestFrom (0x52, 6);    // request data from nunchuck
  while (Wire.available ())
    {
      outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
      digitalWrite (ledPin, HIGH);    // sets the LED on
      cnt++;
    }

  // If we recieved the 6 bytes, then go print them
  if (cnt >= 5)
    {
      print ();
    }
    {
      valeurRetour = conversion(outbuf[3]); // on converti la valeur recue avec la fonction "conversion" en dessous.
     analogWrite(ledPin1, valeurRetour) ;   //commande en PWM la led1 , j'ai mis -50 à outbuf[3] au hazard .
    }

  cnt = 0;
  send_zero (); // send the request for next bytes
  delay (100);
}

//fonction de conversion 
//elle prend un float compris entre 72 et 176 en parametre, et renvoi un entier compris entre 0 et 255
int conversion (float test){
  nouvelleValeur=(int)(255*test/104)-(2295/13);
  return nouvelleValeur;
  }

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits.  That is why I
// multiply them by 2 * 2
void
print ()
{
  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;

// byte outbuf[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 ((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 (joy_x_axis, DEC);
  Serial.print ("\t");

  Serial.print (joy_y_axis, DEC);
  Serial.print ("\t");

  Serial.print (accel_x_axis, DEC);
  Serial.print ("\t");

  Serial.print (accel_y_axis, DEC);
  Serial.print ("\t");

  Serial.print (accel_z_axis, DEC);
  Serial.print ("\t");

  Serial.print (z_button, DEC);
  Serial.print ("\t");

  Serial.print (c_button, DEC);
  Serial.print ("\t");

  Serial.print ("\r\n");
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char
nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}
J'ai testé avec différentes valeurs mais sans nunchuck impossible de dire si c'est bon. En tout cas j'espère que ça fera avancer le schmilblik :D

++

MadProf
 
Alors avec ce nouveau code j'ai 2.5 Volts à l'horizontale ! Le signal descend proportionnellement lorsque que j' incline le capteur vers le haut mais arrivé à peu prés à la verticale , il remonte brusquement à 4.8 Volts .

Lorsque j' incline vers le bas le capteur c'est bien l'inverse , le signale varie de 2.5 Volts à quasi 4.8 Volts puis a peu prés à la verticale il redescend brusquement à 0 Volt .

En résumé , j'ai un signal proportionnel sur une rotation du nunchuk d'environ 80 degré . =D

C'est très très bien comme résultat , dans le cadre de mon projet "suiveur de tète" ce doit être acceptable comme signal , mais dans une application du genre "pilotage d'un modèle grâce au nunchuk" ça sera plus délicat .

Je ne voudrait pas t'embêter , tu m'a déjà énormément aidé , mais pourrais tu me dire sur quelle valeur jouer pour élargir la plage de mouvement ?

Je vais essayer d'envoyer se signal à ma radio , résultat dans quelques instant .
 
Ça fonctionne avec ma radio mais le servo à la bougeotte , le signal PWM est trop lent , et je n'arrive pas à augmenter la fréquence avec "TCCR1B = 0x09; " pourtant ça fonctionnait bien avec un autre code , je passais de 490Hz à 64KHz . :(
 
Petit conseil, met serial.print() pour voir dans le serial monitor ce que te renvoi réellement le nunchuck :

valeurRetour = conversion(outbuf[3]);
serial.print(outbuf[3]);
serial.print(conversion(outbuf[3]));
analogWrite(ledPin1, valeurRetour) ;

dis moi ce que renvoie le nunchuk avant et après la fonction de conversion
 
Haut