Contrôler un robot à distance, quelle idée ! C’est bien plus amusant de le rendre autonome et d’apprendre étape par étape à améliorer son comportement.
Pour ceux qui veulent quand même utiliser une télécommande, autant le faire de manière fun avec un Nunchuck, l’accessoire de la manette Wii qui tient dans le creux de la main, avec quand même un joystick au pouce, deux boutons à l’index et au majeur, et surtout un accéléromètre trois axes.
On connaissait déjà la version classique, avec un fil pour le relier à une manette Wiimote. Il n’a pas fallu longtemps pour la faire fonctionner, les 4 fils correspondant à un bus I2C ou TWI bien connu. Vous pouvez ainsi découvrir le contrôle pan/tilt d’une pince avec un Nunchuck filaire.
Mais la version sans fil a été plus coriace et bien qu’il existe depuis plusieurs mois sur Internet des exemples de réussite, pas de piste sérieuse pour enfin y arriver.
Remerciements
Tout d’abord à Nicolas (EasyRobotics) qui m’a encouragé à continuer mes efforts.
Ensuite au site WiiBrew pour documenter dans le détail tout le fonctionnement des accessoires Wii.
Et puis bien sûr à tous ceux qui publient leur code dans les forums d’électronique, comme Michael Dreher dont j’ai retrouvé les tentatives sur l’excellent site Windmeadow Labs.
Principes
Le Nunchuck sans-fil n’est pas un produit Nintendo, il existe donc plusieurs modèles. Mais tous utilisent le même principe : un petit module à ajouter sous la Wiimote, un peu plus petit et moins design que le Wii Motion Plus.
Ce module est alimenté par la Wiimote, et il gère la communication I2C d’un côté, et sans-fil (radio 2,4 GHz propriétaire le plus souvent) avec le nunchuc
Conseil
Mon plus gros problème était la tension d’alimentation : je voulais utiliser le connecteur de TodBot permettant de brancher un accessoire Wii directement sur les 4 pattes analogiques du bord de la carte Arduino...
En fait il faut utiliser une tension de 3,3 volts. Donc bricoler un peu 4 fils : deux pour la liaison I2C, un pour la masse, un pour la tension 3,3 volts. Comme j’utilise une Arduino Uno pour tester, j’ai un connecteur avec cette tension de disponible.
Dès l’achat de votre Nunchuck sans-fil, vous pouvez faire le test : il y a généralement une lumière indiquant la bonne synchronisation entre la manette et son module radio, elle doit se faire sans aucune programmation de votre part. Alimentez, testez.
Une bonne synchronisation rapide est primordiale.
Le code source
Voici une archive contenant le sketch Arduino commenté. Rien de sorcier, il s’agit d’une reprise d’un code existant, simplifié et nettoyé pour permettre à n’importe quel débutant de le reprendre.
Les points particuliers :
// il faut redéfinir la vitesse I2C à 400 kHz au lieu des 100 kHz habituels
// pour cela on accède directement au registre TWBR du micro-contrôleur ATmega328
TWBR = ((CPU_FREQ / 400000L) - 16) / 2 ;
// boucle infinie (jusqu’à ce que ça ait marché)
while(true)
Serial.print(".") ;
// deux octets doivent être écrits dans la mémoire
// - 0x55 à l’adresse 0xF0
// - 0x00 à l’adresse 0x00
// comme la communication peut être difficile, il faut essayer jusqu’à ce que ça fonctionne
// donc on utilise le test de transmission fournit par la fonction Wire.endTransmission
// 0 signifie le succès (4 autres codes désignent différents types d’erreur, cela ne nous intéresse pas)
// premier octet
Wire.beginTransmission(ADRESSE) ;
Wire.send(0xF0) ; // adresse
Wire.send(0x55) ; // donnée.
// si le premier est passé, on essaie le second
if (Wire.endTransmission() == 0)
Wire.beginTransmission(ADRESSE) ;
Wire.send(0xFB) ;
Wire.send(0x00) ;
// on teste le second
if (Wire.endTransmission() == 0)
// tout va bien, l’initialisation est terminée, on sort de la boucle
Serial.println("C’est parti !") ;
return ;
// Réinitialiser le Nunchuck
// C’est la partie qui m’a longtemps manquée
// et que j’ai trouvée sur le forum Windmeadow Labs !
// sans trop d’explications sur ces 3-0
// peut être les ingénieurs de Nintendo sont fans de la Coupe du Monde 1998 ?
for(byte i = 0 ; i < 3 ; i++)
Wire.beginTransmission(ADRESSE) ;
Wire.send(0x00) ;
Wire.endTransmission() ;
A vous de jouer, et n’oubliez pas de partager ce que vous découvrirez.