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 :

Envoi d'une trame via liaison série


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 117
    Par défaut Envoi d'une trame via liaison série
    Bonjour,

    J'ai posté une seconde fois mon topic car je ne sais pas trop dans quel salon le mettre. Merci aux modérateurs de faire le nécessaire ...


    je souhaiterai qu'un maitre (ici mon PC) puisse envoyer une trame vers un esclave (un module relié par RS485).

    J'ai trouvé une documentation sur le net m'indiquant le format de la trame. Pour une question (interrogation d'un maitre à un esclave) :



    Exemple d’échange entre un maître et un esclave

    Trame émise par le maître : 04 03 00 02 0001 25 CA
    - Adresse esclave : 04
    - Code fonction 03 = lecture registre
    - N° du registre de début de lecture : MSB : 00 et LSB : 02
    - Nombre de registre de lecture : MSB : 00 et LSB : 01
    - CRC : 25 CA


    Vous trouverez le PDF de ce document en cliquant ici

    J'ai commencé un programme qui configure et initialise la liaison 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
    /**************************************************************************\
    *                                                                                                                                                  *
    *                             Programme test de la RS485                           *
    *                                                                                                                                                  *
    *                                                                                                                                                  *
    *                                                                                                                                                  *
    *                                   by Fabien L.                                                   *
    *                                                                                                                                                  *
    \**************************************************************************/
     
     
    #include <windows.h>
    #include <stdio.h>
    #include <iostream>
     
    using namespace std;
    int main(void)
    {
     
    // On crée un handle que l'on initialise à NULL.
    HANDLE SPort=NULL;
    DWORD Event;
    COMMCONFIG tR;
     
     
     
        // Sport est un handle ( identifiant )
    	// Pour mieux comprendre les paramètre passés
    	// consultez la fonction CreateFile();
    	SPort = CreateFile("COM4",
    					   GENERIC_READ | GENERIC_WRITE,
    					   0,
    					   NULL,
    					   OPEN_EXISTING,
    					   0,
    					   NULL);
    	// Le handle sera le lien entre notre apllication
    	// et le port série.
    	// Ici ce sera le port indiquédans le tableau COM déclaré au début qui sera ouvert.
     
    	if ( SPort == INVALID_HANDLE_VALUE )
    	{
    		cout << "Le port selectionne ne peut etre ouvert ou l'est deja" ;
    		cout<<endl;
    		system( "pause" );
    	}
     
    	// Vérification de parité désactivée
    	tR.dcb.fParity=NOPARITY;
    	// La taille du mot donnée est de
    	tR.dcb.ByteSize=8;
    	// Un bit de stop
    	tR.dcb.StopBits=ONESTOPBIT;
    	// désactive les Xon-Xoff
    	tR.dcb.fInX=FALSE;
    	tR.dcb.fOutX=FALSE;
    	// Configuration du BaudRate
    	tR.dcb.BaudRate= CBR_4800;
     
    	// Enregistrer les modifications apportées
    	// au paramètres Xon-Xoff
    	SetCommConfig(SPort, &tR, sizeof(tR));
    	// On remplit la strucuture COMMTIMEOUTS
    	COMMTIMEOUTS tMyTimeOuts =  {
    	100,
        0,
        0,
        1000,
        1000
        };
     	 //Enregistre les modifications concernant le CommTimeouts
    	if (!SetCommTimeouts(SPort, &tMyTimeOuts) )
    	{
    		MessageBox(0,"Erreur de configuration","Erreur",MB_OKCANCEL);
    		cout<<endl;
    		system( "pause" );
    	}
     
    /********************** STRUCTURE RECHERCHEE *************************/
     
     
        system( "pause" );
    }
    Compilé avec Dev-C++.

    Je cherche à établir une trame avec comme indiqué auparavant, le numéro d'esclave, le code fonction (écriture), information demandée, et le mot de contrôle (ici le CRC). Donc si quelqu'un a une idée de la syntaxe à utiliser pour construire cette trame à envoyer sur cette RS485, je suis preneur.

    MERCI D'AVANCE POUR VOTRE AIDE

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Fabien50 Voir le message
    je souhaiterai qu'un maitre (ici mon PC) puisse envoyer une trame vers un esclave (un module relié par RS485).

    J'ai trouvé une documentation sur le net m'indiquant le format de la trame. Pour une question (interrogation d'un maitre à un esclave) :



    Exemple d’échange entre un maître et un esclave

    Trame émise par le maître : 04 03 00 02 0001 25 CA
    - Adresse esclave : 04
    - Code fonction 03 = lecture registre
    - N° du registre de début de lecture : MSB : 00 et LSB : 02
    - Nombre de registre de lecture : MSB : 00 et LSB : 01
    - CRC : 25 CA


    Je cherche à établir une trame avec comme indiqué auparavant, le numéro d'esclave, le code fonction (écriture), information demandée, et le mot de contrôle (ici le CRC). Donc si quelqu'un a une idée de la syntaxe à utiliser pour construire cette trame à envoyer sur cette RS485, je suis preneur.
    Ton code en C...
    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
     
    /*
    **	Programme test de la RS485
    **
    **	by Fabien L.
    */
     
    #include <windows.h>
    #include <stdio.h>
     
    int main (void)
    {
    /* On crée un handle que l'on initialise à NULL. */
       HANDLE SPort = NULL;
       COMMCONFIG tR;
     
    /* Sport est un handle ( identifiant ) */
     
    /* Pour mieux comprendre les paramètre passés */
     
    /* consultez la fonction CreateFile(); */
     
       SPort = CreateFile ("COM4",
                           GENERIC_READ | GENERIC_WRITE,
                           0, NULL, OPEN_EXISTING, 0, NULL);
    /* Le handle sera le lien entre notre apllication */
     
    /* et le port série. */
     
    /* Ici ce sera le port indiquédans le tableau COM déclaré au début qui sera ouvert. */
     
       if (SPort == INVALID_HANDLE_VALUE)
       {
          puts ("Le port selectionne ne peut etre ouvert ou l'est deja");
          system ("pause");
       }
     
    /* Vérification de parité désactivée */
     
       tR.dcb.fParity = NOPARITY;
    /* La taille du mot donnée est de */
     
       tR.dcb.ByteSize = 8;
    /* Un bit de stop */
     
       tR.dcb.StopBits = ONESTOPBIT;
    /* désactive les Xon-Xoff */
     
       tR.dcb.fInX = FALSE;
       tR.dcb.fOutX = FALSE;
    /* Configuration du BaudRate */
     
       tR.dcb.BaudRate = CBR_4800;
     
    /* Enregistrer les modifications apportées */
     
    /* au paramètres Xon-Xoff */
     
       SetCommConfig (SPort, &tR, sizeof (tR));
    /* On remplit la strucuture COMMTIMEOUTS */
       {
          COMMTIMEOUTS tMyTimeOuts = {
             100,
             0,
             0,
             1000,
             1000
          };
    /* Enregistre les modifications concernant le CommTimeouts */
     
          if (!SetCommTimeouts (SPort, &tMyTimeOuts))
          {
             MessageBox (0, "Erreur de configuration", "Erreur", MB_OKCANCEL);
          }
       }
     
    /* STRUCTURE RECHERCHEE */
     
       return 0;
    }
    Ce que tu cherches, c'est à émettre une trame formatée selon une spécification qui dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    [0] Numero d'esclave
    [1] Code fonction
    [2] N octets de données...
    ...
    [2+N]    MSB checksum
    [2+N+1] LSB checksum
    Il y a un problème dans cette définition. L'information "longueur des données" (N) n'est ni transmise, ni marquée.

    Il se peut qu'elle soit fixe, ou qu'elle dépende du code fonction. Il faut le préciser...

    Une fois ces données précisées, il suffit de les placer dans le bon ordre dans un tableau de unsigned char et d'émettre ce tableau caractères par caractères.

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 117
    Par défaut
    Salut Emmanuel Delahaye,

    merci pour ta réponse, je vais tester le tableau à envoyer, et je te dis le résultat.

    Il y a un problème dans cette définition. L'information "longueur des données" (N) n'est ni transmise, ni marquée.

    Il se peut qu'elle soit fixe, ou qu'elle dépende du code fonction. Il faut le préciser...
    Je n'en sais pas plus que le PDF en fait...

  4. #4
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 117
    Par défaut
    Citation Envoyé par Fabien50 Voir le message
    J'ai trouvé une documentation sur le net m'indiquant le format de la trame. Pour une question (interrogation d'un maitre à un esclave) :



    Exemple d’échange entre un maître et un esclave

    Trame émise par le maître : 04 03 00 02 0001 25 CA
    - Adresse esclave : 04
    - Code fonction 03 = lecture registre
    - N° du registre de début de lecture : MSB : 00 et LSB : 02
    - Nombre de registre de lecture : MSB : 00 et LSB : 01
    - CRC : 25 CA
    Je voudrai avoir d'avantage d'informations concernant chacun de ses paramètres notamment le code fonction et les deux suivants, si possible.

    Le code fonction, il me semble que c'est par exemple, si l'on demande de faire une écriture ou une lecture ?!

    Merci pour votre aide.

    Une fois ces données précisées, il suffit de les placer dans le bon ordre dans un tableau de unsigned char et d'émettre ce tableau caractères par caractères.
    As tu un exemple en C à me montrer s'il te plait histoire de comparer à ce que je fais et voir mes erreurs de syntaxe possibles, merci

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Fabien50 Voir le message
    As tu un exemple en C à me montrer s'il te plait histoire de comparer à ce que je fais et voir mes erreurs de syntaxe possibles, merci
    Si on doit émettre une trame contenant 12 34 56 (en hexa) :

    1. on crée un tableau de 3 unsigned char

    2. On met dedans ce qui doit être émis :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      tab[0] = 0x12;
      tab[1] = 0x34;
      tab[2] = 0x56;
    3. et on appelle la fonction d'émission de trame :


    C'est difficile ?

  6. #6
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 117
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message

    C'est difficile ?
    Difficile non, mais je m'informe et je me pose de nombreuses questions auxquelles je voudrais des réponses. D'ailleurs tu m'as encore dirigé là

    Voici le petit programme qui affecte manuellement ou automatiquement les paramètres à envoyer sur la RS485. Ceux affectés en interne sont bien sur prit au hasard pour le moment (j'arrangerai par la suite). Manque juste la partie de l'envoi :

    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
    #include <iostream>
     
    using namespace std;
    int main(void)
    {
        long a,b,c,d,e,A,B,C,D,E;
        unsigned long tab[50],TAB[50];
        int i,choix;
     
        cout<<"### TRAME A EMETTRE ###"<<endl<<endl<<endl;
        cout<<"Choix du mode de transmission : "<<endl<<endl;
        cout<<"1) Manuel "<<endl;
        cout<<"2) Trame donnee "<<endl;
        cout<<"3) Quitter "<<endl;
        cout<<"Choix : 1 / 2 / 3 ? "<<endl;
        cout<<"Votre choix est : ";
        cin>>choix;
     
        while (1)
        {
            if(choix==1)
            {
                cout<<endl<<endl<<"-> Parametrage manuel de la trame... "<<endl;
                cout<<endl<<"Adresse de l'esclave : ";
                cin>>a;
                tab[0]=a;
                cout<<endl<<"Code fonction : ";
                cin>>b;
                tab[1]=b;
                cout<<endl<<"Numero du registre du debut de lecture : ";
                cin>>c;
                tab[2]=c;
                cout<<endl<<"Nombre du registre du debut de lecture : ";
                cin>>d;
                tab[3]=d;
                cout<<endl<<"CRC : ";
                cin>>e;
                tab[4]=e;
                cout<<endl<<endl<<"Trame a envoyer : "<<endl<<endl;
                for(i=0;i<=4;i++)
                {
                    cout<<i<<"     ";
                    cout<<tab[i]<<endl;
                }
                cout<<endl<<"ou"<<endl<<endl;
                for(i=0;i<=4;i++)
                {
                    cout<<tab[i]<<" ";
                }
                cout<<endl<<endl<<endl;
                cout<<"Nouvelle trame ..."<<endl<<endl;
                cout<<"Choix du mode de transmission : "<<endl<<endl;
                cout<<"1) Manuel "<<endl;
                cout<<"2) Trame donnee "<<endl;
                cout<<"3) Quitter "<<endl;
                cout<<"Choix : 1 / 2 / 3 ? "<<endl;
                cout<<"Votre choix est : ";
                cin>>choix;
            }
            if(choix==2)
            {
                cout<<endl<<endl<<"-> Parametrage donnee de la trame... "<<endl;
                A=04;
                TAB[0]=A;
                B=03;
                TAB[1]=B;
                C=0002;
                TAB[2]=C;
                D=0001;
                TAB[3]=D;
                E=2515;
                TAB[4]=E;
                cout<<endl<<endl<<"Trame a envoyer : "<<endl<<endl;
                for(i=0;i<=4;i++)
                {
                    cout<<i<<"     ";
                    cout<<TAB[i]<<endl;
                }
                cout<<endl<<"ou"<<endl<<endl;
                for(i=0;i<=4;i++)
                {
                    cout<<TAB[i]<<" ";
                }
                cout<<endl<<endl<<endl;
                cout<<"Nouvelle trame ?"<<endl;
                cout<<"Choix du mode de transmission : "<<endl<<endl;
                cout<<"1) Manuel "<<endl;
                cout<<"2) Trame donnee "<<endl;
                cout<<"3) Quitter "<<endl;
                cout<<"Choix : 1 / 2 / 3 ? "<<endl;
                cout<<"Votre choix est : ";
                cin>>choix;
            }
            if(choix==3)
            {
                cout<<endl<<endl<<"Fermer l'application en cliquant sur une touche...";
                cout<<endl<<endl;
                return 0;
            }
     
            if(choix>3)
            {
                cout<<"erreur"<<endl;
                cout<<"redemarrer l'application"<<endl;
                return 0;
            }
        }
        return 0;
    }
    Cependant, c'est pour envoyer sur une liaison série RS485, donc le send_frame est elle bien la bonne commande ?
    En utilisant le WriteFile/ReadFile, avec le buffer ?

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Fabien50 Voir le message
    Cependant, c'est pour envoyer sur une liaison série RS485, donc le send_frame est elle bien la bonne commande ?
    En utilisant le WriteFile/ReadFile, avec le buffer ?
    send_frame(), c'est juste un nom de fonction qui exprime mon intention. Tu l'implémente avecles ressources dont tu disposes... send(), write(), WriteFile(), peu importe. C'est le même principe. je ne connais pas ton matériel ni tes drivers...

    P.S. Le code que tu as posté n'est pas du C et il est 10.000 fois trop compliqué pour que je le regarde...

  8. #8
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 117
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    send_frame(), c'est juste un nom de fonction qui exprime mon intention. Tu l'implémente avecles ressources dont tu disposes... send(), write(), WriteFile(), peu importe. C'est le même principe. je ne connais pas ton matériel ni tes drivers...
    J'ai une carte ISA équipée de deux ports RS485 en fait
    Donc je fais comme si je parlais avec le port COM classique de la carte mère (RS232), or là il y a deux ports COM supplémentaires. Le reste, c'est le driver qui s'en charge. Moi je fais comme si il n'y avais pas cette nouvelle carte.

    Citation Envoyé par Emmanuel Delahaye Voir le message
    P.S. Le code que tu as posté n'est pas du C et il est 10.000 fois trop compliqué pour que je le regarde...
    Comment ça ? C'est pourtant du simple C mon code là
    A moins que tu ne veuilles quelques commentaires

Discussions similaires

  1. Envois et reception d'une trame via Port Serie (com)
    Par samirraoui dans le forum VB.NET
    Réponses: 3
    Dernier message: 11/05/2015, 13h15
  2. Envoyer une trame via port série
    Par Lacmé dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 21/04/2015, 08h52
  3. envoi d'une trame via rs232 avec SOH CR LF
    Par tibjedi dans le forum C
    Réponses: 4
    Dernier message: 24/04/2013, 14h06
  4. Problème avec l'envoi d'une trame TCP
    Par fredoBreton dans le forum API, COM et SDKs
    Réponses: 14
    Dernier message: 17/11/2005, 20h19

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