Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Millisekundentimer - mit Abfrage?

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 01.10.2004, 21:21    Titel: Millisekundentimer - mit Abfrage? Antworten mit Zitat

Ich hab ja schon gesehen, dass es da so Millisekunden-Warten-Routinen gibt, was ich jetzt aber mal wissen wollte:
Wäre eine Routine, die wirklich wie Timer funktioniert, wo ich mir also auch die Anzahl der vergangenen Millisekunden rausbekommen kann, irgendwie möglich?

Jede gute Physik-Engine basiert auf Zeit. Um die genau zu benutzen brauche ich auch einen Wert wie bei Timer, aber genauer. Also auch keine Routine wo ich irgendwas für x Millisekunden pausiere sondern wo ich wirklich einen Wert abfragen kann, wie viel Zeit vergangen ist...
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 01.10.2004, 22:02    Titel: Antworten mit Zitat

Hallo !

Dem Zähler, den du mit TIMER abfragen kannst ist ein weiterer Timer vorgeschaltet, dessen Register du auslesen kannst. Dieser besteht aus einem 16-Bit Abwärtszähler, der mit einer Frequenz von 1,193182 MHz getaktet ist. Bei einem Überlauf, also wenn der Zähler von 0 auf 65535 springt, wird der Takt für den TIMER-Befehl erzeugt. 1193182 Hz / 65536 = 18,2065 Hz. So kommt dessen Auflösung von ca. 55 ms zustande.

Die 16 Bit des Zählers sind in ein High- und ein Lowbyte unterteilt, die beide unter der (dezimalen) Adresse 64 ausgelesen werden können. Immer nachdem ein Byte ausgelesen wurde, liegt das jeweils andere unter der selben Adresse. Das Register muss folglich immer zweimal ausgelesen werden. Dabei wird das Lowbyte zuerst ausgegeben. Der Stand des Zählers wird also so gelesen:

low = INP(64)
high = INP(64)
zeit = low + high * 256

So kannst du einen Zeitpunkt theoretisch auf eine millionstel Sekunde genau erfassen.

Ein Tip: manchmal läuft das Lowbyte gerade zwischen den beiden Abfragezeilen über und es kommt für "zeit" ein falscher Wert raus. Da musst du evtl. noch eine Korrektur einbauen.

Dieser Timer lässt sich auch noch rück- und in verschieden Betriebsmodi versetzen. Wenn du dich ausführlicher damit beschäftigen willst:

http://www.sharpmz.org/mz-700/8253ovview.htm

http://ivs.cs.uni-magdeburg.de/bs/lehre/sose99/bs1/aufgaben/aufgabe3/timer.shtml


Gruss
Skilltronic
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 01.10.2004, 22:36    Titel: Antworten mit Zitat

Aja, danke. Werd ich demnächst mal ausprobieren.
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 02.10.2004, 14:37    Titel: Antworten mit Zitat

Äh, mir fällt grad auf: diu hast zwei mal inp(64) genommen, müsste das eine nicht was anders als 64 als parameter haben?
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 02.10.2004, 15:41    Titel: Antworten mit Zitat

Hallo !

Nein. Immer wenn du das erste Byte abgefragt hast, liegt anschliessend das andere unter der selben Adresse. Nach jedem Auslesen lädt das Register 64 abwechselnd das Low- und dann wieder das Highbyte. Das funktioniert so ähnlich wie beim einstellen/einlesen der Farbwerte mit OUT und INP. Da benutzt du sogar drei mal hintereinander die gleiche Adrese.

Probier' doch das mal aus:

FOR t = 0 TO 9
low(t) = INP(64)
high(t) = INP(64)
NEXT
FOR t = 0 TO 9
zeit = low(t) + high(t) * 256
PRINT zeit
NEXT

Weil wie schon erwähnt läuft manchmal das Lowbyte gerade nach der ersten Abfrage über, springt also ( Abwärtszähler !) von 0 auf 255. Dieser Überlauf taktet das Highbyte um eins weiter runter. Dies alles geschieht, während der Rechner in die nächste Programmzeile springt. Da wird dann das neue High- mit dem alten Lowbyte addiert und es kommt was falsches raus .

Du kannst das Problem umgehen, indem du zwar immer beide ausliest, aber z.B. immer nur das Highbyte benutzt. Hängt von der Anwendung ab.

In den Links ist u.a. beschrieben wie der Timer so eingestellt werden kann, dass er von vorneherein nur das eine oder das andere Byte ausgibt.

Du kannst das ganze noch mit TIMER und DATE$ so verbinden, das du einen Moment vom Datum bis zur Mikrosekunde genau festhalten kannst .

Gruss
Skilltronic
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 02.10.2004, 18:56    Titel: Antworten mit Zitat

Hm, habs jetzt mal ausprobiert. Hab aber ein mehr oder weniger Katastrophales Problem verwundert . Dazu etwas "Material": ZeitTest-Protokoll
Eine Zeile ist "DATE$, TIMER, mikrosekundenzeitwert"

In diesem Protokoll kann man sehr schön sehen, dass TIMER nur bei jedem zweiten Umsprung von dem Mikrosekundendingens da umspringt, was das ganze für mich unbrauchbar macht weil ich nicht weiß, ob ich in der ersten oder zweiten Hälfte eines Timerabschnitts bin.

Kannst du da Abhilfe schaffen oder hab ich Pech gehabt? mit den Augen rollen
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2507
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 02.10.2004, 19:16    Titel: Antworten mit Zitat

Ein bekanntes Problem. Siehe Artikel dazu:

http://www.dreael.ch/Deutsch/BASIC-Knowhow-Ecke/ButterweicheAnimationen.html

Soviel dazu: Die Auflösung von TIMER beträgt bekanntlich 2^16 Ticks pro Stunde. Um etwas "Feineres" zu erhalten speziell bei Animationen kann Dir der im Artikel vorgestellte Tiefpassfilter gute Dienste machen.

Für absolute Wartezeiten musst Du evtl. so etwas wie
Code:
kalibier& = 0&
' Diese erste Schleife erscheint auf den ersten Blick sinnlos, wird
' aber gebraucht, damit wir nachfolgend immer bei einem
' "Treppentritt" von TIMER zu messen beginnen
t! = TIMER
WHILE TIMER = t!
WEND
t! = TIMER + 1!
WHILE TIMER < t!
  kalibrier& = kalibrier& + 1&
WEND

und dann später
Code:
FOR i& = 1& TO CLNG(zeit! * faktor! * CSNG(kalibrier&))
NEXT i&

Allerdings müsstest Du faktor! als konstanter Wert mit einer Testroutine noch ausfindig machen, z.B. mit
Code:
INPUT "Faktor"; faktor!
zeit! = 10!
t! = TIMER
FOR i& = 1& TO CLNG(zeit! * faktor! * CSNG(kalibrier&))
NEXT i&
t2! = TIMER - t!
PRINT "Probiere Faktor"; faktor! * zeit! / t2!

Wie weit dies jedoch auf jedem Betriebssystem und CPU-Typ (Intel, AMD, Celeron, Pentium II, Pentium III usw.) läuft, kann ich jedoch nicht beurteilen. Aber ich sehe gerade, dass man dieses Problem doch noch recht elegant lösen können müsste, in dem man den zuletzt berechneten und mit PRINT ausgegebenen Wert als definitiven Faktor speichern kann.

Vorsicht jedoch beim Multitasking von Windows, wenn die CPU-Belastung ständig schwankt: Dann kann es durchaus Schwankungen geben! Würde daher diese Methode nur unter reinem MS-DOS 6.22 einsetzen.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 02.10.2004, 19:27    Titel: Antworten mit Zitat

Hm, das bringt mir dann nix. Sowas hat ich mir auch mal ausgedacht, aber nie versucht zu programmieren, einfach mal zu schaun, wie viele Frames der in einem Timer-zyklus abarbeitet, und dann mit diesem Wert den genaueren Timer zu simulieren. Der Wert müsste sich natürlich dann selber nachstellen, das wird dann halt schwierig. Aber das ist dann auch für so ne kleine engine erst mal etwas viel des guten.
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2507
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 02.10.2004, 20:01    Titel: Antworten mit Zitat

Habe gerade davon noch ein kleines Testprogramm geschrieben:

http://beilagen.dreael.ch/QB/MIKROPAU.BAS

Erfahrungen dazu: In einem CMD.EXE unter Windows (XP Prof. in meinem Fall) schwankt es gehörig, während es unter MS-DOS 6.22 einigermassen brauchbar laufen würde. Der korrigierte Faktor wariiert jedoch kräftig; auf einem Pentium II mit 400 MHz bekomme ich 81, auf einem Pentium 4 mit 2,4 GHz sind es 172. In beiden Fällen unter reinem MS-DOS 6.22 gemessen unter Verwendung von QBasic 1.1 (Interpreter-Version).

Falls Deine Ereignisse zeitlich ziemlich gleichförmig aufgebaut sind, würde ich in Deinem Fall dem Tiefpassfilter den Vorzug geben.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 03.10.2004, 11:28    Titel: Antworten mit Zitat

Hallo

Das mit dem zweifachen Überlauf innerhalb eines TIMER-Taktes scheint (welche Überraschung...) irgendein Windowsproblem zu sein. Ich habe es gerade mal unter DOS getestet und da ändert sich der Wert von TIMER schön ordentlich bei JEDEM Registerüberlauf und auch nur dann. Unter XP hatte ich die selben Schwierigkeiten wie du. Es waren sogar Wechsel von TIMER zwischen zwei Überläufen dabei.

@dreael:

In deinem Text steht, die 55 ms Auflösung des TIMERS rühre daher, dass die Zeitbasis pro Stunde 2^16, also 65536 Takte erzeuge. Das ergäbe eine Frequenz von 65536 / 3600 = 18,20444 Hz bzw. eine Periode von 54,93164 ms für den TIMER.

Ich habe aus mehreren Quellen die Angabe, dass - wie oben beschrieben - die Zeitbasis von einem 1,193182 MHz Quarz gesteuert wird, dessen Takt von einem 16-Bit Zähler heruntergeteilt wird. Die Tatsache, dass unter DOS die TIMER-Takte so schön zu den Zählerüberläufen passen, scheint das ja auch zu bestätigen.

Nun ergibt 1193182 / 65536 aber 18,20651 Hz bzw. 54,9254 ms. Diese Werte weichen von denen aus deiner Rechnung zwar nur wenig ab, über einen Zeitraum von 24 Stunden kommt aber schon eine Differenz von fast 10 Sekunden zusammen.

Kannst du das irgendwie aufklären ?

Gruss
Skilltronic
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz