![]() |
Parallelport-Abfrage mit Timeout
Liebe DP-Gemeinde,
folgendes Thema beschäftigt mich nun schon seit einigen Tagen und ich habe auch hier im Forum etliche Beiträge studiert. Dennoch bin ich noch nicht so richtig schlüssig, wie die beste Lösung aussieht: Ich möchte ein externes Gerät über den Parallelport abfragen und benutze dafür die ![]() Nun möchte ich genau (auf 1 ms) ermitteln, wieviel Zeit bis zu einer Statusveränderung vergeht. Dafür sind mir bisher zwei Lösungen eingefallen: (1) Ein Timer oder (2) ein separater Thread. Dieser soll zurückmelden, wenn (a) eine Statusveränderung am Parallelport aufgetreten ist, oder (b) ein Timeout überschritten wurde. Meine Frage: wie kriege ich das am besten/elegantesten/simpelsten unter einen Hut? Das Hauptprogramm muss in dieser Zeit nichts anderes machen, darf also durchaus "blockiert" werden. Wie würdet Ihr dieses Problem lösen? Wenn (1) Timer, dann welcher? Ausgehend von Henning Brackmanns ![]() Für Euren Input bin ich Euch sehr dankbar! Valentin |
Re: Parallelport-Abfrage mit Timeout
Frei nach dem Motto "keep it simple, stupid" frage ich mich gerade: was wäre das Problem bei folgendem Vorgehen?
Delphi-Quellcode:
CheckFlag prüft hier, ob das Buffer Bit gesetzt ist.
procedure WaitLPT;
begin QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(StartTime); repeat GetState := Inp32($379); CheckFlag(GetState, Buffer, BufferFull); QueryPerformanceCounter(StopTime); WaitTime := (StopTime - StartTime) * 1000 div Frequency; until BufferFull or WaitTime >= TimeOut; end;
Delphi-Quellcode:
Als Output (von WaitLPT) benötige ich lediglich die exakte Zeit, die zwischen Aufruf und BufferFull vergangen ist. Während ich darauf warte, soll das Programm (und das ganze System) nichts anderes machen.
procedure CheckFlag(Value, Flag: Byte; out Check: Boolean);
begin if (Value and Flag) = Flag then Check := True else Check := False; end; Also: wozu Timer bzw. Threads? Oder mache ich es mir hier zu einfach? |
Re: Parallelport-Abfrage mit Timeout
Wenn der Rest egal ist (warten bis sich was tut), dann benutze doch GetTickCount um die Zeit zu ermitteln. Das sollte hinreichend genau sein.
Delphi-Quellcode:
edit: Sorry nicht ganz aufgepasst. Ja, so kannst du das machen. Wenn das Programm bedienbar bleiben soll, dann musst du das ganze LPT-Handling in einen Thread auslagern. Mit der Zeitmessung hat das nichts zu tun. Dafür gibt es aber tolle freie Compos. Ich Glaub bei Async Pro ist auch was dabei.
var LastTime, WaitTime : DWord;
... // hier wird gestartet LastTime := GetTickCount; // hier läuft alles was laufen muss .... // hier ist fertig WaitTime := GetTickCount - LastTime; // und hier hast du in ms die vergangene Zeit // und weiter im Text Gruß oki |
Re: Parallelport-Abfrage mit Timeout
ist heute nicht mein Tag.
Du kannst natürlich auch ein Application.ProcessMessages in deine Repeat-Schleife einbauen. Dann ist dein Programm zwar auch in dieser Zeit nicht bedienbar, aber die Windows-Botschaften werden abgearbeitet und deine Anwendung wird wenn nötig auch neu gezeichnet und "friert" auf dem Bildschirm nicht ein. Gruß oki |
Re: Parallelport-Abfrage mit Timeout
Hallo oki,
danke für Deine Antworten. Asnyc Pro ist wohl ![]() ![]() Gruß, Valentin |
Re: Parallelport-Abfrage mit Timeout
ok, ich bin im Moment nicht hundertprozentig fitt bei diesen Themen, aber ich versuchs mal.
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Gruß oki |
Re: Parallelport-Abfrage mit Timeout
Also, damit Ihr wisst, worum es überhaupt geht: mit dem Programm soll ein Experiment zur Reaktionszeitmessung umgesetzt werden. Die Reaktion (durch die Versuchsperson) erfolgt dabei über ein externes Gerät am Parallelport. Entscheidend ist dabei, die Zeit zwischen Beginn der Abfrage und der Reaktion (signalisiert durch eine Veränderung im Statusregister des Parallelports) möglichst genau zu bestimmen, d.h. mit einer hohen Auflösung (1 ms) und einer hohen Zuverlässigkeit (unabhängig von Störeinflüssen).
Das Windows sowas grundsätzlich nicht zulässt, ist mir schon bekannt. Dennoch versuche ich, die bestmögliche Lösung unter diesen Umständen zu finden. Das System darf während der Zeitmessung komplett lahmgelegt werden, die Versuchsteilnehmer sollen sich ja nicht mit anderen Programmen beschäftigen. Zitat:
![]() Meine Frage war, wie lange ein (!) Durchlauf der repeat Schleife dauert und ob diese Zeit immer gleich ist. Ich habe das jetzt mal so getestet:
Delphi-Quellcode:
Das Array (LoopTime) habe ich dann noch in ein Textfile geschrieben. Dort stehen nur Nullen. Demnach gehe ich davon aus, dass jede Runde weniger als 1 ms gedauert hat. Das ist schon mal gut.
procedure WaitLPT;
begin QueryPerformanceFrequency(Frequency); QueryPerformanceCounter(StartTime); repeat WaitTimeOld := WaitTime; // Letzte Runde GetState := Inp32($379); CheckFlag(GetState, Buffer, BufferFull); QueryPerformanceCounter(StopTime); WaitTime := (StopTime - StartTime) * 1000 div Frequency; inc(i); if i > 100000 then break; // Nach 100.000 Runden -> raus LoopTime[i] := WaitTime - WaitTimeOld; // Aktuelle Rundenzeit until BufferFull or WaitTime >= TimeOut; end; Dann habe ich mir noch die Gesamtzeit angeguckt, die das Programm für die 100.000 Schleifendurchläufe braucht. Die variierte bei meinen Tests zwischen 199 und 312 ms. Das ist eher schlecht. Woran könnte das liegen? Aber solange die Auflösung unter 1 ms bleibt, kann es mir vermutlich egal sein... Gruß, Valentin |
Re: Parallelport-Abfrage mit Timeout
[quote]
Dann habe ich mir noch die Gesamtzeit angeguckt, die das Programm für die 100.000 Schleifendurchläufe braucht. Die variierte bei meinen Tests zwischen 199 und 312 ms. [delphi] Das sind dann wohl knapp 3 ns. Du willst die Reaktion von Menschen testen. Welche Abweichungen sind denn dann zulässig? Denk doch mal darüber nach. Unterstellen wir doch mal eine Abweichung von 1000%. Dann bist du immer noch unter einer Millisekunde. Du möchtest ein Progamm auf einem Betriebssystem schreiben. Wenn dein Programm läuft soll es sich aber lieber raus halten. Frommer Wunsch. Also, wenn du unbedingt im ns-Bereich messen möchtest, dann nehme einen Microcontroller (PIC etc.), dafür gab es hier auch einige Threads, zu haben für wenige Euro, lasse den die Messung machen und schließe ihn über die V24 an deinen Rechner an. Da kannst du dir dann die Zeiten übermitteln lassen. Die sollten dann recht genau sein. Vorausgesetzt du hast einen stabilen Quarz drauf und kennst die genaue Taktfrequenz. Aber die kann man ja messen. Soory, aber wie genau eine Schleife auf Windows im Nanosekunden läuft kann ich dir nicht sagen. Ich denke mal das kann keiner für deinen Rechner tun. Deine Messung mit einer Differenz fast 40% sollte das verdeutlicht haben. Gruß oki |
Re: Parallelport-Abfrage mit Timeout
Ich habe meine "Schleifenmessung" gerade nochmal ein bisschen systematisiert und siehe da: in 100.000 Durchläufen komme ich durchschnittlich auf 245 Runden mit einer Zeit von 1 ms oder mehr (der Rest liegt darunter). Kritisch ist vor allen Dingen das "oder mehr". Denn einzelne Schleifendurchläufe benötigen bis zu 10 ms. Das ist zwar bloß eine aus 100.000, aber möglicherweise erwische ich die ja gerade, wenn die Versuchsperson reagiert. Und eine Verzerrung um 10 ms ist außerhalb der Toleranzgrenze.
Nun habe ich die ganze Prozedur mal auf HIGH_PRIORITY_CLASS und THREAD_PRIORITY_HIGHEST gesetzt (REALTIME bzw. TIME_CRITICAL habe ich mich noch nicht getraut). Und siehe da: es gibt zwar immer noch durchschnittlich 260 (aus 100.000) Runden mit einer Laufzeit von 1 ms, aber keine einzige mehr darüber. Das erscheint mir durchaus praktikabel. Und ich weiß jetzt auch: im Mittel schafft mein Rechner 385 dieser Loops pro Millisekunde... Zitat:
Zitat:
Gruß, Valentin |
Re: Parallelport-Abfrage mit Timeout
Du wirst aber da keine Sicherheit bekommen. Kommt dein BS zwischendurch auf die Idee mal schnell Teile des Speichers auf die Festplatte zu swappen (ich hab bis heute nicht rausbekommen was wann Windows veranlasst dies zu tun) dann wird du u.U. mit erheblich größeren Verzögerungen rechnen müssen. Vielleicht kann dir ja einer sagen, was du an Diensten und sonstiges alles abschalten mußt damit dein BS gerade noch so läuft.
Ich mach mir da echt sorgen und das mit dem Microcontroller war ernst gemeint. Da kannst du dich dann 100 pro drauf verlassen. Gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz