[Tuto] Nunchuck et servo moteur

Nunchuck et Servo moteur

Le but de ce montage est commander un servo moteur à l’aide d’un Nunchuck (Manette de Nintendo Wii). Cet exemple vous montrera comment intégrer d’autres objets à votre montage. Ceci est une adaptation du montage http://tutoarduino.com/comment-controler-un-servomoteur-avec-un-nunchuck-de-wii

Composants nécessaires :

 
composants

Fonctionnement du Nunchuck :

La Nunchuck communique avec la manette Wii en I2C. Ce protocole est également utilisé dans le montage mettant en œuvre 2 Arduinos. La librairie « wire » simplifie l’usage de l’I2C.

Pour fonctionner le Nunchuck doit être connecté à 4 signaux :

  • SCL ↔ Analog 5 du Arduino

  • SDA ↔ Analog 4 du Arduino

  • 3,3V

  • GND

Pour simplifier son câblage, un accessoire existe (Voir ci-contre). Sans cet outillage le câblage est assez complexe.

cablage

nunchuck-cable-schema

 

arduino_accessories_wiichuck_2

Fonctionnement du montage :

La Nunchuck est relié comme périphérique I2C.

Le servo moteur est connecté à une sortie PWM. Les sorties PWM sont indiquées sur le Arduino. Ce sont Digital 3, 5, 6, 9, 10, 11. Les signaux PWM sont des signaux carrés qui permettent la commande de divers éléments comme les servo moteurs.

Dans l’exemple nous utiliserons la PWM de la borne Digital 11.

arduino-nunchuck-servo-schema

Réalisation du montage :

Le montage est entièrement réalisable sur la breadboard. Le servo moteur doit être connecté par 3 fils au Arduino :

  • 5V ↔ Rouge

  • PWM ↔ Orange

  • GND ↔ Gris ou marron

 
arduino-nunchuck-servo-platine

Programmation du montage :

Les informations envoyées via I2C par la Nunchuck comprennent les valeurs d’accélération de tous les axes (X, Y et Z).

Les informations numériques sont codées en une succession de 0 et 1. Chaque chiffre est appelé un bit. Un paquet de 8 bits est appelé octet. La Nunchuck envoie 6 octets présentés comme ceci :

  • Octet 1 :

    • Position du joystick sur l’axe x

  • Octet 2 :

    • Position du joystick sur l’axe y

  • Octet 3 :

    • Accélération sur l’axe x bit 9 à 2

  • Octet 4 :

    • Accélération sur l’axe y bit 9 à 2

  • Octet 5 :

    • Accélération sur l’axe z bit 9 à 2

  • Octet 6 :

    • Accélération sur l’axe z bit 1 et 0

    • Accélération sur l’axe y bit 1 et 0

    • Accélération sur l’axe x bit 1 et 0

    • Statut du bouton C

    • Statut du bouton Z

axe
nunchuck_data__1d73fa__

Le programme du Arduino va lire la valeur de l’accélération sur l’axe Y du Nunchuck grâce à la liaison I2C et faire tourner le servo moteur en lui envoyant une commande angulaire grace à la librairie « Servo ».

La valeur des accélérations est codée sur 10 bits et coupée en 2 parties : les bits de 9 à 2 dans un octet et les bits 1 et 0 dans un autre octet.

#include 
#include 

// Doit être ajusté en fonction de chaque nunchuck
#define ZEROX 530
#define ZEROY 530
#define ZEROZ 530

// adresse I2C du nunchuck
#define WII_NUNCHUK_I2C_ADDRESS 0x52

// définition d'une variable Servo
Servo servomoteur;

// définition d'une variable counter
int counter;

// définition d'un tableau de données
uint8_t data[6];

void setup()
{
// on attache le servomoteur à la pin 11 (PWM)
servomoteur.attach(11);

// initialisation du nunchuck
Wire.begin();

Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0xF0);
Wire.write(0x55);
Wire.endTransmission();

Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0xFB);
Wire.write(0x00);
Wire.endTransmission();
}

void loop()
{
// on demande 6 octets au nunchuck
Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, 6);

counter = 0;
// tant qu'il y a des données
while(Wire.available())
{
// on récupère les données
data[counter++] = Wire.read();
}

// on réinitialise le nunchuck pour la prochaine demande
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();

if(counter >= 5)
{
// on extrait les données
// dans mon exemple j'utilise uniquement les données d'accélération sur l'axe Y
double accelX = ((data[2] << 2) + ((data[5] >> 2) & 0x03) - ZEROX);
double accelY = ((data[3] << 2) + ((data[5] >> 4) & 0x03) - ZEROY);
double accelZ = ((data[4] << 2) + ((data[5] >>; 6) & 0x03) - ZEROZ);

// on limite la valeur entre -180 et 180
int value = constrain(accelY, -180, 180);
// on mappe cette valeur pour le servomoteur soit entre 0 et 180
value = map(value, -180, 180, 0, 180);
// on écrit sur le servomoteur la valeur
servomoteur.write(value);

// un petit delai pour pas saturer le servomoteur
delay(100);
}
}

Il reste à brancher le Arduino pour compiler le programme et le téléverser.

Pour aller plus loin :

Il est possible de rendre autonome le montage en lui ajoutant un coupleur de pile. Il est aussi possible d’ajouter un second mouvement ou action (Allumer une LED par exemple) sur un autre axe. On peut modifier le programme pour utiliser les informations des joysticks.

Il reste à brancher le Arduino pour compiler le programme et le téléverser.

Pour aller plus loin :

Il est possible de rendre autonome le montage en lui ajoutant un coupleur de pile. Il est aussi possible d’ajouter un second mouvement ou action (Allumer une LED par exemple) sur un autre axe. On peut modifier le programme pour utiliser les informations des joysticks.