###### tags: `SPS` `Tinguely EV3` :computer: Tinguely EV3 - Guide du développeur === [ToC] ## Introduction Ce guide est un complément au [Guide de mise en service](https://hackmd.io/@jonathanmichel/B11DPn8wY). Il permet de comprendre en détails le fonctionnement technique du stand Tinguely EV3. **Ce document n'est pas recommandé pour les non-initiés à la programmation ou à Linux, bien qu'il tente de rester haut-niveau et complet à la fois.** Le [Guide mise en service](https://hackmd.io/@jonathanmichel/B11DPn8wY) contient un chapitre "Montage" et "Dépannage" qui permet à quiconque de déployer et réparer le stand en cas de problème. ## 1. Raspberry Pi ### 1.1 Déploiement du Raspberry Pi Le Raspberry Pi fait tourner une version standard de Raspberry Pi OS. Pour y accéder, le plus facile est de connecter un écran, un clavier et une souris. Cependant, pour faciliter le développement il est recommandé de connecter le Raspberry Pi à internet. Pour se faire plusieurs méthodes sont possibles. On peut configurer un réseau WiFi ou connecter le Pi avec un câble Ethernet sur un ordinateur lui même connecté à un WiFi. Si cette deuxième méthode est privilégiée, il faudra partager sa connexion avec le Pi. :::info ### Se connecter en SSH au Raspberry Pi depuis un ordinateur - IP: **192.168.137.139** (Si connecté en Ethernet avec un partage de connexion, sinon à déterminer selon la configuration) - Utilisateur: **pi** - Mot de passe: **raspberry** ::: ## 2. Brique EV3 ### 2.1 Système d'exploitation ev3dev Afin de pouvoir programmer l'EV3 sans utiliser EV3 Classroom ou Lego Mindstorms Education/Home EV3, il a été nécessaire de changer le logiciel interne de la brique. Ceci est faisable simplement grâce à [ev3dev](https://www.ev3dev.org/). Il s'agit d'un système d'exploitation basé sur Debian. Une fois installé, il permet de programmer l'EV3 avec [d'autres langages de programmation](https://www.ev3dev.org/docs/programming-languages/). Pour utiliser ev3dev sur le Mindstorm EV3, il suffit de l'installer sur une carte SD puis de démarrer la brique avec celle-ci. Pour réutiliser l'EV3 normallement, il suffit de retirer la carte SD et de rallumer la brique. Dans notre cas, la carte SD est disponible dans le matériel du stand. Des cartes SD de réserve ont également été faites au besoin, si elles sont utilisées, veillez à suivre le chapitre "Utiliser une carte SD de remplacement" du [Guide mise en service](https://hackmd.io/@jonathanmichel/B11DPn8wY) (@todo). Au besoin, la procédure d'installation d'ev3dev est présentée sur le site [ev3dev.org/docs/getting-started](https://www.ev3dev.org/docs/getting-started/) ### 2.2 Accèder à la brique Une fois ev3dev lancé sur la brique, il est possible de connecter la brique à internet et d'y accéder de plusieurs façons: avec un dongle WiFi, en [USB](https://www.ev3dev.org/docs/tutorials/connecting-to-the-internet-via-usb/) ou même en [Bluetooth](https://www.ev3dev.org/docs/tutorials/connecting-to-the-internet-via-bluetooth/). Les tutoriels sur le site [ev3dev](https://www.ev3dev.org/docs/networking/) présentent ces différentes méthodes. Dans notre cas, l'EV3 est relié par USB au Rasberry Pi. Pour ce faire, le tutoriel [Connecting to the Internet via USB](https://www.ev3dev.org/docs/tutorials/connecting-to-the-internet-via-usb/) a été suivi sur le site ev3dev. Il est ensuite possible de se connecter à la brique en SSH comme présenté dans le tutoriel [Connecting to Ev3dev Using SSH](https://www.ev3dev.org/docs/tutorials/connecting-to-ev3dev-with-ssh/). :::info ### Se connecter en SSH au Mindstorm EV3 depuis le Pi - IP: **ev3dev.local** ou affichée au sommet de l'écran de l'EV3 (10.42.0.45 en général) - Utilisateur: **robot** - Mot de passe: **maker** ::: ### 2.2 Scripts sur la brique EV3 #### 2.2.1 Bash pour arrêter le code :::warning @todo ::: ## 3. Interface tangible ### 3.1 Concept général Chaque bloc Scratch qui compose l'interface tangible du stand contient un Arduino Nano. En branchant les blocs les uns sous les autres, ces derniers vont communiquer dans l'obectif de transmettre au bloc précédent leur instruction représentée par un ID unique et ses éventuels paramètres. La communication est une simple liaisons série sur laquelle repose un protocole qui sera présenté plus bas. En parrallèle, chaque bloc lit le code envoyé par le bloc suivant afin de l'ajouter aux données qu'il va faire remonter. Le bloc au sommet du code transmet au Raspberry Pi le programme complet pour qu'il soit décodé et interprété, puis transmis et exécuté sur l'EV3. La figure ci-dessous présente une vue simplifiée des données qui vont transiter entre les blocs. Dans l'exemple, le bloc bleu qui a pour objectif d'exécuter le moteur a l'ID unique 0x2E. Il le transmet au bloc orange "Attendre" qui a l'ID 0x1F. Ce dernier envoie donc 0x1F2E au bloc violet qui permet de changer la couleur du témoin de la brique et qui a l'ID 0x16. Le code complet (0x2E161F2E) est finalement généré par le bloc de lancement du programme (ID 0x2E) puis envoyé au Raspberry Pi pour être décodé. ![](https://i.imgur.com/peHSn7J.png) :::warning En pratique, chaque bloc a des paramètres (par exemple, le nombre de secondes pour le bloc "Attendre"). Ces-derniers sont transmis à la suite de l'ID et ainsi intégré dans les données qui transitent entre les blocs. Le programme sur le Raspberry Pi connaît ensuite les blocs et est capable de lire les paramètres en fonction de l'ID qu'il reçoit. Pour les détails, se référer à la présentation du protocole dans la suite de ce guide. ::: ### 3.2 Implémentation Les blocs Scratch sont répartis en différents groupes de blocs. Pour les détails, se référer à la documentation officielle de [Scratch](https://en.scratch-wiki.info/wiki/Blocks). ![](https://i.imgur.com/T217SpV.png) #### 3.2.1 Blocs Hat Un code Scratch commence par un bloc "Hat". Dans notre cas, le bloc "au lancement du programme" est utilisé. Ce dernier est relié au Raspberry grâce au câble USB-TTL. Il dispose ensuite d'un connecteur magnétique sur son notch inférieur afin de permettre la connexion des blocs suivants. La figure ci-dessous présente le pinning à utiliser. La connexion avec les Arduino sera présentée plus bas. ![](https://i.imgur.com/hT7MMhH.png) #### 3.2.2 Blocs Stack Les blocs "Stack" quant à eux disposent de deux connecteurs magnétiques logés dans les notches. Le notch supérieur reçoit l'alimentation et envoie le code au bloc le précédant. Le notch inférieur transmet l'alimentation et reçoit le code des blocs suivants. Le dessin ci-dessous présente la connectique entre les connecteurs et l'Arduino. ![](https://i.imgur.com/OTbMgaI.png) :::danger Les flèches sur le dessin ci-dessus représentent une liaison virtuelle. En pratique, les pins des deux connecteurs sont uniquement directement reliées pour l'alimentation (pins 1 et 2) mais doivent être également déportées sur l'Arduino. Les pins 3 des conecteurs sont elles à relier aux entrées de l'Arduino comme indiqué sur le schéma et non pas entre elles. ::: #### 3.2.3 Blocs C Les blocs C (si, si/sinon, répéter, ...) contiennent un Arduino par embranchement. Ainsi un bloc "si" demandera deux instructions (si et end), un "si/sinon" trois (si, sinon, end) et un "répéter" deux (répéter, end). #### 3.2.4 Blocs booléens Pour les blocs booléens qui sont à utiliser dans les blocs C ainsi que dans le bloc "attendre jusqu'à ce que" par exemple, il n'a pas été prévu qu'ils puissent être physiquement changés via l'interface tangible. Cependant le protocole de communication supporte une telle utilisation, comme décrit dans la suite de ce guide. #### 3.2.5 Autre blocs Les bloc reporteurs n'ont pas été implémentés dans la version actuelle du projet, tout comme les opérateurs. ![](https://i.imgur.com/OYADp2H.png) ![](https://i.imgur.com/yesYrMl.png) De plus, aucun bloc "End" n'est utilisé bien que son utilisation soit similaire à un bloc "Stack" standard. #### 3.2.6 Interraction avec les blocs En fonction des blocs, il est possible d'ajouter des entrées externes permettant d'intéragir avec chaque bloc. Un potentiomètre peut par exemple permettre de définir le temps avec leque le bloc attendre est configuré, un switch pourrait permettre de choisir la direction dans laquelle un moteur doit tourner, etc... Pour plus de détails se référer à la documentation du programme tournant sur les Arduino Nano. ### 3.3 Protocole de communication #### 3.3.1 Liste des blocs Chaque bloc disponible dans le logiciel Scratch a été listé et un ID unique lui a été assigné. La liste complète est disponible dans la documentation GitHub du projet. Pour chaque instruction, la liste des paramètres et leurs tailles (en chars) ont été déterminés. Cette liste est connue par les Arduino et par le programme du Raspberry. ![](https://i.imgur.com/6ka84AI.png) :::info Le développeur peut ajouter des instructions personnalisées qui ne seraient pas disponibles dans EV3 Classroom du moment qu'il est possible d'implémenter leur comportement en Python/MicroPython sur ev3dev. Pour plus de détails, se référer à l'explication des programmes tournant sur le Pi et sur les Arduino. Il est également possible d'utiliser ce protocole et donc l'interface tangible pour générer un code qui programmerait autre chose qu'un robot Mindstorm EV3. ::: #### 3.3.2 Type des paramètres Il existe plusieurs types possibles pour les paramètres des blocs: - **uint:** Un nombre positifs. La quantité de digits est spécifiée par la taille du paramètre. - **enum:** Une énumération qui contient une valeur (en général un char) et un chaîne de charactère la décrivant. - **binary:** Une suite de chars, se référer à l'explication du fonctionnement des blocs booléens pour plus de détails. Chaque bloc est décrit dans un fichier *.xml* utilisé par le code Python qui tourne sur le Raspberry Pi. Le fichier spécifie son ID, ses paramètres et leurs tailles/types. L'image ci-dessous présente l'exemple pour le bloc qui permet de faire tourner un moteur. Pour plus de détails, se référer à l'explication du programme Python. ![](https://i.imgur.com/SKV9KT2.png) #### 3.3.3 Encodage des paramètres des blocs La taille (en chars (= bytes)) et le type de paramètres de chaque bloc sont déterminés et connus par le programme Arduino et celui du Pi. L'image ci-dessous présente à titre d'exemple comment encoder l'instruction qui permet de piloter un moteur et ses paramètres: ![](https://i.imgur.com/ckjU5UD.png) Ainsi si l'on souhaite exécuter le moteur B vers la gauche pendant 17 rotations, il suffira d'envoyer la chaîne de charactère depuis l'Arduino `0DBlr017`. L'ID `0D` étant celui de la fonction `motors_run_direction`, le Raspberry Pi pourra décoder et interpréter les paramètres qui le suive. Le détail pour chaque bloc est disponible dans le fichier *.xml* utilisé par le programme Pyhton. #### 3.3.4 Représentation ASCII d'un programme Scratch En chaînant les ID et les paramètres des différents blocs, il est ainsi possible de représenter avec une chaîne de charactères un programme informatique basé sur Scratch. L'exemple de la figure ci-dessous présente les trames séries qui seront transmises par chacun des trois blocs qui constituent un code qui va attendre 50 secondes puis allumer le témoin d'état de la brique en vert. Le code complet correspondant est ainsi `2E|1F50|16g`. ![](https://i.imgur.com/gZOSSV0.png) [Afficher en grand](https://i.imgur.com/gZOSSV0.png) En plus des charactères représentant le programme Scratch, chaque bloc envoie `#` en tant que header pour délimiter le début de la trame et `!` comme symbole de fin. Les différents blocs sont ensuite séparés par le symbole `|` pour être identifiés dans la trame complète. #### 3.3.5 Gestion des booléens Les booléens qui sont à utiliser dans les blocs "si", "attendre jusqu'à ce que" et "répéter jusqu'à ce que" sont considérés comme des paramètres de ces blocs. Ils disposent ainsi d'un paramètre "boolean" de type "binary". ![](https://i.imgur.com/TPVAoNX.png) A ce jour (@todo), il n'a pas été prévu qu'ils puissent être physiquement changés par l'utilisateur sur l'interface tangible. Cependant, la version actuelle du code Arduino des blocs qui utilisent des booléens envoie le suite de bytes qui représente le blocs booléen et leurs paramètres comme expliqué sur l'image ci-dessous. Le booléens qui permet de tester la distance avec la capteur à ultrason a ainsi un ID unique comme les autres blocs Scratch, ainsi qu'une liste de paramètres. ![](https://i.imgur.com/Ok8EVbw.png) Lorsque le booléen est utilisé dans un bloc "attendre jusqu'à ce que" par exemple, son ID et ses paramètres sont envoyés à la suite de l'ID du bloc. A noter qu'un charactère supplémentaire est envoyé devant le bloc booléen car il est de type "binary". Il indique la taille en hexadécimal de la donnée binaire qui suit. Ceci sera nécessaire pour le décodage de la chaîne sur le Raspberry Pi. ![](https://i.imgur.com/flXlHp3.png) ### 3.4 Programme pour les Arduino sur chaque bloc Scratch