Ligne 44 : |
Ligne 44 : |
| [[Fichier:Terminal text.png|200px|vignette|centré|Réception des données ]] | | [[Fichier:Terminal text.png|200px|vignette|centré|Réception des données ]] |
| | | |
| + | '''Choix des valeurs à afficher'''<br> |
| + | Nous avons discuté avec les autres groupes travaillant sur le robot pour savoir quels types d'informations ils aimeraient que l'on affiche sur notre écran. |
| + | Nous allons donc afficher les données suivantes : |
| + | *Tension de la batterie |
| + | *Distance parcourue |
| + | *Vitesse du robot |
| + | *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 |
| + | |
| + | 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. |
| + | |
| + | <br> |
| + | '''Affichage des valeurs souhaitées'''<br> |
| + | Pour transmettre les différentes valeurs souhaitées, nous avons ajouté dans le code de la STM 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 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 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é. |
| + | |
| + | *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]] |
| + | |
| + | '''Système d'exploitation Temps Réel''' <br> |
| + | [[Fichier:Logo freertos.jpg|vignette|droite]] |
| + | |
| + | 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écupérer du code général=== | | ===Récupérer du code général=== |
| + | Pour pouvoir accéder au code général du robot vous devez : |
| + | *Créer un compte GitLab |
| + | *Contacter le responsable de Polybot pour qu'il vous donne l'accès aux Git de polybot |
| + | *Accéder au dossier concerné |
| + | *Télécharger le master |
| + | *Ouvrir le dossier avec STMCubeIDE |
| + | |
| + | <br> |
| + | Si vous souhaitez uniquement regarder la tâche relative à notre partie du projet, vous pourrez la trouver sous format .txt au lien suivant : METTRE LE LIEN DE NOTRE CODE |
| | | |
| ==Utilisation des modules Bluetooth HC-06== | | ==Utilisation des modules Bluetooth HC-06== |