TIA Kurzen Impuls in SCL erzeugen

Beiträge
110
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich programmiere in SCL und dort möchte ich in einer while Schleife eine Variable von "false" kurzzeitig also für eine halbe Sekunde auf "True" setzen. Die Variable "b" wird in der Schleife auf 1 gesetzt und soll dann nach 500ms wieder auf 0 zurückgesetzt werden. Ich bin in meiner Recherche auf die Zeitfunktion S_PULSE gestoßen. Leider habe ich nicht verstanden, wie man diesen einbauen kann.

So sieht mein Programm momentan aus:
Code:
WHILE #x < 10 DO
          b=1
          //(b soll für 500ms auf 1 bleiben und dann auf 0 zurückgesetzt werden)
end_while;

Hat hier jemand Tipps, um den Baustein richtig und möglichst einfach einzubauen?

danke
 
Moin TrainerLaverCup67,

ich vermute, Du kommst von der Hochsprachenprogrammierung richtung SPS und nicht von der Digitaltechnik Richtung SPS?

Eine Schleife in einer SPS läuft immer innerhalb der "großen SPS-Schleife" (OB1 bzw. Cycle oder Zyklus genannt). Dieser Zyklus sollte möglichst klein bleiben. Er wird von der Power der SPS und der Menge an zu verarbeitenden Code beeinflusst und spielt irgendwo bei 2-20ms.

Wenn die While-Schleife länger braucht, geht die CPU in Stopp, da die Zykluszeit (default max: 150ms) überschritten wurde.

Für jegliche Zeitoperationen (Puls von 500ms) eignen sich Zeitfunktionen (z.B. TP - Impuls erzeigen). Die Hilfe im TIA-Portal ist sehr mächtig und informativ. Da findet man auch Informationen zum TP.

Ich würde wahrscheinlich eine Einschaltverzögerung verwenden.

Code:
Pseudocode:

IF
    Einschaltbedingung_fuer_b
THEN
    b := true;
END_IF

"TON_DB".TON(IN := b,
             PT := T#500ms);

IF
     "TON_DB".Q
THEN
    b := false;
END_IF;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus,

nette Endlosschleife hast du da.

Eine Schleife ist hier falsch.
Ich würde dir empfehlen nur mit Timern zu arbeiten.
S_Pulse ist ein alter S5-Timer und hier würde ich dir auch eher TON (Einschaltverzögerung) oder TP(Impuls erzuegen (der neue S_Pulse)) empfehlen.
 
Hallo,
ich programmiere in SCL und dort möchte ich in einer while Schleife eine Variable von "false" kurzzeitig also für eine halbe Sekunde auf "True" setzen. Die Variable "b" wird in der Schleife auf 1 gesetzt und soll dann nach 500ms wieder auf 0 zurückgesetzt werden. Ich bin in meiner Recherche auf die Zeitfunktion S_PULSE gestoßen. Leider habe ich nicht verstanden, wie man diesen einbauen kann.

So sieht mein Programm momentan aus:
Code:
WHILE #x < 10 DO
          b=1
          //(b soll für 500ms auf 1 bleiben und dann auf 0 zurückgesetzt werden)
end_while;

Hat hier jemand Tipps, um den Baustein richtig und möglichst einfach einzubauen?

danke
Noch eine Frage: Ist b ein int oder ein bool?

Wenn b ein Bool ist, besser true und false verwenden.
 
Servus,

nette Endlosschleife hast du da.

Eine Schleife ist hier falsch.
Ich würde dir empfehlen nur mit Timern zu arbeiten.
S_Pulse ist ein alter S5-Timer und hier würde ich dir auch eher TON (Ausschaltverzögerung) oder TP(Impuls erzuegen (der neue S_Pulse)) empfehlen.
TON ist aber eine Einschaltverzögerung; TOF ist eine Ausschaltverzögerung.
 
danke für die Antworten.
Ich bin tatsächlich eher Programmiersprachen wie C++ gewohnt.

Das Programm ist eigentlich eine Schrittkette mit mehreren Schritten. Einen Schritt in dieser Schrittkette, bin ich gezwungen mehrmals zu wiederholen. Deswegen habe ich anstatt den besagten Schritt mehrmals zu Kopieren und einzufügen, einfach eine While Schleife erzeugt, die sich solange wiederholt, bis die Bedingung erfüllt ist. Deswegen habe ich nicht richtig verstanden, wie es ohne Schleifen funktionieren soll.

Also so würde das Programm nicht richtig laufen und das wäre auch die falsche Programmierstrategie?
Code:
WHILE #x < 10 DO
    x := x+1 ;
    b := true; //(b ist bool)
    "TP_DB".TP(IN := b,
             PT := T#500ms);
    IF
        "TON_DB".Q
    THEN
        b := false;
    END_IF;        
end_while;
 
Du würdest zumindest nur einmal einen Impuls von 500ms machen und die schleife vor dem Ende des Impulses verlassen haben.

Ich würde das mit einem case lösen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Üblicherweise würde man bei Schrittketten immer nur einen Schritt pro Zyklus durchlaufen. Somit ist gewährleistet das während der Abarbeitung noch andere Dinge erledigt werden können.

Also wäre eine Schrittketten eher in CASE zu programmieren.
 
danke für die Antworten.
Ich bin tatsächlich eher Programmiersprachen wie C++ gewohnt.
Die Sprache macht doch überhaupt keinen Unterschied. Vermutlich hast du in C++ auch programmiert ohne zu wissen was unterlagert abläuft. Wenn man 500ms wartet, dann passiert solange man kein Multitasking-Betriebssystem im Hintergrund laufen hat, so lange eben einfach gar nichts. Und jeder der auf einem Microcontroller in C oder C++ programmiert hat, wird die Analogie zum OB1 Zyklus der SPS und der sonst üblichen unendlichen for( ; ; ) {} Schleife die da gestartet wird erkennen.
 
Guten Morgen,
Da meine Schrittkette in Fup mir Probleme bereitet hat, habe ich die Schrittkette, nach den Empfehlungen hier im Thread, zu einer Case Struktur umgebaut.
Dabei habe ich das gleiche Problem einen Impuls zu erzeugen.

Code:
        2:  // Schritt 2
            "IEC_Timer_0_DB".TP(IN:=_bool_in_,
                                  PT:= t#250ms,
                                  Q=> Start_1, Start_2,
                                  ET=>_time_out_);
            
            IF "X_DB".REFERENCED
                AND "X_DB".REFERENCED THEN
                "Data".Step := 3;
            END_IF;

Was muss ich den in "IN:=_bool_in_" schreiben, damit der Ausgang sofort für 250ms ausgelöst wird, wenn ich in Schritt 2 bin?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was muss ich den in "IN:=_bool_in_" schreiben
Wenn du einfach nur einen 250ms Impuls erzeugen möchtest, dann musst du dort einfach deine (boolsche) Bedingung angeben.
Das Ganze ohne CASE....
Code:
            "IEC_Timer_0_DB".TP(IN:=deineBoolBedingung,
                                  PT:= t#250ms,
                                  Q=> impulsOut,
                                  ET=>_time_out_);
 
Wie meinst du das ohne Case? Ich möchte dafür sorgen, das sobald ich in dem Case 2 oder Schritt 2 bin, die Variablen Start_1 und Start_2 für 250 ms auf True sind. Meine Bedingung ist also, das ich in Case 2 bin, aber was schreibe ich dann da am besten rein?
 
Dann starte doch einfach deinen TIMER außerhalb des CASE und gebe am Timer als Startbedingung an, dass die CASE Variable den Wert =2 hat.
Code:
            "IEC_Timer_0_DB".TP(IN:=deineCaseVariable = 2,
                                  PT:= t#250ms,
                                  Q=> Start_1,
                                  ET=>_time_out_);
            Start_2 := Start_1;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wieso nicht einfach das Taktmerkerbyte verwendet was die SPS selbst generiert?

Dort gibts einen 2Hz Merker bzw einen 5Hz Merker der eben in den Abschnitten TRUE ist, dann musst du keinen Timer basteln
 
Wie meinst du das ohne Case?
Der Klassiker: Timer dürfen nicht nur (bedingt) in den Zyklen (z.B. Case) aufgerufen werden, wo die Zeit ausgewertet werden soll,
sondern sollte man am besten in jedem Zyklus (also un-bedingt) aufrufen, weil Timer zum Starten eine Flanke am Eingang benötigen. Wird ein Timer immer nur mit IN:=TRUE aufgerufen, dann erkennt er keine Flanke und startet nicht.
Alternative Lösung: den Timer zum Starten ein zusätzliches Mal mit IN:=FALSE aufrufen, danach kann der Timer bedingt nur in dem Case aufgerufen werden.
Beste Lösung: in Cases nur die Variable für den Timer.IN steuern, und den Timer-Aufruf außerhalb der Cases immer aufufen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie meinst du das ohne Case? Ich möchte dafür sorgen, das sobald ich in dem Case 2 oder Schritt 2 bin, die Variablen Start_1 und Start_2 für 250 ms auf True sind. Meine Bedingung ist also, das ich in Case 2 bin, aber was schreibe ich dann da am besten rein?
Code:
CASE CASE_VAR OF

CASE_VAR:= 2;

2:
    Output1:= 1;
    IF Clock_5Hz THEN
Output1:= 0;
        CASE_VAR:= 3;
    END_IF;

Wäre jetzt meine Idee, bin aber kein Freund von Zeiten innerhalb von Schrittketten beim Schalten von Signalen.. dann lieber ein sauberer Handshake zwischen Modulen.
 
Wieso nicht einfach das Taktmerkerbyte verwendet was die SPS selbst generiert?

Dort gibts einen 2Hz Merker bzw einen 5Hz Merker der eben in den Abschnitten TRUE ist, dann musst du keinen Timer basteln
:unsure: ... der eben in den Abschnitten TRUE ist ... ??? Was meinst Du damit und wie kann man das ausnutzen, um damit definierte WarteZeiten zu realisieren? Ich sehe da nur die Möglichkeit, einen TaktMerker mit möglichst hoher Frequenz zu wählen und die Perioden dieses TaktMerkers zu zählen.
Wie willst Du die PhasenLage des TaktMerkerSignals an die Zufälligkeiten anpassen, die bestimmen, ab wann die Zeit beginnen soll zu laufen?
Bekanntlich ist nichts unmöglich, aber eine halbwegs brauchbare Lösung mit einem (oder mehreren) TaktMerker( n ) dürfte unnötig aufwändig sein.
 
Zurück
Oben