Projet IMA3 P3, 2017/2018, TD1 : Différence entre versions

De Wiki de Projets IMA
(Partie informatique)
(Partie informatique)
Ligne 100 : Ligne 100 :
  
 
*Paramétrage du traitement des données des ADXL345
 
*Paramétrage du traitement des données des ADXL345
Concernant le traitement des données des accéléromètres, nous avons créer une fonction writeTo() et une fonction readFrom(). La fonction writeTo() prend en paramètres l'adresse du capteur, le registre du capteur sur lequel on souhaite écrire, la valeur de l'octet que l'on souhaite écrire dans le registre. Elle permet d'écrire une valeur sur un registre d'un des capteurs et permet ainsi d'activer le capteur ciblé. [[Fichier:ecriture_adresse.jpg|200px|thumb|right|Fonction writeTO()]] La fonction readFrom() prend en paramètres le capteur, l'adresse du registre de données de l'accéléromètre, le nombre d'octet qui vont être lus (6 à raison de 2 pour chaque axe), un buffer dans lequel seront stockées les données lues sur le capteur. Cette fonction sert à récupérer un flux de données transmises par le capteur. Ce flux contient les valeurs des positions x, y et z qui seront séparées et stockées dans le buffer qui est un tableau de taille 6 (le nombre d'octet reçu). [[Fichier:lecture_donnees.jpg|200px|thumb|right|Fonction readFrom()]]
+
Concernant le traitement des données des accéléromètres, nous avons créer une fonction writeTo() et une fonction readFrom(). La fonction writeTo() prend en paramètres l'adresse du capteur, le registre du capteur sur lequel on souhaite écrire, la valeur de l'octet que l'on souhaite écrire dans le registre. Elle permet d'écrire une valeur sur un registre d'un des capteurs et permet ainsi d'activer le capteur ciblé.  
 +
 
 +
[[Fichier:ecriture_adresse.jpg|200px|thumb|right|Fonction writeTO()]]  
 +
 
 +
La fonction readFrom() prend en paramètres le capteur, l'adresse du registre de données de l'accéléromètre, le nombre d'octet qui vont être lus (6 à raison de 2 pour chaque axe), un buffer dans lequel seront stockées les données lues sur le capteur. Cette fonction sert à récupérer un flux de données transmises par le capteur. Ce flux contient les valeurs des positions x, y et z qui seront séparées et stockées dans le buffer qui est un tableau de taille 6 (le nombre d'octet reçu).  
 +
 
 +
[[Fichier:lecture_donnees.jpg|200px|thumb|right|Fonction readFrom()]]
 +
 
 +
Nous créons 6 variables correspondant aux axes x, y et z (j, k, l respectivement pour le 2e capteur) dans lesquelles nous stockeront les données contenues dans le buffer. Etant stockées sur 2 octets, nous stockeront buffer[0] et buffer[1] dans les variables x (et j), buffer[2] et buffer[3] dans y (et k), buffer[4] et buffer[5] dans z (et l). [[Fichier:stockage_des_données.jpg|200px|thumb|right|Stockage des donnée]]
 +
Comme dit précédemment, nous recevons des valeurs d'accélération en g comprise entre 0 et 280. Nous avons donc créé une variable de type double pour chaque axe et utilisons la fonction atan() nous permettant de convertir ces mesures en angle. On multiplie cette valeur par 180 ou 3.14 selon que l'on veut cet angle en degrés ou en radians [[Fichier:calcul_dangle.jpg|200px|thumb|right|Conversion de donnée en angle]]

Version du 17 juin 2018 à 02:56

Projet IMA3-SC 2017-2018 : prototype de main artificielle

Description du projet

Cahier des charges

  • Reconnaissance d'un mouvement par la Rpi via l'accelerometre
  • Transmission du mouvement à l'arduino via bluetooth déclenchant le servomoteur
  • Visuel du mouvement sur serveur web
  • Bonus : Faire plusieurs doigts

Description du système

Des accelerometres sont fixés sur la main (le doigt d'abord) de l'utilisateur.
Detection d'un mouvement de doigt par les accelerometres.
Transmission du mouvement au servomoteur via l'arduino.
Transmission des informations a la Rpi pour la reproduction de mouvement sur serveur web.

Matériel nécessaire

  • 2 servomoteurs
  • 2 accelerometres
  • 1 Rasberry Pi 2
  • 1 Arduino Uno

Séance 1 : Début du projet

Durant cette première séance, nous avons constitué les groupes te définit un sujet.
Nous avons pris connaissance des contraintes imposés par le projet.
Chacun de nous a commencé a se familiariser avec les différentes composantes du projet.
Brandon -> Arduino
Flora -> Rasberry
Florent -> Impression du doigt et recherches

Séance 2

Le doigt étant imprimé, nous nous sommes attelés à la conception du programme permettant de faire fonctionner celui-ci. L'objectif était de faire en sorte que, lors de l'envoi d'une donnée précise du capteur à l'Arduino, les servomoteurs suivent le mouvement indiqué par l'utilisateur. Nous pouvons décomposer les mouvements du doigt comme ceci : (images)

Par soucis du matériel et n'étant pas encore sûrs du montage final, nous avons préféré réaliser nos test à l'aide de 1 breadboard sur laquelle nous avons réalisé toutes les connectiques nécessaires à la communication entre l'ADXL et l'Arduino.

A l'issue de la séance, nous avons réussi à simuler le mouvement complet d'un doigt à l'aide d'un capteur comme vous pouvez le voir dans la vidéo ci-dessous : (vidéo)

Cependant, pour pouvoir être en accord avec l'idée de mouvement pré-établi plus haut, il est nécessaire d'ajouter un 2e capteur ADXL au montage. Peut-on contrôler 2 ADXL séparément à l'aide d'une seule carte Arduino ?L'objectif de la séance suivante sera donc de trouver un moyen d'inclure et contrôler le 2e ADXL.

Séance 3

Le but de cette séance fut de pouvoir améliorer notre montage et notre programme en y ajoutant un deuxième capteur. La tâche était assez compliquée dans la mesure où nous devions pouvoir contrôler les 2 capteurs indépendamment. En suivant le même principe que le montage précédent, nous avons pu rajouter le 2e capteur et procéder à des test similaires à ceux réaliser sur le précédent montage. Cependant, le montage était réalisé de telle sorte que les 2 ADXL soient interconnectés. Ainsi, les données relevées par l'un était une copie conforme de celle relevées par l'autre. Cela ne correspondait pas à nos attentes. Nous avons donc tenté de modifier notre programme afin de remédier à cela mais le problème persistait. La seule option possible était de revoir le schéma de montage. N'ayant pas eu suffisamment de temps pour le faire, nous nous sommes accordés à revoir ce soucis hors-séance afin d'achever notre projet.

Bilan

Activité électronique

Afin de réaliser notre projet tout en répondant notre cahier des charges, nous avons établit le montage suivant :
Montage un capteur

La masse (GND) du capteur doit être connectée à celle de l'Arduino. Les broches CS et 3.3V sont reliées à la pin 3.3V de l'Arduino, la broche CS étant étant reliée ainsi afin de faire comprendre à l'ADXL que nous l'utilisons en tant que I2C. Les broches SDA et SCL sont connectées aux pins analogiques A4 et A5 respectivement car la pin A4 de l'Arduino correspond au port série de données tandis que la pin A5 correspond au top d'horloge.

Nous nous sommes également procuré 2 LED et 2 servomoteurs pour servir de voyants repères et de simulation du mouvement respectivement.

(Vous pouvez également voir le rendu vidéo en regardant celle qui se trouve partie Séance 2)

Pour pouvoir contrôler le mouvement de la seconde partie du doigt, il a été nécessaire de rajouter un 2e capteur ADXL345 (de même type). Ainsi, le premier capteur gère le mouvement de la base du doigt, tandis que le 2e s'occupe de celui de la partie supérieure.
Schéma de câblage 2 ADXLs

Faisant suite aux problèmes signalés dans la partie Séance 3, nous avons revu le montage.

La pin SD0 de l'ADXL sert à la sélection de l'adresse de celui-ci. En effet, si on se réfère à la datasheet, l'ADXL dispose de 2 adresses internes qui sont sélectionnées selon l'état du pin SD0 : à l'état haut, c'est l'adresse 0x1D qui est sélectionnée; à l'état bas, c'est l'adresse 0x53 qui est sélectionnée.

Il suffit donc d'attribuer à chaque capteur l'une des 2 adresses. Pour ce faire, si on souhaite choisir l'adresse 0x1D de l'ADXL, il suffit de mettre la pin SD0 à l'état haut, soit le connecter au 3.3V de l'Arduino. À l'inverse, si on souhaite sélectionner l'adresse 0x53, on connecte le pin SD0 à la masse pour le mettre à l'état bas. Ce faisant, nous obtenons le montage ci-contre.
Montage 2 capteurs

Ainsi, nous pouvons contrôler séparément les 2 capteurs grâce au nouveau programme établit : (programme)

Penchons nous à présent sur les données émises par les capteurs. Commençons d'abord par une description générale de l'accéléromètre. Celui que nous utilisons est un ADXL345 dont les principales caractéristiques sont les suivantes :

  • Type de communication: I2C
  • Plage de mesure : ±2g - ±16g ("g" est une unité d'accélération traduisant l'accélération de la pesanteur sur Terre et correspond à 9.81 m.s-²)
  • Sortie numérique : I2C
  • Système de mesure 3 axes : ±2g/±4g/±8g/±16g
  • Tension de fonctionnement: 3V à 5V
  • Temperature de fonctionnement: -40° to 85°
  • Courant de fonctionnement: 30µA
Axes de l'ADXL

L'ADXL345 transmet l'accélération sur chaque axe : il envoie une valeur entre 0 lorsqu'on est à l'horizontale et 280 à la verticale. Nous effectuons conversion dans le programme Arduino afin de récupérer l'angle d'inclinaison du capteur. Ce calcul varie en fonction de l'axe sur lequel on effectue la conversion : sur l'axe x, il faut calculer atan( x / (sqrt(square(y) + square(z)))); sur l'axe y il faut calculer atan( y / (sqrt(square(x) + square(z)))); sur l'axe z on calcule atan( sqrt(square(x) + square(y)) / z). Dans notre cas, nous récupérons l'angle sur l'axe x qui correspond à l'angle compris entre l'axe x et l'axe z.

Un soucis se pose, cependant, concernant les capteurs. En effet, les 2 capteurs fonctionnent correctement mais seul un des 2 capteurs semble influencer les servomoteurs. Ce problème reste encore irrésolu malgré les tests et les hypothèses émises.

Partie informatique

Ici nous présenterons la partie informatique, qui concerne notamment la communication entre l'Arduino et la Raspberry. Le projet initial visait à pouvoir contrôler une main via une application web ou des capteurs, mais aussi à recevoir les données desdits capteurs afin de présenter une modélisation virtuelle du système. Notre application web se présente donc en deux parties : celle gérant le mode application et celle gérant le mode capteurs. Pour cela, deux pages .html sont crées afin de naviguer entre les différentes fonctions : notre fichier index.php nous présente deux liens, afin de nous diriger vers le mode voulu : application ou capteurs. De plus, elle présente un bouton Arrêt afin d'éteindre la Raspberry et de pouvoir la débrancher simplement.

Page d'accueil


  • Partie application

Ici, le doigt est contrôlé via deux boutons, présents sur l'application, permettant d'ouvrir et de fermer le doigt. Pour cela, nous avons repris le code qui nous était fourni en exemple, que nous avons réadapté. Cette liaison série nous a présenté un premier problème : nous voulions pouvoir envoyer un caractère lors de l'appui sur un des deux boutons. Un 'f' déclencherait la partie du code sur l'Arduino correspondant pour "fermer" le doigt, de même avec un 'o' qui devait déclencher l'"ouverture" du doigt. Toutefois, nous nous sommes vite aperçu que l'envoi et le traitement de caractère était problématique. Nous avons donc vite décidé de simplement envoyer un entier : pour ouvrir le doigt, au lieu d'envoyer un 'o' (la 15e lettre de l'alphabet), nous enverrons un 15, et pour fermer nous enverrons un 6. Pour cela, nous passerons donc par la fonction sendMessage ()

function sendMessage(ordre){websocket.send(ordre);}

Ainsi, nous passons grâce aux websockets l'ordre voulu. Il peut ainsi être traité par l'Arduino. Dans le body de notre page html, nous plaçons donc les deux boutons ouverture et fermeture qui utilisent la fonction sendMessage() :

<button onclick="sendMessage(8);">Lancer la commande</button>
<button onclick="sendMessage(15);">Ouverture</button>
<button onclick="sendMessage(6);">Fermeture</button>


Il était initialement prévu de pouvoir naviguer directement d'un mode (appli/capteurs) à l'autre, cependant le code implanté sur l'Arduino impose d'envoyer une variable indiquant au système la fin d'un mode, nous imposant ainsi une nouvelle contrainte. En effet, on ne passe plus simplement d'une page à l'autre, mais lors de chaque appui sur un lien, cela interrompt le mode. Ainsi, nous avons ajouté des appels à la fonction sendMessage() dans toutes les balises <a> afin d'envoyer la valeur 9, permettant à l'Arduino de sortir du mode. Il suffit donc, une fois dans la page appli.html, de lancer la commande puis de choisir le bouton ouvrir ou fermer afin de commander le doigt !

AppliDoigt.JPG
Média:Video-1529153420.mp4

Vous pouvez ici voir que ce ne sont pas les capteurs qui commandent le doigt : ils restent immobiles sur la table. Vous pouvez par contre distinguer le bruit de la souris, avant chaque mouvement du doigt : ce sont les boutons qui sont bien aux commandes.

  • Partie capteurs

Ici, nous utilisons la liaison série dans sa totalité : nous envoyons toujours une variable déclenchant le programme dans l'Arduino, mais nous recevons également des données de celui-ci. En effet, les capteurs n'envoient pas seulement les données vers le doigt pour le commander, afin que celui-ci suive les mouvements, mais ils envoient également ces mêmes données au serveur via le port série. Nous avons le choix : nous pouvons envoyer les positions suivant x ,y, z par exemple. Cependant, nous décidons de traiter ces données au préalable afin d'envoyer l'angle correspondant à la rotation du système. Ainsi, nous pouvons afficher cette valeur, mais surtout modéliser le doigt sur l'application. Le but actuellement est de représenter le doigt de manière simplifiée grâce à un rectangle : il a d'abord fallu réussir à comprendre comment insérer la figure sur l'écran, et comment le faire pivoter en fonction de la valeur reçue. Pour cela, nous utilisons un canvas, dans lequel nous plaçons un rectangle :

  • Paramétrage du traitement des données des ADXL345

Concernant le traitement des données des accéléromètres, nous avons créer une fonction writeTo() et une fonction readFrom(). La fonction writeTo() prend en paramètres l'adresse du capteur, le registre du capteur sur lequel on souhaite écrire, la valeur de l'octet que l'on souhaite écrire dans le registre. Elle permet d'écrire une valeur sur un registre d'un des capteurs et permet ainsi d'activer le capteur ciblé.

Fonction writeTO()

La fonction readFrom() prend en paramètres le capteur, l'adresse du registre de données de l'accéléromètre, le nombre d'octet qui vont être lus (6 à raison de 2 pour chaque axe), un buffer dans lequel seront stockées les données lues sur le capteur. Cette fonction sert à récupérer un flux de données transmises par le capteur. Ce flux contient les valeurs des positions x, y et z qui seront séparées et stockées dans le buffer qui est un tableau de taille 6 (le nombre d'octet reçu).

Fonction readFrom()
Nous créons 6 variables correspondant aux axes x, y et z (j, k, l respectivement pour le 2e capteur) dans lesquelles nous stockeront les données contenues dans le buffer. Etant stockées sur 2 octets, nous stockeront buffer[0] et buffer[1] dans les variables x (et j), buffer[2] et buffer[3] dans y (et k), buffer[4] et buffer[5] dans z (et l).
Stockage des donnée
Comme dit précédemment, nous recevons des valeurs d'accélération en g comprise entre 0 et 280. Nous avons donc créé une variable de type double pour chaque axe et utilisons la fonction atan() nous permettant de convertir ces mesures en angle. On multiplie cette valeur par 180 ou 3.14 selon que l'on veut cet angle en degrés ou en radians
Conversion de donnée en angle