1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 19
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : avril 2017
    Messages : 4
    Points : 1
    Points
    1

    Par défaut Projet : Calcul checksum verification de la trame reçue

    Bonjours ,
    Je suis une débutante , en programmation, j'utilise mikro c , je rencontre quelque problème dans mon programme.
    Mon projet consiste à réceptionné la trame , puis a vérifié la trame avec le checksum .
    Voici mon programme en entier ( la partie USB ne me concerne pas )
    D'après le prof , les reset de chaîne de caractère sont faux puis la récupération du checksum reçu
    merci de bien vouloirs m'aider

  2. #2
    Modérateur
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 693
    Points : 5 367
    Points
    5 367

    Par défaut

    Salut,
    Citation Envoyé par Labete868 Voir le message
    Voici mon programme en entier
    Tu n'as pas posté le programme !
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  3. #3
    Membre confirmé
    Avatar de deletme
    Homme Profil pro
    Inscrit en
    janvier 2011
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2011
    Messages : 253
    Points : 503
    Points
    503

    Par défaut

    En complément de @Vincent PETIT,

    Mon projet consiste à réceptionné la trame , puis a vérifié la trame avec le checksum .
    Quel type de trame ? D'où proviennent elles ? En bref, quelle est l'allure d'une trame type ?
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
    - Martin Golding
    Traduction obligatoire : "Toujours écrire du code en gardant en tête que le mec qui en assurera la maintenance est un psychopathe violent qui connait votre adresse"

  4. #4
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 19
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : avril 2017
    Messages : 4
    Points : 1
    Points
    1

    Par défaut Voici mon programme :

    Le programme d'interruption est normalement ok , la ou cela bloque ces au niveau de la vérification de la trame reçut
    Images attachées Images attachées      

  5. #5
    Modérateur
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 693
    Points : 5 367
    Points
    5 367

    Par défaut

    Tu abuses quand même en nous filant une image de ton programme ! Tu aurais pu nous poster le programme (en texte) et encadré des balises code.

    Cliquer là :

    Nom : Capture du 2017-04-13 21-45-59.png
Affichages : 65
Taille : 735 octets

    Ce qui va afficher ça et tu ajoutes un C comme j'ai entouré en rouge, comme ça la coloration syntaxique du langage C s'affiche :

    Nom : Capture du 2017-04-13 21-45-60.png
Affichages : 63
Taille : 1,8 Ko





    Concernant les 3 flèches que tu as dessiné; CKSUM_Recu et CKSUM_Calcul sont des tableaux, donc pour les "reseter" il faut faire une boucle avec i allant de 0 à 2 et faire CKSUM_Recu[i] = 0; ou CKSUM_Recu[i] = '\0'; si tu veux mettre le caractère de fin de chaîne.

    Dans la dernière fonction Calcul_Cheksum() il y a deux choses bizarres à moins que tu as oublié de nous expliquer quelques choses.

    1. On dirait qu'il y a un problème de portée, ta variable Checksum est utilisée pour faire le calcul (ou exclusif du checksum) sauf que tu ne fais rien de cette variable. Une fois que tu sorts de la fonction Calcul_Cheksum(), la variable locale Checksum disparaît car c'est une variable locale de la fonction ! Soit ta fonction doit retourner la variable Checksum soit il faut que cette variable soit globale.

    2. Ton calcul démarre à partir du caractère 'N' de la trame reçu, c'est normal ? Le caractère '$' n'est pas dans la trame ?



    ps : c'est les réponses qu'attendait deletme et notamment lorsqu'il t'a demandé ce qu'était une trame type.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  6. #6
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 19
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : avril 2017
    Messages : 4
    Points : 1
    Points
    1

    Par défaut

    Le caractère "$" fait partie de le trame ceci va servir à identifier la trame
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // Vérification de l'intégrité de la trame reçue
    /******************************************************************************/
    char Trame_OK(char *string)
    {
      CKSUM_Calcul;                 // Calcul Checksum
      for(i=0 ; i<2 ; i++){
      CKSUM_Calcul == 0;      // Reset chaine caracteres "CKSUM_Calcul"
      CKSUM_Recu[i] = 0;  // Reset chaine caracteres "CKSUM_Recu"
      }
      ShortToHex (Checksum, "6E") //Conversion Checksum --> Hexa
      CKSUM_Recu;                   // Recup. Checksum reçu
      if(string[0]!= 1)             // Comparaison des 2 chaines
      return 0;
    }
    
    /*****************************************************************************/
    Voila ce que ça donne , et mon checksum doit retourner

  7. #7
    Modérateur
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 693
    Points : 5 367
    Points
    5 367

    Par défaut

    Alors là tu me flingues.....

    Ça y est, j'ai compris ! Je suis sensé sortir ma boule de cristal et lui demander :

    Montre moi le minimum qui fonctionne pour avoir une base pour démarrer car Labete868 veut que je l'aide mais en devinant ses pensées, ce qui devrait m'amener à ce que son prof lui demande, puis j'arriverai a cerner le mystérieux projet dont ce programme fait partie.
    Montre moi si ce que je lis est en partie bon (exemple le prof a donné une base solide) ou alors complètement faux (Labete868 a essayé quelque chose au hasard)
    Montre moi pourquoi par exemple, je vois un tableau Trame_Recue[60] d'une taille de 60 caractères alors que la trame dedans ne fait que 48 caractères ? La trame est de taille variable peut être ?
    ...
    ...
    ...
    je pourrai continuer comme ça longtemps






    Je vais t'aider une dernière fois et si jamais tu réponds à nouveau sans faire l'effort de te mettre à la place des autres, qui ne connaissent pas du tout le contexte de ton projet et en ne donnant strictement aucune explication complémentaire..... je te laisse te débrouiller.

    A la fin de ton programme, je parle de celui du tout premier post où tu as donné une image du programme, tu calculs un checksum qui semble être un contrôle de parité, je dis semble être car tu ne nous l'a pas dit clairement. Et cela consiste bien en un XOR (ou exclusif) entre tous les octets de données de la trame. Qu'est ce que des octets de données ?

    $N03,22.3, 1012,166,24.5,4837.5196,00225.2343*6E

    Ça semble être ce qui est en gras, en gris ce sont des identificateurs/séparateurs qui ne sont pas des données et en rouge c'est le checksum de la trame. C'est à dire quelque chose qui ressemble étrangement a une trame NMEA, je dis semble être car tu ne nous l'a pas dit clairement non plus donc à nous de deviner comment se compose une trame. Donc pour calculer le checksum, il faut bien faire :

    'N'^'0'^'3'^','^' '^1........^'4'^'3' = 6E

    Donc par le calcul, tu trouves 6E qu'il faut comparer avec le checksum dans la trame (en rouge) $N03,22.3, 1012,166,24.5,4837.5196,00225.2343*6E et si le calcul 6E correspond aux caractères "6E" alors la trame est ok !
    Mais ce 6E obtenu par le calcul, il faut le remonter et le sortir de la fonction car tu dois t'en servir dans ton programme, pour comparer :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char Calcul_Cheksum(char *string)
    {
    	unsigned char i;
    	unsigned char checksum = 0;
     
    	for(i = 1; i < 45; i++)
    	{
    		checksum = checksum ^ string[i];
    	}
     
    	return checksum;
    }

    Dans ce programme il y a deux choses a comprendre, la première c'est de se demander de où à où on fait le XOR pour calculer le checksum. Je le fais de string[1] qui contient le caractère 'N' jusqu'à string[44] qui contient le caractère '3' ! Attention ! si jamais la trame a une longueur variable, donc qui bouge, alors il faut ajuster la valeur 44 (remarque que dans la boucle for j'ai écrit i strictement inférieur à 45 donc 44) pour ne prendre que les données et la seconde c'est que c'est bien beau de calculer un checksum mais sans la présence de return, une fois la fonction cette valeur est perdue.

    A toi de savoir si la trame est fixe ou alors si elle peut bouger ? Moi j'en sais rien.

    Donc pour appeler la fonction, on fait comme ça :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    char Trame_OK (char *string)
    {
    // dans la fonction main on appellera Trame_OK de cette manière Trame_OK (Trame_Recue) 
    // ce qui sera équivalent a faire Trame_OK ("$N03,22.3, 1012,166,24.5,4837.5196,00225.2343*6E") 
    // et ça nous aménera dans cette fonction ci dessous
     
    // 1) calcule du checksum de la trame reçue
    	char checksum = Calcul_Cheksum(string);
     
    // 2) est ce que la variable checksum calculée juste au dessus contient la même valeur de checksum que ce que je lis dans la trame ?
    // en prenant garde car je m'apprête à comparer une valeur obtenue par calcul avec des caractères ASCII donc il doit y avoir une histoire 
    // de conversion ASCII hexa quelque part pour comparer deux choses comparables. il faut aussi se poser la question de la position des
    // caractères qui composent le checksum dans la trame. c'est les deux dernières caractères, ok ! mais ils sont aux positions string[?] et string[?]
    	...
    	...
    	...
    }

    Est ce que tu comprends jusqu'ici ? Est ce que la trame peut varier en longueur ? C'est à dire est ce que le checksum est toujours composé des caractères 47 et 48 ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  8. #8
    Nouveau Candidat au Club
    Femme Profil pro
    Lycéen
    Inscrit en
    avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 19
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : avril 2017
    Messages : 4
    Points : 1
    Points
    1

    Par défaut

    Merci, d'avoir pris la peine de me répondre .
    Je m'y connais pas vraiment en programmation , désolé si je vous ai laissé sans information .

    Alors je vais vous expliquer mon projet , le sujet consiste à programmer une ballon sonde qui va pouvoir mesurer les températures pour prévoir la météo, ceci pourra être suivi via une application au cas où si celui ci échouerait.
    Les taches seront réparties , en 2 groupes. Donc on a le groupe GPS embarqué et l’équipe terrestre (j'en fais partie) .
    Moi je m'occupe de la réception de la trame, je devrais pouvoir créer un programme d'interruption (ce qui est fait), recevoir la trame de mon collègue qui est celui-ci ''$N03,22.3, 1012,166,24.5,4837.5196,00225.2343*6E puis recalculer la trame avec le checksum pour vérifier si celui est correct .
    Ma trame est variable , je ne recevras pas identiquement la même mais ceci est un test .

    J'ai fait quelques recherches, et j'ai programmé ceci comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char Trame_OK (char *string)
    {
      Calcul_Checksum (*string)
      for (i=0;i<3;i++)
    {
    CKSUM_Calcul  [i] = 0;               //reset chaîne de caractère
    CKSUM_Recu [i] = 0;                 // reset chaîne de caractère
    }
     CKSUM_Recu [] = " " ;      je n'ai pas vraiment d'idée ici 
    if (string[0]!= 1);                       // Comparaison des deux chaines 
    return 0; 
    }
    Voila , je voudrais donc savoir si ceci est correct, sinon si possible me corriger mon sujet doit être terminé pour demain 12h30 svp j'ai besoin d'aide
    J'espère avoir été un peu plus explicatif, sinon me redemander je répondrai dans la soirée.
    Merci

  9. #9
    Modérateur
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 693
    Points : 5 367
    Points
    5 367

    Par défaut

    Ah bah là on a envie de t'aider
    Citation Envoyé par Labete868 Voir le message
    mon sujet doit etre terminer pour demain 12h30 svp j'ai besoin d'aide


    Citation Envoyé par Labete868 Voir le message
    Ma trame est variable , je ne recevrais pas identiquement la même mais ceci est un test .
    C'est une information très très importante car elle signifie que le checksum dans la trame reçu n'est pas toujours composé du caractère n°46 et n°47 (en considérant que le premier caractère, le '$'est le n°0)
    En revanche voilà ce qu'on sait :
    Une trame démarre toujours par un '$'.
    Les données commence au caractère n°1, donc le 'N'.
    Les données sont variables mais elles se terminent avant le caractère '*'.
    Le checksum de la trame reçue est composé des deux caractères qui se trouvent après le caractère '*'.


    Tout d'abord il faut revoir la fonction Calcul_Cheksum (je l'ai commenté pour que tu comprennes)
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    char Calcul_Cheksum(char *string)
    {
    // une trame démarre toujours par un '$'.
    // les données commence au caractère n°1, donc le 'N'.
    // les données sont variables mais elles se terminent avant le caractère '*'.
    // le checksum de la trame reçue est composé des deux caractères qui se trouvent après le caractère '*'.
    //
    // on va faire une boucle qui démarre au caractère n°1 ('N') jusqu'au caractère qui se trouve avant ('*')
    // comme le tableau trame_reçue fait 60 caractères on fera attention a ne pas aller au delà sinon bug
     
    	unsigned char i;
    	unsigned char checksum = 0;
     
    // on fait une boucle allant de 1 à 59 donc potentiellement on est
    // capable d'avoir dedans une trame très longue, genre 60 caractères
    	for(i = 1; i < 60; i++)
    	{
    		if(string[i] != '*') 				// tant qu'on a pas rencontré le caractère '*'
    			checksum = checksum ^ string[i]; 	// on calcul le checksum des données
    		else 						// sinon, donc on a rencontré le caractère '*'
    			i = 60; 				// on met i = 60 comme ça la boucle for va s'arrêter tout de suite.
    	}
     
    	return checksum;
    }


    Citation Envoyé par Labete868 Voir le message
    Voila , je voudrais donc savoir si ceci est correcte , sinon si possible me corriger
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    char Trame_OK (char *string)
    {
      Calcul_Checksum (*string);
     
      for (i=0;i<3;i++)
      {
        CKSUM_Calcul  [i] = 0;               //reset chaîne de caractère
        CKSUM_Recu [i] = 0;                 // reset chaîne de caractère
      }
      CKSUM_Recu [] = " " ;      je n'ai pas vraiment d'idée ici 
     
      if (string[0]!= 1)
        ;                       // Comparaison des deux chaines 
     
      return 0; 
    }
    Il y a des choses qui ne vont pas, autant syntaxiquement que dans le résolution du problème
    Voici comment moi je ferai en modifiant ton programme.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    unsigned char Trame_OK (char *string)
    {
    	unsigned char checksum;
    	unsigned char CKSUM_Calcul[3];
     
    	unsigned char OK = 0;			// par défaut la trame est fausse à l'initialisation
     
    	unsigned char i;
     
     
    	for (i = 0; i  < 3; i++)
    		CKSUM_Calcul  [i] = 0;              //reset chaîne de caractère
     
     
    	checksum = Calcul_Cheksum(string);
    // a cette étape la variable checksum du dessus contient le checksum obtenue par calcul maintenant, il faut s'assurer que le
    // checksum obtenu par calcul est le même que celui qui se trouve dans la trame, c'est à dire, les deux caractères après le '*' dans la trame
    // le problème c'est que les formats ne sont pas les mêmes, d'un côté un a un nombre obtenu par calcul et de l'autre des caractères
     
     
    // on va transformer tout de suite checksum en caractère
    	ShortToHex(checksum, CKSUM_Calcul);
     
     
    // tout comme dans Calcul_Cheksum on va faire une boucle qui démarre au début du tableau et on va partir à la recherche du caractère ('*') une fois
    // trouvé on sait que les deux caractère qui suivent sont le checksum. on fera attention a ne pas aller au dela de 60 qui est la longueur maxi du tableau
    	for(i = 0; i < 60; i++)
    	{
    		if(string[i] == '*')	// on cherche après '*'
    		{
     
    			// si on est là alors on a trouvé '*'
     
    			// on incrémente i de 1 pour aller au caractère suivant
    			i = i + 1;
     
    			// est ce que les premiers caractères sont identiques ?
    			if (CKSUM_Calcul[0]== string[i])
    			{
    				// oui alors on regarde le suivant
     
    				// on incrémente i de 1 pour aller au caractère suivant
    				i = i + 1;
     
    				// est ce que les seconds caractères sont identiques ?
    				if (CKSUM_Calcul[1]== string[i])
    				{
    					// oui alors OK = 1 et on met i à 60 pour arrêté la boucle for inutile de continuer pour rien
    					OK = 1;
    					i = 60;
    				}
    				else
    					// non les seconds caractères ne sont pas identiques, on arrête la boucle
    					i = 60;
    			}
    			else
    				// non les premiers caractères ne sont pas identiques, on arrête la boucle
    				i = 60;
     
    		}
     
    	}
     
     
    	return OK;
    }

    J'ai commenté le plus possible et je pense que ça devrait fonctionner (je n'ai pas MickroC chez moi, je n'utilise plus de microcontrôleur Microchip depuis longtemps) puisque j'ai tout testé avec GCC en implémentant moi même StrToHex qui n'existe que sous MikroC.
    Cette fonction retourne 1 lorsque les checksum sont les mêmes et 0 si ils sont différents.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

Discussions similaires

  1. Calculer checksum d'une entête ip
    Par snyfir dans le forum Développement
    Réponses: 0
    Dernier message: 21/05/2009, 17h28
  2. VB6 et Mscomm Problème dans la Trame Reçue Modbus
    Par mat-tech dans le forum Automation
    Réponses: 13
    Dernier message: 01/10/2008, 19h55
  3. VB6 et Mscomm Problème dans la Trame Reçue Modbus
    Par mat-tech dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 29/09/2008, 17h46
  4. Probleme calcule checksum
    Par nuFox dans le forum Réseau
    Réponses: 17
    Dernier message: 19/02/2008, 08h49
  5. Réponses: 2
    Dernier message: 26/09/2007, 16h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo