Le présent article et la partie 2/2 du projet du jeu labyrinthe avec Arduino et Matlab (voir la partie 1/2). Nous avons abordé dans la première partie l’interface du jeu avec Matlab et comment générer un labyrinthe aléatoire en utilisant une librairie Matlab. Ici on va se focaliser particulièrement sur la liaison télécommande IR-Arduino et Arduino-Matlab. On fera également une mise à jour du programme matlab pour l’adapter à la manette infrarouge. Les objectifs du projet sont les suivants :
Savoir transférer les données entre Arduino et Matlab
Savoir utiliser une télécommande IR
Se familiariser à la programmation matlab
Etc.
Vidéo démonstration
Principe de fonctionnement
En résumé la carte arduino est analogue à une manette de jeu infrarouge sans fil constituée de 4 touches. Chaque touche sert à contrôler le déplacement du joueur dans l’interface Matlab (droite, fauche, haut et bas). La carte dispose également de quatre LED indiquant la touche active. La LED s’allume pendant 200 ms quand l’utilisateur appuie sur la télécommande IR. Ci-dessous la configuration des touches de la télécommande IR et le code correspondant (voir le projet commande IR d’un moteur à CC) .
Programme Arduino
Pinout des composants avec Arduino (voir le schéma au début de l’article)
La carte Arduino scrute le récepteur en boucle. Lorsqu’une touche de la télécommande est active, la carte Arduino communique un code sur 1 octet au logiciel Matlab via la liaison série. En effet, chaque touche de la télécommande dispose d’un code sur 3 octets. Lorsque le récepteur détecte le code, il indique la présence d’une touche. Dans notre cas uniquement 4 touches seront utilisées. Ci-dessous le tableau récapitulatif des codes reçus par la télécommande et ceux envoyés à Matlab :
Touche de la télécommande
Fonction
Code envoyé par la télécommande (HEX)
Code envoyé à Matlab (Décimal)
« 2 »
Up
0xFF18E7
150
« 8 »
Down
0xFF4AB5
160
« 4 »
Left
0xFF10EF
170
« 6 »
Right
0xFF5AA5
180
Autres
Waiting
Others
99
Programme
#include "IRremote.h"
// Numéro du pin sortie du récepteur long int res_val; const int receiver = 11;
// Indicateurs manette const int UpLED = 2; const int DownLED = 3; const int LeftLED = 4; const int RightLED = 5;
// Déclaration d'un objet IRrecv IRrecv irrecv(receiver); decode_results results;
case 0xFF4AB5: // Down digitalWrite(UpLED, LOW); digitalWrite(DownLED, HIGH); digitalWrite(LeftLED, LOW); digitalWrite(RightLED, LOW); Serial.println(160,DEC); delay(200); break;
case 0xFF10EF: // Left digitalWrite(UpLED, LOW); digitalWrite(DownLED, LOW); digitalWrite(LeftLED, HIGH); digitalWrite(RightLED, LOW); Serial.println(170,DEC); delay(200); break;
case 0xFF5AA5: // Right digitalWrite(UpLED, LOW); digitalWrite(DownLED, LOW); digitalWrite(LeftLED, LOW); digitalWrite(RightLED, HIGH); Serial.println(180,DEC); delay(200); break;
default: InitLEDs(); } }
Programme Matlab
Test de l’interface série (voir la vidéo)
Le script Matlab TestManette.m sera utilisé pour valider le bon fonctionnement de l’interface série. Son objectif est la lecture et l’affichage en boucle du contenu de l’interface série au format entier. La carte Arduino envoie le code « 99 » lorsque aucune touche n’est actionnée et un ensemble de 4 valeurs (voir le tableau ci-dessus) au moment d’appui sur la touche. Le programme ci-dessous affiche la valeur acquise lorsqu’elle est différente du « 99 ».
%% Open Serial Port
SerialCOM = Open(); % Open new port
%% Read data from Serial port
while(1) % Read data DataArduino = fscanf(SerialCOM,'%d'); if(DataArduino~=99) DataArduino end end
%% Port Delete (Previous port if exist)
Delete(SerialCOM);
Mises à jour du programme précédent
Le programme est identique au celui de la partie 1/2. Nous avons effectué une légère mise à jour. Nous avons ajouté une boucle infinie au début de la boucle principale (while(1)). Elle bloque le programme en attendant un appui sur une touche de la télécommande (voir ci-dessous).
while(1) ... % Read data from serial port (attente) while(1) DataArduino = fscanf(SerialCOM,'%d'); if (DataArduino~=99) break; end; end; ... end
Nous avons aussi utilisé une nouvelle fonction ManetteVal() qui permet de convertir la valeur acquise en un vecteur de taille quatre. Chaque case du vecteur est liée à un déplacement du joueur dans le labyrinthe (voir partie ½ du projet). Lorsqu’un champ est égal à « 1 », il indique l’activation d’un déplacement. Les champs sont égaux à « 1 » ([1 1 1 1]) dans le cas contraire (voir le script ManetteVal.m).
function Manette = ManetteVal( DataArduino )
switch DataArduino case 150 % UP Manette=[1 0 0 0]; case 160 % DOWN Manette=[0 1 0 0]; case 170 % LEFT Manette=[0 0 0 1]; case 180 % RIGHT Manette=[0 0 1 0]; otherwise Manette=[1 1 1 1]; end end
% Coordonnées de la position initiale du joueur (x0, y0) img_maze0=img_maze; im_rgb=((im2uint8(img_maze0))); pix =[236 28 36]; x_y=GetPixel(im_rgb, pix); Start_y_0=x_y(1);Start_y=Start_y_0; Start_x_0=x_y(2); Start_x=Start_x_0;
% Manette Manette=ones(1,4); Seuil_outZone=0.3;
% Positionner le joueur sur (x0, y0) img_maze0(Start_y_0:Start_y_0+N-1,Start_x_0:Start_x_0+N-1,:)=128*ones(N,N,3); im_affich=imresize(img_maze0,[512 512]); imshow(im_affich); title('Maze size 10x10'); axis square;
% Compteur pas vers la cible Cmp_cible=0; Out_zone_pinal=2; figure(1);
while(1)
% Read data from serial port (attente) while(1) DataArduino = fscanf(SerialCOM,'%d'); if (DataArduino~=99) break; end; end;
% Obtenir le vecteur Manette Manette = ManetteVal( DataArduino );
% Extraction des valeurs Down =Manette(1); Up=Manette(2); Right =Manette(3); Left=Manette(4);
% Déplacement if Up~0 Start_y=Start_y_0+Pas; elseif Down~0 Start_y=Start_y_0-Pas; if Start_y <=0 Start_y=1; end; end; if Right~0 Start_x=Start_x_0+Pas; elseif Left~0 Start_x=Start_x_0-Pas; if Start_x <=0 Start_x=1; end; end;
Nous utilisons des technologies telles que les cookies pour stocker et/ou accéder aux informations relatives aux appareils. Nous le faisons pour améliorer l’expérience de navigation et pour afficher des publicités (non-)personnalisées. Consentir à ces technologies nous autorisera à traiter des données telles que le comportement de navigation ou les ID uniques sur ce site. Le fait de ne pas consentir ou de retirer son consentement peut avoir un effet négatif sur certaines fonctonnalités et caractéristiques.
Fonctionnel
Toujours activé
Le stockage ou l’accès technique est strictement nécessaire dans la finalité d’intérêt légitime de permettre l’utilisation d’un service spécifique explicitement demandé par l’abonné ou l’utilisateur, ou dans le seul but d’effectuer la transmission d’une communication sur un réseau de communications électroniques.
Préférences
L’accès ou le stockage technique est nécessaire dans la finalité d’intérêt légitime de stocker des préférences qui ne sont pas demandées par l’abonné ou l’internaute.
Statistiques
Le stockage ou l’accès technique qui est utilisé exclusivement à des fins statistiques.Le stockage ou l’accès technique qui est utilisé exclusivement dans des finalités statistiques anonymes. En l’absence d’une assignation à comparaître, d’une conformité volontaire de la part de votre fournisseur d’accès à internet ou d’enregistrements supplémentaires provenant d’une tierce partie, les informations stockées ou extraites à cette seule fin ne peuvent généralement pas être utilisées pour vous identifier.
Marketing
Le stockage ou l’accès technique est nécessaire pour créer des profils d’utilisateurs afin d’envoyer des publicités, ou pour suivre l’utilisateur sur un site web ou sur plusieurs sites web ayant des finalités marketing similaires.