Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Einfaches Programm, Denkblockade Analogwertsimulation

2012-02-29
2012-03-01
  • Florian03091988 - 2012-02-29

    Hallo zusammen,

    Mein erstes, kleines Programm soll einen Analogwert simulieren.
    Ich habe aber derzeit eine kleine Denkblockade..

    Hier die Aufgabenstellung:

    • Es soll ein Temperaturwert über ein Merkerwort an die SPS übergeben werden.
      Dieses stellt den Sollwert der Raumtemperatur dar.
      Nun soll der "Istwert" in kleinen Stufen auf den Sollwert steigen/fallen.
      Dies dient zur Simulation, um die Benutzeroberfläche einer Touchscreensoftware zu testen.

    Mein bisheriger Lösungsansatz:

    • Setzen eines Initialwertes für den theoretischen Istwert über einen Digitaleingang, bzw. einen Merker des types BOOL
    • Festlegen des Initialwertes über ein Merkerwort
      Also ungefähr so:
    IF Setzen_Initialwert;
    THEN Merker_Istwert := Merker_Initialwert;
    RETURN;
    ELSE Merker_Istwert;
    END_IF;
    

    Wobei ich hier schon nicht sicher bin, ob die Syntax stimmt.

    Nun soll der Istwert (ein Merkerwort) geändert werden, sobald der Sollwert vom Istwert abweicht:
    Dies würde ich in 2 Programmteilen, einmal für Sollwert > Istwert und einmal für Sollwert < Istwert programmieren.
    Dazu würde ich einen Pulsgeber (GEN_PULSE) aus der Oscat.lib verwenden und diesen auf einen Zähler "hängen", dessen momentaner Zählerwert der Merker_Istwert ist.

    Das gleiche für das Runterzählen.

    Nun habe ich irgendwie keine Ahnung wie ich das in ST hinbekommen soll.
    Ich meine, ich habe schon einiges gelesen und auch kleinigkeiten programmiert, aber in ST ist die Syntax zu extrem wichtig, dass ich bei einem solch kleinen Programm schon etwas überfragt bin.

    Ich hätte angefangen mit dem Erstellen eines FB "Analogsimulation".
    in diesem steht bis jetzt folgender Code, bei dem ich nicht wirklich weiter weiß:

    IF Setzen_Initialwert;
    THEN Merker_Istwert := Merker_Initialwert;
    RETURN;                   (*in jedem Zyklus soll überprüft werden, ob "Setzen_Initialwert" aktiv ist*)
    ELSE Merker_Istwert;
    END_IF;
    IF Sollwert_INT > Merker_Istwert;
    THEN Instanz_GEN_PULSE1(ENQ:=TRUE;PTH:=t#200ms;PTL:=t#200ms);
    

    Ich bin für jede Hilfe und Kritik dankbar!
    Grüße,

    Florian

     
  • Florian03091988 - 2012-02-29

    Hmm,

    Habe noch einen anderen Lösungsansatz. Weiß aber nicht, ob es so funktionieren wird...

    FUNCTION_BLOCK Analogsimulation
    VAR_INPUT
       Sollwert_INT :          INT;
       Setzen_Initialwert: BOOL;
       Merker_Initialwert: INT;
    END_VAR
    VAR_OUTPUT
       Istwert_INT :          INT;
    END_VAR
    VAR
       Merker_Istwert: INT;
    END_VAR
    IF Setzen_Initialwert THEN Merker_Istwert := Merker_Initialwert; END_IF;
    IF Merker_Istwert < Sollwert_INT THEN REPEAT Merker_Istwert := Merker_Istwert+1;UNTIL Merker_Istwert = Sollwert_INT END_REPEAT;
    ELSIF Merker_Istwert > Sollwert_INT THEN REPEAT Merker_Istwert := Merker_Istwert-1;UNTIL Merker_Istwert = Sollwert_INT END_REPEAT;
    END_IF;
    Istwert_INT := Merker_Istwert;
    

    Hier müsste ich dann die Erhöhnung des Wertes noch von einer Zeit abhängig machen.
    Allerdings sollte es dafür erst einmal funktionieren, was es bei der Simulation nicht tut

     
  • Rolf-Geisler - 2012-02-29

    Hallo Florian,

    mit Deinem ersten Programmierbeispiel kann ich nicht so recht etwas anfangen. Ich weiss nicht, was sich hinter Instanz_GEN_PULSE1 verbirgt.

    Dein zweiter Lösungansatz wird funktionieren. Da Du aber den Merker_Istwert in einer REPEAT-Schleife solange veränderst, bis er auf dem Wert von Sollwert_INT steht, wirst Du am Ausgang keine Rampe sehen. Der Baustein wird während der REPEAT-Schleife nicht verlassen, also kannst Du in dieser Konstruktion auch gleich den Sollwert_INT auf den Merker_Istwert zuweisen.

    Wenn Du am Ausgang Rampen sehen willst, musst Du im Baustein z.B. die Aufrufzyklen hochzählen und alle x Zyklen den Merker um 1 erhöhen oder verkleinern, oder Du schaffst Dir einen Zeitgeber, an den Du das Verändern von Merker_Istwert hängst.

    Gruss Rolf

     
  • Florian03091988 - 2012-03-01

    Okay, danke schön.

    Ich habe jetzt einfach einen Pulsgeber benutzt.
    Allerdings waren meine Kenntnisse nicht ausreichend, es in ST zu verwirklichen.
    Dadurch musste ich das Programm in FUP erstellen und versuche es jetzt in ST umzuschreiben.

    Ich hoffe, ich werde es hinbekommen.

    Grüße

     
  • Rolf-Geisler - 2012-03-01

    Hi,
    das ist völlig OK. Schliesslich hat CoDeSys auch AWL und KOP/FUP im Angebot, jeder schreibe halt so, wie er am schnellsten ein Ergebnis erzielt (und die Umgebung das Werk noch verstehen und pflegen kann - man weiss ja nie).
    Zumindest hast Du erst mal aus der Ecke herausgefunden, wie ich Deinen Zeilen entnehme.
    Was das Umschreiben nach ST angeht, hier ein kleiner Vorschlag mit Rampenzähler :

    FUNCTION_BLOCK Analogsimulation
    VAR_INPUT
       Sollwert_INT :          INT;
       Setzen_Initialwert: BOOL;
       Merker_Initialwert: INT;
       Rampenzeit : INT;
    END_VAR
    VAR_OUTPUT
       Istwert_INT :          INT;
    END_VAR
    VAR
       Merker_Istwert: INT;
       Rampe: INT;
       NeuerSollwert : BOOL;
       AlterSollwert : INT;
    END_VAR
    (* --- *)
    IF Setzen_Initialwert 
    THEN Merker_Istwert := Merker_Initialwert; 
    END_IF;
    (* Sollwertänderung abfangen und Rampenzähler auf Null setzen *)
    IF (Sollwert_INT <> AlterSollwert)
    THEN Rampe := 0;
         AlterSollwert := Sollwert_INT;
    END_IF;
    IF (Merker_Istwert <> Sollwert_INT) 
    THEN Rampe := Rampe + 1;  (* Rampe hochzählen - in jedem Durchlauf 1 x *)
         (* Wenn jetzt Rampe = Rampenzeit, dann Zähler zurücksetzen und Merker_Istwert um 1 verändern *)
         IF (Rampe >= Rampenzeit)
         THEN Rampe := 0;
              IF (Merker_Istwert < Sollwert_INT) 
              THEN Merker_Istwert := Merker_Istwert+1;
              ELSE Merker_Istwert := Merker_Istwert-1;
              END_IF;  (* IF Merker_Istwert < Sollwert_INT *)
         END_IF;  (* IF Rampe >= rampenzeit *)
    END_IF;  (* IF Merker_Istwert <> Sollwert_INBT *)
    Istwert_INT := Merker_Istwert;
    

    Hoffe, Du kannst es nachvollziehen.
    Gruss Rolf

     

Log in to post a comment.