Zähler nach Zeitvorgabe?

  • VB.NET

Es gibt 69 Antworten in diesem Thema. Der letzte Beitrag () ist von kollimann.

    Zähler nach Zeitvorgabe?

    Hallo, ich steh etwas im Dunkeln mit meinem VB Net.
    Ich muss von 0 bis 255 zählen und bei Bedarf auch wieder rückwärts und das alles in einer bestimmeten Zeit bzw. der Zählvorgang also das "+1" muss 254mal im gleichen Intervall sein.
    Also zu Deutsch
    0-255 in 1Sekunde, laut meiner Rechnung müsste er alle 3,9ms um 1 erhöhen
    0-255 in 2Sekunden, also dann alle 7,8ms usw usw usw.
    wobei es hier auch gern rund zugehen darf, also 3,9ms kann auch 4ms sein, so genau muss das nicht werden.
    Also wie erhöhe ich +1 alle 4ms z.B. ?

    Mit / Timer Ticks gehts nicht........

    Danke für die Hilfe
    Kollimann

    kollimann schrieb:

    Mit / Timer Ticks
    musst Du es schon machen.
    Was genau geht denn da nicht?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    kollimann schrieb:

    Ohne es gestoppt zu haben
    Richtig. Stopp es einfach.

    VB.NET-Quellcode

    1. Dim SW As System.Diagnostics.Stopwatch
    2. Dim Count As Integer
    3. Private Sub BtnStart_Click(sender As Object, e As EventArgs) Handles BtnStart.Click
    4. Count = 0
    5. SW.Start()
    6. Timer1.Interval = 1
    7. Timer1.Start()
    8. End Sub
    9. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    10. Count = CInt(SW.Elapsed.TotalMilliseconds / 3.9)
    11. End Sub
    Kein Timer innerhalb des Frameworks ist bei Standardeinstellungen schnell genug, um im 4ms-Takt zu feuern.
    Standard ist 15,6 ms.
    Das lässt sich zwar theoretisch verändern, sollte aber nur wohl überlegt gemacht werden.
    Ein interessanter Artikel dazu: randomascii.wordpress.com/2013…olution-megawatts-wasted/

    Meine Vorgehensweise wäre umgekehrt:
    Bei jedem Timerevent die Anzahl der vergangenen Prozessorticks abrufen und den zu diesem Zeitpunkt richtigen Wert in die Variable eintragen.

    Mich würden die Hintergründe interessieren.
    Was willst du damit steuern?

    Halte dir vor Augen, dass Windows kein Echtzeitbetriebssystem ist.
    Du hast nicht in der Hand, dass das System auch mal viele Millisekunden lang dein Programm überhaupt nicht berücksichtigt.
    Da wird ein Timer oder eine Stopwatch einfach um den entsprechenden Zeitraum zu spät feuern bzw. zu hohe Werte anzeigen.
    Du kommst um eine Neusynchronisation bei jedem Event nicht herum, wenn du exakte Timestamps benötigst.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „petaod“ ()

    Mich würden die Hintergründe interessieren.
    Was willst du damit steuern?

    Das ist evtl ein guter Ansatz, könnte sein das ich ja die völlig falsche Denkweise habe, nur wie erklär ich es das es jeder versteht, bin kein Autor.

    Grundlegend steuern will ich ein weiteres Programm per Midi Daten und in dem Programm die Bewegung einer Figur.
    Die Sache ist so gestrickt das ich zwar in dem Programm die Bewegung der Figur fest einstellen kann aber dann von aussen im Betrieb, also Live, nichts ändern kann.
    Man kann aber die Bewegung auch von aussen steuern, per Midi, DMX und weiß ich noch was alles.
    Bedeutet, die Figur spielt 10Sekunden, sie soll von unten nach oben wandern, bedeutet in meinem Fall Midi-Wert 0 = ganz unten, Midi Wert 127 = ganz oben, also jeder Wert 1Schritt nach oben.

    Zwischendurch, 127 ist gut wenn ganz schnell, aber wenn langsam ruckelt es, also Midi über Umweg verdoppelt, mehr Schritte für gleiche Distanz=mehr Auflösung = weniger Ruckeln, daher ich bis 255 zählen.

    So zurück nach oben, jetzt kann ich die Sache auf einen Slider in meinem Midi Keyboard legen und so schnell ich kann den Slider hoch/runter, dann bewegt sich die Figur so schnell wie ich eben kann bzw. so schnell wie Midi kann, lt Wiki 0,96ms pro Befehl/Schritt.
    Das mit dem Slider und meiner Hand will ich nun aber Automatisch mit meiner Soft erreichen.
    Also in 2 Varianten, einmal NUR vorwärts, also ich muss von 0-255 zählen und jeden Schritt/Wert senden, und als 2. vorwärts UND rückwerts, also von 0-255 und wieder von 255 -0.
    So nun kann man anfangen mit rechnen, im extrem Fall Variante 2 benötige ich nun 510 Schritte * 30ms für einen Durchlauf vor und zurück = 15300ms / 15,3Sek für einmal hoch/runter.......echt langsam.
    OK jetzt kann man hergehen und sagen OK wenn "schnell" muss es nicht 255 sein dann kann man es "gröber" machen mit 127, macht immer noch ca 8 Sekunden, immer noch langsam. UND wie soll die Routine aussehen???? Weil ich muss ja immer bis 255 und zurück zu 0 also könnte ich nur sowas wie Step 2 oder Step 3 nutzen.
    Also maximal geht eh nur das was Midi ansich kann, also im Ideal Fall 1ms * 255 Schritte bzw. 512 Schritte, aber davon bin ich ja mit meiner Routine noch weit entfernt.

    UND dazu kommt ja noch, das ganze soll später in 3 einzelnen Instanzen laufen, Vertikal, Horizontal, Drehung 8o

    Das Midi uralt ist und lahm ist weiß ich, aber das ich selbst das lahme Midi im Zeitalter von Core i weiß ich was nicht ausreizen kann mit selbst gestrickter Software, will mir gerade nicht ganz in den Kopf.

    Tjo evtl doch irgendwie mit for Schleife und wait oder sleep oder???? dazwischen irgendwas bauen..................

    Hoffe ihr versteht wie ich das meine......

    Kollimann

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kollimann“ ()

    Stopp es einfach.


    Sehr sehr interessant........
    "Count" direkt in der ersten Zeile meines Timer Tick Events = 2
    "Count" am Ende, also nach meinem ganzen rechnen, + und if und else......= 5

    ?( heftig

    und nun???? bremst mich mein schlechter Code Stil völlig aus

    Kollimann

    kollimann schrieb:

    garnix
    Das Problem ist: Windowas ist kein Echtzeit-Betriebssystem, VB.NET / C# sind keine Echtzeit-Programmiersprachen.
    Wenn Du genaue Taktung brauchst, müsstest Du zumindest mit Sleep() und einer eingefrorenen GUI arbeiten. Desweiteren musst Du den jeweiligen PC / Prozessor kalibrieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. Dim SW As New System.Diagnostics.Stopwatch
    2. Dim Count As Integer
    3. Dim wert as Integer
    4. wert = 0
    5. Private Sub TimerVertikal_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerVertikal.Tick
    6. wert += 1
    7. If wert = 255 Then
    8. Count = CInt(SW.Elapsed.TotalMilliseconds)
    9. Label1.Text = Count
    10. rota_wert = 0
    11. End If
    12. 'Trackbar Value ändern
    13. 'TB_Vert.Value = wert
    14. End Sub
    15. Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    16. Count = 0
    17. SW.Start()
    18. TimerVertikal.Interval = 1
    19. TimerVertikal.Start()
    20. End Sub


    Label1 zeigt mir 3983 .....ms sollen das ja sein? warum oben durch 3.9 weiß ich nicht
    gestoppt extern mit Stoppuhr ca. 4Sek.

    Bedeutet für mich jetzt der Timer läuft im "kleinstmöglichen" Tick, weniger/schneller gehts nicht, entspricht 15,6ms pro Tick.
    Richtig oder falsch?

    OK ich verstehe das mit dem Echtzeit-Betriebssystem kann ich nachvollziehen irgendwie !
    ABER
    ....es muss doch möglich sein Daten Schrittweise an eine Schnittstelle zu senden in Zeiten < 15ms OHNE das eine Gui stehn bleibt.
    In einem separaten Thread

    Bitte für mich als kleinen dummen Idioten etwas ausführlicher,
    sicher sowas wie eine "neue" Form in der dann nicht rum geklickt wird die nur für das senden un zählen irgendwo im Hintergrund geöffnet und geschlossen wird........


    jetzt lese ich mich also erstmal ein , was ist ein neuer Thread.
    Das wäre für mein Fachwissen sicher gut, lößt aber dann mein Problem in ca 3 Wochen....
    DANKE

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kollimann“ ()

    Ich denke, man sollte Threads und Stopwatch etc. hier komplett vergessen, und den Ansatz neu konzipieren - im Grunde ist er auch schon angeklungen.

    kollimann schrieb:

    Grundlegend steuern will ich ein weiteres Programm per Midi Daten und in dem Programm die Bewegung einer Figur.
    Die Sache ist so gestrickt das ich zwar in dem Programm die Bewegung der Figur fest einstellen kann aber dann von aussen im Betrieb, also Live, nichts ändern kann.
    Man kann aber die Bewegung auch von aussen steuern, per Midi, DMX und weiß ich noch was alles.
    So zurück nach oben, jetzt kann ich die Sache auf einen Slider in meinem Midi Keyboard legen und so schnell ich kann den Slider hoch/runter, dann bewegt sich die Figur so schnell wie ich eben kann bzw. so schnell wie Midi kann, lt Wiki 0,96ms pro Befehl/Schritt.
    Imo sollte man einen Timer verwenden, der mw. alle 100ms nachguckt, wie die Midi-Steuerung aktuell eingestellt ist.
    dann die vergangenen 100ms mw. interpolieren, die Figur entsprechend positionieren (wenn das geht), und ihre Bewegung entsprechend der aktuellen Eingabe konfigurieren.

    Dazu mussich sagen, ich hab von Midi keine Ahnung - ich kenne Midi nur als *.mid-Dateien, die ich als Musik abspielen kann.
    mh, nein, ich denke das Stopwatch war nur dafür gedacht das ich feststelle wie lange es wirklich dauert mit meinem Timer Tick, meine Werte waren ja geschätzt.
    Und das mit den Slidern war nur ein Beispiel, ich will keinen Zustand vom Midi Keyboard überwachen, ich will die händischen Aktionen die ich am Keyboard machen würde per Software "auslösen" lassen, mein Programm sendet dann Midi an das nächste Programm, also nix mehr mit Hand dafür will ich ja die Soft schreiben.
    Und ich denke das mit dem neuen Thread ist der Weg !
    Weil ich das so verstehe, ich starte das "zählen" incl der "wartezeit" in einem neuen Thread, das die Gui nicht stehen bleibt. Da kann der neue Thread zählen->senden, Pause->zählen->Senden->Pause usw. ohne das in der Gui was hängt bzw. pausiert.
    Also ich übergebe einem neuen Thread angenommen Pause=5ms, der neue Thread macht dann wert+1->senden->warten 5ms->wert +1->senden->warten 5ms usw usw. und bei dem warten läuft trozdem meine eigentliche Gui weil die vom warten nix mit bekommt da anderer Thread.
    Klingt erstmal plausibel, nun muss ich das nur noch lernen, verstehen wie ich das progge......

    Also hilfreich wäre ein Code Schnippsel.
    Klick Button
    starte neuen Thread
    übernimm wert1 und wert2
    tjo und wenn ich dann in der eigentlichen Gui den Slider Speed bediene muss das ja auch der "neue/andere" Thread mitbekommen
    irgendwann heist es dann
    klick button
    Thread stopp oder so.......

    nunja, ne Menge Stoff für mich
    Sorry, ist mir eben erst aufgefallen.

    kollimann schrieb:

    die Bewegung einer Figur
    Willst Du eine Hochgeschwindigkeitskamera simulieren?
    Überleg mal, was das menschliche Auge wahrnehmen kann. Wie @EDR schon sagte: Mach das gemütlich und sieh Dir an, wie fein Du auflösen musst, damit das Auge das ordentlich wahrnimmt.
    Wenn das Programm selbst auf die Hyperfeinbewegung selbst reagieren sollte, ist da wohl was völlig oversized.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ach ja.......
    Ich will nichts mit Hochgeschwindigkeit oder sonstwas !
    Erklärung.
    Laser sollten alle schon mal gesehen haben.
    Wir befinden uns in einer Halle 40x30m
    Ich möchte eine senkrechte Linie von links nach rechts bewegen, also muss die Linie einen Weg von 30m = 3000cm zurücklegen.
    für die 3000cm hab ich 255 Schritte zu Verfügung, was schon nicht viel ist, (Wert 0 = ganz links, Wert 127 = Mitte, Wert 255 ganz rechts)
    also legt die Linie pro Schritt/Wert 11,7cm zurück, sprich sie springt in 11,7cm Schritten von links nach rechts.
    WENN das nun bei Techno passiert ist das nicht schlimm weil da gehts schnell da sieht man die "Sprünge" nicht, ABER wenn man es langsam macht sieht man schon die 11,7cm Sprünge. Soweit sollte es klar sein das ich die 255 Schritte nicht weiter verkleinern kann, eigentlich noch mehr Schritte bräuchte, aber es geht ja schon mit 255 nicht.

    So wieder beim Thema Techno, nehmen wir an das Lied hat 130BPM, BPM weis auch jeder hoffe ich, die Geschwindigkeit von Musik.
    Also haben wir bei 130BPM alle 1 Sekunde 2Beats. ( !!!!! das ist nicht genau geht aber einfacher zur Erklärung !!!!!!!!!!)
    So nun soll die Linie alle 2 Beats = 1Sek von links nach rechts in 255 Schritten siehe oben. Und was nun? Nun sind wir wieder am Anfang meines Posts, dazu muss meine Soft in 1000ms 255 Werte senden sprich alle 4ms.
    Besser kann ich es nicht erklären sorry.
    OK ich gebe zu das ist schon recht an der Obergrenze was man im Einsatz braucht, aber auch nicht aus der Luft gegriffen.
    Klar schaffe ich den Slider am Keyboard mit meiner Hand von 0-255 in 1 Sekunde zu schieben, ABER das soll ja meine Soft übernehmen.
    Und klar könnte ich bei diesem Speed immer 1 Schritt überspringen, ABER da muss ich ja noch mehr Routinen schreiben , was ich auch nicht wollte, denn WENN es langsamer sein soll brauch ich schon min die 255 Schritte!

    Das alles kann ich logisch FEST in der LaserSoftware einstellen, NUR kann ich es dann LIVE nicht ändern, dazu eben mein Zusatzprogramm.


    Kollimann

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kollimann“ ()

    Aber wie gesagt,
    Windows kann sowas nicht. Ich denke mit nem Arduino könnte das ganze klappen. Du schickst ihm über die Serielle Schnittstelle die Spanne(0-255) und die Zeit(1000ms) und er errechnet wie schnell er sein muss.... und steuert dann den Laser an.

    Lg Mokki
    ​Smartnotr - ein intelligentes Notizprogramm
    zum Thread