AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Parallelport-Abfrage mit Timeout

Ein Thema von valjah · begonnen am 26. Mär 2009 · letzter Beitrag vom 28. Mär 2009
Antwort Antwort
Seite 1 von 2  1 2      
valjah

Registriert seit: 13. Nov 2006
19 Beiträge
 
Delphi 7 Personal
 
#1

Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 00:32
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 inpout32.dll. Soweit funktioniert auch alles wunderbar. Den Status des Geräts frage ich über die function Inp32 aus.
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 Timer-Tutorial kämen entweder (a) ein Threaded Timer oder (b) ein OnIdle Timer in Frage. Was macht mehr Sinn? Und wenn ich es (2) mit Threads löse, wie sollte dann die Zeitmessung bzw. der Timeout sinnvollerweise aussehen?

Für Euren Input bin ich Euch sehr dankbar!

Valentin
  Mit Zitat antworten Zitat
valjah

Registriert seit: 13. Nov 2006
19 Beiträge
 
Delphi 7 Personal
 
#2

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 11:13
Frei nach dem Motto "keep it simple, stupid" frage ich mich gerade: was wäre das Problem bei folgendem Vorgehen?

Delphi-Quellcode:
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;
CheckFlag prüft hier, ob das Buffer Bit gesetzt ist.

Delphi-Quellcode:
procedure CheckFlag(Value, Flag: Byte; out Check: Boolean);
begin
  if (Value and Flag) = Flag then
    Check := True
  else
    Check := False;
end;
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.

Also: wozu Timer bzw. Threads? Oder mache ich es mir hier zu einfach?
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 11:56
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:
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
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.

Gruß oki
42
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 12:04
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
42
  Mit Zitat antworten Zitat
valjah

Registriert seit: 13. Nov 2006
19 Beiträge
 
Delphi 7 Personal
 
#5

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 14:13
Hallo oki,

danke für Deine Antworten. Asnyc Pro ist wohl nur für die serielle Schnittstelle geeignet. Bedienbar muss das Programm nicht sein (außer über den Parallelport eben). Wichtig wäre nur, dass mir Windows oder andere Prozesse nicht dazwischen funken. Auch deshalb hatte ich an einen Thread (dann mit höherer Priorität) gedacht. Ich will, wenn möglich, während dieser Abfrage die "volle Kontrolle" haben (ist kein Anwendungsprogramm). Die Zeitmessung soll auf 1 ms genau sein, deshalb QPC. Ich werde es wohl so (siehe oben) probieren. War mir nur nicht sicher, ob dann während meiner repeat Schleife wirklich nichts anderes läuft. Wie prüfe ich denn eigentlich, wie lange so ein Schleifendurchlauf braucht und wie stabil diese Zeit ist?

Gruß,
Valentin
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 16:20
ok, ich bin im Moment nicht hundertprozentig fitt bei diesen Themen, aber ich versuchs mal.


Zitat:
Bedienbar muss das Programm nicht sein (außer über den Parallelport eben). Wichtig wäre nur, dass mir Windows oder andere Prozesse nicht dazwischen funken. Auch deshalb hatte ich an einen Thread (dann mit höherer Priorität) gedacht. Ich will, wenn möglich, während dieser Abfrage die "volle Kontrolle" haben (ist kein Anwendungsprogramm).
Wenn Windows dir dazwischen funken will, dann tut es das auch. Man kann natürlich die Taskpriorität erhöhen, aber im Zweifelsfall legst du alles andere dann durch dein Programm (Task) lahm. Ich hatte auch mal mit der Taskpriorität rumexperimentiert, lahm legen konnte ich den Rechner damit aber so nicht. Wie das bei deiner Repeat-Schleife aussieht kann ich aber nicht sagen. Da deine Anwendung auch nur ein Thread ist und die nach deinen Aussagen nicht bedient werden soll, ist es eigentlich egal, ob du das nun auslagerst oder deiner Anwendung eine höhere Priorität gibst. Kommt imho aufs selbe raus.



Zitat:
Die Zeitmessung soll auf 1 ms genau sein, deshalb QPC. Ich werde es wohl so (siehe oben) probieren.
GetTickCount gibt dir auch die Zeit auf die Millisekunde genau. Ob das gleichwertig zu deiner Variante ist kann ich nicht sagen. Das sagt die Windows Hilfe zu GetTickCount:
Zitat:
Retrieves the number of milliseconds that have elapsed since the system was started. The resolution is limited to the resolution of the system timer.
Es läuft also über die Systemzeit und sollte eigentlich genau sein.



Zitat:
Asnyc Pro ist wohl nur für die serielle Schnittstelle geeignet. Bedienbar muss das Programm nicht sein (außer über den Parallelport eben).
Bei Async war ich mir nicht mehr sicher. Aber wird wohl so sein. Async stellt aber ne Menge mehr zur Verfügung als man auf den ersten Blick sieht.



Zitat:
Wie prüfe ich denn eigentlich, wie lange so ein Schleifendurchlauf braucht und wie stabil diese Zeit ist?
Versteh ich jetzt nicht, na wie beschrieben durch die Zeitmessung. Was du mit stabil meinst ist mir jetzt aber nicht klar.

Gruß oki
42
  Mit Zitat antworten Zitat
valjah

Registriert seit: 13. Nov 2006
19 Beiträge
 
Delphi 7 Personal
 
#7

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 19:28
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:
GetTickCount gibt dir auch die Zeit auf die Millisekunde genau.
GetTickCount ist nur auf etwa 10 ms genau, wie u.a. hier nachzulesen ist. Daher ist QPC die bessere Lösung.

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:
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;
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.
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
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 19:56
[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
42
  Mit Zitat antworten Zitat
valjah

Registriert seit: 13. Nov 2006
19 Beiträge
 
Delphi 7 Personal
 
#9

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 20:05
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:
Du willst die Reaktion von Menschen testen. Welche Abweichungen sind denn dann zulässig?
Also, da wir kognitionspsychologische Experimente durchführen, bei denen sich die durchschnittlichen Reaktionszeiten zwischen unterschiedlichen Bedingungen teilweise nur um 20 ms unterscheiden (das aber zuverlässig), ist eine Genauigkeit auf 1 ms schon wichtig. Nanosekunden interessieren mich nicht.

Zitat:
Du möchtest ein Progamm auf einem Betriebssystem schreiben. Wenn dein Programm läuft soll es sich aber lieber raus halten. Frommer Wunsch.
Man kann ja wenigstens versuchen, das Bestmögliche herauszuholen. Am Ende wird es immer ein Kompromiss sein.

Gruß, Valentin
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Parallelport-Abfrage mit Timeout

  Alt 26. Mär 2009, 20:26
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
42
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz