Step 7 Probleme mit SFB3 TP beim Erzeugen von Pulsen

DDuesentrieb

Level-1
Beiträge
44
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ihr,

ich habe folgendes Problem. Ich habe mir einen Baustein für die Erstellung von Pulsen mit vorgegebenen Pausenzeiten erstellt.
Dies funktioniert auch gut solang als Pausenzeit nicht 0 gewählt ist.
Für einen Sekundenpuls müsste ich aber die Pausenzeit auf 0 setzen.
Nachfolgend mein Quellcode als Quelle.

Code:
FUNCTION_BLOCK "Pulses_and_Flashers_Cont"
TITLE =
VERSION : 0.1


VAR_INPUT
  Enable : BOOL ;    //Enable or Disable the Function Block (Insert 0 = Disable 1 = Enable)
  Puls_Length : TIME ;    //Length of Puls
  Pause_Length : TIME ;    //Length of Pause
END_VAR
VAR_OUTPUT
  Puls : BOOL ;    //Output Bit while Puls is 1
  Pause : BOOL ;    //Output Bit while Pause is 1
END_VAR
VAR
  Timer_Puls : "TP";    
  Timer_Pause : "TP";    
  Release_Puls : BOOL ;    
  Release_Pause : BOOL ;    
  Rest_Time_Puls : TIME ;    
  Rest_Time_Pause : TIME ;    
END_VAR
BEGIN
NETWORK
TITLE =

      UN    #Enable; 
      SPB   Ende; 

      UN    #Puls; 
      UN    #Pause; 
      S     #Release_Puls; 


      CALL #Timer_Puls (
           IN                       := #Release_Puls,
           PT                       := #Puls_Length,
           Q                        := #Puls,
           ET                       := #Rest_Time_Puls);

      UN    #Puls; 
      R     #Release_Puls; 
      S     #Release_Pause; 

      CALL #Timer_Pause (
           IN                       := #Release_Pause,
           PT                       := #Pause_Length,
           Q                        := #Pause,
           ET                       := #Rest_Time_Pause);

      UN    #Pause; 
      R     #Release_Pause; 

Ende: NOP   0; 


END_FUNCTION_BLOCK

Wo ist mein Fehler?

Schon mal vielen Dank für eure Hilfe!
 
Hallo,
wenn du die Zeit auf "0" setzt dann läuft der Timer gar nicht erst - wie du schon selber festgestellt hast. Du hast also nur die Alternative, den Zeitwert abzufragen und wenn da "0" drin steht, den Timer gar nicht erst zu benutzen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Pulse

Rest
_Time = Ruhezeit :D
Die gängige Bezeichnung wäre RemainingTime bzw. RT

PS: Das Problem mit PT = 0 habe ich auch beim TIMER_P-Baustein, der dann im Modus Ausschaltverzögerung trotz Eingang IO=1 den Ausgang Q = 0 lässt..
 
Zuletzt bearbeitet:
@Flux Dankeschön für den Hinweis :D
Da haben sich wohl ein paar deutsche Wörter mit eingeschlichen ^^

Ich bin im moment auch noch etwas ratlos, wie ich das am besten löse.

Ich kann mir nicht erklären warum aber der folgende Code funktioniert auch, wenn ich die Zeiten für die
Pause auf 0 lasse.
Gefällt mir aber eigentlich von der Programmierung her nicht und kann mir wie gesagt nicht erklären warum
es so wie es im Code steht funktioniert.

Code:
FUNCTION_BLOCK "Pulses_and_Flashers_Cont"
TITLE =
VERSION : 0.1


VAR_INPUT
  Enable : BOOL ;    //Enable or Disable the Function Block (Insert 0 = Disable 1 = Enable)
  Puls_Length : TIME ;    //Length of Puls
  Pause_Length : TIME ;    //Length of Pause
END_VAR
VAR_OUTPUT
  Puls : BOOL ;    //Output Bit while Puls is 1
  Pause : BOOL ;    //Output Bit while Pause is 1
END_VAR
VAR
  Timer_Puls : "TP";    
  Timer_Pause : "TP";    
  Release_Puls : BOOL ;    
  Release_Pause : BOOL ;    
END_VAR
BEGIN
NETWORK
TITLE =

      UN    #Enable; 
      SPB   Ende; 


      UN    #Puls; 
      UN    #Pause; 
      S     #Release_Puls; 



      CALL #Timer_Puls (
           IN                       := #Release_Puls,
           PT                       := #Puls_Length,
           Q                        := #Puls);

      UN    #Puls; 
      CLR   ; 
      =     #Release_Puls; 

      UN    #Puls; 
      S     #Release_Pause; 

      CALL #Timer_Pause (
           IN                       := #Release_Pause,
           PT                       := #Pause_Length,
           Q                        := #Pause);

      UN    #Pause; 
      CLR   ; 
      =     #Release_Pause; 

Ende: NOP   0; 


END_FUNCTION_BLOCK
 
Ich würde am Anfang des FB folgendes abfangen:

Pulse0 := PT_Pulse = T#0s;
Pause0 := PT_Pause = T#0s;

IF Pulse0 THEN
Pulse := 0; Pause := 1;
GOTO Ende;

ELSIF Pause0 THEN // implizit: AND NOT Pulse0
Pulse := 1; Pause := 0;
GOTO Ende;

ELSE

//..dein Code

END_IF;

ENDE : ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Flux,

danke für die Antwort!

Ich werde mir deinen Lösungsweg mal anschauen.

Ich habe zwischenzeitlich folgenden Lösungweg gefunden.

Code:
FUNCTION_BLOCK "Pulses_and_Flashers_Cont"
TITLE =
VERSION : 0.1


VAR_INPUT
  Enable : BOOL ;    //Enable or Disable the Function Block (Insert 0 = Disable 1 = Enable)
  Pulse_Length : TIME ;    //Length of Puls
  Pause_Length : TIME ;    //Length of Pause
END_VAR
VAR_OUTPUT
  Pulse : BOOL ;    //Output Bit while Puls is 1
  Pause : BOOL ;    //Output Bit while Pause is 1
END_VAR
VAR
  Release_Pulse : BOOL ;    
  Release_Pause : BOOL ;    
  Storage_FP_Pulse : BOOL ;    
  Storage_FP_Pause : BOOL ;    
  RT_Pulse : TIME ;    
  RT_Pause : TIME ;    
  Timer_Pulse : "TP";    
  Timer_Pause : "TP";    
END_VAR
BEGIN
NETWORK
TITLE =

      UN    #Enable; 
      SPB   Ende; 


      UN    #Pulse; 
      UN    #Pause; 
      FP    #Storage_FP_Pulse; 
      =     #Release_Pulse; 



      CALL #Timer_Pulse (
           IN                       := #Release_Pulse,
           PT                       := #Pulse_Length,
           Q                        := #Pulse,
           ET                       := #RT_Pulse);

      UN    #Pulse; 
      FP    #Storage_FP_Pause; 
      =     #Release_Pause; 

      CALL #Timer_Pause (
           IN                       := #Release_Pause,
           PT                       := #Pause_Length,
           Q                        := #Pause,
           ET                       := #RT_Pause);


Ende: NOP   0; 


END_FUNCTION_BLOCK

Der einzige Stolperstein hier ist soweit ich das jetzt mit PLCSIM feststellen konnte, dass die Pulszeit nicht 0 sein darf.
In meinem konkreten Anwendungsfall wird die Pulszeit nie 0, weswegen dieser Umstand für mich vernachlässigbar ist.
 
Auf den ersten Blick gefällt mir der Code überhaupt nicht. Das Überspringen der Flankenerkennungen und der Timeraufrufe und der Ausgangszuweisungen ist normalerweise überhaupt nicht gut.
Und (später mal?) im TIA wird Dir das Abfragen der Ausgänge vor einer Zuweisung um die Ohren gehauen.

Was soll passieren, wenn Enable false wird? Und wenn er wieder true wird?
Was soll passieren, wenn Pulse_Length oder Pause_Length sich ändern während die Zeit läuft?
Was soll passieren, wenn die SPS eingeschaltet wird (Warmstart)?
Wie genau sollen die Pulszeiten sein?
Was soll passieren wenn Pause_Length = T#0s ist?


In meinem konkreten Anwendungsfall wird die Pulszeit nie 0, weswegen dieser Umstand für mich vernachlässigbar ist.
"Sag niemals nie." In einem halben Jahr willst Du oder jemand anders den tollen Baustein woanders nutzen...
Wenn Du schon weisst, daß T#0s und negative T#... ein Problem für Deinen Baustein sind, dann fange diese Probleme sicherheitshalber trotzdem ab.

Harald
 
stimme PN/DP zu. Guter Code zeichnet sich durch Verständlichkeit (gut kommentiert), Einfachheit (und trotzdem technisch korrekt) und (DAU-)Sicherheit aus :)

Generell arbeite ich meistens mit Eingangs- und Ausgangsabbildern sowie Arbeitsvariablen im STAT-Bereich. Damit hat man volle Kontrolle, wann bspw. geänderte Eingagnswerte übernommen werden bzw. kann bei Erkennung einer Änderung angemessen reagieren..

EDIT: Ich würde dir dann aber stark empfehlen zwecks Übersichtlichkeit auf SCL zu wechseln, wenn du die Möglichkeit hast.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
1. Was soll passieren, wenn Enable false wird? Und wenn er wieder true wird?
2. Was soll passieren, wenn Pulse_Length oder Pause_Length sich ändern während die Zeit läuft?
3. Was soll passieren, wenn die SPS eingeschaltet wird (Warmstart)?
4. Wie genau sollen die Pulszeiten sein?
5. Was soll passieren wenn Pause_Length = T#0s ist?

Hallo Harald,

danke für deine Antwort.
Das sind ja ganz schön viel Fragen :D.

Ich hab mir erlaubt die Fragen mal durch zu nummerieren.

1. Da habe ich mir ehrlich gesagt noch gar keine Gedanken gemacht. Weil bisher handhabe ich es so, dass ich in einem MultiFB 15 Bausteinaufrufe vorgesehen habe und nur die, die ich verwende fest auf True setze.
2. Das gleiche gilt im Moment bei den Zeiten. Aber im Moment kann ich mir aber noch kein Problem vorstellen, wenn ich die Zeiten ändere. Sich ändernde Zeiten könnte ich mir vorstellen, wenn ich den Baustein zum Takten von Ventilen benutze und die Zeiten über die HMI eingebe.
3. Wenn die SPS angeschaltet wird sollen die Pulse einfach anfangen zu laufen.
4. Die Zeiten müssen nicht übermäßig genau sein. Verwende den Baustein z.B. zum Erzeugen eines 1 Sekunden Pulses.
5. Für den Sekunden Puls ist z.B. die Pausen Zeit 0. Das soll bewirken, dass der Ausgang 1 sec lang 1 ist und für einen Zyklus dann Null. In der Firma in der ich arbeite sind die Zähler so realisiert, dass wenn der Ausgang 1 ist der Zähler übersprungen wird.

Bin gerade am Überlegen, wenn ich die Extremfälle abfange, was ich dann am besten mit den Sollwerten mache. In der HMI kann ich ja beschränken, was der Benutzer eingeben darf aber wie es in der S7 umsetze weiß ich noch nicht genau.

Ganz gefallen tut es mir auch noch nicht. Aber im Moment weiß ich noch nicht genau, wie ich es viel besser machen soll :/
 
Zurück
Oben