TIA Timer - TON - SCL - Startet nicht

Lain91

Level-1
Beiträge
18
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich arbeite aktuell während meines Studiums an einer SPS und bekomme irgendwie den TON - Timer per SCL Code nicht zum laufen.

Theoretisch sollte dies ja relativ simpel funktionieren:

Code:
            #IEC_Timer_0_Instance(IN:=TRUE,
                                    PT:=t#5s,
                                    Q=>#wait_for_timer,
                                    ET=>#timer_actuall_time);

            WHILE #wait_for_timer = FALSE DO
                ;
            END_WHILE;
            // Mache etwas nach 5 Sekunden

Zunächst initialisiere ich den Timer (in dem Fall als Multi - Instanz).
Danach lasse ich die While - Schleife so lange laufen, bis der Ausgang - Q auf TRUE springt. Dies müsste theoretisch nach 5 Sekunden passieren.

Leider passiert jedoch gar nichts. Ich habe es auch vorher als Einzel - Instanz versucht, den Timer sowohl in einem FC als auch FB ohne erfolg versucht zum laufen zu bekommen.

Aktuell habe ich ihn in einem FB als Multi - Instanz.
Übersehe ich etwas einfaches?

Vielen Dank für die Hilfe.
 
Tolle Idee ...
Also erstmal möchte so ein TON einen False->True-Übergang am IN - den gibt es bei dir nicht.
Und dann hältst du die komplette Programm-Abarbeitung mit dem While fest. Du müßtest also eine Zykluszeit-Überschreitung bekommen - das Ereignis kann ja nicht kommen da das Programm nicht mehr weiter bearbeitet wird - also auch nicht der Timer ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Tolle Idee ...
Also erstmal möchte so ein TON einen False->True-Übergang am IN - den gibt es bei dir nicht.

Das habe ich bereits im Internet lesen können und folgendes ohne Erfolg probiert:

Code:
            #IEC_Timer_0_Instance(IN:=FALSE,
                                  PT:=t#5s,
                                  Q=>#wait_for_timer,
                                  ET=>#timer_actuall_time);
            
            #IEC_Timer_0_Instance.IN := TRUE;
            
            
            WHILE #wait_for_timer = FALSE DO
                ;
            END_WHILE;

Laufen Timer auf der SPS nicht im Hintergrund weiter? Jedenfalls kenne ich so Timer von Mikrocontrollern. Ich initialisiere den Timer und bekomme ein Interrupt, wenn der Timer abgelaufen ist.
Diesen Interrupt, so dachte ich, würde der Q - Ausgang darstellen?
 
Laufen Timer auf der SPS nicht im Hintergrund weiter? Jedenfalls kenne ich so Timer von Mikrocontrollern. Ich initialisiere den Timer und bekomme ein Interrupt, wenn der Timer abgelaufen ist.
Diesen Interrupt, so dachte ich, würde der Q - Ausgang darstellen?

Bei Siemens laufen die im Hintergrund, aber bei anderen Herstellern muss der Timerbaustein in jedem Zyklus aufgerufen werden.
Du solltest Dich erstmal ganz allgemein in die Funktionsweise von SPSen einlesen, speziell in die Unterschiede zu PC-Programmen. Soetwas wie Interrupts gibt es bei den meisten SPSen nicht.
Die Abarbeitung erfolgt fat immer zyklisch, das heiß, das Programm startet, läuft bis zum Ende durch und wird dann wieder neu gestartet, wobei der Start in definierten zeitlichen Abständen erfolgt.
Ein Programm mit einer While Schleife anhalten zu wollen ist der Standard Fehler von PC-Programmierern und führt zur von Larry schon erwähnten Zykluszeitüberschreitung.
 
Zuletzt bearbeitet:

Bei Siemens laufen die im Hintergrund, aber bei anderen Herstellern muss der Timerbaustein in jedem Zyklus aufgerufen werden.
Du solltest Dich erstmal ganz allgemein in die Funktionsweise von SPSen einlesen, speziell in die Unterschiede zu PC-Programmen. Soetwas wie Interrupts gibt es bei den meisten SPSen nicht.
Die Abarbeitung erfolgt fat immer zyklisch, das heiß, das Programm startet, läuft bis zum Ende durch und wird dann wieder neu gestartet, wobei der Start in definierten zeitlichen Abständen erfolgt.
Ein Programm mit einer While Schleife anhalten zu wollen ist der Standard Fehler von PC-Programmierern und führt zur von Larry schon erwähnten Zykluszeitüberschreitung.

Okay, ich habe es gerade nochmal anders versucht. Leider weiterhin ohne Erfolg.
Ich würde sagen dies berücksichtigt eure Kommentare, sowohl das Programm läuft weiter, als auch der Wechsel von False -> True bei IN ist gegeben. Leider läuft der Timer dennoch nicht los.

Code:
            // Ganz am Anfang und nur 1x im Programm, Timer Init
            #IEC_Timer_0_Instance(IN := FALSE,
                                  PT := t#5s,
                                  Q => #wait_for_timer,
                                  ET => #timer_actuall_time);

           // Schritt meiner State - Maschine 
           IF #IEC_Timer_0_Instance.IN = FALSE THEN
                 #IEC_Timer_0_Instance.IN := TRUE;
            END_IF;


            IF #wait_for_timer = TRUE THEN
                // Mache etwas
                // Gehe zu nächsten Schritt der State Maschine
            END_IF;
 
Sehe leider keinen Fehler. Grob dargestellt sollte der Ablauf wie folgt sein:

1) Initialisiere Timer bei ersten Aufruf des FBs mit IN = False
2) Wenn State - Maschine am Punkt angekommen, bei dem der Timer benötigt wird, starte Timer, wenn nicht bereits aktiv (Schutz vor unnötig doppeltem starten)
3) Führe solange die State - Maschine in dem aktuellen State aus, bis Q auf True wechselt, führe Code aus und gehe in den nächsten State.

Es gibt keine blockierende Schleife mehr und der FB kann ständig von vorne durchlaufen.

In der Beschreibung von TON konnte ich nun leider keinen Hinweis auf meinen Fehler finden. Daher melde ich mich ja hier :)
 
OK, dann will ich Dich mal in die richtige Richtung schubsen.
Dein Programm wird nicht einmal, sondern immer wieder von vorne bis zum Ende ausgeführt.
Zuerst wird der Timer-Baustein mit IN := FALSE aufgerufen, dann setzt Du IN auf TRUE, aber ohne den Timerbaustein aufzurufen. Ich bin leider Siemens Laie und kann nicht sagen ob die IEC-Timer im Hintergrund laufen und das zum Starten reichen würde. Bei anderen Systemen (z.B. TwinCAT) würde das definitiv nicht reichen, da müsste der FB auch aufgerufen werden.
Dann fragst Du das Ergebnis ab und Dein Programm ist zu Ende.
Und jetzt kommt Dein Gedankenfehler.
Ein TON-Baustein schaltet den Ausgang nach einer eingestellten Zeit auf TRUE, wenn an IN TRUE anliegt und lässt den Ausgang so lange auf TRUE wie IN weiterhin TRUE ist. Das Problem ist, dass Dein Programm dann wieder startet und im nächsten Zyklus Dein IN wieder FALSE ist und somit der Timer gar nicht wirklich in Schwung kommt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Oliver:
Ich unterstelle mal, dass der Unterschied hier nicht so groß ist ...

@TE:
Wenn das immer noch nicht läuft (wobei ich deine False-True-Variante gelinde gesagt K....e finde) solltest du vielleicht mal überlegen, den Schritt deiner Statemachine, der der eigentlich Trigger sein soll, an den Timer zu legen ...
UND ... ganz wichtig : den Timer-Aufruf NICHT bedingt bearbeiten (also nicht innerhalb eines IF-Konstrukts o.ä.).

Gruß
Larry
 
Code:
#IEC_Timer_0_Instance(IN := #aufDenTimerSollGewartetWerden,
                      PT := T#5s,
                      Q  => #timer_Q,
                      ET => #timer_actuall_time);

IF #aufDenTimerSollGewartetWerden AND #timer_Q THEN
    // Mache etwas
    // Gehe zu nächsten Schritt der State Maschine
END_IF;

Harald
 
@Harald
Startet leider auch nicht den Timer, wobei es ja auch quasi mein Code von Post#5 ist.

@Oliver
Du magst recht haben, vielleicht fehlt ein initialer "JETZT STARTE ENDLICH!" Impuls für den Timer. Ich finde es allerdings nicht, selbst mit eurer Hilfe.

@Larry
Ich finde die Lösung auch nicht schön, aber es ist ja offensichtlich auch nicht die Lösung :ROFLMAO:


@All
Ich das Problem nun umgangen und einen FUB TON Timer erstellt. Ganz simpel, Verdrahtung genau so, wie ich es auch im SCL getan habe.
Dann den Ausgang als "Timer_Ende" Bool in meiner Variablentabelle angelegt und meine IF - Abfrage auf "Timer_Ende" = true abgeändert.

Funktioniert.

Richtig hässliche Lösung und totale Krücke, würde es super gerne nur in einem SCL FB haben und nicht den Timer in einem Separaten FUB - FC in der nur der Timer steckt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... dann solltest du dir doch mal die Unterschiede zwischen dem einen und dem anderen Konstrukt ansehen - an irgendeiner Stelle hast du etwas anders gemacht.
TON ist TON - ob in SCL oder FUP spielt keine Rolle ...
Was sagt denn die Online-Sicht ? Nimm als Trigger mal eine von dir steuerbare Variable ...
 
@Harald
Startet leider auch nicht den Timer, wobei es ja auch quasi mein Code von Post#5 ist.

@Oliver
Du magst recht haben, vielleicht fehlt ein initialer "JETZT STARTE ENDLICH!" Impuls für den Timer.
In Deinem Code #5 rufst Du den Timer immer nur mit IN = FALSE auf. So kann ein TON nicht laufen. Ob das Manipulieren "#IEC_Timer_0_Instance.IN := TRUE" ohne den Timer aufzurufen irgendwas bewirkt weiß ich nicht. So schräg programmiere ich nie - erst recht nicht die völlig schrägen TIA-Timer. Möglicherweise reicht es tatsächlich, den Timer einmal mit IN = TRUE aufzurufen und dann nur noch den Timerinstanz.Q abzufragen. Irgendsoeinen Schwachfug hat Siemens da eingebaut, weil Newcomer einfach nicht lernen wollen, wie man S7-Timer richtig programmiert ;)

Ein TON-Timer braucht keinen Impuls zum starten, sondern eine dauerhafte Freigabe am IN, die mindestens so lange TRUE sein muß wie der Timer messen soll (IN muß vordem Timer-Start mindestens einmal FALSE gewesen sein). Sobald der Timer mit IN = FALSE aufgerufen wird, wird er wieder zurückgesetzt und läuft nicht.

Harald
 
In Deinem Code #5 rufst Du den Timer immer nur mit IN = FALSE auf. So kann ein TON nicht laufen. Ob das Manipulieren "#IEC_Timer_0_Instance.IN := TRUE" ohne den Timer aufzurufen irgendwas bewirkt weiß ich nicht. So schräg programmiere ich nie - erst recht nicht die völlig schrägen TIA-Timer. Möglicherweise reicht es tatsächlich, den Timer einmal mit IN = TRUE aufzurufen und dann nur noch den Timerinstanz.Q abzufragen. Irgendsoeinen Schwachfug hat Siemens da eingebaut, weil Newcomer einfach nicht lernen wollen, wie man S7-Timer richtig programmiert ;)

Ein TON-Timer braucht keinen Impuls zum starten, sondern eine dauerhafte Freigabe am IN, die mindestens so lange TRUE sein muß wie der Timer messen soll (IN muß vordem Timer-Start mindestens einmal FALSE gewesen sein). Sobald der Timer mit IN = FALSE aufgerufen wird, wird er wieder zurückgesetzt und läuft nicht.

Harald

Ich denke das war grundsätzlich das Problem, jedoch habe ich nicht verstanden, warum mein Ansatz dies nicht umsetzt.

Nun habe ich meine State - Maschine etwas abgeändert und für den Timer neustart extra States eingeführt und mit einem "RETURN" in dem jeweiligen State dafür gesorgt, dass der Timer auch sicher wieder aufgerufen wird, bevor ich in den nächsten State wechsel.
Aktuell habe ich es nur für 2 von 10 Timer aufrufen probiert, aber es scheint nun zu funktionieren.

Mein FB in dem die State - Maschine steckt läuft bis zum ersten Timer Aufruf durch, macht seine Aufgaben während der Timer läuft, danach beendet sich der FB, startet den Timer neu und geht dann wieder in den FB an den zuletzt gespeicherten State.

Wunderbar! Ich danke euch für die Hilfe :)
 
Ein TON-Timer, welcher in seinem Instanz-DB bei der Eingangsvariable In den Startwert true aufweist, fängt aber nach SPS Start nicht an zu laufen, wenn die im Programm mit In verknüpfte Variable ab Start gleich true ist.

Den Grund einen TON-Timer so zu programmieren werde ich wohl nie verstehen. Ein TON-Timer besitzt genau 3 Zustände: läuft nicht (IN=false), läuft(IN=true), abgelaufen(IN=true, OUT=true).
Warum zum Kuckuck muss es einen Zustand geben, dass IN=TRUE, der Timer weder läuft noch abgelaufen ist? Wozu?
 
Hallo Leute ich hoffe ihr seid mir nicht Böse den ich Frage nur immer!
Erstmal ich bin kein Programmierer, stöbere nur im AWL, FUP, VB, SCL als gewöhnlicher Elektriker.
Also wenn das hier unpassend sein sollte bitte Löschen!
Jetzt wo ich bischen SCL Erfahrung habe wollte ich von meinem Pelletofen Temperatur über SPS steuern.

Da habe ich aus verschieden SCL Quellen hin und her kopiert um halbwegs auf das was ich brauche hinzukommen.
1.) Welche Literatur bzw. wo könnte ich mir Wissen holen um weiter zu kommen.
Ich habe mir einige Videos über SCL angesehen und gelesen aber so wirklich auf was brauchbares für diesen Fall nicht gestoßen.

Bei Generieren vom FB aus dem SCL-Cod wo wird da die FB Nummer bestimmt?
Wie kann ich Zeiten Starten für Schritte bzw. für die Ausgänge?

Bitte um Tipps bzw.
ich möchte auch etwas tiefer ins SCL.


[FONT=&quot]Danke grüße
Code:
FUNCTION_BLOCK Auto_OFEN
TITLE = 'Auto_OFEN'

VERSION : '0.1'
AUTHOR  : HANNS
NAME    : Auto_OFEN
FAMILY  : OFEN

VAR_INPUT
    EIN_AUS: BOOL;    //Ofen EIN
    P_AN : BOOL;      //Puffer Anforderung
    P_AUS : BOOL;     //Puffer AUS
    K_VOR : REAL;     //Ofenvorlauf Temperatur
    ABGAS : REAL;     //Ofen Abgastemperatur
    SOLL :REAL;       //Ofen Solltemperatur
END_VAR

VAR_INPUT
    ZUND_TI : TIME:= T#20m;  //Zündung MAX Dauer
    FEUE_ST : TIME :=T#6m;   //Feuer Stabilisierung
    REINI_I : TIME :=T#30m;  //Reinigung Interval alle 30min
    REINI_Z : TIME := T#15s; //Reinigungs Zeit
    T_DIFF : REAL := 10.0;
END_VAR

VAR_TEMP
    tx : REAL;       //P_VOR unterschied zu soll

END_VAR    

VAR_OUTPUT
    VENT_EIN : BOOL;    //Ventilator EIN
    SCH_EIN : BOOL;     //Schnecke EIN
    HEIZ_EIN : BOOL;    //Heizzunge EIN
    STATUS : BYTE;
END_VAR


BEGIN

// Initialisirung
VENT_EIN = FALSE;
SCH_EIN = FALSE;
HEIZ_EIN = FALSE;


IF  EIN_AUS THEN  STATUS := 1; END_IF                                    // Funktion nur bei EIN
    
IF P_AN AND STATUS = 1 THEN STATUS := 2; END_IF                          //Puffer anforderung

IF STATUS := 2 AND NOT P_AUS AND K_VOR <85 AND ABGAS <240 THEN STATUS := 3 ; END_IF  // ZÜNDUNG und starte die Zündungszeit (Schrittdauer)18min wenn nicht K_VOR >55 bisdahin, Störung
            
IF STATUS := 3 AND  K_VOR >55 THEN STATUS := 4;END_IF                    //STABILISIERUNG starte Zeit (Schrittdauer)6 min

IF STATUS := 4 AND ZEIT2 =>6 THEN STATUS := 5; END_IF                    //Sollwert Regelung 

IF status := 1 AND P_AUS THEN STATUS := 6; END_IF                        //Ausschaltzyklus

IF STATUS := 2 AND //ab da 30 min wiederkehrend  THEN STATUS :=7 ; END_IF                        //Reinigungszyklus

IF STATUS := 6 AND ABGAS <71 THEN STATUS :=8 ; END_IF                    //Störung





CASE BYTE_TO_INT(STATUS) OF
    
    3:                //ZÜNDUNG an, K_VOR hatt 18 min Zeit um > 55°C zu werden sonst Störung
    VENT_EIN = TRUE;
    SCH_EIN  = TRUE;  //600ms impuls 200ms pause
    HEIZ_EIN = TRUE;
    
    
    
    
    
    
    4:                //STABILISIERUNG 6 min danach status 5
    VENT_EIN = TRUE;
    SCH_EIN  = TRUE;  //800ms impuls 200ms pause
    HEIZ_EIN = FALSE;
    
    
    
    
    
    5:               //SOLLWERTREGELUNG
    
    tr: = SOLL - P_VOR;
    
    IF tr: => 10 THEN
    
    VENT_EIN = TRUE;
    SCH_EIN  = TRUE;  //3s impuls 300ms pause
        
    END_IF 
     
     IF tr: = 9 OR 8 THEN
     VENT_EIN = TRUE;
     SCH_EIN  = TRUE;  //2,4s impuls 300ms pause
     END_IF
       
      IF tr: = 7 OR 6 OR 5 THEN
      VENT_EIN = TRUE;
      SCH_EIN  = TRUE;  //1,9s impuls 300ms pause
      END_IF
      
       IF tr: = 4 OR 3 THEN
       VENT_EIN = TRUE;
       SCH_EIN  = TRUE;  //1,4s impuls 500ms pause
       END_IF

        IF tr: = 2 OR 1 OR 0 THEN
        VENT_EIN = TRUE;
        SCH_EIN  = TRUE;  //300ms impuls 900ms pause  
        END_IF 
    
    
     
    
    
    
    7:                //Reinigungszyklus dauer 15sec
    VENT_EIN = TRUE;
    SCH_EIN  = TRUE;  //1,3ss impuls 200ms pause
    
    
    
    
    
    
    
    6:                 //Ausschaltzyklus
    VENT_EIN = TRUE;
    SCH_EIN = FALSE;
    
         IF ABGAS < 80 THEN 
         VENT_EIN = FALSE;
         END_IF   
        
        
        
        
    7:                 //Störung
               IF ABGAS >80 OR K_VOR >80 THEN
               VENT_EIN = TRUE;
               SCH_EIN = FALSE;   
               END_IF





END_FUNCTION_BLOCK
[/FONT]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Den Grund einen TON-Timer so zu programmieren werde ich wohl nie verstehen. Ein TON-Timer besitzt genau 3 Zustände: läuft nicht (IN=false), läuft(IN=true), abgelaufen(IN=true, OUT=true).
Warum zum Kuckuck muss es einen Zustand geben, dass IN=TRUE, der Timer weder läuft noch abgelaufen ist? Wozu?

#t_in := true;


"TempStabilityTON".TON(IN := #t_in,
PT := #Delay,
Q => #t_out,
ET => #t_et);

IF #t_out THEN
RESET_TIMER("TempStabilityTON");

END_IF;

Ich konnte es so lösen: In meinem Fall möchte ich, dass die Zeit zyklisch in einem bestimmten Intervall abläuft. Mit RESET_TIMER könntest du versuchen es zu Initialisieren.
 
Den Grund einen TON-Timer so zu programmieren werde ich wohl nie verstehen. Ein TON-Timer besitzt genau 3 Zustände: läuft nicht (IN=false), läuft(IN=true), abgelaufen(IN=true, OUT=true).
Warum zum Kuckuck muss es einen Zustand geben, dass IN=TRUE, der Timer weder läuft noch abgelaufen ist? Wozu?

Der Timer nimmt vermutlich intern bei der steigenden Flanke des "IN" die "Systemzeit" und speichert sie in der Variable "ET". Sobald "ET" plus "PT" größer als die "Systemzeit" ist, setzt er dann den "Q".
 
Der Timer nimmt vermutlich intern bei der steigenden Flanke des "IN" die "Systemzeit" und speichert sie in der Variable "ET". Sobald "ET" plus "PT" größer als die "Systemzeit" ist, setzt er dann den "Q".
Transition von Zustand "läuft nicht" nach "läuft", dann bräuchte man keine eigene Flanke außerhalb des Zustandsdiagramms und es kann keinen undefinierten Zustand geben. Oder dieses Verhalten ist durch die IEC festgelegt, kann ich mir aber auch kaum vorstellen, da sich die TIA-TONs ja schon sehr grundlegend anders verhalten.
 
Zurück
Oben