Arduino #1 : fabrique ta (presque) wiimote!

Je vous propose un petit retour sur mes expérimentations autour de Arduino. On va créer une mini wiimote maison. Si si ! (Bon sans les boutons hein !)
Pour ce petit tuto nous aurons besoin de :
- Un microcontrôleur Arduino
- Un accéléromètre (le « 3 axes » de Sparkfun est très bien)
- Un jeu de connecteur mâle.
- Un peu d’étain
- Un fer a souder pas pourri (ca vous évitera de transpirer pour souder, comme j’ai pu le faire…)
Compter 26euros pour la platine Arduino USB de base, une 20euros pour l’accéléromètre, et 35 centimes les 20 connecteurs. L’étain et le fer à souder ce trouvent chez votre papa/oncle/pote/voisin (sinon chez votre pépé).
Si vous êtes guerrier, des platines Bluetooth existent, et des extensions super fun pour votre board (un mini écran tactile, un pack batterie lithium,….) Mais là on va faire simple pour cette article. Pour le reste, on verra plus tard.
Un peu d’électronique
En premier, nous devons souder les broches sur l’accéléromètre, histoire de pouvoir le fixer sur le microcontrôleur.

Noter la qualité incroyable de la soudure.
Ensuite, il faut fixer l’accéléromètre sur la platine. Arduino a 5 « pins » de connexion analogique. Il suffit de placer l’accéléromètre dessus. Le plus dur est de ne pas se tromper de sens.
![]() |
![]() |
Vous pouvez prendre un café.
Ardu, I know
Nous avons donc une magnifique platine, qui ne sait pas encore qu’elle a plein de talents pour se mouvoir gracieusement. Nous allons y remédier.
Note préliminaire
Nous avons fait les bricoleurs du Dimanche, mais je n’ai pas parlé de ce qu’est Arduino. C’est une plateforme de prototypage open source. C’est à dire un bidule électronique, qui vous sert de base pour tester un assemblage d’autres bidules électronique, plus ou moins complexe. C’est utilisé pour tout et n’importe quoi: la mise au point de carte électronique, la création de robot, l’utilisation dans l’univers artistique ou du modélisme (rien a voir, mais c’est ce que je fait). Donc une platine électronique. Avec une EEPROM que l’on peut programmer facilement, grâce à un jeu de libraire fourni.
La Programmation Arduino est basé sur Processing. C’est en fait du Java, version pas chiant, ou tout ce dont vous avez besoin est déjà là. Exit donc les Maven, Nexus et autre repository. On est là pour coder rigolo. (Ce qui ne vous empêche pas d’utiliser une librairie Java dans Processing, en la collant dans le répertoire des librairies: ça marche)
Les liens qui vont bien :
- Le site officiel : http://www.arduino.cc/
- Getting Started, à lire de préférence, et surtout pour l’installation du driver pour la Board :
- Tutos et description des API standards
Un programme Arduino s’articule autour de 2 fonctions principales : setup() qui va initialiser des trucs, et loop() qui va exécuter du code en boucle.
setup
Comme nous ne voulons pas que la platine fasse l’autiste, et qu’elle nous parle, nous allons lui demander d’envoyer des infos sur le port série.
void setup()
{
// initialize the serial communications:
Serial.begin(9600);
}
9600 est le port sur lequel la platine va balancer ces infos le débit, en bit/seconde (baud) de la transmission sur le port série. Vous pouvez choisir n’importe quelle autre port, ça ne me fait rien.
Il faut ensuite lui indiquer quelle sont les « pins » qui vont l’alimenter (ouai, elle est un peu con con, mais c’est comme çà).
const int groundpin = 18;
const int powerpin = 19;
void setup()
{
// initialize the serial communications:
Serial.begin(9600);
// initialize pins on the board
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);
}
loop
Dans cette boucle, nous allons lui demander de lire les infos analogiques via la méthode analogRead( pinNumber );
Nous allons aussi « lisser » ces valeurs. Les valeurs analogiques sont exprimées en millivolts: c’est la variation électrique du circuit qui nous est restituée. Comme le circuit est très précis, les variations sont importantes. Il est donc utile de lisser les nouvelles valeurs par rapport aux anciennes. J’utilise un algorithme très simple. Pour plus de précision, il serait intéressant d’intégrer des formules de lissage plus complexes. Si vous avez des électroniciens autour de vous, ils pourront vous en parler.
Enfin, nous envoyons ces valeurs sur le port série.
Le code complet :
const int groundpin = 18; // analog ground pin
const int powerpin = 19; //
const int xpin = 3; // x-axis of the accelerometer
const int ypin = 2; // y-axis
const int zpin = 1; // z-axis (only on 3-axis models)
int sensorx, sensory, sensorz = 0; // store the values
int smoothedx, smoothedy, smoothedz = 0; // smoothed results
int precision = 5; // amount of precision
void setup()
{
// initialize the serial communications:
Serial.begin(9600);
// initialize pins on the board
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);
}
void loop()
{
// read analogic data from input pin
sensorx = analogRead(xpin);
sensory = analogRead(ypin);
sensorz = analogRead(zpin);
// smothing values
smoothedx = smoothedx + ((sensorx - smoothedx)/precision);
smoothedy = smoothedy + ((sensory - smoothedy)/precision);
smoothedz = smoothedz + ((sensorz - smoothedz)/precision);
// send values on the Serial port
Serial.print(smoothedx);
Serial.print(",");
Serial.print(smoothedy);
Serial.print(",");
Serial.print(smoothedz);
Serial.println();
delay(10);
}
On ajoute à la fin le delay(10); qui lui indique de cadencer la boucle loop toute les 10 millisecondes.
Il ne vous reste plus qu’a uploader ce code dans votre platine. Toutes les infos sous ce lien.
Un peu de Processing
Ce qu’il y a de bien avec Processing, c’est qu’on peut faire ce que l’on veut avec. Du joli graphisme, à la reprogrammation de votre Micro-Onde pour qu’il congèle plus vite, vous avez de quoi faire. Là nous allons écouter le port série de notre platine Arduino pour lire les informations analogiques envoyées, et en faire quelque chose.
L’IDE Processing se télécharge ici.
Les étapes :
- Lister les ports série ouverts;
- Se connecter sur celui qu’on veut;
- Ecouter les événements provenant du port série;
- Faire des trucs avec les données reçues.
Processing c’est comme pour Arduino (normal c’est la même chose). Vous avez 2 fonctions principales : setup() et draw() (équivalent à loop() chez Arduino).
RE:setup
Pour le truc, nous allons initialiser une scène OpenGL (pour au final afficher un cube, et le faire bouger). Super!
void setup() {
size( 800, 800, OPENGL );
}
Pour se connecter au port série, c’est extrêmement simple, Processing dispose d’une lib faite pour ça : processing.serial. Pour trouver le bon port, nous allons lister les ports série ouverts. Dans mon cas, la platine se connecte sur le port 0. Il suffit de récupérer le nom du port, créer une connexion série, et l’initialiser :
void setup() {
size( 800, 800, OPENGL );
println( Serial.list() );
String usbPort = Serial.list()[0];
port = new Serial(this, usbPort, 9600);
port.bufferUntil('\n');
port.write(65);
}
Et je l’écoute comment le port série?
Très bonne question ! En fait Processing et la librairie serial expose le port série entrant via la fonction serialEvent(Serial port). Vous n’avez pas de point d’écoute à monter. C’est magique, c’est pas chiant.
Arduino nous envoie les valeurs sous forme de texte comme ceci : « valeurX,valeurY,valeurZ ». Nous devons donc lire le port série, et découper le texte, comme ci-dessous :
void serialEvent(Serial port) {
String serialStr = port.readStringUntil('\n');
serialStr = trim(serialStr);
int values[] = int(split(serialStr, ','));
...
Plus qu’a lire les infos contenu dans le tableau values[]
(voir plus bas pour le code complet)
draw (comme loop en fait)
Pour le cube 3D, il faut placer un point de vue virtuel au centre de la scène, placer une lumière, créer le cube, rotationner le point de vue en fonction des valeurs de l’accéléromètre, et lui dire de recommencer toutes les 100 millisecondes. Ouf ! ça c’est de la phrase ! Heureusement en terme de code c’est moins long :
void draw() {
background(0);
stroke(255);
translate(800/2,800/2,0);
lights();
rotateX(xvalue);
rotateY(yvalue);
box(300,300,300);
delay(100);
}
super total
Le code complet pour la partie processing :
import processing.net.*;
import processing.opengl.*;
import processing.serial.*;
Serial port;
byte zero = 0;
float xvalue = 0;
float yvalue = 0;
float zvalue = 0;
void setup() {
size( 800, 800, OPENGL );
println( Serial.list() );
String usbPort = Serial.list()[0];
port = new Serial(this, usbPort, 9600);
port.bufferUntil('\n');
port.write(65);
}
void draw() {
background(0);
stroke(255);
translate(800/2,800/2,0);
lights();
rotateX(xvalue);
rotateY(yvalue);
box(300,300,300);
delay(100);
}
void serialEvent(Serial port) {
String serialStr = port.readStringUntil('\n');
serialStr = trim(serialStr);
int values[] = int(split(serialStr, ','));
if( values.length == 3 ) {
xvalue =calculate( values[0], 512 );
yvalue = -calculate( values[1], 500 );
}
}
float calculate( float returnValue, int baseValue ) {
float diff = returnValue - baseValue;
returnValue = (diff*90) / 115;
// to radian
returnValue = PI*returnValue/180;
// trunc value
returnValue = round( returnValue*100 );
returnValue = returnValue /100;
return returnValue;
}
Dans la fonction calculate, qui transforme les valeurs en volt vers des valeurs angulaires, vous verrez un truc bizarre. Je divise par 115 un nombre. Ce n’est pas du pifomètre ! En fait cette valeur correspond à la moitié de la variation en volt des valeurs. Plus clairement : Les valeurs analogiques varient entre un minimum et un maximum. Sur mon accéléromètre (un ADXL 335), les valeurs X et Y on une variation de 330 millivolts, avec comme valeur médiane 512 millivolts (soit une valeurs comprise entre 397 et 627 millivolts). Tout ceci est fonction de votre accéléromètre. Il vous faudra donc farfouiller dans les spécifications du circuit, qui doivent être disponibles là où vous l’achetez, pour connaître ces variations.
Jouons !
Voilà !
Connectez votre platine, lancez votre programme Processing, et faites bouger le cube avec « rythm ».
Vous l’aurez peut être remarqué : je n’utilise que 2 axes de l’accéléromètre (x et y). Pour obtenir une information correcte sur l’axe z, il s’avère nécessaire d’avoir un gyroscope électronique : un DOF (Degree Of Liberty) comme on les appelle. Il en existe plein : 3DOF, 5DOF, … ils peuvent s’utiliser couplés à un accéléromètre, en connectant les axes du DOF et ceux de l’accéléromètre sur les mêmes « pins » analogiques de la board Arduino. Les calculateurs des 2 circuits, travaillant ensemble, vous retourneront les bonnes valeurs spatiales de la platine. Je vous ferais un p’tit article sur le sujet si cela vous intéresse.
2ème remarque, que vous avez forcement remarqué : je n’ai JAMAIS mis les mots FLASH ou FLEX dans cet article. « Ouaaa ! Quel exploit! », « merci, merci! Cela m’a demandé beaucoup d’entraînement ». Rassurez vous : le prochain article va vous expliquer comment utiliser tout ce biniou électronique avec votre actionscript préféré, et surtout comment faire VOTRE serveur de port série. Classe ! (et finalement j’aurais quand même placer ces mots… Je suis faible)
Je vous invite fortement à lire (et écouter) Vincent Maitray dans ces UNBELIEVABLE articles (featuring Nicolas Gans) concernant Arduino. Ca va loin, et vous aurez absolument toutes les cartes en main pour ajouter des p’tits boutons et avoir au final une VRAI wiimote « made by me ».
Sinon vous avez un autre montage, version poilu, de « la Grotte du Barbu » sous ce lien.
Tags: Arduino, Processing



--> 7 avril 2010 ( 10:11 )
vous êtes un grand malade monsieur.
je me le garde sous le coude pour quand je serai devenu un inventeur génial ^^
--> 7 avril 2010 ( 10:37 )
Un autre article qui rox
Félicitation boyz !
--> 23 septembre 2010 ( 16:19 )
Petits correctifs
Serial.begin(9600) ne permet de choisir le port, mais son débit.
cf. http://www.arduino.cc/en/Serial/Begin
L’arduino n’a qu’un port, le choix est vite fait
Le « delay(10); » serai probablement plus utile dans la méthode loop.
Car la méthode « setup » n’est executée qu’une fois, le delai ne sera appliqué qu’une fois, et encore probablement avant les itérations de loop.
Petit conseil :
La fenetre de lissage est vraiment grande lorsque la variable ‘précision’ a une petite valeur.
Et comme tous les échantillonnages sont communiqués, il vaudrai mieux laisser faire le lissage par l’ordinateur, il calcule bien plus vite et cela lui laisse un boulevard pour effectuer des filtrages sioux.
Merci pour l’article.
--> 23 septembre 2010 ( 20:28 )
@ PaulBalez : Ahh! Les erreurs du débutant, trop pressé pour lire la doc correctement!
Effectivement, le delay est bien plus utile dans la loop.C’est d’ailleurs ce que j’avais fait sur Processing, et pas corrigé sur la partie Arduino… Je corrige tout ça !
Je suis intéressé si tu as des méthodo de lissage des valeurs analogiques!
Merci pour ce retour, et ces précisions.
--> 7 novembre 2010 ( 5:34 )
Salut salut !!
Après avoir vu et revu tout ça, une question se pose
C’est quoi le nom des broches en anglais ? J’en vois 50 différentes sur plusieurs sites et je suis pas sur de ce que je dois prendre pour créer la connectique du capteur
Merci !