Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Detection fin de trame UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » ven. 7 avr. 2017 11:44 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Je suis toujours en train de configurer mes modules radio AMB8420. Je me heurte à un soucis, que j'ai plus ou moins réussis à résoudre, mais étant pas un expert je me demande si il n'existe pas une meilleure façon de faire la détection de fin de trame.

J'ai créer un dialogue UART entre mon PIC et le module, un classique :-) . Contrairement à d'habitude, le module ne renvoie pas de "CR" ni de "LF" :sad: . Son dernier caractère c'est un checksum. Et ce cheksum est l'addition de XOR des bytes précédentes. Donc il est variable et inconnu ! .

Au final je ne peux pas savoir ou est la fin de trame et donc quand je peux la traiter.
cependant il existe un indice dans la trame reçu ! c'est le nombre de bytes composant le message .

Prenons un exemple plus parlant :

Quand je reçois un message par voie radio, voici la trame reçue en hexa :
<Start> <Commands> <number of data bytes + 1> <data bytes> <field strength><Checksum>

Si je reçois par exemple la valeur "1\r" :
02 81 03 41 0D 26 EA ( chiffre en hexa sans les "0x")

Mon but est d'extraire pour traitement les DATA et le RSSI (field strength) .

Voici ma routine d'interrpution :

Code : Tout sélectionner

//###########################     VARIABLE     ###################################
char tmp, Index_Buffer, Data_prete, RSSI ;
signed short  Fin_trame = -1;

char Buffer[100];

void interrupt(){

 //-----------------------          UART        -----------------------------
  if (RC1IF_bit == 1) {

    tmp = UART1_Read();      // On récupere et stock la donnée

    if (Index_Buffer == Fin_trame){
        Buffer[Index_Buffer] = tmp ;
        Buffer[Index_Buffer+1] = 0 ;
        Fin_trame = -1;
        Index_Buffer = 0;
        Data_prete = 1;
     }
    else {
        Buffer[Index_Buffer] = tmp ;
        Index_Buffer++;
        if (Index_Buffer == 3 ) Fin_trame = tmp+3;
        if (Index_Buffer>=99)Index_Buffer=0;  // GARDE-FOU, en cas de dépassement de Buffer j'écrase le début
    }
  }
}


Le nombre de bytes de données se trouve toujours en position 3 soit placé dans Buffer[2]. Avec ce chiffre je calcule ou se trouve la fin de trame que je stock dans la variable Fin_trame. A chaque réception je regarde si je suis arrivé au bout !

Voila pour le moment ca à l'air de fonctionner, a condition d'avoir toujours le nombre de bytes de la data indiqué en position 3 .

Je ne sais pas si ma méthode est bonne ou améliorable .

Merci à vous .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Detection fin de trame UART
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » sam. 8 avr. 2017 11:31 lien vers la Data-Sheet : Cliquez ici

bonjour Jeremy

Code : Tout sélectionner

 if (Index_Buffer == 3 ) Fin_trame = tmp+3

pourquoi le +3 ?
le 3em c'est 0x41 ? puisque tu incrementes l'index avant la comparaison
As-tu toujours le caractere 0x0D =CR dans ta trame ?

si tu as un temps mort entre chaque trame, tu pourrais utiliser un timeout
pour declarer fin de trame
Timer enclenché à la 1ere apparition de caractere
Aide toi, le ciel ou FantasPic t'aidera

Detection fin de trame UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » sam. 8 avr. 2017 14:12 lien vers la Data-Sheet : Cliquez ici

Bonjour Paul et à tous,

paulfjujo a écrit :Source du message pourquoi le +3 ?


Car l'indication du nombre de data bytes se trouve en 3iéme position dans le buffer[2].
il faut donc que je rajoute 3 si je veux avoir la trame entière, du START jusqu’au Cheksum. LE hasard de mon exemple n'est pas trés explicite car le chiffre "3" revient souvent ! :lol:

voici un autre exemple avec 4 données envoyés ("1 2 3 CR"):
02 81 05 41 42 43 0D 26 ED

Quand on arrive au Buffer[2], la valeur "temp" correspond au nombre de data, mais pas à la fin de trame, car on est déjà à la 3 donnée. il faut donc faire un offset pour aller jusqu’à la fin de la trame , cheksum compris !

Je sais pas si c'est très clair ! :sad:

paulfjujo a écrit :Source du message As-tu toujours le caractere 0x0D =CR dans ta trame ?

Oui, car c'est moi qui l'impose à l’émission. Bien sur je pourrais l'enlever au besoin et mettre chose. Mais je me suis dis que c'était une bonne idée si je dois faire d'autre chose! au cas ou ! :wink:

paulfjujo a écrit :Source du message si tu as un temps mort entre chaque trame, tu pourrais utiliser un timeout
pour declarer fin de trame

ca c'est une bonne idée que je vais creuser ! mais mon but n'étant pas de faire trop complexe, sinon je vais me noyer ! je précise que pour l'heure ca fonctionne , mais je n'en suis qu'a l'apprentissage de ces modules ! car d’après ce que j'ai lu, le 3iéme bytes reçu n'est pas toujours le nombre de data suivant la commande que lui envoie :sad: . Pour le moment ca passe :shock: mais si je pousse un peu l'utilisation y'a des chances que ca coince par la suite !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Detection fin de trame UART
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#4 Message par paulfjujo » sam. 8 avr. 2017 21:10 lien vers la Data-Sheet : Cliquez ici

tu as donc bien un caractere specifique fin de trame = 0x0D
pour dire fin de trame,
apres quoi tu lis les 2 caractere suivants du checksum, en testant l'evolution de l'indexà index +2
ou alors tu ignore carrement le checksum en stopant la rexception RCEN=0
Aide toi, le ciel ou FantasPic t'aidera

Detection fin de trame UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » dim. 9 avr. 2017 10:41 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Comment bien souvent j'ai posté trop vite !

Je souhaite paramétré mon module a l'allumage ! comme par exemple pour lui donné son numéro d'identité VIA un DIP switch .

Pour cela je dois dialoguer directement avec le module sans RF. Donc je ne maitrise pas les réponses , donc je n'ai pas de "0x0D" pour chaque fin de trame !
La seule constante reste le byte3 soit le Buffer[2] dans mOn cas ! ceci est toujours le nombre de bytes de la donnée.

Du coup pour "examiner" les réponses je vais peut être me diriger vers une espèce de machine d'état comme pour le module SMS ! ? !

Il y a bien un système de time-Out , mais seulement pour l'émission. Pour faire partir un message, j'ai plusieurs choix, le time-out, le packet , le choix d'un caractère ( ici pour moi le 0x0D) et une PIN.
Pour la recepetion pas de time-out.

J'y en réfléchi, mais ça complique les choses, car cela inclus une INT dans une INT ! chose que je ne suis pas sur de maitriser !
Je vais rester sur mon idée de trouver la fin de trame, en comptant les bytes recu !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Detection fin de trame UART
JMarc
Confirmé
Confirmé
Messages : 605
Enregistré en : août 2016
Localisation : Dans le Sud...

#6 Message par JMarc » dim. 9 avr. 2017 23:04 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous

J'aime bien ta méthode de lire le troisième bit et s'en servir pour la longueur de trame et Se servir du cheksum uniquement pour vérifier s'il y a erreur dans la transmission.


En tout cas cela m'a donné l'idée qu'il me manquait pour mon protocole, merci

Detection fin de trame UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » lun. 10 avr. 2017 09:10 lien vers la Data-Sheet : Cliquez ici

Bonjour ,

JMarc a écrit :Source du message J'aime bien ta méthode de lire le troisième bit et s'en servir pour la longueur de trame

Oui mais je m'en rend compte que ce n'est peut être pas optimum ! tout du moins le début de l'analyse . Je n'ai eu aucun problème pour le moment , due à des conditions idéales de test je pense .

Mais une question me turlupine, pour la fiabilité, QUID si je ne reçois qu'une ou deux bytes par erreur ???? Le calcul de fin de trame est donc pas calculé donc les données restent dans le buffer, et tronqueront la prochaine infos !

Il me semble que le time-out est plus intéressant dans ce cas la , ou alors une machine d'état ( ce que je vais tester aujourd'hui) .

@Paul : si tu as du temps pouyrrait tu me décrire comment faire une Timeout sur la réception ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Detection fin de trame UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#8 Message par Jérémy » lun. 10 avr. 2017 13:35 lien vers la Data-Sheet : Cliquez ici

Me revoilou !

Bon, il s’avère que Paul avait raison, ( pour ne pas changer humour!! ) sur ce time OUT !

Ma première idée fonctionne parfaitement, quand tout le reste fonctionne parfaitement aussi !
La machine d'état fonctionne parfaitement aussi, quand tout le reste fonctionne parfaitement !
Moi je souhaite que ça fonctionne parfaitement, même quand le reste fonctionne mal ! Je m'explique .

La problématique est que, sur chaque caractère reçu, sa valeur n'est pas inscrite dans le marbre. Il est donc impossible de faire des conditions avec des "if".
Le checksum varie en fonction des valeurs reçues et du nombre de bytes. le nombre de bytes varie en fonction du nombre de data reçues . les datas varient en fonction des réponses !
Bref.....
Les données reçues, ne sont pas prévisibles et donc pas testables si elles sont bonnes ou mauvaises voir manquantes( plus de réception).

Le time-out me semble le seul moyen de débloquer un éventuel problème de réception !

Je vais donc partir sur cette idée . Voici mon raisonnement :

- Réception du bytes de start (0x02) par ma machine d'état .
- Je lance mon timer0 (compteur incrémenté toutes les milli-secondes).
- Je reçois mes données suivantes ou non !
- Si j'ai pu recevoir mes données jusqu'au bout, à la fin de la trame j’arrête et je réinitialise mon compteur(Timer0).
- Si mon compteur atteint 10ms, c'est que mon UART à planter(suite à problème) et ma trame n'arrive jamais à s’arrêter. Donc j’arrête le timer0 et je réinitialise toute ma machine d'état !

Pour résumé , dés que je reçois un START, je me laisse 10ms pour recevoir la trame entière ! sinon je réinitialise tout .

Question :
- mon raisonnement est il viable ? bon ? mauvais ? incomplet ? améliorable ?
- comment savoir la durée approximative d'une trame ? suivant le nombre de caractère reçus ? je suis partis sur 10ms max mais j'ai peut être vu trop grand ou trop court pour 9600 bauds !

Merci
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Detection fin de trame UART
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#9 Message par paulfjujo » lun. 10 avr. 2017 20:46 lien vers la Data-Sheet : Cliquez ici

ton raisonnement parait OK..

Connais-tu le maxima de caracteres recus ?

à 9600 bauds => 960 cars en 1000mS
96 cars en 100mS
9,6 cars en 10mS :furieux:
ça pourrait etre trop juste
Aide toi, le ciel ou FantasPic t'aidera

Detection fin de trame UART
Claudius
Avatar de l’utilisateur
Passioné
Passioné
Messages : 260
Âge : 69
Enregistré en : septembre 2015
Localisation : ELANCOURT (78 - YVELINES)
Contact :

#10 Message par Claudius » lun. 10 avr. 2017 22:46 lien vers la Data-Sheet : Cliquez ici

Bonsoir,

... 02 81 03 41 0D 26 EA est tout simplement du TLV (Type Longueur Valeur en Français ou Type Length Value in English)...

Ce protocole TLV est très utilisé en Telecom qui permet de se passer de cette gazinière de caractère de fin de trame, timeout and Co. ;-)


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 42 invités