[Anfrage] Möchte Stoppuhr mit USB Button und Eingabeformular programmieren

  • Hey Tuxedo ,

    ich kann dir nicht ganz folgen, bitte erläutere das näher.

    Zitat

    Beim Testen deines Scripts ist mir das merkwürdige Verhalten der Millisekunden in der Zeitanzeige aufgefallen.

    Was ist dir da aufgefallen?

    Zitat

    Das dürfte von den ticks Funktionen stammen.

    meinst du _TicksToTime ??

    damit wird doch nur die Tierzeit in einzelne Bestandteile herunter aufgelöst ?

    Zitat

    Ausserdem wäre zu überdenken ob du für eine Stoppuhr die durch Menschenhand gesteuert wird nicht besser auf die Millisekundenanzeige verzichtest,

    und nur auf Hundertstel genau anzeigst.

    Dies war zu beginn auch meine Überlegung, in einem anderen Thema hatte man mich dann aber belehrt das man das auf 3 Stellen genau macht, daher sind nun 3 Stellen zu sehen.

  • Das Auffällige so genau zu beschreiben ist gar nicht so leicht, ein vergleichsvideo wär perfekt.

    Die linke Stelle der millisekunden ist ja die Zehntelsekunde, und die würde man bei einer realen Stoppuhr schön fortlaufend raufzählen sehen, was bei

    deiner Uhr aber nicht der Fall ist.

    Dieses Verhalten habe ich aber nur bei Verwendung von _TicksToTime

  • Ah Ok, jetzt wies ich was du meinst.

    wenn du in der ziele:

    C
    IF $Status = "Play" and $Status_GUI_Open = "Play" then
        Sleep(44); Aktualisierungsinterval in ms
        _GetTime()  ; Aktuelle Zeit holen

    wenn du die 44 zu einer 10 machst dann ist das der Fall.

    Ich gehe davon aus das das damit zusammen hängt das ich zu langsam Aktualisiere.

    Die Funktion / Makro / Befehl was auch immer da ist _TicksToTime ist nicht die schnellste,

    jedoch gibt dieses teil mir die ms gar nicht aus.

    die anzuzeigenden ms werden hier berechnend:

    C
        $g_iTicks = TimerDiff($g_hTimer) ; Zeitunterschied  zum $g_hTimer =  Startzeit
        $g_iMilliSecs = StringRegExpReplace($g_iTicks, '.+\.(.+)', '\1')  ; MilliSecs ermitteln

    wenn ich mich Irre dann immer raus damit, das sind alles nur Mutmaßungen bei mir.

    Gruß Mücke

  • Weil 1000 Millisekunden einer Sekunde entsprechen, sollte die Anzeige der Millisekunden von 000 bis 999 gehen, denn bei 1000 ist ja schon die nächste Sekunde erreicht.

    Bei mir dauert es etwa 33 Sekunden, um die Funktion _GetTime() 1000000 mal aufzurufen - das sind pro Durchlauf ca. 0.505 ms

    Das merkwürdige Verhalten der Millisekunden in der Zeitanzeige ist bedingt durch den Aktualisierungsinterval. Wenn dieser größer als 1 ms ist, werden einige Werte dadurch einfach übersprungen.

    Setzt man den Aktualisierungsinterval auf <= 1 ms, wäre die Zeitanzeige für die Millisekunden zwar immer korrekt, aber nicht mehr lesbar und würde dann keinen Sinn mehr machen.

    Es gibt also zwei Möglichkeiten: Entweder findet sich einen zufriedenstellenden Wert für den Aktualisierungsinterval (Lesbarkeit/Flackern), oder man lässt die Millisekunden komplett weg, wie es Tuxedo es bereits vorgeschlagen hat.

  • Jetzt fühle ich mich langsam gezwungen 2 Beispiele zu zeigen die Version 1 arbeitet zwar mit 20 ms Aktualisierungsrate und nur bis zur Hundertstel Sekunde und sieht irgendwie runder und flüssiger irgendwie stimmiger aus(was aber auch bei 40ms der Fall wäre).

    Die Version 2 arbeitet wieder mit 40ms Aktualisierungsrate und zeigt komplette Millisekunden an und sieht trotzdem stimmiger aus.

    Hier sieht man trotzdem die Zehntelsekunden hochzählen, was bei der Ursprungsversion mit der _GetTime Funktion eben nicht so ist.

    Muecke ich hoffe du verzeihst mir das neue Design, musst es ja nicht übernehmen(ich finds echt hübsch).

    Sorry, ich habe schon daran gearbeitet als du noch die alte Version gepostet hattest. Wenn du es übernehmen willst,

    musst du die neue Hilfe Funktion mit dem Tooltip wieder einpflanzen.

    Meine geänderten Stellen habe ich mit "Tuxedo kommentiert und meistens die vorherige Zeile als Kopie drin gelassen.

    So kannst du schnell wieder meine Veränderungen rausnehmen.

    Jetzt vergleiche mal deine Version und meine 2 Beispiele(dann müsste dir der Unterschied auffallen,achte besonders auf die Zehntel Sekunden).

    Achja und übrigens könntest du auch zum Anzeigen nur die Hundertstel Sekunden verwenden und trotzdem für die Endberechnung

    die Millisekunden mit einbeziehen wenn das wichtig sein sollte.

    Schönen SonnAbend noch

    Tuxedo

    Hätte fast die Anhänge vergessen


    Nach zahlreichen Testdurchläufen bin ich mir ziemlich sicher, daß die merkwürde Anzeige der Millisekunden von der Funktion TicksToTime

    verursacht wird. Ich dachte erst es liegt eventuell an den vielen schnellen Funktionsaufrufgen von _GetTime(), was aber nicht der Fall ist.

    Ebenso die Vermutung von Bitnugger , daß es vom Aktualisierungsinterval (das 44ms Sleep) stammt hat sich bei mir nicht bestätigt.

    Ich kann von 1 ms bis 100 ms durchgehen und habe nie das selbe merkwürdige Verhalten, nur bei zu kurzen Timings setzt die Anzeige der Millisekunden gelegentlich aus (wird schwarz) was aber bei einem Sleep von 1 bis 5 Millisekunden kein Wunder darstellt.

    Ich hab es jetzt mit einer neu gebauten _GetTime Funktion versucht und die Zehntelsekunden laufen wunderbar weich durch,

    wie es sich gehört. Bei den restlichen 2 Stellen kann ich es Mangels (meines Gehirn+Augen Speeds) nicht mehr beurteilen.

    Ohne TicksToTime Funktion ist das Ergebnis auf jeden Fall besser.

    SChönen Wochenbeginn wünscht

    Tuxedo

  • Ohne TicksToTime Funktion ist das Ergebnis auf jeden Fall besser.

    Hilf mir mal bitte auf die Sprünge... denn ich stehe gerade auf dem Schlauch!

    _TicksToTime wird doch auf jeden Fall benötigt, um die Ticks in Stunden, Minuten, Sekunden und Millisekunden umzurechnen... wobei die Millisekunden optional sind.

    Was also soll an einem Ergebnis ohne _TicksToTime besser sein, wenn dann keine Stunden, Minuten, Sekunden und Millisekunden mehr berechnet werden, um sie anzuzeigen?

    Ebenso die Vermutung von Bitnugger , daß es vom Aktualisierungsinterval (das 44ms Sleep) stammt hat sich bei mir nicht bestätigt.

    Das ist keine Vermutung, sondern einfache Mathematik...

    • Wenn ich nur alle 44 ms aktualisiere, kann ich nicht gleichzeitig eine "Anzeige der Millisekunden in Echtzeit" erwarten!
    • Wenn ich alle 1 ms aktualisiere, ist die Anzeige der Millisekunden nicht mehr lesbar, weil das menschliche Auge (und womöglich auch der Monitor) zu träge dafür ist.

    Ich hatte doch geschrieben, dass die Funktion _GetTime(), die ohne _TicksToTime keinen Sinn macht, pro Durchlauf ca. 0.505 ms benötigt... daran kann es also keinesfalls liegen, wenn irgendwas mit der Anzeige nicht stimmt!

  • Wenn das so stimmt wie du behauptest Bitnugger, dann überspringt das originale Script von Muecke bei mir aber nicht nur ein paar Millisekunden sondern über 900 ms. Und das halte ich für ausgeschlossen. Denn bei mir bleibt die Zehntelsekunde beim Start von Muecke's Script mehre Sekunden im selben Bereich stehen z.B. 5?? 5?? 5?? 4?? 6?? 5?? 3?? 5??. So oder ähnlich sieht das bei mir immer aus. Ohne TicksToTime habe ich den Effekt eben nicht. Dann kommt 1?? 2?? 3?? 4?? 5?? 6?? 7?? 8?? 9?? 0??, so wie man es eben erwarten würde.

    Siehst du jetzt klarer? Wenn nicht brauchs du vielleicht eine Brille?^^

    Und ja es geht sehr wohl ohne TicksToTime auf eine Zeit umzurechnen, man kann sich das Ergebnis von Timerdiff ja auch

    selbst in Stunden Minuten Sekunden und Millisekunden zersägen. TickstoTime tut ja auch nix anders, nur eben nicht auf optimale Art.


    Edit: Ich hätte jetzt ein Video-Sample mit ca 3,3MB wohin könnte ich das uploade, damit mans hier verlinken könnte?

    In diesem Video sieht man den Effekt sehr gut.

    Einmal editiert, zuletzt von Tuxedo (3. Dezember 2018 um 10:21)

  • Bitnugger und Tuxedo !

    Wenn das so stimmt wie du behauptest Bitnugger, dann überspringt das originale Script von Muecke bei mir aber nicht nur ein paar Millisekunden sondern über 900 ms. Und das halte ich für ausgeschlossen. Denn bei mir bleibt die Zehntelsekunde beim Start von Muecke's Script mehre Sekunden im selben Bereich stehen z.B. 5?? 5?? 5?? 4?? 6?? 5?? 3?? 5??. So oder ähnlich sieht das bei mir immer aus. Ohne TicksToTime habe ich den Effekt eben nicht. Dann kommt 1?? 2?? 3?? 4?? 5?? 6?? 7?? 8?? 9?? 0??, so wie man es eben erwarten würde.

    Siehst du jetzt klarer? Wenn nicht brauchs du vielleicht eine Brille? ^^

    Keinen Streit bitte :P

    Bitnugger hat bzgl. _TicksToTime völlig recht, was die mathematischen Aspekte anbelangt !

    Tuxedo hat recht, was die optische Erscheinung anbelangt.

    Das Problem ist meiner Meinung nach nicht TicksToTime sondern :

    Func _GetTime()

    $g_iMilliSecs = StringRegExpReplace($g_iTicks, '.+\.(.+)', '\1') ; MilliSecs ermitteln

    StringRegExpReplace scheint hier der Zeitfresser zu sein.

    Ersetzt im Originalskript von Bitnugger diese Zeile mal durch :

    $g_iMilliSecs = StringRight(Int($g_iTicks),3)

    Dann läuft es bei mir flüssig !

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

    Einmal editiert, zuletzt von Musashi (3. Dezember 2018 um 10:43)

  • Der Nagel ist sowas von Tod, das war Goldrichtig(Nagel auf Kopmitte und so...)

    Dann hat wohl die RegexReplace Zeile auf meinem Rechner wirklich eine ca. Sekunde gebraucht, das ist ja verrückt.

    Naja eventuell liegts ja auch an meinem PC ein bisschen(ein alter Core 2 Duo P8400, aber ein stabiler alter Hase.)

    Hätte nicht gedacht, daß Regex so langsam ist. Wenngleich es mir merkwürdig vorkam hier Regex zu verwenden statt einfach

    die 3 rechten Zeichen zu holen wie in deinem Tipp.

    Und zum Streit, von mir aus gibts keinen Streit, ich habe immer noch beste Laune keine Sorge.

    Ich denke doch Bitnugger hat damit auch kein Problem, hoffe ich zumindest.

    Danke Musahi, jetzt sind wir alle wieder ein bisschen schlauer.

    Einmal editiert, zuletzt von Tuxedo (3. Dezember 2018 um 13:32)

  • Hätte nicht gedacht, daß Regex so langsam ist. Wenngleich es mir merkwürdig vorkam hier Regex zu verwenden statt einfach die rechten 3

    wie in deinem Tipp jetzt.

    Ist zwar ein wenig OT aber mit Regex schießt du hier mit Kanonen auf Spatzen.

    Wenn du immer dreistellige Nachkommazahlen hast kannst du die Stringfunktionen verwenden, das ist wesentlich schneller, da der Interpreter nicht erst die RegEx-Maschine anschmeißen und alles in deinem Pattern durchparsen muss. Auch bei Zahlen ohne drei Nachkommastellen kannst du mit StringInStr nach dem Dezimalkomma suchen und ab dort abschneiden, wäre auch viel schneller.

  • Hey miteinander,

    erst mal finde ich es bewundernswert wie Ihr euch hier mit der Stoppuhr beschäftigt.

    ich habe min meiner Version die Zeile wie von Musashi gezeigt geändert:

    ALT:

    $g_iMilliSecs = StringRegExpReplace($g_iTicks, '.+\.(.+)', '\1') ; MilliSecs ermitteln

    NEU:

    $g_iMilliSecs = StringRight(Int($g_iTicks),3)


    Das Bild das Tuxedo beschreibt das eine oder auch zwei zelten Sekunde immer deutlich zu sehen sind habe ich bei mir auch wenn die Pause zu lange wird.

    Ehrlich gesagt sehe ich keinen großen unterschied zwischen den beiden Versionen von Musashi Wenn das jedoch schneller ist, nehme ich das, das auch auf einem Anderen Rechner das nicht so auffällig wird.

    Im Anhang hab ich noch mal das Script von mir, da ich noch ein paar kleine Bugs gefunden habe (Kopierfehler z.B. die Hintergrundfarbe habe ich vergessen umzuschreiben etc.)

    Am Formular bin ich gerade noch dran, wird aber auch schon sehr gut, jedoch nutze ich nicht den Formular Generator, sobald das Formular fertig ist und gespeichert werden kann werde ich auch das Script noch mal hochladen.


    Gruß Mücke

  • 'Schneller' ist bei einer Zeitmessung ggf. der falsche Ausdruck :P. Wenn Du genau hinschaust, dann müsstest Du den Unterschied bei den Zehntelsekunden sehen. In der Version NEU: zählen diese kontinuierlich von 0...9 durch.

    Bei ALT: sprangen sie doch recht wild herum.

    Grund dafür war nicht die Funktion TicksToTime (aus Func _GetTime() ), sondern der Zeitverbrauch beim Ausführen von StringRegExpReplace (siehe meinen Beitrag #29).

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Ersetzt im Originalskript von Bitnugger diese Zeile mal durch :

    $g_iMilliSecs = StringRight(Int($g_iTicks),3)

    Hihi... echt jetzt?

    Das funktioniert so aber mal gar nicht... denn mit Int() bekommst du ja nur die Ziffern vor dem Punkt... gebraucht werden aber die hinter dem Punkt?!

    $g_iTicks = 0.009

    $g_iTicks = 221.8233

    $g_iTicks = 805.0881

    $g_iTicks = 1029.0668

    $g_iTicks = 1077.171

    $g_iTicks = 1130.1266

    ...

    Das Problem dabei ist, dass die Stellen vor dem Punkt variieren... wenn nicht mit StringRegExpReplace(), dann fallen mir nur zwei Lösungen ein, wie man das gescheit lösen könnte... doch einen Gewinn bringen die nicht!

    Code
    Benötigte Zeit, um die Funktion _GetTime() 1000000 mal aufzurufen:
    
    $g_iMilliSecs = StringRegExpReplace($g_iTicks, '.+\.(.+)', '\1')           ; 33 Sekunden - so wie es aktuell im Script verwendet wird!
    $g_iMilliSecs = StringMid($g_iTicks, StringInStr($g_iTicks, '.') +1, 3)    ; 36 Sekunden
    $g_iMilliSecs = StringMid($g_iTicks, StringInStr($g_iTicks, '.') +1)       ; 35 Sekunden
    $g_iMilliSecs = StringTrimLeft($g_iTicks, StringInStr($g_iTicks, '.'))     ; 34 Sekunden

    Ich denke doch Bitnugger hat damit auch kein Problem, hoffe ich zumindest.

    Warum sollte ich? Bin ja schließlich nicht aus Watte... 8)

  • Was ist mit der Sicht von Musashi und

    Grüße autoiter

  • Musashi

    Arrrg... ok, habe mich soeben klug gemacht!

    Die Stellen bei $g_iTicks hinter dem Punkt sind Mikrosekunden - was wir brauchen, sind aber die Millisekunden... und ja, die stehen vor dem Punkt. Tja, irren ist menschlich!

    Dann kann man das natürlich besser so machen...

    $g_iMilliSecs = Int(Mod($g_iTicks, 1000)) ; 29 Sekunden für 1000000 Durchläufe

    Oscar

    Int() ist nötig, weil wir ja keine Zahl mit Nachkommastellen wollen.

    Return StringLeft($sTest, StringInStr($sTest, ".") + $iNachkommastellen)

    Die Nachkommastellen sollten in der Funktion _GetTime() nicht direkt in $g_iMilliSecs gespeichert werden, da sie evtl. noch für andere Berechnungen gebraucht werden könnten.

    Um sie 3-stellig im Label darzustellen, würde ich es wie gehabt vorziehen:

    GUICtrlSetData($idLabelMilli, StringFormat('%03i', StringLeft($g_iMilliSecs, 3)))

  • @Musashi

    Arrrg... ok, habe mich soeben klug gemacht!

    ...

    Tja, irren ist menschlich!

    Du hast vor kurzem in der SB ja noch Nietzsche zitiert - Da Gott (laut Nietzsche) tot ist, und wir keine Götter, sollte das also kein Problem sein :P.

    Muecke :

    Ich hoffe, die ganze Diskussion wird für Dich nicht zu verwirrend. Manchmal entwickelt ein Thread eine gewisse Eigendynamik;)

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

    Einmal editiert, zuletzt von Musashi (3. Dezember 2018 um 20:00)

  • Ich habe das jetzt nicht komplett verfolgt, aber hattet ihr nicht Stringformat für die Ausgabe benutzt?

    Ja, das ist schon richtig, aber wenn ich die Stunden, Minuten und Sekunden ganzzahlig speichere, warum sollte ich es bei den Millisekunden dann anders haben wollen?