Réception des premiers message pour piloter la LED par USB avec le format de messagerie : Fonctionnel (voir notes du Readme.md)
This commit is contained in:
parent
7ce5acb7bf
commit
61f9429a36
29
Readme.md
29
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
|
- Ajout de la communication USB
|
||||||
* 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
|
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
151
communication.c
Normal file
151
communication.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#include "pico/error.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#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<nb_recu; i++){
|
||||||
|
input_char = tampon_usb[i];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
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<index_chaine_recue; i++){
|
||||||
|
int index_fin_message = 0;
|
||||||
|
// Com v2
|
||||||
|
// OxFF OxFF <taille> ... ... <fin (0x00)>
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
3
communication.h
Normal file
3
communication.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
void communication_reception_message(void);
|
||||||
|
void communication_init(void);
|
||||||
4
main.c
4
main.c
@ -227,9 +227,9 @@ void gestion_PAMI(uint32_t step_ms, int * asser_pos){
|
|||||||
case PAMI_DANCE:
|
case PAMI_DANCE:
|
||||||
Moteur_Stop();
|
Moteur_Stop();
|
||||||
if(Temps_get_temps_ms() - temps_tirette > 15000){
|
if(Temps_get_temps_ms() - temps_tirette > 15000){
|
||||||
while(1){
|
/*while(1){
|
||||||
PAMI_dance(get_identifiant());
|
PAMI_dance(get_identifiant());
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
26
messagerie.c
Normal file
26
messagerie.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
messagerie.h
Normal file
23
messagerie.h
Normal file
@ -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);
|
||||||
Loading…
Reference in New Issue
Block a user