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 ---
- 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 ---
Modérateur : Jérémy
Detection fin de trame UART
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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" . 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 :
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 .
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" . 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 .
Detection fin de trame UART
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour Jeremy
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
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
Detection fin de trame UART
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonjour Paul et à tous,
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 !
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 !
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 !
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 . Pour le moment ca passe mais si je pousse un peu l'utilisation y'a des chances que ca coince par la suite !
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 !
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 !
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 !
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 . Pour le moment ca passe mais si je pousse un peu l'utilisation y'a des chances que ca coince par la suite !
Detection fin de trame UART
Detection fin de trame UART
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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 !
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 !
Detection fin de trame UART
Detection fin de trame UART
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonjour ,
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 ?
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 ?
Detection fin de trame UART
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Me revoilou !
Bon, il s’avère que Paul avait raison, ( pour ne pas changer ) 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
Bon, il s’avère que Paul avait raison, ( pour ne pas changer ) 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
Detection fin de trame UART
Detection fin de trame UART
- Claudius
Passionné- Messages : 260
- Âge : 69
- Enregistré en : septembre 2015
- Localisation : ELANCOURT (78 - YVELINES)
- Contact :
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. ;-)
... 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. ;-)
Enregistreur de traces GPS & Boussole GPS parlante (PIC & Arduino)
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 132 invités