Systemzeit



  • Hallo zusammen,
    Ich muss in einer Anwendung eine bestimmte Funktion (laufzeit unbestimmt/unbestimmbar) eine genaue Zeitlang aufrufen, z.B. 1 Sekunde, dazu hab' ich folgenden Code entwichelt:

    int __fastcall TRegler::StartRegel(void)
    {
    // Reglerfunktion
      if(this->ComBus)
        {//Profibus
        int i;
        SYSTEMTIME time;                   // Strukturdeklaration für das Einlesen der Systemzeit
        GetSystemTime(&time);                // einlesen der Systemzeit
        // for so lange durchzählen lassen, bis letzte systemzeit+Messzeit erreicht ist.
        for (i=time.wMilliseconds; i<=(time.wMilliseconds+this->MeassureTime); i++)
          {
          Application->ProcessMessages();
          Profi_p->RecParam(&OutData,&InData,1);
    
          }
        ShowMessage(IntToStr(time.wMilliseconds) + " ---- " + IntToStr(i));
        }
      else
        {//CAN-Bus
        // Der CAN-Klasse den Funktionspointer übermitteln
        }
    }
    

    Wenn ComBus=1 ist und this->MeassureTime=1000, dauert die for, ziemlich genau 10Sekunden, wenn ich aber Profi_p->RecParam(&OutData,&InData,1); auskommentiere, dann gehts ziemlich genau 1 Sekunde bis die Meldung erscheint, wesshalb bloss?



  • Ich würde sagen, das "Profi_p->RecParam(&OutData,&InData,1);" ziemlich viel zu tun hat und zwar weil du die Sie ja auch "MeassureTime" oft aufrufst.

    Ist doch klar, das das einen Unterschied macht!



  • Wäre hier eine while-Schleife nicht die bessere Wahl? Abbruchbedingung ist, wenn die Zeit erreicht ist, anstatt in Millisekundenschritten eine
    for-Schleife zu durchlaufen. Ich denke PuppetMaster2k hat schon recht mit seiner Vermutung.

    Gruß,

    Alexander



  • Wenn du die Zeit messen bzw. abfragen möchtest, dann musst du dir eine Startzeit holen und dann in einem Intervall die aktuelle Zeit abfragen. Anders wird das wohl nicht funktionieren.

    Ungefähr so. (Ist jetzt nur zur Veranschaulichung. Ob das so funktioniert weiß ichnicht, kann das hier nicht testen!)

    int __fastcall TRegler::StartRegel(void)
    {
    // Reglerfunktion
      if(this->ComBus)
        {//Profibus
        int i;
        SYSTEMTIME startzeit, aktZeit;                   // Strukturdeklaration für das Einlesen der Systemzeit
        GetSystemTime(&startzeit);                // einlesen der Systemzeit
        startzeit.wMilliseconds += MeassureTime;
        while(aktZeit < startzeit)
          {
          Application->ProcessMessages();
          Profi_p->RecParam(&OutData,&InData,1);
          GetSystemTime(&aktZeit);
          }
        ShowMessage(IntToStr(time.wMilliseconds) + " ---- " + IntToStr(i));
        }
      else
        {//CAN-Bus
        // Der CAN-Klasse den Funktionspointer übermitteln
        }
    }
    


  • Ok, hab' jetzt folgenden Code:

    int __fastcall TRegler::StartRegel(void)
    {
    // Reglerfunktion
      if(this->ComBus)
        {//Profibus
        int ms_int=0;                                   // Zeit gemessen (verstrichen in der Schleife)
        int i;                                          // Deklaration der Zählvariable
        SYSTEMTIME Messzeit, aktZeit;                   // Strukturdeklaration für das Einlesen der Systemzeit
        aktZeit.wMilliseconds=0;                        // Initialisierung damit er min. einmal durch die while läuft.
        GetSystemTime(&Messzeit);                       // einlesen der Systemzeit
        Messzeit.wMilliseconds += MeassureTime;         // zur eingelesenen Systemzeit, die Messzeit addieren.
        while (ms_int < Messzeit.wMilliseconds)         // warten, bis die aktuelle Zeit, grösser ist, als die Messzeit.
          {
          Application->ProcessMessages();
          Profi_p->RecParam(&OutData,&InData,1);
          GetSystemTime(&aktZeit);
          ms_int+=aktZeit.wMilliseconds;
          i++;
          }
        ShowMessage(IntToStr(ms_int) + " ---- " + IntToStr(Messzeit.wMilliseconds)+"\nAnzahl Durchläufe (Übermittlungen)"+IntToStr(i));
        }
      else
        {//CAN-Bus
        // Der CAN-Klasse den Funktionspointer übermitteln
        }
    }
    

    es dauert aber nie 10 Sekunden wenn ich MeassureTime auf=10000 setze..., was ist da noch falsch? 😞



  • aha, ich musste einfach die sekunden auch noch einbeziehen, und dann funktionierts super... 🙂 👍 😋



  • Kommt mir ziemlich kompliziert vor. Wofür ist eigentlich die Variable "i" gut?
    Du hast eine while-Schleife mit einer Abbruchbedingung. Wenn die Schleife Deiner Meinung nach zu früh abgebrochen wird, dann kann das entweder
    an einer falschen Abbruchbedingung liegen, oder daran, dass der Schleifenzähler falsch berechnet wird. Schau Dir mal beides an, dann kommst
    Du schon dahinter.
    Es liegt entweder daran:

    while (ms_int < Messzeit.wMilliseconds)         // warten, bis die aktuelle Zeit, grösser ist, als die Messzeit.
    

    oder daran:

    ms_int+=aktZeit.wMilliseconds;
    

    Gruß,

    Alexander



  • roN schrieb:

    aha, ich musste einfach die sekunden auch noch einbeziehen, und dann funktionierts super... 🙂 👍 😋

    Echt? Zeig mal!

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    roN schrieb:

    aha, ich musste einfach die sekunden auch noch einbeziehen, und dann funktionierts super... 🙂 👍 😋

    Echt? Zeig mal!

    Gruß,

    Alexander

    Violà:

    int __fastcall TRegler::StartRegel(void)
    {
    // Reglerfunktion
      PPO2 *recValue=new PPO2[0];
      if(this->ComBus)
        {//Profibus
        int akt_int=0, MessTime_int;                    // Decl. der Zeiten  (Ist und Soll)
        int i;                                          // Deklaration der Zählvariable
        int oldSec_int;
        SYSTEMTIME MessZeit, aktZeit;                   // Strukturdeklaration für das Einlesen der Systemzeit
        aktZeit.wMilliseconds=0;                        // Initialisierung damit er min. einmal durch die while läuft.
        GetSystemTime(&MessZeit);                       // einlesen der Systemzeit
        MessTime_int=(MessZeit.wSecond*1000)+MessZeit.wMilliseconds + MeassureTime;// zur eingelesenen Systemzeit, die Messzeit addieren um die Sollzeit zu definieren.
        while (akt_int < MessTime_int)                  // warten, bis die aktuelle Zeit, grösser ist, als die Messzeit.
          {
          Application->ProcessMessages();               // Windows-MessageQue abarbeiten
          Profi_p->RecParam(&OutData,&InData,1);        // Werte empfangen
          GetSystemTime(&aktZeit);                      // Systemzeit lesen
          akt_int=(aktZeit.wSecond*1000)+aktZeit.wMilliseconds;// aktuelle Zeit aus der gelesenen Ystemzeit berechnen
          i++;                                          // Durchlauf-Variable inkrementieren
          }
        ShowMessage(IntToStr(akt_int) + " ---- " + IntToStr(MessTime_int)+"\nAnzahl Durchläufe (Übermittlungen)"+IntToStr(i));
        }
      else
        {//CAN-Bus
        // Der CAN-Klasse den Funktionspointer übermitteln
        }
    }
    


  • Ist aber ganz gut, dass Du in dem Zug auch gleich aus dem += ein = gemacht hast.

    Gruß,

    Alexander


Anmelden zum Antworten