Stoppuhr im hundertstel bereich

  • Hallo

    Ich bin im Forum auf diesen Quellcode gestoßen:

    [autoit]


    #include <WindowsConstants.au3>
    #include <Date.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $Start = False, $Timer = 0, $tmpTimer = 0, $LastTimer = 0
    Dim $iHours = 0, $iMins = 0, $iSecs = 0, $iHsecs = 0

    [/autoit][autoit][/autoit][autoit]

    Opt("GUIOnEventMode",1) ;Enable Interrupts for GUI
    $GUI = GUICreate("Stoppuhr", 325, 126, 214, 139, 0x00080000, 0x00000008) ;Create GUI with Topmost ID
    $Stoppuhr = GUICtrlCreateLabel("Stoppuhr", 8, 8, 135, 41)
    GUICtrlSetFont(-1, 26, 400, 0, "Arial")
    $Zeit = GUICtrlCreateLabel("00:00:00.00", 8, 56, 178, 41)
    GUICtrlSetFont(-1, 26, 400, 0, "Arial")
    GUICtrlSetColor(-1, 0xFF0000)
    $StartStopp = GUICtrlCreateButton("Start", 225, 8, 89, 41, $WS_GROUP)
    GUICtrlSetFont(-1, 16, 400, 0, "Arial")
    $Reset = GUICtrlCreateButton("Reset", 225, 56, 89, 41, $WS_GROUP)
    GUICtrlSetFont(-1, 16, 400, 0, "Arial")

    [/autoit][autoit][/autoit][autoit]

    GUICtrlSetOnEvent($StartStopp, "StartStopp") ;Create events for Buttons
    GUICtrlSetOnEvent($Reset, "Reset")
    GUISetOnEvent(-3, "End") ;Create Event for {ESC} and Close
    GUISetState(@SW_SHOW) ;Show GUI

    [/autoit][autoit][/autoit][autoit]

    While Sleep(50) ;Main Loop
    If $Start Then ;Only if start is pressed....
    $tmpTimer = (TimerDiff($Timer)) + $LastTimer
    Convert() ;Convert ticks to time and splitt it into HH:MM:SS.hh
    GUICtrlSetData($Zeit, $iHours & ":" & $iMins & ":" &$iSecs & "." & $iHsecs) ;Update GUI
    EndIf
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Func StartStopp() ;Interrupt for start/stop buttons
    If $Start Then ;Stop button pressed
    GUICtrlSetData($StartStopp, "Start") ;Change button text
    $tmpTimer = (TimerDiff($Timer)) + $LastTimer
    $LastTimer = $tmpTimer
    $Start = False
    Convert() ;Convert ticks to time and splitt it into HH:MM:SS.hh
    GUICtrlSetData($Zeit, $iHours & ":" & $iMins & ":" &$iSecs & "." & $iHsecs) ;Update GUI
    Else
    GUICtrlSetData($StartStopp, "Stopp") ;Start button pressed
    $Start = True
    $Timer = TimerInit()
    EndIf
    EndFunc ;==>StartStopp

    [/autoit][autoit][/autoit][autoit]

    Func Reset() ;Resets GUI
    GUICtrlSetData($Zeit, "00:00:00.00")
    $LastTimer = 0
    $Timer = TimerInit()
    EndFunc ;==>Reset

    [/autoit][autoit][/autoit][autoit]

    Func Convert() ;Convert ticks to time and splitt it into HH:MM:SS.hh
    _TicksToTime($tmpTimer, $iHours, $iMins, $iSecs)
    $iHsecs = Round(($tmpTimer - (($iHours * 3600000) + ($iMins * 60000) + ($iSecs * 1000))) / 10)
    If $iHours < 10 Then $iHours = "0" & $iHours
    If $iMins < 10 Then $iMins = "0" & $iMins
    If $iSecs < 10 Then $iSecs = "0" & $iSecs
    If $iHsecs < 10 Then $iHsecs = "0" & $iHsecs
    EndFunc ;==>Convert

    [/autoit][autoit][/autoit][autoit]

    Func End() ;Exit
    Exit
    EndFunc ;==>End

    [/autoit]

    Allerdings ist diese Stoppuhr für mich zu ungenau, da die Zeit alle 10 millisekunden übersprungen wird.
    Ich möchte das alle Zahlen im hundertstel Bereich angezeigt werden, bevor man auf die Stopptaste drückt.

    Ich weiß für euch Profis ist so etwas einfach, aber ich tue mich damit schwer. :D

    Wie kriegt man nochmal das ganze transparent , so das man nur den text sieht?

    Einmal editiert, zuletzt von Daniel35 (15. November 2010 um 17:43)

  • Ich habe jetzt den Wert auf 1 geändert

    [autoit]


    While Sleep(1) ;Main Loop

    [/autoit]

    Die Zahlen springen jetzt alle 3 hundertstel Sekunden.
    Kann man die Differenz noch weiter veringern?

  • Die Zahlen springen jetzt alle 3 hundertstel Sekunden.

    Kein Mensch kann so schnell schauen, was bist du :?:;)

    Kann man die Differenz noch weiter veringern?

    Jein,

    • ein Sleep(10) ist der kleinste Sleepwert der eingesetzt werden kann, kleinere Werte werden als 10 interpretiert.
    • du kannst aber anstelle von [autoit]While Sleep(10) ;Main Loop
      [/autoit][autoit]While 1 ;Main Loop[/autoit]
      verwenden. Nachteil Anzeige flackert und die CPU-Auslastung geht für einen Kern auf 100% und eventuell wird dadurch der Event für die Func StartStop etwas verzögert ausgelöst

    Ja, mit AdlibRegister:

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <Date.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $Start = False, $Timer = 0, $tmpTimer = 0, $LastTimer = 0
    Dim $iHours = 0, $iMins = 0, $iSecs = 0, $iHsecs = 0

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode",1) ;Enable Interrupts for GUI
    $GUI = GUICreate("Stoppuhr", 325, 126, 214, 139, 0x00080000, 0x00000008) ;Create GUI with Topmost ID
    $Stoppuhr = GUICtrlCreateLabel("Stoppuhr", 8, 8, 135, 41)
    GUICtrlSetFont(-1, 26, 400, 0, "Arial")
    $Zeit = GUICtrlCreateLabel("00:00:00.00", 8, 56, 178, 41)
    GUICtrlSetFont(-1, 26, 400, 0, "Arial")
    GUICtrlSetColor(-1, 0xFF0000)
    $StartStopp = GUICtrlCreateButton("Start", 225, 8, 89, 41, $WS_GROUP)
    GUICtrlSetFont(-1, 16, 400, 0, "Arial")
    $Reset = GUICtrlCreateButton("Reset", 225, 56, 89, 41, $WS_GROUP)
    GUICtrlSetFont(-1, 16, 400, 0, "Arial")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetOnEvent($StartStopp, "StartStopp") ;Create events for Buttons
    GUICtrlSetOnEvent($Reset, "Reset")
    GUISetOnEvent(-3, "End") ;Create Event for {ESC} and Close
    GUISetState(@SW_SHOW) ;Show GUI

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_Show",2)

    [/autoit] [autoit][/autoit] [autoit]

    While 1 ;Main Loop
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Show()
    If $Start Then ;Only if start is pressed....
    $tmpTimer = (TimerDiff($Timer)) + $LastTimer
    Convert() ;Convert ticks to time and splitt it into HH:MM:SS.hh
    GUICtrlSetData($Zeit, $iHours & ":" & $iMins & ":" &$iSecs & "." & $iHsecs) ;Update GUI
    ConsoleWrite($iHours & ":" & $iMins & ":" &$iSecs & "." & $iHsecs & @CRLF) ;schreibt zur Kontrole in die console
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func StartStopp() ;Interrupt for start/stop buttons
    If $Start Then ;Stop button pressed
    GUICtrlSetData($StartStopp, "Start") ;Change button text
    $tmpTimer = (TimerDiff($Timer)) + $LastTimer
    $LastTimer = $tmpTimer
    $Start = False
    Convert() ;Convert ticks to time and splitt it into HH:MM:SS.hh
    GUICtrlSetData($Zeit, $iHours & ":" & $iMins & ":" &$iSecs & "." & $iHsecs) ;Update GUI
    Else
    GUICtrlSetData($StartStopp, "Stopp") ;Start button pressed
    $Start = True
    $Timer = TimerInit()
    EndIf
    EndFunc ;==>StartStopp

    [/autoit] [autoit][/autoit] [autoit]

    Func Reset() ;Resets GUI
    GUICtrlSetData($Zeit, "00:00:00.00")
    $LastTimer = 0
    $Timer = TimerInit()
    EndFunc ;==>Reset

    [/autoit] [autoit][/autoit] [autoit]

    Func Convert() ;Convert ticks to time and splitt it into HH:MM:SS.hh
    _TicksToTime($tmpTimer, $iHours, $iMins, $iSecs)
    $iHsecs = Round(($tmpTimer - (($iHours * 3600000) + ($iMins * 60000) + ($iSecs * 1000))) / 10)
    If $iHours < 10 Then $iHours = "0" & $iHours
    If $iMins < 10 Then $iMins = "0" & $iMins
    If $iSecs < 10 Then $iSecs = "0" & $iSecs
    If $iHsecs < 10 Then $iHsecs = "0" & $iHsecs
    EndFunc ;==>Convert

    [/autoit] [autoit][/autoit] [autoit]

    Func End() ;Exit
    Exit
    EndFunc ;==>End

    [/autoit]

    mfg autoBert

    2 Mal editiert, zuletzt von autoBert (14. November 2010 um 15:50)

  • Hi AutoBert

    Ich habe dein neues Programm ausprobiert, und die Anzeige flackert ein wenig. Die Zahlen blieben im 3 hundertstel Bereich.
    Zu dem Zitat:

    Zitat

    Kein Mensch kann so schnell schauen, was bist du :?: ;)

    Ich habe HyperCam2 (Desktop Capture Programm) benutzt um das ganze zu testen.

    Keine Ahnung, vielleicht brauche ich ein HighEnd PC um auf die hunderstel Sekunde genau zu kommen.

  • Jetzt überleg mal was so eine Grafikkarte als Bildfrequenz (nicht Bildwiederholrate!) raushaut und überlege dann nochmal in Ruhe warum es vielleicht unwahrscheinlich sein könnte auf 10ms zu kommen....
    Da sind noch nichtmal die Verzögerungseffekte z.B. durch den AutoIt-Interpreter mit berücksichtigt.

    Einmal editiert, zuletzt von AspirinJunkie (14. November 2010 um 17:26)

  • Ich habe dein neues Programm ausprobiert, und die Anzeige flackert ein wenig. Die Zahlen blieben im 3 hundertstel Bereich.

    Das flackern kannst du verringern, indem du die Zeitanzeige in einzelne Segmente aufteilst und nur bei Veränderung eines Segments updatest. Ich bezweifle das dein Capture-Programm auf deinem System wirklich 100 Bilder pro Sec. machen kann, denn in meinem Test mit Adlib habe ich eine Consolenausgabe in dieser wird jede hundertstel mindestens 1 mal angezeigt. Das ganze auf einem NetBook mit Atom-Prozessor, welche ja nicht für ihre Schnelligkeit berühmt sind,

    mfg autoBert

    • Offizieller Beitrag

    Hier mal eine Stoppuhr mit einzelnen Segmenten und Start/Pause/Stopp:

    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    Opt('GUIOnEventMode', 1)

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate('Stoppuhr', 200, 100)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
    Global $ahTime[4], $aOld[4], $iTimer, $fPause = False
    For $i = 0 To 3
    $ahTime[$i] = GUICtrlCreateLabel(StringFormat('%0' & 2 + Number($i = 3) & 'i', 0), 40 + $i * 30, 20, 30, 20)
    GUICtrlSetFont(-1, 14, 400, 0, 'Tahoma', 5)
    If $i < 3 Then
    GUICtrlCreateLabel(':', 62 + $i * 30, 20, 10, 20)
    GUICtrlSetFont(-1, 14, 400, 0, 'Tahoma', 5)
    EndIf
    Next
    $hStart = GUICtrlCreateButton('Start', 10, 60, 50, 25)
    GUICtrlSetOnEvent(-1, '_Start')
    $hPause = GUICtrlCreateButton('Pause', 70, 60, 50, 25)
    GUICtrlSetOnEvent(-1, '_Pause')
    GUICtrlSetState(-1, $GUI_DISABLE)
    $hStopp = GUICtrlCreateButton('Stopp', 130, 60, 50, 25)
    GUICtrlSetOnEvent(-1, '_Stopp')
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(1000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _End()
    Exit
    EndFunc ;==>_End

    [/autoit] [autoit][/autoit] [autoit]

    Func _Start()
    GUICtrlSetState($hStart, $GUI_DISABLE)
    GUICtrlSetState($hStopp, $GUI_ENABLE)
    GUICtrlSetState($hPause, $GUI_ENABLE)
    $iTimer = TimerInit()
    AdlibRegister('_ShowTime', 10)
    EndFunc ;==>_Start

    [/autoit] [autoit][/autoit] [autoit]

    Func _Pause()
    $fPause = Not $fPause
    Switch $fPause
    Case True
    AdlibUnRegister('_ShowTime')
    GUICtrlSetData($hPause, 'Weiter')
    Case False
    AdlibRegister('_ShowTime', 10)
    GUICtrlSetData($hPause, 'Pause')
    EndSwitch
    EndFunc ;==>_Pause

    [/autoit] [autoit][/autoit] [autoit]

    Func _Stopp()
    AdlibUnRegister('_ShowTime')
    _ShowTime()
    GUICtrlSetState($hStart, $GUI_ENABLE)
    GUICtrlSetState($hStopp, $GUI_DISABLE)
    GUICtrlSetState($hPause, $GUI_DISABLE)
    EndFunc ;==>_Stopp

    [/autoit] [autoit][/autoit] [autoit]

    Func _ShowTime()
    Local $aTime[4], $iTicks = TimerDiff($iTimer)
    $aTime[2] = Int($iTicks / 1000)
    $aTime[3] = Int($iTicks - $aTime[2] * 1000)
    $aTime[0] = Int($aTime[2] / 3600)
    $aTime[2] = Mod($aTime[2], 3600)
    $aTime[1] = Int($aTime[2] / 60)
    $aTime[2] = Mod($aTime[2], 60)
    For $i = 0 To 3
    If $aTime[$i] <> $aOld[$i] Then GUICtrlSetData($ahTime[$i], StringRight('00' & $aTime[$i], 2 + Number($i = 3)))
    Next
    $aOld = $aTime
    EndFunc ;==>_ShowTime

    [/autoit]

    Aber eine AdlibZeit von kleiner als 10 halte ich auch für schlecht, weil die _ShowTime-Funktion schon einige Millisekunden (je nach Rechner) benötigt.

  • Welche Programme hast du für dein test verwendet Autobert?

    Wie hast du es geschafft das jede hundertstel mindestens 1 mal angezeigt wird?

    Mach mich nicht neugierig :D

  • Hallo Daniel35,

    ich habe eine Ausgabe in die Scite-Konsole integriert:

    [autoit]

    ConsoleWrite($iHours & ":" & $iMins & ":" &$iSecs & "." & $iHsecs & @CRLF) ;schreibt zur Kontrole in die console

    [/autoit]

    und dann das Skript mit F5 gestartet. In der Konsolenausgabe von Scite standen danach alle hundertsel Sekunden mindetens 1 mal (die meisten öfter). Die Ausgabe in der GUI kannst du damit natürlich nicht kontrollieren, aber ich wollte testen ob AdLib-Funktionen einen kleineren Wert als 10 ms haben können,

    mfg autoBert

  • Hallo,

    auf den mir zur Verfügung stehenden 3 Rechnern wird die AdlibRegister-Funktion mit einem minimalen Abstand von 15/16 ms aufgerufen. MSDN spricht allerdings von 10 ms:

    Zitat

    If uElapse is less than USER_TIMER_MINIMUM (0x0000000A), the timeout is set to USER_TIMER_MINIMUM. If uElapse is greater than USER_TIMER_MAXIMUM (0x7FFFFFFF), the timeout is set to USER_TIMER_MAXIMUM.

  • @Großvater,

    ich habe es extra getestet, da ich auch erwartet hatte nicht unter 10 ms zu kommen, hier die Konsolenausgabe dazu:

    Spoiler anzeigen

    Skript ist weiter oben.

    mfg autoBert

  • autoBert,

    ich habe es auch getestet und hier ist meine Konsolenausgabe:

    Spoiler anzeigen

    00:00:00.01
    00:00:00.03
    00:00:00.05
    00:00:00.06
    00:00:00.08
    00:00:00.10
    00:00:00.11
    00:00:00.12
    00:00:00.14
    00:00:00.15
    00:00:00.17
    00:00:00.19
    00:00:00.20
    00:00:00.22
    00:00:00.23
    00:00:00.25
    00:00:00.26
    00:00:00.28
    00:00:00.30
    00:00:00.31
    00:00:00.33
    00:00:00.34
    00:00:00.36
    00:00:00.37
    00:00:00.39
    00:00:00.40
    00:00:00.42
    00:00:00.44
    00:00:00.45
    00:00:00.47
    00:00:00.48
    00:00:00.50
    00:00:00.51
    00:00:00.53
    00:00:00.55
    00:00:00.56
    00:00:00.58
    00:00:00.59
    00:00:00.61
    00:00:00.62
    00:00:00.64
    00:00:00.66
    00:00:00.67
    00:00:00.69
    00:00:00.70
    00:00:00.72
    00:00:00.73
    00:00:00.75
    00:00:00.76
    00:00:00.78
    00:00:00.80
    00:00:00.81
    00:00:00.83
    00:00:00.84
    00:00:00.86
    00:00:00.87
    00:00:00.89
    00:00:00.91
    00:00:00.92
    00:00:00.94
    00:00:00.95
    00:00:00.97
    00:00:00.98
    00:00:00.100


    Die Ergenisse unter XP Pro SP3 und Vista Home Premium sind nahezu identisch.

  • @Grossvater: setze die ms auf 5 oder 10, denn bei mir sind die Werte mit 1 ms schlechter als mit 2.

    @Fr34k: nur nicht übertreiben, den im Skript sind 2 ms eingestellt also 5* wäre optimal, selbst wenn du auf 1 ms heruntergegangen bist sind es <= 10

    denke aber, für exakte Timings gibt es bessere Sprachen

    @Threadersteller setze bitte das Thema auf gelöst,

    mfg autoBert