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++Builder Discussion :

[C++ Builder 6] Timer de précision pour chronomètre


Sujet :

C++Builder

  1. #1
    Membre éclairé
    Avatar de doudoustephane
    Homme Profil pro
    Gérant
    Inscrit en
    Août 2005
    Messages
    1 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 129
    Points : 862
    Points
    862
    Par défaut [C++ Builder 6] Timer de précision pour chronomètre
    Bonjour.

    Je recherche un timer pour me faire un chronomètre qui soit précis au moins jusqu'au 100ièmes de secondes (voire 1000ième si possible), quelle que soit la config du poste sur lequel l'appli final tourne.

    Connaissez-vous un composant qui est cela ?????

    J'en ai besoin d'URGENCE........

    Merci à tous 8) 8) 8)

  2. #2
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Le composant Ttimer de C++ Builder est à la milliseconde, 1000=1 seconde, il est tout à fait possible de faire une chronomètre avec.

    À bientôt
    Gilles

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Points : 1 148
    Points
    1 148
    Par défaut
    Faux (je crois), le timer ne descend pas à la milliseconde.
    Je crois que le seuil minimal est de l'ordre de 50ms, même si le composant autorise une valeur inférieur il ne réagira pas toutes les millisecondes mais toutes les 50ms.

    Pour faire un bon chronomètre : utilise les compteurs de performance de Windows.
    Regarde du côté de GetTickCount ou cherche "compteur de performance" sous google.

  4. #4
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Voici un exemple de chromonètre que j'ai utilisé dans ma class CTracer:

    Le header:
    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
     
    class CTracer  {
     
      public:
        //----- Ctors & dtor -----
        CTracer();
       ~CTracer();
     
        //----- Misc -----
        double Pause();               //!< Pause the current chronometer
     
        //------ Output -----
        //! Display all the current information about all the sections
        friend ostream& operator<<(ostream&,const CTracer&);
     
      protected:
        //----- Protected data -----
        LARGE_INTEGER  start;      //!< The start time of the chronometer
        LARGE_INTEGER  subTotal;   //!< Subtotal time before the first current pause
        bool           HRPCAvail;  //!< Is there an available HRPC
     
        //----- Protected methods -----
        //! Start the chronometer
        void Start();
    };
    et l'implémentation (cpp):
    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
     
    //----------------------------------------------------------------------------
    //! Start the chronometer
    /*! Try to use the High Resolution Time Performance Counter. If it is not
        available, then use the low resolution GetTickCount function as a time
        counter.
     */
    void CTracer::Start() {
     
      HRPCAvail=QueryPerformanceCounter(&start);
      if (!HRPCAvail) {
        start.LowPart = ::GetTickCount();
        start.HighPart = 0;
      }
     
    }
     
    //! Pause the chronometer (allow nested pause: each pause must have its Continue)
    /*! Compute how many time elapsed since the last start/continue command and
        store it in the temporary subTotal variable.
        \return The elapsed time in milliseconds (is zero if already in pause)
     */
    double CTracer::Pause() {
     
      double result=0;
     
      if (pauses==0) {
        // Stop the chronometer and store the temporary total in subTotal
        if (HRPCAvail) {
          // Get the current time and add it the the sub-total
          LARGE_INTEGER stop; QueryPerformanceCounter(&stop);
          subTotal.QuadPart+=(stop.QuadPart - start.QuadPart);
          // Convert it in milliseconds
          LARGE_INTEGER FQPF; QueryPerformanceFrequency(&FQPF);
          result=static_cast<double>(stop.QuadPart - start.QuadPart) * 1000
                /static_cast<double>(FQPF.QuadPart);
        } else {
          // Get the current time and convert it in a large integer
          DWORD stop = ::GetTickCount();
          LARGE_INTEGER total;
          total.HighPart=0; total.LowPart=stop-start.LowPart;
          // Add it to the sub-total
          subTotal.QuadPart+=stop;
          // Convert to result
          result=(double)stop;
        }
      }
     
      // Count the number of pauses
      ++pauses;
     
      // Return the number of milliseconds
      return result;
     
    }
    A épurer et retravailler un peu... Je ne t'ai pas mis le code pour reprendre après une pause ou arrêter définitivement le chronomètre. Si tu en as besoin, n'hésites à pas à me le demander; j'ai donné ce code pour la page des sources mais il n'est pas encore disponible.

  5. #5
    Expert éminent sénior


    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    7 856
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 7 856
    Points : 34 380
    Points
    34 380
    Par défaut
    Citation Envoyé par Patrick Seuret
    j'ai donné ce code pour la page des sources mais il n'est pas encore disponible.
    Ce n'est plus qu'une question de jours !

    Edit -> le voici : http://c.developpez.com/sources/bcb/...rairie#ctracer

  6. #6
    Membre éclairé
    Avatar de doudoustephane
    Homme Profil pro
    Gérant
    Inscrit en
    Août 2005
    Messages
    1 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 129
    Points : 862
    Points
    862
    Par défaut
    Merci à tous. Je vois ça et je vous tiens au courant.

    Par contre, Patrick, oui j'ai besoin de faire des pauses et arrêt définitf.
    peux-tu me donner le code pour cela??

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Il te suffit de rajouter ces deux fonctions (et le destructeur que j'avais oublié):

    Dans le header:
    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
     
         CTracer();
       ~CTracer();
     
        //----- Misc -----
        void Start();                //!< Start the chronometer
        double Pause();               //!< Pause the current chronometer
        void   Continue();            //!< Restart the current chronometer
        void   Stop();                //!< Stop the chronometer
     
        //------ Output -----
        //! Display all the current information about all the sections
        friend ostream& operator<<(ostream&,const CTracer&);
     
      protected:
        //----- Protected data -----
        unsigned int   pauses;     //!< How many pauses are currently called
        LARGE_INTEGER  start;      //!< The start time of the chronometer
        LARGE_INTEGER  subTotal;   //!< Subtotal time before the first current pause
        bool           HRPCAvail;  //!< Is there an available HRPC
    Implémentation:
    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
     
    //----------------------------------------------------------------------------
    //! Continue after a pause (restart only when all pauses are continued)
    void CTracer::Continue() {
     
      // Not in pause
      if (pauses==0) return;
     
      // Restart the chronometer if it was the last pause
      if ((--pauses)==0) Start();
     
    }
     
    //----------------------------------------------------------------------------
    //! Stop the chronometer and store the result in the section
    void CTracer::Stop() {
     
      // Stop the chrono whatever its state
      Pause();
     
      // Add the current subtotal of time to the section entry
      section->totalTime.QuadPart+=subTotal.QuadPart; subTotal.QuadPart=0;
      section->count++;
     
      // Reset subTotal
      subTotal.QuadPart=0;
     
    }
     
    //----------------------------------------------------------------------------
    //! The tracer is deleted. Stop the chronometer and unregister from the tree
    /*! In the RAII pattern design, some very important tasks are done in the
        destructor. Here we stop the chronometer and store the counted time in the
        tree.
     */
    CTracer::~CTracer() {
     
      // Stop the chronometer
      Stop();
     
    }
    Tu n'as pas besoin de la variable "count" car dans mon code, elle sert à compter combien de fois chaque chronomètre a été appelé...

  8. #8
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Citation Envoyé par Neilos
    Faux (je crois), le timer ne descend pas à la milliseconde.
    Je crois que le seuil minimal est de l'ordre de 50ms, même si le composant autorise une valeur inférieur il ne réagira pas toutes les millisecondes mais toutes les 50ms.
    Vous avez raison, j'ai fait un petit test, le TTimer ne réagit pas toutes les millisecondes (ce nombre a sans doute été été choisi pour pouvoir régler à la milliseconde près l'appel du timer à partir du moment où effectivement l'intervalle est assez grand.)

    Je déclare deux variables dans la classe principale.

    N sera le nombre de fois où le timer est appelé (réglé à 1) et DepSec est le numéro de seconde de l'heure courante au départ.

    J'initialise ces variables dans le constructeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
    N=0;
    TDateTime D=Now();
    DepSec= StrToInt(FormatDateTime("s",D));
    }
    On met un timer et deux TEdit sur la forme, le premier affichera le nombre de fois que le timer a été appelé et le second le nombre de secondes depuis le début de l'exécution. L'événement OnTimer affiche ces données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    int NbSec;
    TDateTime D=Now();
     
    NbSec= StrToInt(FormatDateTime("s",D))-DepSec;
    if(NbSec<0) NbSec+=60;
    Edit1->Text=(IntToStr(N++));
    Edit2->Text=(NbSec);
    if(NbSec==10) Timer1->Enabled=false;
    }
    On arête le timer au bout de 10 secondes. On voit qu'il n'est appelé que 600 fois environ soit une fois toute les 16 millisecondes mais il se peut que ça dépende aussi de la performance de la machine.

    À bientôt
    Gilles

  9. #9
    Candidat au Club
    Inscrit en
    Mai 2003
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    la resolution de TOUTS les timer de Windows sont basé sur l'horloge sytème qui controle le signal d'interruption NMI.
    On ne peut pas en sortir directement par soft.
    Sur les sytème equipé du µP à une frequence ~2 Ghz la frequence de ce signal est d'environ 10 ms pour les frequence superieure la fresquence est 1/64 sec.
    En consquence touts les evenements ne peuvent se produire que toutes x*10ms ou x*1/64ms.

    Pour connaitre la resolution actuelle du système d'horloge :

    GetSystemTimeAdjustment(

    &lpTimeAdjustment, // size, in 100-nanosecond units, of a periodic time adjustment
    &lpTimeIncrement, // time, in 100-nanosecond units, between periodic time adjustments
    &lpTimeAdjustmentDisabled // whether periodic time adjustment is disabled or enabled
    );

    lpTimeAdjustment /10 = frequence timer.

    Pour modifier cette resolution , 2 solutions:
    1/ modifier le signal NMI et mettre à jour le sytème ( c'est prevus en mode Maître).
    2/ Autre solution plus abordable generer un signal que l'on applique sur le port serie et se synchroniser dessus.

    Pour plus d'info voir :
    http://www.developpez.net/forums/viewtopic.php?t=399929

  10. #10
    Membre éclairé
    Avatar de doudoustephane
    Homme Profil pro
    Gérant
    Inscrit en
    Août 2005
    Messages
    1 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 129
    Points : 862
    Points
    862
    Par défaut
    Merci à tous.

    Malgré le temps système de 10ms chez moi, les timers que vous m'avez donné fonctionne comme je le souhaite.

    merci encore à vous tous pour aide 8)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin d'une précision pour try/catch, svp
    Par hallek60 dans le forum C++
    Réponses: 9
    Dernier message: 05/01/2006, 21h15
  2. [timer] Compte à rebours pour redirection !
    Par Raideman dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 31/12/2005, 20h07
  3. [VB.NET]Besoin de précision pour architecture 3-tiers
    Par Dnx dans le forum Windows Forms
    Réponses: 8
    Dernier message: 14/09/2005, 09h09
  4. Réponses: 19
    Dernier message: 15/03/2005, 09h05
  5. Timer de précision
    Par guigui dans le forum MFC
    Réponses: 1
    Dernier message: 04/12/2002, 15h21

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