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 :

Comment attendre une trame sur le port série ?


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut Comment attendre une trame sur le port série ?
    Bonjour à tous,

    je suis en train de créer un programme qui lit sur la com série.
    Sur cette com est branché un module qui reçoit des trammes, que je dois pouvoir lire avec l'application que je réalise pour ensuite enregistrer ces informations dans un fichier.

    Pour le moment, j'ai réussi à ouvrir et à configurer la com.
    Mon problème est que maintenant je voudrai voir les infos qui arrive avec la fonction ReadFile, mais lorsque je lance le programme, il s'ouvre puis se referme.
    J'aimerai que ce programme tourne à l'infini car les infos arrivent à peu près toutes les minutes.

    Merci pour vos réponses, à bientôt !

  2. #2
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Il faut que tu lances un thread en parallèle de ton programme principal et qui génère un évènement (par exemple) lorsque il lit quelque chose sur la liaison série.
    Il existe sûrement d'autres possibilités, mais je trouve ça assez simple à mettre en oeuvre.
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    OK d'accord, car mon programme donne cela pour l'instant :

    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
     
    #include <vcl.h>
     
    #include <stdio.h>
    #include <windows.h>
    #include <windef.h>
    #include <stdlib.h>
    #include <iostream.h>
    #include <limits.h>
     
    #pragma hdrstop
     
    //---------------------------------------------------------------------------
     
    #pragma argsused
    int main(int argc, char* argv[])
    {
     
    	HANDLE handle;
    	DCB dcb;
     
    	BOOL PortReady;
    	BOOL fSuccess;
     
    	DWORD nblu=0,nbecrit; 
     
    /*--------------------------------------------------------------------*/
    /* Ouverture du port de communication pour la base de collecte */
    /*--------------------------------------------------------------------*/
     
     
    	handle = CreateFile(
    			"COM5",
    			GENERIC_READ | GENERIC_WRITE , // acces pour lire et ecrire sur le port
    			0,
    			NULL,
    			OPEN_EXISTING,
    			0,
    			NULL
    			) ;
     
    	if(handle == INVALID_HANDLE_VALUE)
    	{
    		printf("Impossible d'ouvrir le port (erreur %d)\n", GetLastError());
    	return 0;
     
    	}
    		printf("Ouverture du port reussie");
     
     
    	return 0;
     
    	PortReady=SetupComm(handle,5000,5000);
     
    	fSuccess = GetCommState(handle, &dcb);
     
    	if (!fSuccess)
    	{
    		printf("probleme 1");
     
    	getchar();
    	}
     
    	dcb.BaudRate = 38400 ; /* vitesse */
    	dcb.ByteSize =8 ; /* nombre de bits */
    	dcb.Parity=NOPARITY;
    	dcb.StopBits = ONESTOPBIT;
    	dcb.fNull=FALSE;
    	dcb.fRtsControl=RTS_CONTROL_ENABLE;
    	dcb.fInX=FALSE;
    	dcb.fOutX=FALSE;
    	dcb.fDtrControl=DTR_CONTROL_ENABLE;
     
    /*-----------------------------------------------------------*/
    /* on applique les changements au port COM1 */
    /*-----------------------------------------------------------*/
     
    	PortReady=SetCommState(handle,&dcb);
     
    	if(!SetCommState(handle,&dcb))
    	{
    		printf("probleme 1");
     
    		getchar();
     
    	}
     
     
     
        char buf;
     
    	ReadFile(handle,&buf,sizeof(buf),&nblu,NULL);
     
    	printf ("octets lus : %h ", buf );
     
     
    	CloseHandle(handle);
    Est-ce utile de lancer un thread ?

    Punaise je ne comprend pas le fonctionnement des threads !!!

    Comment on les utilise ???

    Comment dois-je faire dans mon application ?

  4. #4
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Pour moi, il est utile de lancer un thread sinon ton application bloquera sur chaque lecture/écriture que tu lui demanderas.
    Un thread est un bout de code qui va s'exécuter en parallèle* du code principal. Tu le lances avec la fonction CreateThread (voir MSDN).
    En bref, en faisant une recherche "thread" ou "createthread" dans la partie C++ du forum, tu trouveras sûrement ton bonheur dans des exemples d'autres participants du forum!

    *pas vraiment exact, mais ce n'est pas le sujet ici
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Je partage l'avis de SpoutSpout. Lorsqu'une application doit se mettre à l'écoute d'un flux de données, il est toujours bon de le découper en au moins 2 threads: un premier pour gérer la réception des données, un second pour gérer leur traitement et l'IHM (le 'et' tendrait à dire 3 thread si le traitement des données est gourmand).
    Enfin, dans ton bout de code, tu ne fais pas de boucle sur la réception. Dès le premier octet reçu, tu sort de ReadFile et quitte la fonction.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    J'ai compris, mais l'application que je fais ne dois pas avoir d'IHM.
    C'est une application de type console qui doit tourner en permanence !

  7. #7
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Donc deux threads: gestion de la liaison et traitement des données.
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Points : 100
    Points
    100
    Par défaut
    C'est d'accord, merci !

    Pouvez-vous me donner un lien sur la FAQ par exemple pour savoir comment je dois m'y prendre dans l'application ?

  9. #9
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    J en trouve pas d'entrée pour les thread dans la FAQ, mais ça ne m'étonne pas, ça varie beaucoup en fonction des types d'application. Le mieux pour toi, c'est de regarder aux adresses MSDN ici et . Si tu as des questions techniques au cours de ton implémentation, n'hésite pas
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Points : 148
    Points
    148
    Par défaut
    Je ne suis pas expert sur le sujet, mais je me suis recemment pose la question de la necessite du threading sur liaison RS232. Au terme de ma longue reflexion, j'ai conclu que le threading etait inutile.

    L'application de c_boireau met manifestement en jeu une liaison RS232 synchrone a 38400 bauds. RS232 envoie, si je ne m'abuse, un octet par symbole. Donc, son application envoie/recoit 38400 o/s.

    Il faudrait vraiment que le traitement soit tres gourmant pour que le processeur ne suive pas et qu'on ait besoin de bufferiser les donnees.

  11. #11
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Tout dépend si tu sais exactement quand tu recevras des données sur ta liaison ou non... De plus tu ne peux pas prévoir à 100% le comportement de l'équipement d'en face à la seconde près, donc tu peux bloquer sur une lecture. Le thread a au moins l'avantage de ne pas bloquer le reste de l'application.
    Après c'est un choix, et cela dépend de la manière dont tu fais ta conception.
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Points : 148
    Points
    148
    Par défaut
    Je ne comprends pas.

    C'est sense etre synchrone ! Donc, tu connais forcement quand les donnees vont arriver sur ta liaison, non ?

  13. #13
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Prenons un exemple:
    • T0 : PC1 envoie un message à PC2 par une liaison série
    • T1 : PC1 attends une réponse et PC2 effectue un traitement
      ...
    • TN : PC2 répond et PC1 reçoit la réponse de PC2
    Que s'est-il passé du côté de PC1 entre l'envoi et la réception de la réponse de PC2?
    Si ton ReadFile intervient durant cette période, il va sortir tout de suite en disant qu'il n'a rien lu. S'il intervient après, c'est bon, mais comment quantifier le temps nécessaire et ne pas bloquer ton programme?

    NB pour c_boireau: Si tu attends d'être sûr d'avoir reçu quelque chose pour lire (la moins pire des solutions cra-cra ), prévois au moins un tableau de char assez grand pour contenir ta trame. Tu auras alors:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Envoi du message
    ....
     
    // Attente
    Sleep(XXX);
     
    // Lecture
    char myBuffer[4096];
    ReadFile(handle,&myBuffer,sizeof(myBuffer),&nblu,NULL);
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Si le programme se contente de lire des bytes au fur et à mesure qu'ils arrivent et pour les écrire dans un fichier.

    Les lectures seront bien plus lentes que les écritures: pas la peine de s'embêter avec des threads.

    1. - attente bytes présent ou timeout,
    2. - lecture des bytes reçus
    3. - écriture des bytes lus


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par wiztricks
    1. - attente bytes présent ou timeout,
    2. - lecture des bytes reçus
    3. - écriture des bytes lus
    Mais comment vas-tu matérialiser le timeout et l'attente dont tu parles (1) si ce n'est en attendant une durée choisie totalement arbitrairement (Sleep(), boucle toute moche,...)?? Un envoi/réception ponctuel peut éventuellement se passer de thread, mais au risque de ne pas faire la lecture au bon moment.
    Lorsqu'il s'agit de l'écoute d'un flux, tu ne peux pas (à mon sens) faire autrement qu'en faire un dédié à cette tâche.
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Points : 148
    Points
    148
    Par défaut
    Citation Envoyé par spoutspout Voir le message
    Lorsqu'il s'agit de l'écoute d'un flux, tu ne peux pas (à mon sens) faire autrement qu'en faire un dédié à cette tâche.
    Pas sur. Par exemple, je developpe un protocole sur RS232. Je sais dans quel ordre et en quel nombre mes octets arrivent sur la liaison. Donc, a priori, je n'aurais pas besoin de thread. Pourtant, je recupere bien un flux d'octet de taille variable (mais connue, grace a une entete).

    PS : Je n'en suis qu'au debut. Il est donc possible que le threading s'avere tout de meme necessaire par la suite.

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par spoutspout Voir le message
    Mais comment vas-tu matérialiser le timeout et l'attente dont tu parles (1) si ce n'est en attendant une durée choisie totalement arbitrairement (Sleep(), boucle toute moche,...)??

    A partir du moment ou il n'y a rien d'autre à faire qu'attendre que les bytes arrivent.... Une fonction équivalente à select suffit.
    Note: On peut faire des trucs plus compliqués, mais rien n'indique pour l'instant que cela le mérite: restons "simples".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Un envoi/réception ponctuel peut éventuellement se passer de thread, mais au risque de ne pas faire la lecture au bon moment. ;)
    
    Lorsqu'il s'agit de l'écoute d'un flux, tu ne peux pas (à mon sens) faire autrement qu'en faire un dédié à cette tâche.[/QUOTE]
    A voir selon l'OS et le paramètrage du port, mais le driver bufferise un minimum (et en général suffisament) pour stocker quelques caractères.

    Note: De toutes façon tel qu'est décrit le programme, il n'y a aucun moyen de savoir si on perd ou pas des caractères. Pour cela il faudra peut être les regrouper en trames avec un minimum d'en-tête.

    Dans ce cas, le contexte de 'lecture de la trame en cours' pourrait mériter un threads (quoique).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Tymk Voir le message
    Pas sur. Par exemple, je developpe un protocole sur RS232. Je sais dans quel ordre et en quel nombre mes octets arrivent sur la liaison. Donc, a priori, je n'aurais pas besoin de thread. Pourtant, je recupere bien un flux d'octet de taille variable (mais connue, grace a une entete).

    PS : Je n'en suis qu'au debut. Il est donc possible que le threading s'avere tout de meme necessaire par la suite.
    Appelons "trame", l'en-tête et les octets de donnés qu'elle décrit.
    Lorsqu'il y a des caractères à lire, nous avons besoin d'un contexte qui dise ou mettre ces caractères lus et si la trame est complète ou pas.

    L'autre question est "comment détecte-t-on qu'il y a de nouveaux caractères à lire?". On peut créer un thread qui attendra de façon active l'arrivée de caractères... (mais ce n'est pas la seule solution).

    L'erreur à ne pas faire (dans ce cas) est de rendre le contexte si dépendant de la threads qu'on ne puisse multiplier le nombre de flux sans en faire autant côté threads (1 flux = 1 threads).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  19. #19
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    j'ai écris un post sur le sujet de la réception série dans la faq visual C++
    la réception est traitée dans un thread a part.
    la seule différence c'est que j'envoie une notification par message a l'ihm (MFC) quand un évènement arrive .
    dans ton cas il suffit de procéder directement au traitement ...
    je pense que la classe est facilement modifiable pour gérer ton cas en mode console.

  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Points : 148
    Points
    148
    Par défaut
    Farscape, pourquoi dans ton document tu dis que la liaison serie synchrone est ingerable ?

    Chez moi, ca a l'air de marcher assez bien.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/06/2008, 16h12
  2. Comment envoyer une adresse par le port série
    Par christophe_s46 dans le forum WinDev
    Réponses: 3
    Dernier message: 10/09/2007, 01h52
  3. Comment lire une pin sur le port série du pc
    Par KENPACHI dans le forum LabVIEW
    Réponses: 1
    Dernier message: 25/05/2007, 12h56
  4. Réponses: 3
    Dernier message: 18/07/2006, 13h37
  5. [USB]envoyer une trame sur le port USB
    Par ced38100 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 03/11/2005, 12h54

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