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 :

Com Port Série : 600 millisec pour lire 1 byte !


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 48
    Points : 31
    Points
    31
    Par défaut Com Port Série : 600 millisec pour lire 1 byte !
    Bonjour et bonne année,

    J'ai retourné mon problème dans tous les sens, j'ai vraiment besoin de vos avis éclairés ...

    Je réalise un programme C (WinXP SP2, BCC 5.02) pour lire des données émises par un appareil bluetooth (qui communique avec le port 40 de mon pc).

    Le programme crée un handle sur le port 40 (fonctions createfile, ...), paramètre les propriétés de l'appareil (baud rate = 9600, no parity, 1 stop bit), la taille du buffer, les timeouts.
    ! Je n'ai rien paramétré de spécial pour 'No Flow Control' par contre.

    La connexion est OK, les données sont lues (la doc technique indique : 3 paquets de 125 Bytes de données par sec).

    Le programme lit les données Byte par Byte, en mode synchrone (readfile).
    La plupart des durées de lecture sont < 1ms. MAIS

    tous les 250 bytes environ, la lecture d'un byte va prendre 600 ms (ou encore 15 ms).

    J'ai fixé les timeouts comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ReadIntervalTimeout=10;
    ReadTotalTimeoutMultiplier=10;
    ReadTotalTimeoutConstant=5000;
    Mais ça n'a aucun effet (les 2 premiers en tout cas), est - ce le fait que c'est une connexion bluetooth ?
    Merci par avance. je suis preneur de toutes les idées !
    Les miennes sont :
    1) Readfile n'a rien à lire pendant 600 ms et attend. Mais pourquoi les timeout n'ont aucun effet ?
    2) Les données arrivent normalement en continu mais la fonction Readfile 'buggue pendant 600 ms' pour la lecture d'un byte classique
    3) Readfile met 600 ms pour lire un gros truc. Est ce possible que des stop bits soient manquants (erreur de l'appareil) pendant 600 ms ?

    Pour info, j'utilise la Instrument Control Toolbox de matlab et j'ai exactement le même comportement.

    Patrick

  2. #2
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Je n'ai pas tout saisi, mais tu dis toi même que ton appareil bluetooth émet 3 paquets de 125 caractères toutes les secondes.
    Citation Envoyé par LePapat26 Voir le message
    La connexion est OK, les données sont lues (la doc technique indique : 3 paquets de 125 Bytes de données par sec).
    Si on dit qu'un caractère est émis toute les millisecondes (9600 bauds), alors les 3 paquets sont émis en 375ms.
    Ce qui veut dire qu'il y a un trou de 625ms toutes les secondes.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 48
    Points : 31
    Points
    31
    Par défaut oui en effet. Merci Mais les timeouts?
    Citation Envoyé par crocodilex Voir le message
    Je n'ai pas tout saisi, mais tu dis toi même que ton appareil bluetooth émet 3 paquets de 125 caractères toutes les secondes.

    Si on dit qu'un caractère est émis toute les millisecondes (9600 bauds), alors les 3 paquets sont émis en 375ms.
    Ce qui veut dire qu'il y a un trou de 625ms toutes les secondes.
    En effet Crocodilex, en fait l'appareil envoie 2 paquets puis stand by de 625 ms puis 2 paquets puis 625 ms. ce qui fait bien 625 + 250 = 875 et il me reste bien 125 ms pour compléter ma seconde et récupérer mon dernier paquet. Le fait que 3 paquets n'arrivaient pas en même temps me troublaient.

    Mais par contre, pourquoi les timeouts n'ont aucun effet dans ce cas ? Quand je mets ReadTotalTimeoutConstant=600, le programme ne sort pas !

    Merci encore, j'avais trop le nez dans mon projet.

    Patrick

  4. #4
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par LePapat26 Voir le message
    Mais par contre, pourquoi les timeouts n'ont aucun effet dans ce cas ? Quand je mets ReadTotalTimeoutConstant=600, le programme ne sort pas !
    Sans le code qui pose problème, nous ne pouvons pas dire grand chose....

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 48
    Points : 31
    Points
    31
    Par défaut Voici le code
    Citation Envoyé par crocodilex Voir le message
    Sans le code qui pose problème, nous ne pouvons pas dire grand chose....
    je vous joins la partie qui concerne la lecture des données. Pour l'instant je lis les données byte par byte et récupère l'heure quand le byte = 1.

    Ainsi que la fonction openPort que j'ai définie dans Byte.c et qui permet d'ouvrir le port et de définir les timeouts..

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
    // Specific librairies
    #include "Byte.h"
     
    int main()
    {
    clock_t start, end;
    // Define port object and event
    HANDLE h;
    DWORD dwEventMask;
    int coolH;
    // Open Serial Port
    coolH = openPort(&h);
    if (coolH != 0) return 26;
     
    // Set up a Read event
    SetCommMask(h,EV_RXCHAR); // kind of event which will be checked by WaitCommEvent()
     
    if (WaitCommEvent(h, &dwEventMask, NULL))
    {
    	 unsigned char initszBuf[1];
        DWORD dwIncommingReadSize; // number of bytes read
        int i,num,b1;
        time_t t;
        printf("Receiving data\n");
        i = 0;
        do
        {
             start = clock();
    	      if(ReadFile(h, &initszBuf, sizeof(unsigned char), &dwIncommingReadSize, 0) !=0)
       	   {
             		num = (int)initszBuf[0];
             	   if (num == 1)
                	{
                   	time(&t);
    	            	b1 = num;
                   	i = 1;
                	}
             }
             end = clock();
             printf("The time was: %f\n", (end - start) / CLK_TCK);
        } while(dwIncommingReadSize > 0);
    }
     
    // close port
    CloseHandle(h);
    return 0;
    }
    et la fonction openPort()
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
     
    int openPort(HANDLE *h)
    {
    	DCB dcb = {0};
    	COMMTIMEOUTS timeouts={0};
    	BOOL portReady,fSuccess;
    	int retValue;
       retValue = 0;
    	*h = CreateFile(
    				"\\\\.\\COM40",
                GENERIC_READ,
                0,    // must be opened with exclusive-access
                NULL, // default security attributes
                OPEN_EXISTING, // must use OPEN_EXISTING
                0,    // not overlapped I/O
                NULL  // hTemplate must be NULL for comm devices
                );
     
    	if(*h == INVALID_HANDLE_VALUE)
    	{  // Handle the error.
      		printf ("CreateFile failed with error %d.\n", GetLastError());
      		retValue = 1;
    	}
     
    	// define buffer size for sending and receiving [number of Bytes]
    	portReady = SetupComm(*h,1024,1024);
    	if (!portReady)
    	{  // Handle the error.
      		printf ("SetupComm failed with error %d.\n", GetLastError());
      		retValue = 2;
    	}
     
    	// define state of commport
    	fSuccess = GetCommState(*h, &dcb);
    	if (!fSuccess)
    	{  // Handle the error.
      		printf ("GetCommState failed with error %d.\n", GetLastError());
      		retValue = 3;
    	}
     
    	// Fill in DCB: 9,600 bps, 8 data bits, no parity, and 1 stop bit.
       dcb.BaudRate = CBR_9600;     // set the baud rate
       dcb.ByteSize = 8;             // data size
       dcb.Parity = NOPARITY;        // no parity bit
       dcb.StopBits = ONESTOPBIT;    // one stop bit
     
    	fSuccess = SetCommState(*h, &dcb);
    	if (!fSuccess)
    	{   // Handle the error.
       	printf ("SetCommState failed with error %d.\n", GetLastError());
       	retValue = 4;
    	}
     
    	// define Timeouts [milliseconds]
    	timeouts.ReadIntervalTimeout=10;
    	timeouts.ReadTotalTimeoutMultiplier=10;
    	timeouts.ReadTotalTimeoutConstant=1000;
    	fSuccess = SetCommTimeouts(*h,&timeouts);
    	if(!fSuccess)
    	{
    		printf ("SetCommTimeouts failed with error %d.\n", GetLastError());
       	retValue = 5;
    	}
     
    	return retValue;
    }


    Merci d'avance.

  6. #6
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    N’ayant jamais développé sous Windows, je ne suis pas certain de ma réponse.
    A priori, il semblerait que ta fonction soit bloquante en attente d’évènement (réception d’un caractère) par l’intermédiaire de la fonction WaitCommEvent().
    Or, le timeout, d’après la doc MSDN, n’est valable que pour les opérations de lecture et d’écriture.
    D’après ton code, la fonction ReadFile() est exécutée uniquement si des caractères sont présents dans le buffer de réception. Donc ton timeout ne sera jamais actif…

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 48
    Points : 31
    Points
    31
    Par défaut Readfile et TimeOut
    Citation Envoyé par crocodilex Voir le message
    N’ayant jamais développé sous Windows, je ne suis pas certain de ma réponse.
    A priori, il semblerait que ta fonction soit bloquante en attente d’évènement (réception d’un caractère) par l’intermédiaire de la fonction WaitCommEvent().
    Or, le timeout, d’après la doc MSDN, n’est valable que pour les opérations de lecture et d’écriture.
    D’après ton code, la fonction ReadFile() est exécutée uniquement si des caractères sont présents dans le buffer de réception. Donc ton timeout ne sera jamais actif…
    Bonjour,

    je vous remercie pour le temps que vous me consacrez ! Mais mes idées ne sont toujours pas claires.

    J’utilise WaitCommEvent() 1 fois pour lancer ‘la suite du programme’ dès que je reçois le premier caractère.
    ReadFile est exécutée tant qu’elle trouve quelque chose à lire dans le buffer ; mais, dans mon idée, si l’attente est supérieure au TimeOut, on devrait quitter la boucle !
    La doc MSDN indique en effet « the time-out parameters for a communications device […] determine the behavior of ReadFile ».

    Comment relier Readfile aux timeout ? Y a t'il des fonctions spécifiques ?

    Patrick

Discussions similaires

  1. API, COM, Port Série
    Par RATIB dans le forum API, COM et SDKs
    Réponses: 0
    Dernier message: 09/08/2012, 17h45
  2. Remplacer Mscomm32.ocx pour lire port com(rs232)
    Par girardeau dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 14/12/2011, 19h10
  3. port série RS232 virtuel pour C++
    Par Estelle.nugues dans le forum C++
    Réponses: 0
    Dernier message: 24/04/2008, 16h33
  4. Réponses: 11
    Dernier message: 29/03/2006, 17h23
  5. Quel langage choisir pour lire sur le port série ?
    Par Nico76 dans le forum Windows
    Réponses: 7
    Dernier message: 28/04/2004, 11h42

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