Zähler mit Zeitvorgabe, von x bis y in xxx

  • VB.NET

Es gibt 47 Antworten in diesem Thema. Der letzte Beitrag () ist von wolfi_bayern.

    Zähler mit Zeitvorgabe, von x bis y in xxx

    Hallo, ich hatte mein Problem vor längerer Zeit schon einmal gefragt, hab leider keine Lösung bisher..
    Ich möchte von 0 bis 1270 Zählen aber in einer bestimmten Zeit! Mein Problem liegt darin, das ich nicht weiß wie ich "das warten" realisiere ohne die CPU zu belasten.
    Es geht dabei NICHT um 1000% Genauigkeit !
    Timer fallen weg, da die ja nur im 1ms Bereicht arbeiten.
    Ich arbeite mit Stopwatch, das funktioniert, NUR wie warte ich xxx Zeit bis zum nächsten Schritt/Zählen, die "Do" ist enorm CPU Lastig.

    Beispiel von 0 bis 1270 in 2Sekunden.

    VB.NET-Quellcode

    1. Private Sub zaehlen()
    2. Dim Timestamp As Double
    3. For i = 0 To 1270
    4. Timestamp = SW.ElapsedTicks * 1000000 / Stopwatch.Frequency
    5. 'Ausgabe , senden, oder sonst irgendwas tun mit dem Wert i
    6. Do Until SW.ElapsedTicks * 1000000 / Stopwatch.Frequency >= Timestamp + 'xxx Wartezeit im Beispiel 1,57ms
    7. Loop
    8. Next
    9. End Sub


    evtl. hat ja jemand einen Vorschlag wie ich "warten" ohne CPU Last realisiere

    Danke Heiko

    CodeTags korrigiert ~VaporiZed

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

    Threding.Thread.Sleep(AnzahlDerMillisekundenDieDuSelberAusDerAnzahlDerZahlenUndDerGesamtdauerBerechnenKannst)?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Was um Himmels Willen möchtest du im Mikrosekundenbereich messen oder steuern?
    Windows ist nicht Real-Time-fähig.
    Und .Net schon gar nicht.
    Bei so kleinen Zeitspannen treibt dir jeder Kontext-Switch die Präzision ins Nirvana.

    Was hast du vor?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Was hast du vor?


    zu deutsch, eine Lampe in 1270 Schritten gleichmäßig in einer bestimmten Zeit von 0 auf 100% Helligkeit bringen, wobei die Zeit Variabel sein muss.

    Das Beispiel oben sagt doch das 1270 Schritte in 2Sekunden ausgeführt werden sollen, wobei es unwichtig ist ob der Prozess am Ende in 1,998 Sekunden abgearbeitet ist oder auch gern 2,023Sekunden.
    Wichtig ist das die "Schrittbreite" bei 1ms oder 2ms zu groß ist. Daher der Mikrosekunden Quark, denn da geht halt 1,57ms(Umgerechnet).

    Wichtig ist die Breite der Gesamtzeit/Anzahl Schritte, NICHT ob es Timing/die Ausführungszeit genau ist.

    Edit: Lampe wirkt wieder verwirrend......
    andere Erklärung, Bewegung !!!!
    0=ganz unten, 1270 ganz oben, jeder Wert zwischen 0 und 1270 ist quasi "1Punkt höher",
    ich möchte gleichmäßig mit variabler Zeit von Punkt 0 zu 1270

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

    @kollimann Dann wechsle das Betriebssystem, nimm ein Echtzeit-Betriebssystem
    oder
    verringere die Schrittanzahl und erhöhe den Zeitabstand drastisch.
    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!
    ​nimm ein Echtzeit-Betriebssystem

    wasn das für ein Blödsinn, andere Programmierumgebungen machen solchen Blödsinn ohne CPU Last !
    Es gibt sicherlich auch in VB irgendeine Möglichkeit, nur kenne ich die noch nicht.

    versteht ihr meine Fragestellung falsch? Drücke ich mich so komisch aus bei meiner Frage?

    Aufgabe:
    zähle linear/gleichmäßig von 0 bis 1270 in 1000ms
    zähle linear/gleichmäßig von 0 bis 1270 in 1300ms
    zähle linear/gleichmäßig von 0 bis 1270 in 1600ms
    zähle linear/gleichmäßig von 0 bis 1270 in 2200ms

    ich will doch nur die Wartezeit die durch Do Loop CPU Last erzeugt ändern, das Zählen und alles drumherum funktioniert, NUR die leere Do Loop verursacht CPU, was auch bekannt ist, es muss doch eine andere Lösung geben....

    kollimann schrieb:

    Blödsinn
    Deine Schritte sind Bruchteile von Millisekunden.
    Die .NET-Timer und .Sleep() arbeiten auf Millisekunden-Basis.
    Alles was darunter ist, musst Du selbst zählen, und das kostet CPU-Last.
    Auch wenn Du das in einen Thread auslagerst, kostet das CPU-Last.
    Ach ja:
    Welche Programmierumgebungen unter Windows machen das ohne CPU-Last?
    Und wie?
    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!

    petaod schrieb:

    Was hast du vor?
    Egal, ob Bewegungssimulation oder Helligkeit einer Lampe: Deine Anforderung wäre so beschrieben für die genannten Beispiele nicht praxisrelevant. Wenn Du es nicht verraten willst, wird es schwierig, eine für Dich passende Lösung zu finden, da wir auch die Relevanz nicht sehen. Augenlaser-OPs sind z.B. wohl besser nicht in .Net zu schreiben.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    kann sein das ich jetzt technischen Blödsinn schreibe.....ich kann es nicht erklären in Worten, hab es nur praktisch so verstanden..
    ​Die .NET-Timer und .Sleep() arbeiten auf Millisekunden-Basis.Alles was darunter ist, musst Du selbst zählen, und das kostet CPU-Last


    richtig das die nur im ms Bereich arbeiten, die nutze ich ja aber NICHT ! Ich nutze ja diesen "Stopwatch" Dingens, der errechnet sich irgendwie nach CPU Frequenz usw. und den auszulesen braucht keine CPU Last da der eh immer läuft !
    Ein leeres Do Loop brauch in meinem Fall die CPU Last, nicht der Stopwatch !
    Kann jeder testen, macht in einem neuen Thread eine leere Do Loop.......das "nichts" tun ist die Last.
    Ich frage ja auch nicht wie ich in der vorgebenen Zeit das zählen hin bekomme, NEIN ich frage wie ich die Do Loop raus/weg bekomme.

    ​Wenn Du es nicht verraten willst

    hab ich verraten, es wurde nur nicht verstanden, lineare/gleichmäßige Bewegung von A nach B in 1270 Schritten in einer variablen Zeitspanne, wobei mein Programm die Schritte steuert/berechnet.

    auch mehrfach geschrieben hab ich das es nichts mit Echtzeit und Timing zu tun hat, es ist relativ egal, wenn ich 2000ms vorgebe ob das Programm es dann in 1890ms oder 2090ms abgearbeitet hat.

    Ich werde einige andere Ansätze versuchen die mir durch den Kopf schwirren.......mal sehen ob es was bringt.
    z.B.
    aus Zeitvorgabe und Schritten die "Abstände" des zählens ermitteln
    startzeit setzen
    dann sagen zähle von 0 bis 999999999999999999999999
    wenn startzeit + Abstand erreicht....DANN meinen Wert +1 UND oberen zähler zurück auf 0
    next

    von 0 bis irgendwohin zählen tut der CPU nicht weh......
    ich werd es versuchen
    Ach, jetzt ist es angekommen, da stand ich aber echt auf der Leitung, sorry.
    Der Code aus Post#1 soll 1.57 ms warten, dauert aber durch die Do-Schleife länger. Bei mir sind's auf PC1 ca. 16 ms.
    Du suchst also einen Verzögerungscode, der nicht so viel Zeit in Anspruch nimmt wie die Do-Schleife. Ok. Vielleicht lässt sich da was finden.

    btw: Musst ggf. noch nicht mal mit der Stopwatch arbeiten. Mit Date.Now.Ticks bekommst Du Einheiten in 100 Nanosekundenschritten. Aber jetzt geht's ja trotzdem um einen winzigen Verzögerungsmechanismus, um die Zeit einzuhalten. Leere Sub-Aufrufe dauern zu lange. Aber ja, mit ner For-Schleife ginge es, allerdings auch nicht sonderlich gut.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    ​Der Code aus Post#1 soll 1.57 ms warten, dauert aber durch die Do-Schleife länger. Bei mir sind's auf PC1 ca. 16 ms.Du suchst also einen Verzögerungscode, der nicht so viel Zeit in Anspruch nimmt wie die Do-Schleife


    16ms ???? da hast du einen falschen Wert hinter dem + eingegeben...!!!!
    1000 = 1ms .....also müsste laut dem Beispiel da 1570 hin......

    es geht nicht um Zeit, es geht um CPU Last beim warten !!!!!

    Weiß nicht wie ich das anders erklären soll
    Hallo!
    Zwei Anmerkungen... Kann sein dass ich falsch liege...

    1. Wenn es um eine Bewegung geht wäre es nicht geschickter einen intervalltimer zu verwenden und die Position anhand der vergangenen Zeit zu berechnen?

    2. Sollte es sich um ein pwm Signal handeln um irgendwas zu dimmen könnte eine pwm lib hilfreich sein... Aber sowas ist mit Micro Controller besser zu realisieren
    Der Beitrag wurde aus 100% wiederverwendbaren Elektronen erstellt!
    @kollimann: Nein, die 16 ms sind bei einem Do-Schleifen-Durchgang schon rum. Bei 1270 Durchgängen sind es dann eben keine angepeilten 2 Sekunden Gesamtzeit, sondern > 20 Sekunden.

    kollimann schrieb:

    1000 = 1ms
    Das verstehe ich ohne Zusammenhang nicht, aber wurscht, ich glaube es wird klar, was ich meinte.
    Aber weder mit Do, noch mit For, noch mit Nebenläufigkeit erhalte ich an PC2 CPU-Auslastungen < 9%. Sorry.

    @wolfi_bayern: Es geht wohl um weder das eine noch das andere. Es geht einfach nur darum, 1270 Schritte in einer bestimmten Zeit zu absolvieren, ohne dass die CPU-Last dabei merklich steigt. Was dahinter steckt: Entweder gar nichts oder etwas noch nicht genanntes.
    Allerdings wird die Aktion, die nach der Wunsch-1,57ms-Verzögerung liegt, ebenfalls Zeit kosten, möglicherweise viel Zeit. Vielleicht ist es relevant, vielleicht nicht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    im Anhang ein Test-Project, erstellt in Visual Studio 2012.
    3 dieser Threads verursachen bei mir ca 50% CPU Last ! Und es liegt nicht daran das da ein Regler hin und her fährt oder eine Consolen Ausgabe stattfindet !
    Testet es.....dann schauen wir mal was ihr so sagt.
    Dateien

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

    @kollimann Zunächst hast Du die Verzeichnisse bin und obj mit in die zip gepackt, editiere Deinbe ZIP und entferne diese.
    Ich kann 5 Deiner "Dinger" starten, den 6. nicht. Die CPU-Auslastung liegt bei 4 bKernen bei über 80%, die GUI reagiert nicht mehr, ich kann nichts stoppen und muss das Programm "mit Gewalt" beenden. Damit hört für mich der Test auf.
    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!
    Verzeichnisse bin und obj

    Sorry, das war mir nicht bekannt das die da nicht mir rein dürfen, ENTSCHULDIGUNG !!! hab es entfernt

    Ja, bei 4 5 und 6 ist ja Kommentiert, !!! Tests !!!, da kann es passieren das da etwas nicht geht !!!
    Bei mir laufen 6 gleichzeitig ohne Probleme mit Stop....
    Wieviel Kerne hast Du?

    I7..7th Generation......4Kerne

    ​Ich kann 5 Deiner "Dinger" starten, den 6. nicht. Die CPU-Auslastung liegt bei 4 bKernen bei über 80%


    genau das ist mein Problem bzw. meine Frage, wie bekomme ich das besser hin, die "Kiste" zählt nur, aus meiner Sicht keine Aufgabe für ne CPU......
    Probier mal das hier. Sollte bis auf 5-15 Millisekunden genau funktionieren und frisst absolut keine Performance.

    VB.NET-Quellcode

    1. Private InitialTime As Double
    2. Private Seconds As Integer
    3. 'Start Sub
    4. Public Sub Zählen()
    5. Seconds = CInt(txtSeconds.Text) 'Hier alternative Übergabe der Sekundenanzahl einfügen, aktuell halt über eine Textbox gesteuert
    6. InitialTime = Date.Now.Minute * 60000 + Date.Now.Second * 1000 + Date.Now.Millisecond
    7. Timer1.Start()
    8. End Sub
    9. 'Timer ins Projekt einfügen und folgenden Tick-Handle implementieren (Interval auf 10 ms (Ergibt eine maximale Abweichung von 17 Millisekunden(getestet mit 3, 5 und 7 Sekunden Laufzeit)
    10. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    11. Dim DateNow As Double = Date.Now.Minute * 60000 + Date.Now.Second * 1000 + Date.Now.Millisecond
    12. Update_Wert(DateNow - InitialTime)
    13. End Sub
    14. 'Folgenden Sub implementieren in dem du den Code für deine Dimmer-Birne einfügst
    15. Public Sub Update_Wert(NewValue As Integer)
    16. Dim Value = NewValue / (1000 * Seconds) * 1270
    17. If Value >= 1270 Then
    18. Timer1.Stop()
    19. End If
    20. End Sub
    21. 'Startbutton und TextBox ergänzen wo du die Sekunden einfügst (kein Plan ob du das brauchst, aber den Code kannst du sicher deinen Bedürfnissen entsprechend anpassen ;-))
    22. Private Sub Start_Click(sender As Object, e As EventArgs) Handles bnStart.Click
    23. Zählen()
    24. End Sub



    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.