1. Introduction

Ce nouveau projet consiste en la réalisation d'un contrôle à distance pour le bras mécanique que j'ai construit dans le projet h en option complémentaire informatique. Ce bras devrait donc, à l'aide de ce nouveau projet, être contrôlable depuis n'importe quel appareil (mobile, ordinateur, tablette, etc.) connecté au même réseau. Ce nouveau projet n'a donc comme but que l'amélioration de la méthode d'utilisation du bras, car celle-ci était plutôt complexe. Des améliorations au niveau physique ou concernant les divers autres problèmes de la première version ne seront pas réalisées. Cette nouvelle version du bras mécanique sera donc contrôlable depuis un navigateur web, par n'importe quel utilisateur.
Les différents objectifs sont donc la réalisation du site web, la communication entre le Raspberry Pi et l'Arduino ainsi la communication en l'utilisateur depuis son navigateur jusqu'au Raspberry Pi.

2. Matériel et méthodes

2.1. Matériel

Pour la réalisation de ce nouveau projet, quelques éléments sont requis.

  • Le bras mécanique réalisé sur ce billet: ici
  • Un Arduino (disponible ici) Le 'Uno' est utilisé pour ce projet).
  • Une Breadboard
  • Un Raspberry Pi (disponible ici) Le B+ sera utilisé dans ce projet.
  • Un SparkFun Pi Wedge B+ (disponible ici).
  • Beaucoup de fils électriques
  • Une connexion internet câblée pour le Raspberry Pi

2.2. Méthode

Dans cette section, les principales parties du contrôle du bras seront expliquées. Pour de plus amples détails, veuillez vous référer au code source - commenté - directement, disponible à cette adresse, contenant toutes les sources du projet: ici

2.2.1. L'aspect visuel du site

Pour le contrôle du bras, il va falloir passer par un site web, hébergé sur le raspberry Pi. Pour cela, trois langages de description et programmation seront utilisés: html, css et php. Ce blog n'a pas comme but d'être une introduction à ces langages, et il est donc fortement conseillé d'en connaître les fondamentaux. Si ce n'est pas le cas, voici quelques ressources utiles:

  • Openclassroom vous donnera les bases sur tous les langages cités, et bien d'autres: ici.
  • W3schools offre un accès à beaucoup d'informations sur css, et bien plus encore: ici.
  • PHP.net est la documentation officielle de php et offre beaucoup d'informations à son sujet : ici.

Les détails de réalisation de l'aspect visuel du site ne seront pas abordés dans ce billet. Cependant, les sources du site sont disponibles à cette adresse: ici.

2.2.2. La communication des valeurs entre l'utilisateur et le script python

Lorsque l'utilisateur a cliqué sur une case, la valeur de celle-ci doit être transmise au script python communicant avec l'Arduino. Pour arriver à ce résultat, plusieurs options sont envisageables.

2.2.2.1. L'utilisation d'une base de données

Pour communiquer les données, une des méthodes consiste en l'enregistrement des valeurs dans une base de données. Ensuite, de son côté, le script python récupère les valeurs et les transmet à l'Arduino.
Cette méthode présente plusieurs avantages, notamment celui de pouvoir avoir une liste d'attentes pour les valeurs, ainsi qu'un historique. Si l'utilisateur envoie plusieurs valeurs alors que le bras n'a pas fini son l'action précédente, les valeurs sont enregistrées à la suite dans la base de données, et seront traitées à la suite.
Cependant, cette méthode pose plusieurs problèmes. Le premier est que le script python doit dynamiquement ou périodiquement rechercher les valeurs, ce qui n'est pas optimisé. Le second problème est qu'il faut maitriser un language supplémentaire pour y arriver: MySQL (ou autres dérivés).

2.2.2.2. L’exécution du script avec php

La méthode utilisée dans ce projet est donc l'envoi de la donnée en même temps que l’exécution du script. Pour cela, un argument sera utilisé. La commande bash se formera donc de cette manière:

sudo ./script.py VALEUR

Ainsi, l'exécution du script et la transmission de la valeur se passe au même moment.
Afin de lancer cette commande, une petite astuce est utilisée. Lors de la pression du bouton, la page est rechargée, en modifiant l'option 'button' dans l'URL pour y ajouter la valeur demandée. Celui-ci aura cette forme:

www.ip.domaine/?button=VALEUR

Du coup, dans le début du code, l'existence de cette option est vérifiée avec la fonction isset(). Dans le cas où 'button' n'existe pas, FALSE sera envoyé. Dans le cas où elle existe, isset() envoie TRUE, et le script python sera exécuté avec la valeur en argument.

Lire la valeur de 'button' dans l'URL est facile, car celle-ci est présente dans la variable $_GET['button']. Il faut désormais passer à l'étape suivante, l'exécution du script python. Pour y parvenir, plusieurs étapes sont exécutées. La première est de savoir dans quel dossier travaille l'utilisateur apache. Il suffit donc d'exécuter la commande qui suit, pour permettre d'enregistrer dans la variable $pwd le dossier de travail.

$pwd = shell_exec('pwd');

Puis, cette commande est exécutée pour se rendre dans ce dossier.

exec("cd $pwd", $output, $return);

La fonction exec() est utilisée pour le debug, car dans le cas où une erreur est relevée, elle peut-être plus facilement traitée. Quand celle-ci retourne 0 dans la variable $return, aucune erreur n'est à déclarer. Dans le cas contraire, il faut le résoudre en cherchant sur internet l'erreur associée à un nombre.
Finalement, il ne reste plus qu'à exécuter le script.

exec("sudo ./script.py ".escapeshellarg($square), $output, $return);

Vu que la commande est exécutée en SupeUser, il est fortement conseillé de faire transiter les données de l'utilisateur, soit normalement la valeur de la case, à travers la fonction escapeshellarg(). La raison de son utilisation est que la valeur peut être très facilement modifiée en passant par l'URL. Si il y a la moindre faille, une attaque de type injection est envisageable. escapeshellarg() est donc là pour limiter les risques. Dans ce cas, $square contient la valeur de la case demandée.

2.2.3. GPIO

Les ports GPIO (General Purpose Input/Output) sont un système d'entrée/sortie qui permet à plusieurs microcontrôleurs de communiquer entre eux. [1]
Dans le cadre de ce projet, ces ports sont utilisés pour que le Raspberry Pi puisse communiquer avec l'Arduino. Ceux-ci sont reliés à l'aide du Pi Wedge B+ à la Breadboard de l'Arduino. Pour comprendre son utilisation, le manuel officiel du Pi Wedge B+ est disponible à cette adresse: ici

2.2.4. La communication Master/Slave

La communication entre le Raspberry Pi et l'Arduino se passe en suivant le principe d'un système Maître (Master en anglais) - Esclave (Slave en anglais). [2] Chez les humains, un maître ordonne aux esclaves une tâche. Lorsque celle-ci est réalisée, ils en préviennent le maître et attendent leur prochaine tâche. Au niveau informatique, cela se passe de la même manière, sans les questions des droits de la personne. Le maître, le Raspberry Pi, donne un ordre à l'esclave, l'Arduino, et celui-ci, lorsqu'il a fini sa tâche, l'annonce à son maître et attend la suite. La communication se passe de cette manière dans ce projet. En premier lieu, le maître code les coordonnées en 4 bits chacun. La ligne d'un côté, la colonne de l'autre. Ensuite, il va 'allumer' ou 'éteindre' le courant dans les 4 fils (représentant les 4 bits) pour envoyer la première coordonnée (la colonne dans ce projet). À partir de ce moment-là, il va donner l'autorisation à l'esclave de lire ces données en 'allumant' un cinquième fil. Lorsque l'esclave a lu les différentes valeurs, il envoie, à l'aide d'un sixième fil, un nouveau courant pour annoncer qu'il a fini la tâche. Le maître retire donc l'autorisation en éteignant le cinquième fil, et le sixième fil est également 'éteint'. Les mêmes opérations sont répétées avec l'autre coordonnée (la ligne dans ce projet). Ainsi, la coordonnée peut-être facilement transferée d'une machine à une autre. Si cette description n'est pas suffisante pour la compréhension des différentes opérations, cette image devrait clarifier le tout.

Figure 1. - Schéma de la communication entre le Raspberry Pi et l'Arduino. M/S est l'autorisation du maître à l'esclave. Il est composé d'une double autorisation, lorsque le premier vaut 1, le second vaut 0. TASK va de l'esclave au maître, afin de prévenir lorsque la tâche de l'esclave est finie. Ces deux liaisons permettent de synchroniser les différentes étapes du mécanisme, et fluidifie les opérations.

Prenons l'exemple des coordonnées 'G3' :
'A' en décimal vaut 65. Comme 'A' est la valeur minimum du projet, il suffit de ramener 'A' à '0', soit en soustrayant 65 à 'A'. Dans le cas de la coordonnée 'G', il faut faire exactement la même chose. Cette lettre en decimal vaut '71'. 71 - 65 = 6.
Il faut maintenant coder en 4 bits les deux coordonnées. Pour cela, un opérateur bit à bit (bitwise operation en anglais) est utilisé, AND. Voici la table de vérité relative à l'opérateur AND.

Figure 2. - Table de vérité de l'opérateur AND (et). 'p' et 'q' sont deux propositions. 1 est 'True' (vrai), 0 est 'False' (faux). 'p AND q' vaut 1 si et seulement si ces deux propositions valent 1. Sinon, 'p AND q' vaut 0.

Pour savoir si le premier bit doit contenir 0 ou 1, il suffit de comparer la valeur '6' et '1' avec l'opérateur AND. Pour le second bit, il faut comparer '6' AND '2', pour le troisième il faut comparer '6' AND '4' et pour le dernier, il faut comparer '6' AND '8'. Désormais, le maître sait que '6' en binaire vaut '0110'. Il faut de même avec la ligne et obtient que '3' vaut '0011' en binaire. À l'aide de la technique précédemment évoquée, il ne lui reste plus qu'à transmettre ces valeurs.

2.2.5. La configuration

Pour la réalisation, plusieurs étapes de configuration doivent être réalisées. Avant toute chose, munissez vous des fichiers du projet disponibles ici.

L'installation d'un service web sur le raspberry pi est requise pour mouvoir le bras depuis un navigateur. Pour ce fait, entrer ces commandes dans le terminal.

sudo apt-get update -y
sudo apt-get install apache2 php5 libapache2-mod-php5 -y

La première commande met à jour la liste des packages et la seconde installe les packages requis. Un nouveau dossier s'est créé sous /var/www/. Il s'agit de la racine d'apache, tout ce qui ce trouve dans se dossier sera disponible sur internet, tout ce qui ne s'y trouve pas, ne le sera pas. (Sauf en cas de configuration personnalisée)
Dans ce dossier, devront se trouver tous les fichiers de frontend. Pour y accéder depuis un navigateur, entrez l'ip du serveur. Ceci devrait s'afficher :

Figure 3. - Capture d'écran du site pour en donner l'aspect visuel. Elle permet au lecteur de se représenter le rendu final du site. Les zones 'vides' de la page ont été retirées de cette capture d'écran afin d'en garder l'essentiel.
Si l'image n'est pas suffisante, une version du site est disponible en ligne à cette adresse: Ici. L'erreur affichée est parfaitement normale. En effet, aucun bras mécanique n'est connecté.
Si ce n'est pas le cas, tentez de résoudre le problème en fonction de l'erreur affichée. Ce projet n'a pas de réponse préparée pour chaque problème. Il n'a pas été réalisé sur la même machine que la vôtre, et donc ne sera pas victime des mêmes erreurs.

Ensuite, copiez les fichiers de la racine du projet ailleurs, où vous le souhaitez. Rappellez-vous juste du chemin d'accès, il aura une importance plus tard.

Pour que le Raspberry Pi puisse communiquer à l'aide des ports GPIO, le script python doit être exécuté en SuperUser. Pour ce fait, afin de ne pas donner trop d'autorisations à l'éventuel utilisateur, le fichier 'script.py' va être ajouté dans /etc/sudoers. Pour ce faire, vérifiez tout d'abord que le bit d'écriture est bien activé sur ce fichier. Sinon, lancer cette commande:

sudo chmod 640 /etc/sudoers

Puis, modifiez ce même fichier en y ajoutant sous '#includedir /etc/sudoers.d' le code suivant (en modifiant ce qui doit l'être) :

ALL ALL=NOPASSWD: /chemin/vers/script.py

La dernière étape consiste en la modification du chemin d'accès au fichier communication.py, se trouvant à la racine du projet. Munissez-vous tout d'abord de ce chemin d'accès, et vérifiez bien que ce soit le chemin absolu et non relatif. Puis, il va falloir indiquer à 'script.py' (le script executé par le navigateur) l'endroit où se situe communication.py. Pour ce fait, j'ai créé une option au script , DEBUG, qui permet très simplement de modifier ce chemin. Depuis la racine du projet, lancez cette commande, puis suivez les instructions :

./script.py DEBUG

Sauf en cas d'erreur, la configuration du Raspberry Pi devrait être terminée.

3. Résultats

Le meilleur moyen de visualiser les résultats de ce projet est la présentation d'une vidéo. Si l'intégration de la vidéo dans ce blog ne fonctionne plus, voici son lien direct : Ici.



Figure 3. - Vidéo des résultats de ce projet. En fond se trouve le bras mécanique. En haut à gauche se situe le tableau visible depuis le site. Seul le tableau est représenté pour des questions d'espace. La précision du bras n'est pas parfaite. Il faut souvent décaler le pion légèrement sur la droite de la case, afin que le bras l'attrape. Les cases extrèmes, soit celles situées sur les lignes '0' et '9' ainsi que sur les colonnes 'A' et 'B' sont expérimentales. En effet, la précision n'est pas garantie sur ces cases. Comme le montre à deux reprises la vidéo, le bras a parfois tendance à se "déconnecter" et à faire n'importe quoi. Chaque opération dure en moyenne 10 secondes.

4. Discussion

4.1. Les problèmes phyiques

Depuis la réalisation de la première version du bras mécanique, il n'y a pas vraiment eu d'améliorations au niveau matériel. Les problèmes de précisions sont toujours présents, et les vibrations également. Cependant, entre-temps, la structure semble s'être fragilisée. En effet, le problème des vibrations est beaucoup plus présent maintenant qu'auparavant (comme le montre la vidéo).
Pour essayer de contrer le problème, de petites masses ont été ajoutées à l'avant-bras. Ceux-ci devraient servir à mieux stabiliser le bras, et ainsi éviter d'entrer dans le cercle vicieux des vibrations. Ces masses, des simples cailloux collés sur les côtés, ont en effet amélioré ce problème. Les vibrations se déclenchent moins régulièrement, mais un problème supplémentaire s'est également ajouté. Dans la vidéo des résultats, le bras réagit de manière aléatoire au bout d'un moment, et n'est récupérable qu'en le déconnectant du secteur. La cause exacte n'est pas connue, mais est probablement liée aux cailloux.

4.2. La facilité d'utilisation

Le but principal de cette nouvelle version du bras mécanique et de faciliter l'accès aux commandes du bras. Ce but est d'une part atteint, car il permet à tous les mobiles, ordinateurs ou autres, connectés sur le même réseau que le bras à le contrôler. Cependant, comme montré dans la vidéo, il est très facile de se tromper de case. À plusieurs reprises, la case où se situe le pion est manquée à une case près. Le problème, d'une part, provient du grand nombre de cases. Le plateau possèdant 10x10 cases, il est très facile de se tromper. Pour résoudre ce problème, il est par exemple possible de réduire ce nombre de cases, en utilisant un plateau 8x8. En effet, sur le plateau utilisé dans ce projet, les cases situées sur les extrêmités sont relativement expérimentales, et peuvent donc être évitées. Le plateau peut être encore réduit. De plus, ces dimensions sont celles utilisé par le jeu d'échec. Ainsi, une réduction de 100 à 64 cases est significatif au niveau visuel.

4.3. La sécurité

Un des problème qui est apparu dans cette nouvelle version du bras mécanique, est la sécurité qui l'entour. En effet, pour envoyer les données à l'Arduino, le Raspberry Pi utilise les ports GPIOs, qui requièrent d'être exécutés en SuperUser. Du coup, depuis le site, une commande avec 'sudo' est exécutée. De plus, l'utilisateur doit transmettre les coordonnées dans la commande précédemment citée. Du coup, le site possède un gros problème de sécurité. En effet, celui-ci pourrait subir une attaque de type injection. Grossièrement, cette attaque utilise le fait qu'une commande est exécutée avec des caractères entrés par l'utilisateur. Ainsi, en l'utilisant bien, cette technique peut s'avérer puissante.
Dans notre cas, pour contrer au maximum ce souci, l'argument entré est traité par la fonction escapeshellarg(). De toute façon, dans le cadre de ce projet, les problèmes de sécurité ne peuvent produire des dégats que limités. Cependant, si les mêmes étapes sont reproduites sur un site important, les conséquences peuvent être plus violentes.

La durée de vie des signaux du Raspberry Pi

Un problème constaté durant la réalisation de ce projet est la non-aptitude du Raspberry Pi à garder un signal lorsque le script est éteint. Cependant, le problème n'est pas encore là. Périodiquement, celui-ci se réactive, sans raison apparente, et envoie de fausses valeurs à l'Arduino. La cause exacte de cette périodicité n'a pas pu être trouvée, et a donc posé problème. Pour contrer ce souci, deux méthodes ont été appliquées. Le premier est de placer des délais répartis dans le code. Comme de toute façon les deux appareils sont sychronisés à chaque étape, cela ne pose pas de problèmes. Du coup, cela permet de réduire la chance de tomber sur un moment où le signal se réactive. La seconde méthode appliquée bien plus tard est la double autorisation. En effet, le problème intervient principalement sur le signal d'autorisation du Raspberry Pi. Du coup, un second lien d'autorisation a été mis en place, sauf que celui-ci fonctionne en inverse du premier. Lorsque le premier fil a du courant ('1' pour l'Arduino), le second n'en a pas. ('0' pour l'Arduino) Cela semble aider à contrer ce souci. Bien qu'il soit encore présent, les deux méthodes précédentes ont bien réduit l'activation involontaire du bras.

5. Conclusion

Finalement, ce nouveau projet accomplit son but, malgré ses quelques défauts. Les diverses problèmes de vibration ou de précision n'ont pas été corrigés, mais ce n'est pas l'objectif de cette nouvelle version du projet.
Tous les objectifs énoncés dans l'introduction ont été atteint. La création du site web est réussite bien que celui-ci soit un peu minimaliste, la communication entre le Raspberry Pi et l'Arduino fonctionne également, avec le souci de la périodicité du signal du Raspberry Pi, et enfin, concernant la communication entre l'utilisateur et le Raspberry Pi, aucune erreur flagrante n'est à déclarer.
Si une troisième version de ce projet était réalisée, je pense que les modifications majeures à apporter toucheraient la partie physique du bras mécanique. Le point qui me semble le plus important est de rendre le bras plus rigide. En gardant la structure en bois actuelle, il est par exemple possible de placer de la fibre de carbone perpendiculairement pour le solidifier. Il est également possible d'utiliser des métaux pour améliorer ce point. Cependant, si des métaux sont utilisés, il faut drastiquement changer le moyen de mouvoir le bras. Les servos ne sont plus suffisants. Il est possible de les remplacer par des moteurs pas à pas, beaucoup plus puissants, et plus précis.
Comme cela a déjà été dit dans le billet concernant la première version de ce bras mécanique, ce n'est qu'un prototype. Cependant, avec cette "mise à jour", ce prototype ressemble un peu plus à un bras réellement utilisable dans divers secteurs.
Cette nouvelle version a pu me familiariser avec les technologies basiques du web, avec le language python, ainsi qu'avec des principes de communications entre appareils, et les problèmes liés à ceux-ci.

6. Références

[1] Contributeurs de Wikipédia, "General Purpose Input/Output," Wikipédia, l'encyclopédie libre, http://fr.wikipedia.org/w/index.php?title=General_Purpose_Input/Output&oldid=123938028 (Page consultée le mai 1, 2016).

[2] Wikipedia contributors, "Master/slave (technology)," Wikipedia, The Free Encyclopedia, https://en.wikipedia.org/w/index.php?title=Master/slave_(technology)&oldid=712680040 (accessed May 5, 2016).

7. Ressources

Le site web réalisé dans ce projet utilise le système de détection d'appareils mobiles de 'Detect Mobile Browsers', disponible à cette adresse : http://detectmobilebrowsers.com/. Ce système est opensource et est disponible pour tous.

Le site web réalisé dans ce projet utilise la police d'écriture 'Geomanist' de Atipo fonts, disponible à cette adresse : http://geomanist.com/