IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Emission / Réception par port série


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut Emission / Réception par port série
    Bonjour à tous,

    J'ai pour projet TPE de programmer un robot en C.
    A la base j'ai un programme basic, que j'ai réussi à traduire en français.

    J'ai récupéré sur le net un code source pour contrôler le port série, avec la fonction main vide. (On peut faire ce qu'on veut de ce code).
    J'ai ensuite créé mon programme pour envoyer des ordres au robot.

    Lorsque je relie les broches 2 et 3 du port série (les broches d'émission et de réception), toutes les chaînes de caractères que j'envoie avec le programme sont ensuite reçues. J'en déduis que mon programme fonctionne correctement.

    Mon problème : lorsque j'envoie la chaîne {2,'B','O',3,0} au robot (pour l'initialiser), je ne reçois pas la réponse attendue {2,'O',3,0} mais une chaîne bizarre. Je reçois cette même chaîne si je débranche le robot.
    J'en déduis : le robot ne reçois pas mes ordres, ou il les reçoit mais mon programme ne peut pas recevoir la réponse, donc problème dans la fonction d'émission, ou de réception.

    Voici des codes.

    Extrait de la fonction main :
    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
    17
    18
    19
    20
    21
    22
     
    char init[]={2,'B','O',3,0}; // chaîne d'initialisation
    char *pointeur; 
    pointeur = &init;
     
    char je_recois[25]; // chaîne qui recoit les caractères envoyés par le robot
    int max = 25; // nombre maximum de caractères à lire lors de la réception
    int ai_lu = 0; // rapporte le nombre de caractères lus lors de la réception
     
    /* Configuration du port serie :
         * Communication sur le port COM1
         * Débit de 9600 bits/s
         * 8 bits de données
         * Pas de bit de parité
         * 2 bits d'arrêt         */   
        g_ErrCom=OuvreCom(PORT1,V9600,BITS_8,PAS_DE_PARITE,BIT_DE_STOP_2);
     
    /* Envoi de la chaîne qui initialise le robot */
    g_ErrCom=EmissionCom(pointeur,sizeof(init));
     
    /*Réception de l'accusé */
    g_ErrCom=ReceptionCom(&je_recois ,max, &ai_lu);


    Fonction EmissionCom :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    //---------------------------------------------------------------------------- 
    // FONCTION    : EmissionCom 
    //---------------------------------------------------------------------------- 
    // DESCRIPTION    : 
    // Emission d'octets sur la liaison série 
    // 
    //---------------------------------------------------------------------------- 
    // PARAMETRES    : 
    //        -lpBuf Pointeur sur les octets a emettre 
    //        -nCount Nombre d'octet a emettre 
    // 
    //---------------------------------------------------------------------------- 
    // RETOUR    :Code d'erreur 
    //---------------------------------------------------------------------------- 
    e_ErrCom EmissionCom(const void* lpBuf,unsigned int nCount) 
    {     
     
        DWORD NumBytes=0; 
     
        if(g_hCom!=NULL) 
        { 
            // On pari sur pas d'erreur 
            g_ErrCom=e_ErrCom_None; 
     
            //Emission du buffer 
            if(WriteFile(g_hCom,lpBuf,nCount,&NumBytes,NULL)==0) 
            { 
                g_ErrCom=e_ErrCom_Emission; 
            } 
        } 
        else 
            //Le port n'a pas été ouvert 
            g_ErrCom=e_ErrCom_Creation; 
     
        return g_ErrCom; 
     
    }

    La fonction ReceptionCom:
    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
    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
     
    //--------------------------------------------------------------------------- 
    // FONCTION    : ReceptionCom 
    //--------------------------------------------------------------------------- 
    // DESCRIPTION    : 
    // Reception de caractères sur la liaison série 
    // 
    //--------------------------------------------------------------------------- 
    // PARAMETRES    : 
    //        -lpBuf Pointeur sur le buffer de caractère a lire 
    //        -nCountMax Nombre maxi de caractère a lire 
    //        -pCountRead Pointeur sur le nombre de caractères lus 
    //--------------------------------------------------------------------------- 
    // RETOUR    :Code d'erreur 
    //--------------------------------------------------------------------------- 
    e_ErrCom ReceptionCom(void *lpBuf,unsigned int nCountMax, unsigned int* pCountRead) 
    { 
    COMSTAT Stat; 
    DWORD Errors; 
    unsigned int nCarALire; 
    unsigned long NCarLus=0; 
     
        if(g_hCom!=NULL) 
        { 
            //on pari sur pas d'erreur 
            g_ErrCom=e_ErrCom_None; 
     
            //Pour éviter de gérer un time out 
            Sleep(500); 
     
            //Pour connaitre le nombre d'octets dans le buffer d'entrée 
            ClearCommError(g_hCom,&Errors,&Stat); 
            nCarALire=Stat.cbInQue; 
     
            //On effectue la lecture si il y a des caractères présents 
            if( (nCarALire>0)&&(nCarALire<=nCountMax) ) 
            { 
                if(ReadFile(g_hCom,lpBuf,nCarALire,&NCarLus,NULL)==0) 
                {         
                    g_ErrCom=e_ErrCom_Reception; 
                } 
     
            } 
            *pCountRead=NCarLus; 
        } 
        else 
            //Le port n a pas été ouvert 
            g_ErrCom=e_ErrCom_Creation; 
     
        //Compte rendu de l'exécution 
        return g_ErrCom; 
     
    }

    Voilà, j'ai donc du mal à saisir ce qui ne va pas.
    Je suis sûr qu'il faut envoyer la chaîne ascii 2 + 'B' + 'O' + ascii 3 (j'ai testé le programme basic).

    Merci beaucoup.
    S'il vous manque des renseignements, dites le moi.


  2. #2
    Membre à l'essai
    Inscrit en
    Décembre 2005
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 12
    Points : 10
    Points
    10
    Par défaut
    tu est sur qu'il faut envoyer la chaîne {2,'B','O',3,0} car si c une chaine de caractère,
    sa se trouve il faut que tu envois la chaîne {'2','B','O','3','0'}
    car 2 et '2' c'est pas la meme chose. Tu peut toujours essaier.

    Autrement je suis bien interesser par les fonctions qui utilise le port serie, si tu peut les passer. Merci !!!

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Lorsque je compile ton code de ton main, j'obtiens:

    warning: assignment from incompatible pointer type
    La ligne qui pose probleme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char init[]={2,'B','O',3,0}; // chaîne d'initialisation
    char *pointeur;
    pointeur = &init;   //fy: ICI, c'est pas le bon type!
    En effet, pointeur est un pointeur vers un caractere et init est un tableau de caractere. Autrement dit tu devrais ecrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char init[]={2,'B','O',3,0}; // chaîne d'initialisation
    char *pointeur;
    pointeur = init;   //fy: ICI, c'est pas le bon type!

    Ensuite, quand tu appelles ReceptionCom, tu fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_ErrCom=ReceptionCom(&je_recois ,max, &ai_lu);
    Or tu devrais faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_ErrCom=ReceptionCom(je_recois ,max, &ai_lu);
    Car le premier argument est un void *lpBuf...

    Si on y reflechit bien, ton probleme vient du fait que tu n'as pas saisi (ou on dirait que c'est ca!) qu'un tableau est en fait deja un pointeur, ce n'etait donc pas la peine de t'amuser a faire des indirections...

    Pour terminer, ce n'est pas necessaire dans le cas present de creer une variable pointeur, utilise directement ta variable init...

    Jc

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Merci, je vais essayer ça fy.
    En effet j'ai du mal avec les pointeurs et les fonctions...

    mdtdamien, voici le code source avec toutes les fonctions nécessaires pour contrôler le port série.

    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
    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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
     
    // FICHIERS D'INCLUSION 
    //------------------------------------------------------------------------------ 
    #include <windows.h> 
    #include <winbase.h> 
    #include <stdio.h> 
    #include <conio.h> 
    #include <string.h> 
     
    // CONSTANTES 
    //------------------------------------------------------------------------------- 
    // Définition du code d'erreurs 
    typedef enum 
    { 
        e_ErrCom_None,        // Pas d'erreur 
        e_ErrCom_Creation,    // Erreur lors de la création du flux 
        e_ErrCom_Utilise,        // Le port com est déjà utilisé 
        e_ErrCom_Inexistant,    // Le port com n'existe pas 
        e_ErrCom_Timeout,    // Timeout lors d'une émission-réception 
        e_ErrCom_Emission,        // Erreur lors de l'émission 
        e_ErrCom_Reception,        // Erreur lors de la réception 
        e_ErrCom_Definition_Trame,    // Erreur de définition de la trame 
        e_ErrCom_Nack,    // Demande non prise en compte 
        e_ErrCom_Checksum        // Erreur de checksum 
    } e_ErrCom; 
     
    // Nom du port série 
    #define PORT1        "COM1" 
    #define PORT2        "COM2" 
     
    // Définition des vitesses de communication 
    #define V1200        1200 
    #define V2400        2400 
    #define V4800        4800 
    #define V9600        9600 
     
    // Définition du nombre de bits 
    #define BITS_7    7 
    #define BITS_8     8 
     
    // Définition du nombre de bits de stop 
    #define BIT_DE_STOP_1    1 
    #define BIT_DE_STOP_2    2 
     
    // Définition de la parité 
    #define PAS_DE_PARITE    'N' 
    #define PARITE_IMPAIRE    'O' 
    #define PARITE_PAIRE    'E' 
     
    // Codes de retour génériques 
    #define OK 1 
    #define KO 0 
     
    // Longueur max réservée pour une trame 
    #define LG_TRAME    100 
     
    // PROTOTYPES 
    //---------------------------------------------------------------------------- 
    e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int Parity,int StopBits); 
    e_ErrCom EmissionCom(const void *lpBuf, unsigned int nCount); 
    e_ErrCom ReceptionCom(void *lpBuf, unsigned int nCountMax, unsigned int *pCountRead); 
    void FermeCom(); 
     
    // VARIABLES GLOBALES 
    //----------------------------------------------------------------------------- 
    DCB g_DCB; // structure dcb du port 
    e_ErrCom g_ErrCom= e_ErrCom_None;    // Variable des erreurs de com 
    HANDLE g_hCom = 0;            // handle de la com 
     
     
    int main (void) 
    {
     
    } 
     
     
    //------------------------------------------------------------------------------ 
    // FONCTION    : OuvreCom 
    //------------------------------------------------------------------------------ 
    // DESCRIPTION     : 
    // Initialise et ouvre un port série 
    // 
    //------------------------------------------------------------------------------ 
    // PARAMETRES     : 
    //        - strPort        Nom du port "COM1", "COM2" 
    //        - BaudRate        Vitesse 
    //        - BitsSize        Taille de l'info 
    //        - Parity        Parité 
    //        - StopBits        Nombre de bits de stop 
    // 
    // RETOUR     :Code d'erreur 
    //------------------------------------------------------------------------------ 
    e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int Parity,int StopBits) 
    { 
        g_ErrCom = e_ErrCom_None; 
     
        // On ouvre le port série 
        g_hCom = CreateFile(strPort,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,NULL); 
     
        if(g_hCom == INVALID_HANDLE_VALUE) 
        { 
            // Echec 
            g_ErrCom=e_ErrCom_Creation; 
        } 
        else 
        { 
            // On vide les buffers 
            PurgeComm(g_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);         
     
            // On paramètre le port série 
            g_DCB.DCBlength = sizeof(DCB); 
            //Configuration actuelle 
            GetCommState(g_hCom, &g_DCB); 
            //Modification du DCB 
            g_DCB.BaudRate=BaudRate; 
            g_DCB.ByteSize=BitsSize; 
            g_DCB.Parity=Parity; 
            g_DCB.StopBits=StopBits; 
            g_DCB.fDtrControl=DTR_CONTROL_DISABLE; 
            //Configuration de la liaison serie 
            SetCommState(g_hCom,&g_DCB); 
        } 
        return g_ErrCom; 
    } 
     
     
     
    //---------------------------------------------------------------------------- 
    // FONCTION    : EmissionCom 
    //---------------------------------------------------------------------------- 
    // DESCRIPTION    : 
    // Emission d'octets sur la liaison série 
    // 
    //---------------------------------------------------------------------------- 
    // PARAMETRES    : 
    //        -lpBuf Pointeur sur les octets a emettre 
    //        -nCount Nombre d'octet a emettre 
    // 
    //---------------------------------------------------------------------------- 
    // RETOUR    :Code d'erreur 
    //---------------------------------------------------------------------------- 
    e_ErrCom EmissionCom(const void* lpBuf,unsigned int nCount) 
    {     
     
        DWORD NumBytes=0; 
     
        if(g_hCom!=NULL) 
        { 
            // On pari sur pas d'erreur 
            g_ErrCom=e_ErrCom_None; 
     
            //Emission du buffer 
            if(WriteFile(g_hCom,lpBuf,nCount,&NumBytes,NULL)==0) 
            { 
                g_ErrCom=e_ErrCom_Emission; 
            } 
        } 
        else 
            //Le port n'a pas été ouvert 
            g_ErrCom=e_ErrCom_Creation; 
     
        return g_ErrCom; 
     
    } 
     
    //--------------------------------------------------------------------------- 
    // FONCTION    : ReceptionCom 
    //--------------------------------------------------------------------------- 
    // DESCRIPTION    : 
    // Reception de caractères sur la liaison série 
    // 
    //--------------------------------------------------------------------------- 
    // PARAMETRES    : 
    //        -lpBuf Pointeur sur le buffer de caractère a lire 
    //        -nCountMax Nombre maxi de caractère a lire 
    //        -pCountRead Pointeur sur le nombre de caractères lus 
    //--------------------------------------------------------------------------- 
    // RETOUR    :Code d'erreur 
    //--------------------------------------------------------------------------- 
    e_ErrCom ReceptionCom(void *lpBuf,unsigned int nCountMax, unsigned int* pCountRead) 
    { 
    COMSTAT Stat; 
    DWORD Errors; 
    unsigned int nCarALire; 
    unsigned long NCarLus=0; 
     
        if(g_hCom!=NULL) 
        { 
            //on pari sur pas d'erreur 
            g_ErrCom=e_ErrCom_None; 
     
            //Pour éviter de gérer un time out 
            Sleep(500); 
     
            //Pour connaitre le nombre d'octets dans le buffer d'entrée 
            ClearCommError(g_hCom,&Errors,&Stat); 
            nCarALire=Stat.cbInQue; 
     
            //On effectue la lecture si il y a des caractères présents 
            if( (nCarALire>0)&&(nCarALire<=nCountMax) ) 
            { 
                if(ReadFile(g_hCom,lpBuf,nCarALire,&NCarLus,NULL)==0) 
                {         
                    g_ErrCom=e_ErrCom_Reception; 
                } 
     
            } 
            *pCountRead=NCarLus; 
        } 
        else 
            //Le port n a pas été ouvert 
            g_ErrCom=e_ErrCom_Creation; 
     
        //Compte rendu de l'exécution 
        return g_ErrCom; 
     
    } 
     
    //----------------------------------------------------------------------- 
    // FONCTION    : FermeCom 
    //----------------------------------------------------------------------- 
    // DESCRIPTION    : 
    // Ferme le port série préalablement ouvert avec OuvreCom 
    // 
    //----------------------------------------------------------------------- 
    // PARAMETRES    : 
    //        Néant 
    //----------------------------------------------------------------------- 
    // RETOUR    :Néant 
    //----------------------------------------------------------------------- 
    void FermeCom() 
    { 
        if(g_hCom!=NULL) 
        { 
            CloseHandle(g_hCom); 
        } 
    }

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Tiens nous au courant et mets ce sujet en Resolu si ca marche...

    Par contre la remarque de mdtdamien est tout a fait pertinente:
    tu est sur qu'il faut envoyer la chaîne {2,'B','O',3,0} car si c une chaine de caractère,
    sa se trouve il faut que tu envois la chaîne {'2','B','O','3','0'}
    car 2 et '2' c'est pas la meme chose. Tu peut toujours essaier.
    Verifie bien la spec de ton robot...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    J'ai un dossier sur le robot qui dit :

    Chaque message doit être clôturé, caractère ascii 2 au début et caractère ascii 3 à la fin. "BO" initialise le robot. La chaîne dans le programme basic est celle-ci : 2 + "BO" + 3
    Donc je pense que ça se traduit en C par {2,'B','O',3,0}

    Bon samedi
    Dès que je vois que ça marche (pas avant fin de semaine prochaine) je mets sur résolu.

  7. #7
    Membre à l'essai
    Inscrit en
    Décembre 2005
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 12
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par odSen

    Chaque message doit être clôturé, caractère ascii 2 au début et caractère ascii 3 à la fin. "BO" initialise le robot. La chaîne dans le programme basic est celle-ci : 2 + "BO" + 3
    dans se cas il faut donc que tu envoi comme je le penser {'2','B','O','3',0}
    se sont des caracteres que tu envoie pas des chiffres, voie le '2' comme un symbole et non comme un chiffre.
    le chiffre 2 vaut 2
    alors que le caractere 2 vaut 50 dans le code ascii

    je c'st pas si j'ai été tres claires

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par mdtdamien
    dans se cas il faut donc que tu envoi comme je le penser {'2','B','O','3',0}
    A mon avis, la notation ascii 2 ne signifie pas qu'il faut envoyer le caractere '2' mais bien la valeur 2 contenu dans un char. Sinon la documentation parlerait plutot de '2' et '3'.
    En outre c'est assez courant dans des protocoles de communication d'utiliser la valeur 2 et 3 (respectivement STX et ETX) pour marquer le debut et la fin d'un bloc de donnees. Par contre ce qui me surprends c'est l'absence de somme de controle dans la chaine envoye, je me serais attendu a trouver un LRC apres le 3

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    Par contre ce qui me surprends c'est l'absence de somme de controle dans la chaine envoye, je me serais attendu a trouver un LRC apres le 3
    Je ne comprends pas bien, tu peux m'expliquer ?
    Merci

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odSen
    Par contre ce qui me surprends c'est l'absence de somme de controle dans la chaine envoye, je me serais attendu a trouver un LRC apres le 3
    Je ne comprends pas bien, tu peux m'expliquer ?
    Lorsqu'on transmet des données, celle-ci peuvent être altérées. Afin de vérifier ce qui est reçu, on transmet donc en plus une valeur calculée à partir des données à transmettre.

    Le plus simple est la 'somme de contrôle' sur 8-bit, par exemple, qui consiste à faire la somme (sans retenue) des données transmises et d'ajouter le résultat (ou son complément à deux) aux données. Ca permet alors de vérifier à l'arrivée que les données reçues sont correctes.

    Evidemment, il existe des degrés de fiablilité d'un tel mécanisme. Celui-ci est assez faible, mais mieux que rien...

    Ca peut éviter quelques dégats...

    Pas de Wi-Fi à la maison : CPL

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Merci pour les explications Emmanuel
    Dans mon cas, vu que je ne communique pas directement avec le robot mais par le biais d'une interface matérielle, je pense que les vérifications se font au niveau de cette dernière. (Du moins c'est ce qu'on a vu en cours).

    Ton robot a plus de gueule que le mien

  12. #12
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odSen
    Dans mon cas, vu que je ne communique pas directement avec le robot mais par le biais d'une interface matérielle, je pense que les vérifications se font au niveau de cette dernière. (Du moins c'est ce qu'on a vu en cours).
    Ce que tu appelles l'interface matérielle est l'UART (composant électronique assurant la conversion paralelle/série). Le mode série est probablement asyncrone et peut (c'est optionnel) disposer d'un contrôle de parité au niveau d'une unité de données (information de 5 à 8 bits). C'est le bit de parité qui peut être absent (None), représenter la parité paire (Even) ou impaire (Odd). Ce contrôle ne concerne que l'unité de donnée courante. Elle permet de signaler qu'une unité de donnée est defectueuse.

    Supposons maintenant que l'unité de donnée est de 8 bits (soit un octet). Si dans le message (séquence d'octets) reçu, il manque un ou plusieurs octets, on ne peut le savoir que si il existe un mecanisme de contrôle de l'integrité du message.

    En fait, et comme toujours en matière de transmission de données, chaque couche de protocole peut avoir ses mécanismes de contrôles, et ceux-ci sont indépendants les uns des autres.

    NOTA : rien de tout ceci n'a à voir de près ou de loin avec le langage C.
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Sympa pour les explications

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Bonsoir,
    J'ai testé le programme avec vos indications.
    Le robot ne répond toujours pas aux instructions...

    Voici mon code, simplifié, sans les fonctions d'ouverture de ports, d'émission etc :
    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
    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
    int main (void) 
    {     
     
        char je_recois []={0};  // Variable qui reçoit les caractères  
        unsigned int max=50;  // Caractères à lire au max
        unsigned int ai_lu=0;  // Rapporte le nombre de caractères lus
     
        char init[]={2,'B','O',3,0}; // Chaîne d'initialisation
        char lecture[]={2,'L',3,0}; // Chaîne pour interroger les coordonnées du robot
     
        OuvreCom(PORT1,V9600,BITS_8,PAS_DE_PARITE,BIT_DE_STOP_2);  // Ouverture du port        
     
        printf("Initialisation, patientez..."); 
        do     // Boucle : On envoie la chaîne init, et tant qu'on ne reçoit rien de la part du robot on continue                       
        {
                                EmissionCom(init, sizeof init); 
                                ReceptionCom(je_recois ,max, &ai_lu);
        } while (ai_lu==0);
     
        printf("\n\nNombre : %d",ai_lu);
        printf("\n\nCaracteres recus : %s",je_recois);
     
        ai_lu = 0;    
     
        printf("\n\n\n\nLecture des coordonnees...",lecture);
        do  // Boucle : Après initialisation, on envoie une chaîne au robot pour l'interroger sur la position de ses axes.
        { 
                                EmissionCom(lecture,sizeof lecture);
                                ReceptionCom(je_recois ,max, &ai_lu);
        }while (ai_lu==0);
     
        printf("\n\nNombre : %d",ai_lu);
        printf("\n\nCaracteres recus : %s",je_recois);
     
        getch();
     
        FermeCom();
     
        return 0;
     
    }
    Donc voilà, ma première boucle ne s'arrête pas car je ne reçois rien de la part du robot (il doit retourner ascii2 '0' ascii3). Si je branche sur le com une boucle (broches 2 et 3 reliées) je reçois tout ce que j'envoie (je reçois ma chaîne d'initialisation et ma chaîne d'interrogation).

    Je peux vous montrer des codes basic qui fonctionnent (j'ai testé).

    Le code qui correspond au mien :
    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
    17
    18
    CLS
     
    CLOSE
    OPEN "com1:9600,N,8,2" FOR RANDOM AS #1
     
    PRINT "Mode micro"
    PRINT #1, CHR$(2) + "BO" + CHR$(3)
    INPUT #1, MsgR$
    PRINT VAL(MsgR$)
     
    PRINT "Lecture axe"
    DO
            PRINT #1, CHR$(2) + "L" + CHR$(3)
            INPUT #1, MsgR$
     
            LOCATE 10, 1: PRINT MsgR$
     
    LOOP UNTIL INKEY$ = CHR$(27)
    Code pour initialiser, puis donner des ordres :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    CLOSE
    OPEN "com1:9600,N,8,2" FOR RANDOM AS #1
     
    PRINT "Mode micro"
    PRINT #1, CHR$(2) + "BO" + CHR$(3)
    INPUT #1, MsgR$
    PRINT VAL(MsgR$)
     
    PRINT "Ecriture axe"
    MsgE$ = CHR$(2) + "T"
     
    INPUT "Axe 1  : "; A$
    MsgE$ = MsgE$ + A$
    INPUT "Axe 2  : "; A$
    MsgE$ = MsgE$ + A$
    INPUT "Axe 3  : "; A$
    MsgE$ = MsgE$ + A$
    INPUT "Axe 4  : "; A$
    MsgE$ = MsgE$ + A$ + "2048" + CHR$(3)
     
     
     
    PRINT #1, MsgE$
    INPUT #1, MsgR$
    LOCATE 10, 1: PRINT MsgR$
    Donc voilà, je vois pas ce qui foire dans mon programme C et je tatonne un peu.
    Si vous avez une idée allez-y.
    Merci beaucoup.

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odSen
    Voici mon code, simplifié, sans les fonctions d'ouverture de ports, d'émission etc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int main (void) 
    {     
        char je_recois []={0};  // Variable qui reçoit les caractères
    1 seul caractère ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        unsigned int max=50;  // Caractères à lire au max
        unsigned int ai_lu=0;  // Rapporte le nombre de caractères lus
     
        char init[]={2,'B','O',3,0}; // Chaîne d'initialisation
        char lecture[]={2,'L',3,0}; // Chaîne pour interroger les coordonnées du robot
     
        OuvreCom(PORT1,V9600,BITS_8,PAS_DE_PARITE,BIT_DE_STOP_2);  // Ouverture du port        
     
        printf("Initialisation, patientez...");
    Pas logique, j'aurais fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        printf("Initialisation, patientez...\n"); 
        OuvreCom(PORT1,V9600,BITS_8,PAS_DE_PARITE,BIT_DE_STOP_2);  // Ouverture du port
    Qu'et-ce qui me prouve que cette fonction fait ce qu'on attend d'elle ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        do     // Boucle : On envoie la chaîne init, et tant qu'on ne reçoit rien de la part du robot on continue                       
        {
                                EmissionCom(init, sizeof init); 
                                ReceptionCom(je_recois ,max, &ai_lu);
        } while (ai_lu==0);
    Pas logique... J'aurais fait ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       EmissionCom(init, sizeof init); 
        do     // Boucle : On envoie la chaîne init, et tant qu'on ne reçoit rien de la part du robot on continue                       
        {
           ReceptionCom(je_recois ,max, &ai_lu);
        } while (ai_lu==0);
    etc.
    Pas de Wi-Fi à la maison : CPL

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Salut,
    J'avais mis char je_recois[] parce que je pensais qu'ainsi je n'avais pas à définir un nombre précis de caractères...d'ailleurs ça marche avec ma prise port série ou j'ai relié émission/réception. Je reçois des chaînes aussi grandes que je veux.

    Pour la boucle, j'ai bien essayé de faire à ta manière, mais toujours pas de résultats. J'ai vraiment l'impression d'avoir essayé mille trucs mais j'arrive vraiment pas à mettre le doigt sur ce qui va pas.

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odSen
    J'avais mis char je_recois[] parce que je pensais qu'ainsi je n'avais pas à définir un nombre précis de caractères...
    Ah ? Tu crois que tu peux déborder d'un tableau de char impunément ? Malheureux !
    d'ailleurs ça marche avec ma prise port série ou j'ai relié émission/réception. Je reçois des chaînes aussi grandes que je veux.

    Pour la boucle, j'ai bien essayé de faire à ta manière, mais toujours pas de résultats. J'ai vraiment l'impression d'avoir essayé mille trucs mais j'arrive vraiment pas à mettre le doigt sur ce qui va pas.
    Il faudrait déjà être sûr des fonctions de base... On peut voir le code ?
    Pas de Wi-Fi à la maison : CPL

  18. #18
    Membre habitué
    Inscrit en
    Novembre 2002
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 120
    Points : 125
    Points
    125
    Par défaut
    J'ai remarqué un petit changement par rapport au code basic. Lorsque que tu fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EmissionCom(init, sizeof init);
    Tu n'envoies pas init en tant que chaîne de caractères, mais en tant que block mémoire. En gros, le '\0' est, lui aussi, envoyé. Essaye:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EmmissionCom(init, sizeof init - 1);

  19. #19
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par odSen
    J'avais mis char je_recois[]
    Ah ? Tu crois que tu peux déborder d'un tableau de char impunément ? Malheureux !
    Woups , savais pas. Je peux mettre une valeur trop grande par contre ? Ca gênera pas ?
    Il faudrait déjà être sûr des fonctions de base... On peut voir le code ?
    Pour pas encombrer le sujet, je le mets ici : http://perso.wanadoo.fr/2501/base.c

    J'ai remarqué un petit changement par rapport au code basic. Lorsque que tu fais:

    Code:
    EmissionCom(init, sizeof init);


    Tu n'envoies pas init en tant que chaîne de caractères, mais en tant que block mémoire. En gros, le '\0' est, lui aussi, envoyé. Essaye:

    Code:
    EmmissionCom(init, sizeof init - 1);
    Je connais pas bien la fonction sizeof.
    Je veux bien essayer

  20. #20
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odSen
    Je connais pas bien la fonction sizeof.
    Ouch ! C'est un opérateur basique du langage C. Il retourne la taille d'un objet en bytes.
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. [Débutant] Problème réception trame Port Série
    Par cedricdu91 dans le forum VB.NET
    Réponses: 3
    Dernier message: 13/08/2013, 20h55
  2. Communication par Port Série Non fonctionnel
    Par Jazys dans le forum Java ME
    Réponses: 0
    Dernier message: 12/03/2012, 15h26
  3. Communication Kit Velleman K8063 par port série et TComport
    Par carotreger dans le forum Composants VCL
    Réponses: 16
    Dernier message: 07/11/2005, 21h11
  4. Interfacer un logiciel et un système hardware par port série
    Par jean-claude74 dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 13/08/2005, 16h52
  5. [Débutant] Réception sur port série
    Par Tophe59 dans le forum Langage
    Réponses: 43
    Dernier message: 28/06/2004, 11h04

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