begin process at 2010 02 09 21:47:06
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Divers

 > [THREAD] EXEMPLE DE "TIMER MICROSECONDE PAS TRÉS PRECIS"

[THREAD] EXEMPLE DE "TIMER MICROSECONDE PAS TRÉS PRECIS"


 Information sur la source

Note :
Aucune note
Catégorie :Divers Classé sous :timer, microseconde, queryperformancecounter, queryperformancefrequency, thread Niveau :Initié Date de création :13/02/2006 Date de mise à jour :16/02/2006 13:44:02 Vu / téléchargé :8 226 / 615

Auteur : Sylvainlefou

Ecrire un message privé
Commentaire sur cette source (18)
Ajouter un commentaire et/ou une note

 Description

J'ai besoin d'un timer assez précis pour gérer un afficheur à persistance rétinniene, c'est ainsi que l'ai codé ce truc (il est probable d'en trouver des semblables sur internet).
Ce petit timer est basé sur le code de rylryl : http://www.delphifr.com/codes/PETITE-PAUSE-MICROSE CONDE_30901.aspx
Ce timer est censé étre précis à la microseconde, cependant, sur mon Athlon 2100Mhz (476 nanoseconde/front) les résultats semblent médiocres : en de créant un signale carré sur le port //, d'une periode d'une milliseconde, on voit a l'oscilloscope qu'une periode foire de temps en temps, alors qu' avec un timer Windows, le signale est impecable.
J'aimerais trouver la cause de ce probleme, vous pourez peut-etre m'aider :
- Mon code bug ?
- QueryPerformanceCounter pas assez fiable ?
- Le rapport (Frequence processeur)/(periode esperée) est trop faible ? (pourtant, 1000 microsecondes <=> 2000 fronts, ce qui est pas mal je pense)


Source

  • Code complétement commenté dans le ZIP !
Code complétement commenté dans le ZIP !

 Conclusion

Merci de critiquer au maximum mon code pour l'améliorer (et moi aussi par la méme occasion) :-)

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

16 février 2006 13:44:03 :
Ce timer n'est pas satisfaisant, ma source n'est plus qu'un exemple d'utilisation de thread (rigueure non garantie)

 Sources du même auteur

Source avec Zip JEUX AVEC PLUSIEURS ECRANS : PAS DE REDUCTION LORS DE LA PER...

 Sources de la même categorie

Source avec Zip Source avec une capture LOGICIEL DE DIAGNOSTIC AUTOMOBILE KWP2000 par Oniria
Source avec Zip Source avec une capture RÉGLE TRANSPARENTE POUR MESURER UN OBJET ECRAN par dubois77
Source avec Zip Source avec une capture LE BOOK DU PAUVRE par dubois77
Source avec Zip Source avec une capture CAHIER 90 PAGES par dubois77
Source avec Zip Source avec une capture TABLEAU DE BOUTONS DYNAMIQUES (AGENDA) par dubois77

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture THREAD ET BITMAP (DESSIN AU CRAYON) par barbichette
Source avec Zip Source avec une capture PRÉ-COMPOSANT D'AFFICHAGE DE TEXTE PROGRESSIF... par blueperfect
Source avec Zip Source avec une capture ANIMATION AVEC PNG par Bacterius
Source avec Zip Source avec une capture LES FIBERS : DES THREADS NON PRÉEMPTÉS PAR LE SYSTÈME par Caribensila
Source avec Zip TMICROTIMER - TIMER À LA MICROSECONDE ! par Bacterius

Commentaires et avis

Commentaire de f0xi le 14/02/2006 06:43:58 administrateur CS

modification dans Create :

procedure TForm1.FormCreate(Sender: TObject);
begin
  LongTimeFormat := 'hh:nn:ss.zzz';
  MicroTimer1 := MicroTimer.Create(nil);
  MicroTimer1.OnTimer := MicroTimer1OnTimer;
end;
__________________________________________________________________

modification de OnTimer :

procedure TForm1.MicroTimer1OnTimer(Sender: TComponent);
var t : int64;
begin
  QueryPerformanceCounter(t);
  caption := format('%s || %d',[TimeToStr(now),t]);
end;
__________________________________________________________________

modification de Main() :

Procedure MicroTimer.Main();
var
  Time_now, Time_memo, IntervalRecalc: Int64;
  Ic : integer;
begin
  Time_now  := 0;
  Time_memo := 0;
  Ic        := 0;
  while FEnabled do begin
    IntervalRecalc := FInterval - (Time_now - Time_memo) * 1000000 div FFrq_Base;
    FThread:= MicroTimerTh.Create(FFrq_Base, IntervalRecalc);
    while (not(FThread.ThreadTerminated)) and (FEnabled) do
      if Ic = 1000 then begin
         Application.ProcessMessages;
         Ic := 0;
      end;
      Inc(Ic);
    end;
    QueryPerformanceCounter(Time_memo);
    FOnTimer(Self);
    QueryPerformanceCounter(Time_now);
  end;
end;
__________________________________________________________________

Modification d'execute :

procedure MicroTimerTh.Execute;
var
  Time_memo, Time_now, dif: Int64;
begin
  QueryPerformanceCounter(Time_memo);
  while dif <= FInterval do begin
    QueryPerformanceCounter(Time_now);
    dif := (Time_now - Time_memo) * 1000000 div FFrq_Base;
  end;
end;
__________________________________________________________________

evite de balancer des données qui change tout le temps dans une liste ... utilise un label plutot ou un tstringlist (durant le calcul).

Commentaire de wolf691300 le 14/02/2006 09:12:22

Je ne suis pas à une seconde près pour créer une application. Tant que l'exécutable fonctionne bien avec un Timer normal ... J'en vois aucune utilité d'amélioration, idem dans le monde réel.

Wolf691300

Commentaire de cirec le 14/02/2006 12:01:29 administrateur CS

Salut,
Wolf ce qui est valable pour toi ne l'est pas forcément pour les autres.
Si aujourd'hui tu ne vois aucune utilité à un timer de haute précision, demain il en sera peut être autrement. C'est sur que pour afficher un message où fermer un rideau c'est pas utile d'être précis à la microseconde mais il n'y a pas que ça, je pense notamment au multimédia qui dans certaine circonstance demande une précision extrême mais il y a encore plein d'autres applications.

@+
Cirec

Commentaire de pepitto le 14/02/2006 13:34:14

Si tu n'est pas à la seconde je te propose d'utiliser une petite fonction simple (tu peux trouver l'aide dans Win32.hlp) qui utilise les messages :

dans private ajoute :
procedure OnTimer(var msg : Tmessage); message WM_TIMER;

//--------------------------------------------

procedure TForm1.OnTimer(var msg : Tmessage);
begin
// ici places les action à effecturer toutes les secondes
if Msg.wParam = 1234 then // si plusieurs timers une sellection
                          // est possible avec wParam
begin


end;
end;

//-------------------------------------------------
dans Procedure Tform1.Create(Sender: TObject); ajoute
setTimer(Handle,
         1234,  // identifiant du timer
         1000,  // temps en milliseconde (1 seconde dans ce cas)
         nil);  // voir aide (je ne suis pas trop copain avec l'anglais)


// pour stopper le timer utilies
Killtimer(Handle,
          1234);  //identifiant du timer


Toutes ces lignes peuvent t'éviter de creer un timer est peut être très simple d'utilisation (Quand on essaie l'emploie les <<message>>)

Commentaire de Sylvainlefou le 14/02/2006 14:58:54

Message envoyé par jlen100 :
"salut,pas mal ton code. Une petite chose tu n'as pas donné de priorité à la construction (si je ne trompe pas par défaut elle doit être à   Priority := tpNormal)
pour les décalages j'ai eu le même probleme avec un thread et ce quelque soit la priorité donnée; le decalage pouvant atteindre 15ms en fait cela s'explique facilement : avec le Application.processmessages on indique au programme qu'il doit redonner la main à windows qui gère la file d'attente (et celà est préférable sous peine de blocage) résultat il faut bien qu'il traite aussi les autres threads et cela prend comme le refroidissement du fût du canon ... un certain temps.
en conclusion il est pratiquement impossible de garantir un timming précis en dessous de la milliseconde sans bloquer le processus (interdire à windows de traiter les threads).
Pour obtenir des timming plus petit il faut passer par des cartes d'extension qui génèrent le signal (avec ou sans bufferisation des données s'il faut les transmettre) une carte à microcontroleur fait génèralement l'affaire avec des horloge à 20 ou 50MHz on arrive facilement à des signaux precis à 50 à 100ns
Mais la persistance rétienienne étant ~100ms un timer standard réglé à 40/50 ms fait très bien l'affaire tu peux même descendre à 20ms en gardant un bonne reproductivité. Mais comme je ne connais pas ton application je ne fairais pas plus de commentaires"
j'espère que cela pourra t'être utile

@+
jlen

Commentaire de Sylvainlefou le 14/02/2006 15:40:11

Le petit exemple d'utilisation du timer a était codé simplement pour montrer l'irrégularité du timer, il est vrai qu'ils n'est pas trés propre.

f0xi : merci, c'est vrai qu'un while...do semble plus logique qu'un repeat...until, je ne met pas a jour la source mais je modifie mon code.
Sinon la liste servait a montrer que, chaque seconde, il y avant un décalage de x milliseconde. cependant, un label reste beaucoup plus léger pour la machine (méme si les temps d'executions de "OnTimer" sont compensée).

pepitto : cette gestion des timers est la maniere plus direct, d'utiliser les timers windows (API). C'est ca qui est utiliser par le composant TTimer.

jlen100: il faut alors géré, en plus du temps d'execution de "OnTimer", les temps de Application.ProcessMessages et des differentes boucles, de la creation du thread... il y a pas mal de choses a changer, je vais voir cela.

Merci a tous

Commentaire de jlen100 le 14/02/2006 18:27:41

test à partir d'un autr PC

Commentaire de jlen100 le 14/02/2006 18:31:42

retour sur le pc principal

Commentaire de Kenavo le 15/02/2006 14:52:15

Arghhhh .....
"If FEnabled=True then Main; "
"until FEnabled = False;"
Ben non ! Ecris plutôt :
"If FEnabled then Main; "
"until not FEnabled;"

Sinon pour le timer, c'est une catastrophe ! Je déconseille aux âmes sensibles d'aller voir le taux d'occupation du processeur !
Le meilleur timer est .... le timer le mieux adapté au problème !
Rylryl l'utilisait pour séquencer des trames de télécommande RC5 (durée de la trame 25 ms, duré du bit 1,78 ms) où il était adapté : Besoin de précision et utilisation courte. Pour des périodes de l'ordre de la seconde, le timer TTimer est très correct. Entre 1 et 100 millisecondes, le timer multimedia est sans doute le plus adapté.

Kenavo

Commentaire de jlen100 le 15/02/2006 15:25:51

oui kenavo le MMTimer il est très précis mais assez gourmand en ressource.
de toute façon dés que tu mets un application.processmessage le taux d'occupation passe à 100% en effet windows reboucle sur l'instruction while tant que la condition de sortie n'est pas remplie; mais cela n'a pas d'influence sur le déroulement des autres programes puisqu'il ne revient dans le while q'après avoir traité les messages et autres threads cela permet simplement une réponse plus rapide qu'un scan et sans bloquer Windows le probléme restant c'est qu'on ne peut pas déterminer à l'avance combien durera une boucle puisqu'elle dépend du nombre et de la priorité des thread et des messages et que par conséquent cette durée est tout à fait aléatoire (ce qui est d'ailleurs à l'origine du manque de précision de ce timer.

@+
jlen

Commentaire de Sylvainlefou le 15/02/2006 15:37:48

Ok, vous confirmez ce que je pensais, mon timer est nul et useless, lol, tempi ! :) :)
Je vire la source où peut-elle servir ?

Commentaire de jlen100 le 15/02/2006 15:50:17

non laisses la elle est un exemple d'ulisation de thread par contre il vaudrait peut être mieux la renommer et mettre un avertissement

@+
jlen

Commentaire de f0xi le 17/02/2006 23:04:58 administrateur CS

tu sais de ou viens ton probleme ?

je vais te le dire : l'appel de Application.ProcessMessage dans ton thread.

mais si on l'enleve, l'application freeze ... normal.

Commentaire de jlen100 le 17/02/2006 23:44:26

pour éviter l'appel a application.ProcessMessage il faudrait passer par une gestion évènementielle (comme le fait le timer) et ne gérer que l'évènement. Mais même dans ce cas la précision n'est pas garantie en effet Windows place l'évènement dans une file de traitement  et il ne sera traité que lorsque les précédents auont été traité. La réaction est meilleure que le traitement du thread seul mais il n'est pas "en temps réel" mais en batch (par exemple si un évènement comme un ontimer est en court de traitement l'évenement ne sera traité qu'après et cela peut prendre des millisecondes) l'avantage est que le thread continue d'être traité et qu'on ne cumule pas les erreurs, enfin dans la limite de charge du processeur. Comme il n'y a qu'un seul processeur il faut bien qu'il traite toutes les demandes!
On rencontre d'ailleurs le même problème quand on gère des interruptions: on donne des priorités mais il y a toujours des taches favorisées et d'autres qui attendent; quand on travaille en assembleur et qu'il n'y a pas trop de processus en cours on arrive à s'en sortir mais dans le cas de window s'est pratiquement impossible (le nombre et la priorité des processus peut varier)

Commentaire de ACHPI32 le 23/02/2006 01:15:22

y'a pu qu'a sortir le free pascal ou le TP7 et faire un programme sous DOS... lol

Commentaire de jlen100 le 23/02/2006 07:45:42

ACHP132--> à condition de pas travailler sous XP puisque dans ce cas il n'y a pas de dos mais seulement une émulation du dos gérer par Windows et il reprend la main régulièrement pour traiter les messages.
Comme tu travailles en temps partagé tu ne garantiras pas la durée du traitement (ni à la milliseconde et encore moins à la microseconde)

Commentaire de karim18 le 18/06/2006 02:34:28

ce programme n'existe pas ??????????????

Commentaire de MUSTAPH_A le 24/10/2007 22:55:20

SALUT MES AMIS: j'ai un probleme avec le timer de Delphi je voudrer ajouter une parametre dans timer et j'arrive pas a ajouter alors aider moi svp, mon problem c'est a chaque fois on clic sur la form un nouveau boutton doit etre creer et la valaur 100 est affecter au caption de ce button j'usqua se mement c'est simple mais le probleme qui se pose: j'ai associe a chaque button une timer qui creer de meme principe de button maintenat je voudrer décrementer la valeur de chaque button indepondament au autres button jusqu'a arrivé a 0. merci d'avance et j'attend votre reponse.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

TIMER MICROSECONDE PAS TRÉS PRECIS [ par jlen100 ] salut &#224; tous, puisqu'un bug informatique m'emp&#234;che de r&#233;pondre directement en commentaire de cette source je le fairais par cet interme Comment implémenter ce Thread ? [ par djiga4me ] Bonjour, dans mon application, j'ai un timer qui effectue un check toutes les 5 secondes (une verif un peu longue) et qui par sa nature provoque un pe Rafraichir Main depuis un thread [ par syphon22 ] Bonjour à tous, voila mon problème : j'ai crée un Thread que je lance depuis ma form Main. Dans ce Thread, diverses opérations sont effectuées et j' thread - début puis sortie immédiate [ par syphon22 ] Bonjour à tous, je vous explique mon problème : Quand je lance mon thread depuis mon application principale avec un bouton, des fois, il entre puis [thread] pb apres arret de thread [ par titiyo ] bonjour, j'ai un pb car quand j'arrete un thread , j'ai un message : receiveheader:net packets out of order : received[0], expected[1]. quoi que je fa progressbar et timer [ par guigui265 ] Bonjour,j'ai sur mon formulaire un progressbar,un timer et un bouton,entre autres.Coomment faire pour que,sur le clic du bouton, la progressbar progre comment imbriquer des action timer les unes dans les autres ? [ par littlemogwai ] Bonjour,Je cherche une solution pour imbriquer plusieurs action de timer.un algo qui ressemble &#224; &#231;aAffichage fenetre&nbsp;&nbsp;&nbsp;Frappe détecter l'utilisation d'une appli pour activer logoff [ par PhilLU ] Salut,J'ai cr&#233;&#233; une appli avec un logoff automatique li&#233; &#224; un timer.(un login permet l'identification de l'utilisateur)Je souhaite détection utilisation appli [ par PhilLU ] Salut, J'ai créé une appli avec un logoff automatique lié à un timer.(un login permet l'identification de l'utilisateur) Je souhaite que ce timer déma Utiliser un Timer en mode console [ par Francky23012301 ] Salut, Je voudrais pouvoir utiliser un Timer en mode console. Comment faire ? Merci


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,530 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales