Linear Feedback Shift Register with VHDL.
La lecture du livre Arduino Cookbook m'a décidé à essayer d'interfacer cette manette Nintendo appelée Nunchuk qui est utilisé avec la console Wii. La manette qui utilise le bus I2C pour communiquer dispose d'un joystick 2 axes, d'un accéléromètre 3 axes et de deux bouttons classiques (appelés C et Z). J'ai bien sûr démonté (ou presque...) proprement le connecteur propriétaire et récupérer les 4 fils VCC (rouge), GND (blanc), SDA (vert) et SCL (jaune). Voici les quelques photos prises ce pluvieux dimanche 25 juin.
Il faut tout d'abord savoir qu'il existe sur le marché deux types de manettes Nunchuk que rien ne distingue en apparence, la manette officielle Nintendo et la manette générique non-officielle. Tout d'abord PRENEZ GARDE aux couleurs des cables, si vous avez un doute, regardez de face le connecteur comme sur cette image. Ensuite la manette générique (celle que j'ai utilisé pour le montage) ne fonctionne pas avec les séquences habituelles d'initialisation et de communication fournies dans le livre Arduino Cookbook et sur ce site web qui traite pourtant spécifiquement de la connexion de la manette avec la platine beaglebone.
Il m'a fallu une après-midi de bidouillage pour isoler le problème et ainsi partir rechercher si il existait d'autres "codes" pour établir la communication, c'est là que j'ai compris que selon qu'on avait affaire à une manette officielle ou non, il y avait une différence.
Ce qui suit va donc traiter de l'interfaçage d'une manette Nunchuk générique no-name comme disent les anglo-saxons. Je pars du principe que vous avez déjà lu et compris la Partie 2 de ce site sur le bus I2C.
Je connecte donc le cable rouge de la manette sur la patte VDD_3V3 de la platine, le cable blanc sur la patte GND, le cable vert (SDA) sur la patte P9_20 (I2C2_SDA) et le cable jaune (SCL) sur la patte P9_19 (I2C2_SCL). Les pattes P9_19 et P9_20 sont déjà paramétrées avec les résistances de tirage Pull Up internes activées donc il n'y a pas besoin d'en rajouter.
Selon la documentation trouvée sur le web, la manette doit apparaître sur l'un des bus I2C à l'adresse 0x52.
root@beaglebone:~# i2cdetect -y -r 3 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- 52 -- UU UU UU UU -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --Nous avons donc notre Nunchuk "reconnue" sur le bus 3 à l'adresse 0x52. Pour la suite je me suis inspiré de ce projet (anglais) pour la platine Beagleboard, la grande soeur de la Beaglebone. Si vous ne parlez pas du tout anglais ce n'est pas grave ;)
Tout d'abord ce projet utilise les bonnes commandes d'initialisation de la manette, enfin disons plutôt les commandes adéquates pour TOUT type de manette Nunchuk. C'est important car la plupart des manettes d'occasion à 5 eur que l'on trouve sont des manettes génériques. Et ce serait bête de jeter votre manette en pensant qu'elle est HS alors que pour 5 eur, on a droit à un joystick et un accéléromètre entre autres !
Placez vous dans votre répertoire maison et entrez ces commandes qui permettent de télécharger et d'installer le projet.
root@beaglebone:~# wget http://elinux.org/images/4/41/Beagleboard_trainer_chuk.tgz Connecting to elinux.org (140.211.166.147:80) Beagleboard_trainer_ 100% |****************************************************| 13996 0:00:00 ETA root@beaglebone:~# tar -xvf Beagleboard_trainer_chuk.tgz trainer_chuk/ trainer_chuk/chuk_com.c trainer_chuk/beagleboard_trainer_chuk.tar.gz trainer_chuk/chuk_trainer.c trainer_chuk/chuk_trainer trainer_chuk/chuk_trainer.h
Essayons maintenant de lancer le programme (en langage C) chuk_trainer après s'être placé dans le répertoire créé précédemment.
root@beaglebone:~# cd trainer_chuk root@beaglebone:~/trainer_chuk# ./chuk_trainer Failed to open the bus.
Tiens encore un problème ;) Une petite vérification sur le fichier chuck_com.c nous montre qu'il faut changer le bus I2C No 2 pour le bus I2C No 3. Il y a donc une seule et unique ligne à modifier dans le fichier chuck_com.c, c'est la ligne 48 où il faut remplacer sprintf(filename, "/dev/i2c-2"); par sprintf(filename, "/dev/i2c-3"); tout simplement !
L'un des fichiers du projet a été modifié, il faut donc recompiler et reconstruire à nouveau ! Si vous ne connaissez pas le langage C, pas de problème, tapez les commandes ci-dessus pour compiler puis construire le fichier exécutable (programme) chuk_trainer.
root@beaglebone:~/trainer_chuk# gcc -c chuk_trainer.c chuk_com.c root@beaglebone:~/trainer_chuk# gcc -o chuk_trainer chuk_trainer.o chuk_com.o root@beaglebone:~/trainer_chuk# ./chuk_trainer Opened /dev/i2c-2 Comm to chuk is open. I2C send buf[1] success. I2C send buf[2] success. Joy_x: 129, Joy_y: 128, Accel_x: 317, Accel_y: 508, Accel_z: 586, B_Z: 1, B_C: 1
C'est gagné ! Vous pouvez par exemple bouger la croix et voir les valeurs qui varient de 0 à 255 (128 étant le centre approximatif). Vous pouvez aussi appuyer sur les deux touches C et Z, et voir les valeurs codées sur 10 bits varier sur les 3 axes de l'accéléromètre entre 150 et 875 selon l'inclinaison de la manette sur les axes x, y et z.
Il est bien sûr préférable de connaître un peu le langage C pour comprendre le fonctionnement (assez simple cependant) de la lecture des 6 octets renvoyés par la manette. Allez jeter un oeil sur les deux fichiers et surtout sur chuk_com.c pour comprendre "l'étrange façon" dont les données sont renvoyées ;) En effet les 2 premiers octets comportent les valeurs des axes x et y du joystick mais les 3 octets suivants ne comportent que les 8 bits significatifs des 10 bits de chaque axe x y z de l'accéléromètre. Le dernier octet comprends donc les 2 bits liés au deux boutons C et Z puis les 2 bits restants de chaque axe x y z de l'accéléromètre.
D'ailleurs ce petit script shell rapide nunchuk.sh nous permets de lire les valeurs de x et y du joystick comprises entre 0 et 255 et de vérifier la pression ou non sur l'un des 2 boutons poussoirs (Quittez la boucle en appuyant sur le gros bouton Z).
#!/bin/sh # nunchuk.sh # réveil de la manette i2cset -y 3 0x52 0xF0 0x55 b i2cset -y 3 0x52 0xFB 0x00 b boutonZ=1; while [ $boutonZ -ne 0 ]; do clear # initialisation nécessaire avant chaque lecture i2cset -y 3 0x52 0x00 0x00 b # on ne lit que les 2 premiers octets (valeur x y joystick) var1=$(i2cget -y 3 0X52 0x00 b) printf 'Axe X joystick: %d\n' $var1 var2=$(i2cget -y 3 0x52 0x01 b) printf 'Axe Y Joystick: %d\n' $var2 # on lit le dernier octet et on ne prend que les 2 premiers bits var3=$(i2cget -y 3 0X52 0x05 b) printf 'Bouton Z: %d\n' $(( var3 & 0x01 )) printf 'Bouton C: %d\n\n' $(( var3 & 0x02 )) boutonZ=$(( var3 & 0x01 )) sleep 0.2 done
En résumé, pour 5 eur sur le marché de l'occasion, vous avez une superbe télécommande filaire entre les mains pour commander des servos ou autres bras articulés ! Encore une fois, merci Nintendo ;) et surtout merci les gars pour la Beaglebone, super petit bijou.