Exakter Timer

Anfängerfragen zum Programmieren mit PureBasic.
pede
Beiträge: 90
Registriert: 08.07.2007 20:37
Wohnort: brixen / Italien

Exakter Timer

Beitrag von pede »

Hallo

Ich möchte einen auf die Hundertstel Sekunde exate Stoppuhr programmieren.

Soweit mein Code:

Code: Alles auswählen

Enumeration 
    #window_main
    #text_m ;minuten
    #text_s ;sekunden
    #text_c ;hundertstel
    #frame_m
    #frame_s
    #frame_c
    
    #font_stopper
EndEnumeration

SetPriorityClass_(GetCurrentProcess_(),#HIGH_PRIORITY_CLASS)

LoadFont(#font_stopper, "Arial", 40, #PB_Font_Bold)

Global minuten = 0
Global sekunden = 0
Global hundertstel = 0

Procedure Open_window_main()
    OpenWindow(#window_main, #PB_Ignore, #PB_Ignore, 400, 200, "Cube Stopper ", #PB_Window_SystemMenu)
    CreateGadgetList(WindowID(#window_main))
    
    Frame3DGadget(#frame_m, 25, 25, 100, 100, "Minuten")
    TextGadget(#text_m, 45, 45, 60, 60, "00")
    SetGadgetFont(#text_m, FontID(#font_stopper))

    Frame3DGadget(#frame_s, 145, 25, 100, 100, "Sekunden")
    TextGadget(#text_s, 165, 45, 60, 60, "00")
    SetGadgetFont(#text_s, FontID(#font_stopper))

    Frame3DGadget(#frame_c, 265, 25, 100, 100, "Hundertstel")
    TextGadget(#text_c, 285, 45, 60, 60, "00")
    SetGadgetFont(#text_c, FontID(#font_stopper))

EndProcedure

Procedure timer(hwnd, uMsg, idEvent, dwEvent)
    Shared minuten
    Shared sekunden
    Shared hundertstel
    hundertstel = hundertstel + 1
    If hundertstel > 9 
        hundertstel = 0
        sekunden = sekunden + 1
        If sekunden > 59
            sekunden = 0
            minuten = minuten + 1
        EndIf
    EndIf
    
    sekunden$ = Str(sekunden)
    minuten$ = Str(minuten)
    hundertstel$ = Str(hundertstel)
    
    SetGadgetText(#text_c, hundertstel$)
    SetGadgetText(#text_m, minuten$)
    SetGadgetText(#text_s, sekunden$)      
    
EndProcedure

Open_Window_main()

hwnd = WindowID(#window_main)
timer = SetTimer_(hwnd, 1, 100, @timer())
ende = 0

Repeat
    event = WaitWindowEvent(10)
    Select Event
        Case #PB_Event_CloseWindow
            ende = 1
    EndSelect
Until ende = 1 
Das Problem ist, dass das Programm alles andere als genau funktioniert.
Auf 20 Sekunden geht die "Stoppuhr" ca. 1 Sekunde nach...

kann ich das irgendwie vermeiden?

Danke für die Hilfe
lg
"oh... ein Sarkasmus-Detektor... ein wirklich nützliches Gerät" .. dit.. dit.. ditditdit.. *bumm*
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Ruf doch einfach immer die aktuelle Zeit ab und stelle diese dar. Dafür sind die Timer ja da, und die stimmen dann auch :)

Wenn Du einfach nur Ganzzahlen aufsummierst, ist es klar, daß irgendwann Abweichungen auftreten.
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

ZeHa hat geschrieben:Ruf doch einfach immer die aktuelle Zeit ab und stelle diese dar. Dafür sind die Timer ja da, und die stimmen dann auch :)
Wenn man dafür die Date() Funktion nimmt... wie bastel ich denn aus dieser Zahl die Hundertstel ? Es sind ja "nur" Sekunden
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Deluxe0321
Beiträge: 336
Registriert: 19.05.2006 00:31
Kontaktdaten:

Beitrag von Deluxe0321 »

vll. gettickcount_()? Verwende ich zumindest immer um Timer im Millisekundenbereich zu erstellen.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

...oder timeGetTime_() oder ElapsedMilliSeconds() ;)

Da kriegst Du Tausendstel-Sekunden, brauchst also bloß durch 10 zu teilen :)
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
pede
Beiträge: 90
Registriert: 08.07.2007 20:37
Wohnort: brixen / Italien

Beitrag von pede »

Danke erstmal für die ganzen Antworten.

Wie in meinem Beispiel oben, möchte ich jedoch, dass die zeitliche Änderung dargestellt wird, wie bei einer Stoppuhr...

Und genau deswegen habe ich auch eine Timerprocedure verwendet...

Bei der graphischen Darstellung versagt auch ElapseMilliseconds(), oder?
Bisonte hat geschrieben:Wenn man dafür die Date() Funktion nimmt... wie bastel ich denn aus dieser Zahl die Hundertstel ? Es sind ja "nur" Sekunden
genau deswegen habe ich auch einen anderen Ansatz gewählt...
"oh... ein Sarkasmus-Detektor... ein wirklich nützliches Gerät" .. dit.. dit.. ditditdit.. *bumm*
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

ElapseMilliseconds() liefert Dir die Zeit in Millisekunden, seit der Rechner eingeschalten wurde. Also rufst Du beim Starten der Uhr die Funktion auf und speicherst den Wert z.B. als startTime.

Nun brauchst Du nur in Deiner Hauptschleife ständig die neue Zeit abzufragen und von dieser die startTime abziehen. Schon hast Du die vergangene Zeit. Diese kannst Du dann entsprechend divideren um auf Deine unterschiedlichen Angaben zu kommen, z.B. so:

Code: Alles auswählen

startTime = ElapsedMilliseconds()

Repeat
    time = ElapsedMilliseconds() - startTime

    centiseconds = (time / 10) % 100
    seconds = (time / 1000) % 60
    minutes = (time / 60000) % 60
    hours = (time / 3600000) % 60

    ; hier kommt dann der Code hin, wo Du die Zahlen auf die entsprechenden Felder setzt

    WindowEvent()
    Delay(0) ; keine Ahnung ob das was bringt, das sollen andere hier beantworten
Forever
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hab den Code von Zeha mal etwas Systemfreundlicher gestaltet :wink:

Code: Alles auswählen

EnableExplicit

Global Time.l

Procedure timerCB(hwnd, uMsg, idEvent, dwEvent)
  Static NewTime.l
  Protected hours.l, minutes.l, seconds.l, centiseconds.l, zeit.s
 
  If NewTime <> Time
    NewTime = ElapsedMilliseconds() - Time
    centiseconds = (NewTime / 10) % 100
    seconds = (NewTime / 1000) % 60
    minutes = (NewTime / 60000) % 60
    hours = (NewTime / 3600000) % 60
   
    zeit = RSet(Str(hours), 2, "0") + ":" + RSet(Str(minutes), 2, "0") + ":" + RSet(Str(seconds), 2, "0") + "::" + RSet(Str(centiseconds), 3, "0")
    SetWindowTitle(0, zeit)
  EndIf
EndProcedure

Procedure Main()
 
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 190, 50, "00:00:00::000", #PB_Window_SystemMenu) And CreateGadgetList(WindowID(0))
   
    ButtonGadget(0, 10, 10, 80, 30, "Start / Stop", #PB_Button_Toggle)
    ButtonGadget(1, 100, 10, 80, 30, "Pause", #PB_Button_Toggle)
   
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 0
              SetGadgetState(1, 0)
              If GetGadgetState(0)
                Time = ElapsedMilliseconds()
                SetTimer_(WindowID(0), 1, 20, @timerCB())
              Else
                Time = 0
                KillTimer_(WindowID(0), 1)
              EndIf
            Case 1
              If GetGadgetState(0)
                If GetGadgetState(1)
                  KillTimer_(WindowID(0), 1)
                Else
                  SetTimer_(WindowID(0), 1, 20, @timerCB())
                EndIf
              Else
                SetGadgetState(1, 0)
              EndIf
           EndSelect
      EndSelect
    ForEver
  EndIf
EndProcedure

Main()
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
pede
Beiträge: 90
Registriert: 08.07.2007 20:37
Wohnort: brixen / Italien

Beitrag von pede »

:allright: :praise: :praise: :praise: :praise: :praise: :praise:

DANKE an alle =)

mfg
pede
"oh... ein Sarkasmus-Detektor... ein wirklich nützliches Gerät" .. dit.. dit.. ditditdit.. *bumm*
Antworten