Wie bekommt man eine Zeit in eine If-Bedingung?



  • Hallo zusammen,

    ich bin C++-Einsteiger und stehe nun vor einem kleinen Problem.

    Ich erzeuge ständig durch einen Funktionsaufruf Messwerte, die ich in eine Datei schreibe.

    Allerdings werden viel zu nah beineinander liegende Messwerte erzeugt, die durch den kurzen Zeitabstand fehlerbehaftet sind (ungefähr 24 Messwerte pro Sekunde).

    Ich möchte nun eine Bedingung nutzen, die Prüft, ob z.B. seit dem letzten Aufruf mindestens eine halbe Sekunde vergangen ist und dann erst einen neuen Funktionsaufruf zulässt.

    Leider kann ich keine Delay-Funktion nutzen, da das Programm im Hintergrund weiter laufen muss.

    Hat jemand einen Tipp, wie ich das lösen kann?
    Zeiten und Timer sind für mich komplettes Neuland.

    Vielen Dank 🙂



  • Du holst dir einfach bei einer Messung den aktuellen Zeitwert und bildest bei jeder neuen Messung die Differenz. Und per if fragst du ab, ob seit der letzten Messung mehr als eine gewisse Zeit vergangen ist.

    in etwa so

    high_resolution_clock::time_point t1;
    
    while ( true ) 
    {
    	// ...
    	high_resolution_clock::time_point t2 = high_resolution_clock::now();
    	if ( duration_cast<duration<double>>(t2 - t1).count() >= 500 )
    	{
    		// ...
    		t1 = high_resolution_clock::now();
    	}
    	// ...
    }
    

    (ungetestet und sicherlich falsch)



  • #include <chrono>
    
    int main()
    {
        auto t = std::chrono::high_resolution_clock::now();
        while (true)
        {
            if (std::chrono::high_resolution_clock::now() - t > std::chrono::milliseconds(500))
            {
                // foo();
                t = std::chrono::high_resolution_clock::now();
            }
        }
    }
    

    Skym0sh0 schrieb:

    (ungetestet und sicherlich falsch)

    Da hast du recht, welchen Wert hat t1? 🤡



  • Hab nur auf die schnelle mal kurz geguckt. Ich würde es eigentlich mit 0 initialisieren, aber da gibts kein Konstruktor für.

    Naja, mir gings auch nur drum das Prinzip zu verdeutlichen, den genauen Weg muss sich der TE selbst aneignen.



  • Vielen Dank für die super Antworten. 🙂

    Ich musste erstmal herausfinden, wie ich die Fehlermeldung, dass dies eine experimentelle Funktion sei, abschalte 😉

    Wenn das mal jemand für QT sucht:
    Einfach in der .pro-Datei "QMAKE_CXXFLAGS += -std=c++0x" hinzufügen und dann unter dem Menupunkt "Build" QMake ausführen.

    Ich habe leider noch ein kleines Problem.
    Die hier angedeutete While-Schleife muss ich verlassen.
    Die Lösung habe ich mir etwa so vorgestellt:

    #include <chrono>
    
    int main()
    {
    
    for(;;)
    {
     bool flag=0;
     if (flag==0)
        {auto t = std::chrono::high_resolution_clock::now();}
    
        while (true)
        {
            if (std::chrono::high_resolution_clock::now() - t > std::chrono::milliseconds(500))
            {
                // foo();
                t = std::chrono::high_resolution_clock::now();
                flag=1;
            }
        }
    }
    }
    

    Das funktioniert leider aber nicht, weil t dann nicht in der zweiten if-Bedingung deklariert ist.

    Wenn ich als globale Variable "auto t" schreibe gehts auch nicht, weil ich die Variable ja nicht an der Stelle initialisieren kann.

    Wenn ich das "auto" durch "long int" ersetze, gibt es eine Fehlermeldung, dass er long int nicht in long int konvertieren könne.
    Ich habe auch schon andere Datentypen ausprobiert, aber nichts half.

    Wie löse ich dieses kleine Problem?

    Vielen Dank 🙂



  • Ok, vielen Dank.

    Es funktioniert alles super!

    Ich musste nur die Zeitvariable außerhalb der Main deklarieren.
    Manchmal sieht man eben den Wald vor lauter Bäumen nicht 😉



  • Britzi schrieb:

    Ich musste nur die Zeitvariable außerhalb der Main deklarieren.

    Nein, nein, nein, nein. Nein. Nein! Nein!! Nicht, bitte...
    Keine globalen Variablen für so etwas!



  • Nathan schrieb:

    Britzi schrieb:

    Ich musste nur die Zeitvariable außerhalb der Main deklarieren.

    Nein, nein, nein, nein. Nein. Nein! Nein!! Nicht, bitte...
    Keine globalen Variablen für so etwas!

    Ok, ich nehme mir das zu Herzen.

    Allerdings mangelt es mir gerade an einer funktionierenden Alternative 😉



  • #include <chrono>
    
    int main()
    {
    
    for(;;)
    {
     bool flag=0;
     std::chrono::high_resolution_clock::time_point t;
     if (flag==0)
        {t = std::chrono::high_resolution_clock::now();}
    
        while (true)
        {
            if (std::chrono::high_resolution_clock::now() - t > std::chrono::milliseconds(500))
            {
                // foo();
                t = std::chrono::high_resolution_clock::now();
                flag=1;
            }
        }
    }
    }
    

    ?



  • Danke für den Vorschlag.

    Leider funktioniert er nicht.
    Die zweite If-Bedingung wird nie wahr.

    Es gibt keine Fehlermeldung, aber wenn ich das zweite If auskommentiere, läuft das Programm wie zu Anfang.

    Ein "static" vor der Deklaration des time_point t hilft leider auch nicht.

    Mit der suboptimalen globalen Variable lief es.



  • Das macht 0 Sinn, erklär mal in Worten was du erreichen willst. Warum sollte die Definition und Initialisierung einer Variablen von irgendeinem flag abhängen? wtf?



  • Ok, ich probiere es mal in Pseudocode zu erklären.

    while(1)
    {
    Zeitflag=0;
    Wenn (Zeitflag ==0){Deklariere und initialisiere Zeitpunkt t mit Systemzeit;}
    
    Wenn (Systemzeit jetzt - t größer als 500 ms,) 
       {führe nachfolgend Dinge aus;
        Speichere jetzige Systemzeit für späteren erneuten Vergleich;
        Setzte Zeitflag 1, damit soeben gespeicherte Zeit nicht durch erneute initialisierung überschrieben wird. } }
    

    Ich habe eine Schleife. In dieser muss ich zu Beginn meinen Zeitpunkt, mit dem ich später vergleiche festlegen.
    Hier deklariere und initialisiere ich diesen Zeitpunkt t.

    Die zweite If-Bedingung prüft dann, ob seit dem letzten Zeitpunkt schon 500 ms rum sind, um dann ggf. etwas auszuführen. Hierbei wird ein neuer Zeitpunkt festgelegt, mit dem dann später wieder verglichen wird.
    Jetzt muss ich mit einem Flag die Deklaration des ersten Zeitpunktes außer Funktion setzen, weil sonst durch die Schleife der in der zweiten If-Bedingung zuletzt gespeicherte Zeitpunkt überschrieben würde.

    Ich hoffe das ist so halbwegs verständlich 😉



  • Das ist kein Pseudocode das ist exakt der gleiche Code wie vorher auch nur nicht mehr gültig nach den Regeln von C...



  • Nathan schrieb:

    Das ist kein Pseudocode das ist exakt der gleiche Code wie vorher auch nur nicht mehr gültig nach den Regeln von C...

    Ich weiß, dass es derselbe Code ist.
    Ich wollte damit verdeutlichen, warum ich meiner Meinung nach einen Flag brauche.

    Ich bin wirklich C++ Beginner und leider weiß nicht nicht, warum das Beispiel ohne globale Variable nicht funktioniert während das mit der globalen Variable einwandfrei läuft.



  • Um... dann definiere die Variable halt außerhalb der Schleife? Ich seh das Problem gerade nicht.



  • cooky451 schrieb:

    Um... dann definiere die Variable halt außerhalb der Schleife? Ich seh das Problem gerade nicht.

    Dann wäre es eben eine globale Variable und zumindest der Vorredner Nathan schrieb hier, dass man für sowas wie hier niemals eine globale Variable nehmen sollte.

    Ich muss aber auch sagen, dass meine Programme einfach und überschaubar sind.
    Daher denke ich, dass es villeicht für mich am besten ist, einfach wirklich eine globale Variable zu nutzen.

    Danke nochmals für die super Hilfe hier.
    Echt prima! 🙂



  • Britzi schrieb:

    cooky451 schrieb:

    Um... dann definiere die Variable halt außerhalb der Schleife? Ich seh das Problem gerade nicht.

    Dann wäre es eben eine globale Variable

    Nein. Globale Variablen sind anders, sie werden nämlich außerhalb von Funktionen deklariert.
    Sie sind fehleranfällig, weil sie von jeder Funktion verändert werden kann und außerdem kann man ein einmal geschriebenes Programm mit globalen Variablen schwer fehlerfrei erweitern.
    Bei deinem Programm wird sie nur außerhalb des Schleife angelegt, aber immer noch innerhalb der Funktion.



  • Britzi schrieb:

    Dann wäre es eben eine globale Variable

    Eh... nein. :p



  • Ok, ich habs verstanden.
    Alles außerhalb der Main ist global und sonst nicht 🙂

    Wenn ich aber nun die Variable in der Main und nicht global deklariere, ist sie in einer Funktion in der späteren Schleife nicht deklariert und somit nicht verfügbar.

    void  Zeitfunktion ()
     {
      //Hier muss t verfügbar sein
     }
    
    int main( int argc, const char** argv )
    {
       auto t = std::chrono::high_resolution_clock::now();
       for(;;)
        {
          Zeitfunktion ();
        }
    }
    

    Wie kann ich sie dort verfügbar machen?
    Ich möchte dabei t nicht als Parameter der Funktion übergeben.
    Die hat schon genug Parameter 😉

    Ich weiß, das sind sicherlich triviale Basics, aber jeder fängt mal klein an 😉

    Vielen Dank 🙂



  • Britzi schrieb:

    Ok, ich habs verstanden.
    Alles außerhalb der Main ist global und sonst nicht 🙂

    Eher Variablen, die ausserhalb von Funktionen und Klassen definiert sind, nicht nur main() .

    Britzi schrieb:

    Wie kann ich sie dort verfügbar machen?

    Parameter.

    Britzi schrieb:

    Ich möchte dabei t nicht als Parameter der Funktion übergeben.
    Die hat schon genug Parameter 😉

    Dann ist das dein Problem. Verringere die Anzahl der Parameter; z.B. indem du zusammengehörige Werte gruppierst.


Log in to reply