cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 2009
-
22 avril 2005 à 08:10
pouicnet
Messages postés1Date d'inscriptionsamedi 5 février 2005StatutMembreDernière intervention 6 janvier 2006
-
6 janv. 2006 à 15:10
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
pouicnet
Messages postés1Date d'inscriptionsamedi 5 février 2005StatutMembreDernière intervention 6 janvier 2006 6 janv. 2006 à 15:10
Dit donc pour les pauses de quelques microsecondes, je peux vous dire qu'elles me sont très utile lorsque je veux prendre le contrôle du port parallèle pour le pilotage de moteurs pas à pas... Merci donc pour ce delayus bien pratique :)
cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 20145 26 avril 2005 à 10:47
Si ça bouffe 1 microseconde du CPU y' a pas mort d' homme !
Sinon oui, je connaissait TMMTimer Kenavo, pour la bonne raison qu' il est meilleur que sleep et que je l' ai deja conseillé à plusieurs personnes sur ce site :)
GrandVizir demande quel est l' intérêt ... aucun à première vue, mais utilisé dans une boucle, il permet de dessiner sur un canvas en faisant une micropause. Bref, j' en sais strictement rien mais on va bien lui trouver un truc à ce code :)
cs_grandvizir
Messages postés1106Date d'inscriptionsamedi 8 novembre 2003StatutMembreDernière intervention 3 septembre 200622 24 avril 2005 à 18:09
L'avantage avec le Sleep est qu'il ne bouffe PAS de CPU contrairement à ce prog qui, certes très intéressant, reste malgré tout trop gourmand. Et la non consommation de flux par Sleep est très utile pour le threading à très haute priorité... Il faut donc garder Sleep dans ces domaines.
rylryl fait une pause en travaillant. C'est paradoxal, contrairement à Sleep qui fait sa pause en ne faisant vraiment rien...
Mais quel peut être l'intérêt de faire une pause de quelques microsecondes ? Quand vous prenez votre café, vous n'êtes pas pressés... ?
rylryl
Messages postés311Date d'inscriptionmardi 9 mars 2004StatutMembreDernière intervention15 décembre 20061 23 avril 2005 à 00:38
Merci, j'y vais !
ryl...
rylryl
Messages postés311Date d'inscriptionmardi 9 mars 2004StatutMembreDernière intervention15 décembre 20061 22 avril 2005 à 21:39
Moi je ne connais pas ce "TMMTimer" as tu plus d'infos stp Kenavo ?
ryl...
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 22 avril 2005 à 19:45
A la décharge du Sleep, il faut quand même bien dire que la pause à Ryryl est exclusuive. Pas de ProcessMessages qui foutrait en l'air toute la précision du principe.
Mauricio, si tu veux une pause précise qui laisse tourner les autres taches, une pause basée sur le TMMTimer (que tu connais, je crois) devrait pouvoir répondre à tes attentes. Il faudrait essayer.
Ken@vo
rylryl
Messages postés311Date d'inscriptionmardi 9 mars 2004StatutMembreDernière intervention15 décembre 20061 22 avril 2005 à 18:35
Bonjour MAURICIO et merci a toi !!
ryl...
cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 20145 22 avril 2005 à 14:53
Excelent !!!
Le Sleep() peut aller se coucher vu qu' il ne gère même pas correctement sous 10ms ...
rylryl
Messages postés311Date d'inscriptionmardi 9 mars 2004StatutMembreDernière intervention15 décembre 20061 22 avril 2005 à 11:39
Ben une fois de plus bravo kenavo rien a dire!
Je vais de ce pas modifier et tester...
Merci pour cette amélioration, ça fait plaisir!
J'ai fait la même "micro bétise" sous VB, je vais donc la modifier en ton nom !
Encore merci Kenavo...
Quel talent!!
a+
ryl...
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 22 avril 2005 à 08:27
J'avais pas fini !.....
Moy1 = 1001.40 environ
Moy2 = 1003.00 environ
On voit ici le temps d'appel et de retour de la procedure, et le temps de calcul de la ligne
dif := (Time_now - Time_memo) * 1000000 div Frq_Base;
J'ai donc modifié la procédure pour éviter les calculs :
procedure DelayUS(MicroS: int64);
var
Limite: Int64;
begin
if QueryPerformanceFrequency(Frq_Base) then
begin
QueryPerformanceCounter(Time_memo); // Repère temps
Limite := Time_Memo + round(MicroS * Frq_Base / 1000000); // calcul fait une seule fois
repeat
QueryPerformanceCounter(Time_now);
until Time_now >= Limite;
end;
end;
ce qui donne :
Moy1 = 1000.05 environ
Moy2 = 1001.30 environ
toujours le même écart de plus d'une µseconde, mais plus précis.
Pas facile d'être précis à la µseconde puisqu'on commence à toucher à un ordre de grandeur qui n'est pas si éloigné de celui du temps d'une ligne de code.
Dans ton cas (RC5), Ryryl, le risque sur de petites machines est de voir s'accumuler les erreurs au point de se déphaser d'un demi-bit. Heureusement que la trame RC5 n'est pas trop longue, et sa fréquence bit trop grande !
Kenavo
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 22 avril 2005 à 08:10
Ha ! Ryryl, j'avais oublié de le signaler dans le code précédent, mais la logique voudrait que l'on écrive :
until dif >= MicroS; plutôt que juste >
sinon, on se décale d'une µseconde (énorme !)
Et puisqu'on est dans la µseconde, voilà ce que j'ai fait pour tester ce code
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
Moy1, Moy2: Double;
T1, T2: Int64;
TabCpt1, TabCpt2: array[0..99] of Double;
TabCpt3, TabCpt4: array[0..99] of Double;
begin
for i := 0 to 99 do
begin
QueryPerformanceCounter(T1);
DelayUS(1000);
QueryPerformanceCounter(T2);
TabCpt1[i] := Time_Now;
TabCpt2[i] := Time_Memo;
TabCpt3[i] := T2;
TabCpt4[i] := T1;
end;
for i := 0 to 99 do
begin
TabCpt1[i] := Round((TabCpt1[i] - TabCpt2[i]) * 1000000 / Frq_Base);
TabCpt3[i] := Round((TabCpt3[i] - TabCpt4[i]) * 1000000 / Frq_Base);
end;
Moy1 := Mean(TabCpt1);
Moy2 := Mean(TabCpt3);
Label1.Caption := FloatToStrf(Moy1, ffFixed, 15, 2);
Label2.Caption := FloatToStrf(Moy2, ffFixed, 15, 2);
end;
en rendant globales les variables de ta procédure d'attente.
6 janv. 2006 à 15:10
26 avril 2005 à 10:47
Sinon oui, je connaissait TMMTimer Kenavo, pour la bonne raison qu' il est meilleur que sleep et que je l' ai deja conseillé à plusieurs personnes sur ce site :)
GrandVizir demande quel est l' intérêt ... aucun à première vue, mais utilisé dans une boucle, il permet de dessiner sur un canvas en faisant une micropause. Bref, j' en sais strictement rien mais on va bien lui trouver un truc à ce code :)
24 avril 2005 à 18:09
rylryl fait une pause en travaillant. C'est paradoxal, contrairement à Sleep qui fait sa pause en ne faisant vraiment rien...
Mais quel peut être l'intérêt de faire une pause de quelques microsecondes ? Quand vous prenez votre café, vous n'êtes pas pressés... ?
23 avril 2005 à 00:38
ryl...
22 avril 2005 à 21:39
ryl...
22 avril 2005 à 19:45
Mauricio, si tu veux une pause précise qui laisse tourner les autres taches, une pause basée sur le TMMTimer (que tu connais, je crois) devrait pouvoir répondre à tes attentes. Il faudrait essayer.
Ken@vo
22 avril 2005 à 18:35
ryl...
22 avril 2005 à 14:53
Le Sleep() peut aller se coucher vu qu' il ne gère même pas correctement sous 10ms ...
22 avril 2005 à 11:39
Je vais de ce pas modifier et tester...
Merci pour cette amélioration, ça fait plaisir!
J'ai fait la même "micro bétise" sous VB, je vais donc la modifier en ton nom !
Encore merci Kenavo...
Quel talent!!
a+
ryl...
22 avril 2005 à 08:27
Moy1 = 1001.40 environ
Moy2 = 1003.00 environ
On voit ici le temps d'appel et de retour de la procedure, et le temps de calcul de la ligne
dif := (Time_now - Time_memo) * 1000000 div Frq_Base;
J'ai donc modifié la procédure pour éviter les calculs :
procedure DelayUS(MicroS: int64);
var
Limite: Int64;
begin
if QueryPerformanceFrequency(Frq_Base) then
begin
QueryPerformanceCounter(Time_memo); // Repère temps
Limite := Time_Memo + round(MicroS * Frq_Base / 1000000); // calcul fait une seule fois
repeat
QueryPerformanceCounter(Time_now);
until Time_now >= Limite;
end;
end;
ce qui donne :
Moy1 = 1000.05 environ
Moy2 = 1001.30 environ
toujours le même écart de plus d'une µseconde, mais plus précis.
Pas facile d'être précis à la µseconde puisqu'on commence à toucher à un ordre de grandeur qui n'est pas si éloigné de celui du temps d'une ligne de code.
Dans ton cas (RC5), Ryryl, le risque sur de petites machines est de voir s'accumuler les erreurs au point de se déphaser d'un demi-bit. Heureusement que la trame RC5 n'est pas trop longue, et sa fréquence bit trop grande !
Kenavo
22 avril 2005 à 08:10
until dif >= MicroS; plutôt que juste >
sinon, on se décale d'une µseconde (énorme !)
Et puisqu'on est dans la µseconde, voilà ce que j'ai fait pour tester ce code
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
Moy1, Moy2: Double;
T1, T2: Int64;
TabCpt1, TabCpt2: array[0..99] of Double;
TabCpt3, TabCpt4: array[0..99] of Double;
begin
for i := 0 to 99 do
begin
QueryPerformanceCounter(T1);
DelayUS(1000);
QueryPerformanceCounter(T2);
TabCpt1[i] := Time_Now;
TabCpt2[i] := Time_Memo;
TabCpt3[i] := T2;
TabCpt4[i] := T1;
end;
for i := 0 to 99 do
begin
TabCpt1[i] := Round((TabCpt1[i] - TabCpt2[i]) * 1000000 / Frq_Base);
TabCpt3[i] := Round((TabCpt3[i] - TabCpt4[i]) * 1000000 / Frq_Base);
end;
Moy1 := Mean(TabCpt1);
Moy2 := Mean(TabCpt3);
Label1.Caption := FloatToStrf(Moy1, ffFixed, 15, 2);
Label2.Caption := FloatToStrf(Moy2, ffFixed, 15, 2);
end;
en rendant globales les variables de ta procédure d'attente.
Resultats :
Frq_Base = 2 793 060 000 !!!!.....
Moy1 =
Moy2
Ken@vo