Modifications

28 986 octets ajoutés ,  29 mars 2021 à 15:53
aucun résumé de modification
Ligne 2 : Ligne 2 :  
Dans le cadre de notre projet de fin d'étude, nous avons choisi de travailler sur l'amélioration des robots de Polybot, le club de robotique de Polytech Grenoble, dans l'objectif de participer à la Coupe de France de Robotique 2021.
 
Dans le cadre de notre projet de fin d'étude, nous avons choisi de travailler sur l'amélioration des robots de Polybot, le club de robotique de Polytech Grenoble, dans l'objectif de participer à la Coupe de France de Robotique 2021.
 
Après réflexion et discussion avec les autres groupes et notre tuteur, nous avons décidé d'apporter des améliorations aux robots via deux sous-projets que vous découvrirez plus en détail dans la suite de ce rapport : la création d'une nouvelle carte de puissance et l'affichage des données en temps-réel concernant le robot.
 
Après réflexion et discussion avec les autres groupes et notre tuteur, nous avons décidé d'apporter des améliorations aux robots via deux sous-projets que vous découvrirez plus en détail dans la suite de ce rapport : la création d'une nouvelle carte de puissance et l'affichage des données en temps-réel concernant le robot.
 +
 +
Si vous souhaitez reprendre une partie du projet, nous avons rédigé un document tuto expliquant en détail comment nous avons réalisé le projet et comment reproduire ou modifier certaines étapes : [[Projet_5A_2020_2021/Tuto utilisation et modification|Tutoriel d’utilisation]].
 
<br>
 
<br>
 
<br>
 
<br>
Ligne 8 : Ligne 10 :  
===La coupe de France de robotique===
 
===La coupe de France de robotique===
 
[[Fichier:Sail the world.png|150px|vignette|droite|Thème de la compétition]]
 
[[Fichier:Sail the world.png|150px|vignette|droite|Thème de la compétition]]
La Coupe de France de Robotique est un défi s’adressant à n’importe quelle équipe de jeune s’intéressant à la robotique. Les participants doivent concevoir puis réaliser un robot autonome, conforme au règlement et apte à participer aux matchs organisés. Chaque match oppose 2 robots. Le but pour chaque robot est de réaliser différentes actions afin de récolter plus de points que l’adversaire.<br>
+
La Coupe de France de Robotique est un défi s’adressant à n’importe quelle équipe de jeune s’intéressant à la robotique. Les participants doivent concevoir puis réaliser 2 robots autonomes, conformes au règlement et aptes à participer aux matchs organisés. Chaque match oppose les 2 robots d'un groupe contre les 2 robots d'un groupe adverse. Le but pour chaque robot est de réaliser différentes actions afin de récolter plus de points que l’adversaire.<br>
   −
Cette année, la coupe de France de robotique aura lieu à la Roche-Sur-Yon en Mai 2021. Le thème de cette année est “Sail the World”. Le terrain représentera une carte du monde sur laquelle se trouveront des phares, des chenaux, des gobelets (représentant des bouées), des drapeaux ou encore d’autres éléments avec lesquels pourra interagir notre robot pour gagner des points.
+
Cette année, la coupe de France de robotique aura lieu à la Roche-Sur-Yon en Juillet 2021. Le thème de cette année est “Sail the World”. Le terrain représentera une carte du monde sur laquelle se trouveront des phares, des chenaux, des gobelets (représentant des bouées), des drapeaux ou encore d’autres éléments avec lesquels pourront interagir nos robot pour gagner des points.
    
<br>
 
<br>
Ligne 40 : Ligne 42 :  
Les moteurs permettent les déplacements du robot via la rotation de ses 2 roues motrices. Les encodeurs permettent de déterminer le nombre de tours qu'a effectué chacune des roues, nous pourrons ainsi en déduire la position du robot ainsi que sa vitesse.
 
Les moteurs permettent les déplacements du robot via la rotation de ses 2 roues motrices. Les encodeurs permettent de déterminer le nombre de tours qu'a effectué chacune des roues, nous pourrons ainsi en déduire la position du robot ainsi que sa vitesse.
 
Les servomoteurs ne sont pas utilisés pour le moment.  
 
Les servomoteurs ne sont pas utilisés pour le moment.  
Enfin, le microcontrôleur STM32 nous permet de gérer le fonctionnement de robot. En effet, celui ci va exécuter le programme mis en mémoire qui envoie des consignes pour gérer le comportement de tous les composants reliés à la STM32.
+
Enfin, le microcontrôleur STM32 nous permet de gérer le fonctionnement du robot. En effet, celui ci va exécuter le programme mis en mémoire qui envoie des consignes pour gérer le comportement de tous les composants reliés à la STM32.
    
===Présentation de notre projet===
 
===Présentation de notre projet===
Ligne 128 : Ligne 130 :  
===<big>Réalisation</big>===
 
===<big>Réalisation</big>===
 
Comme vu plus haut, on part sur une solution de protection et d'alimentation gérée et coupée par une STM32. Nous allons voir ici comment nous coupons l'alimentation dans les cas de batterie faible.
 
Comme vu plus haut, on part sur une solution de protection et d'alimentation gérée et coupée par une STM32. Nous allons voir ici comment nous coupons l'alimentation dans les cas de batterie faible.
 +
Passons en revue les composants choisis.
    
====<big>Hardware</big>====
 
====<big>Hardware</big>====
 
Pour cette partie Hardware, on peut voir le schéma en entier de cette carte ci-dessous:
 
Pour cette partie Hardware, on peut voir le schéma en entier de cette carte ci-dessous:
[[Fichier:Schéma final.png|vignette|centré|Le schéma final]]
+
[[Fichier:Schéma final.png|500px|vignette|centré|Le schéma final]]
 
<br>
 
<br>
=====Circuit relais=====
+
<br>
 +
'''Circuit relais'''<br>
 +
 
 
Nous optons pour une solution de coupure à base de relais normalement ouverts. Ils seront pilotés par des transistors NMOS, et reliés à la tension 5V du µC comme on peut le voir sur le schéma ci-dessous.
 
Nous optons pour une solution de coupure à base de relais normalement ouverts. Ils seront pilotés par des transistors NMOS, et reliés à la tension 5V du µC comme on peut le voir sur le schéma ci-dessous.
 
[[Fichier:Screenshot relais.png|vignette|centré|Circuit relais]]
 
[[Fichier:Screenshot relais.png|vignette|centré|Circuit relais]]
Ligne 139 : Ligne 144 :  
Ces relais ont une résistance de 113 ohm et ont une tension de bobine de 5V. Donc ces transistors sont dimensionnés pour faire passer du 50mA dans la bobine du relais.
 
Ces relais ont une résistance de 113 ohm et ont une tension de bobine de 5V. Donc ces transistors sont dimensionnés pour faire passer du 50mA dans la bobine du relais.
 
On choisit alors de commander des NMOS CMS (boîtier SOT-23), pour prendre moins de place, c'est plus joli et ça rajoute un peu de challenge pour souder.
 
On choisit alors de commander des NMOS CMS (boîtier SOT-23), pour prendre moins de place, c'est plus joli et ça rajoute un peu de challenge pour souder.
   
<br>
 
<br>
 +
<br>
 +
'''Bus CAN'''<br>
   −
=====Bus CAN=====
   
[[Fichier:Branchement CAN.png|vignette|droite|Schéma de branchement du chip CAN]]
 
[[Fichier:Branchement CAN.png|vignette|droite|Schéma de branchement du chip CAN]]
 
On aimerait envoyer la tension de la batterie sur l'application du deuxième projet. Pour cela, il faut communiquer entre notre STM et la STM principale du robot, grâce à un bus CAN (Controller Area Network).
 
On aimerait envoyer la tension de la batterie sur l'application du deuxième projet. Pour cela, il faut communiquer entre notre STM et la STM principale du robot, grâce à un bus CAN (Controller Area Network).
 
On utilise un chip SN65HVD230, que nous câblons comme on peut le voir sur le schéma à droite.
 
On utilise un chip SN65HVD230, que nous câblons comme on peut le voir sur le schéma à droite.
   
<br>
 
<br>
 +
<br>
 +
'''Convertisseurs de tension'''<br>
   −
=====Convertisseurs de tension=====
+
[[Fichier:Screenshot 3.png|100px|vignette|droite|Convertisseur DC-DC 12V utilisé]]
[[Fichier:Screenshot 3.png|vignette|droite|Convertisseur DC-DC 12V utilisé]]
   
Pour les convertisseurs de tension, on choisit d'utiliser les convertisseurs déjà utilisés sur l'ancienne carte, et qui peuvent fournir 12V 4A pour l'un, et 5V 4A pour l'autre.
 
Pour les convertisseurs de tension, on choisit d'utiliser les convertisseurs déjà utilisés sur l'ancienne carte, et qui peuvent fournir 12V 4A pour l'un, et 5V 4A pour l'autre.
 
Les références:
 
Les références:
 
*12V: JCK5012S12
 
*12V: JCK5012S12
 
*5V: JCK2012S05  
 
*5V: JCK2012S05  
 +
Pour alimenter la Raspberry, il nous fallait la possibilité de pouvoir régler la tension précisément. En effet, si on l'alimente avec une tension juste en dessous de 5V, la Raspberry va fonctionner mais avec une fréquence grandement réduite. Ainsi, il est conseillé de lui fournir du 5.2V pour avoir un fonctionnement optimal. On a donc choisi d'utiliser un petit module Buck réglable grâce à un petit potentiomètre. Une fois la tension fixée, on empêche la vis de tourner grâce à un peu de colle chaude.
 +
On a également ajouté des fusibles avant les convertisseurs, pour protéger coûte que coûte.
 +
[[Fichier:LM2937IMP.jpg|100px|vignette|droite|Convertisseur LM2937IMP-5.0]]
 +
Pour alimenter le µC STM32, on a choisi un petit convertisseur de tension LM2937IMP-5.0, en boîtier SOT-223 (SMD) avec un petit radiateur pour refroidir ce composant car il chauffe très rapidement.
 
<br>
 
<br>
 +
<br>
 +
'''Connecteurs'''<br>
   −
=====Connecteurs=====
   
Pour les connecteurs, nous avons décidé d'utiliser des XT-60 pour connecter la batterie, le bouton d'arrêt d'urgence et le contrôleur moteur (qui est en série avec l'arrêt d'urgence et la batterie). Ce choix a été fait car ces connecteurs sont bien connus pour pouvoir faire passer beaucoup de puissance, et sont en général la référence dans les batteries Lipo.
 
Pour les connecteurs, nous avons décidé d'utiliser des XT-60 pour connecter la batterie, le bouton d'arrêt d'urgence et le contrôleur moteur (qui est en série avec l'arrêt d'urgence et la batterie). Ce choix a été fait car ces connecteurs sont bien connus pour pouvoir faire passer beaucoup de puissance, et sont en général la référence dans les batteries Lipo.
 
Pour les sorties en tension 12V et 5V, nous utilisons des borniers à vis, doublés avec des connecteurs JST, si jamais on choisi de faire des connecteurs permanents pour plus de facilité.
 
Pour les sorties en tension 12V et 5V, nous utilisons des borniers à vis, doublés avec des connecteurs JST, si jamais on choisi de faire des connecteurs permanents pour plus de facilité.
 
On a choisi d'utiliser un connecteur JST pour alimenter la Raspberry, pour avoir un connecteur permanent qui est propre et sans risque de court-circuit comme avec les borniers à vis où il peut y avoir quelques brins d'un des fil qui s'en échappe.
 
On a choisi d'utiliser un connecteur JST pour alimenter la Raspberry, pour avoir un connecteur permanent qui est propre et sans risque de court-circuit comme avec les borniers à vis où il peut y avoir quelques brins d'un des fil qui s'en échappe.
 
<br>
 
<br>
 +
<br>
 +
'''Microcontrôleur'''<br>
   −
=====Microcontrôleur=====
   
Nous avons choisit un contrôleur NUCLEO32-F303K8 qui nous permet de réaliser ces fonctions:
 
Nous avons choisit un contrôleur NUCLEO32-F303K8 qui nous permet de réaliser ces fonctions:
 
* Envoi par le bus CAN
 
* Envoi par le bus CAN
Ligne 171 : Ligne 182 :  
Ce µC est monté sur des connecteurs pin femelle, ce qui nous permet de le changer facilement si jamais un soucis arrive, et qu'un remplacement est nécessaire.
 
Ce µC est monté sur des connecteurs pin femelle, ce qui nous permet de le changer facilement si jamais un soucis arrive, et qu'un remplacement est nécessaire.
 
<br>
 
<br>
 +
<br>
 +
'''LED et Buzzer'''<br>
 +
 +
Comme vu auparavant, nous avons choisi une LED et un buzzer pour prévenir quand la batterie atteint un niveau assez bas.
 +
On connecte ces composants sur des pattes du contrôleur où il y a un timer. Ainsi, on peut facilement faire clignoter la LED et faire fonctionner le buzzer. Nous avons cependant commis une erreur que nous avons corrigé sur la deuxième carte (que nous verrons plus tard): nous n'avons pas mis de transistor pour piloter le buzzer, ce qui fonctionne, mais qui risque de cramer la patte de sortie si on n'a pas de chance. Donc pour être sur, il vaut mieux piloter le buzzer avec un transistor et y ajouter une diode de roue libre pour décharger sa bobine.
 +
<br>
 +
<br>
 +
'''Liste des composants'''<br>
 +
{| class="wikitable"
 +
|-
 +
! Description !! Réferences !! Lien
 +
|-
 +
| Relais || HF118F || https://fr.rs-online.com/web/p/relais-sans-accrochage/1762821/
 +
|-
 +
| Transistors NMOS || IRLML2402TRPBF || https://fr.farnell.com/infineon/irlml2402pbf/transistor-mosfet-canal-n-logique/dp/9102710
 +
|-
 +
| Convertisseur 5V - 3A || Buck Converter || https://www.dfrobot.com/product-1552.html
 +
|-
 +
| Convertisseur 5V - 4A || JCK2012S05 || https://fr.farnell.com/xp-power/jck2012s05/converter-dc-dc-20w-5v/dp/1738247
 +
|-
 +
| Convertisseur 12V - 4A || JCK5012S12 || https://www.mouser.fr/ProductDetail/XP-Power/JCK5012S12?qs=w%2Fv1CP2dgqouNLoOdGyFaQ%3D%3D
 +
|-
 +
| Connecteurs XT60 pcb femelle || RS PRO || https://fr.rs-online.com/web/p/connecteurs-de-puissance-compacts/1805374/
 +
|-
 +
| Connecteurs XT60 Mâle || RS PRO || https://fr.rs-online.com/web/p/connecteurs-de-puissance-compacts/1805365/
 +
|-
 +
| Fusible 4A|| RS PRO || https://fr.rs-online.com/web/p/fusibles-cartouches/0563542/
 +
|-
 +
| Porte fusible || RS PRO || https://fr.rs-online.com/web/p/porte-fusible-pour-ci/6119302/
 +
|-
 +
| STM32 || Nucleo-F303K8 || https://fr.farnell.com/stmicroelectronics/nucleo-f303k8/carte-de-dev-nucleo-32-mcu/dp/2500224
 +
|-
 +
| Régulateur 5V || LM2937IMP-5.0 || https://fr.farnell.com/stmicroelectronics/nucleo-f303k8/carte-de-dev-nucleo-32-mcu/dp/2500224
 +
|-
 +
| CAN transceiver || SN65HVD ||
 +
|}
 +
<br>
 +
<br>
 +
 +
====<big>Software</big>====
 +
Pour la partie software nous utilisons le logiciel de développement de ST Cube ide. L’extension Cube MX permet de générer le code d’initialisation et la configuration des différentes pattes associé à la référence de notre microcontrôleur (NUCLEO32-F303K8).
 +
 +
Dans un premier temps le  but de notre partie software est de récupérer la valeur précise de la batterie sur l’ADC pour pouvoir piloter les signaux d’alertes (led, buzzer) et ouvrir les circuits en fonction du niveau de décharge de la batterie.
 +
Ensuite nous souhaitons mettre en place un bus CAN pour communiquer avec la carte STM principale pour lui permettre de commander les relais via l'application développée par l'autre binôme de notre projet.
 +
<br>
 +
<br>
 +
'''Configuration de l’ADC'''
 +
<br>
 +
<br>
 +
Dans un premier temps nous avons mit en place un pont diviseur directement relié a la patte de l’ADC (PA0) qui supporte une tension de 0V à 3,3V. La résolution de 12 bit nous donne donc une valeur de 0 à 4096 exploitable pour cette plage de tension. La décharge de la batterie compris entre 17V et 13V correspond à une variation de 2,87V à 2,19V soit de 3400 à 2685. L’ADC fonctionne en «polling mode» : Il démarre, charge un condensateur pendant 10 ms , lit puis stock cette valeur dans une variable puis s’arrête jusqu’à la prochaine boucle.                                   
 +
<br>
 +
<br>
 +
'''Configuration des timers'''
 +
<br>
 +
<br> 
 +
Pour piloter le buzzer et la led en fonction du niveau de la batterie, nous devons mettre en place des signaux PWM générés par des timers. Pour cela nous configurons l’horloge des timers à 16Mhz. CubeMX nous permet de régler ensuite le préscaler qui divise la fréquence. Ensuite il nous reste à régler le counter_périod qui est un registre de 16 bits qui compte de 0 à 65536, cela nous permet d’avoir la fréquence souhaitée. <br>
 +
Pour le buzzer le préscaler est à 16 (1Mhz) et le  counter_périod est à 2272 pour donner un avertissement sonore en La (440hz) .
 +
Pour la led nous avons un préscaler de 1000 (16khz) et un  counter_period de 8000 pour un clignotement de (2hz).
 +
<br>
 +
<br>
 +
'''Signaux d’alerte et coupure des circuits en fonction de la décharge de la batterie'''
 +
<br>
 +
<br>
 +
[[Fichier:Configuration CubeMX|vignette|droite|Configuration CubeMX STM32F303K8]]
 +
 +
{| class="wikitable"
 +
|-
 +
! Tension de la batterie !! Valeur adc !!% de décharge !! Action
 +
|-
 +
| 17 V || 100% || 3400 ||
 +
|-
 +
| 16,16 V || 80% || 3255 ||
 +
|-
 +
| 15,32 V || 60% || 3115 ||
 +
|-
 +
| 14,48 V || 40% || 2980 || Led clignote
 +
|-
 +
| 14.06 V || 30% || 2930 || Buzzer alerte
 +
|-
 +
| 13,64 V || 20% || 2880|| Coupure des circuit de puissance 12V , 5V et des moteurs
 +
|-
 +
| 13.32 V || 10% || 2720 || Coupure de la Raspberry
 +
|-
 +
| 13 V ||  0% || 2685 || Seuil critique
 +
|}   
 +
<br>
 +
 +
===<big>2e Carte Compacte Intégrée</big>===
 +
Nous avons voulu faire une deuxième carte d'alimentation sur le même cahier des charges, mais pour le deuxième robot qui est plus petit. Ainsi la carte ne devra pas dépasser les 10cm de côté. Pour arriver à ce résultat, et pour avoir plus de challenge pour la fin, nous avons décidé d'intégrer directement le chip STM32F405RGT6 sur le pcb, et d'y inclure tout ses composants essentiels: le quartz, les nombreuses capacités de découplage, le bouton reset, le pull-down du pin BOOT0, et le connecteur pour le ST-Link, pour programmer.
 +
Aussi, grâce à l'expérience gagnée avec la première carte, cette carte qui est plus petite et plus complexe, a été plus rapide à designer que la première. C'est aussi parce qu'il n'y avait pas toute la partie puissance à refaire (car le cahier des charges ne change pas).
 +
<br>
 +
====<big>Réalisation</big>====
 +
Nous allons voir ici ce qu'il y a en plus ou ce qui a changé par rapport à la première carte. Ci-dessous, le schéma en entier.
 +
[[Fichier:Schéma.png|vignette|centré|Schéma de la 2e carte de puissance avec STM intégrée]]
 +
 +
<br>
 +
'''Micro Controller'''<br>
 +
Nous avons choisi le µC STM32F405RGT6 pour cette application car il a des CAN, et suffisamment d'entrées/sorties pour nous permettre de remplir les fonctions de base et même d'ajouter des LED (nous verrons pourquoi dans la partie dédiée). Nous configuré les pattes de ce contrôleur dans CubeMX, avec la configuration que vous pouvez voir ci-dessous.
 +
[[Fichier:CubeMX 2e carte.png|vignette|centré|Les différents branchements du chip]]
 +
Ce composant a besoin de certains autres composants pour fonctionner tel que le quartz (ici un quartz 16MHz). Il faut aussi ajouter une capacité de découplage par patte VDD.
 +
Pour l'alimentation de ce composant (3.3V) on choisit d'utiliser un circuit intégré buck (MP2451), et lui ajouter les capacités et bobine nécessaires. On y ajoute une led pour indiquer que la tension est bien présente.
 +
Il faut également filtrer cette alimentation avec une perle de ferrite et des capacités pour alimenter l'ADC. En effet, sa tension doit être extrêmement stable pour pouvoir faire des mesures précises.
 +
<br>On peut voir tout ça sur le schéma au début de cette section.
 +
 +
<br>
 +
'''Signaux d'alerte'''<br>
 +
A la place d'une LED, comme dans la 1ere carte, on en met 4. Ces LED vont indiquer le niveau de la batterie: A 20% de batterie, une seule est allumée. A 40%, deux sont allumées. A 60%, 3 sont allumées et à 80%, elles sont toutes allumées. Cela va permettre de voir facilement Le niveau de charge. Le buzzer s'allume toujours à 30% de charge et les coupures se font toujours à 20% et 10%. Le buzzer est maintenant piloté par un MOSFET, pour éviter le risque de "cramer" la patte de sortie de la STM.
 +
 +
<br>
 +
'''Routage du PCB'''<br>
 +
C'est la partie la plus complexe, puisqu'il faut réussir à placer tout les composants dans un espace réduit de maximum 10x10cm. En réétudiant le placement, on arrive à tout faire rentrer. On a enlevé les connecteur JST, et laissé les borniers à vis pour gagner de la place, et on met uniquement un seul connecteur pour la sortie moteurs. En faisant le placement, on fait bien attention au chevelu, qui nous indique globalement les futures pistes. De cette façon, le routage sera effectué sans encombre, et sans devoir déplacer des composants après coup.<br>
 +
On choisit de faire une carte à 4 couches. De cette manière, on peut ajouter certains plans sur certaines couches, comme sur le tableau ci-dessous qui montre notre répartition des couches.
 +
{| class="wikitable"
 +
|-
 +
! Couche !! Pistes / Plans
 +
|-
 +
| 1 ||  Signaux + Plan GND
 +
|-
 +
| 2 ||  Plan GND
 +
|-
 +
| 3 || Plan 3.3V
 +
|-
 +
| 4 || Signaux + Plan GND
 +
|}
 +
Grâce à ces plans, on peut simplifier le routage en utilisant des vias pour aller chercher le 3.3V ou le GND à n'importe quel endroit sans devoir faire de grandes pistes. <br>
 +
Ainsi, on peut passer au routage, et comme prévu, le placement était assez bien fait pour ne pas avoir à déplacer de composants. On obtient ce résultat:
 +
[[Fichier:Routage2eCarte.png|vignette|centré|Routage de la 2e carte]]
 +
Les plans ne sont pas affichés ici, pour que les pistes soient bien visibles.
 +
On peut voir sur ce routage toutes les pistes qui partent du chip, on trouve ça plutôt joli.
 +
A gauche du chip, il y a toute la partie quartz. Au dessus, on peut voir la partie Buck Converter. A droite, il y a la partie CAN, et le connecteur pour programmer et débugger le chip "JLink1". En dessous, il y a l'espace pour le bouton, le buzzer et les LED de niveau de batterie. A gauche du Buck, on peut y voir le pont diviseur de tension qui adapte la tension de la batterie pour pouvoir la mesurer avec l'ADC.
 +
<br>
 +
Cette carte ayant beaucoup de composants CMS, nous pouvons directement choisir l'option de JLC PCB: ils peuvent souder tous les composants CMS de la carte. C'est très pratique car pour souder la STM à la carte, ça risque d'être très complexe. Ainsi dans cette optique on configure les fichiers .BOM (Bill of Materials) avec la colonne LCSC remplie avec les noms de composants de la librairie de composants de JLC PCB. On Génère aussi un fichier de placement des composants, pour qu'ils puissent les placer au bon endroit et dans le bon sens. Ces fichiers sont dans le GIT, dans le répertoire "assembly" du projet KiCad de notre branche "Power Module".
 +
Ci-dessous, on peut voir la vue 3D de la nouvelle carte:
 +
[[Fichier:Carte 3D - Copie.png|vignette|centré|Vue 3D de la carte intégrée]]
    
==Projet 2 : Écran de contrôle==
 
==Projet 2 : Écran de contrôle==
Ligne 177 : Ligne 322 :  
[[Fichier:Mode de comm.png|vignette|droite|Différents modes de communication]]
 
[[Fichier:Mode de comm.png|vignette|droite|Différents modes de communication]]
 
* Système fiable, donc plateforme Raspberry/STM et moyen de communication RF/bluetooth/WiFi à choisir par rapport à ça.
 
* Système fiable, donc plateforme Raspberry/STM et moyen de communication RF/bluetooth/WiFi à choisir par rapport à ça.
* Documentation du projet sur le wiki polybot
   
* Affichage des infos telles que:  
 
* Affichage des infos telles que:  
 
**Les coordonnées des robots  
 
**Les coordonnées des robots  
Ligne 205 : Ligne 349 :     
'''Étapes principales du projet 2'''<br>
 
'''Étapes principales du projet 2'''<br>
Nous avons réfléchis aux grandes étapes qui vont composer ce projet :  
+
Dès le début, nous avons réfléchis aux grandes étapes qui allaient composer ce projet :  
 
* Le choix, la commande et le montage des composants
 
* Le choix, la commande et le montage des composants
 
* La communication entre la STM32 et le module HC-06
 
* La communication entre la STM32 et le module HC-06
Ligne 217 : Ligne 361 :  
'''Choix du protocole de communication'''
 
'''Choix du protocole de communication'''
   −
Pour répondre au cahier des charges, nous avons choisi d'utiliser une communication Bluetooth pour envoyer les données souhaitées à depuis notre microcontrôleur STM32. En effet, il s'agit d'un moyen de communication suffisamment fiable et plutôt simple à implémenter. De plus, nous n'avons pas besoin d'une grande distance de fonctionnement, ni de beaucoup de stockage. Le Bluetooth semble donc être une solution adaptée pour répondre à notre cahier des charges.
+
Pour répondre au cahier des charges, nous avons choisi d'utiliser une communication Bluetooth pour envoyer les données souhaitées depuis notre microcontrôleur STM32. En effet, il s'agit d'un moyen de communication suffisamment fiable et plutôt simple à implémenter. De plus, nous n'avons pas besoin d'une grande distance de fonctionnement, ni de beaucoup de stockage. Le Bluetooth semble donc être une solution adaptée pour répondre à notre cahier des charges.
 
<br>  
 
<br>  
 
<br>
 
<br>
 
'''Choix et commande des des composants'''<br>
 
'''Choix et commande des des composants'''<br>
Après quelques recherches, nous avons découvert le module HC-06 qui permet de réaliser une liaison Bluetooth entre des microcontrôleurs et un autre appareil. Nous avons donc commandé ce composant en double. Il s'agit du seul matériel que nous avons eu besoin de commander pour ce projet.
+
Après quelques recherches, nous avons découvert le module HC-06 qui permet de réaliser une liaison Bluetooth entre un microcontrôleur et un autre appareil. Nous avons donc commandé ce composant en double (coût total : 20€). Il s'agit du seul matériel que nous avons eu besoin de commander pour ce projet.
 
[[Fichier:Nucleo et HC-06.png|300px|Connexion STM et HC-06 (dans le cas du protocole UART1)|vignette]]
 
[[Fichier:Nucleo et HC-06.png|300px|Connexion STM et HC-06 (dans le cas du protocole UART1)|vignette]]
   Ligne 228 : Ligne 372 :  
'''Montage des composants'''<br>
 
'''Montage des composants'''<br>
   −
Concernant le montage du montage sur la STM32, il suffit de brancher les 4 pins du module sur la STM32 :  
+
Concernant le montage du montage sur la STM32, il suffit de brancher les 4 pins du module sur la STM32 en fonction du protocole de communication choisi :  
    
{| class="wikitable"
 
{| class="wikitable"
Ligne 245 : Ligne 389 :  
===Communication STM/HC-06===
 
===Communication STM/HC-06===
 
'''Protocoles de communication existants'''<br>
 
'''Protocoles de communication existants'''<br>
Après avoir connecté notre module Bluetooth HC-06 à la STM, il faut maintenant réaliser une communication entre les 2 composants pour envoyer les informations souhaitées sur le module HC-06 qui transmettra ensuite ces informations à notre application via Bluetooth. Il existe différents protocoles de communication comme le SPI, I2C, UART, CAN... Après quelques recherches, nous nous sommes rendus compte que pour ce genre de système, l'UART offrait une communication série fiable et plutôt simple à implémenter.
+
Après avoir connecté notre module Bluetooth HC-06 à la STM, il faut maintenant réaliser une communication entre les 2 composants pour envoyer les informations souhaitées sur le module HC-06 qui transmettra ensuite ces informations à notre application via Bluetooth. Il existe différents protocoles de communication comme le SPI, I2C, UART, CAN...  
Nous avons donc choisi d'utiliser le protocole UART et plus particulièrement l'UART3 de la SMT32 car il n'est pas encore utilisé par le robot (l'UART1 et 2 étaient déjà pris). On branchera donc la pin RXD du module Bluetooth sur la pin PB10 de la STM32 et la pin TXD du module sur la pin PC5 de la STM32.
      
*La liaison UART (Universal Asynchronous Receiver Transmitter) est une liaison “point à point”, ce qui signifie que deux dispositifs numériques sont connectés entre eux directement, sans passer par un routeur ou tout dispositif qui permettrait d’aiguiller des trames venant d’un émetteur vers plusieurs récepteurs. Une liaison “point à point” est clairement une version très simple et rudimentaire de liaison série. Il existe d’autres normes que la liaison UART en mode “point à point” mais c’est la plus utilisée car, comme son nom l'indique, elle revendique d’être universelle.
 
*La liaison UART (Universal Asynchronous Receiver Transmitter) est une liaison “point à point”, ce qui signifie que deux dispositifs numériques sont connectés entre eux directement, sans passer par un routeur ou tout dispositif qui permettrait d’aiguiller des trames venant d’un émetteur vers plusieurs récepteurs. Une liaison “point à point” est clairement une version très simple et rudimentaire de liaison série. Il existe d’autres normes que la liaison UART en mode “point à point” mais c’est la plus utilisée car, comme son nom l'indique, elle revendique d’être universelle.
 
*On distingue ensuite les liaisons multipoints à bas débit. On connait par exemple le CAN (pour Controller Area Network) utilisé notamment dans l’automobile. L’idée, dans l’automobile ou dans les véhicules en général, est de diminuer les kilomètres de câbles qui permettent de relier tous les dispositifs numériques entre eux, en connexions point à point. C’est donc un BUS (pour Bit Unit System) qui relie en mode multipoint tous les systèmes numériques entre eux (l’ABS, le contrôle de trajectoires ESP, les éléments de confort, climatisation, chauffage, etc.). Une unité centrale envoie des trames que tous les dispositifs esclaves reçoivent, mais dans la trame figure également le destinataire qui seul exécutera la commande correspondante.
 
*On distingue ensuite les liaisons multipoints à bas débit. On connait par exemple le CAN (pour Controller Area Network) utilisé notamment dans l’automobile. L’idée, dans l’automobile ou dans les véhicules en général, est de diminuer les kilomètres de câbles qui permettent de relier tous les dispositifs numériques entre eux, en connexions point à point. C’est donc un BUS (pour Bit Unit System) qui relie en mode multipoint tous les systèmes numériques entre eux (l’ABS, le contrôle de trajectoires ESP, les éléments de confort, climatisation, chauffage, etc.). Une unité centrale envoie des trames que tous les dispositifs esclaves reçoivent, mais dans la trame figure également le destinataire qui seul exécutera la commande correspondante.
 
*Enfin, on distingue les liaisons multipoints à haut débit comme Ethernet, mis en œuvre pour Internet, USB ou FireWire.
 
*Enfin, on distingue les liaisons multipoints à haut débit comme Ethernet, mis en œuvre pour Internet, USB ou FireWire.
 +
 +
Après quelques recherches, nous nous sommes rendus compte que pour ce genre de système, l'UART offrait une communication série fiable et plutôt simple à implémenter.
 +
Nous avons donc choisi d'utiliser le protocole UART et plus particulièrement l'UART4 de la SMT32 car il n'est pas encore utilisé par le robot (l'UART1, 2 et 3 étaient déjà pris). On branchera donc la pin RXD du module Bluetooth sur la pin PA0 de la STM32 et la pin TXD du module sur la pin PA1 de la STM32. Une carte fille ajoutée sur l'Arduino nous donne accès aux pin de l'UART4 plus facilement, on pourra donc l'utiliser à cet endroit là si nécessaire.
    
<br>'''Présentation du protocole UART'''<br>
 
<br>'''Présentation du protocole UART'''<br>
Ligne 264 : Ligne 410 :  
<br>
 
<br>
 
Quand on initialise la liaison (il faut le faire du côté émetteur et aussi du côté récepteur), il faut initialiser de façon cohérente des deux côtés de la liaison. En particulier, il faut régler la vitesse de transmission sur l’une des vitesses standard (le Baudrate).
 
Quand on initialise la liaison (il faut le faire du côté émetteur et aussi du côté récepteur), il faut initialiser de façon cohérente des deux côtés de la liaison. En particulier, il faut régler la vitesse de transmission sur l’une des vitesses standard (le Baudrate).
Pou ce projet, nous allons utiliser un baudrate de 9600 qui correspond à 9600 bits par seconde. C’est suffisamment rapide pour que la transmission de quelques chaînes de caractères assez courtes semble instantanée, et suffisamment lent pour permettre au code STM de tourner.
+
Pou ce projet, nous allons utiliser un baudrate de 9600 qui correspond à 9600 bits par seconde. C’est suffisamment rapide pour que la transmission de quelques chaînes de caractères assez courtes semble instantanée, et suffisamment lent pour permettre au code STM de tourner.  
    
<br>
 
<br>
 
'''Réalisation de la communication via UART'''<br>
 
'''Réalisation de la communication via UART'''<br>
 +
[[Fichier:Config.png|vignette|droite|Configuration STMCube]]
 
Pour réaliser la communication UART entre la STM32 et notre module Bluetooth, on commence par brancher les câbles comme mentionnées un peu plus haut. On doit ensuite configurer notre projet sur STMCubeIDE. Pour cela il suffit de sélectionner l'UART, de l'activer puis de régler certains paramètres.
 
Pour réaliser la communication UART entre la STM32 et notre module Bluetooth, on commence par brancher les câbles comme mentionnées un peu plus haut. On doit ensuite configurer notre projet sur STMCubeIDE. Pour cela il suffit de sélectionner l'UART, de l'activer puis de régler certains paramètres.
On pourra ainsi modifier le baudrate, la structure de la trame (nombre de bit de stop, nombre de bits de données...), activer ou non les interruptions...
+
On pourra ainsi modifier le baudrate, la structure de la trame (nombre de bit de stop, nombre de bits de données...), activer ou non les interruptions... Dans notre cas, on choisira le mode Asynchrone pour l'UART, un baudrate de 9600 et on activera les interruptions.
[[Fichier:Baudrate.png|vignette|centré|Réglage des paramètres de l'UART3]]
     −
Une fois ces réglages réalisés, notre communication est opérationnelle. On pourra ainsi utiliser différentes fonctions dans le code de la STM32 pour envoyer les données sur les pins de l'UART3.
+
Une fois ces réglages réalisés, notre communication est opérationnelle. On pourra ainsi utiliser différentes fonctions dans le code de la STM32 pour envoyer les données sur les pins de l'UART4.
 
On utilisera par exemple les fonctions :  
 
On utilisera par exemple les fonctions :  
*HAL_UART_Transmit_IT(&huart3, (uint8_t*) txt_a_envoyer ",sizeof(txt_a_envoyer));
+
'''HAL_UART_Transmit_IT'''(&huart4, (uint8_t*) txt_a_envoyer,sizeof(txt_a_envoyer));
*HAL_Delay(temps) qu'on remplacera par osDelay(temps) avec l'utilisation de FreeRTOS
+
'''HAL_Delay'''(temps) qu'on remplacera par osDelay(temps) avec l'utilisation de FreeRTOS
 +
 
 +
La fonction HAL_UART_Transmit permet de transmettre une chaine de caractère sur l'UART souhaité. Les fonctions HAL_Delay et osDelay permettent d'ajouter un temps d'attente entre les différents Transmit afin de laisser suffisamment de temps au microcontrôleur pour envoyer les données.
 +
[[Fichier:Config uart4.png|vignette|centré|Réglage des paramètres de l'UART4]]
    
On pourra ainsi envoyer des données et aller les récupérer via un terminal (connecté au module Bluetooth) ou a une application.
 
On pourra ainsi envoyer des données et aller les récupérer via un terminal (connecté au module Bluetooth) ou a une application.
Ligne 286 : Ligne 435 :  
Nous allons donc afficher les données suivantes :
 
Nous allons donc afficher les données suivantes :
 
*Tension de la batterie
 
*Tension de la batterie
*Encodeurs (nombre de tours réalisé par chaque encodeur)
+
*Distance parcourue
 
*Vitesse du robot
 
*Vitesse du robot
 
*Coordonnées du robot (position)
 
*Coordonnées du robot (position)
 
*Trajectoire (peut-être), le but serait qu'à la fin du parcours on affiche graphiquement la trajectoire qu'a emprunté le robot. Mais à voir si cela est possible et utile surtout
 
*Trajectoire (peut-être), le but serait qu'à la fin du parcours on affiche graphiquement la trajectoire qu'a emprunté le robot. Mais à voir si cela est possible et utile surtout
   −
Nous aimerions également pouvoir stocker les données recueillies pendant le parcours du robot. Toutes ces informations pourraient nous permettre pendant le parcours de vérifier le bon fonctionnement du robot. En cas d'erreur/problème/bug on pourra étudier les données stockées pour tentant de trouver l'origine du problème. A MODIFIER EN FONCTION DE NOTRE AVANCEMENT
+
Nous aimerions également pouvoir stocker les données recueillies pendant le parcours du robot. Toutes ces informations pourraient nous permettre pendant le parcours de vérifier le bon fonctionnement du robot. En cas d'erreur/problème/bug on pourra étudier les données stockées pour tentant de trouver l'origine du problème.
   −
On pense également qu'il pourrait être intéressant de rajouter une option sur l'écran de contrôle permettant l'arrêt d'urgence du robot en cas de problème détecté. Pour cela, nous avons travaillé avec Florian et Flavien qui travaillent sur la carte de puissance pour qu'ils intègrent cela à leur système. A MODIFIER EN FONCTION DE NOTRE AVANCEMENT
+
On pense également qu'il pourrait être intéressant de rajouter une option sur l'écran de contrôle permettant l'arrêt d'urgence du robot en cas de problème détecté. Pour cela, nous avons travaillé avec Florian et Flavien qui travaillent sur la carte de puissance pour qu'ils intègrent cela à leur système.  
    
<br>
 
<br>
 
'''Affichage des valeurs souhaitées'''<br>
 
'''Affichage des valeurs souhaitées'''<br>
Dans notre code
+
Pour transmettre les différentes valeurs souhaitées, nous avons ajouté dans le code de la STM les fonctions mentionnées plus haut.  
Pour transmettre les différentes valeurs, nous avons donc utilisé les fonctions mentionnées plus haut.  
+
On envoie ensuite les données dans un ordre précis : on commence par envoyer le flag qui va nous permettre de marquer le début de chaque nouveau while, nous avons choisi de lui donner la valeur -9999 car cette valeur ne peut être atteinte par aucune autre données que nous affichons. Il n'y a donc pas de problème possible de ce côté là. Ce flag nous sera utile pour la suite car cela signalera à l'application qui réceptionne les données quand nous serons au début de la boucle while du code. Cela permet donc de synchroniser l'envoi des données.
On commence par envoyer le flag, nous avons choisi de lui donner la valeur -100. Ce flag nous sera utile pour la suite car cela signalera à l'application qui réceptionne les données quand nous serons au début de la boucle while du code. Cela permet donc de synchroniser l'envoi des données.
   
On convertit ensuite chacune des valeurs a envoyer en texte afin de pouvoir les envoyer sous forme de texte à l'aide de la fonction sprintf.
 
On convertit ensuite chacune des valeurs a envoyer en texte afin de pouvoir les envoyer sous forme de texte à l'aide de la fonction sprintf.
*parler de la synchronisation de la clock de l'appli avec la synchronisation des Delay.
+
*On synchronise donc les données de manières temporelles, afin que l'application reçoive les données régulièrement et ait le temps de les traiter et de les afficher, d'où la présence de "osDelay" dans le code de la STM32. Il faut aussi accorder l'horloge de l'application afin qu'elle soit en phase avec le code de la STM32. Par exemple, si on choisit d'écrire dans le code de la STM "osDelay(200)" entre chaque Transmit alors on devra régler la Clock de l'application sur 200. Si on ne fait pas ça l'affichage ne sera pas synchronisé.
*parler de la valeur du flag
  −
*parler de comment on récupére les données dans le code du robot (encodeurs et tension)
  −
*parler des calculs pour déterminer les valeurs de la vitesse et de la position.
  −
*parler des différentes lignes de code : sprintf, hal_uart_transmit, osDelay(200)...
  −
*dire qu'après on peut tester sur le vrai robot
     −
Par exemple l'image ci-dessous avec des valeurs fictives (compteurs qui s'incrémente) :
+
*Concernant la valeur de la tension de la batterie, il faut récupérer cette valeur sur le bus CAN1 car elle est gérée par une autre STM32 qui communique avec la STM principale par bus CAN. La communication n'étant pas encore en place, nous ne pouvons pas encore récupérer la valeur de tension. De ce fait, nous retournons une valeur fixe de 17V. Lorsque la communication avec le bus CAN sera réalisée, il sera possible de modifier la fonction pour que l'on renvoie la valeur réelle de la tension.
 +
 
 +
*Pour calculer la vitesse du robot, sa position et la distance parcourue, on a besoin de récupérer les valeurs renvoyées par les encodeurs. Les encodeurs nous indique précisément le nombre de tours qu'a réalisé chaque roue du robot. Ils sont gérés par un contrôleur MCP233 sur le robot, qui est connecté à l'UART1 de la STM. On doit donc récupérer les valeurs des encodeurs à travers l'UART1 et le MCP233. On utilise des fonctions déjà crées par les équipes de Polybot, à savoir :
 +
uint8_t '''MCP233_readEncoderCountM1'''(MCP233_t *mcp, int32_t *count)
 +
uint8_t '''MCP233_readEncoderCountM2'''(MCP233_t *mcp, int32_t *count)
 +
Ces fonctions permettent de récupérer les valeurs d'incrémentation des encodeurs et les stockent à des adresses (int32_t *count). L'argument (MCP233_t *mcp) permet quant à lui de lire dans le contrôleur MCP233. <br>
 +
 
 +
*Afin d'obtenir les différentes données à envoyer, à savoir la vitesse, la distance parcourue, ainsi que la position (x,y) du robot, nous devons mettre en place des calculs spécifiques. On notera que l'on ne peut pas reset les encodeurs au début de chaque boucle (plus facile pour calculer la différence de tour par rapport à la boucle précédente) car ceux ci servent aussi à asservir les moteurs du robot en position. On va donc d'abord mettre en place quelques lignes permettant de faire nos calculs comme si nous avions un reset des encodeurs. On commence par stocker les valeurs des encodeurs avant que ceux ci soient mis à jour avec la fonction de lecture des encodeurs, on récupère ensuite les nouvelles valeurs puis on réalise la différence entre ces 2 valeurs. On obtient alors le nombre de tours en plus (ou en moins dans le cas d'une marche arrière) par rapport au while précédent.
 +
encRg_save = encRg;
 +
encRd_save = encRd;
 +
MCP233_readEncoderCountM1(&mcp,&encRg);
 +
MCP233_readEncoderCountM2(&mcp,&encRd);
 +
encRg = encRg - encRg_save;
 +
encRd = encRd - encRd_save;
 +
On en vient maintenant aux calculs en eux même. Pour la distance totale parcourue, on met en place des variables qui calculent le cumul des incréments des encodeurs depuis le démarrage du robot, on calcule ensuite la moyenne des valeurs (des 2 encodeurs) afin d'obtenir la distance parcourue par le centre du robot. Finalement, on vient multiplier cette résultante par 2*pi*R/incr (incr étant le nombre incréments de l'encodeurs lorsqu'il effectue un tour et R le rayon des encodeurs). Dans notre cas on aura incr = 4096 et R=44mm. <br>
 +
distRd = distRd + encRd; 
 +
distRg = distRg + encRg; 
 +
distTot = ((M_PI*2*R/incr)*(distRd+distRg))/2;  (à noter que le résultat est en mm ici)
 +
Pour la vitesse, on doit d'abord calculer la distance parcourue par le robot entre 2 prises de valeurs d'encodeurs, afin d'avoir une vitesse le plus instantané possible. On calcule donc cette distance exactement de la même manière que précédemment sauf qu'on ne cumule pas les valeurs d'incréments des encodeurs, en effet, on veut ici les valeurs d'incrémentation momentanées. On vient ensuite faire un rapport dist/time (dist étant la valeur que l'on vient de calculer, time étant le temps d'exécution d'une boucle d'envoie des données, on estime sa valeur par rapport aux "osDelay") : <br>
 +
dist = (M_PI*2*R/incr)*((encRd+encRg)/2); //en mm 
 +
speed = (dist/time)*100; // en cm/s 
 +
Pour la position (x,y) du robot, on calcule d'abord l'angle du robot par rapport à son angle d'origine : <br>
 +
angle = ((M_PI*2*R/incr)*((distRd-distRg)/LargRobot));  //angle en radian 
 +
On calcule ensuite les positions x et y en faisant respectivement le cosinus et sinus de l'angle multiplié par la distance parcourue entre 2 relevés d'encodeurs auxquels on ajoute les positions precédentes afin de pouvoir voir le robot se déplacer comme s'il était dans un repère orthonormé : <br>
 +
posx = (cos(angle)*dist)+posx;  //posx en mm 
 +
posy = (sin(angle)*dist)+posy;  //posy en mm 
 +
*On en vient maintenant à l'envoie des données. On commence par concaténer nos valeurs à envoyer dans des buffer char grâce à la fonction sprintf :  <br>
 +
sprintf(buff_enco,"%5d",(int)distTot);    // distance parcourue en mm 
 +
sprintf(buff_tens,"%5d",(int)Voltage);    // pas encore opérationnel 
 +
sprintf(buff_vit,"%5d",(int)speed); 
 +
sprintf(buff_posx,"%5d",(int)posx);    // en mm 
 +
sprintf(buff_posy,"%5d",(int)posy);    // en mm 
 +
On passe ensuite à l'envoie. On utilise la fonction mise à disposition par l'outil STM32CubeIDE : <br>
 +
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 
 +
L'argument (UART_HandleTypeDef *huart) sert à sélectionner l'uart sur lequel est branché notre module HC-06 <br>
 +
L'argument (uint8_t *pData) est celui sur lequel on va rentrer notre buffer où est contenue la données (on mettra (int8_t*)buffer car la fonction attend un buffer en int8_t* alors que notre buffer est en format char de base). <br>
 +
L'argument (uint16_t Size) sert à spécifier la taille du buffer : sizeof(buffer) <br>
 +
On établit donc le code que l'on va utiliser pour envoyer : <br>
 +
HAL_UART_Transmit_IT(&huart3, (uint8_t*) buff_enco,sizeof(buff_enco)); // encodeurs
 +
osDelay(200);
 +
HAL_UART_Transmit_IT(&huart3, (uint8_t*) buff_tens,sizeof(buff_tens)); // tension batterie
 +
osDelay(200);
 +
HAL_UART_Transmit_IT(&huart3, (uint8_t*) buff_vit,sizeof(buff_vit)); // vitesse robot
 +
osDelay(200);
 +
HAL_UART_Transmit_IT(&huart3, (uint8_t*) buff_posx,sizeof(buff_posx)); // position x
 +
osDelay(200);
 +
HAL_UART_Transmit_IT(&huart3, (uint8_t*) buff_posy,sizeof(buff_posy)); // position y
 +
osDelay(400);
 +
*Notre code est maintenant prêt à être implémenté sur le robot.
 +
 
 +
Par exemple l'image ci-dessous avec des valeurs fictives (compteurs qui s'incrémentent) :
    
[[Fichier:Terminal.png|200px|vignette|centré|Réception de données]]
 
[[Fichier:Terminal.png|200px|vignette|centré|Réception de données]]
   −
Pour suivre le schéma de code utilisé par les autres groupes, nous avons dû créer une nouvelle tâche avec FreeRTOS : dataDisplayTask. Tout notre code se trouve donc à l'intérieur de cette tâche. FreeRTOS se chargera ensuite d'alterner entre toutes les tâches du programme du robot en fonction de leur priorité. On considère comme vous pouvez vous en douter que notre tâche ne sera que de priorité assez faible puisqu'il s'agit simplement d'affichage. On pourra par contre revoir cette priorité dans le cas où l'on ajoute un bouton d'arrêt sur notre application. Il serait même peut être plus simple de créer une nouvelle tâche uniquement pour l'arrêt d'urgence qui sera de priorité très forte.
+
'''Système d'exploitation Temps Réel''' <br>
 +
[[Fichier:Logo freertos.jpg|vignette|droite]]
   −
METTRE LOGO FREERTOS
+
Afin de coordonner toutes les tâches que le robot a à effectuer, on utilise conjointement avec l'équipe de projet de 4A un OS (système d'exploitation) temps réel. Il s'agit de FreeRTOS. Celui-ci est intégrable directement depuis l'outil STMCubeIDE et il est même possible de prédéfinir nos différentes tâches et une multitude de paramètres (les priorités des tâches par exemple). Un OS temps réel permet aussi de gérer la préemptivité (ou la priorité) de chaque tâche, une tâche de haute priorité ayant toujours la priorité sur une tâche de basse priorité. Il va de soit que notre tâche prendra une priorité faible par rapport aux autres tâches puisque le plus important pour le robot est qu'il puisse se diriger et manœuvrer et que notre tache consiste juste à afficher des données. Pour suivre le schéma de code utilisé par les autres groupes, nous avons dû créer une nouvelle tâche avec FreeRTOS : dataDisplayTask. Tout notre code se trouve donc à l'intérieur de cette tâche. FreeRTOS se chargera ensuite d'alterner entre toutes les tâches du programme du robot en fonction de leur priorité. On pourra par contre revoir cette priorité dans le cas où l'on ajoute un bouton d'arrêt d'urgence sur notre application ou même créer une autre tâche spécialement pour ce bouton avec une forte priorité. Une fois la ou les tâche(s) et les paramètres définis, il nous suffit de générer le code et de remplir notre tâche.
 +
[[Fichier:Capture menu FreeRTOS.png|centré|vignette|Paramétrage de FreeRTOS]]
    
===Réalisation de l'application===
 
===Réalisation de l'application===
 
'''Interface'''<br>
 
'''Interface'''<br>
 
Pour réaliser notre application, nous avons utilisé MIT App Inventor qui permet de réaliser des applications pour mobile, tablette ou autre périphérique grâce au langage de programmation Scratch.
 
Pour réaliser notre application, nous avons utilisé MIT App Inventor qui permet de réaliser des applications pour mobile, tablette ou autre périphérique grâce au langage de programmation Scratch.
Nous aurions pu réaliser une application plus développée avec autre langage de programmation mais le but de ce projet n'était pas de réaliser la meilleure application mais plutôt de bien recevoir et afficher les données.
+
Nous aurions pu réaliser une application plus développée avec un autre langage de programmation mais le but de ce projet n'était pas de réaliser la meilleure application mais plutôt de bien recevoir et afficher les données.
    
Nous avons donc commencé à réaliser les différentes pages (Screen) de l'application. Pour cela nous avons utilisé les différents outils mis à notre disposition par App Inventor (boutons, texte, switch, images ...).
 
Nous avons donc commencé à réaliser les différentes pages (Screen) de l'application. Pour cela nous avons utilisé les différents outils mis à notre disposition par App Inventor (boutons, texte, switch, images ...).
 +
[[Fichier:App inventor.png|vignette|centré|Outils de création de l'interface]]
    
Voici les différents Screen crées :  
 
Voici les différents Screen crées :  
Ligne 328 : Ligne 524 :  
* Screen 3 : Affichage des données souhaitées
 
* Screen 3 : Affichage des données souhaitées
   −
METTRE LES PHOTOS DES TROIS SCREEN
+
 
 +
[[Fichier:Screen1.png|250px|vignette|centré|Screen 1 de l'application]]
 +
[[Fichier:Screen2.png|250px|vignette|centré|Screen 2 de l'application]]
 +
[[Fichier:Appli2.png|250px|vignette|centré|Screen 3 de l'application]]
       
Pour télécharger l'application et la faire fonctionner, nous vous invitons à suivre notre tuto d'utilisation au lien suivant :  
 
Pour télécharger l'application et la faire fonctionner, nous vous invitons à suivre notre tuto d'utilisation au lien suivant :  
METTRE LE LIEN DU TUTO
+
[[Projet_5A_2020_2021/Tuto utilisation et modification|Tutoriel d’utilisation]]
    
<br>
 
<br>
 
'''Programmation'''<br>
 
'''Programmation'''<br>
 +
Étant donné que nous avons utilisé App Inventor pour réaliser notre application, nous avons uniquement pu utiliser du Scratch pour coder le fonctionnement de l'appli. Malheureusement ce langage de programmation sous forme de blocs entraine souvent de grosses suites de blocs pas toujours très lisibles. Nous allons donc essayer de vous expliquer clairement et simplement ce que nous avons réalisé pour chaque Screen.
 +
 +
*Screen 1 : on affiche simplement le logo de Polybot pendant 4 secondes puis on ouvre le Screen suivant.
 +
[[Fichier:Code1.png|vignette|centré|Code pour le Screen 1 ]]
 +
*Screen 2 : on initialise les variables globales qui nous indiqueront si les valeurs ont été cochées (1) ou décochées (0), c'est à dire si on souhaite les afficher par la suite ou non. On aura donc une variables globale pour chaque donnée à afficher (distance parcourue, tension, vitesse, position...).
 +
[[Fichier:Code2 1.png|vignette|centré|Initialisation des variables globales]]
 +
Ensuite, toutes les secondes on vient inspecter l'état des Checkbox pour voir si elles sont cochées ou non puis on modifie la variable globale correspondante en fonction de cela : 0 si décochée, 1 si cochée.
 +
 +
[[Fichier:Code2 3.png|vignette|centré|Modification des variables globales ]]
 +
On va ensuite stocker les valeurs de nos variables globales dans la base de donnée de l'application. Nous avons besoin de faire cela afin de pouvoir récupérer ces valeurs dans le Screen suivant. Une fois toutes les variables stockées correctement, on ouvre le Screen suivant.
 +
 +
[[Fichier:Code2 2.png|vignette|centré|Stockage des variables]]
 +
*Screen 3 : à l'ouverture du Screen on va récupérer les valeurs des variables globales dans la base de donnée. En fonction de leur valeur (0 ou 1) on rendra visible ou non les données correspondantes. Par exemple, si la variable box_tension vaut 1 alors les valeurs de la tension seront rendues invisibles sur l'écran.
 +
 +
[[Fichier:Code3 1.png|vignette|centré|Récupération des variables globales]]
 +
On configure ensuite le bouton qui nous permet d'aller nous connecter au périphérique souhaité (ici notre module HC-06). Il affiche la liste des périphériques Bluetooth connecté, après en avoir sélectionné un on affiche "Périphérique Connecté".
 +
 +
[[Fichier:Code3 2.png|vignette|centré|500px|Connexion au périphérique Bluetooth]]
 +
Ensuite, on créé et on initialise une variable globale nommée flag (à ne pas confondre avec le flag envoyé par la STM) qui va nous permettre de bien synchroniser la réception des données. En effet, à chaque parcours de boucle on ne veut recevoir qu'une seule donnée (par exemple la tension) et au tour de boucle suivant, on affichera la donnée suivante uniquement (par exemple la vitesse).
 +
Et afin de synchroniser parfaitement l'envoi et la réception on commence détecter la réception d'une donnée précise (le flag de la STM) valant -9999. Nous avons choisi cette valeur car elle ne pourra jamais être atteinte par aucune des données affichées donc pas d'erreur possible. Une fois qu'on a reçu cette donnée valant -9999 on sait que les données reçues ensuite seront, dans l’ordre, la distance parcourue (encodeurs), la tension de la batterie, la vitesse, la position x et la position y. On chaque fin d'un tour de boucle, on incrémente le flag.
   −
===Résultats et bilan du projet===
+
[[Fichier:Code3 3.png|vignette|700px|centré|Réception et affichage des données]]
'''Résultat et performances'''<br>
      +
Enfin, nous avons créé plusieurs fonctions permettant le stockage des données affichées si l'utilisateur le souhaite. Nous avons par exemple créé la fonction nettoyer_fichier qui vide le fichier à chaque nouveau lancement de l'application, et la fonction stockage_data qui va ajouter les données dans le fichier de stockage. En amont, il faudra ajouter un fichier .csv dans le téléphone. Pour avoir plus d'informations sur la façon dont nous avons géré le stockage, nous vous invitons à aller voir notre page de tuto : [[Projet_5A_2020_2021/Tuto utilisation et modification|Tutoriel d’utilisation]]
   −
'''Difficultés rencontrées'''<br>
+
=Résultats et bilan du projet=
 +
==Résultat et performances==
 +
*Pour le projet 1, nous avons pu tester le fonctionnement de la carte et tout marche parfaitement. Par exemple, lorsque l'on a branché sur notre carte une batterie à moins de 30% de sa puissance alors les LED et les buzzers l'ont bien signalé. Après vérification de la tension de la batterie, on était bien dans la bonne fourchette de tension.
 +
 
 +
*Pour le  projet 2, nous avons réalisé un système fonctionnel qui récupère correctement les informations souhaitées et les affiche sur l'application Polybot. Cependant, nous nous sommes retrouvés limités concernant la fréquence d'affichage et d'envoi des données. Cela est peut être dû à l'application qui a été réalisé en Scratch (pas un code très précis) ou a un baudrate trop faible mais comme nous l’avons dit plus haut, nous n’avons pas eu le temps de tester nos solutions car le robot ne fonctionnait pas les derniers jours de projet. Pour le moment, une même donnée sera actualisée toutes les 0,8 secondes.
 +
Cependant, certains bouts de code du robot (qui ne font pas partie de notre projet) sont manquants ou défaillants, notamment le code des encodeurs qui engendre souvent des erreurs (envoie de valeurs négatives), ou encore le code pour récupérer la valeur de la tension de la batterie (bus CAN de la carte d'alimentation) qui n'a pas encore été crée.
 +
 
 +
==Difficultés rencontrées==
 
Voici les principales difficultés que nous avons rencontrées durant ce projet :  
 
Voici les principales difficultés que nous avons rencontrées durant ce projet :  
* Réalisation du diagramme de Gantt et avancement du projet : Par manque d'expérience nous ne connaissions pas toujours le temps nécessaire à la réalisation de chaque étape. Nous avons donc eu un peu de mal à respecter le diagramme de Gantt prévu, mais heureusement nous allions en général toujours plus vite que prévu. Nous avons également constaté que de nouvelles étapes arrivaient au fur et à mesure du projet, des étapes que nous n'avions pas prévu à la base. Mais grâce à notre avance, nous avons eu le temps de réaliser ces nouvelles étapes.<br>
+
*Réalisation du diagramme de Gantt et avancement du projet : Par manque d'expérience nous ne connaissions pas toujours le temps nécessaire à la réalisation de chaque étape. Nous avons donc eu un peu de mal à respecter le diagramme de Gantt prévu. Nous avons également constaté que de nouvelles étapes arrivaient au fur et à mesure du projet, des étapes que nous n'avions pas prévu à la base. Globalement nous avons avancé très vite au début et beaucoup lentement sur la fin mais nous avons terminé à temps.<br>
 +
*Pour le projet 1, lors de la première commande, nous avions commandé des transistors beaucoup trop petits (moins d'un millimètre de long), ce qui les rendait insoudables. Nous avions également commandé des convertisseurs de tension qui étaient tout simplement insoudables, car leur pad de soudure étaient en dessous du composant. Nous avons donc recomandés d'autres composants plus adéquats et de la bonne taille. Nous avons eu aussi pendant nos test, des composants qui chauffaient trop. On a pu pour certains changer le schéma à temps pour baisser la tension par exemple pour les relais, et on a mis un radiateur sur le convertisseur, ce qui le refroidit bien. Et enfin, les délais de commande de PCB nous retardaient pour pouvoir réaliser la carte, et surtout pour la deuxième.
 +
*Pour le projet 2, nous n'avions pas réalisé que la gestion de petit bugs nous prendrait autant de temps. Par exemple, nous avons mis 3 ou 4 jours pour réaliser une certaine version du code pour la STM32, et cela nous a pris tout autant de temps pour réussir à intégrer ce code au code actuel du robot. Nous avons retrouvé ce problème à plusieurs étapes de ce projet. Nous pensions donc pouvoir finir en avance mais nous avons fini tout juste à temps.
 +
 
 +
==Améliorations possibles==
 +
Concernant le projet 1 , il faudrait réaliser le code pour la communication via le bus CAN afin de pouvoir envoyer à la STM principale la tension de la batterie, et de pouvoir recevoir des instructions d'arrêt d'urgence de l'application. En effet, ça peut être intéressant de déclencher l'arrêt d'urgence depuis l'appli.
 +
<br>
      −
'''Améliorations possibles'''<br>
+
Concernant le projet 2, nous aurions pu ajouter plusieurs fonctionnalités supplémentaires, telles que :
 +
*L'ajout sur l'application d'un bouton d'arrêt d'urgence permettant de contrôler le robot. A noter que le binôme travaillant sur la carte de puissance à pris cela en compte dans la conception de la carte. Cela sera donc tout à fait possible, il suffira de créer le code pour cette fonctionnalité.
 +
*Il pourrait aussi être intéressant de faire communiquer les 2 robots ensemble en leur branchant tous les 2 un module Bluetooth HC-06. Cela leur permettraient de mieux se coordonner ensemble sur le terrain pendant les matchs.
 +
[[Fichier:2 modules.png|vignette|500px|centré|Communication entre 2 robots équipés du module HC-06]]
 +
*On pourrait également ajouter un bouton permettant de choisir la stratégie que le robot doit adopter sur le terrain (parmi plusieurs stratégies possibles).
 +
*On pourrait également améliorer la fréquence d'envoi et d'affichage des données. On se demande si la limite ne provient de l'application qui a été réalisée sur Scratch et qui ne permet donc pas vraiment une grande liberté dans la conception de l'appli.
    +
*Enfin, nous aurions souhaité afficher la trajectoire du robot sur l'image du terrain de jeu que nous avons mis sur l'application. Nous aurions par exemple pu utiliser une petite croix placée sur la carte pour signaler sa position. Cependant, App Inventor, que nous avons utilisé pour la conception de notre application, ne semble pas permettre de pouvoir réaliser cela de manière simple (on ne peut pas placer d'image librement sur l'interface). Nous n'avons donc pas vraiment eu le temps de réfléchir à une manière d'implémenter cela. En attendant, il est tout de même possible d'aller dans le fichier .csv contenant les valeurs enregistrées et de tracer nous-même le dessin de la trajectoire du robot à partir des données "position x" et "position y".
   −
A MODIFIER EN FONCTION DE NOTRE AVANCEMENT
+
[[Fichier:Trajectoire.png|vignette|centré|Espace prévu pour l'affichage de la trajectoire]]
   −
Concernant le projet 2, nous aurions pu ajouter plusieurs fonctionnalités supplémentaires : par exemple le stockage des données affichées (afin de pouvoir étudier ensuite ces données pour déceler un potentiel dysfonctionnement), l'ajout sur l'application d'un bouton d'arrêt d'urgence permettant de contrôler le robot (le groupe travaillant sur la carte de puissance on fait en sorte que cela soit possible dans leur système).
+
*Dans le cas où quelqu’un souhaiterait reprendre ce projet, nous avons rédigé un document tuto expliquant en détail comment nous avons réalisé le projet et comment reproduire ou modifier certaines étapes : [[Projet_5A_2020_2021/Tuto utilisation et modification|Tutoriel d’utilisation]].
   −
==Suivi du projet==
+
=Suivi du projet=
 
* [[Projet_5A_2020_2021/Semaine 1|Semaine 1]]
 
* [[Projet_5A_2020_2021/Semaine 1|Semaine 1]]
 
* [[Projet_5A_2020_2021/Semaine 2|Semaine 2]]
 
* [[Projet_5A_2020_2021/Semaine 2|Semaine 2]]
Ligne 362 : Ligne 600 :  
* [[Projet_5A_2020_2021/Semaine 7|Semaine 7]]
 
* [[Projet_5A_2020_2021/Semaine 7|Semaine 7]]
   −
==Sources==
+
=Sources=
 
* http://thierryperisse.free.fr/documents/TER/TER-BUS-CAN/note_application_com_pic_mppt.pdf
 
* http://thierryperisse.free.fr/documents/TER/TER-BUS-CAN/note_application_com_pic_mppt.pdf
 
* https://www.technologuepro.com/cours-systemes-embarques/cours-systemes-embarques-Bus-CAN.htm
 
* https://www.technologuepro.com/cours-systemes-embarques/cours-systemes-embarques-Bus-CAN.htm
 
* https://openclassrooms.com/fr/courses/5224916-developpez-un-robot-mobile-connecte-par-bluetooth/5500616-utilisez-une-liaison-serie-uart
 
* https://openclassrooms.com/fr/courses/5224916-developpez-un-robot-mobile-connecte-par-bluetooth/5500616-utilisez-une-liaison-serie-uart
243

modifications