¤ CONTRÔLE GESTIQUE ¤

Porteur(s) du projet : Julien Warin

Date : Mars 2017

Contexte : Cours de programmation

programmes : Arduino + Processing

Ce projet qui emploi 2 types de programmes, Arduino et Processing, vise à montrer comment par le biais de la captation de gestes via le capteur de mouvement sur Arduino, il est possible d'influencer les particules qui retranscrivent l'image de la webcam sur Processing. La volonté d'employer un capteur de mouvement est en lien avec mon mémoire porté sur le geste et l'interactivité. C'est pourquoi travailler dessus, m'a permis de voir les points forts et les points faibles que peuvent apporter les 2 logiciels de programmations.

NB : afin de pouvoir faire fonctionner correctement les programmes, il faut tout d'abord télécharger quelques librairies afin de rendre possible la retranscription de la webcam via processing, mais aussi de faire fonctionner le capteur. C'est pourquoi, je vous conseille de vous rendre à l'onglet “ressources” ce trouvant en bas de la page et qui vous permettra de vous procurer tout les éléments nécessaires à la réalisation de ce projet.

¤ PROGRAMMES ¤

Processing : en ce qui concerne le programme de processing, il vous vaudra plusieurs choses. la bibliothèque vidéo que vous pourrez télécharger sur processing en vous rendant dans “sketch > librairie > importer une librairie > taper vidéo dans la barre de recherche > cliquer sur télécharger en bas à droite > fermer processing puis le réouvrir”. Une fois la librairie importer, copier le programme ci-dessous puis créer une class en cliquant sur la flèche à côté de l'onglet de votre programme puis copiez le code suivant.

Code Processing webcam

//librairies
import processing.video.*; //import librairie vidéo
Particle[] particles;
Capture cam;//PImage cam;
import processing.serial.*; //import librairie serial pour arduino
Serial myPort; // créé un objet sérial myPort
// Déclaration des variables globales
int val;// Data reçue/envoyée dans le port
color c1 = color(39, 23, 229);
void setup() { // initialiser les variables et initialisation des paramètres d'affichage
size(640, 360); //taille d'affichage
cam = new Capture(this, width, height);//création de la caméra, prend la taille de la taille d'affichage en largeur et hauteur
cam.start();//caméra fonctionne
particles = new Particle [1000]; //création des particules + nombres de particules affichées
for (int i = 0; i < particles.length; i++) {
particles[i] = new Particle();
}
background(0);
String portName = Serial.list()[5];// va chercher/voir dans le port 0 = peut être modifié (1,2,3,...)
myPort = new Serial(this, portName, 9600);//9600 doit être pareil que dans le fichier arduino sinon ne marche pas
}
//affiche la vidéo/capture de la caméra
void captureEvent(Capture video) {
video.read();
}
void draw() {
if ( myPort.available() > 0) { // si la donnée est valide,
val = myPort.read(); // la valeur dans myPort est lu
}
if(val == 65){ //65 = A dans arduino à cause de l'ASCII = http://www.asciitable.com/
rect(0, 0, 640, 360);
filter(INVERT); //filter = réaliser un effet sur une image, une vidéo, ...
}
/* autre possibilité
if(val ==66){
filter(THRESHOLD);
}
*/
for (int i = 0; i < particles.length; i++) {//boucle : i = 0, si i est plus petit que la que la limite des particules, alors i est incrémenté
particles[i].display(); //activation de void display dans la classe particle
particles[i].move(); //activation de void move dans la classe particle
//particle[i].size(); possibilité de jouer sur la taille des particules
}
}

Code Processing particles_class

//création de la class particles
class Particle {
// Déclaration des variables globales
float x; //variables x = abscisses
float y; //variables y = ordonnées
float sizeX = 12; //variable taille x
float sizeY = 12;//variable taille y
float vx;
float vy;
//constructeur
Particle() {
x = width/2;
y = height/2;
float a = random(TWO_PI);
float speed = random(1,4);//vitesse déplacement particules
vx = cos(a)*speed;
vy = sin(a)*speed;
}
void display() { //méthode pour afficher les particules
noStroke(); //sans contour
color c = cam.get(int(x),int(y));//instanciation de la variable couleur + chaque particules va prendre la couleur en x et y de la capture de la cam
fill(c,25); //c = variable color + 25 = transparence
ellipse(x, y, sizeX, sizeY);//taille particules
}
void move() { //méthode pour faire bouger les particules + collision
x = x + vx;//random(-5, 5);
y = y + vy;//random(-5, 5);
if (y < 0) {
y = height;
}
if (y > height) {
y = 0;
}
if (x < 0) {
x = width;
}
if (x > width) {
x = 0;
}
}
/* modifier la taille des particles
void size(){
if(val == 65){
sizeX = + 1;
sizeY = + 1;
}
else if(val == 66){
sizeX = - 1;
sizeY = - 1;
}
}
*/
}

Arduino : Maintenant en ce qui concerne Arduino, je vous conseille donc de vous rendre dans l'onglet “ressources” en bas de la page afin de télécharger la librairie qui vous permettra de faire marcher le programme. Pour importer une librairie dans Arduino, il vous faudra déposer le dossier de la librairie du capteur geste dans le dossier “libraries”, ce trouvant lui aussi dans un dossier “Arduino” qui ce trouve dans le dossier “documents” (voir image ci-dessous).

Après avoir ajouter la librairie, il ne vous restera plus qu'à “téléverser” votre programme vers la carte Arduino, puis d'ouvrir le moniteur de série afin de s'assurer que le programme fonctionne.

NB : quand vous voulez afficher votre travail sur Processing, pensez à fermer la fenêtre “moniteur de série”, sinon votre travail ne ce lancera pas.

#include <Wire.h>// permet de communiquer avec les composants utilisant le protocole I2C / TWI
#include "paj7620.h" //librairie du capteur
/*
Notice: Lorsque vous souhaitez reconnaître le geste Forward / Backward ou d'autres gestes continus, le temps de réaction de vos gestes doit être inférieur à GES_REACTION_TIME (0.8s).
Vous pouvez également régler le temps de réaction en fonction de la circonstance réelle.
*/
#define GES_REACTION_TIME	8 //reaction du capteur
#define GES_QUIT_TIME	10 //temps avant de répéter l'action = delay
void setup()
{
uint8_t error = 0;
Serial.begin(9600); //Fixe le débit de communication en nombre de caractères par seconde
Serial.println("\nPAJ7620U2 TEST DEMO: Recognize 15 gestures.");
error = paj7620Init();	// initialisation du Paj7620
if (error)
{
Serial.print("INIT ERROR,CODE:");
Serial.println(error); //Affiche les données sur le port série suivi d'un caractère de "retour de chariot"
}
else
{
Serial.println("INIT OK");
}
Serial.println("Please input your gestures:");
}
void loop()
{
uint8_t data = 0, data1 = 0, error;
error = paj7620ReadReg(0x43, 1, &data); // Read Bank_0_Reg_0x43/0x44 for gesture result.
if (!error)
{
//switch/case = pareil que if/else mais plus flexible, si durant le procesus, la donnée est "vraie" et rencontre "break", le loop s'arrête
// Lorsque différents gestes sont détectés, la variable «données» sera définie sur différentes valeurs par paj7620ReadReg(0x43, 1, &data).
switch (data)//permet au programmeur de construire une liste de "cas" (ou possibilités) à l'intérieur d'accolades.
{
case GES_RIGHT_FLAG: //Si l'instruction break n'est pas trouvée après avoir exécuté le code d'une condition vraie, le programme continuera à tester les conditions restantes parmi les cas restants.
delay(GES_REACTION_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_LEFT_FLAG)
{
Serial.println("Right-Left");
}
else if(data == GES_FORWARD_FLAG)
{
Serial.println("forward");
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
delay(GES_QUIT_TIME);
}
else
{
Serial.println("A");//right = A = 65 sur processing (à cause de l'ASCII
}
break; //Sans une instruction break, l'instruction switch continuera à exécuter les expressions suivantes
case GES_LEFT_FLAG:
delay(GES_REACTION_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_RIGHT_FLAG)
{
Serial.println("Left-Right");
}
else if(data == GES_FORWARD_FLAG)
{
Serial.println("forward");
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
delay(GES_QUIT_TIME);
}
else
{
Serial.println("B");//left = A = 66 sur processing (à cause de l'ASCII
}
break;
//break;
case GES_UP_FLAG:
delay(GES_REACTION_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_DOWN_FLAG)
{
Serial.println("Up-Down");
}
else if(data == GES_FORWARD_FLAG)
{
Serial.println("forward");
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
delay(GES_QUIT_TIME);
}
else
{
Serial.println("C");//up = A = 67 sur processing (à cause de l'ASCII
}
break;
case GES_DOWN_FLAG:
delay(GES_REACTION_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_UP_FLAG)
{
Serial.println("Down-Up");
}
else if(data == GES_FORWARD_FLAG)
{
Serial.println("forward");
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
delay(GES_QUIT_TIME);
}
else
{
Serial.println("down");//down
}
break;
case GES_FORWARD_FLAG:
delay(GES_REACTION_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_BACKWARD_FLAG)
{
Serial.println("Forward-Backward");
delay(GES_QUIT_TIME);
}
else
{
Serial.println("forward");
delay(GES_QUIT_TIME);
}
break;
case GES_BACKWARD_FLAG:
delay(GES_REACTION_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_FORWARD_FLAG)
{
Serial.println("Backward-Forward");
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Backward");
delay(GES_QUIT_TIME);
}
break;
case GES_CLOCKWISE_FLAG:
Serial.println("Clockwise");
break;
case GES_COUNT_CLOCKWISE_FLAG:
Serial.println("anti-clockwise");
break;
default:
paj7620ReadReg(0x44, 1, &data1);
if (data1 == GES_WAVE_FLAG)
{
Serial.println("wave");
}
break;
}
}
delay(10);
}

¤ PHOTOS ¤

¤ IMPORTANT À SAVOIR ¤

Si vous voulez avoir plus d'informations sur comment marche ce dialogue entre Arduino et Processing ou même, de quelle autre manière il est possible de dialoguer avec ces 2 programmes, vous pouvez aller voir la page dédiée au système RFID !

¤ RESSOURCES ¤

Librairie capteur de geste : gesture_paj7620-master.zip

Capteur de geste : https://www.gotronic.fr/art-capteur-de-gestes-grove-101020083-23831.htm