Go Down

Topic: protocole de communication série bi-directionnel entre carte (Read 4 times) previous topic - next topic

fdufnews

Quote
Donc si je comprend bien lenght et start + stop obligatoire...

Je dirais qu'à minima start est indispensable car c'est lui qui te confirme que tu tiens bien le début de ton message.
length et start c'est plutôt des sécurités qui te permettent de savoir que tu as reçu le nombre de caractères attendus lorsque tu arrives à la fin du message.

De toute les façons, un protocole de communication c'est toujours un compromis entre la sécurisation de la transmission et la garantie d'un débit.
Il y a des choix à faire:
   1) puis-je garantir qu'une erreur ne va pas me planter complètement mon logiciel ou bien risquer de détruire le matériel?
   2) est-ce que les sécurités que j'ai mis en place afin de robustifier ma liaison ne vont pas faire chuter mon débit et limiter la quantité d'informations utiles que je veux émettre.

Donc avant toutes choses il faut:
   1) évaluer la quantité d'informations que l'on veut récupérer à l'arrivée. Combien d'octets pour chaque message, récurrence des messages
   2) avoir une bonne idée du débit que l'on peut obtenir sur la liaison que l'on va utiliser. Cela dépend du support physique (fils simples, paires torsadées, paires torsadées blindées, ...), des niveaux électriques  (RS232, RS422, TTL,...) et de la distance
   3) criticités des informations transportées (l'allumage d'un voyant n'est pas être pas aussi important que l'activation d'une sécurité par exemple)
   4) capacités de traitement des informations à l'émission comme à l'arrivée (il faudrait pas non plus que ton processeur soit saturé par la gestion de la liaison de données et ne puisse plus rien faire à coté)

Avec ces informations tu peux estimer combien d'octets de contrôle tu peux ajouter à tes messages afin de sécuriser la liaison sans pour autant compromettre la bonne marche de ton application.

AlienArea51

Salut @ tous
Merci fdufnews pour ton lien , ça serai bien de l'integrer soit dans la rubrique TUTOS ou le Guide Arduino  ,je ne sais pas ce que vous en pensez ??
@+
William

P.S: je suppose qu'il y a sur ce site d'autres explications sur des questions posées sur le Forum ?  ;)
The truth is elsewhere !!

Geeks

#37
Apr 07, 2012, 10:34 am Last Edit: Apr 07, 2012, 02:34 pm by Geeks Reason: 1
Ok, donc je pense faire ceci:

Tout étant constituer d'octets, j'aurais la trame suivante:
[Start][Lenght][Data 1][Data 2][Data x][End]

1 - Cas ou j'ai des PWM: 3 octets.
2 - Cas ou j'ai des tout ou rien: 2 octets.

Principe de fonctionnement:
Au démarrage, je force chaque sorties avec des valeurs de base leurs correspondant. Ici c'est des PWM allant de 1 à 2ms.
On entre dans la boucle et toute les 18 à 20ms on prends chaque sorties les une derrières les autres et on écrit ce que l'on a dans les variables.

A partir de là, si on reçois quelque-chose sur RX, on passe en mode interruption, et on y reste le temps qu'on a pas reçu toute la trame de start + lenght à stop.
0x01 = Start
0x02 = Stop
Attention, un timer est quand même mis par sécurité afin de ne pas rester sur une erreur d'envoie. Charger la variable avec la donnée reçu. Revenir de l'interruption vers le programme principal.

Je pense codé sur 3 octets mes pulses. En effet, un octet pour choisit la sortie, un octet pour le premier chiffre, et un octet pour se second chiffre. Ainsi: si j'ai 1ms, 0x01 0x03 0x01 0x01 0x00 0x02.
Si j'ai 1,5ms, 0x01 0x03 0x01 0x01 0x05 0x02.
Et pour 2 ms : 0x01 0x03 0x01 0x02 0x00 0x02.

Soit une trame (S)(L)(var1)(var2)(var3)(E) donc varPwm = var2,var3 donc sortie var1 (varPwm). Je me trompe peut-être en mettant ça. C'est très théorique pour le moment afin de m'organiser. Je veux dire par la que je cherche à comprendre comment je vais faire pour que ce soit compréhensible. En même temps, là, il n'y a plus qu moi qui comprends.. Non ?

Pour mes lights c'est beaucoup plus simple bien sûr. Grâce au lenght, je peux lui dire je te place tel sortie à 0x01 ou 0x00. En 2 octets... Comme ceci:
0x01 0x02 0x08 0x01 0x02 soit (S)(L)(var1)(var2)(E) avec var1 la pin light et var2 la valeur 1 ou 0. Ici on allume la light.

Un détail me chagrine! Avons nous besoin d'un caractère d'espacement entre chaque valeurs d'octet ?  :smiley-roll-sweat:

Et bien maintenant, je vais commencer à travailler une une ébauche de tableau correspondant à mes varX, un tableau par sorties à affectés. En espérant que ce soit faisable sans trop de cafouillage.

AlienArea51, je suis bien d'accord avec toi. D'autant plus que c'est pas si compliqué mais que la représentation que l'on en fait dans le code peut-être difficile. Comme j'ai dit même si appeler Paul pour savoir ce que contient Jack est facile à comprendre, je ne sait toujours pas faire la différence entre * Paul et *. Peut être que si titi * fait référence à Jack alors titi * peut aussi faire référence à Martin, pour peu que l'on ai mis aussi un *Martin quelque-part. C'est ça qui me bloque et je pense ne pas être le seul ;)

Merci en tout cas pour votre aide à la fois sur la compréhension de pointeur et pour ce qui est de ma communication entre carte.  XD

osaka

#38
Apr 07, 2012, 10:37 am Last Edit: Apr 07, 2012, 10:57 am by osaka Reason: 1

Donc si je comprend bien lenght et start + stop obligatoire...


C'est comme fdufnews l'indique, tout dépend du niveau de sécurité dont tu as besoin, il ne sera pas identique si ton arduino doit gérer un aquarium ou une centrale nucléaire.
start et stop permettent de "détecté" un début de trame et ajoute une petite sécurité sur la validité de la trame, je te garanti que rien n'est plus incertain que la bonne transmission et réception de donnée quelque soit le support.
Dans mon cas j'ai ajouter un crc16 qui a mon grand étonnement ne demande pas énormément de ressource, j'ai mesuré entre 400 et 500 micro seconde pour un calcul sur 5 octet.
Length est là pour des trames de longueur variable, s'assurer que la trame est complète mais également bien utile pour situé les données (ou ce trouve l'octet de fin de trame ?, etc), boucler cette trame rapidement hormis à la déclaration et réservation difficile de connaître la taille d'un tableau, etc, etc, ...  


Pour les pointeur je comprend parfaitement ce qui est mis. Mais en code ?
À la création d'un pointeur * est utilisé. Parfois on retrouve & . C'est austère.

Je ne fais pas la différence entre * et * et entre * et &. Mais il doit y avoir moyen de s'y retrouver. Particulièrement s'il y a plusieurs pointeurs.


il y a deux signification possible à * elles se situent soit à la déclaration soit à l'utilisation.

Code: [Select]

char unChar = 'a';
char *uneVariablePointeur; //Je déclare une variable de type pointeur de char
char *uneAutreVariablePointeur = &unChar; //je déclarare une variable de type pointeur de char et je l'initialise en lui donnant comme valeur l'adresse (&) de la variable unChar qui doit être de type char. (un pointeur pointe une adresse).
uneVariablePointeur = uneAutreVariablePointeur; //Je donne la valeur (une adresse) contenue dans uneAutreVariablePointeur (la valeur contenue dans mon pointeur étant l'adresse de unChar) à un autre pointeur de type pointeur de char uneVariablePointeur.Donc mes deux pointeur pointe sur la même variable unChar.
char unAutreChar = *uneAutreVariablePointeur ; //Je déclare une autre variable de type char et je l'initialise à la valeur situé à l'adresse contenue dans ma variable uneAutreVariablePointeur.



pour les fonctions, on reprend les même variable qu'au dessus.
Code: [Select]


maFonction(uneVariablePointeur); //je lui donne en paramètre la valeur contenue dans ma variable de type pointeur, donc l'adresse de ma variable de type char.
maFonction(&unChar); //je lui donne en paramètre l'adresse de ma variable de type char

char* maFonction(char* unPointeur) // Le paramètre est de type pointeur donc la valeur qui doit lui être passer est une adresse, s'il avait été de type int par exemple on aurais du lui transmettre un entier.
{
   *unPointeur = 'b'; //je modifie la valeur de la variable situé à l'adresse contenue dans mon pointeur
   return unPointeur; // je retourne un pointeur contenant l'adresse d'une variable
}


Dans les deux cas ma fonction demande une adresse

Citation du site du zero adapté:
Quote

   Sur une variable, comme la variable "unChar" :
       "unChar" signifie : "Je veux la valeur de la variable unChar".
       "&unChar" signifie : "Je veux l'adresse où se trouve la variable unChar".
   Sur un pointeur, comme "uneVariablePointeur" :
       "uneVariablePointeurr" signifie : "Je veux la valeur de uneVariablePointeur" (cette valeur étant une adresse).
       "*uneVariablePointeur" signifie : "Je veux la valeur de la variable qui se trouve à l'adresse contenue dans uneVariablePointeur"


Geeks

Ah wai, on comprends nettement mieux ainsi.

Bon, le CR16. J'avoue je ne connais pas  :smiley-roll-sweat:
On à l'air de dire que c'est rapide et facile, je suis loin d'être d'accord avec ça, d'autant plus qu'on a du mal à trouver ne serais-ce que quelques sources parlant d'un transfert fiable. a mon sens, l'I2C est bien plus simple d'autant plus que l'ack confirme la réception.

Go Up