diff --git a/Readme.md b/Readme.md index 215e8b5..7fbb2fa 100644 --- a/Readme.md +++ b/Readme.md @@ -1,20 +1,19 @@ -PAMI 2025 - Poivron Robotique +Propulsion 2026 - Riombotique ======================================= -Code du PAMI 2025 de l'équipe Poivron Robotique. +Basé sur le code du PAMI 2025 de l'équipe Poivron Robotique. -La carte contient les éléments suivants : +Principales évolutions: -* Microcontrôleur Raspberry Pi Pico -* Connecteur pour l’arrêt d’urgence -* 2 prises moteurs (pilotés par un L293D) -* 2 prises codeurs -* 1 prise Gyroscope (L3GD20H) -* 1 prise I2C pour du TOF -* 1 prise "choix couleur" -* 1 prise tirette -* Surveillance tension batterie -* 1 LED -* 3 Dip Switch +- Ajout de la communication USB -Grandement basé sur le code du PAMI 2024 +Méthode de test +--------------- +Éteindre la LED avec la trame : `echo -e "\xFF\xFF\x06rD\x00\x01\x36\x00" > /dev/ttyACM0` +Allumer la LED avec la trame : `echo -e "\xFF\xFF\x06rD\x00\x01\x06\x00" > /dev/ttyACM0` + +Difficultés +----------- +Il suffit d'une petite modification du code (ajout d'un `printf` par exemple), pour que la communication se bloque côté PC +L'utilisation du second cœur pour envoyer la télémétrie peut perturber le débug avec printf => Augment grandement le délai de réponse +La communication crash rapidement : à cause de la danse du PAMI => Suppression de la dance du PAMI (c'était codé à l'arrache) diff --git a/communication.c b/communication.c new file mode 100644 index 0000000..ab79b67 --- /dev/null +++ b/communication.c @@ -0,0 +1,151 @@ +#include "pico/error.h" +#include +#include "communication.h" +#include "messagerie.h" +#include "tusb.h" + +#define TAMPON_TAILLE 1020 + +struct com_reception_buffer_t{ + char tampon[TAMPON_TAILLE]; // Tampon tournant - 1er niveau de tampon + unsigned int index_tampon_ecriture, index_tampon_lecture; +}; + +struct com_reception_buffer_t com_reception_buffer; + + +void communication_init(){ + com_reception_buffer.index_tampon_ecriture=0; + com_reception_buffer.index_tampon_lecture=0; +} + +/// @brief Incrémente l'index du tampon tournant +/// @param index +/// @return +void increment_index(unsigned int *index){ + *index = 1 + *index ; + if((*index) >= TAMPON_TAILLE){ + *index = 0; + } +} + +/// @brief augmente la position l'index du tampon tournant +/// @param index +/// @return +void augmente_index(unsigned int *index, unsigned int offset){ + *index = offset + *index ; + if((*index) >= TAMPON_TAILLE){ + *index -= TAMPON_TAILLE; + } +} + +/// @brief Vérifie si des caractères ont été reçu par la liaison série +/// et analyse si un message valide a été reçu. +void communication_reception_message(){ + int input_char; + int chaîne_octets_reçus[TAMPON_TAILLE]; + unsigned int index_chaine_recue; + unsigned int index_tampon; + struct message_t message; + // Si un caractère est reçu, ajout du caractère au tampon tournant + + /// TODO: Tester le code suivant à la place de while get_char(); + /* + char nb_recu=0; + if(tud_cdc_available()){ + char tampon_usb[128]; + nb_recu = tud_cdc_read(tampon_usb, 128); + // copie dans le tampon tournant + for(int i=0; i= TAMPON_TAILLE){ + com_reception_buffer.index_tampon_ecriture = 0; + } + com_reception_buffer.tampon[com_reception_buffer.index_tampon_ecriture] = input_char; + } + }*/ + + input_char = stdio_getchar_timeout_us(0); + while(input_char != PICO_ERROR_TIMEOUT){ + com_reception_buffer.index_tampon_ecriture++; + if(com_reception_buffer.index_tampon_ecriture >= TAMPON_TAILLE){ + com_reception_buffer.index_tampon_ecriture = 0; + } + com_reception_buffer.tampon[com_reception_buffer.index_tampon_ecriture] = input_char; + + // Caractère suivant ? + input_char = stdio_getchar_timeout_us(0); + } + + // Copie du tampon tournant dans une chaine + // Parce que c'est plus simple à traiter + index_chaine_recue = 0; + index_tampon = com_reception_buffer.index_tampon_lecture; + if(index_tampon != com_reception_buffer.index_tampon_ecriture){ + while(index_tampon != com_reception_buffer.index_tampon_ecriture){ + chaîne_octets_reçus[index_chaine_recue] = com_reception_buffer.tampon[index_tampon]; + index_chaine_recue++; + increment_index(&index_tampon); + } + chaîne_octets_reçus[index_chaine_recue] = com_reception_buffer.tampon[index_tampon]; + index_chaine_recue++; + increment_index(&index_tampon); + } + + // Traitement + // Si on trouve le début du message + // Si on trouve la taille du message + // Si le caractère de fin est bien à la fin du message + int fin_message = 0; + for(int i=0; i ... ... + if(i + 2 < index_chaine_recue){ + // Test début message + if(chaîne_octets_reçus[i] == 0xFF && chaîne_octets_reçus[i+1] == 0xFF){ + //printf("Debut message: 0xFF 0xFF\n"); + // Taille du message (sans l'entête) + uint8_t offset = chaîne_octets_reçus[i+2]; + if(i + 2 + offset < index_chaine_recue){ + // printf("Message totalement reçu, taille %d\n", offset); + // Test fin message + if(chaîne_octets_reçus[i + 2 + offset] == 0x00){ + // printf("Fin message OK\n"); + // Lecture du message + message.type = 'b'; // Message binaire (par opposition à un message Texte) + message.taille_donnees = offset - 1; + for(int index_donnees = 0; index_donnees < message.taille_donnees; index_donnees++){ + message.donnees[index_donnees] = chaîne_octets_reçus[index_donnees + i + 3]; + } + fin_message = i + 2 + offset; + messagerie_put_message(message); + }else{ + // printf("Fin message NOK, attendu 0x00, recu %x\n", chaîne_octets_reçus[i + 2 + offset]); + } + } + } + } + if(chaîne_octets_reçus[i] == '>'){ + message.type = chaîne_octets_reçus[i]; + message.taille_donnees=0; + while(message.taille_donnees + i < index_chaine_recue){ + message.donnees[message.taille_donnees] = chaîne_octets_reçus[i+message.taille_donnees]; + if(message.donnees[message.taille_donnees] == '\n'){ + i = i + message.taille_donnees; + message.taille_donnees++; + message.donnees[message.taille_donnees] = '\0'; + messagerie_put_message (message); + fin_message = i; + break; + } + message.taille_donnees++; + } + } + } + + // Mettre à jour l'index de lecture du tampon tournant + augmente_index(&(com_reception_buffer.index_tampon_lecture), fin_message); + +} diff --git a/communication.h b/communication.h new file mode 100644 index 0000000..a074357 --- /dev/null +++ b/communication.h @@ -0,0 +1,3 @@ + +void communication_reception_message(void); +void communication_init(void); diff --git a/main.c b/main.c index 4b1ae51..bbc28c1 100644 --- a/main.c +++ b/main.c @@ -227,9 +227,9 @@ void gestion_PAMI(uint32_t step_ms, int * asser_pos){ case PAMI_DANCE: Moteur_Stop(); if(Temps_get_temps_ms() - temps_tirette > 15000){ - while(1){ + /*while(1){ PAMI_dance(get_identifiant()); - } + }*/ } break; diff --git a/messagerie.c b/messagerie.c new file mode 100644 index 0000000..df64305 --- /dev/null +++ b/messagerie.c @@ -0,0 +1,26 @@ +#include "messagerie.h" + +#define NB_MAX_MESSAGE 30 + +int index_message=0; +struct message_t message_liste[NB_MAX_MESSAGE]; + +/// @brief Renvoi 1 si des message sont disponibles +/// @return +bool messagerie_message_disponible(){ + return (index_message != 0); +} + +/// @brief Renvoi un message à traiter, à n'appeler que si message_disponible() renvoie 1 +/// @return Message +struct message_t messagerie_get_message(){ + index_message = index_message - 1; + return message_liste[index_message]; +} + +void messagerie_put_message(struct message_t message){ + if(index_message < NB_MAX_MESSAGE-1){ + message_liste[index_message] = message; + index_message = index_message + 1; + } +} \ No newline at end of file diff --git a/messagerie.h b/messagerie.h new file mode 100644 index 0000000..6eec6fc --- /dev/null +++ b/messagerie.h @@ -0,0 +1,23 @@ +#include "pico/stdlib.h" + +#define MESSAGE_TIMEOUT_US 2000 + +struct message_t{ + uint8_t type; // 'd' pour demande, 'r' pour une réception de données, 'w' pour écrire des données, '>' pour des logs + uint8_t id_carte; // Identifiant de la carte (on reprend les adresses I2C) + uint8_t adresse_registre; // Adresse du registre lu + uint8_t taille_donnees; + uint8_t donnees[255]; +}; + +struct message_requete_t{ + uint8_t commande; + uint8_t id_carte; // Identifiant de la carte (on reprend les adresses I2C) + uint8_t adresse_registre; // Adresse du registre lu + uint8_t taille_donnees; +}; + + +bool messagerie_message_disponible(); +struct message_t messagerie_get_message(); +void messagerie_put_message(struct message_t message);